8

I have an Access database (MS Access 2010) that allows users to enter a variety of land treatment information including associated points, lines, or polygons which users can select and the database would then load as part of the project, to a master geodatabase, and allow the user to view the features in an ArcMap. In Arc 9.3 this was all accomplished with VBA and worked well. Because of the upgrade to Arc 10, VBA is no longer an option and I have been learning how to program in python and call the commands through Access using the Shell feature. I have nearly completed everything except for the ability to allow users to add their feature to the current ArcMap document. Here are the steps that should occur.

1) User clicks a button in the Access program which identifes the feature(s) of interest.

2) Access determines if the correct mxd is open and if not opens it (the document is usually open so this step is often uneccessary)

3) The Python script opens using the Python shell command, identifes the correct and open mxd, and adds feature to the open ArcMap document

I have tried both arcpy and ArcObjects. I can run arcpy within the open map but opening a Python file via VBA in MS Access does not manipulate the open mxd. The ESRI forum suggested that I work with ArcObjects. I have found and used code to identify and manipulate layer already loaded in the ArcMap document of interest but am completely stuck on how to identify and add a new layer. Here is the code so far, I think it will work if I can correctly identify the layer file in the last section of code. At least it all runs without the pMap.AddLayer(FC) near the bottom of the code, but I am an ecologist and not a programmer by training so there may be something else I am missing. Any help would be appreciated.

Update: I am now very close. I can identify the feature in the geodatabase but now ArcMap crashes when attempting to add the data to the map and I generate the error: COMError: (-2147467259, 'Unspecified error', (None, None, None, 0, None)). However, my output appear to identify the correct feature. I am unsure as to why ArcMap is crashing. Please help, I am so close.

import arcpy
from arcpy import env
import os
import sys
import comtypes.gen.esriArcMapUI as esriArcMapUI
import comtypes.gen.esriCarto as esriCarto
import comtypes.gen.esriGeoDatabase as esriGeoDatabase
import comtypes.gen.esriFramework as esriFramework
import comtypes.gen.esriSystem as esriSystem
import comtypes.gen.esriDataSourcesFile as DataSourcesFile

#Eventaully these will be the arguments that call the feature
#test = sys.argv[0]
#Name = sys.argv[1]
#Alias = sys.argv[2]

def NewObj(MyClass, MyInterface):
    from comtypes.client import CreateObject
    try:
        ptr = CreateObject(MyClass, interface=MyInterface)
        return ptr
    except:
        return None

def CType(obj, interface):
    try:
        newobj = obj.QueryInterface(interface)
        return newobj
    except:
        return None

def GetApp():
    """Get a hook into the current session of ArcMap""" 
    #from comtypes.gen import esriFramework
    pAppROT = NewObj(esriFramework.AppROT, esriFramework.IAppROT)
    if pAppROT is not None:
        iCount = pAppROT.Count 
        if iCount == 0: 
            print 'No ArcGIS application currently running.  Terminating ...' 
            return None 
        for i in range(iCount): 
            pApp = pAppROT.Item(i)  #returns IApplication on AppRef
            print pApp.Name
            if pApp.Name == 'ArcMap': 
                print "ArcMap found"
                pDoc = pApp.Document
                print pDoc.Title
                if pDoc.Title == "CreateShapefile10x.mxd" or pDoc.Title == "CreateShapefile10x":
                    return pApp 
    print 'No ArcMap session is running at this time.' 
print "No AppROT found"
print "Failed"
return None

pApp = GetApp()

try:
    pDoc = pApp.Document
    pMxDoc = CType(pDoc, esriArcMapUI.IMxDocument)
    pMap = pMxDoc.FocusMap
    if pMap.Name == "LTDL Layers":

        ###New Code###

        sPath = r"Y:\LTDL_Data\LTDL_Files\Abate_Seeding_1965\Abate_Seeding_1965.gdb"
        sPath1 = r"Abate_Seeding_1965"
        pWSF = NewObj(esriDataSourcesGDB.FileGDBWorkspaceFactory, esriGeoDatabase.IWorkspaceFactory)
        print pWSF
        pWS = pWSF.OpenFromFile(sPath, 0)
        pDS = CType(pWS, esriGeoDatabase.IDataset)

        print "Workspace name: " + pDS.BrowseName
        print "Workspace category: " + pDS.Category

        FWSS = CType(pWS, esriGeoDatabase.IFeatureWorkspace)
        FL = NewObj(esriCarto.FeatureLayer, esriCarto.IFeatureLayer)
        FL.FeatureClass = FWSS.OpenFeatureClass(sPath1)
        print FL
        print FL.FeatureClass.AliasName
        LAN = CType(FL, esriCarto.ILayer)
        LAN.Name = FL.FeatureClass.AliasName + ": Project Boundary"
        print LAN.Name

        ###New Code###

        pMap.AddLayer(FC)
        pLayout = pMxDoc.PageLayout
        pActiveView = CType(pLayout, esriCarto.IActiveView)
        pActiveView.Refresh()
        pMxDoc.UpdateContents
    print "Done"
except:
    print "Failed"
3
  • 1
    Try using IObjectFactory to create the workspace factory singleton in the correct process as in this question: ArcMap/ArcObjects - Drawing graphics onscreen: Explanation or tutorial for Draw/Refresh/PartialRefresh methods?
    – blah238
    Commented Mar 9, 2012 at 22:10
  • Tried to add atext element as described and it still threw an error. pFact = CType(pApp, esriFramework.IObjectFactory) graphicsContainer = pMxDoc.ActiveView.GraphicsContainer textElement = CType(pFact.Create("esriCarto.TextElement"), esriCarto.ITextElement) graphicsContainer.AddElement(textElement, 0) pMxDoc.ActiveView.PartialRefresh(esriCarto.esriViewGraphics, None, None). Next I added an empty layer with no data source and used mapAdmin2.FireChangeFeatureClass(OFL, NFC) to assign a data source. ArcMap started and then crashed and shut down as before.
    – user6287
    Commented Mar 13, 2012 at 14:34
  • 1
    This question should probably be closed as it appears that the author has lost interest.
    – blah238
    Commented Oct 9, 2013 at 3:20

1 Answer 1

2

You're adding a layer "FC" to your map which should be "FL" or "LAN". Either the feature layer or the layer should work.

Be aware that the map may be in data view instead of layout view in which case pMxDoc.PageLayout is incorrect... I can't tell what pLayout is as it's not defined in the code block.

It would be safer to use IMXDocument.FocusMap as this could be either of type layout or data view.

assuming pApp is IApplication:

IMxDocument pDoc = (IMxDocument) pApp.Document;
IMap pMap = pDoc.FocusMap;
pMap.AddLayer(LAN);

OR

(pApp.Document as IMxDocument).FocusMap.AddLayer(LAN);

I usually do it on the three lines so it's not so confusing for the reader.

  • oops! that was C#, my bad! The VB isn't too hard to work out from here as you're already up to the pMap = pMxDoc.FocusMap.

p.s. I personally prefer to dim my objects, it makes it easier to work out what's happening:

dim pMxDoc as IMxDocument = ctype(pApp.Document, IMxDocument)
dim pMap as IMap = pMxDoc.FocusMap

That way the reader knows for a certainty what each object is.

2
  • Besides this question being over a year and a half old, it is in Python + comtypes, not C# or VB.NET. And I think the FC thing was probably just a typo in the question rather than the actual code, as there would have been a NameError instead.
    – blah238
    Commented Oct 9, 2013 at 2:45
  • 3
    I didn't look at how old the thread was, that's not important to the next reader that finds there way here from google just like I have many times... so many times I felt I should join. A question is a question and for the next readers sake I felt I should point out the obvious error. Commented Oct 9, 2013 at 3:06

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.