My mxd has a dataframe which contains a MS Word-Object ("Insert" - "Object"). The Object was added to data view.
I want to access the MXD dataframe in PyScripter using
arcpy.mapping.ListDataFrames(mxd)[0]
However, I get the following error:
AttributeError: 'NoneType' object has no attribute 'dataFrames'
I'd also like to import the MXD to ArcGIS Pro but it doesn't work, I get an error.
When I delete the Word-Object all these errors do not occur.
(Note: When I use the Python window in ArcMap, the AttributeError does not occur. However, I would like to make it work in PyScripter)
I thought about deleting the Word-Object with ArcPy, is that possible? I have hundreds of MXDs with this Word-Object, so I need to automate this.
I already tried using ListLayoutElements but nothing is returned because the object was added in data view.
1 Answer 1
I don't think arcpy exposes any methods that allow you to delete OLE objects inserted into a data frame. You can automate this using ArcObjects.
So in screen shot below I have a polyline layer, graphic and an OLE word document in a map view (so NOT layout).
The following VBA code will find any OLE frame and delete it:
Sub test()
' This code demonstrates how to find OLE Frames in map and delete them
' This code does not save the map to make changes permanent use IApplication to do that
'
' Duncan Hornby, 19/12/2023
Dim pMXD As IMxDocument
Set pMXD = ThisDocument
Dim pActiveView As IActiveView
Set pActiveView = pMXD.ActiveView
Dim pMap As IMap
Set pMap = pActiveView.FocusMap
Dim pGraphicsLayer As IGraphicsLayer
Set pGraphicsLayer = pMap.ActiveGraphicsLayer
Dim pGraphicsContainer As IGraphicsContainer
Set pGraphicsContainer = pGraphicsLayer
pGraphicsContainer.Reset
Dim pElementProp As IElementProperties
Dim pElement As IElement
Dim pOLEFrame As IOleFrame
' Step through elements in map
Set pElement = pGraphicsContainer.Next()
Do Until pElement Is Nothing
Set pElementProp = pElement
If pElementProp.Type = "OLE Frame" Then
' Found an OLE Frame, now delete it
Set pOLEFrame = pElement
pGraphicsContainer.DeleteElement pOLEFrame
End If
Set pElement = pGraphicsContainer.Next()
Loop
' Refresh map
pActiveView.Refresh
End Sub
You can run this directly inside the VBA editor in ArcMap, or you now have the basic template of code to convert this into VB.Net and run it as outside ArcMap, your choice.
After running this code we see only the Word OLE element has been removed.
-
I doubt many users will have VBA in ArcMap after it went out of support at 10.2.2. VB.Net would be fine though.Berend– Berend2023年12月19日 12:17:59 +00:00Commented Dec 19, 2023 at 12:17
-
1@Berend, yes indeed! I do feel like I'm part of a rapidly vanishing subset of users! The king is dead (VBA) long live the King (Python)! I tend to use VBA to answer such questions as firing up Visual Studio is too much when trying to demonstrate a solution.Hornbydd– Hornbydd2023年12月19日 12:56:28 +00:00Commented Dec 19, 2023 at 12:56
-
2Despite VBA being "dead"... this is a great answer! Proof that nothing truly dies if it's loved. Well, maybe love is too strong a word here....KHibma– KHibma2023年12月19日 17:11:11 +00:00Commented Dec 19, 2023 at 17:11
-
I'd like to run this code for hundreds of MXDs. The MXD paths are stored in a txt file. In python i would loop over the txt file, could I do the same in VBA? Also, should i do this in the ArcMap VBA Editor (i thought about downgrading ArcMap to an earlier Version) or rather in VB.net using VSCode? I am completely new to ArcObjects and VBA programming.Philip Srnck– Philip Srnck2023年12月20日 09:20:11 +00:00Commented Dec 20, 2023 at 9:20
-
1Be aware ESRI have withdrawn development and no doubt support for ArcMap in the near future, so you are flogging a dead horse if your organisation wants to continue using Arcmap. You should seriously consider migrating to ArcPro, that is the future ESRI have envisaged.Hornbydd– Hornbydd2023年12月20日 11:44:48 +00:00Commented Dec 20, 2023 at 11:44