crMODIFY & DBase Files. How to use?????:(

My question is as follows,

How on earth do you use crMODIFY to alter the fields in a dataset other than the first one. I can use it successfully to edit the first fields Type,Width and precision but am unable to modify any other field as I keep getting
"invalid restructure operation" . Does anyone have some code to show the correct way to step through a list of field descriptors as I am at my wits end trying to solve this. Surely someone has done this before?? I can also use the crAdd and crDrop successfully but the crMODIFY has got me stumped. I have already had a look at some source that just shows how to Add a new field but gee I need something more than that as I has adjusted the code to suit a modify operation and as I said it does alter/modify the first field descs in the DBase table but when it tries to do the DbiDoRestructure on the second field it crashes out every time. Anyone ??

Westy (PS Good points for this)

westy100697Asked:
Who is Participating?
 
ZifNabConnect With a Mentor Commented:
Hi westy,

have you already looked at the great examples at Inprise concerning DBE?

Guess this is exactly what you need, isn't it?

Here is an example :

Example 3: Alter a field in a Paradox or dBASE table.

                         This example will alter an existing field in a Paradox or dBASE table.
                         NOTE: You must fill in all options in the ChangeRec with 0 or '' if the option is not used in the restructure.
                         FillChar can be used to do this: Fillchar(MyChangeRec, sizeof(MyChangeRec), 0);
                         This example uses the following input:
                         ChangeField(Table1, Table1.FieldByName('FOO'), MyChangeRec)
                         ChangeRec is defind as follows:

                         ChangeRec = packed record
                             szName: DBINAME;
                             iType: word;
                             iSubType: word;
                             iLength: word;
                             iPrecision: byte;
                           end;

                         The function is defined as follows:

                         procedure ChangeField(Table: TTable; Field: TField; Rec: ChangeRec);
                         var
                           Props: CURProps;
                           hDb: hDBIDb;
                           TableDesc: CRTblDesc;
                           pFields: pFLDDesc;
                           pOp: pCROpType;
                           B: byte;

                         begin
                           // Initialize the pointers...
                           pFields := nil; pOp := nil;
                           // Make sure the table is open exclusively so we can get the db handle...
                           if Table.Active = False then
                             raise EDatabaseError.Create('Table must be opened to restructure');
                           if Table.Exclusive = False then
                             raise EDatabaseError.Create('Table must be opened exclusively to restructure');

                           Check(DbiSetProp(hDBIObj(Table.Handle), curxltMODE, integer(xltNONE)));
                           // Get the table properties to determine table type...
                           Check(DbiGetCursorProps(Table.Handle, Props));
                           // Make sure the table is either Paradox or dBASE...
                           if (Props.szTableType <> szPARADOX) and (Props.szTableType <> szDBASE) then
                             raise EDatabaseError.Create('Field altering can only occur on Paradox' +
                                         ' or dBASE tables');
                           // Allocate memory for the field descriptor...
                           pFields := AllocMem(Table.FieldCount * sizeof(FLDDesc));
                           // Allocate memory for the operation descriptor...
                           pOp := AllocMem(Table.FieldCount * sizeof(CROpType));
                           try
                             // Set the pointer to the index in the operation descriptor to put
                             // crMODIFY (This means a modification to the record is going to happen)...
                             Inc(pOp, Field.Index);
                             pOp^ := crMODIFY;
                             Dec(pOp, Field.Index);
                             // Fill the field descriptor with the existing field information...
                             Check(DbiGetFieldDescs(Table.Handle, pFields));
                             // Set the pointer to the index in the field descriptor to make the
                             // midifications to the field
                             Inc(pFields, Field.Index);

                             // If the szName portion of the ChangeRec has something in it, change it...
                             if Length(Rec.szName) > 0 then
                               pFields^.szName := Rec.szName;
                             // If the iType portion of the ChangeRec has something in it, change it...
                             if Rec.iType > 0 then
                               pFields^.iFldType := Rec.iType;
                             // If the iSubType portion of the ChangeRec has something in it, change it...
                             if Rec.iSubType > 0 then
                               pFields^.iSubType := Rec.iSubType;
                             // If the iLength portion of the ChangeRec has something in it, change it...
                             if Rec.iLength > 0 then
                               pFields^.iUnits1 := Rec.iLength;
                             // If the iPrecision portion of the ChangeRec has something in it, change it...
                             if Rec.iPrecision > 0 then
                               pFields^.iUnits2 := Rec.iPrecision;
                             Dec(pFields, Field.Index);

                             for B := 1 to Table.FieldCount do begin
                               pFields^.iFldNum := B;
                               Inc(pFields, 1);
                             end;
                             Dec(pFields, Table.FieldCount);
                             
                             // Blank out the structure...
                             FillChar(TableDesc, sizeof(TableDesc), 0);
                             //  Get the database handle from the table's cursor handle...
                             Check(DbiGetObjFromObj(hDBIObj(Table.Handle), objDATABASE, hDBIObj(hDb)));
                             // Put the table name in the table descriptor...
                             StrPCopy(TableDesc.szTblName, Table.TableName);
                             // Put the table type in the table descriptor...
                             StrPCopy(TableDesc.szTblType, Props.szTableType);
                             // The following three lines are necessary when doing any field restructure
                             // operations on a table...

                             // Set the field count for the table
                             TableDesc.iFldCount := Table.FieldCount;
                             // Link the operation descriptor to the table descriptor...
                             TableDesc.pecrFldOp := pOp;
                             // Link the field descriptor to the table descriptor...
                             TableDesc.pFldDesc := pFields;
                             // Close the table so the restructure can complete...
                             Table.Close;
                             // Call DbiDoRestructure...
                             Check(DbiDoRestructure(hDb, 1, @TableDesc, nil, nil, nil, FALSE));
                           finally
                             if pFields <> nil then
                               FreeMem(pFields);
                             if pOp <> nil then
                               FreeMem(pOp);
                           end;
                         end;

Zif.
0
 
westy100697Author Commented:
Where is that at inprise? FAQ? Anyway will look at this immediately and let you know how it goes. Had a look at it here and it looks like it will do the job. Thanks Zif appreciate the help.

WESTY 8)
(Will most likely award the points as soon as I test it ok)
0
 
ZifNabCommented:
0
Free Tool: Port Scanner

Check which ports are open to the outside world. Helps make sure that your firewall rules are working as intended.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

 
westy100697Author Commented:
Zif,
    What you just gave me works fine. I will have to automate it though to give me the ability to modify more than one field at a time and will need to be able to do this without actually typing in the field description but this part should be fine now that I know what has been going wrong. Appreciate the help and here are the points and an A grading.
TA heaps.

WESTY
0
 
ZifNabCommented:
Hi westy,

Sorry for not looking earlier to your question, but I guess it slipped through the fingers. Good idea for posting that reminder.

Greetings, Zif.

Happy BDE programming.
0
 
westy100697Author Commented:
Zif,
    After I got this going I did a little more research as I kept getting " Invalid field descriptor" . I went back to the D3 help for TFields and starting reading then I went and bashed my head on the wall after reading  ".....is a zero based array." I have for the last couple of months been trying on and off to solve this and as it turned out I was initialising my loop with 1 instead of 0. Almost Comical EH!

WESTY (PS. Thanks again)
0
 
ZifNabCommented:
westy, hope your head is ok again ;-). I guess, we all have this thing now and then... some almost everytime ... ;-). See you, Zif.
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.