delphi set dataset

¿Cuál es la mejor manera de almacenar un conjunto de Delphi en un conjunto de datos?



set dataset (3)

Puede usar un TBytesField o un TBlobField

ClientDataSet1MySet: TBytesField, Size = 32

var MySet: set of Byte; Bytes: array of Byte; begin MySet := [1, 2, 4, 8, 16]; // Write Assert(ClientDataSet1MySet.DataSize >= SizeOf(MySet), ''Data field is too small''); SetLength(Bytes, ClientDataSet1MySet.DataSize); Move(MySet, Bytes[0], SizeOf(MySet)); ClientDataSet1.Edit; ClientDataSet1MySet.SetData(@Bytes[0]); ClientDataSet1.Post; // Read SetLength(Bytes, ClientDataSet1MySet.DataSize); if ClientDataSet1MySet.GetData(@Bytes[0]) then Move(Bytes[0], MySet, SizeOf(MySet)) else MySet := []; // NULL end;

El título lo dice todo. Estoy usando un TClientDataset para almacenar una matriz de objetos, y uno de los objetos tiene un miembro definido como un conjunto de un tipo enumerado. Tal como lo entiendo, los conjuntos de Delphi son bitfields cuyo tamaño puede variar de 1 a 32 bytes, según la cantidad de datos que contengan, y Delphi no define un TSetField. ¿Qué tipo de campo debo usar para cargar este valor?


Puedes convertirlos a Byte, así:

var States : TUpdateStatusSet; // Can be any set, I took this one from DB.pas unit SetAsAInteger: Integer; dbs: Pointer; // Here''s the trick begin States := [usModified, usInserted]; // Putting some content in that set dbs := @States; SetAsAInteger := PByte(dbs)^; //Once you got it, SetAsAInteger is just another ordinary integer variable. //Use it the way you like. end;

Para recuperarse desde cualquier lugar:

var MSG: string; Inserted, Modified: string; States: TUpdateStatusSet; MySet: Byte; begin while not ClientDataSet.Eof do begin //That''s the part that interest us //Convert that integer you stored in the database or whatever //place to a Byte and, in the sequence, to your set type. iSet := Byte(ClientDatasetMyIntegerField);// Sets are one byte, so they // fit on a byte variable States := TUpdateStatusSet(iSet); //Conversion finished, below is just interface stuff if usInserted in States then Inserted := ''Yes''; if usModified in States then Modified := ''Yes''; MSG := Format(''Register Num: %d. Inserted: %s. Modified:%s'', [ClientDataSet.RecNo, Inserted, Alterted]); ShowMessage( MSG ); ClientDataset.Next; end; end;


Basado en el ejemplo de Andreas, pero en mi humilde opinión hizo mi humilde opinión.

Probado en XE2

Puede usar un TBytesField o un TBlobField

ClientDataSet1MySet: TBytesField, Size = 32

1) Escribir

var MySet: set of Byte; Bytes: TBytes; begin MySet := [0]; // Write Assert(ClientDataSet1Test.DataSize >= SizeOf(MySet), ''Data field is too small''); SetLength(Bytes, ClientDataSet1Test.DataSize); Move(MySet, Bytes[0], SizeOf(MySet)); ClientDataSet1.Edit; ClientDataSet1Test.AsBytes := Bytes; ClientDataSet1.Post; end;

2) Lectura

var MyResultSet: set of Byte; begin Move(ClientDataSet1Test.AsBytes[0], MyResultSet, ClientDataSet1Test.DataSize); end;