Recent

Author Topic: Multiple chechbox Value on One Value  (Read 5005 times)

BSaidus

  • Hero Member
  • *****
  • Posts: 545
  • lazarus 1.8.4 Win8.1 / cross FreeBSD
Multiple chechbox Value on One Value
« on: September 24, 2017, 11:06:41 am »
Hello,
Say, I have 8 checkboxe's for parametring, and saving the values on database.
So, Is there any way to combine CheckBoxe's Values in Only one Value (With some kind of operation) and Store only this Value on Database (One Field). And what would the reverse operation.

Thanks.
lazarus 1.8.4 Win8.1 / cross FreeBSD
dhukmucmur vernadh!

wp

  • Hero Member
  • *****
  • Posts: 11910
Re: Multiple chechbox Value on One Value
« Reply #1 on: September 24, 2017, 11:33:12 am »
Sounds like an excercise in binary numbers...

You must (at least mentally) assign a binary value (1, 2, 4, 8, 16, ...) to each checkbox. To get the total value you just add the values of the checked checkboxes. If no box is checked the total will be 0, if the ones with weight 1 and 2 are checked the total will be 3 etc. The maximum total will be 255 for 8 checkboxes (1+2+4+8+16+32+64+128).

Conversely, if you have a total value and want to find out which checkboxes will have to be checked then divide the total by each checkbox value and see if the result is 0 (checkbox not checked) or not (checkbox checked).

Assigning a binary value to each checkbox is quite easy if you put the eight checkboxes into an array[0..7]. If the number 1 is left-shifted (shl) by the array index of a checkbox you'll get its binary value.

A working example is in the attachment. It just displays the resulting total, it does not store it in a database.

BSaidus

  • Hero Member
  • *****
  • Posts: 545
  • lazarus 1.8.4 Win8.1 / cross FreeBSD
Re: Multiple chechbox Value on One Value
« Reply #2 on: September 24, 2017, 11:45:14 am »
Thanks,  :D
lazarus 1.8.4 Win8.1 / cross FreeBSD
dhukmucmur vernadh!

engkin

  • Hero Member
  • *****
  • Posts: 3112
Re: Multiple chechbox Value on One Value
« Reply #3 on: September 24, 2017, 06:20:03 pm »
Bitpacked! This actually calls for Bitpacked Array and Bitpacked Record:
Code: Pascal  [Select][+][-]
  1. type
  2.   TAB8 = bitpacked array[0..7] of boolean;
  3.   TCBStatus = bitpacked record
  4.     case boolean of
  5.     true: (Val: byte);
  6.     false: (Checked: TAB8)
  7.   end;

This would make it possible to use:
Code: Pascal  [Select][+][-]
  1.     cbs.Checked[i] := FCheckboxes[i].Checked;

instead of:
Code: Pascal  [Select][+][-]
  1.     if FCheckboxes[i].Checked then
  2.       val := val or (1 shl i);

and to use/display the value using:
Code: Pascal  [Select][+][-]
  1.   Label1.Caption := IntToStr(cbs.val);
  2.   SpinEdit1.Value := cbs.val;

The opposite direction:
Code: Pascal  [Select][+][-]
  1. procedure TForm1.SpinEdit1EditingDone(Sender: TObject);
  2. var
  3.   i: Integer;
  4.   cbs: TCBStatus;
  5. begin
  6.   cbs.val := Byte(SpinEdit1.Value);
  7.   for i:=0 to 7 do
  8.     FCheckboxes[i].Checked := cbs.Checked[i]

Noodly

  • Jr. Member
  • **
  • Posts: 70
Re: Multiple chechbox Value on One Value
« Reply #4 on: September 24, 2017, 11:28:32 pm »
... Conversely, if you have a total value and want to find out which checkboxes will have to be checked then divide the total by each checkbox value and see if the result is 0 (checkbox not checked) or not (checkbox checked) ...

Actually you need to AND the total value with each checkbox value to find out if the result is not zero and therefore that checkbox is set.
Windows 10 Home, Lazarus 2.02 (svn 60954), FPC 3.04

wp

  • Hero Member
  • *****
  • Posts: 11910
Re: Multiple chechbox Value on One Value
« Reply #5 on: September 24, 2017, 11:46:55 pm »
Right, sorry for the confusion. At least it's correct in the demo, though...

Of course, engkin's BitPacked Array is much simpler. But this will not help the OP in understanding binary numbers.

BSaidus

  • Hero Member
  • *****
  • Posts: 545
  • lazarus 1.8.4 Win8.1 / cross FreeBSD
Re: Multiple chechbox Value on One Value
« Reply #6 on: September 26, 2017, 08:43:32 am »
OK ok !!!
Can some one do a simple program to demonstrate this ..
thanks.
lazarus 1.8.4 Win8.1 / cross FreeBSD
dhukmucmur vernadh!

balazsszekely

  • Guest
Re: Multiple chechbox Value on One Value
« Reply #7 on: September 26, 2017, 09:08:11 am »
See attachment. D0 is the least significant value. When you wish to convert back to checkbox values, just loop through variable "binarystring" D7 is the first char, D0 the last one, obviously '1' is checked '0' is not checked.

BSaidus

  • Hero Member
  • *****
  • Posts: 545
  • lazarus 1.8.4 Win8.1 / cross FreeBSD
Re: Multiple chechbox Value on One Value
« Reply #8 on: September 26, 2017, 11:12:06 am »
See attachment. D0 is the least significant value. When you wish to convert back to checkbox values, just loop through variable "binarystring" D7 is the first char, D0 the last one, obviously '1' is checked '0' is not checked.

Thanks,
This is valable if only if I have 8 checkboxes, not more !??
lazarus 1.8.4 Win8.1 / cross FreeBSD
dhukmucmur vernadh!

molly

  • Hero Member
  • *****
  • Posts: 2330
Re: Multiple chechbox Value on One Value
« Reply #9 on: September 26, 2017, 11:21:31 am »
@BSaidus:
at a quick glance it seems bound by the use of integer. So if the digits together overflow an integer it will fail.

In order to let it work with more than 8 'checkboxes' some additional modifications would have to be made to the example though

1) The binary string should be adjusted (now it has only room for 8 digits)
2) the lines "BinaryString[8 - (Sender as TCheckBox).Tag] ..." use a hard-coded value of 8

I'm sure i forgot something there... but in theory that should be all.

BSaidus

  • Hero Member
  • *****
  • Posts: 545
  • lazarus 1.8.4 Win8.1 / cross FreeBSD
Re: Multiple chechbox Value on One Value
« Reply #10 on: September 26, 2017, 11:22:48 am »
Oh! yes !!
Thnks.
lazarus 1.8.4 Win8.1 / cross FreeBSD
dhukmucmur vernadh!

molly

  • Hero Member
  • *****
  • Posts: 2330
Re: Multiple chechbox Value on One Value
« Reply #11 on: September 26, 2017, 11:39:13 am »
I think GetMem's idea there (but i should probably let him speak for himself), is to show you how you could take different approaches.

Can you see the logic in storing the ones and zero's inside a string ? If you do then you might probably also realize that a string is also a valid (single) database field, e.g. you are not bound by numbers alone. Strings (or to stick with the example, the number of digits) can be much larger then any number a integer variable would be able to 'store' (although int64... that should be enough 'digits' to play around with).

So you could always opt for not using a number, but a use a string instead. I think that would be enough room for an average amount of checkboxes that you would use for a program (there are always exception of course :) )
« Last Edit: September 26, 2017, 11:51:32 am by molly »

Fungus

  • Sr. Member
  • ****
  • Posts: 353
Re: Multiple chechbox Value on One Value
« Reply #12 on: September 26, 2017, 11:59:52 am »
From my old toolbox:

Code: Pascal  [Select][+][-]
  1. function CheckBoxesToCardinal(const CB: array of TCheckBox): Cardinal;
  2. var I: Integer;
  3. begin
  4.   Result:= 0;
  5.   for I:= Low(CB) to High(cb) do if CB[I].Checked then Result:= Result or (1 shl (I - Low(CB)));
  6. end;
  7.  
  8. procedure CardinalToCheckBoxes(const C: Cardinal; const CB: array of TCheckBox);
  9. var I: Integer;
  10. begin
  11.   for I:= Low(CB) to High(cb) do CB[I].Checked:= (C and (1 shl (I - Low(CB)))) <> 0;
  12. end;

You can then convert up to 32 checkboxes to and from a 32 bit value with:

Code: Pascal  [Select][+][-]
  1. var C: Cardinal;
  2. begin
  3.   //Get 32 bit value from checkboxes
  4.   C:= CheckBoxesToCardinal([Checkbox1, Checkbox2, Checkbox3, Checkbox4, ...]);
  5.  
  6.   //Set checkboxes from a 32 bit value
  7.   CardinalToCheckBoxes(C, [Checkbox1, Checkbox2, Checkbox3, Checkbox4, ...]);
  8. end;

Nice and neat! :)

jamie

  • Hero Member
  • *****
  • Posts: 6128
Re: Multiple chechbox Value on One Value
« Reply #13 on: September 26, 2017, 11:31:32 pm »
I like using BitPacked records for this..

 TMyCheckBoxSettings = BitPacked Record

    Button1:0..1;
    Button2:0..1;
    Butoon3:0..1;
    BUtton4:0..1;
    Button5.0..1;
    Button6:0..1;
    Button7:0..1;
    button8:0..1;
    button9.0..1;
 End;  // just keep on adding....

Var
 MySettings:TMyCheckBoxSettings;

This can be written out and read as an Integer because it has 32 bits.
Just set the fields as needed before writing it out.

MySettings.Button1 := Byte(CheckBox1.Checked);


The only true wisdom is knowing you know nothing

 

TinyPortal © 2005-2018