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> & "#"
Related
I am currently trying to put a macro together to sort files into folders based on a filename. I am locked into using VBA due to the system we are on.
For example sorting just the excel documents from below present in C:\ :
123DE.xls
124DE.xls
125DE.xls
124.doc
123.csv
into the following folder paths:
C:\Data\123\Data Extract
C:\Data\124\Data Extract
C:\Data\125\Data Extract
The folders are already created, and as in the example are named after the first x characters of the file. Batches of 5000+ files will need to be sorted into over 5000 folders so im trying to avoid coding for each filename
I am pretty new to VBA, so any guidance would be much appreciated. So far I have managed to move all the excel files into a single folder, but am unsure how to progress.
Sub MoveFile()
Dim strFolderA As String
Dim strFolderB As String
Dim strFile as String
strFolderA = "\\vs2-alpfc\omgusers7\58129\G Test\"
strFolderb = "\\vs2-alpfc\omgusers7\58129\G Test\1a\"
strFile = Dir(strFolderA & "*.xlsx*")
Do While Len(strFile) >0
Name StrFolderA & strFile As strFolderB & strFile
strFile = Dir
Loop
End Sub
Greg
EDIT
Sub MoveFile()
Dim strFolderA As String
Dim strFile As String
Dim AccNo As String
strFolderA = "\\vs2-alpfc7\omgUSERS7\58129\G Test\"
strFile = Dir(strFolderA & "*.xlsx*")
Do While Len(strFile) > 0
AccNo = Left(strFile, 2)
Name strFolderA & strFile As strFolderA & "\" & AccNo & "\Data Extract\" & strFile
strFile = Dir
Loop
End Sub
Thanks folks, are a few more bits and pieces i want to add, but functionality is there!
Sub DivideFiles()
Const SourceDir = "C:\" 'where your files are
Const topdir = "\\vs2-alpfc\omgusers7\58129\G Test\"
Dim s As String
Dim x As String
s = Dir(SourceDir & "\*.xls?")
Do
x = Left(s, 3) 'I assume we're splitting by first three chars
Name SourceDir & s As topdir & s & "\" & s
Loop Until s = ""
End Sub
If I understand you correctly, the problem is deriving the new fullpathname from the file name to use as the newpathname argument of the Name function.
If all of your files end with DE.XLS* you can do something like:
NewPathName = C:\Data\ & Split(strFile, "DE")(0) & "\Data Extract\" & strFile
You could use Filesystem object (tools > references > microsoft scripting runtime
This does a copy first then delete. You can comment out delete line and check copy is safely performed.
If on Mac replace "\" with Application.PathSeparator.
Based on assumption, as you stated, that folders already exist.
Option Explicit
Sub FileAway()
Dim fileNames As Collection
Set fileNames = New Collection
With fileNames
.Add "123DE.xls"
.Add "124DE.xls"
.Add "125DE.xls"
.Add "124.doc"
.Add "123.csv"
End With
Dim fso As FileSystemObject 'tools > references > scripting runtime
Set fso = New FileSystemObject
Dim i As Long
Dim sourcePath As String
sourcePath = "C:\Users\User\Desktop" 'where files currently are
For i = 1 To fileNames.Count
If Not fso.FileExists("C:\Data\" & Left$(fileNames(i), 3) & "\Data Extract\" & fileNames(i)) Then
fso.CopyFile (sourcePath & "\" & fileNames(i)), _
"C:\Data\" & Left$(fileNames(i), 3) & "\Data Extract\", True
fso.DeleteFile (sourcePath & "\" & fileNames(i))
End If
Next i
End Sub
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
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
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.
Pretty simple question really, I suppose. How can I amend the below so that rather than looking at LOI.CSV it looks at all .CSV files in the Intraday Folder?
LastSaved = FileDateTime("W:\Settlements\Intraday\LOT.csv")
If LastSaved < Date Then
MsgBox ("The current day file for LOI was last saved " & LastSaved)
End If
Try this
Const sPath As String = "W:\Settlements\Intraday\"
Sub LoopThroughFilesInAFolder()
Dim StrFile As String
StrFile = Dir(sPath & "\*.Csv")
Do While Len(StrFile) > 0
Debug.Print FileDateTime(sPath & "\" & StrFile)
'~~> Rest of the code here
StrFile = Dir
Loop
End Sub