Je cherche à extraire certaines données contenues dans un fichier *.DBF (BDD dbase).
En farfouillant sur le net je suis tombé sur une fonction créée par Dmitry Yudin. Celle-ci date de 2009 et lorsque j'essaye de l'exécuter j'ai une erreur sur la ligne 40 (Case Asc("C") or Asc("D") or Else). Voici la fonction:
► Afficher le texte
#include-once
;===============================================================================
;
; Description: Directly read DBF database file to array
; Parameter(s): $sFileName - name of DBF file
; $nFlags
; 1 - convert from OEM to ANSI
; 2 - strip leading and trailing witespaces
; Requirement(s): Autoit 3.2.9.0 +
; Return Value(s): On Success - 2D array, first row - names of fields
; On Failure - no decent way to check errors
; Author(s): Dmitry Yudin (Lazycat)
; Version: 0.3
; Date: 14.12.2009
; Note(s): Many DBF functions and flags are not read - just because
; I wasn't need it
;
;===============================================================================
Func _FileReadDBF($sFileName, $nFlags = 0)
Local $hFile = FileOpen($sFileName, 16)
Local $pReadBuffer = DllStructCreate("byte[32]") ; Header size
DllStructSetData($pReadBuffer, 1, FileRead($hFile, 32))
$pDBFHeader = DllStructCreate("byte;byte;byte;byte;int;short;short;byte[20]" , DllStructGetPtr($pReadBuffer)) ; Header struct
$nRecords = DllStructGetData($pDBFHeader, 5) ; Get number of records
$nDataPos = DllStructGetData($pDBFHeader, 6) ; Get data start position
$nRecordSize = DllStructGetData($pDBFHeader, 7) ; Get record size (included deleted flag)
$nFields = Floor($nDataPos / 32) - 1
$nDataGap = $nDataPos - ($nFields + 1) * 32
Local $aData[$nRecords+1][$nFields]
Local $sRecordStruct = "byte;" ; Struct string, based on fields size and type, first byte - deleted mark
For $i=0 To $nFields - 1
DllStructSetData($pReadBuffer, 1, FileRead($hFile, 32))
$pField = DllStructCreate("char[11];byte;int;byte;byte[15]" , DllStructGetPtr($pReadBuffer)) ; Field structure
$aData[0][$i] = DllStructGetData($pField, 1) ; Name of field
; Create struct based on field size and type (now unfinished, treat all types as string)
Switch DllStructGetData($pField, 2)
Case Asc("C") or Asc("D") or Else
$sRecordStruct &= "char[" & DllStructGetData($pField, 4) & "];"
EndSwitch
Next
$sRecordStruct = StringTrimRight($sRecordStruct, 1) ; Trim last ";"
FileRead($hFile, $nDataGap) ; Skip ending marker, it's size may vary
$pReadBuffer = DllStructCreate("byte["&$nRecordSize&"]") ; New buffer, now based on record size
For $i = 1 To $nRecords
DllStructSetData($pReadBuffer, 1, FileRead($hFile, DllStructGetSize($pReadBuffer)))
$pRecord = DllStructCreate($sRecordStruct , DllStructGetPtr($pReadBuffer))
For $j = 0 To $nFields - 1
$aData[$i][$j] = DllStructGetData($pRecord, $j+2)
If BitAND($nFlags, 1) Then $aData[$i][$j] = _Ascii2Ansi($aData[$i][$j])
If BitAND($nFlags, 2) Then $aData[$i][$j] = StringStripWS($aData[$i][$j], 3)
Next
Next
FileClose($hFile)
Return $aData
EndFunc
;===============================================================================
;
; Description: Directly read DBF database file to array
; Parameter(s): $sFileName - name of DBF file
; $nFlags
; 1 - convert from OEM to ANSI
; 2 - strip leading and trailing witespaces
; Requirement(s): Autoit 3.2.9.0 +
; Return Value(s): On Success - 2D array, first row - names of fields
; On Failure - no decent way to check errors
; Author(s): Dmitry Yudin (Lazycat)
; Version: 0.3
; Date: 14.12.2009
; Note(s): Many DBF functions and flags are not read - just because
; I wasn't need it
;
;===============================================================================
Func _FileReadDBF($sFileName, $nFlags = 0)
Local $hFile = FileOpen($sFileName, 16)
Local $pReadBuffer = DllStructCreate("byte[32]") ; Header size
DllStructSetData($pReadBuffer, 1, FileRead($hFile, 32))
$pDBFHeader = DllStructCreate("byte;byte;byte;byte;int;short;short;byte[20]" , DllStructGetPtr($pReadBuffer)) ; Header struct
$nRecords = DllStructGetData($pDBFHeader, 5) ; Get number of records
$nDataPos = DllStructGetData($pDBFHeader, 6) ; Get data start position
$nRecordSize = DllStructGetData($pDBFHeader, 7) ; Get record size (included deleted flag)
$nFields = Floor($nDataPos / 32) - 1
$nDataGap = $nDataPos - ($nFields + 1) * 32
Local $aData[$nRecords+1][$nFields]
Local $sRecordStruct = "byte;" ; Struct string, based on fields size and type, first byte - deleted mark
For $i=0 To $nFields - 1
DllStructSetData($pReadBuffer, 1, FileRead($hFile, 32))
$pField = DllStructCreate("char[11];byte;int;byte;byte[15]" , DllStructGetPtr($pReadBuffer)) ; Field structure
$aData[0][$i] = DllStructGetData($pField, 1) ; Name of field
; Create struct based on field size and type (now unfinished, treat all types as string)
Switch DllStructGetData($pField, 2)
Case Asc("C") or Asc("D") or Else
$sRecordStruct &= "char[" & DllStructGetData($pField, 4) & "];"
EndSwitch
Next
$sRecordStruct = StringTrimRight($sRecordStruct, 1) ; Trim last ";"
FileRead($hFile, $nDataGap) ; Skip ending marker, it's size may vary
$pReadBuffer = DllStructCreate("byte["&$nRecordSize&"]") ; New buffer, now based on record size
For $i = 1 To $nRecords
DllStructSetData($pReadBuffer, 1, FileRead($hFile, DllStructGetSize($pReadBuffer)))
$pRecord = DllStructCreate($sRecordStruct , DllStructGetPtr($pReadBuffer))
For $j = 0 To $nFields - 1
$aData[$i][$j] = DllStructGetData($pRecord, $j+2)
If BitAND($nFlags, 1) Then $aData[$i][$j] = _Ascii2Ansi($aData[$i][$j])
If BitAND($nFlags, 2) Then $aData[$i][$j] = StringStripWS($aData[$i][$j], 3)
Next
Next
FileClose($hFile)
Return $aData
EndFunc
Merci de votre aide.




