DIR function and Naming Tables in Access - vba

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.

Related

Save and Rename File based on location

I have working code to:
Insert the Date, Company Name & Order Number into the proof at a specific location (data is pulled from the file location "C:\2020\My Company\Company Name\COM001 - 01\Layouts")
Determine the amount of pages in the document
Paste step 1 onto the other pages
Export the document as a .pdf
What I am trying to achieve, is before the .pdf is saved that the file is renamed (in this case COM001 - 01) adds a version indicator (" _v1") then saves the .cdr file and then runs the .pdf export function but does not overwrite the original.
I have been trying to adapt code I found on thespreadsheetguru.
The code adds the version indicator and exports the .pdf in the correct file location, but as soon as I open another file in a different location it will save it in the previous location instead.
Here is that piece of code: (I can upload the entire code if needed.)
Private Sub SaveNewVersion()
'PURPOSE: Save file, if already exists add a new version indicator to filename
Dim FolderPath, myPath, SaveName, SaveExt, VersionExt As String
Dim Saved As Boolean
Dim x As Long
Saved = False
x = 1
'Version Indicator (change to liking)
VersionExt = " _v"
'Pull info about file
On Error GoTo NotSavedYet
myPath = ActiveDocument.FileName
myFileName = Mid(myPath, InStrRev(myPath, "\") + 1, InStrRev(myPath, ".") - InStrRev(myPath, "\") - 1)
FolderPath = Left(myPath, InStrRev(myPath, "\"))
SaveExt = "." & Right(myPath, Len(myPath) - InStrRev(myPath, "."))
On Error GoTo 0
'Determine Base File Name
If InStr(1, myFileName, VersionExt) > 1 Then
myArray = Split(myFileName, VersionExt)
SaveName = myArray(0)
Else
SaveName = myFileName
End If
'Need a new version made
Do While Saved = False
If FileExist(FolderPath & SaveName & VersionExt & x & SaveExt) = False Then
ActiveDocument.SaveAs FolderPath & SaveName & VersionExt & x & SaveExt
Saved = True
Else
x = x + 1
End If
Loop
Exit Sub
'Error Handler
NotSavedYet:
MsgBox "This file has not been initially saved. " & _
"Cannot save a new version!", vbCritical, "Not Saved To Computer"
End Sub
Function FileExist(FilePath As String) As Boolean
'PURPOSE: Test to see if a file exists or not
Dim TestStr As String
'Test File Path (ie "C:\Users\Chris\Desktop\Test\book1.xlsm")
On Error Resume Next
TestStr = Dir(FilePath)
On Error GoTo 0
'Determine if File exists
If TestStr = "" Then
FileExist = False
Else
FileExist = True
End If
End Function
I have a feeling the code is messing up in the "pull info about file section".
You need to store the final path in a way that you can inspect it before you use it. Swap out this block of code here:
Dim newFileName as String
newFileName = FolderPath & SaveName & VersionExt & x & SaveExt
Debug.Print newFileName
If FileExist(newFileName) = False Then
ActiveDocument.SaveAs newFileName
Saved = True
Else
x = x + 1
End If
This will print the final filename to the Immediate Window before the save happens. If it is incorrect, change newFileName to be whatever you want.
Turns out it was a simple issue regarding the File path not returning any information..
changed out this code and now it works perfectly
On Error GoTo NotSavedYet
myFile = ActiveDocument.FileName
myPath = (ActiveDocument.FilePath)
myFileName = Mid(myFile, InStrRev(myFile, "\") + 1, InStrRev(myFile, ".") - InStrRev(myFile, "\") - 1)
FolderPath = Left(myPath, InStrRev(myPath, "\"))
SaveExt = "." & Right(myFile, Len(myFile) - InStrRev(myFile, "."))
Debug.Print FolderPath
On Error GoTo 0
Thanks #HackSlash for the tip, much appreciated

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> & "#"

VBA; how to extract all files names from a folder - without using Application.FileDialog object

As in the Question: the task is to extract all files names from a folder, but the folder path needs to be hard coded into the macro, to prevent these dialog boxes asking me things and wasting my time.
I will not change this folder. It will be the same one until the end of time, and I want to extract the files names into the Excel column, starting from second row.
this is the folder I want to extract ALL files names from.
"C:\Users\michal\SkyDrive\csv\bossa\mstcgl_mst\"
this is my portion of code:
Option Explicit
Sub GetFileNames()
Dim axRow As Long ' inside the Sheet("Lista") row#
Dim xDirectory As String
Dim xFname As String ' name of the file
Dim InitialFoldr$
Dim start As Double
Dim finish As Double
Dim total_time As Double
start = Timer
ThisWorkbook.Sheets("Lista").Range("D2").Activate
InitialFolder = "C:\Users\michal\SkyDrive\csv\bossa\mstcgl_mst"
If Right(InitialFolder, 1) <> "\" Then
InitialFolder = InitialFolder & "\"
End If
Application.InitialFolder.Show
If InitialFolder.SelectedItems.Count <> 0 Then
xDirectory = .SelectedItems(1) & "\"
xFname = Dir(xDirectory, vbArchive)
' Dir's job is to return a string representing
' the name of a file, directory, or an archive that matches a specified pattern.
Do While xFname <> "" ' there is already xFname value (1st file name) assigned.
ActiveCell.Offset(xRow) = xFname
xRow = xRow + 1 ' następny xRow
xFname = Dir()
Loop
End If
End With
finish = Timer ' Set end time.
total_time = Round(finish - start, 3) ' Calculate total time.
MsgBox "This code ran successfully in " & total_time & " seconds", vbInformation
End Sub
this is the line that crushes:
If InitialFolder.SelectedItems.Count <> 0 Then
xDirectory = .SelectedItems(1) & "\"
And two more important questions in the .png file.
Please, respond to them as well - it's very important 4 me.
Or if U guys know any other method to do this faster just don't hesitate and share Your Code with me - I'll be very grateful.
Sub Files()
Dim sht As Worksheet
Dim strDirectory As String, strFile As String
Dim i As Integer: i = 1
Set sht = Worksheets("Sheet1")
strDirectory = "C:\Users\User\Desktop\"
strFile = Dir(strDirectory, vbNormal)
Do While strFile <> ""
With sht
.Cells(i, 1) = strFile
.Cells(i, 2) = strDirectory + strFile
End With
'returns the next file or directory in the path
strFile = Dir()
i = i + 1
Loop
End Sub
See example below
Public Sub Listpng()
Const strFolder As String = "C:\SomeFolder\"
Const strPattern As String = "*.png"
Dim strFile As String
strFile = Dir(strFolder & strPattern, vbNormal)
Do While Len(strFile) > 0
Debug.Print strFile '<- view this in Immediate window; Ctrl+g will take you there
strFile = Dir
Loop
End Sub
There's a couple of procedures I use depending on whether I want subfolders as well.
This loops through the folder and adds path & name to a collection:
Sub Test1()
Dim colFiles As Collection
Dim itm As Variant
Set colFiles = New Collection
EnumerateFiles "C:\Users\michal\SkyDrive\csv\bossa\mstcgl_mst\", "*.xls*", colFiles
For Each itm In colFiles
Debug.Print itm
Next itm
End Sub
Sub EnumerateFiles(ByVal sDirectory As String, _
ByVal sFileSpec As String, _
ByRef cCollection As Collection)
Dim sTemp As String
sTemp = Dir$(sDirectory & sFileSpec)
Do While Len(sTemp) > 0
cCollection.Add sDirectory & sTemp
sTemp = Dir$
Loop
End Sub
This second way goes through the subfolders as well returning path & name. For some reason if you change InclSubFolders to False it only returns the name - got to sort that bit out.
Sub Test2()
Dim vFiles As Variant
Dim itm As Variant
vFiles = EnumerateFiles_2("C:\Users\michal\SkyDrive\csv\bossa\mstcgl_mst\", "xls*")
For Each itm In vFiles
Debug.Print itm
Next itm
End Sub
Public Function EnumerateFiles_2(sDirectory As String, _
Optional sFileSpec As String = "*", _
Optional InclSubFolders As Boolean = True) As Variant
EnumerateFiles_2 = Filter(Split(CreateObject("WScript.Shell").Exec _
("CMD /C DIR """ & sDirectory & "*." & sFileSpec & """ " & _
IIf(InclSubFolders, "/S ", "") & "/B /A:-D").StdOut.ReadAll, vbCrLf), ".")
End Function

Automating import of an Excel file

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

Import Excel files into Access whilst Looping

I am comfortable with using VBA to import excel sheets into access, and to loop through a given folder to bring back everything in there. However, I want to loop through a folder and only import a selection of the files. Can someone help? Each file is called REPORT1 etc and runs to REPORT67. I only want to pick 1-47.
Code below works fine, but this just copies everything in from the specified location.
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
I just replaced your code, "Do While Len(strFile) > 0" into "Do While Int(Mid(strFile, 7)) < 48", hope it helps.
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 Int(Mid(strFile, 7)) < 48
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
I would do:
Dir$()
DoWhile Val(Mid(filename, 7, 2))<48
Import the file
Dir$()
Loop