I receive various spreadsheets from clients. I want to rename the source files to include the date the file was created by the client into the filename. I read a list of the file names, and store them in an Access table. I read the table, and for each file listed, i open excel so that i can get the built-in document property for the spreadsheet, and then attempt to rename the file.
The code works, but on some occasions, i get an ERROR 91 on the line that tries to retrieve the "creation date" of the excel file. I cannot determine a specific reason why it happens. Sometimes it works thru the full list of files, sometimes it does not. Sometimes I get ERROR 91 when there is only 1 file. And sometimes it runs fine thru a list of 5 to 10. The files are located on a network share, and my intuition is maybe the code is trying to access the property before the file is fully loaded into Excel. Is that possible? I have tried creating an artificial pause. Issue still exists. I tried actually making the spreadsheet active, even though i didn't think i should have to do this. I have turned off updating and alerts. None of this matters so far. Originally started with file scripting, instead of opening the excel files. but fso property for creation date looks like the date the file was created on our file system, NOT the date the client created the spreadsheet.
Private Sub RenameImportFiles()
'On Error GoTo ErrorHandler
Dim dbMedent As Database
Dim oFS As Object
Dim strFileParts() As String
Dim strDateParts() As String
Dim strDayParts() As String
Dim strTimeParts() As String
Dim strCreation As String
Dim strSQL As String
Dim rsRead As Recordset
Dim strFileName As String
Dim strFileNameNew As String
Dim intTime As Integer
Dim intRecExpect As Integer
Dim intRecCurr As Integer
Dim intRecComp As Integer
Me.txtProcWindow = "Renaming Import Files ..."
intRecExpect = 0
intRecCurr = 0
intRecComp = 0
'This creates an instance of the MS Scripting Runtime FileSystemObject class
Set oFS = CreateObject("Scripting.FileSystemObject")
strSQL = "SELECT * FROM Files_In_Folders ORDER BY FileName"
Set dbMedent = CurrentDb
Set rsRead = dbMedent.OpenRecordset(strSQL)
intRecExpect = rsRead.RecordCount
Me.txtFileCnt_Expect = intRecExpect
With rsRead
.MoveLast
.MoveFirst
If .RecordCount < 1 Then
'/***************** ERROR HANDLING ****************
End If
Dim xlApp As Excel.Application
Set xlApp = CreateObject("Excel.Application")
While Not .EOF
intRecCurr = intRecCurr + 1
Me.txtFileCnt_Current = intRecCurr
Me.txt_Curr_FileNm = strFileName
Me.txtCurr_FileID = rsRead![FileID]
strFileName = ![FilePath] & ![FileName]
xlApp.ScreenUpdating = False
xlApp.DisplayAlerts = False
xlApp.EnableEvents = False
xlApp.Visible = False
xlApp.Workbooks.Open FileName:=strFileName
'for debugging errror #91 pops up occasionally; why does it sometimes think property doesn't exist
'force excel to activate a sheet, then get property; or force excel to wait a few seconds???
Call WaitFor(1)
xlApp.Worksheets(1).Activate
'MsgBox "trying to open: " & strFileName
***strCreation = ActiveWorkbook.BuiltinDocumentProperties("Creation Date")***
strFileParts = Split(strCreation)
strDayParts = Split(strFileParts(0), "/")
strTimeParts = Split(strFileParts(1), ":")
If strFileParts(2) = "PM" Then
intTime = CInt(strTimeParts(0)) + 12
Else
intTime = CInt(strTimeParts(0))
End If
strFileNameNew = ![FilePath] & ![FilePracticeTIN] & "_" & _
strDayParts(2) & Format(strDayParts(0), "00") & Format(strDayParts(1), "00") & _
Format(intTime, "00") & Format(strTimeParts(1), "00") & Format(strTimeParts(2), "00") & _
"_" & ![FileMeas] & ![FileType]
ActiveWorkbook.Close SaveChanges:=False
oFS.CopyFile strFileName, strFileNameNew, True
rsRead.Edit
![FileName] = ![FilePracticeTIN] & "_" & _
strDayParts(2) & Format(strDayParts(0), "00") & Format(strDayParts(1), "00") & _
Format(intTime, "00") & Format(strTimeParts(1), "00") & Format(strTimeParts(2), "00") & _
"_" & ![FileMeas] & ![FileType]
![FileRptDate] = strDayParts(2) & Format(strDayParts(0), "00") & Format(strDayParts(1), "00")
![FileRptTime] = Format(intTime, "00") & Format(strTimeParts(1), "00") & Format(strTimeParts(2), "00")
rsRead.Update
intRecComp = intRecComp + 1
Me.txtFileCnt_Good = intRecComp
Me.txtFileCnt_Bad = intRecExpect - intRecComp
Me.txt_Curr_FileNm = strFileName
DoEvents
rsRead.MoveNext
Wend
End With
xlApp.ScreenUpdating = True
xlApp.DisplayAlerts = True
xlApp.EnableEvents = True
xlApp.Quit
RenameImportFiles_Exit:
xlApp.Quit
Set dbMedent = Nothing
Set oFS = Nothing
Me.txtProcWindow = Me.txtProcWindow & vbCrLf & SPACE8 & "Expected " & intRecExpect & " files." & _
vbCrLf & SPACE8 & "Renamed " & intRecComp & " files." & _
vbCrLf & SPACE8 & (intRecExpect - intRecComp) & " files had Errors or other issues." & _
vbCrLf & SMALL_DONE
Call HideProgressBar(True)
Exit Sub
ErrorHandler:
MsgBox "Error #: " & Err.Number & vbCrLf & vbCrLf & Err.Description
Resume RenameImportFiles_Exit
End Sub
Error 91 does not always happen. It can occur when 1 file to rename or many. It's not any specific interval that i can tell. Example, 5 files to process. 1st pass, it renames 2 files, then error 91 on file 3. 20 minutes later, i try again, and all 5 get processed no problem. 10 minutes later, i try again, and it ERROR 91 on the first file. if i msgbox the filename, it seems to work every time. but when this process is moved to production, that is not a feasible option, since we expect to process 30 to 40 files at a time, from 2 to 3 clients a day.
Dim xlApp As Excel.Application Set xlApp = CreateObject("Excel.Application")
You're early-bound, there's no need to hit the registry with CreateObject
to get a hold of the Excel.Application
type. Just New
it up, the compiler already knows where to find it:
Set xlApp = New Excel.Application
You're discarding the returned Workbook
object here:
xlApp.Workbooks.Open FileName:=strFileName
Capture it instead:
Dim xlBook As Workbook
Set xlBook = xlApp.Workbooks.Open(strFileName)
This is a problem:
strCreation = ActiveWorkbook.BuiltinDocumentProperties("Creation Date")
Unqualified, ActiveWorkbook
is implicitly creating an Excel.Global
/ Excel.Application
object to which you hold no reference: that object is not your xlApp
- it's an implicit ghost instance that gets created implicitly, and it has no workbook that's active, which would explain error 91. Qualify the member call:
strCreation = xlApp.ActiveWorkbook.BuiltinDocumentProperties("Creation Date")
But really if you captured the workbook variable, you couldn't care less what the active workbook is:
strCreation = xlBook.BuiltinDocumentProperties("Creation Date")
Same here:
ActiveWorkbook.Close SaveChanges:=False
Turn to:
xlBook.Close SaveChanges:=False
There may be a number of "ghost" EXCEL.EXE processes lingering in Task Manager after Access is closed: you'll have to manually kill these processes if that's the case.
This is also potentially problematic:
xlApp.Quit RenameImportFiles_Exit: xlApp.Quit
If the While...Wend
loop (should be Do While...Loop
) runs to completion, then xlApp.Quit
gets to run twice... that can't be right.
'for debugging errror #91 pops up occasionally; why does it sometimes think property doesn't exist
Error 91 doesn't mean "property doesn't exist", that would be error 438. Error 91 means " object doesn't exist", as in, you want to invoke foo.Bar
, but foo
is Nothing
.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.