1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105
| uses Bde;
type
ChangeRec = packed record
szName: DBINAME;
iType: Word;
iSubType: Word;
iLength: Word;
iPrecision: Byte;
end;
procedure ChangeField(Table: TTable; Field: TField; Rec: ChangeRec);
var
Props: CURProps;
hDb: hDBIDb;
TableDesc: CRTblDesc;
pFields: pFLDDesc;
pOp: pCROpType;
B: Word;
begin
// Initialise les pointeurs...
pFields := nil;
pOp := nil;
// Être sûr que la table est ouverte exclusivement, pour récupérer le Handle...
if not Table.Active then
raise EDatabaseError.Create('Table must be opened to restructure');
if not Table.Exclusive then
raise EDatabaseError.Create('Table must be opened exclusively to restructure');
Check(DbiSetProp(hDBIObj(Table.Handle), curxltMODE, Integer(xltNONE)));
// Reçoit les propriétés pour déterminer le type...
Check(DbiGetCursorProps(Table.Handle, Props));
// Paradox ou dBASE...
if (Props.szTableType <> szPARADOX) and (Props.szTableType <> szDBASE) then
raise EDatabaseError.Create('Field altering can only occur on Paradox or dBASE tables');
pFields := AllocMem(Table.FieldCount * sizeof(FLDDesc));
pOp := AllocMem(Table.FieldCount * sizeof(CROpType));
try
// Mettre crMODIFY dans le pointeur d'opération du champ à modifier
Inc(pOp, Field.Index);
pOp^ := crMODIFY;
Dec(pOp, Field.Index);
// Reçoit les informations du champ...
Check(DbiGetFieldDescs(Table.Handle, pFields));
// Attribuer les changements dans le champ...
Inc(pFields, Field.Index);
// Nom du champ
if (Length(Rec.szName) > 0) then pFields^.szName := Rec.szName;
// Type de champ
if (Rec.iType > 0) then pFields^.iFldType := Rec.iType;
// Sous-type de champ
if (Rec.iSubType > 0) then pFields^.iSubType := Rec.iSubType;
// Longueur du champ
if (Rec.iLength > 0) then
begin
pFields^.iUnits1 := Rec.iLength;
pFields^.iLen := Rec.iLength;
end;
// Precision
if (Rec.iPrecision > 0) then pFields^.iUnits2 := Rec.iPrecision;
Dec(pFields, Field.Index);
// Mettre à jour les numéros des champs
for B := 1 to Table.FieldCount do
begin
pFields^.iFldNum := B;
Inc(pFields, 1);
end;
Dec(pFields, Table.FieldCount);
// Description de la table...
FillChar(TableDesc, sizeof(TableDesc), #0);
// Trouver le Handle de la database à partir du cursor de la table...
Check(DbiGetObjFromObj(hDBIObj(Table.Handle), objDATABASE, hDBIObj(hDb)));
// Assigner le nom de la table...
StrPCopy(TableDesc.szTblName, Table.TableName);
// Assigner le type de la table...
StrPCopy(TableDesc.szTblType, Props.szTableType);
// Nombre de champs dans la table
TableDesc.iFldCount := Table.FieldCount;
// Opération à faire...
TableDesc.pecrFldOp := pOp;
// Définition des champs...
TableDesc.pFldDesc := pFields;
// Fermer la table...
hDb := Table.Database.Handle;
Table.Database.KeepConnection := True;
Table.Close;
// Restructurer la table...
Check(DbiDoRestructure(hDb, 1, @TableDesc, nil, nil, nil, False));
finally
if (pFields <> nil) then FreeMem(pFields);
if (pOp <> nil) then FreeMem(pOp);
Table.Open;
Table.Database.KeepConnection := False;
end;
end; |
Partager