2010-06-10 34 views
0

J'ai récemment trouvé un script d'ArcScripts sur la façon d'obtenir une table Access dans ArcGIS par programmation et cela fonctionne bien. Mais c'est pour Access 2003 (extension .mdb) et plus tôt. Le code est posté ci-dessous, et je veux savoir comment le modifier pour utiliser Access 2007 (extension .accdb) et les bases de données plus récentes.Obtention d'une table Access 2007 (extension .accdb) dans ArcMap par programme

Attribute VB_Name = "Access_connect" 
Sub Open_Access_Connect() 
    'V. Guissard Jan. 2007 

    On Error GoTo EH 

    Dim data_source As String 
    Dim pTable As ITable 
    Dim TableName As String 

    Dim pFeatWorkspace As IFeatureWorkspace 
    Dim pMap As IMap 
    Dim mxDoc As IMxDocument 
    Dim pPropset As IPropertySet 
    Dim pStTab As IStandaloneTable 
    Dim pStTabColl As IStandaloneTableCollection 
    Dim pWorkspace As IWorkspace 
    Dim pWorkspaceFact As IWorkspaceFactory 


    Set pPropset = New PropertySet 
    ' Get MDB file name 
    data_source = GetFolder("mdb") 
    ' Connect to the MDB database 
    pPropset.SetProperty "CONNECTSTRING", "Provider=Microsoft.Jet.OLEDB.4.0;" _ 
    & "Data source=" & data_source & ";User ID=Admin;Password=" 

    Set pWorkspaceFact = New OLEDBWorkspaceFactory 
    Set pWorkspace = pWorkspaceFact.Open(pPropset, 0) 
    Set pFeatWorkspace = pWorkspace 

    ' Get table name 
    TableName = SelectDataSet(pFeatWorkspace, "Table") 
    ' Open the table 
    Set pTable = pFeatWorkspace.OpenTable(TableName) 
    'Create Table collection and add the table to ArcMap 
    Set mxDoc = ThisDocument 
    Set pMap = mxDoc.FocusMap 
    Set pStTab = New StandaloneTable 
    Set pStTab.Table = pTable 
    Set pStTabColl = pMap 
    pStTabColl.AddStandaloneTable pStTab 

    ' Update ArcMap Source TOC 
    mxDoc.UpdateContents 

    Exit Sub 

EH: 

    MsgBox "Access connect: " & Err.Number & " " & Err.Description 

End Sub 

Public Function GetFolder(Optional aFilter As String) As String 
    ' Open a GUI to let the user select a Folder path name (by default) or : 
    ' Set aFilter = "shp" to get a shapefile name 
    ' Set aFilter = "mdb" to get an MS Access file name 
    ' Return the Folder Path or phath & file name As String 
    ' V. Guissard Jan. 2007 

    Dim pGxDialog As IGxDialog 
    Dim pFilterCol As IGxObjectFilterCollection 
    Dim pCurrentFilter As IGxObjectFilter 
    Dim pEnumGx As IEnumGxObject 

    Select Case aFilter 
    Case "shp" 
     Set pCurrentFilter = New GxFilterShapefiles 
     aTitle = "Select Shapefile" 
    Case "mdb" 
     Set pCurrentFilter = New GxFilterContainers 
     aTitle = "Select MS Access database" 
    Case Else 
     Set pCurrentFilter = New GxFilterBasicTypes 
     aTitle = "Select Folder" 
    End Select 

    Set pGxDialog = New GxDialog 
    Set pFilterCol = pGxDialog 
    With pFilterCol 
    .AddFilter pCurrentFilter, True 
    End With 
    With pGxDialog 
    .Title = aTitle 
    .ButtonCaption = "Select" 
    End With 

    If Not pGxDialog.DoModalOpen(0, pEnumGx) Then 
    Smp = MsgBox("No selection : Exit", vbCritical) 
    End 
    'Exit Function 'Exit if user press Cancel 
    End If 
    GetFolder = pEnumGx.Next.FullName 

End Function 

Public Function SelectDataSet(pWorkspace As IWorkspace, Optional theDataType As String) As String 
    ' Open a GUI to let the user select a DataSet into a Workspace 
    ' (Table or Request into an MS Access Database or a Geodatabase File) 
    ' Set pWorkspace to the DataSet IWorkspace 
    ' Set theDataType = "Table" to select a Table name of the DataSet 
    ' Return the selected Table or Request Table name As String 
    ' V. Guissard Jan. 2007 

    Dim aDataset As Boolean 
    Dim boolOK As Boolean 
    Dim DataSetList As New Collection 
    Dim datasetType As Integer 
    Dim n As Integer 

    Dim pDataSetName As IDatasetName 
    Dim pListDlg As IListDialog 
    Dim pEnumDatasetName As IEnumDatasetName 

    ' Set the Dataset Type 
    Select Case theDataType 
    Case "Table" 
     datasetType = 10 
    Case Else 
     Answ = MsgBox("Need a Dataset Type : Exit", vbCritical, "SelectDataset") 
     End 
    End Select 

    ' Get the Dataset Names included in the workspace 
    Set pEnumDatasetName = pWorkspace.DatasetNames(datasetType) 

    ' Create the Dataset Names List Dialog 
    aDataset = False 
    Set pListDlg = New ListDialog 
    pEnumDatasetName.Reset 
    Set pDataSetName = pEnumDatasetName.Next 
    Do While Not pDataSetName Is Nothing 

     pListDlg.AddString pDataSetName.name 
     DataSetList.Add (pDataSetName.name) 
     Set pDataSetName = pEnumDatasetName.Next 
     aDataset = True 
    Loop 

    ' Open a GUI for the user to select a dataset 
    If aDataset Then 
    boolOK = pListDlg.DoModal("Select a " & theDataType, 0, Application.hwnd) 
    n = pListDlg.choice 
    If (n <> -1) Then 
     SelectDataSet = DataSetList(n + 1) 
    Else 
     Sup = MsgBox("No DataSet selected : EXIT", vbCritical, "SelectDataset") 
     End 
    End If 
    End If 
End Function 

Voici le lien vers le ArcScript: http://arcscripts.esri.com/Data/AS14882.bas

PS Je sais que ce code est écrit en VBA et je ne sais pas si une version modifiée est en VB.NET ou quelle que soit la langue d'autre.

Merci, Adrian

Répondre

0

Lorsque vous essayez de comprendre les propriétés de connexion pour ArcObjects , Je trouve cela utile o configurer une connexion OleDB dans arccatalog en utilisant l'interface graphique. Une fois les tests réussis, je lance ensuite ce script VBA pour répertorier les propriétés de connexion, que je peux ensuite copier et coller dans mon code.

Sub ListConnProps() 
    Dim pGxApp As IGxApplication 
    Set pGxApp = Application 
    If Not TypeOf pGxApp.SelectedObject Is IGxDatabase Then 
     Debug.Print "select a geodb first" 
     Exit Sub 
    End If 
    Dim pGXdb As IGxDatabase2 
    Set pGXdb = pGxApp.SelectedObject 
    Dim names As Variant, values As Variant 
    Debug.Print pGXdb.WorkspaceName.WorkspaceFactoryProgID 
    pGXdb.WorkspaceName.ConnectionProperties.GetAllProperties names, values 
    Dim l As Long 
    For l = 0 To UBound(names) 
     Debug.Print names(l), values(l) 
    Next l 

End Sub 

Mise à jour: est ici un code que je l'ai testé avec succès après avoir téléchargé le fournisseur de here, et un fichier accdb de test à partir here. Je n'utilisais pas de mot de passe, donc je n'ai pas pu le tester.

public static void TestOleDB() 
{ 
    IWorkspaceFactory wsf = new OLEDBWorkspaceFactoryClass(); 
    IPropertySet ps = new PropertySetClass(); 
    string connStr = "Provider=Microsoft.ACE.OLEDB.12.0;" 
     + @"Data Source=D:\Projects\AmberGIS\Forums\MikeGarage\MikeGarage.accdb;" 
     + "Persist Security Info=False"; 

    // if you're using a password, use next line (??) 
    //((IOleDBConnectionInfo)wsf).SetParameters(connStr, ""); 
    ps.SetProperty("CONNECTSTRING", connStr); 
    IWorkspace ws = wsf.Open(ps, 0); 
    IEnumDatasetName enumDsn = ws.get_DatasetNames(esriDatasetType.esriDTAny); 
    IDatasetName dsn; 
    while((dsn=enumDsn.Next())!= null) 
     Debug.Print(dsn.Name); 

} 
+0

Remou, je voulais écrire plus tôt que j'avais essayé cela et il est venu avec une erreur. Kirk, j'ai couru ce code et c'est bien comme ça donne la chaîne de connexion mais j'ai eu la même erreur quand je l'ai mis dans mon code existant. L'erreur que j'ai eue était "5 appel ou argument de procédure invalide". Y a-t-il quelque chose d'autre qui me manque? Ou s'agit-il d'un problème qui ne peut pas être géré correctement, car c'est accdb qui ne fonctionne pas directement avec ArcGIS? Merci – Adrian

+0

Alors que ESRI ne prend pas en charge les fichiers .accdb pour les géodatabases de la même manière qu'ils prennent en charge les fichiers .mdb, ils prennent en charge OleDB. Pouvez-vous voir les tables via votre connexion oleDB dans arccatalog? Vous pouvez également essayer d'appeler IOleDBConnectionInfo.SetParameters sur workspacefactory avant d'appeler open avec votre propertyset. –

+0

Oui, je peux les voir dans ArcCatalog et les importer dans ArcGIS. J'ai essayé de jouer avec l'interface IOleDBConnectionInfo mais j'ai eu les mêmes erreurs. Y at-il quelque chose d'autre qui me manque en raison du fait que c'est l'accdb? Ou pouvez-vous donner un exemple de ce que tous doivent intégrer dans des arcobjects afin d'obtenir ces tables par programmation? Comme ce que je veux dire, quelles variables et interfaces ai-je besoin de lier ensemble (de IOleDBConnectionInfo à quoi?) Merci! – Adrian

0

La chaîne de connexion pour Access 2007 est

Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\myFolder\myAccess2007file.accdb;Persist Security Info=False; 

Alors

pPropset.SetProperty "CONNECTSTRING", "Provider=Microsoft.ACE.OLEDB.12.0;" _ 
& "Data source=" & data_source & ";User ID=Admin;Password=" 

-http://www.connectionstrings.com/access-2007

+0

Notez que OLEDB ne peut pas gérer un mot de passe de base de données, mais ODBC peut. –