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– Vince2015年12月07日 19:34:10 +00:00Commented Dec 7, 2015 at 19:34
4 Answers 4
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.
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– GeoStoneMarten2015年12月08日 10:16:26 +00:00Commented 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.Alex– Alex2015年12月08日 12:00:36 +00:00Commented Dec 8, 2015 at 12:00
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– Alex2015年12月08日 07:15:29 +00:00Commented 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)GeoStoneMarten– GeoStoneMarten2015年12月14日 13:14:39 +00:00Commented Dec 14, 2015 at 13:14
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.