Я обрабатываю 200 текстовых файлов в папке. Когда я их обрабатываю, я записываю прогресс в файл журнала. Когда я собираюсь прочитать его, когда он обработан, и если произойдет какое-либо предопределенное событие.
До сих пор я использовал Open и Close в подпункте WriteToLog
. Пока что такой проблемы нет (2 года).
Недавно возникла проблема: после непредсказуемого количества отдельных записей я получил: 70 - Permission denied
ошибка при:
Open sFileFullPath For Append As #filenumber
.
В качестве фатальной ошибки я прекращаю запуск приложения. - Подозреваю:
a) запрос на новую запись происходит до того, как будет выполнено предыдущее закрытие
b) файл журнала анализа антивируса с большим количеством операций
в) сбойный кластер на жестком диске.
d) некоторая ошибка файловой системы (поскольку chkdsk
обнаружил некоторые проблемы, но исправил их).
e) Я подозреваю также, что filenumber = FreeFile
техника, которую я недавно изменил, оказывает влияние на Close (не работает должным образом). 2 года с № 1, № 2, № 3 и т. Д. Без такой проблемы.
Это происходит, даже если я проверяю: If f_IsFileOpen(sFileFullPath)
, прежде чем пытаться открыть его для добавления.
Есть идеи, как точно определить проблему?
Option Explicit
Public bDevMode As Boolean '-- Development mode - Y/N= where Log file is Opened/Closed
Public sLogPath As String '-- store log path for easy change
Public sLogFileName As String
Sub ProcessFilesAndLog()
Dim sLogFileName As String
Dim sLogFileFullPath As String
Dim sErrMsg As String
Dim sInfo As String
'-- ini variables
bDevMode = False '-- i.e. in production mode
sLogFileName = ActiveSheet.Cells(5, 3) '-- "working.log"
sLogPath = ActiveSheet.Cells(6, 3) '-- "c:\temp\"
'-- STEP INI0.3.5 - try to Write into the Log file in LogFolder given by Options.
sLogFileFullPath = ActiveSheet.Cells(6, 3) '-- "c:\temp\"
sInfo = vbCrLf & Now & " --- Processing started"
p_WriteToLogINITEST sLogFileFullPath, sInfo, True, sErrMsg
sInfo = ""
'Application.Wait (Now + TimeValue("0:00:02"))
'--- what to test here ?
'-- STEP INI0.4 - when in PRODUCTION mode, Open the log file, only once. - 2019-05-09
If Not bDevMode Then
Open sLogFileFullPath For Append As #2 '-- HERE occassionally : 70 - Permission denied !
If sErrMsg <> "" Then Print #2, sErrMsg
End If '--- of If not bDevMode
sErrMsg = ""
'-- analyze files code ....
'-- close log file
If Not bDevMode Then
Close #2
End If
MsgBox "Finished!"
End Sub
и использованные подводные лодки:
'-- check if a file is still open
Function f_IsFileOpen(filename As String) As Boolean
Dim filenum As Integer
Dim errnum As Integer
On Error Resume Next ' Turn error checking off.
filenum = FreeFile() ' Get a free file number.
'-- Attempt to open the file and lock it.
Err.Clear
Open filename For Input Lock Read As #filenum
errnum = Err.Number ' Save the error number that occurred.
Close filenum ' Close the file.
On Error GoTo 0 ' Turn error checking back on.
'-- Check to see which error occurred.
Select Case errnum
'-- 0 - No error occurred - File is NOT open by another user.
Case 0
f_IsFileOpen = False
'-- 70 - Error number for "Permission Denied." File is already opened by another user.
Case 70
f_IsFileOpen = True
'-- 53 - doesn't exist
Case 53
f_IsFileOpen = False
'-- Another error occurred.
Case Else
f_IsFileOpen = True
'Error errnum
End Select
End Function
Sub p_WriteToLogINITEST(ByRef sLogFileFullPath As String, ByVal sMsg As String, ByVal bAppend As Boolean, ByRef sErrMsg As String)
Dim nCycleCnt As Integer
nCycleCnt = 1
On Error GoTo FILE_ERR
'-- Write ini processing msg to log file
If sMsg = "" Then sMsg = vbCrLf & Now & " --- Processing started"
If bAppend = True Then
Open sLogFileFullPath For Append As #2
Else
Open sLogFileFullPath For Output As #2
End If
Print #2, sMsg
Close #2
'-- Wait, until it's sure that previous log file writing has finished, incl. Close. Wait max 10 seconds.
Do While nCycleCnt < 11 '-- 10 trials
If f_IsFileOpen(sLogFileFullPath) Then
sErrMsg = sErrMsg & String(nCycleCnt, "#") & "," '-- for DEBUG ! only
Application.Wait (Now + TimeValue("0:00:01"))
Else '-- file IS NOT OPEN, i.e. I can LEAVE this sub !
Exit Do
End If
nCycleCnt = nCycleCnt + 1
Loop
Exit Sub
FILE_ERR:
sErrMsg = "M1.57: Fatal error: Error writing into the log file: " & sLogFile
'-- better error handling - 2019-05-08
On Error Resume Next
Close '-- MS HELP: If you omit filenumberlist, all active files opened by the Open statement are closed. - 2019-05-08
On Error GoTo 0 '-- terminate any further error handling here
End Sub
Чаще всего я получал ошибку 70, когда запускался первым после открытия XLSM, когда файл журнала еще не существовал и IDE закрывалась.