Имеется вот такой честно найденный и доработанный скрипт:
Работает хорошо. Но иной раз оказывается что база Access битая и это вызывает критическую ошибку в $oADO.Open ($adSource). Как правильно ее обойти ?
Код:
#Include <Array.au3>
#Include <File.au3>
Global Const $adOpenStatic = 3
Global Const $adLockOptimistic = 3
Global Const $adoProvider = _adoProvider()
Dim $oWS
_FileReadToArray (@ScriptDir&"\WS.txt", $oWS)
If @error Then Exit
$file = FileOpen(@ScriptDir&"\log.txt",2)
If @error Then Exit
_main($oWS)
FileClose($file)
Exit
Func _main($fWS)
$i = 0
Do
$i = $i + 1
If _Path($fWS[$i]) = 3 Then
FileWrite($file,$fWS[$i]&@CRLF)
FileWrite($file,"Рабочая станция недоступна"&@CRLF)
FileWrite($file,"-------------"&@CRLF)
Else
If _Path($fWS[$i]) = 1 Then
FileCopy ("\\"&$fWS[$i]&"\c$\Program Files\databases\admlog.mdb",@ScriptDir&"\DB\"&$fWS[$i]&".mdb",9)
$_array = _accessQueryLike(@ScriptDir&"\DB\"&$fWS[$i]&".mdb","Admlog", "Flg","4096")
ElseIf _Path($fWS[$i]) = 2 Then
FileCopy ("\\"&$fWS[$i]&"\c$\Program Files (x86)\databases\admlog.mdb",@ScriptDir&"\DB\"&$fWS[$i]&".mdb",9)
$_array = _accessQueryLike(@ScriptDir&"\DB\"&$fWS[$i]&".mdb","Admlog", "Flg","4096")
EndIf
FileWrite($file,$fWS[$i]&@CRLF)
;For $j = 1 To $_array[0] Step 1
If $_array = 1 Then
FileWrite($file,"Изменений нет"&@CRLF)
FileWrite($file,"-------------"&@CRLF)
Else
$info = StringSplit($_array[$_array[0]], " ")
$date = StringRegExp($info[1], "(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})",1)
FileWrite($file,$date[0]&"."&$date[1]&"."&$date[2]&" "&$date[3]&":"&$date[4]&":"&$date[5]&@CRLF)
FileWrite($file,"-------------"&@CRLF)
EndIf
EndIf
Until $i = $fWS[0]
EndFunc
Func _Path ($pWS)
Local $iCount = 1
While FileExists("\\"&$pWS&"\c$\Program Files\databases\admlog.mdb") = 0 ;Or FileExists("D:\FILEPATH2") = 0
If $iCount = 100 Then ; 10 seconds in total.
$iCount = 0
ExitLoop
EndIf
Sleep(10)
$iCount += 1
WEnd
If Not $iCount Then
Local $iCount = 1
While FileExists("\\"&$pWS&"\c$\Program Files (x86)\databases\admlog.mdb") = 0 ;Or FileExists("D:\FILEPATH2") = 0
If $iCount = 100 Then ; 10 seconds in total.
$iCount = 0
ExitLoop
EndIf
Sleep(10)
$iCount += 1
WEnd
If $iCount Then
Return (2)
Else
Return (3)
EndIf
Else
Return (1)
EndIf
EndFunc
Func _accessQueryLike($adSource,$adTable, $adCol,$Find, $adFull = 1)
Local $I, $Rtn
$oADO = 'ADODB.Connection'
If IsObj($oADO) Then
$oADO = ObjGet('',$oADO)
Else
$oADO = _dbOpen($adSource)
EndIf
If IsObj($oADO) = 0 Then Return SetError(1)
$oRec = _dbOpenRecordset();ObjCreate("ADODB.Recordset")
If IsObj($oRec) = 0 Then Return SetError(2)
$oRec.Open ("SELECT * FROM "& $adTable & " WHERE " & $adCol & " Like '%" & $Find & "%'", $oADO, $adOpenStatic, $adLockOptimistic)
If $oRec.RecordCount < 1 Then
Return SetError(1)
Else
SetError(0)
$oRec.MoveFirst()
;MsgBox(0,'TEST', "Number of records: " & $oRec.RecordCount);;<<====== For testing only
Do
If $adFull = 1 Then
For $I = 0 To _accessCountFields($adSource,$adTable)-1
;MsgBox(0,'TEST 2 ', "Value of field " & $oRec.Fields($I).Name & ' is:' & @CRLF & @CRLF & $oRec.Fields($I).Value);;<<====== For testing only
$Rtn = $Rtn & $oRec.Fields($I).Value &" "& Chr(28);;<<====== Separate the fields with a non-printable character
Next
EndIf
$Rtn = $Rtn & Chr(29);;<<====== Separate the records with a non-printable character
$oRec.MoveNext()
Until $oRec.EOF
$oRec.Close()
$oADO.Close()
If $adFull = 1 Then Return StringSplit(StringTrimRight($Rtn, 2),Chr(29))
Return StringSplit(StringTrimRight($Rtn, 1),Chr(29))
EndIf
EndFunc ;<===> _accessQueryLike()
Func _dbOpen($adSource)
$oADO = ObjCreate("ADODB.Connection")
$oADO.Provider = $adoProvider
$oADO.Open ($adSource)
Return $oADO
EndFunc ;<===> _dbOpen()
Func _adoProvider()
Local $oProvider = "Microsoft.Jet.OLEDB.4.0; "
Local $objCheck = ObjCreate("Access.application")
If IsObj($objCheck) Then
Local $oVersion = $objCheck.Version
If StringLeft($oVersion, 2) == "12" Then $oProvider="Microsoft.ACE.OLEDB.12.0; "
EndIf
Return $oProvider
EndFunc
Func _dbOpenRecordset()
$oRec = ObjCreate("ADODB.Recordset")
Return $oRec
EndFunc ;<===> _dbOpenRecordset()
Func _accessCountFields($adSource,$adTable)
$oADO = 'ADODB.Connection'
If IsObj($oADO) Then
$oADO = ObjGet('',$oADO)
Else
$oADO = _dbOpen($adSource)
EndIf
If IsObj($oADO) = 0 Then Return SetError(1)
$oRec = _dbOpenRecordset();ObjCreate("ADODB.Recordset")
If IsObj($oRec) = 0 Then Return SetError(2)
$oRec.open ($adTable , $oADO, $adOpenStatic, $adLockOptimistic)
$Fc = $oRec.fields.count
$oRec.Close
$oADO.Close
Return $Fc
EndFunc ;<===> _accessCountFields()
Работает хорошо. Но иной раз оказывается что база Access битая и это вызывает критическую ошибку в $oADO.Open ($adSource). Как правильно ее обойти ?