I have an Access file which I will be using for quality assurance of data.
I will be inputting data from three Excel files, each into its own Access table.
At present, I have three buttons and corresponding text boxes. I manually enter the file path and name into the text box, click the button and it completes the rest of my macro, importing the data.
I'd like to use the file picker dialog box to populate the textbox with the path.
This code and worked for me:
Private Sub Comando32_Click()
Dim f As Object
Dim strFile As String
Dim strFolder As String
Dim varItem As Variant
Set f = Application.FileDialog(3)
f.AllowMultiSelect = False
If f.Show Then
For Each varItem In f.SelectedItems
strFile = Dir(varItem)
strFolder = Left(varItem, Len(varItem) - Len(strFile))
MsgBox "Folder: " & strFolder & vbCrLf & _
"File: " & strFile
Me.certidao.Value = varItem
Next
End If
Set f = Nothing
End Sub
Of course, it is possible to call the file Dialog API in VBA!
An example direct from Microsoft VBA documentation:
Private Sub cmdFileDialog_Click()
' Requires reference to Microsoft Office XY.0 Object Library.
Dim fDialog As Office.FileDialog
Dim varFile As Variant
' Clear listbox contents.
Me.FileList.RowSource = ""
' Set up the File Dialog.
Set fDialog = Application.FileDialog(msoFileDialogFilePicker)
With fDialog
' Allow user to make multiple selections in dialog box
.AllowMultiSelect = True
' Set the title of the dialog box.
.Title = "Please select one or more files"
' Clear out the current filters, and add our own.
.Filters.Clear
.Filters.Add "Access Databases", "*.MDB"
.Filters.Add "Access Projects", "*.ADP"
.Filters.Add "All Files", "*.*"
' Show the dialog box. If the .Show method returns True, the
' user picked at least one file. If the .Show method returns
' False, the user clicked Cancel.
If .Show = True Then
'Loop through each file selected and add it to our list box.
For Each varFile In .SelectedItems
Me.FileList.AddItem varFile
Next
Else
MsgBox "You clicked Cancel in the file dialog box."
End If
End With
End Sub
Please note you have to include a reference to Microsoft Office 11.0 Library
(in code window, select menu option Tools, Reference and select your library for the correct version of your Office Version)
Thanks for the response.
I did google it first and tried everything I came across. I also came across the very set of code pasted above. I Played around with it for a while and whatever I did returned errors. I decided to try the code in Excel instead of Access and it worked straight away. The only thing I could think was that the code wasn't applicable to access. Following all of that I asked the question here.
Private Sub cmdDialog_Click()
Dim fDialog As Office.FileDialog
Dim varFile As Variant
Me.txtFileSelect.RowSource = ""
Set fDialog = Application.FileDialog(msoFileDialogFilePicker)
With fDialog
.AllowMultiSelect = False
.Title = "Please select one or more files"
.Filters.Clear
.Filters.Add "Excel Files", "*.XLSX"
.Filters.Add "All Files", "*.*"
If .Show = True Then
For Each varFile In .SelectedItems
Me.txtFileSelect.AddItem varFile
Next
Else
MsgBox "You clicked Cancel in the file dialog box."
End If
End With
End Sub
With this code I get:
Compile error;
User-defined type not identified
Try this code, for single file:
MyFileURL = aBrowseForFile("C:\users\")
Public Function aBrowseForFile(aStartFolder As String) As String
' Needs a reference to Microsoft Office Object Library 15.0
On Error GoTo Err_txtBrowseForFile
Dim fDialog As Office.FileDialog
Dim varfile As Variant
Dim strPath As String
Dim strFilter As String, strFileName As String
Dim Main_Dir As String, DefFolder As String
Set fDialog = Application.FileDialog(msoFileDialogFilePicker)
With fDialog
.InitialView = msoFileDialogViewThumbnail
.AllowMultiSelect = False
.Title = "Please select one or more files"
.InitialFileName = aStartFolder
.InitialView = msoFileDialogViewThumbnail
.Filters.Clear
.Filters.Add "all files", "*.*"
' Show the dialog box. If the .Show method returns True, the
' user picked at least one file. If the .Show method returns
' False, the user clicked Cancel.
If .Show = True Then
aBrowseForFile = .SelectedItems(1)
Else
'MsgBox "You clicked Cancel in the file dialog box."
End If
End With
Exit_txtBrowseForFile:
Exit Function
Err_txtBrowseForFile:
MsgBox Err.Description, vbCritical, "MyApp"
Resume Exit_txtBrowseForFile
End Function
Put this function in a module, as it is.
Do not put some other code inside, so you can call it in other projects and build your own tools set.
Call it as shown above in your form.
This code runs well and it is tested.
If you want to check this code, in the debug window type
debug.print aBrowseForFile("C:\users\")
and see what happens. If you have other run-time or compile errors, please post another question.
Hope this helps
Thanks for the response.
I solved the problem in the end, I hadn't selected the object database. I found the following code to work:
Private Sub cmdInput_Click()
Dim fDialog As Office.FileDialog
Dim varFile As Variant
Set fDialog = Application.FileDialog(msoFileDialogFilePicker)
With fDialog
.AllowMultiSelect = False
.Title = "Please select a file"
.Filters.Clear
.Filters.Add "Excel Files", "*.XLSX"
.Filters.Add "All Files", "*.*"
If .Show = True Then
For Each varFile In .SelectedItems
DoCmd.TransferSpreadsheet acImport, 10, "InputData", varFile, True, ""
Beep
MsgBox "Import Complete!", vbExclamation, ""
Next
Else
MsgBox "You clicked Cancel in the file dialog box."
End If
End With
End Sub
Related
I want to browse/select a database file through an Access form and run a query on it based on the file path of the selected database file. I have tried like this:
SELECT *
FROM ExternalTableName IN '[Forms]![MyForm]![SelectedFilePath]'
WHERE Condition
...but that didn't work however this SQL did work:
SELECT *
FROM ExternalTableName IN 'C:\users\desktop\filename.mdb'
WHERE Condition
For browsing the file, I used this VBA snippet:
Private Sub cmd1()
Dim fd As FileDialog
Dim oFD As Variant
Dim fileName As String
Set fd = Application.FileDialog(msoFileDialogFilePicker)
With fd
.ButtonName = "Select"
.AllowMultiSelect = False
.Filters.Add "Access Files", "*.mdb", 1
.Title = "Choose Text File"
.InitialView = msoFileDialogViewDetails
.Show
For Each oFD In .SelectedItems
fileName = oFD
Next oFD
On Error GoTo 0
End With
'~~> Change this to the relevant TextBox
Me.TextFieldName = fileName
Set fd = Nothing
End Sub
Edit:
To query a table located in an MDB that the user selects from a File Open dialog, the simplest way (while avoiding additional References) is like this:
Option Explicit
Sub testQueryExternalTable()
'displays RecordCount from specified table, selected database
Const tableName = "tblLog"
Const defaultPath = "c:\users\" 'default path OR path+filename
Dim rs As Recordset, fName As String, sql as String
fName = getFileOpenDialog(defaultPath) 'get filename
If fName = "" Then MsgBox "You clicked cancel!": Exit Sub
sql = "select * from " & tableName & " in '" & fName & "'"
Set rs = CurrentDb.OpenRecordset( sql ) 'query the table
With rs
.MoveLast 'count records
MsgBox .RecordCount & " records found"
.Close 'close recordset
End With
Set rs = Nothing 'always clean up objects when finished
End Sub
Function getFileOpenDialog(defaultPath As String) As String
'returns filename selected from dialog ("" if user Cancels)
With Application.FileDialog(3)
.Title = "Please select a database to query" 'set caption
.InitialFileName = defaultPath 'default path OR path+filename
.AllowMultiSelect = False 'maximum one selection
.Filters.Clear 'set file filters for drop down
.Filters.Add "All Files", "*.*" '(in reverse order)
.Filters.Add "Access Databases", "*.mdb" '(last = default filter)
If .Show = True Then getFileOpenDialog = .SelectedItems(1) 'show dialog
End With
End Function
More Information:
MSDN : Application.FileDialog Property (Access)
MSDN : FileDialog.InitialFileName Property
MSDN : Accessing External Data with MS Access
MSDN : Database.OpenRecordset Method (DAO)
Original Answer:
It's easier (and more efficient) to use Access's built-in functionality rather than recreating it in VBA.
(Click to enlarge images)
The first option imports, and the seconds option emphasized textlinks without importing. Once the table is linked you can work with it in VBA or queries as if it's a local table.
I have built a form where a user can select one or more files and import them into a single table. When the user selects the file, or yet, multiple files, once the import is complete, I want the file name to be added on each row, of course, related to the correct file.
I am able to setup a query to manually add the filename, but how would I be able to do this in a more automated fashion. For example, if the user selects a file how can I code the SQL query to automatically detect the filename and add it? If the user selects more than one file, how can the query write the correct filename for each row?
Here is my form code:
Option Compare Database
'Private Sub Command0_Click()
Private Sub cmdFileDialog_Click()
'Requires reference to Microsoft Office 12.0 Object Library.
Dim fDialog As Office.FileDialog
Dim varFile As Variant
'Clear listbox contents.
'Me.FileList.RowSource = ""
'Set up the File Dialog.
Set fDialog = Application.FileDialog(msoFileDialogFilePicker)
With fDialog
'Allow user to make multiple selections in dialog box.
.AllowMultiSelect = True
'Set the title of the dialog box.
.Title = "Please select one or more files"
.InitialFileName = "C:\Users\ABCCCCC\Desktop\January CMS reports for CCCCC"
'Clear out the current filters, and add our own.
.Filters.Clear
'.Filters.Add "Access Databases", "*.MDB; *.ACCDB"
.Filters.Add "Access Projects", "*.txt"
'.Filters.Add "All Files", "*.*"
'Show the dialog box. If the .Show method returns True, the
'user picked at least one file. If the .Show method returns
'False, the user clicked Cancel.
If .Show = True Then
'Loop through each file selected and add it to the list box.
For Each varFile In .SelectedItems
' Me.FileList.AddItem varFile
Call InsertCMS_Reports_2ndSave(varFile)
Next
Else
MsgBox "You clicked Cancel in the file dialog box."
End If
End With
End Sub
Module Code:
Function InsertCMS_Reports_2ndSave(FileName As Variant)
'DoCmd.DeleteObject CopyOfCOMPRPT_CE, "CMS_Reports_2ndSave"
DoCmd.TransferText acImportFixed, "CMS_Reports_Import", _
"CMS_Reports_Import", "C:\Users\ABCCCCC\Desktop\January CMS reports for CCCCC\FileName"
CurrentDb.Execute "UPDATE CopyOfCOMPRPT_CE SET FileName = 'HLTH_COMPRPT_1701011028174_h0062.txt' WHERE FileName is NULL", dbFailOnError
End Function
Provided the code you provided is already working, then this should work for you.
CurrentDb.Execute "UPDATE CopyOfCOMPRPT_CE SET FileName = '" & FileName & "' WHERE FileName is NULL", dbFailOnError
If you have issues, it's most likely a syntax issue with the sql string and quotation marks will be the most likely culprit. If you have problems, put a debug statement in your code so you can see what sql statement is getting generated. For instance:
Function InsertCMS_Reports_2ndSave(FileName As Variant)
Dim strSQL as String
'DoCmd.DeleteObject CopyOfCOMPRPT_CE, "CMS_Reports_2ndSave"
DoCmd.TransferText acImportFixed, "CMS_Reports_Import", _
"CMS_Reports_Import", "C:\Users\ABCCCCC\Desktop\January CMS reports for CCCCC\FileName"
strSQL = "UPDATE CopyOfCOMPRPT_CE SET FileName = '" & FileName & "' WHERE FileName is NULL", dbFailOnError"
debug.print strSQL
CurrentDb.Execute strSQL, dbFailOnError
End Function
I am receiving a ByRef argument type mismatch. The following code (varFile specificaly) is highlighted for the error:
Call InsertCMS_Reports_2ndSave(varFile)
Here is my form:
Option Compare Database
'Private Sub Command0_Click()
Private Sub cmdFileDialog_Click()
'Requires reference to Microsoft Office 12.0 Object Library.
Dim fDialog As Office.FileDialog
Dim varFile As Variant
'Clear listbox contents.
'Me.FileList.RowSource = ""
'Set up the File Dialog.
Set fDialog = Application.FileDialog(msoFileDialogFilePicker)
With fDialog
'Allow user to make multiple selections in dialog box.
.AllowMultiSelect = True
'Set the title of the dialog box.
.Title = "Please select one or more files"
.InitialFileName = "C:\Users\ABCDEF\Desktop\CCCEEe CMS Reports"
'Clear out the current filters, and add our own.
.Filters.Clear
'.Filters.Add "Access Databases", "*.MDB; *.ACCDB"
.Filters.Add "Access Projects", "*.txt"
'.Filters.Add "All Files", "*.*"
'Show the dialog box. If the .Show method returns True, the
'user picked at least one file. If the .Show method returns
'False, the user clicked Cancel.
If .Show = True Then
'Loop through each file selected and add it to the list box.
For Each varFile In .SelectedItems
' Me.FileList.AddItem varFile
Call InsertCMS_Reports_2ndSave(varFile)
Next
Else
MsgBox "You clicked Cancel in the file dialog box."
End If
End With
End Sub
Module Code:
Function InsertCMS_Reports_2ndSave(FileName As String)
'DoCmd.DeleteObject CopyOfCOMPRPT_CE, "CMS_Reports_2ndSave"
DoCmd.TransferText acImportFixed, "CMS_Reports_Import", _
"CMS_Reports_Import", "C:\Users\A088982\Desktop\January CMS reports for Centene\FileName"
CurrentDb.Execute "UPDATE CopyOfCOMPRPT_CE SET FileName = 'HLTH_COMPRPT_1701011028174_h0062.txt' WHERE FileName is NULL", dbFailOnError
End Function
The reason you're receiving this error is because you've dimensioned varFile as a variant, however your function is expecting a string. Try this instead:
Function InsertCMS_Reports_2ndSave(FileName)
I am using FileDialog code for importing Excel table(s) into Access 2013-32 bit that works exactly like I want. When I use the code in Access 2016 I get an error in code that says "Can't find project of library". I have checked my references and they appear to be the same.
Here is my code:
Private Sub Command2_Click()
Dim JobName As String
Dim f As FileDialog
Dim tblImport As String
Dim varfile As Variant
Dim MyJobs As DAO.Recordset
JobName = lbl1.value
DoCmd.Close
Set f = Application.FileDialog(msoFileDialogFilePicker)
With f
.Title = "Choose Excel File(s) to Import"
.Filters.Clear
.Filters.Add "Excel Files", "*.xlsx"
.AllowMultiSelect = True
If f.Show = True Then
For Each varfile In .SelectedItems
Msgbox "IMPORTING: " & varfile
tblImport = varfile
DoCmd.TransferSpreadsheet acImport, 10, "Parts", tblImport, True
Next varfile
'Add Job Name to Parts Table
TempVars("jobName") = JobName
DoCmd.OpenQuery "Update Job Name"
'Add Job Name to Jobs Table
Set MyJobs = CurrentDb.OpenRecordset("Jobs")
MyJobs.AddNew
MyJobs![JobName] = JobName
MyJobs.Update
Set f = Nothing
Else
Msgbox "You Cancelled."
End If
End With
End Sub
How do I change my code to get the file name instead of the directory name? openDialog.InitialFilename gives me the directory name.
openDialog.FileName gives me the error "Method or data member not found".
Private Sub btnEditPhoto_Click()
If (txtImageName > "") Then
Application.FollowHyperlink txtImageName
Else
Dim openDialog As Office.FileDialog
Set openDialog = Application.FileDialog(msoFileDialogFilePicker)
openDialog.Filters.Clear
openDialog.Filters.Add "JPEG Files", "*.jpg"
Dim pickedFile As Boolean
pickedFile = openDialog.Show
If pickedFile Then
txtImageName.SetFocus
txtImageName.Text = openDialog.InitialFileName
End If
End If
End Sub
You want:
OpenDialog.SelectedItems.Item(1)
In place of:
OpenDialog.InitialFileName
As you have not allowed multiselect.
So:
''Reference Microsoft Office x.x Object Library
Dim openDialog As Office.FileDialog
Set openDialog = Application.FileDialog(msoFileDialogFilePicker)
openDialog.Filters.Clear
openDialog.Filters.Add "JPEG Files", "*.jpg"
If openDialog.Show Then
''SelectedItems is not zero based
''Do not use .Text property in MS Access except
''in special cases, then you will not have to set focus
''txtImageName.SetFocus
txtImageName = openDialog.SelectedItems(1)
End If
If AllowMultiSelect is used, you need to iterate through SelectedItems
''Reference Microsoft Office x.x Object Library
Dim openDialog As Office.FileDialog
Dim i As Integer
Set openDialog = Application.FileDialog(msoFileDialogFilePicker)
'Use ctl or shift + click to select more than one file
openDialog.AllowMultiSelect = True
openDialog.Filters.Clear
openDialog.Filters.Add "JPEG Files", "*.jpg"
If openDialog.Show Then
For i = 1 To openDialog.SelectedItems.Count
Imagelst = Imagelst & ";" & openDialog.SelectedItems(i)
Next
End If
I needed to select a single text file... this is what I did... it worked fine.
' Get the File
'----------------------------------------------------------
Dim dialog As Object
Dim pickedfile As Boolean
Dim myfile As String
Set dialog = Application.FileDialog(msoFileDialogFilePicker)
With dialog
.AllowMultiSelect = False
.Title = "Please pick the file to convert."
.Filters.Clear
.Filters.Add "Text Files", "*.TXT"
.Filters.Add "All Files", "*.*"
pickedfile = False
pickedfile = .Show
If pickedfile Then
myfile = .SelectedItems.Item(1)
End If
End With
'----------------------------------------------------------
Additionally... you can replace the dialog type with...
Set dialog = Application.FileDialog(msoFileDialogOpen)
and it worked equally well.
Private Sub Command135_Click()
Dim dialog As Object
Dim pickedfile As Boolean
Dim myfile As String
Set dialog = Application.FileDialog(1)
With dialog
.AllowMultiSelect = False
.Title = "Please pick the file to convert."
.Filters.Clear
.Filters.Add "Picture Files", "*.Jpg"
.Filters.Add "All Files", "*.*"
pickedfile = False
pickedfile = .Show
If pickedfile Then
myfile = .SelectedItems.Item(1)
End If
End With
Me.Form.Picture = myfile
End Sub
Command_135=Button Name
Me.Form.Picture = "The Control Name"