#include "FiveWin.ch"
PROCEDURE Main
LOCAL cFilePath := "x:\xwhdaten\datawin\KUNDEN.dbf"
LOCAL cName := "Otto"
LOCAL nStartTime := SECONDS()
LOCAL aResult, nEndTime, nDuration
LOCAL hRecord
aResult := FindNameInDbf(cFilePath, cName)
nEndTime := SECONDS()
nDuration := (nEndTime - nStartTime) * 1000 // Dauer in Millisekunden
? "Suchzeit: " + STR(nDuration, 10, 2) + " ms"
? "Gefundene Datensätze: " + LEN(aResult[1])
// ? "Recordnummern: " + ARRAYTOSTR(aResult[2], ", ")
// Ausgabe der gefundenen Datensätze
? "Recordnummer", "Name", "Vorname", "Straße", "Ort"
FOR EACH hRecord IN aResult[1]
? hRecord["recno"], hRecord["NAME"], hRecord["VORNAME"], hRecord["STRASSE"], hRecord["ORT"]
NEXT
RETURN
FUNCTION FindNameInDbf(cFilePath, cName)
LOCAL nHandle := FOPEN(cFilePath)
LOCAL cHeader := SPACE(32)
LOCAL nHeaderSize, nRecordSize, nNumRecords
LOCAL aFieldDescriptors := {}
LOCAL aFieldOffsets := {}
LOCAL nOffset := 0
LOCAL cFieldDescriptor, cFieldName
LOCAL nFieldLength
LOCAL nNameOffset, nNameLength
LOCAL aMatchingRecords := {}
LOCAL aMatchingRecordNumbers := {}
LOCAL cRecord, cLastName
LOCAL hField, hRecordData
LOCAL i
LOCAL cFieldValue
LOCAL hFieldDescriptor := {=>}
LOCAL nFieldCount, nField, nFieldLen
IF nHandle == -1
? "Konnte die Datei nicht öffnen."
RETURN {}
ENDIF
// Header lesen
// Header lesen
FREAD(nHandle, @cHeader, 32)
// Byte-Interpretation der Header-Daten
nNumRecords := Bit32Unpack(SUBSTR(cHeader, 5, 4))
nHeaderSize := Bit16Unpack(SUBSTR(cHeader, 9, 2))
nRecordSize := Bit16Unpack(SUBSTR(cHeader, 11, 2))
// ? "nNumRecords: " + STR(nNumRecords)
// ? "nHeaderSize: " + STR(nHeaderSize)
// ? "nRecordSize: " + STR(nRecordSize)
// Felddeskriptoren lesen
FSEEK(nHandle, 32)
DO WHILE .T.
cFieldDescriptor := SPACE(32)
FREAD(nHandle, @cFieldDescriptor, 32)
IF ASC(LEFT(cFieldDescriptor, 1)) == 13
EXIT
ENDIF
cFieldName := RTRIM(SUBSTR(cFieldDescriptor, 1, 11))
nFieldLength := ASC(SUBSTR(cFieldDescriptor, 17, 1))
AADD(aFieldDescriptors, { "name" => cFieldName, "length" => nFieldLength })
ENDDO
//ok ? valtype(aFieldDescriptors)
//ok xbrowse(aFieldDescriptors)
// Feld-Offsets berechnen
FOR i:= 1 TO len( aFieldDescriptors )
//xbrowse( aFieldDescriptors[i] )
hFieldDescriptor := aFieldDescriptors[i]
//ok? hFieldDescriptor["name"]
//ok ? nOffset
//ok ? hFieldDescriptor["length"]
AAdd(aFieldOffsets, { hFieldDescriptor["name"], nOffset, hFieldDescriptor["length"] })
nOffset += hFieldDescriptor["length"]
NEXT
//ok
// xbrowse(aFieldOffsets)
//? valtype(aFieldOffsets[1])
//xbrowse(aFieldOffsets[1])
//AScan( aFieldOffsets , { |a| msginfo( ( a[1] ) ) } )
// xbrowse(aFieldOffsets )
// ? AScan( aFieldOffsets, { |a| a[1] } )
// I := AScan( aFieldOffsets, { |a| a[ 1 ] == "NAME" } )
//OK AScan( aFieldOffsets , { |a| msginfo(len(a[1])) , msginfo( "-" + ( ALLTRIM( a[1] ) ) + "-" ) } )
//OK ? AScan( aFieldOffsets, { |a| left( a[ 1 ], 10 ) = "NAME" } )
// Offset für das Feld "NAME" finden
nNameOffset := AScan( aFieldOffsets, { |a| left( a[ 1 ], 10 ) = "NAME" } )
? aFieldOffsets[ nNameOffset, 1]
nNameLength := aFieldOffsets[ nNameOffset, 3]
? nNameLength
// aFieldDescriptors[ASCAN(aFieldDescriptors, {|h| h["name"] == "NAME" })]["length"]
// bis hier her getestet
FSEEK(nHandle, nHeaderSize)
FOR i := 1 TO nNumRecords
cRecord := SPACE(nRecordSize)
FREAD(nHandle, @cRecord, nRecordSize)
// hier wird der record ausgelesen
// ok ? cRecord
cLastName := RTRIM(SUBSTR(cRecord, nNameOffset + 1, nNameLength))
? cLastName
IF !EMPTY(cLastName) .AND. AT("vogel", LOWER(cLastName)) == 1
hRecordData := { "recno" => i }
nOffset := 0
FOR EACH hField IN aFieldDescriptors
cFieldValue := RTRIM(SUBSTR(cRecord, nOffset + 1, hField["length"]))
hRecordData[hField["name"]] := cFieldValue
nOffset += hField["length"]
NEXT
AADD(aMatchingRecords, hRecordData)
AADD(aMatchingRecordNumbers, i)
ENDIF
NEXT
FCLOSE(nHandle)
RETURN { aMatchingRecords, aMatchingRecordNumbers }
FUNCTION Bit16Unpack(cData)
RETURN (ASC(SUBSTR(cData, 1, 1)) + (ASC(SUBSTR(cData, 2, 1)) * 256))
FUNCTION Bit32Unpack(cData)
RETURN (ASC(SUBSTR(cData, 1, 1)) + (ASC(SUBSTR(cData, 2, 1)) * 256) + (ASC(SUBSTR(cData, 3, 1)) * 65536) )