I'm not sure if anyone has posted this type of example, but I could not find it, so here goes. I hope this helps someone trying to solve the ADO riddle for dBase databases. Reading records and updating fields.
I cannot stress enough how much reading the msdn info on ADO helped me figure this out.
http://msdn.microsoft.com/en-us/library ... 85%29.aspx
I don't have an example dbf file to share, but assume that wrkorder.dbf contains a unique key field of WKORDNUM (work order number), a bunch of other fields, and two long string fields called NOTE1 and NOTE2 that are (not too surprisingly) for notes. varOurWkNum is just a work order number used to pick a specific record.
In my program, I grab the two notes, remove certain references, put them all at the end of the 2nd note and put an ETA date at the beginning of the 1st note. There's a lot of fancy formatting and frippery at work.
For simplicity, this example will just read the two fields, change them slightly, and write them back.
Code:
;Dbq is the path to the dbf file. (S:\ or whatever) This sConnect is highly dbf oriented (DBASE). (http://www.codeproject.com/KB/database/connectionstrings.aspx#dBASE)
sSource := "SELECT WKORDNUM,NOTE1,NOTE2 FROM " . "wrkorder.dbf" . " WHERE WKORDNUM = '" . varOurWkNum . "'"
sConnect := "Driver={Microsoft dBASE Driver (*.dbf)};DriverID=277;Dbq=S:\;"
COM_Init() ; (Initialize the process, start the motor, on your mark)
prs := COM_CreateObject("ADODB.Recordset") ; define prs as a Recordset object, ready to be acted upon
;Define properties of recordset that tell how it will operate (BEFORE recordset opened) (numbers from w3schools.com/ado/ado_ref_recordset.asp ).
COM_Invoke(prs, "CursorLocation=", 3) ; adUseClient = 3 , local (not on server) use of data
COM_Invoke(prs, "CursorType=", 0) ; adOpenForwardOnly = 0 , cursor will not go backward (I don't need to in this case)
COM_Invoke(prs, "LockType=", 3) ; adLockOptimistic = 3 , Not entirely clear on this, but won't lock out others entirely?
COM_Invoke(prs, "Open", sSource, sConnect) ; Open the recordset, if any, using the source and connect string from above.
Loop
{
If COM_Invoke(prs, "EOF")
Break ; no fields? no match? (not sure) checking for end of fields
pFields := COM_Invoke(prs, "Fields") ; Get all the fields (together) in the current row of the recordset
; The below are out of order, just to prove it didn't matter. First field index is 0.
; You could loop through these, as in other examples, but to me this saves steps by defining the variables as they come.
pField := COM_Invoke(pFields, "Item", 2) , varNote2 := COM_Invoke(pField, "Value") , COM_Release(pField)
pField := COM_Invoke(pFields, "Item", 0) , varWorkyNum := COM_Invoke(pField, "Value") , COM_Release(pField)
pField := COM_Invoke(pFields, "Item", 1) , varNote1 := COM_Invoke(pField, "Value") , COM_Release(pField)
;Add ETAXXXX in front of Note1 and NOETAXXXX at end of Note2
varNote1 := "ETAXXXX" . varNote1
varNote2 .= "NOETAXXXX"
;This does the actual value changing of the individual field in this record. 1st part defines/addresses, 2nd part changes, 3rd part releases.
pField := COM_Invoke(pFields, "Item", 1) , COM_Invoke(pField, "Value=", varNote1) , COM_Release(pField)
pField := COM_Invoke(pFields, "Item", 2) , COM_Invoke(pField, "Value=", varNote2) , COM_Release(pField)
COM_Invoke(prs, "Update") ; Is this even necessary? Works without it I think. Anyone know?
COM_Release(pFields) ; Release the recordset row (group of fields).
COM_Invoke(prs, "MoveNext") ; Move to next row, if multirow
}
COM_Invoke(prs, "Close") ; Close the recordset
COM_Release(prs) ; Release the resources/memory (afaik)
COM_Term() ; Close the whole COM process (end to Init)
I hope this helps someone shortcut the chasm of ignorance I had to trudge over. If it doesn't make sense, steep yourself in ADO knowledge.
THANKS SEAN! I really don't think I can know how much I appreciate your COM work, and how excited I am that I finally understand enough to program direct access to my dbf files, rather than going through Access queries as I have been.
Thanks to all others for the contributed code examples.
Toxey