As you can see I tool the liberty to repost my old code snippets I posted last year. Most of them are a bit dated and are not tested with the latest GridView version (especially the gridview code modifications).
I have consolidated most into a separate unit i've included below. All routines take a Gridview as parameter. Please read the other articles for background information on the code.
If you got any questions, feel free to mail or pm me.
CODE
unit GridViewUtils;
interface
uses
GridView;
procedure GV_SaveGridLayout(const GridView: TGridView; const FileName: string; const Prefix: string = '');
procedure GV_RestoreGridLayout(var GridView: TGridView; const FileName: string; const Prefix: string = '');
procedure GV_SaveGridData(const GridView: TGridView; const FileName: string; const Prefix: string = '');
procedure GV_RestoreGridData(var GridView: TGridView; const FileName: string; const Prefix: string = '');
procedure GV_ExportToCsv(const GridView: TGridView; const fn: string; const header: Boolean = True);
procedure GV_ExportToXml(const GridView: TGridView; const fn: string);
procedure GV_ImportFromXml(var GridView: TGridView; const fn: string);
procedure GV_MoveSelectionUp(var Gridview: TGridView);
procedure GV_MoveSelectionDown(var Gridview: TGridView);
procedure GV_AddRowWithValues(var GridView: TGridView; const columnnames, columnvalues: array of OleVariant);
function GV_LookupValue(const GridView: TGridView; const lookupcolumnname, lookupvalue, valuecolumnname: OleVariant): OleVariant;
function GV_InsertGridViewTable(const GridView: TGridView): string;
implementation
uses
ColumnClasses,
Columns,
Classes,
Dialogs,
IniFiles,
StrUtils,
SysUtils,
Variants, CustomGridViewControl;
procedure GV_SaveGridLayout(const GridView: TGridView; const FileName: string; const Prefix: string = '');
var
IniFile : TIniFile;
Section : string;
Layout : TStringList;
i : Integer;
begin
Section := Format('%sLayout', [Prefix]);
with GridView do
begin
IniFile := TIniFile.Create(FileName);
IniFile.WriteInteger(section, 'ColumnsCount', Columns.Count);
Layout := TStringList.Create;
for i := 0 to Pred(Columns.Count) do
begin
Layout.Clear;
Layout.Add(IntToStr(Ord(Columns[i].SortKind)));
Layout.Add(IntToStr(Ord(Columns[i].Visible)));
Layout.Add(IntToStr(Ord(Columns[i].Sorted)));
Layout.Add(IntToStr(Ord(Columns[i].Position)));
Layout.Add(IntToStr(Ord(Columns[i].Width)));
Layout.Delimiter := ListSeparator;
IniFile.WriteString(section, Format('Column%d', [i]), Layout.DelimitedText);
end;
IniFile.UpdateFile;
Layout.Free;
IniFile.Free;
end;
end;
procedure GV_RestoreGridLayout(var GridView: TGridView; const FileName: string; const Prefix: string = '');
var
IniFile : TIniFile;
Layout : TStringList;
Section : string;
Count,
i : Integer;
begin
Section := Format('%sLayout', [Prefix]);
with GridView do
begin
IniFile := TIniFile.Create(FileName);
Layout := TStringList.Create;
Count := IniFile.ReadInteger(section, 'ColumnsCount', Columns.Count);
for i := 0 to Pred(Count) do
begin
Layout.Delimiter := ListSeparator;
Layout.DelimitedText := IniFile.ReadString(section, Format('Column%d', [i]), '');
if (Layout.Count = 5) then
begin
Columns[i].SortKind := TSortKind(StrToInt(Layout[0]));
Columns[i].Visible := Boolean(StrToInt(Layout[1]));
Columns[i].Sorted := Boolean(StrToInt(Layout[2]));
Columns[i].Position := StrToInt(Layout[3]);
Columns[i].Width := StrToInt(Layout[4]);
end;
end;
Layout.Free;
IniFile.Free;
end;
end;
procedure GV_ExportToCsv(const GridView: TGridView; const fn: string; const header: Boolean = True);
{
normalcol;"colwithlistseparator;";"colwithquote"""
1;2;5
4;3;6
}
var
r, c : Integer;
sl : TStringList;
s : string;
function EscapeSeparator(const value: string): string;
begin
if (Pos('"', value) > 0) then
Result := StringReplace(value, '"', '""', [rfReplaceAll])
else
Result := value;
if (Pos(ListSeparator, Result) > 0) or (Pos('""', Result) > 0) then
Result := '"' + Result + '"'
end;
begin
sl := TStringList.Create;
if header then
begin
s := '';
for c := 0 to Pred(GridView.Columns.Count) do
begin
if c <> 0 then
s := s + ListSeparator + EscapeSeparator(GridView.Columns[c].Header.Caption)
else
s := EscapeSeparator(GridView.Columns[c].Header.Caption);
end;
sl.Add(s);
end;
for r := 0 to Pred(GridView.RowCount) do
begin
s := '';
for c := 0 to Pred(GridView.Columns.Count) do
begin
if c <> 0 then
s := s + ListSeparator + EscapeSeparator(GridView.Cell[c, r].AsString)
else
s := EscapeSeparator(GridView.Cell[c, r].AsString);
end;
sl.Add(s);
end;
sl.SaveToFile(fn);
sl.Free;
end;
procedure GV_ExportToXml(const GridView: TGridView; const fn: string);
var
r, c : Integer;
sl : TStringList;
function EscapeValue(const value: string): string;
begin
//Not implemented yet.
//Change all characters outside the letters, numbers and crlf to
//< format where 3C is the hex value of the Characters Ord.
Result := value;
end;
begin
sl := TStringList.Create;
sl.Add('<?xml version="1.0"?>');
sl.Add(Format('<GridView version = "%s">', ['2.4.1'])); //Should be stVersion!
sl.Add(' <Columns>');
for c := 0 to Pred(GridView.Columns.Count) do
begin
//Use Attributes to Export Column Dependend settings like min/max values.
sl.Add(Format(' <Column Name="%s" ColumnClass="%s">', [GridView.Columns[c].Name, GridView.Columns[c].ClassName]));
sl.Add(' ' + EscapeValue(GridView.Columns[c].Header.Caption));
sl.Add(' </Column>');
end;
sl.Add(' </Columns>');
sl.Add(' <Rows>');
for r := 0 to Pred(GridView.RowCount) do
begin
sl.Add(' <Row>');
for c := 0 to Pred(GridView.Columns.Count) do
begin
sl.Add(' <Cell>');
{if not (GridView.Columns[c].ClassNameIs('TGraphicColumn') or
GridView.Columns[c].ClassNameIs('TImageColumn')) then}
sl.Add(' ' + EscapeValue(GridView.Cell[c, r].AsString));
sl.Add(' </Cell>');
end;
sl.Add(' </Row>');
end;
sl.Add(' </Rows>');
sl.Add('</GridView>');
sl.SaveToFile(fn);
sl.Free;
end;
procedure GV_ImportFromXml(var GridView: TGridView; const fn: string);
var
sl : TStringList;
function FetchAttributes(tag, value: string; var a: TStringList): string;
var
i : Integer;
s : string;
begin
//Fetch the attributes into a TStringList.
Result := value;
Delete(Result, 1, Length(Format('<%s ', [tag])));
Delete(Result, Pos('>', Result), Length(Result));
a.Text := Trim(Result);
//Return the input value without the Attributes.
Result := value;
Delete(Result, 1, Pos('>', Result) + 1);
Result := Format('<%s>', [tag]) + Result;
//Remove Surrounding Quotes from Value.
for i := 0 to Pred(a.Count) do
begin
s := a.Values[a.Names[i]];
if (s[1] = '"') and (s[Length(s)] = '"') then
begin
Delete(s, 1, 1);
Delete(s, Length(s), 1);
end;
a.Values[a.Names[i]] := s;
end;
end;
function FetchInnerText(tag, value: string): string;
begin
//Fetch the Text between a start and end tag.
Result := value;
Delete(Result, 1, Length(Format('<%s>', [tag])));
while not (AnsiEndsText(Format('</%s>', [tag]), Result)) do
begin
Result := Result + Trim(sl[0]);
sl.Delete(0);
end;
Delete(Result, Pos(Format('</%s>', [tag]), Result), Length(Result));
Result := Trim(Result);
end;
type
states = (xmlNone, xmlHeader, xmlGridView, xmlColumns, xmlColumn, xmlRows, xmlRow, xmlCells, xmlCell);
var
r, c : Integer;
i : Integer;
s : string;
state : states;
a : TStringList;
begin
sl := TStringList.Create;
GridView.ClearRows;
for i := 0 to Pred(GridView.Columns.Count) do
GridView.Columns[i].Header.Caption := '';
GridView.Update;
sl.LoadFromFile(fn);
r := 0;
c := 0;
state := xmlNone;
repeat
s := Trim(sl[0]);
sl.Delete(0);
if (CompareText(s, '<?xml version="1.0"?>') = 0) then //Process XML Version
begin
if (state <> xmlNone) then
begin
ShowMessage('Xml header not found.');
Break;
end
else
state := xmlHeader;
end
else if (CompareText(s, '<GridView version = "2.4.1">') = 0) then //Process GridView Tag
state := xmlGridView
else if (CompareText(s, '<Columns>') = 0) then //Process Columns Tag
begin
//sl.Add(Format(' <Column Name="%s" ColumnClass="%s">', [GridView.Columns[c].Name, GridView.Columns[c].ClassName]));
//sl.Add(' ' + EscapeValue(GridView.Columns[c].Header.Caption));
c := 0;
State := xmlColumns;
end
else if AnsiStartsText('<Column ', s) then //Process Column Tag
begin
state := xmlColumn;
a := TStringList.Create();
s := FetchAttributes('Column', s, a);
s := FetchInnerText('Column', s);
GridView.Columns[c].Header.Caption := s;
//Use StringList 'a' here to restore Column Class Dependend Values (like min/max).
//This information can also be cached to match <Cell> tags to the correct column
//so importing data after changing the order of the columns is also supported.
Inc(c);
a.Free;
state := xmlColumns;
end
else if (CompareText(s, '</Columns>') = 0) then //Finished Processing Columns Tag
begin
c := 0;
State := xmlGridView;
end
else if (CompareText(s, '<Rows>') = 0) then //Process Rows Tag
begin
State := xmlRows;
end
else if (AnsiStartsText(s, '<Row>')) then //Process Row Tag
begin
Inc(r);
GridView.AddRow();
c := 0;
State := xmlRows;
end
else if AnsiStartsText('<Cell>', s) then //Process Cell Tag
begin
State := xmlCell;
GridView.Cell[c, Pred(GridView.RowCount)].AsString := FetchInnerText('Cell', s);
Inc(c);
State := xmlCells;
end
else if (CompareText(s, '</Row>') = 0) then //Finished Processing Row Tag
begin
State := xmlRows;
end
else if (CompareText(s, '</Rows>') = 0) then //Finished Processing Rows Tag
begin
State := xmlGridView;
end
else if (CompareText(s, '</GridView>') = 0) then //Finished Processing GridView Tag
state := xmlNone;
until sl.Count = 0;
sl.Free;
end;
procedure GV_MoveSelectionUp(var Gridview: TGridView);
var
i, j : Integer;
begin
//determine if we can move or condense any further upwards
for i := 0 to Pred(GridView.SelectedCount) do
if not (GridView.Selected[i]) then
begin
for j := i to Pred(GridView.RowCount) do
if (GridView.Selected[j]) then
GridView.MoveRow(j, Pred(j));
Break;
end;
end;
procedure GV_MoveSelectionDown(var Gridview: TGridView);
var
i, j : Integer;
begin
//determine if we can move or condense any further downwards
for i := Pred(GridView.RowCount) downto (GridView.RowCount - GridView.SelectedCount) do
if not (GridView.Selected[i]) then
begin
for j := i downto 0 do
if (GridView.Selected[j]) then
GridView.MoveRow(j, Succ(j));
Break;
end;
end;
procedure GV_AddRowWithValues(var GridView: TGridView; const columnnames, columnvalues: array of OleVariant);
var
i : Integer;
begin
//Sample Usage:
// AddRowWithValues(GridView1, ['Columnname1','ColumnName2'], ['aValue',25]);
if (Length(columnnames) = Length(columnvalues)) then
begin
GridView.AddRow();
for i := 0 to Pred(Length(columnnames)) do
GridView.CellByName[columnnames[i], 'last'].AsString := columnvalues[i];
end;
end;
function GV_LookupValue(const GridView: TGridView; const lookupcolumnname, lookupvalue, valuecolumnname: OleVariant): OleVariant;
var
i : Integer;
begin
//Sample Usage:
// value:=LookupValue(GridView2, 'ParameterNames', 'aKey', 'ParameterValues');
Result := '';
with GridView do
for i := 0 to Pred(RowCount) do
if CompareText(CellByName[lookupcolumnname, i].AsString, VarToStr(lookupvalue)) = 0 then
begin
Result := CellByName[valuecolumnname, i].AsString;
Break;
end;
end;
function GV_InsertGridViewTable(const GridView: TGridView): string;
var
r, c : Integer;
sl : TStringList;
begin
//Sample StyleSheet:
// <STYLE>
// TABLE {border-collapse:collapse}
// TD {border-width:1px}
// TH {background-color:silver}
// </STYLE>
sl := TStringList.Create;
sl.Add('<TABLE BORDER CELLSPACING=0 CELLPADDING=1 WIDTH="100%">');
sl.Add('<TR ALIGN="left" VALIGN="middle">');
for c := 0 to Pred(GridView.Columns.Count) do
sl.Add(Format(' <TH>%s</TH>', [GridView.Columns[c].Header.Caption]));
sl.Add('</TR>');
for r := 0 to Pred(GridView.RowCount) do
begin
sl.Add('<TR ALIGN="left" VALIGN="middle">');
for c := 0 to Pred(GridView.Columns.Count) do
begin
if (GridView.Columns.Item[c] is TNumericColumn) then
sl.Add(Format(' <TD ALIGN="right">%s</TD>', [GridView.Cells[c, r]]))
else
sl.Add(Format(' <TD>%s</TD>', [GridView.Cells[c, r]]));
end;
sl.Add('</TR>');
end;
sl.Add('</TABLE>');
Result := sl.Text;
sl.Free;
end;
procedure GV_SaveGridData(const GridView: TGridView; const FileName: string; const Prefix: string = '');
var
IniFile : TIniFile;
Section : string;
Data : TStringList;
i, j : Integer;
begin
Section := Format('%sData', [Prefix]);
with GridView do
begin
IniFile := TIniFile.Create(FileName);
IniFile.WriteInteger(section, 'ColumnsCount', Columns.Count);
IniFile.WriteInteger(section, 'RowsCount', RowCount);
Data := TStringList.Create;
for j := 0 to Pred(RowCount) do
begin
Data.Clear;
for i := 0 to Pred(Columns.Count) do
Data.Add(Cells[i, j]);
Data.Delimiter := ListSeparator;
IniFile.WriteString(section, Format('Row%d', [j]), Data.DelimitedText);
end;
IniFile.UpdateFile;
Data.Free;
IniFile.Free;
end;
end;
procedure GV_RestoreGridData(var GridView: TGridView; const FileName: string; const Prefix: string = '');
var
IniFile : TIniFile;
Layout : TStringList;
Section : string;
Cols, Rows,
i, j : Integer;
begin
Section := Format('%sData', [Prefix]);
with GridView do
begin
ClearRows;
IniFile := TIniFile.Create(FileName);
Layout := TStringList.Create;
Cols := IniFile.ReadInteger(section, 'ColumnsCount', Columns.Count);
Rows := IniFile.ReadInteger(section, 'RowsCount', Columns.Count);
for j := 0 to Pred(Rows) do
begin
Layout.Delimiter := ListSeparator;
Layout.DelimitedText := IniFile.ReadString(section, Format('Row%d', [j]), '');
if (Layout.Count = Cols) then
begin
AddRow();
for i := 0 to Pred(Cols) do
Cells[i, j] := Layout[i];
end;
end;
Layout.Free;
IniFile.Free;
end;
end;
end.
interface
uses
GridView;
procedure GV_SaveGridLayout(const GridView: TGridView; const FileName: string; const Prefix: string = '');
procedure GV_RestoreGridLayout(var GridView: TGridView; const FileName: string; const Prefix: string = '');
procedure GV_SaveGridData(const GridView: TGridView; const FileName: string; const Prefix: string = '');
procedure GV_RestoreGridData(var GridView: TGridView; const FileName: string; const Prefix: string = '');
procedure GV_ExportToCsv(const GridView: TGridView; const fn: string; const header: Boolean = True);
procedure GV_ExportToXml(const GridView: TGridView; const fn: string);
procedure GV_ImportFromXml(var GridView: TGridView; const fn: string);
procedure GV_MoveSelectionUp(var Gridview: TGridView);
procedure GV_MoveSelectionDown(var Gridview: TGridView);
procedure GV_AddRowWithValues(var GridView: TGridView; const columnnames, columnvalues: array of OleVariant);
function GV_LookupValue(const GridView: TGridView; const lookupcolumnname, lookupvalue, valuecolumnname: OleVariant): OleVariant;
function GV_InsertGridViewTable(const GridView: TGridView): string;
implementation
uses
ColumnClasses,
Columns,
Classes,
Dialogs,
IniFiles,
StrUtils,
SysUtils,
Variants, CustomGridViewControl;
procedure GV_SaveGridLayout(const GridView: TGridView; const FileName: string; const Prefix: string = '');
var
IniFile : TIniFile;
Section : string;
Layout : TStringList;
i : Integer;
begin
Section := Format('%sLayout', [Prefix]);
with GridView do
begin
IniFile := TIniFile.Create(FileName);
IniFile.WriteInteger(section, 'ColumnsCount', Columns.Count);
Layout := TStringList.Create;
for i := 0 to Pred(Columns.Count) do
begin
Layout.Clear;
Layout.Add(IntToStr(Ord(Columns[i].SortKind)));
Layout.Add(IntToStr(Ord(Columns[i].Visible)));
Layout.Add(IntToStr(Ord(Columns[i].Sorted)));
Layout.Add(IntToStr(Ord(Columns[i].Position)));
Layout.Add(IntToStr(Ord(Columns[i].Width)));
Layout.Delimiter := ListSeparator;
IniFile.WriteString(section, Format('Column%d', [i]), Layout.DelimitedText);
end;
IniFile.UpdateFile;
Layout.Free;
IniFile.Free;
end;
end;
procedure GV_RestoreGridLayout(var GridView: TGridView; const FileName: string; const Prefix: string = '');
var
IniFile : TIniFile;
Layout : TStringList;
Section : string;
Count,
i : Integer;
begin
Section := Format('%sLayout', [Prefix]);
with GridView do
begin
IniFile := TIniFile.Create(FileName);
Layout := TStringList.Create;
Count := IniFile.ReadInteger(section, 'ColumnsCount', Columns.Count);
for i := 0 to Pred(Count) do
begin
Layout.Delimiter := ListSeparator;
Layout.DelimitedText := IniFile.ReadString(section, Format('Column%d', [i]), '');
if (Layout.Count = 5) then
begin
Columns[i].SortKind := TSortKind(StrToInt(Layout[0]));
Columns[i].Visible := Boolean(StrToInt(Layout[1]));
Columns[i].Sorted := Boolean(StrToInt(Layout[2]));
Columns[i].Position := StrToInt(Layout[3]);
Columns[i].Width := StrToInt(Layout[4]);
end;
end;
Layout.Free;
IniFile.Free;
end;
end;
procedure GV_ExportToCsv(const GridView: TGridView; const fn: string; const header: Boolean = True);
{
normalcol;"colwithlistseparator;";"colwithquote"""
1;2;5
4;3;6
}
var
r, c : Integer;
sl : TStringList;
s : string;
function EscapeSeparator(const value: string): string;
begin
if (Pos('"', value) > 0) then
Result := StringReplace(value, '"', '""', [rfReplaceAll])
else
Result := value;
if (Pos(ListSeparator, Result) > 0) or (Pos('""', Result) > 0) then
Result := '"' + Result + '"'
end;
begin
sl := TStringList.Create;
if header then
begin
s := '';
for c := 0 to Pred(GridView.Columns.Count) do
begin
if c <> 0 then
s := s + ListSeparator + EscapeSeparator(GridView.Columns[c].Header.Caption)
else
s := EscapeSeparator(GridView.Columns[c].Header.Caption);
end;
sl.Add(s);
end;
for r := 0 to Pred(GridView.RowCount) do
begin
s := '';
for c := 0 to Pred(GridView.Columns.Count) do
begin
if c <> 0 then
s := s + ListSeparator + EscapeSeparator(GridView.Cell[c, r].AsString)
else
s := EscapeSeparator(GridView.Cell[c, r].AsString);
end;
sl.Add(s);
end;
sl.SaveToFile(fn);
sl.Free;
end;
procedure GV_ExportToXml(const GridView: TGridView; const fn: string);
var
r, c : Integer;
sl : TStringList;
function EscapeValue(const value: string): string;
begin
//Not implemented yet.
//Change all characters outside the letters, numbers and crlf to
//< format where 3C is the hex value of the Characters Ord.
Result := value;
end;
begin
sl := TStringList.Create;
sl.Add('<?xml version="1.0"?>');
sl.Add(Format('<GridView version = "%s">', ['2.4.1'])); //Should be stVersion!
sl.Add(' <Columns>');
for c := 0 to Pred(GridView.Columns.Count) do
begin
//Use Attributes to Export Column Dependend settings like min/max values.
sl.Add(Format(' <Column Name="%s" ColumnClass="%s">', [GridView.Columns[c].Name, GridView.Columns[c].ClassName]));
sl.Add(' ' + EscapeValue(GridView.Columns[c].Header.Caption));
sl.Add(' </Column>');
end;
sl.Add(' </Columns>');
sl.Add(' <Rows>');
for r := 0 to Pred(GridView.RowCount) do
begin
sl.Add(' <Row>');
for c := 0 to Pred(GridView.Columns.Count) do
begin
sl.Add(' <Cell>');
{if not (GridView.Columns[c].ClassNameIs('TGraphicColumn') or
GridView.Columns[c].ClassNameIs('TImageColumn')) then}
sl.Add(' ' + EscapeValue(GridView.Cell[c, r].AsString));
sl.Add(' </Cell>');
end;
sl.Add(' </Row>');
end;
sl.Add(' </Rows>');
sl.Add('</GridView>');
sl.SaveToFile(fn);
sl.Free;
end;
procedure GV_ImportFromXml(var GridView: TGridView; const fn: string);
var
sl : TStringList;
function FetchAttributes(tag, value: string; var a: TStringList): string;
var
i : Integer;
s : string;
begin
//Fetch the attributes into a TStringList.
Result := value;
Delete(Result, 1, Length(Format('<%s ', [tag])));
Delete(Result, Pos('>', Result), Length(Result));
a.Text := Trim(Result);
//Return the input value without the Attributes.
Result := value;
Delete(Result, 1, Pos('>', Result) + 1);
Result := Format('<%s>', [tag]) + Result;
//Remove Surrounding Quotes from Value.
for i := 0 to Pred(a.Count) do
begin
s := a.Values[a.Names[i]];
if (s[1] = '"') and (s[Length(s)] = '"') then
begin
Delete(s, 1, 1);
Delete(s, Length(s), 1);
end;
a.Values[a.Names[i]] := s;
end;
end;
function FetchInnerText(tag, value: string): string;
begin
//Fetch the Text between a start and end tag.
Result := value;
Delete(Result, 1, Length(Format('<%s>', [tag])));
while not (AnsiEndsText(Format('</%s>', [tag]), Result)) do
begin
Result := Result + Trim(sl[0]);
sl.Delete(0);
end;
Delete(Result, Pos(Format('</%s>', [tag]), Result), Length(Result));
Result := Trim(Result);
end;
type
states = (xmlNone, xmlHeader, xmlGridView, xmlColumns, xmlColumn, xmlRows, xmlRow, xmlCells, xmlCell);
var
r, c : Integer;
i : Integer;
s : string;
state : states;
a : TStringList;
begin
sl := TStringList.Create;
GridView.ClearRows;
for i := 0 to Pred(GridView.Columns.Count) do
GridView.Columns[i].Header.Caption := '';
GridView.Update;
sl.LoadFromFile(fn);
r := 0;
c := 0;
state := xmlNone;
repeat
s := Trim(sl[0]);
sl.Delete(0);
if (CompareText(s, '<?xml version="1.0"?>') = 0) then //Process XML Version
begin
if (state <> xmlNone) then
begin
ShowMessage('Xml header not found.');
Break;
end
else
state := xmlHeader;
end
else if (CompareText(s, '<GridView version = "2.4.1">') = 0) then //Process GridView Tag
state := xmlGridView
else if (CompareText(s, '<Columns>') = 0) then //Process Columns Tag
begin
//sl.Add(Format(' <Column Name="%s" ColumnClass="%s">', [GridView.Columns[c].Name, GridView.Columns[c].ClassName]));
//sl.Add(' ' + EscapeValue(GridView.Columns[c].Header.Caption));
c := 0;
State := xmlColumns;
end
else if AnsiStartsText('<Column ', s) then //Process Column Tag
begin
state := xmlColumn;
a := TStringList.Create();
s := FetchAttributes('Column', s, a);
s := FetchInnerText('Column', s);
GridView.Columns[c].Header.Caption := s;
//Use StringList 'a' here to restore Column Class Dependend Values (like min/max).
//This information can also be cached to match <Cell> tags to the correct column
//so importing data after changing the order of the columns is also supported.
Inc(c);
a.Free;
state := xmlColumns;
end
else if (CompareText(s, '</Columns>') = 0) then //Finished Processing Columns Tag
begin
c := 0;
State := xmlGridView;
end
else if (CompareText(s, '<Rows>') = 0) then //Process Rows Tag
begin
State := xmlRows;
end
else if (AnsiStartsText(s, '<Row>')) then //Process Row Tag
begin
Inc(r);
GridView.AddRow();
c := 0;
State := xmlRows;
end
else if AnsiStartsText('<Cell>', s) then //Process Cell Tag
begin
State := xmlCell;
GridView.Cell[c, Pred(GridView.RowCount)].AsString := FetchInnerText('Cell', s);
Inc(c);
State := xmlCells;
end
else if (CompareText(s, '</Row>') = 0) then //Finished Processing Row Tag
begin
State := xmlRows;
end
else if (CompareText(s, '</Rows>') = 0) then //Finished Processing Rows Tag
begin
State := xmlGridView;
end
else if (CompareText(s, '</GridView>') = 0) then //Finished Processing GridView Tag
state := xmlNone;
until sl.Count = 0;
sl.Free;
end;
procedure GV_MoveSelectionUp(var Gridview: TGridView);
var
i, j : Integer;
begin
//determine if we can move or condense any further upwards
for i := 0 to Pred(GridView.SelectedCount) do
if not (GridView.Selected[i]) then
begin
for j := i to Pred(GridView.RowCount) do
if (GridView.Selected[j]) then
GridView.MoveRow(j, Pred(j));
Break;
end;
end;
procedure GV_MoveSelectionDown(var Gridview: TGridView);
var
i, j : Integer;
begin
//determine if we can move or condense any further downwards
for i := Pred(GridView.RowCount) downto (GridView.RowCount - GridView.SelectedCount) do
if not (GridView.Selected[i]) then
begin
for j := i downto 0 do
if (GridView.Selected[j]) then
GridView.MoveRow(j, Succ(j));
Break;
end;
end;
procedure GV_AddRowWithValues(var GridView: TGridView; const columnnames, columnvalues: array of OleVariant);
var
i : Integer;
begin
//Sample Usage:
// AddRowWithValues(GridView1, ['Columnname1','ColumnName2'], ['aValue',25]);
if (Length(columnnames) = Length(columnvalues)) then
begin
GridView.AddRow();
for i := 0 to Pred(Length(columnnames)) do
GridView.CellByName[columnnames[i], 'last'].AsString := columnvalues[i];
end;
end;
function GV_LookupValue(const GridView: TGridView; const lookupcolumnname, lookupvalue, valuecolumnname: OleVariant): OleVariant;
var
i : Integer;
begin
//Sample Usage:
// value:=LookupValue(GridView2, 'ParameterNames', 'aKey', 'ParameterValues');
Result := '';
with GridView do
for i := 0 to Pred(RowCount) do
if CompareText(CellByName[lookupcolumnname, i].AsString, VarToStr(lookupvalue)) = 0 then
begin
Result := CellByName[valuecolumnname, i].AsString;
Break;
end;
end;
function GV_InsertGridViewTable(const GridView: TGridView): string;
var
r, c : Integer;
sl : TStringList;
begin
//Sample StyleSheet:
// <STYLE>
// TABLE {border-collapse:collapse}
// TD {border-width:1px}
// TH {background-color:silver}
// </STYLE>
sl := TStringList.Create;
sl.Add('<TABLE BORDER CELLSPACING=0 CELLPADDING=1 WIDTH="100%">');
sl.Add('<TR ALIGN="left" VALIGN="middle">');
for c := 0 to Pred(GridView.Columns.Count) do
sl.Add(Format(' <TH>%s</TH>', [GridView.Columns[c].Header.Caption]));
sl.Add('</TR>');
for r := 0 to Pred(GridView.RowCount) do
begin
sl.Add('<TR ALIGN="left" VALIGN="middle">');
for c := 0 to Pred(GridView.Columns.Count) do
begin
if (GridView.Columns.Item[c] is TNumericColumn) then
sl.Add(Format(' <TD ALIGN="right">%s</TD>', [GridView.Cells[c, r]]))
else
sl.Add(Format(' <TD>%s</TD>', [GridView.Cells[c, r]]));
end;
sl.Add('</TR>');
end;
sl.Add('</TABLE>');
Result := sl.Text;
sl.Free;
end;
procedure GV_SaveGridData(const GridView: TGridView; const FileName: string; const Prefix: string = '');
var
IniFile : TIniFile;
Section : string;
Data : TStringList;
i, j : Integer;
begin
Section := Format('%sData', [Prefix]);
with GridView do
begin
IniFile := TIniFile.Create(FileName);
IniFile.WriteInteger(section, 'ColumnsCount', Columns.Count);
IniFile.WriteInteger(section, 'RowsCount', RowCount);
Data := TStringList.Create;
for j := 0 to Pred(RowCount) do
begin
Data.Clear;
for i := 0 to Pred(Columns.Count) do
Data.Add(Cells[i, j]);
Data.Delimiter := ListSeparator;
IniFile.WriteString(section, Format('Row%d', [j]), Data.DelimitedText);
end;
IniFile.UpdateFile;
Data.Free;
IniFile.Free;
end;
end;
procedure GV_RestoreGridData(var GridView: TGridView; const FileName: string; const Prefix: string = '');
var
IniFile : TIniFile;
Layout : TStringList;
Section : string;
Cols, Rows,
i, j : Integer;
begin
Section := Format('%sData', [Prefix]);
with GridView do
begin
ClearRows;
IniFile := TIniFile.Create(FileName);
Layout := TStringList.Create;
Cols := IniFile.ReadInteger(section, 'ColumnsCount', Columns.Count);
Rows := IniFile.ReadInteger(section, 'RowsCount', Columns.Count);
for j := 0 to Pred(Rows) do
begin
Layout.Delimiter := ListSeparator;
Layout.DelimitedText := IniFile.ReadString(section, Format('Row%d', [j]), '');
if (Layout.Count = Cols) then
begin
AddRow();
for i := 0 to Pred(Cols) do
Cells[i, j] := Layout[i];
end;
end;
Layout.Free;
IniFile.Free;
end;
end;
end.
Have fun coding..