I need to import multiple text (csv) files into multiple tables in access. At the moment I do it one by one using External data, browsing to the file, importing it, setting specifications and saving it as a table. It's tedious.
I've found plenty of code which let me import multiple files to multiple tables. My issue is that each import has different specs.
I have this code which works but it still means that i have to select table one then go back and select table two then go back and select table 3 etc.
Is there a way I can loop through the directory, and import the files with their specific spec? Table names never change, spec for each table never changes. They need to be separate tables.
Any and all help gratefully recieved!
Private Sub Command1_Click()
Dim strPathFile As String, strFile As String, strPath As String
Dim strTable As String
'In case we have to run everything more than once, make sure table is clear before appending data
DoCmd.SetWarnings (False)
DoCmd.RunSQL "DELETE * FROM " & "TABLEONEHeader"
'Explorer window opens
With Application.FileDialog(msoFileDialogFilePicker)
'Only show CSV files
.Filters.Add "Text Files", "*.csv", 1
.Title = "Select TABLE ONE..."
'Prevent user selecting multiple files.
.AllowMultiSelect = False
'If the users selects a file use it, otherwise show an error message
If .Show Then
strFile = .SelectedItems(1)
Else
MsgBox "You haven't selected a file.", vbCritical
End If
End With
'Import data to table using specific specifications
DoCmd.TransferText acImportDelim, "TABLEONE", "TABLEONEHeader", strFile, True
MsgBox "TABLEONEHeader has been imported"
'move on to next file
'In case we have to run everything more than once, make sure table is clear before appending data
DoCmd.SetWarnings (False)
DoCmd.RunSQL "DELETE * FROM " & "TABLETWO"
'Explorer window opens
With Application.FileDialog(msoFileDialogFilePicker)
'Only show CSV files
.Filters.Add "Text Files", "*.csv", 1
.Title = "Select TABLE TWO file..."
'Prevent user selecting multiple files.
.AllowMultiSelect = False
'If the users selects a file use it, otherwise show an error message
If .Show Then
strFile = .SelectedItems(1)
Else
MsgBox "You haven't selected a file.", vbCritical
End If
End With
DoCmd.TransferText acImportDelim, "TABLETWO", "TABLETWOHeader", strFile, True
MsgBox "TABLETWO has been imported"
'move on to next file
I recommend you make a subroutine that takes parameters, like the below - then call this multiple times from another sub.
For example:
Sub Import_Table(TableName as String, FileFullPath as String)
With DoCmd
.SetWarnings False
.RunSQL "DELETE * FROM " & TableName & "Header"
.SetWarnings True
.TransferText acImportDelim, TableName, TableName & "Header", FileFullPath, True
End With
MsgBox TableName & " has been imported.", vbInformation
End Sub
For the other part of your question, looping through files in a folder is easily done using a Do Until Loop and the Dir function - I can't write this code for you not knowing the exact names and paths of the different text files you want to import, but here's a trimmed-down example.
Sub Loop_through_text_files()
Dim FileNum as Long: FileNum = 1
Dim FileLocation as String: FileLocation = "C:\Users\Me\Documents\Testing\"
Dim FileName as String
Do
FileName = Dir(FileLocation & FileNum & "*.csv")
If FileName = "" Then Exit Do 'Will stop looping when it doesn't find a relevant file
Import_Table _
TableName:="Table_" & FileNum, _
FileFullPath:=FileLocation & FileName
FileNum = FileNum + 1
Loop
End Sub
The above will look for .csv files in the folder "C:\Users\Me\Documents\Testing" that have 1, 2, 3 etc in their name, and import that to tables called Table_1, Table_2, Table_3 etc.
Note that 1, 2, 3 is different from "ONE", "TWO", "THREE" so you may have to adapt your naming protocol to deal with this. If that's not an option, see here for a handy function on converting numbers to words.
Related
I am a beginner with Excel VBA and have some questions.
I want to search a specified folder based on user input (a file name). I can get that part to work, however, I want it to search for more than just the one format (.docx), and also include a search of both .pdf and .doc.
Clarification:
The folder under G:\NEWFOLDER\NAMEFOLDER contains files with extensions .doc, .docx, and .pdf and I want to search the entire folder and report back to my spreadsheet on Sheet2.
Dim NAME As String
Dim File_Path As String
NAME = InputBox(" Enter Your NAME (EX: JOHNP) ")
File_Path = "G:\NEWFOLDER\NAMEFOLDER" & NAME & ".docx"
If Dir(File_Path) <> "" Then
ThisWorkbook.Sheets("Sheet2").Activate
Range("D5") = ("Checked")
Range("E5") = NAME
Else
MsgBox "NAME Not found"
End If
End Sub
How do I search the document within?
Clarification:
The above code only tells me if the user input is located inside the coded path. The next step I want to do is to search within that document for keyword and report back to spreadsheet. For example, within JOHNP.doc there is a column of age. I want the code to report back to Sheet2 cell with "22".
Is this even possible with word document search, or is it better if the JOHNP is in excel format?
This should help you a little bit - This will cycle through files in the named folder location (if it exists), and will only target ones that are .doc, .docx or .pdf.
As for your second question - Yes, you can pull that number from your documents, however, you'll need to be more specific as to where that number is. If it's in the same spot each time, then that would be fairly easy - hopefully in a Table, then it would have an explicit reference (like ActiveDocument.Tables(1).Cells(1,1), etc. For now, this code below will go through all the files and when it finds the first match, it'll open the word document for you (then exit the loop).
Sub Test()
Dim NAME As String
Dim File_Path As String
Dim StrFile As String
NAME = InputBox(" Enter Your NAME (EX: JOHNP) ")
File_Path = "G:\NEWFOLDER\NAMEFOLDER\" & NAME & "\"
StrFile = Dir(File_Path)
If Dir(File_Path) <> "" Then
Do While Len(StrFile) > 0
If InStr(StrFile, ".doc") > 0 Or _
InStr(StrFile, ".pdf") > 0 Then
Debug.Print StrFile
'ThisWorkbook.Sheets("Sheet2").Range("D5") = ("Checked")
'ThisWorkbook.Sheets("Sheet2").Range("E5") = NAME
If InStr(StrFile, ".doc") > 0 Then
Set wordapp = CreateObject("word.Application")
wordapp.documents.Open File_Path & StrFile
wordapp.Visible = True
Exit Do
End If
End If
StrFile = Dir
Loop
Else
MsgBox NAME & " Not found"
End If
End Sub
I've got a folder which contains .txt files (they contain PHI, so I can't upload the .txt file, or an example without PHI, or even any images of it). I need an excel macro, which will allow the user to choose the folder containing the file, and will then insert the .txt file data into a new excel workbook, format the rows and columns appropriately, and finally save the file to the same folder that the source was found in.
So far I've got all of that working except for the formatting of rows and columns. As of now, the .txt data is inserted to a new workbook & worksheet, but I can't seem to figure out how to get rid of rows I don't need, or how to get the columns formatted appropriately.
Again, I can't upload the .txt file (or anything) because the Healthcare organization I work for blocks it - even if I've removed all PHI.
Below is the macro I've created so far:
Private Sub CommandButton2_Click()
On Error GoTo err
'Allow the user to choose the FOLDER where the TEXT file(s) are located
'The resulting EXCEL file will be saved in the same location
Dim FldrPath As String
Dim fldr As FileDialog
Dim fldrChosen As Integer
Set fldr = Application.FileDialog(msoFileDialogFolderPicker)
With fldr
.Title = "Select a Folder containing the Text File(s)"
.AllowMultiSelect = False
.InitialFileName = "\\FILELOCATION"
fldrChosen = .Show
If fldrChosen <> -1 Then
MsgBox "You Chose to Cancel"
Else
FldrPath = .SelectedItems(1)
End If
End With
If FldrPath <> "" Then
'Make a new workbook
Dim newWorkbook As Workbook
Set newWorkbook = Workbooks.Add
'Make worksheet1 of new workbook active
newWorkbook.Worksheets(1).Activate
'Completed files are saved in the chosen source file folder
Dim CurrentFile As String: CurrentFile = Dir(FldrPath & "\" & "*.txt")
Dim strLine() As String
Dim LineIndex As Long
Application.ScreenUpdating = False
Application.DisplayAlerts = False
While CurrentFile <> vbNullString
'How many rows to place in Excel ABOVE the data we are inserting
LineIndex = 0
Close #1
Open FldrPath & "\" & CurrentFile For Input As #1
While Not EOF(1)
'Adds number of rows below the inserted row of data
LineIndex = LineIndex + 1
ReDim Preserve strLine(1 To LineIndex)
Line Input #1, strLine(LineIndex)
Wend
Close #1
With ActiveSheet.Range("A1").Resize(LineIndex, 1)
.Value = WorksheetFunction.Transpose(strLine)
.TextToColumns Other:=True, OtherChar:="|"
End With
ActiveSheet.UsedRange.EntireColumn.AutoFit
ActiveSheet.Name = Replace(CurrentFile, ".txt", "")
ActiveWorkbook.SaveAs FldrPath & "\" & Replace(CurrentFile, ".txt", ".xls"), xlNormal
ActiveWorkbook.Close
CurrentFile = Dir
Wend
Application.DisplayAlerts = True
Application.ScreenUpdating = True
End If
Done:
Exit Sub
err:
MsgBox "The following ERROR Occurred:" & vbNewLine & err.Description
ActiveWorkbook.Close
End Sub
Any ideas of how I can delete entire lines from being brought into excel?
And how I can format the columns appropriately? So that I'm not getting 3 columns from the .txt file all jammed into 1 column in the resulting excel file?
Thanks
I'd recommend you not to re-invent the wheel. Microsoft provides an excellent add-on to accomplish this task, Power Query.
It lets you to load every file in a folder and process it in bulks.
Here you have a brief introduction of what can do for you.
I have a macro that asks a user to choose multiple files for data analysis. User selects a Excel or CSV file first (XLSX, XLS, CSV), then asks for a second file but CSV only. The intent of the tool is to combine the two data files into one.
In one Sub, I ask the user to select any compatible XLSX, XLS, or CSV files using the FileDialog code:
Dim myObj As Object
Dim myDirString As String
Set myObj = Application.FileDialog(msoFileDialogFilePicker)
With myObj
.InitialFileName = "C:\Users\" & Environ$("Username") & "\Desktop"
.Filters.Add "Custom Excel Files", "*.xlsx, *.csv, *.xls"
.FilterIndex = 1
If .Show = False Then MsgBox "Please select Excel file.", vbExclamation: Exit Sub
myDirString = .SelectedItems(1)
End With
It seems to filter appropriately:
After this data analysis in complete, then the user runs a second sub to select another file, but it must be a CSV file only. So I use this code to request CSV:
Dim yourObj3 As Object
Dim yourDirString3 As String
Set yourObj3 = Application.FileDialog(msoFileDialogFilePicker)
With yourObj3
.InitialFileName = "C:\Users\" & Environ$("Username") & "\Desktop"
.Filters.Add "CSV Files", "*.csv"
.FilterIndex = 1
If .Show = False Then MsgBox "Please select CSV file.", vbExclamation: Exit Sub
yourDirString3 = .SelectedItems(1)
End With
The problem is the FileDialog box remembers the first filter (Custom XLS) and they need to click the drop down to see the appropriate filter for CSV only...
So this would certainly be confusing to the user...I'm guessing I need to "clear" our that first filter after the user completes the first macro. Any suggestions on that code to clear (or reset) the first filter?
Tried adding this below it when I found what I thought was a similar question FileDialog persists previous filters:
With .Filters
.Clear
End With
But results in Compile error: Invalid or unqualified reference
This works in my environment. The only thing I made differently was to declare dialogs as FileDialog instead of Object.
Sub Test()
Dim myObj As FileDialog
Dim myDirString As String
Set myObj = Application.FileDialog(msoFileDialogFilePicker)
With myObj
.InitialFileName = "C:\Users\" & Environ$("Username") & "\Desktop"
.Filters.Clear
.Filters.Add "Custom Excel Files", "*.xlsx, *.csv, *.xls"
.FilterIndex = 1
.Show
End With
Dim yourObj3 As FileDialog
Dim yourDirString3 As String
Set yourObj3 = Application.FileDialog(msoFileDialogFilePicker)
With yourObj3
.InitialFileName = "C:\Users\" & Environ$("Username") & "\Desktop"
.Filters.Clear
.Filters.Add "CSV Files", "*.csv"
.FilterIndex = 1
.Show
End With
End Sub
Although it is not directly the answer to the specific msoFileDialogFilePicker from the OP (and googled this answer), I had the same problem with the msoFileDialogSaveAs dialog in Excel 2010 where errors are raised trying to modify the filters in any way because it obviously is not supported :-/
The msoFileDialogSaveAs dialog does NOT support file filters
I have some working code that loops through a folder full of Excel files, and imports a table from each into the an Access table. All I'm trying to do is add a field at the end of the table called FileName that has the name of the source Excel file.
I've done some Googling and found this solution:
How to add file name when importing multiple Excel files to one Access table
I've tried to incorporate the solution into my code, but when I reach the execute statement, I get:
Run-time error '3061' Too few parameters. Expected 2.
I think the problem is just with the strSQL statement and/or the way I'm executing it at the end.
Public Sub Command0_Click()
Dim strFile As String 'Filename
Dim strFileList() As String 'File Array
Dim intFile As Integer 'File Number
Dim filename As String
Dim path As String
Dim qdf As DAO.QueryDef
Set db = CurrentDb()
'make the UPDATE a parameter query ...
strSQL = "UPDATE Test SET FileName=[pFileName] WHERE FileName Is Null OR
FileName='';"
Set qdf = db.CreateQueryDef(vbNullString, strSQL)
path = "C:\Users\u005984\Desktop\Test\"
'Loop through the folder & build file list
strFile = Dir(path & "*.xlsx")
While strFile <> ""
'add files to the list
intFile = intFile + 1
ReDim Preserve strFileList(1 To intFile)
strFileList(intFile) = strFile
strFile = Dir()
Wend
'see if any files were found
If intFile = 0 Then
MsgBox "No files found"
Exit Sub
End If
'cycle through the list of files
For intFile = 1 To UBound(strFileList)
filename = path & strFileList(intFile)
DoCmd.TransferSpreadsheet acImport, 9, "Test", filename, True
'Add filename field
qdf.Parameters("pFileName").Value = strFileList(intFile)
qdf.Execute dbFailOnError
Next intFile
End Sub
I'm new to Access VBA and SQL, and can't figure out why its expecting 2 parameters. Grateful for any help.
Adjust your SQL query, your's doesn't contain the parameter.
strSQL = "PARAMETERS pfilename Text ( 255 ); UPDATE Test SET FileName=[pFileName] WHERE FileName Is Null OR FileName='';"
Adding a FileName field is markedly different than updating its value. Hence, you need two SQL action queries: ALTER and UPDATE statements.
Specifically, the query requires two components that are unknown by the engine: FileName column and [pFileName] parameter value. Most likely, your Excel worksheets do not have a FileName column being imported into Test table.
Consider the following setup employing an ALTER statement within loop (only on very first iteration since all worksheets append to same table):
'Add filename field
For intFile = 1 To UBound(strFileList)
filename = path & strFileList(intFile)
DoCmd.TransferSpreadsheet acImport, 9, "Test", filename, True
If intFile = 1 then
' ALTER TABLE
CurrentDb.Execute "ALTER TABLE [Test] ADD COLUMN [FileName] TEXT(255)", dbFailOnError
End If
' UPDATE TABLE (PASSING PARAM VALUE)
qdf.Parameters("pFileName").Value = strFileList(intFile)
qdf.Execute dbFailOnError
Next intFile
Ok so I am trying to quickly open a file path using 2 cell values, everything works fine if I know the information verbatim. My issue is on the last value I will only have the first part of the file name, I have tried using the wildcard * but can't seem to get it to work. Keep getting "Path not found error". The second value is a project name, however, the folders also contain a description of the project. For example I know the project name is TB1756_2156 but the folder is named "TB1756_2156 Project Description Person in Charge January 2014" this is the code I have so far:
Sub Button2_Click()
ChDrive "S:\"
ChDir "S:\CLIENTS " & Range("B10").Value & "\Client1\" & Range("B11").Value & "*\Sample"
strFile = Application.GetOpenFilename
End Sub
EDIT:
Ok so if I where to manually open the file I want to examine this would be my path: S:\CLIENTS YEAR\FOLDER NAME\Project # Description Project Lead Year\Sample\File I want.xls
The vba I want open the dialog box and goes to the S:\CLIENTS then adds value from cell B10 then continues to FOLDER NAME\ then grabs just the Project # from cell B11 as this is all you would have handy , then would fill in the missing information, then continue to \Sample where the user would then select the file they want to open.
So manipulating the code provide by #dcromley this is what I got:
Sub UseFileDialogOpen()
With Application.FileDialog(msoFileDialogOpen)
.AllowMultiSelect = True
.InitialFileName = "S:\CLIENTS " & Range("C10").Value & "\FOLDER NAME\ & Range("C11").Value
.Show
End With
End Sub
My issue with this is that it only enters the Project # into the File Name: but does not actually open it. So looking for a way to parse the directory as I have it already from my original code minus the "*\Sample" and that it would open the only folder that starts with the Project #
If you have the first part of the file name and want the filename, this will do it.
If you want a directoryname, change vbNormal to vbDirectory.
Sub Main()
MsgBox FindFilename("abc", "Z:\untitled\")
End Sub
Function FindFilename$(FirstPart$, DirWhere$)
Dim sw1&, Filename$
Do
If sw1 = 0 Then
sw1 = 1
Filename = Dir$(DirWhere, vbNormal)
Else
Filename = Dir$()
End If
If Filename = "" Then Exit Do
If FirstPart = Left$(Filename, Len(FirstPart)) Then
FindFilename = Filename
Exit Function
End If
Loop
MsgBox "Error - Filename not found"
End Function
EDIT:
From the Excel 2003 help (you have the complete (initial) dirname now, right?):
Sub UseFileDialogOpen()
Dim lngCount&
With Application.FileDialog(msoFileDialogOpen)
.AllowMultiSelect = True
.InitialFileName = "Z:\untitled\"
.Show
For lngCount = 1 To .SelectedItems.Count
MsgBox .SelectedItems(lngCount)
Next lngCount
End With
End Sub
EDIT2: To open a *.xls file:
Sub Openxls()
Dim filename$
filename = "z:\untitled\dave1.xls"
Workbooks.Open filename
End Sub
I think dcromley's approach is sound but let us simplify things a little bit.
Dim prjDir As String, prjName As String
Dim initialFile As String, myDirString As String
'~~> B11 contains part of the foldername
'~~> B10 value as is
prjDir = "C:\CLIENTS\" & Range("B10") & "\Client1\" & Range("B11") & "*"
prjDir = Dir(prjDir, vbDirectory) '~~> use Dir to get the actual folder name
prjName = "C:\CLIENTS\" & Range("B10") & "\Client1\" & prjDir & "\*SAMPLE*.xls"
prjName = Dir(prjName, vbNormal) 'use Dir to get the actual filename
initialFile = "C:\CLIENTS\" & Range("B10") & "\Client1\" & prjDir & "\" & prjName
With Application.FileDialog(msoFileDialogFilePicker)
.Filters.Add "Excel Files", "*.xls"
.FilterIndex = 1
.InitialFileName = initialFile
.AllowMultiSelect = False
If .Show = False Then MsgBox "Please select Excel file.", vbExclamation: Exit Sub
myDirString = .SelectedItems(1)
.Filters.Clear
End With
Workbooks.Open myDirString '~~> Open the file
Is this close to what you want to achieve?
Btw, I assumed your Project # is unique.