2008-12-07 77 views
6

標題幾乎說明了一切。我正在使用TClientDataset存儲對象數組,其中一個對象的成員定義爲集合枚舉類型。據我瞭解,Delphi集是位字段,其大小可以從1到32個字節不等,取決於它們包含的數據量,Delphi不定義TSetField。我應該用什麼樣的字段來加載這個值?在數據集中存儲Delphi集合的最佳方式是什麼?

+0

請參閱[如何保存/加載一組類型?](http://stackoverflow.com/q/9553510/757830)。 – NGLN 2015-12-25 20:27:34

回答

14

你可以使用一個TBytesField或TBlobField

ClientDataSet1MySet:TBytesField,大小= 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; 
+0

這比我的好。和更清晰的...酷 – 2009-07-22 19:17:50

+0

1)爲了使您的示例更清晰,我建議將「ClientDataSet1MySet.SetData(@Bytes [0])」更改爲「ClientDataSet1MySet.AsBytes:= Bytes」 2)// Read塊(在移動線上),我認爲你必須將「SizeOf(MySet)」更改爲「ClientDataSet1MySet.DataSize」以保持一致。 – rvheddeg 2013-12-04 16:55:33

2

你可以將它們轉換成字節,這樣的:

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; 

歇着任何地方:

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; 
0

基於安德烈亞斯的例子,但做了一些簡單和清晰的恕我直言。

測試在XE2

你可以使用一個TBytesField或TBlobField

ClientDataSet1MySet:TBytesField,大小= 32

1)書寫

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)閱讀

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