Persist column state in advgridworkbook

I am having a problem when trying to persist column order selected by users in the sheets on AdvGridWorkBook.  I setup the grid so that the columns can be moved, and that's fine.  There are 6 sheets in the workbook.  The settings are saved in an INI file.  When the program executes, though, I get an Index out of bounds (6) error.


This is the code that loads the values onFormShow:

    s1 := Ini.ReadString('Grid','Wkbksht1','');
    s2 := Ini.ReadString('Grid','Wkbksht2','');
    s3 := Ini.ReadString('Grid','Wkbksht3','');
    s4 := Ini.ReadString('Grid','Wkbksht4','');
    s5 := Ini.ReadString('Grid','Wkbksht5','');
    s6 := Ini.ReadString('Grid','Wkbksht6','');

I don't set the column order until the user has selected to run the program with their chosen parameters.  At the start of the execution, I rebuild to workbook to account for users running it multiple times:

    AGWB.Sheets.Clear;
    AGWB.Sheets.Add.Name := 'All_Items';
    AGWB.Sheets.Add.Name := 'Owners';
    AGWB.Sheets.Add.Name := 'DayLease';
    AGWB.Sheets.Add.Name := 'Company';
    AGWB.Sheets.Add.Name := 'Other';
    AGWB.Sheets.Add.Name := 'DLExceptions';

I then build the columns, column headers and other data.  Sheet 1 has 35 columns, sheets 2 - 5 have 19 columns and sheet 6 has 7 columns.  After building these in the design time order, I execute the loop:

  for i = 0 to 5 do
  begin
     AGWB.ActiveSheet := i;
     AGWB.Grid.SetColumnOrder;
  end;

After loading all rows with data, I attempt to set the column order for each sheet as the user last did:

    AGWB.ActiveSheet := 0;
    if s1 <> '' then
      AGWB.Grid.StringToColumnStates(s1);
    AGWB.ActiveSheet := 1;
    if s2<> '' then
      AGWB.Grid.StringToColumnStates(s2);
    AGWB.ActiveSheet := 2;
    if s3 <> '' then
      AGWB.Grid.StringToColumnStates(s3);
    AGWB.ActiveSheet := 3;
    if s4 <> '' then
      AGWB.Grid.StringToColumnStates(s4);
    AGWB.ActiveSheet := 4;
    if s5 <> '' then
      AGWB.Grid.StringToColumnStates(s5);
    AGWB.ActiveSheet := 5;
    if s6 <> '' then
      AGWB.Grid.StringToColumnStates(s6);

When this runs, I get the Index Out of Bounds(6) error.  If I comment this code out, I get no error and the program runs.

Checking the INI values, I have:

Wkbksht1=35#40,74,89,68,53,65,60,40,86,86,57,78,65,69,85,87,57,62,66,75,62,76,68,81,103,57,80,70,100,99,76,94,108,103,57#0,1,2,3,4,5#1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
Wkbksht2=19#71,65,69,65,89,73,73,93,80,75,65,54,67,61,73,73,70,50,78#0,1,2,3,4,5#1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
Wkbksht3=19#71,65,69,65,89,65,65,93,80,75,57,54,67,61,66,65,70,50,78#0,1,2,3,4,5#1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
Wkbksht4=19#71,65,69,65,89,65,65,93,80,75,49,54,67,61,66,65,70,50,78#0,1,2,3,4,5#1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
Wkbksht5=19#71,65,69,64,89,62,57,93,80,75,41,54,67,61,66,41,70,50,78#0,1,2,3,4,5#1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
Wkbksht6=7#40,72,77,75,64,67,70#0,1,2,3,4,5#1,1,1,1,1,1,1

I am not certain, but I believe the format of the parameter value stored in the INI is number of items # column sizes # column order # some other value #

None of the parameters seem to have the correct number of values in the column order group, but show the Sheet order (6 sheets).

Does anyone know if it is possible to persist column settings in a workbook by sheet?


In TAdvGridWorkbook there is actually only one grid (and data) for memory usage reasons. Therefore, it is unfortunately not going to work to use column persistence this way. What might work is to initialize the column state each time a new sheet is activated (from the OnSheetChanged event)

Noted.  Crawling through the source code, after saving the settings without moving any columns produced this:


Wkbksht1=35#40,74,89,68,53,65,60,40,141,86,57,78,65,69,85,87,49,62,66,75,62,76,68,81,103,57,80,70,100,99,76,94,108,103,57#0,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#1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
Wkbksht2=20#71,65,78,78,86,89,86,86,93,80,78,86,78,54,67,61,86,86,78,69#0,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#1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
Wkbksht3=20#71,65,78,78,78,89,86,86,93,80,78,86,78,54,67,61,86,86,78,64#0,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#1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
Wkbksht4=20#71,65,78,78,65,89,78,78,93,80,75,86,57,54,67,61,78,78,70,64#0,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#1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
Wkbksht5=20#71,65,78,69,64,89,62,57,93,80,75,86,49,54,67,61,66,49,70,56#0,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#1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
Wkbksht6=7#40,72,87,75,65,67,70#0,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#1,1,1,1,1,1,1

Where the column order now contains the maximum number of columns used on a sheet, I found that the sections that are working OK in AdvGrid.pas do a simple loop:

for i := 0 to ColCount - 1 + NumHiddenColumns do

where the section handling the column order does  a loop

if FColumnOrder.Count = 0 then
begin
  for i = ...
end
else
  for i := 0 to FColumnOrder.Count -1 do

Not knowing why the column order is based on the Integer List FColumnOrder instead of ColCount basically means I will not be able to use that feature.  So basically, not all features of AdvStringGrid are usable with AdvStringGridWorkBook.
  1. Column state contains not only the order of columns but also the visibility. As such, it restores hidden columns too and needs to take the nr. of hidden columns in account

    2) The feature of column state persistence remains available on a per grid level in a TAdvGridWorkbook. But, as I noted, for memory usage reasons, there is only one real grid used in AdvGridWorkbook and therefore, there is no support to persists at one time column states of all sheets. It needs to be handle on a per sheet basis.