Automating import of an Excel file - vba

I am trying to import a file, saved in our public drive, into an Access database as a table.
This is what I have so far.
Dim TimeStamp2 As String
TimeStamp2 = Month(Date) & "." & Day(Date) - 1 & "." & Year(Date)
Dim xlFile As String, shtName
xlFile = "Open Orders # " & TimeStamp2 & ".xls"
shtName = "Current Open Orders"
DoCmd.TransferSpreadsheet aclimport, acSpreadsheetTypeExcel12, "Open Orders From Yesterday", "\\cletus\KNXGENDB$\Daily Order Bookings\Open Orders # " & TimeStamp2 & ".xls", True, shtName & "!"
This is the error I'm getting:
Run time error 2306: There are too many rows to output, based on the limitation specified by the output format or by Microsoft Access

Here are the specific fixes:
Fix the file extension. In one place you have it as ".xlsx" and in another, ".xls"
Correct the spelling of acImport (in your code it is incorrectly spelled as "aclImport")
To delete the table before you import, try DoCmd.DeleteObject acTable, "Open Orders From Yesterday"
When dimensioning multiple variables on the same line, you have to provide a variable type for each or it will use the default of Variant. So in this case you would write Dim xFile As String, shtName As String
You don't actually use the xFile variable. You should either remove it or add it into the DoCmd.TransferSpreadsheet line to avoid confusion.
And here is everything all together:
Dim TimeStamp2 As String
TimeStamp2 = Month(Date) & "." & Day(Date) - 1 & "." & Year(Date)
Dim shtName As String
shtName = "Current Open Orders"
'Delete the existing table
DoCmd.DeleteObject acTable, "Open Orders From Yesterday"
'Import the data, recreating the table
DoCmd.TransferSpreadsheet aclimport, acSpreadsheetTypeExcel12, "Open Orders From Yesterday", "\\cletus\KNXGENDB$\Daily Order Bookings\Open Orders # " & TimeStamp2 & ".xls", True, shtName & "!"
One question: is your sheet name really "Current Open Orders!"? If not, you probably want to remove the exclamation mark from the end of DoCmd.TransferSpreadsheet aclimport, acSpreadsheetTypeExcel12, "Open Orders From Yesterday", "\\cletus\KNXGENDB$\Daily Order Bookings\Open Orders # " & TimeStamp2 & ".xls", True, shtName & "!"

Try dimming "Open Orders from Yesterday" and the file path, etc.
This code worked for me to do the same thing. You can ignore the loop if it's only one file you're doing.
Sub Import2()
Dim strPathFile As String, strFile As String, strPath As String
Dim strWorksheet As String, strTable As String
Dim blnHasFieldNames As Boolean
' Change this next line to True if the first row in EXCEL worksheet
' has field names
blnHasFieldNames = True
' Replace C:\Documents\ with the real path to the folder that
' contains the EXCEL files
strPath = CurrentProject.Path & "\Folder\"
' Replace tablename with the real name of the table into which
' the data are to be imported
strTable = "AccessTableNameGoesHere"
strWorksheet = "DataSheet"
strFile = Dir(strPath & "*.xls")
Do While Len(strFile) > 0
strPathFile = strPath & strFile
DoCmd.TransferSpreadsheet acImport, acSpreadsheetTypeExcel9, _
strTable, strPathFile, blnHasFieldNames, strWorksheet & "$"
' Uncomment out the next code step if you want to delete the
' EXCEL file after it's been imported
' Kill strPathFile
strFile = Dir()
Loop
MsgBox "Import Successful!"
End Sub

Related

Add field filepath for multiple Excel file import within Access

I have the following Module in Access:
On Error Resume Next
Dim strDir As String
Dim strFile As String
Dim I As Long
I = 0
strDir = "C:\excelTest\"
strFile = Dir(strDir & "*.xlsx")
While strFile <> ""
I = I + 1
strFile = strDir & strFile
Debug.Print "importing " & strFile
DoCmd.TransferSpreadsheet acImport, , "mainTable", strFile, False 'has columnheaders
strFile = Dir()
Wend
MsgBox "Load Finished"
importExcelSheets = I
End Function
This imports the data from the xlsx files within the directory (C:\excelTest). This all works fine, but how can I add an additional field which stores the directory and file?
ie. If I have a file test.xlsx during the import a field is created and the path C:\excelTest\test.xlsx is stored.
After records are imported, run an SQL UPDATE action with criteria that distinguishes those new records from previously existing, possibly a date value. Something like:
CurrentDb.Execute "UPDATE tablename SET fieldname = '" & strFile & "' WHERE datefield = #" & <some date input here> & "#"

Showing excel save as dialog box and prefill with cell reference

With no coding knowledge, I have attempted to use some code found here: Automatically name a file based on cell data when saving a spreadsheet?. Thanks to Jean-François Corbett
I have adapted as follows to show the dialog box:
Sub SaveAsString()
Dim strPath As String
Dim strFolderPath As String
strFolderPath = "N:\PROJECTS\"
strPath = strFolderPath & _
Sheet1.Range("B2").Value & "_" & _
Sheet1.Range("B6").Value & "_" & _
Sheet1.Range("X1").Value & "-JS-1" & ".xlsm"
Application.Dialogs(xlDialogSaveAs).Show strPath
ActiveWorkbook.SaveAs FileFormat:=xlOpenXMLWorkbookMacroEnabled
End Sub
I am opening an .xltm file, and attempting to save with the ability to select the subfolder of N:\PROJECTS\ with the combination of cell references shown.
The dialog box appears fine, already showing N:\PROJECTS. However, it does not fill the file name, unless the file is first saved as a .xlsm. It then always attempts to overwrite as well.
This worked for me, utilizing a slightly different code technique.
Option Explicit
Sub SaveAsString()
Dim strPath As String
Dim strFolderPath As String
ChDir "N:\PROJECTS\" 'set directory with this line
With Sheet1
strPath = .Range("B2").Value
strPath = strPath & "_" & .Range("B6").Value
strPath = strPath & "_" & .Range("X1").Value
strPath = strPath & "-JS-1.xlsm"
End With
Application.Dialogs(xlDialogSaveAs).Show strPath 'load file name with this argument
ActiveWorkbook.SaveAs FileFormat:=xlOpenXMLWorkbookMacroEnabled
End Sub
The main issue remaining was that opening from a template didn't automatically save as .xlsm. Apparently Application.Dialogs doesn't support file filters, so the problem is better solved with GetSaveasFileName.
Full code as follows:
Sub SaveAsString()
Dim strPath As String
Dim strFolderPath As String
strFolderPath = "N:\PROJECTS\"
strPath = strFolderPath & _
Sheet1.Range("B2").Value & "_" & _
Sheet1.Range("B6").Value & "_" & _
Sheet1.Range("X1").Value & "-JS-1" & ".xlsm"
fileSaveName = Application.GetSaveAsFilename(strPath _
, fileFilter:="Excel Files (*.xlsm), *.xlsm")
End Sub

VBA procedure to import only selected csv files (from one folder) into a single table in access

I have a folder that contains 2000 *.csv files. But not all of them are important 4 me. Only 60 of them are important, and I have them listed, by names in access table. there is no header - only file names that need to be read into the single table database.
it looks like this:
these *.mst files are really *.csv files - it will work that way.
I need a VBA procedure, that imports ONLY SELECTED files (these listed in the table) out of this folder into a single access table.
yes, all these files have exactly the same structure, so they can be merged into these access table and that is the goal of this VBA procedure.
this is how every file looks like:
the code I already got just pulls every file from this folder and imports it into the single table in access.
I need it changed to pull only the selected files.
destination table name is: "all_stocks"
Sub Importing_data_into_a_single_table()
Dim start As Double
Dim total_time As String
Dim my_path As String, my_ext As String, my_file As String
Dim FileNum As Integer
Dim DataLine As String
Dim pola() as String
Dim SQL1 As String, file_array() As String
start = Timer
my_path = "C:\Users\michal\SkyDrive\csv\bossa\mstcgl_mst\" 'Source folder.
my_ext = "*.mst" ' all files with .mst extension.
my_file = Dir(my_path & my_ext) ' take the first file from my_path.
DoCmd.SetWarnings False ' turn off warnings.
Do While my_file <> ""
FileNum = FreeFile()
Open my_path & my_file For Input As #FileNum
Line Input #FileNum, DataLine
' Reads a single line from an open sequential file and assigns it to a String variable.
While Not EOF(FileNum) ' EOF function returns a Boolean value True when the end of a file.
Line Input #FileNum, DataLine
pola = Split(DataLine, ",")
SQL1 = "INSERT INTO Tabela1 (Ticker, day, open, high, low, close, vol) VALUES('" & pola(0) & "', " & _
pola(1) & ", " & pola(2) & ", " & pola(3) & ", " & _
pola(4) & ", " & pola(5) & ", " & pola(6) & ")"
Debug.Print SQL1
DoCmd.RunSQL SQL1
Wend
Close
my_file = Dir()
Loop
DoCmd.SetWarnings True
total_time = Format((Timer - start) / 86400, "hh:mm:ss")
' total_time = Round(Timer - start, 3)
MsgBox "This code ran successfully in " & total_time & " minutes", vbInformation
End Sub
If You could optimize this code to run faster, please be my guest.
Now its importing the data using "Line Input" method, and I've heard, that there are some better ways to do that, but I'm no programmer myself so I'm dependent on Your help my friends.
Thank U for all help and code provided :-)
screen shot 4 for A.S.H
Listing the 2000+ files in the directory, checking if each is listed in the selection table, is not the right approach. It is surely preferable to read the selected files from the table and access them one by one.
The other potential speedup is using the built-in DoCmd.TransferText (as already pointed in other answers). Built-ins are usually very optimized and robust so you should prefer them unless there's a specific reason. Your own tests should confirm it.
Sub Importing_data_into_a_single_table()
Dim my_path As String, rs As Recordset, start As Double, total_time As String
my_path = "C:\Users\michal\SkyDrive\csv\bossa\mstcgl_mst\" 'Source folder.
DoCmd.SetWarnings False
start = Timer
Set rs = CurrentDb.OpenRecordset("Selected_Files")
Do Until rs.EOF
If Dir(my_path & rs.Fields(0).Value) <> "" Then
DoCmd.TransferText , , "Tabela1", my_path & rs.Fields(0).Value, True
' You could also use your code's loop here; Open my_path & my_file For Input As #FileNum etc..
End If
rs.MoveNext
Loop
DoCmd.SetWarnings True
total_time = Format(Timer - start, "hh:mm:ss")
MsgBox "This code ran successfully in " & total_time, vbInformation
End Sub
I would try using a combination of different method. I will admit I have never interacted with a .mst file in the manner youre using them but I think what IM suggesting will still work perfectly fine.
Use this to check table for file name:
Do While my_file <> "" 'some where after this line
If Isnull(Dlookup("your field name", "your table name", "Field name='" & my_file & "'") = False then
'do stuff b/c you found a match
else
'dont do stuff b/c no match
end if
Then you could use DoCmd.TransferText to import the entire file into the table
Documentation of transfer text method
https://msdn.microsoft.com/VBA/Access-VBA/articles/docmd-transfertext-method-access
I use frequently Excel vba. This bellows is Excel vba method. Compare the speed of this with your method.
Sub OpenCSvs()
Dim sWs As String, Fn As String
Dim Wb As Workbook
Dim start As Double
Dim total_time As String
Dim my_path As String, my_ext As String, my_file As String
start = Timer
my_path = "C:\Users\michal\SkyDrive\csv\bossa\mstcgl_mst\" 'Source folder.
my_ext = "*.mst" ' all files with .mst extension.
my_file = Dir(my_path & my_ext) ' take the first file from my_path.
Do While my_file <> ""
Fn = my_path & my_file
Set Wb = Workbooks.Open(Fn, Format:=2)
sWs = ActiveSheet.Name
With ActiveSheet
.Rows(1).Insert
.Range("a1").Resize(1, 7) = Array("Ticker", "day", "open", "high", "low", "close", "vol")
End With
ExportToAccess Fn, sWs
Wb.Close (0)
my_file = Dir()
Loop
total_time = Format((Timer - start) / 86400, "hh:mm:ss")
MsgBox "This code ran successfully in " & total_time & " minutes", vbInformation
End Sub
Sub ExportToAccess(myFn As String, sWs As String)
Dim PathOfAccess As String
Dim strConn As String, strSQL As String
PathOfAccess = "C:\Database6.accdb" '<~~ your database path
strConn = "Provider=Microsoft.ACE.OLEDB.12.0;" & _
"Data Source=" & PathOfAccess & ";"
Set cn = CreateObject("ADODB.Connection")
cn.Open strConn
strSQL = "INSERT INTO Tabela1 (Ticker, day, open, high, low, close, vol) select * from [" & sWs & "$] IN '' " _
& "[Excel 8.0;HDR=yes;IMEX=2;DATABASE=" & myFn & "]"
cn.Execute strSQL
End Sub

Appending Username and Date to Save As in VBA

How can I save the excel file using vba code so that the Username and Date are attached in a macro?
Here is the code that I worked on to try to make it work:
ActiveWorkbook.SaveAs FileName:=(Environ$("Username")) & "_" & Date & "_BKMtracker.xlsx", FileFormat:=xlOpenXMLWorkbook
Try this:-
ActiveWorkbook.SaveAs FileName:=(Environ$("Username")) & "_" & Date & "_BKMtracker.xlsx", FileFormat:=xlOpenXMLWorkbook
With credit to #MatthewD
Sub SaveDocument()
Dim username As String
Dim nowFormated As String
Dim path As String
Dim filename As String
Dim extention As String
username = Environ("Username") & "_" 'gets the username
nowFormated = CStr(Format(now, "yymmdd")) 'or every format you like
path = "D:\" 'Wherever you want to save the file
filename = "_BKMtracker" 'or what you want
extention = ".xlsm" 'for example (with macros, else you have to change the FileFormat too)
ActiveWorkbook.SaveAs filename:=path & username & nowFormated & filname & extention, _
FileFormat:=xlOpenXMLWorkbookMacroEnabled, CreateBackup:=False
End Sub

DIR function and Naming Tables in Access

I am using the DIR function to import a set of excel files into access. I then pass the attributes of the DIR to make the name of the table in access the same as the excel file. The only problem is that I also get xls in the name how I can I stop this?
Code below:
Sub Sample2()
Const cstrFolder As String = "F:\TCB_HR_KPI\Data View\"
Dim strFile As String
Dim i As Long
strFile = Dir(cstrFolder & "*.xls")
If Len(strFile) = 0 Then
MsgBox "No Files Found"
Else
Do While Len(strFile) > 0
Debug.Print cstrFolder & strFile
DoCmd.TransferSpreadsheet acImport, acSpreadsheetTypeExcel9, _
strFile, cstrFolder & strFile, True
i = i + 1
strFile = Dir()
Loop
MsgBox i & " Files are imported"
End If
End Sub
Strip it off as necessary with a helper function...
Function StripFileExt(FileName As String) As String
Dim Pos As Long
Pos = InStrRev(FileName, ".")
If (Pos > 0) And (Pos > InStrRev(FileName, "\")) Then
StripFileExt = Left$(FileName, Pos - 1)
Else
StripFileExt = FileName
End If
End Function
Use the Split Function to split on ".", and take the first element of that array for your table name.
Split(strFile, ".")(0)
You could store that result in a intermediate variable. Or just use the expression directly in the TransferSpreadsheet statement.
DoCmd.TransferSpreadsheet acImport, acSpreadsheetTypeExcel9, _
Split(strFile, ".")(0), cstrFolder & strFile, True
Note: Based on your previous question, I assumed the workbook file names contain only a single dot: names from REPORT1.xls thru REPORT67.xls However if the file names you're dealing with this time can include more than one dot, my first suggestion is inappropriate.
In that case, you can still use an expression which includes Split(), but that expression would not be as simple.
Left(strFile, Len(strFile) - Len(Split(strFile, ".")(1)) -1)
Notice that approach would accommodate any of the other Excel file extensions in addition to .xls
Do you want this ?
Sub Sample2()
'
Const cstrFolder As String = "F:\TCB_HR_KPI\Data View\"
'
Dim i As Long, lng As Long
'
Dim strExt As String, strFile As String, strTable As String
'
strExt = ".xls"
lng = Len(strExt)
strFile = Dir(cstrFolder & "*" & strExt)
'
If Len(strFile) = 0 Then
MsgBox "No Files Found"
Else
Do While Len(strFile) > 0
'
' Debug.Print cstrFolder & strFile
'
strTable = Left(strFile, Len(strFile) - lng)
'
DoCmd.TransferSpreadsheet acImport, acSpreadsheetTypeExcel9, _
strTable, cstrFolder & strFile, True
i = i + 1
strFile = Dir()
Loop
MsgBox i & " Files are imported"
End If
'
End Sub
As this a file like Sample1.xls will be improrted as the table Sample1.