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

Hornbydd
44.9k5 gold badges43 silver badges84 bronze badges
asked Dec 7, 2015 at 19:22
1
  • Please edit the Question to clearly state your question (ending in a question mark) Commented Dec 7, 2015 at 19:34

4 Answers 4

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.

answered Nov 10, 2017 at 3:35
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" )
answered Dec 7, 2015 at 21:23
2
  • @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. Commented Dec 8, 2015 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. Commented Dec 8, 2015 at 12:00
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
answered Dec 7, 2015 at 20:54
2
  • 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? Commented Dec 8, 2015 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) Commented Dec 14, 2015 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.

answered Mar 28, 2019 at 14:00

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.