2008-12-07 12 views
6

शीर्षक यह सब कुछ कहता है। मैं ऑब्जेक्ट्स की एक सरणी को स्टोर करने के लिए एक TClientDataset का उपयोग कर रहा हूं, और ऑब्जेक्ट्स में से एक को के एक समेकित प्रकार के रूप में परिभाषित किया गया है। जैसा कि मैं इसे समझता हूं, डेल्फी सेट बिटफिल्ड हैं जिनके आकार में 1 से 32 बाइट्स भिन्न हो सकते हैं, इस पर निर्भर करता है कि उनके पास कितना डेटा है, और डेल्फी टीएसईटीफ़िल्ल्ड को परिभाषित नहीं करता है। इस मूल्य को लोड करने के लिए मुझे किस प्रकार का क्षेत्र उपयोग करना चाहिए?किसी डेटासेट में डेल्फी सेट को स्टोर करने का सबसे अच्छा तरीका क्या है?

+0

यह भी देखें [प्रकारों को कैसे सेट/लोड करें?] (Http://stackoverflow.com/q/9553510/757830)। – NGLN

उत्तर

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

यह मेरे से बेहतर है। और स्पष्ट ... कूल –

+0

1) अपना नमूना भी स्पष्ट करने के लिए मैं "क्लाइंटडेटासेट 1 मैटसेट.एटडेटा (@ बाइट्स [0])" को "क्लाइंटडेटासेट 1 मैटसेट.एस्बाइट्स: = बाइट्स" 2 में बदलने का प्रस्ताव करता हूं) // पढ़ें ब्लॉक में (मूव लाइन पर), मुझे लगता है कि आपको "SizeOf (MySet)" को "ClientDataSet1MySet.DataSize" में लगातार होना चाहिए। – rvheddeg

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

यह तब तक ठीक काम करता है जब तक कि आपको 32 बिट्स से अधिक की आवश्यकता न हो। सेट 256 बिट्स तक जाते हैं, और मैं ऐसी परिस्थिति में हूं जहां मुझे उस स्थान के अच्छे हिस्से की आवश्यकता हो सकती है। –

+0

मैं इसे उस परिदृश्य में अनुकूलित करने की कोशिश करूंगा। –

0

एंड्रियास के उदाहरण के आधार पर, लेकिन कुछ सरल और स्पष्ट IMHO बनाया।

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; 
संबंधित मुद्दे

 संबंधित मुद्दे