1

GetOpenFilename doesn't work in arcobjects VBA, so I have to use pGxDialog.

Standard pGxDialog doesn't let to open any file I want, a few extentions are available only (shp, dxf, xls...).

Maybe, I just don't know how to set a Filter.

I don't need to open extra extension files for reading/writing, I just need to return the PATH of the document to a variable, which will be used later on in the code.

I scripting in VBA, arcgis 10.2.2

  • Please edit the Question to clearly state your question (ending in a question mark) – Vince Dec 7 '15 at 19:34
1

You can call directly COM object dll

Private Declare Function GetOpenFileName Lib "comdlg32.dll" Alias "GetOpenFileNameA" (pOpenfilename As OPENFILENAME) As Long

Private Type OPENFILENAME
  lStructSize As Long
  hwndOwner As Long
  hInstance As Long
  lpstrFilter As String
  lpstrCustomFilter As String
  nMaxCustFilter As Long
  nFilterIndex As Long
  lpstrFile As String
  nMaxFile As Long
  lpstrFileTitle As String
  nMaxFileTitle As Long
  lpstrInitialDir As String
  lpstrTitle As String
  flags As Long
  nFileOffset As Integer
  nFileExtension As Integer
  lpstrDefExt As String
  lCustData As Long
  lpfnHook As Long
  lpTemplateName As String
End Type

Function f_OpenFileName(Titre As String) As String
'Function for select file
Dim OpenFile As OPENFILENAME
Dim lReturn As Long
Dim sFilter As String

OpenFile.lStructSize = Len(OpenFile)

'Filter
sFilter = "prj" & Chr(0) & "*.prj" & Chr(0) & Chr(0)
OpenFile.lpstrFilter = sFilter
OpenFile.nFilterIndex = 1
OpenFile.lpstrFile = String(257, 0)
OpenFile.nMaxFile = Len(OpenFile.lpstrFile) - 1
OpenFile.lpstrFileTitle = OpenFile.lpstrFile
OpenFile.nMaxFileTitle = OpenFile.nMaxFile

' default path
OpenFile.lpstrInitialDir = "c:\"

'Title
OpenFile.lpstrTitle = Titre
OpenFile.flags = 0
lReturn = GetOpenFileName(OpenFile)

If lReturn = 0 Then
  'message
  f_OpenFileName = 0
Else
  f_OpenFileName = Trim(OpenFile.lpstrFile)
End If
End Function

use function:

Dim txtSelectFile As String
path = f_OpenFileName( "Select a file" )
  • @Alex for your information, all vba code exist in Arcgis v9. You can import dll as reference or call as previous method. In addition VBA is depreciated and will disappear. I suggest you to migrate your code to VB.NET solution or start new development with python. – GeoStoneMarten Dec 8 '15 at 10:16
  • thanks for information. I heard about VBA disappearing. I'm intending to learn how to make add-ins in VisualStudio in vb.net. I think it's a good idea and hope this way of arcGIS developing won't disappear too. – Alex Dec 8 '15 at 12:00
2

This is substantially the work of Radar in an answer to a similar question, using the same ArcObjects as Hornbydd does.

I have modified Radar's function for my clients to select a delimited text file then this function returns both the path to the selected file and the file name. This fulfills Alex's request for "...return the PATH of the document to a variable"

I trimmed it down a little so it uses just core ArcObjects libraries.

Public Function BrowseForTextFile(ByVal sTitle As String, ByRef sFolder As String, ByRef sName As String) As Boolean
    'Source: Radar https://gis.stackexchange.com/questions/9000/opening-geodatabase-files-using-browse-dialog-command-vb-net-c-of-arcobjects
    Dim pGxDialog As IGxDialog = New GxDialog
    Dim pGxObjectFilter As IGxObjectFilter = New ESRI.ArcGIS.Catalog.GxFilterTextFiles()

    Dim pFilterCol As IGxObjectFilterCollection
    Dim pEnumGx As IEnumGxObject
    Dim pGxObject As IGxObject

    sFolder = ""
    sName = ""

    pFilterCol = pGxDialog
    pFilterCol.AddFilter(pGxObjectFilter, True)
    pGxDialog.RememberLocation = True
    pGxDialog.AllowMultiSelect = False
    pGxDialog.Title = sTitle


    If pGxDialog.DoModalOpen(0, pEnumGx) Then
        pGxObject = pEnumGx.Next
        sName = pGxObject.Name
        sFolder = pGxObject.Parent.FullName

        Return True
    End If

End Function

You can call this with

Imports ESRI.ArcGIS.Catalog     'for IGxObjectFilter
Imports ESRI.ArcGIS.CatalogUI   'for IGXdialog

Friend m_sFilePathName As String
'...snipped
Dim sCSVPath As String
Dim sCSVName As String
If BrowseForTextFile("Choose a text file to load", sCSVPath, sCSVName) Then
     m_sFilePathName = sCSVPath & "\" & sCSVName
     MsgBox("The file you chose was " & m_sFilePathName,MsgBoxStyle.Information, "Result")
Else
    'Nothing chosen, Abort
     Exit Sub
End If

In this case I all I want shown in the dialog is delimited text files, so I use 'GxObjectFilter' of 'GxFilterTextFiles'. You could specify 'GxFilterFiles' if you just want to be able to select "any file"

There are also scores upon scores of coclasses and classes for every object in ArcCatalog if you need to filter the browser dialog to another type. For example you could use 'GxFilterMaps' to target .mxd documents or 'GxFilterFileGeodatabases' to specify FGDBs. You can be even more specific, for example to only choose feature classes within file geodatabases if that's what you need to do.

1

Below is the code you require:

Public Sub OpenDataset()
    ' Open a dialog for user to select FeatureClasses
    Dim pEnumGXObject As IEnumGxObject
    Set pEnumGXObject = Nothing
    Dim pGxDialog As IGxDialog
    Dim pGXObjectFilter As IGxObjectFilter
    Set pGXObjectFilter = New GxFilterFeatureClasses
    Set pGxDialog = New GxDialog
    With pGxDialog
        .AllowMultiSelect = False
        .Title = "Select a file"
        .ButtonCaption = "Select"
        Set .ObjectFilter = pGXObjectFilter
        .DoModalOpen 0, pEnumGXObject
    End With
    pEnumGXObject.Reset
    Dim pGxobject As IGxObject
    Set pGxobject = pEnumGXObject.Next
    MsgBox pGxobject.FullName
End Sub
  • thanks a lot for your help, and sorry for my english. This code doesn't solve the problem - "standard pGxDialog doesn't let to open any file I want". How to set the ObjectFilter to show another file type except for shp, dxf, xls? – Alex Dec 8 '15 at 7:15
  • 2
    @Alex for that it's necessary to declare your file extention in ArcCatalog because this is an object of ArcObjects Library Reference (Catalog) – GeoStoneMarten Dec 14 '15 at 13:14
0

I know the question was specifically for VBA, and is a little dated, but since I found this question in a search for a solution to my similar situation, using c#.net, I will post the solution I found.

Firstly, to open any extension not already provided by Catalog, you must define your own custom GX filter class. Below, I create a filter for XML extensions.

public class GxCustomFilter : ESRI.ArcGIS.Catalog.IGxObjectFilter {
    private IGxObjectFilter _basicFilter;

    public GxCustomFilter(){
        _basicFilter = new GxFilterBasicTypesClass();
    }
    public bool CanChooseObject(ESRI.ArcGIS.Catalog.IGxObject obj, ref ESRI.ArcGIS.Catalog.esriDoubleClickResult result) {
        //Set whether the selected object can be chosen
        bool bCanChoose = false;
        bCanChoose = false;
        if (obj is IGxFile) {
            string sExt = null;
            sExt = GetExtension(obj.Name);
            if (sExt.ToLower() == ".xml") // define your extension here
                bCanChoose = true;
        }
        return bCanChoose;
    }
    public bool CanDisplayObject(ESRI.ArcGIS.Catalog.IGxObject obj) {
        //Check if objects can be displayed
        try {
            //Check objects can be displayed
            if (_basicFilter.CanDisplayObject(obj))
                return true;
            else if (obj is IGxFile) {
                string sExt = null;
                sExt = GetExtension(obj.Name);
                if (sExt.ToLower() == ".xml") // define your extension here
                    return true;
            }

        } catch (Exception ex) {
            System.Windows.Forms.MessageBox.Show(ex.ToString());
        }
        return false;
    }
    public bool CanSaveObject(ESRI.ArcGIS.Catalog.IGxObject Location, string newObjectName, ref bool objectAlreadyExists) {
        return false;
    }
    public string Description {
        get {
            //Set filet description
            return "eXtensible Markup Language (.xml)";
        }
    }
    public string Name {
        get {
            //Set filter name
            return "XML filter";
        }
    }
    private string GetExtension(string sFileName) {
        string tempGetExtension = null;
        //Get extension
        long pExtPos = 0;
        pExtPos = (sFileName.LastIndexOf(".") + 1);
        if (pExtPos > 0)
            tempGetExtension = sFileName.Substring((Int32)pExtPos - 1);
        else
            tempGetExtension = "";
        return tempGetExtension;
    }
}

Then, in your GxDialog, you use the custom class to define a ObjectFilter. You also have to define file filters on the GxDialog.InternalCatalog.

IGxDialog gxDialog = new GxDialog();
IGxCatalog gxCat = gxDialog.InternalCatalog;
IGxFileFilter fileFilter = gxCat.FileFilter;
if (fileFilter.FindFileType("XML") < 0) {
    fileFilter.AddFileType("XML", "eXtensible Markup Language ", "");
}
IGxObjectFilter objFilter = new GxCustomFilter();
gxDialog.ObjectFilter = objFilter;

If you wish to use the filter with a GxDialog.DoModalSave(), you must modify the custom filter class property CanSaveObject to return true.

I hope this helps someone, as I spent longer than I would have liked figuring it out.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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