Что нового

[Ошибки] Как правильно обойти ошибку при открытии биотго файла Access ?

Houl777

Знающий
Сообщения
38
Репутация
5
Имеется вот такой честно найденный и доработанный скрипт:
Код:
#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). Как правильно ее обойти ?
 
Автор
H

Houl777

Знающий
Сообщения
38
Репутация
5
The requested action with this object has failed.
$oADO.Open ($adSource)^ ERROR

Думаю можно попробовать обойти при помощи ObjEvent
 

kaster

Мой Аватар, он лучший самый
Команда форума
Глобальный модератор
Сообщения
4,020
Репутация
626
Код:
Func _dbOpen($adSource)
   $oADO = ObjCreate("ADODB.Connection")
   If IsObj($oADO) Then
       $oADO.Provider = $adoProvider
       $oADO.Open ($adSource)
       Return $oADO
    EndIf
EndFunc    ;<===> _dbOpen()
 
Автор
H

Houl777

Знающий
Сообщения
38
Репутация
5
Как ни странно, данный код снова стал вызывать ошибку
The requested action with this object has failed.
$oADO.Open ($adSource)^ ERROR

Тестово получилось сделать так:

Код:
Func _dbOpen($adSource)

	$oMyError = ObjEvent("AutoIt.Error", "MyErrFunc")

	$oADO = ObjCreate("ADODB.Connection")
	$oADO.Provider = $adoProvider
	$oADO.Open ($adSource)
	If @error Then $oADO = 0
	Return $oADO

EndFunc

Func MyErrFunc($oError)
    Return SetError (1)
EndFunc


Дополнительно в функции _accessQueryLike () сделал исправление:

Код:
If IsObj($oADO) = 0 Then Return ("error")


И дописал дествие на "error".

Впринципе весь этот костыль на тестовых файлах работает.
 
Автор
H

Houl777

Знающий
Сообщения
38
Репутация
5
Т.е. так как там ввели данную фишку "Изменено: Ошибки при использовании объектов больше не являются критическими (работа скрипта не нарушается).", то теперь просто возвращается @error и все будет работать просто замечательно?

P.s. Не хочу ставить бэту - так как до финала все еще могут поменять.
 
Верх