DBF Files
-
BackupUser
- PureBasic Guru

- Posts: 16777133
- Joined: Tue Apr 22, 2003 7:42 pm
Restored from previous forum. Originally posted by blueb.
For those of you who want XBase compatibility without using ODBC you might want to try a product called Cheetah. It's definitly fast. I have used it with PowerBASIC and VB. I haven't tried it with PureBasic yet...hopefully this week.
It's a complete multi-user DLL less than 60k. And has a free demo at their web site for you to try. http://www.planetsquires.com/cheetah.htm
Regards,
--Bob
For those of you who want XBase compatibility without using ODBC you might want to try a product called Cheetah. It's definitly fast. I have used it with PowerBASIC and VB. I haven't tried it with PureBasic yet...hopefully this week.
It's a complete multi-user DLL less than 60k. And has a free demo at their web site for you to try. http://www.planetsquires.com/cheetah.htm
Regards,
--Bob
-
BackupUser
- PureBasic Guru

- Posts: 16777133
- Joined: Tue Apr 22, 2003 7:42 pm
-
BackupUser
- PureBasic Guru

- Posts: 16777133
- Joined: Tue Apr 22, 2003 7:42 pm
Restored from previous forum. Originally posted by blueb.
Hi Siggi,
As you know, the best things in life are free, but not database systems. While I have a lot of code to build dbf files, it would take me 2 lifetimes to build something that could even compare with a commercial product.
Think of it:
- date manipulation routines
- multiuser access system
- built-in query engine
- file encryption system (3 or 4 different ones)
- etc, etc.
And time is money, as they say. So... for a few dollars??? That'd be like trying to build what Fred's built.
Regards,
--Bob
Hi Siggi,
As you know, the best things in life are free, but not database systems. While I have a lot of code to build dbf files, it would take me 2 lifetimes to build something that could even compare with a commercial product.
Think of it:
- date manipulation routines
- multiuser access system
- built-in query engine
- file encryption system (3 or 4 different ones)
- etc, etc.
And time is money, as they say. So... for a few dollars??? That'd be like trying to build what Fred's built.
Regards,
--Bob
-
BackupUser
- PureBasic Guru

- Posts: 16777133
- Joined: Tue Apr 22, 2003 7:42 pm
Restored from previous forum. Originally posted by Rings.
and remember, if a thirdpartyproduct has a bug, your appz too.
It's not the money ($89 is not a lot for a database) its the complete control (The Source) over the database in my own hands.
And for our small appz in PureBasic, most databases are overloaded with functionality.
For example if you want a simple address-manager, you don't need those features which cheetah has.Btw. cheetah was a cool product for a small price.
If i want more stable for buisness, i prefer pure SQL (where $89 is a lack).
Years ago i have bought the source for VB-compatible Dbase3/4 access.Believe me, i'm totally happy to have the source, coz i can do(code) what i want with it.And can fix some errors too.
Getting better with a little help from my friends....thx Siggi
and remember, if a thirdpartyproduct has a bug, your appz too.
It's not the money ($89 is not a lot for a database) its the complete control (The Source) over the database in my own hands.
And for our small appz in PureBasic, most databases are overloaded with functionality.
For example if you want a simple address-manager, you don't need those features which cheetah has.Btw. cheetah was a cool product for a small price.
If i want more stable for buisness, i prefer pure SQL (where $89 is a lack).
Years ago i have bought the source for VB-compatible Dbase3/4 access.Believe me, i'm totally happy to have the source, coz i can do(code) what i want with it.And can fix some errors too.
Getting better with a little help from my friends....thx Siggi
-
BackupUser
- PureBasic Guru

- Posts: 16777133
- Joined: Tue Apr 22, 2003 7:42 pm
-
BackupUser
- PureBasic Guru

- Posts: 16777133
- Joined: Tue Apr 22, 2003 7:42 pm
Restored from previous forum. Originally posted by Rings.
Today i began with developing Dbase(Xbase) functions for PureBasic in native PureBasic.
First tests going very well and very speedy.On my Roadmap are acess for *.dbf,*.dbt and *.ndx Files.Also an easy forumla-expressor(mini sql) is planed.The Code will been developed and tested simultan between Windows-PC and Linux version.If anyone will test them under Amiga, just inform me.
Hope to release first versions at eastern.
Any suggestions welcome.
Getting better with a little help from my friends....thx Siggi
Today i began with developing Dbase(Xbase) functions for PureBasic in native PureBasic.
First tests going very well and very speedy.On my Roadmap are acess for *.dbf,*.dbt and *.ndx Files.Also an easy forumla-expressor(mini sql) is planed.The Code will been developed and tested simultan between Windows-PC and Linux version.If anyone will test them under Amiga, just inform me.
Hope to release first versions at eastern.
Any suggestions welcome.
Getting better with a little help from my friends....thx Siggi
- the.weavster
- Addict

- Posts: 1581
- Joined: Thu Jul 03, 2003 6:53 pm
- Location: England
dBase functions for PureBasic
Did anyone make any progress with theseBackupUser wrote:<i>Restored from previous forum. Originally posted by <b>Rings</b>.</i><br /><br /> Today i began with developing Dbase(Xbase) functions for PureBasic in native PureBasic.<br />First tests going very well and very speedy.On my Roadmap are acess for *.dbf,*.dbt and *.ndx Files.Also an easy forumla-expressor(mini sql) is planed.The Code will been developed and tested simultan between Windows-PC and Linux version.If anyone will test them under Amiga, just inform me.<br />Hope to release first versions at eastern.<br />Any suggestions welcome.<br /><br />Getting better with a little help from my friends....thx Siggi
- the.weavster
- Addict

- Posts: 1581
- Joined: Thu Jul 03, 2003 6:53 pm
- Location: England
CDBFAPI.DLL
Has anybody tried using CDBFAPI.DLL?
It's available from:
http://www.whitetown.com
It only costs $15.00 ($50 with source code) and has 120 commands for manipulating xBase files.
Unfortunately alot of the parameters and results of functions are passed in structures. There are files that define these for pascall and c++, maybe someone familiar with one of these languages would be willing to translate them to PB.
It's available from:
http://www.whitetown.com
It only costs $15.00 ($50 with source code) and has 120 commands for manipulating xBase files.
Unfortunately alot of the parameters and results of functions are passed in structures. There are files that define these for pascall and c++, maybe someone familiar with one of these languages would be willing to translate them to PB.
- Michael Vogel
- Addict

- Posts: 2820
- Joined: Thu Feb 09, 2006 11:27 pm
- Contact:
...years later...nicksteel wrote:Has anyone made any progress with using Purebasic with DBF files?
I have to read some old dbase files to make some reports, the files are relatively big (up to 50MByte) and the cheetah (dll) seems to be only fast on short files. So I started doing some procedures for my own - if someone is interested, I'll post it here (but a lot of things are still missing, maybe I'll NEVER realize procedures for floating point numbers, because I've seen a lot of rounding issues for now)
Michael
What version of Cheetah are you using? It's as fast as any dBase product that I've seen.
A 50mb file isn't large. Perhaps a sample of what you're trying to do would help.
--blueb
A 50mb file isn't large. Perhaps a sample of what you're trying to do would help.
--blueb
- It was too lonely at the top.
System : PB 6.21(x64) and Win 11 Pro (x64)
Hardware: AMD Ryzen 9 5900X w/64 gigs Ram, AMD RX 6950 XT Graphics w/16gigs Mem
System : PB 6.21(x64) and Win 11 Pro (x64)
Hardware: AMD Ryzen 9 5900X w/64 gigs Ram, AMD RX 6950 XT Graphics w/16gigs Mem
- Michael Vogel
- Addict

- Posts: 2820
- Joined: Thu Feb 09, 2006 11:27 pm
- Contact:
Thanks for trying to help - I just downloaded the last version available on the net (cheetah2.dll) and tried the following:blueb wrote:What version of Cheetah are you using? It's as fast as any dBase product that I've seen.
A 50mb file isn't large. Perhaps a sample of what you're trying to do would help.
--blueb
I just scan through a relatively big/small/normal
Code: Select all
XIncludeFile "CheetahInc.pb"
xdbUseDLL()
dBaseArtikel=xdbOpen("g:\auf\00001\fpos.dbf")
Debug dBaseArtikel
Records=xdbRecordCount(dbaseartikel)
Fields=xdbFieldCount(dbaseartikel)
Debug fields
FieldNumber=1
Debug xdbFieldName(dbaseartikel, FieldNumber)
Debug xdbFieldType(dbaseartikel, FieldNumber)
Debug xdbFieldLength(dbaseartikel, FieldNumber)
;Debug xdbFieldDecimals(dbaseartikel, FieldNumber)
MessageRequester("Achtung!","Durchsuche "+Str(records)+" Einträge...")
wg=xdbFieldnumber(dbaseartikel, "wg")
gp=xdbFieldnumber(dbaseartikel, "GP")
test.q=0
Debug wg
For i=1 To records
xdbGetRecord(dbaseartikel,i)
If xdbFieldValue(dbaseartikel,"",wg)="Battery"
test+1
EndIf
Next i
Debug "ok"
MessageRequester("Ergebnis:",StrQ(test))
Code: Select all
; Define
EnableExplicit
#dBaseMaxFiles=100
#dBaseMaxFields=1000
#dBaseIgnoreErrors=#False
#dBaseEnableDebug=#True
#dBaseDatabaseCode=3
#dBaseFieldEndCode=$d
#dBasePositionStart=4
#dBasePositionFields=32
Global dBaseFieldCounter=0
Structure dBaseFileStructure
;ID.l
Name.s
;Open.w
Records.l
Start.w
Size.w
FieldID.l
Fields.l
EndStructure
Structure dBaseFieldStructure
Name.s
Type.c
Offset.l
Size.b
Fix.b
EndStructure
Global Dim dBaseFile.dBaseFileStructure(#dBaseMaxFiles)
Global Dim dBaseField.dBaseFieldStructure(#dBaseMaxFields)
Global *MemBlock=AllocateMemory(256); die maximale Länge eines Feldes ist 255 Zeichen
; Aufbau eriner dBase-Datei (empirisch ermittelt):
;
; Byte Länge Inhalt
; 0 1 Kennung 3 (dBase-Datei-III ohne Memofelder)
; 1 3 letzte Änderung Tag/Monat/Jahr
; 4 4 Anzahl der Einträge
; 6 2 Start der Datensätze
; 8 2 Länge eines Datensatzes (inklusive Löschbyte)
; 10 20 ?
; 32 11 1. Feld, Name ('_' anstelle ' ', Null-Byte schließt ab)
; 43 1 1. Feld, Typ ('C' Character, 'N' Numeric, 'L' Logical, 'D' Date)
; 44 4 1. Feld, Offset (kann auch leer bleiben)
; 48 1 1. Feld, Länge
; 49 1 1. Feld, Dezimalzeichen
; 50 14 1. Feld, ?
; 64 : 2. Feld, Name...
; :
; : 1 Endesymbol ($D)
; : 1 1. Eintrag, Löschbyte (' ' oder '*') ?
; : 1. Eintrag, Feld 1, 2, 3,...
; : 1 2. Eintrag, Löschbyte (' ' oder '*') ?
; : 2. Eintrag, Feld 1, 2, 3,...
; : 1 Endesymbol ($1A)
; EndDefine
Macro MyDebug(zahl,text="Wert",format=Str)
If #DBaseEnableDebug
Debug text+": "+format#(zahl)
EndIf
EndMacro
Procedure.s ReadStringLen(id,len)
ReadData(id,*MemBlock,len)
PokeB(*MemBlock+len,0)
ProcedureReturn PeekS(*MemBlock)
EndProcedure
Procedure dBaseError(text.s,file=0,record=0,field=0)
If #dBaseIgnoreErrors=#False
If file+record+field
text+#CR$+LSet("",Len(text)>>1,"—")+#CR$
If file : text+"Datei: "+GetFilePart(dBaseFile(file)\Name)+#CR$ : EndIf
If record: text+"Eintrag: "+Str(record)+#CR$ : EndIf
If field : text+"Feld: "+dBaseField(field)\Name+#CR$ : EndIf
EndIf
MessageBox_(0,text,"dBase-Problem",#MB_ICONERROR|#MB_OK)
End
EndIf
EndProcedure
Procedure dBaseCheckFileID(id,name.s)
If id<#dBaseMaxFiles
;dBaseFileCounter+1
;ReDim dBaseFile.dBaseFileStructure(dBaseFileCounter)
With dBaseFile(id)
;\ID=id
If \Name=""
\Name=name
\Records=0
Else
dBaseError("Datenbank ID bereits in Verwendung!",id)
EndIf
EndWith
Else
dBaseError("Zuviele Datenbanken aktiv!")
EndIf
EndProcedure
Procedure dBaseIncFieldCounter(n=1)
If dBaseFieldCounter+n>#dBaseMaxFields
dBaseError("Zuviele Datenfelder aktiv!")
Else
dBaseFieldCounter+n; neue Array-Größe
;ReDim dBaseField.dBaseFieldStructure(dBaseFieldCounter)
EndIf
EndProcedure
Procedure.s dBaseReadField(id,record,field)
record-1
field+dBaseFile(id)\FieldID
;Mydebug(dBaseFile(id)\Start,Str(dBaseFile(id)\Size*record+dBaseField(field)\Offset))
;Mydebug(dBaseField(field)\offset,Str(dBaseField(field)\Offset))
FileSeek(id,dBaseFile(id)\Start+dBaseFile(id)\Size*record+dBaseField(field)\Offset)
ProcedureReturn ReadStringLen(id,dBaseField(field)\Size)
EndProcedure
Procedure.l dBaseGetFieldNr(id,name.s)
Protected n=dBaseFile(id)\FieldID
Protected i=dBaseFile(id)\Fields
name=LCase(name)
While i
If name=LCase(dBaseField(n+i)\name)
Break
EndIf
i-1
Wend
If i=0
dBaseError("Feldname '"+name+"' nicht definiert!",id)
EndIf
ProcedureReturn i
EndProcedure
Procedure dBaseDefineFile(id,name.s,fields.s); Offset, Size etc. fehlt noch...
Protected i,j,n,z
; Array vergrößern...
dBaseCheckFileID(id,name)
; Felder überprüfen...
n=CountString(fields,"|")
If (n>1) And (n%3<>1)
n=(n+1)/3
; Array vergrößern...
z=dBaseFieldCounter
dBaseIncFieldCounter(n)
With dBaseFile(id)
\Fields=n
\FieldID=z
EndWith
; Felddaten übernehmen...
j=0
For i=1 To n
MyDebug(i,"Feld")
z+1
With dBaseField(z)
j+1 : \Name=StringField(fields,j,"|")
j+1 : \Type=Asc(StringField(fields,j,"|"))&$DF
j+1 : \Size=Val(StringField(fields,j,"|"))
If FindString("NCDL",Chr(\Type),1)=0;
dBaseError("Ungültiger Typ "+#DQUOTE$+Chr(\Type)+#DQUOTE$+"!",id,0,dBaseFieldCounter)
EndIf
MyDebug(\Name,"Name",Trim)
MyDebug(\Type,"Typ",Chr)
MyDebug(\Size,"Länge")
EndWith
Next i
Else
dBaseError("Falsche Felddefinition!",id)
EndIf
EndProcedure
Procedure.l dBaseOpenFile(id,name.s)
Protected i,n,z
Protected dummy.s
dBaseCheckFileID(id,name.s)
If FileSize(name)>#dBasePositionFields
If OpenFile(id,name)
If ReadByte(id)=#dBaseDatabaseCode
FileSeek(id,#dBasePositionStart)
With dBaseFile(id)
\Records=ReadLong(id)
\Start=ReadWord(id)
\Size=ReadWord(id)
\Fields=0
\FieldID=dBaseFieldCounter
MyDebug(\Records,"Einträge")
MyDebug(\Start,"Start")
MyDebug(\Size,"Länge")
MyDebug(\FieldID,"Felder")
MyDebug(dBaseFieldCounter,"Zeiger")
EndWith
FileSeek(id,#dBasePositionFields)
n=0
Repeat
;z=dBaseIncFieldCounter(\Records)
dummy.s=ReadStringLen(id,11); 10 Zeichen + Null
If Asc(dummy)=#dBaseFieldEndCode
Break
Else
n+1
dBaseIncFieldCounter()
With dBaseField(dBaseFieldCounter)
\Name=dummy
\Type=ReadByte(id)
\Offset=ReadLong(id); gefällt mir nicht, lieber 'händisch' ausrechnen...
\Offset=1; Offset=0: Löschzeichen (' ': ok, '*': Datensatz gelöscht)
If n>1 : \Offset=dBaseField(dBaseFieldCounter-1)\Offset+dBaseField(dBaseFieldCounter-1)\Size : EndIf
\Size=ReadByte(id)
\Fix=ReadByte(id)
dummy.s=ReadStringLen(id,14)
;MyDebug(\Name,Str(n),Trim)
EndWith
EndIf
ForEver
dBaseFile(id)\Fields=n
Else
dBaseError("Keine gültige Datenbank!",id)
EndIf
ProcedureReturn #True
Else
dBaseError("Datei kann nicht geöffnet werden!",id)
EndIf
Else
dBaseError("Datei existiert nicht oder ist zu klein!",id)
EndIf
ProcedureReturn #False
EndProcedure
; Test-Beispiel
; dBase-Dateien öffnen...
dBaseOpenFile(2,"g:\auf\00001\fpos.dbf")
; Felder suchen...
Define f=dBaseGetFieldNr(2,"Wg")
Define g=dBaseGetFieldNr(2,"Gp")
Define i.l
Define test.q
Define dummy.s
MessageRequester("Achtung!","Durchsuche "+Str(dBaseFile(2)\Records)+" Einträge...")
; alle Einträge durchgehen...
For i=1 To dBaseFile(2)\records
dummy=Trim(dBaseReadField(2,i,f)); Texteintrag lesen, Leerzeichen entfernen...
;OemToChar_(@dummy,@dummy); Umlaute anpassen...
If dummy="Battery"; Daten ausfiltern...
;dummy=dBaseReadField(2,i,g); Zahlenwert lesen...
test+1;MakeInteger(dummy); und aufsummieren...
EndIf
Next i
MessageRequester("Ergebnis:",Str(test))
FreeMemory(*MemBlock)
-
Edwin Knoppert
- Addict

- Posts: 1073
- Joined: Fri Apr 25, 2003 11:13 pm
- Location: Netherlands
- Contact:

