Select to view content in your preferred language

Export to Image by VBA from outside ArcMap fails

1227
11
09-29-2011 08:53 AM
DanielFuchs
Emerging Contributor
I know a rather similar topic has been around before, but without a really satisfying answer, so I'll try again.

I wrote a short export routine in VBA that simply exports the current PageLayout to a PDF file, and if run from within ArcMap it works fine. But if I put the same function in a module in MSAccess and run it from there it produces a blank page (of the right dimensions, however). All other ArcMap automation run from MSAccess works ok, e. g. if I set the layout zoom factor to 100 or refresh the page layout, that's done. Only the export itself produces a blank page.

The actual code is attached although as I said it's working in ArcMap. I very much hope someone out there has a solution - thanks in advance.

Daniel
0 Kudos
11 Replies
JamesCrandall
MVP Alum
If you are attempting to place this code into VBA-Access, and I don't necessarily know the answer to this, but how does it know what an IActiveView or an IPageLayout2 is?  Aren't these ArcObjects, specific to ArcGIS?

Sorry I don't have a direct answer, but I am unsure how you could implement any ArcObject into a non-ArcGIS application (Microsoft Access).
0 Kudos
DanielFuchs
Emerging Contributor
James, that's quite easy actually. You only have to check the necessary ArcObject libraries in the Tools - References menu (ESRICarto UI Object library etc.) within the VBA environment in MSAccess and then you can use all ArcObject functions, methods and so on within Access - of course you'll need some ArcMap App that's running at the same time that your code interacts with. All that works - but for the export I mentioned.

Daniel
0 Kudos
JamesCrandall
MVP Alum
James, that's quite easy actually. You only have to check the necessary ArcObject libraries in the Tools - References menu (ESRICarto UI Object library etc.) within the VBA environment in MSAccess and then you can use all ArcObject functions, methods and so on within Access - of course you'll need some ArcMap App that's running at the same time that your code interacts with. All that works - but for the export I mentioned.

Daniel


huh.  I had no idea.  I had to do a double take when I saw all of the ESRI references in the list!

What's your code that sets the pPageLayout?
0 Kudos
DanielFuchs
Emerging Contributor
Yeah, it's quite neat to run ArcMap from somewhere else ... the pPageLayout is obtained in other parts of the code, where I check if the ArcMap App is running and if so I get the IMxDoc::PageLayout from this App. This seems to work since if I do something with this pPageLayout - e. g. change the Zoom Factor - in Access ArcMap responds ok. But still - I too have a hunch that this reference to the PageLayout could be the problem but I can't think of another method to verify or change this!
0 Kudos
JamesCrandall
MVP Alum
Yeah, it's quite neat to run ArcMap from somewhere else ... the pPageLayout is obtained in other parts of the code, where I check if the ArcMap App is running and if so I get the IMxDoc::PageLayout from this App. This seems to work since if I do something with this pPageLayout - e. g. change the Zoom Factor - in Access ArcMap responds ok. But still - I too have a hunch that this reference to the PageLayout could be the problem but I can't think of another method to verify or change this!


Just check to make sure of something like... if the Set pPageLayout = ActiveView or something to that effect.  I mean, what if the active view was not the LayoutView?  Or does it interperet the activeView as something within Access?

I really don't know.
0 Kudos
NeilClemmons
Honored Contributor
Your code is not running inside of ArcMap.  Therefore, any ArcObjects you create using the NEW keyword are created outside of ArcMap's process space.  ArcObjects are single apartment threaded, meaning they will not marshal correctly across process boundaries.  In order to work correctly, you will need to create all instances of the ArcObjects you're using inside of ArcMap's process space.  This can be done by using IObjectFactory.
0 Kudos
DanielFuchs
Emerging Contributor
Your code is not running inside of ArcMap.  Therefore, any ArcObjects you create using the NEW keyword are created outside of ArcMap's process space.  ArcObjects are single apartment threaded, meaning they will not marshal correctly across process boundaries.  In order to work correctly, you will need to create all instances of the ArcObjects you're using inside of ArcMap's process space.  This can be done by using IObjectFactory.


Neil, thanks for your reply. I have never used the IObjectFactory before, and there's one thing I don't quite understand. In my example there's quite a lot of ArcObjects that are created with the NEW keyword within MSAccess (in other parts of the code that's got nothing to do with exporting an image) and they all seem to work correctly. One thing I did not mention is that in our case MSAccess and ArcMap are always running at the same time - is this relevant for the question if one has to use the IObjectFactory? If not: do you have an idea where it will be necessary to use an IObjectFactory - to get the pPageLayout (which for some cases seems to work ok, e. g. when refreshing the LayoutView) or to get the New IExport? Thanks again, Daniel
0 Kudos
AlexanderGray
Honored Contributor
Neil is right.  New objects will work in the MSAccess workspace factory in some cases.  For exampl,e you could create a new featurelayer, set its featureclass, name, symbols, etc.  even save it as an lyr file, no problem.  Try adding that layer to an ArcMap running in a different process, many many problems.  If you are only interacting with a object in the local MSAccess memory space, new is the way to go.  Technically if you are just calling some method with literal values, strings, integers, booleans, everything should be ok because you are not passing references to objects so the values get copied to the new process.  If the object has to interact with objects in another memory space, such as ArcMap, ObjectFactory is the only way to go.  You don't have the code posted but I suspect you create some object that interact with the pagelayout, if you create those objects in the MSAccess process, they have to go cross process to ArcMap to get the pagelayout, that is when bad things happen.
0 Kudos
DanielFuchs
Emerging Contributor
Alexander, thanks for the clarification. I had the code posted in my original post, and from what you tell me I suspect the problem might occur when I set a NEW ExportPDF. At the moment I wrote a workaround where the exporting sub stays within ArcMap and is triggered from MSAccess by a IVbaApplication.RunVBAMacro line, and this works. Unfortunately, I have to deal with other projects for the next few days but I'll come back to that and I'll try the IObjectFactory then. Thanks to all.
0 Kudos