Jump to content


Photo

NextGridUtils


  • Please log in to reply
3 replies to this topic

#1 wvd_vegt

wvd_vegt

    Master Member

  • Honorable Members
  • PipPipPipPipPip
  • 710 posts
  • Gender:Male
  • Location:the Netherlands

Posted 26 May 2005 - 09:39 PM

Hi,

Bit late but I updated my Gridview Utils to NextGridUtils.

Besides translation the only new thing is a selected parameter for the CVS routines. I moved the bulk of the code from NG_ExportToCsv to a new funtion called NG_ToCsvString. This to enable clipboarding to excel like:

CODE
var

 ls                : Char;

begin

 ls := ListSeparator;

 ListSeparator := #9;

 ClipBoard.AsText := NG_ToCsvString(NextGrid1, False, True);

 ListSeparator := ls;


Note without the #9 Excel will paste all into the first column. For cvs files the separator has to be the listseparator.

As usual have fun coding and share it!

CODE
{-----------------------------------------------------------}

{----Purpose : NextGrid utilities                           }

{    By      : Ir. G.W. van der Vegt                        }

{    For     : Myself.                                      }

{    Depends : NextGrid                                     }

{-----------------------------------------------------------}

{ ddmmyyyy comment                                          }

{ -------- ------------------------------------------------ }

{ ddmmyyyy-Initial version                                  }

{ 26052005-Translated to NextGrid.                          }

{         -Added NG_ToCsvString function.                   }

{-----------------------------------------------------------}

{ notes:                                                    }

{ 1.                                                        }

{-----------------------------------------------------------}

{ todo:                                                     }

{ 1.                                                        }

{-----------------------------------------------------------}



unit NextGridUtils;



interface



uses

 NxGrid;



procedure NG_SaveGridLayout(const NextGrid: TNextGrid; const FileName: string; const Prefix: string = '');

procedure NG_RestoreGridLayout(var NextGrid: TNextGrid; const FileName: string; const Prefix: string = '');



procedure NG_SaveGridData(const NextGrid: TNextGrid; const FileName: string; const Prefix: string = '');

procedure NG_RestoreGridData(var NextGrid: TNextGrid; const FileName: string; const Prefix: string = '');



procedure NG_ExportToCsv(const NextGrid: TNextGrid; const fn: string; const header: Boolean = True; const selected: Boolean = False);

function NG_ToCsvString(const NextGrid: TNextGrid; const header: Boolean = True; const selected: Boolean = False): string;



procedure NG_ExportToXml(const NextGrid: TNextGrid; const fn: string);

procedure NG_ImportFromXml(var NextGrid: TNextGrid; const fn: string);



procedure NG_MoveSelectionUp(var NextGrid: TNextGrid);

procedure NG_MoveSelectionDown(var NextGrid: TNextGrid);



procedure NG_AddRowWithValues(var NextGrid: TNextGrid; const columnnames, columnvalues: array of OleVariant);



function NG_LookupValue(const NextGrid: TNextGrid; const lookupcolumnname, lookupvalue, valuecolumnname: OleVariant): OleVariant;



function NG_InserNextGridTable(const NextGrid: TNextGrid): string;



function NG_LocateGrid(const NextGrid: TNextGrid; colnames, values: array of

 string): Integer;



function NG_LookupGrid(const NextGrid: TNextGrid; colnames: array of string;

 values: array of variant; return: string): string;



implementation



uses

 NxCustomGridControl,

 NxColumnClasses,

 NxColumns,

 Classes,

 Dialogs,

 IniFiles,

 StrUtils,

 SysUtils,

 Variants;



procedure NG_SaveGridLayout(const NextGrid: TNextGrid; const FileName: string; const Prefix: string = '');

var

 IniFile           : TIniFile;

 Section           : string;

 Layout            : TStringList;

 i                 : Integer;

begin

 Section := Format('%sLayout', [Prefix]);



 with NextGrid 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 NG_RestoreGridLayout(var NextGrid: TNextGrid; const FileName: string; const Prefix: string = '');

var

 IniFile           : TIniFile;

 Layout            : TStringList;

 Section           : string;

 Count,

   i               : Integer;

begin

 Section := Format('%sLayout', [Prefix]);



 with NextGrid 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 NG_ExportToCsv(const NextGrid: TNextGrid; const fn: string; const header: Boolean = True; const selected: Boolean = False);

var

 sl                : TStringList;

begin

 sl := TStringList.Create;

 sl.Text := NG_ToCsvString(NextGrid, header, selected);

 sl.SaveToFile(fn);

 sl.Free;

end;



function NG_ToCsvString(const NextGrid: TNextGrid; const header: Boolean = True; const selected: Boolean = False): string;

{

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(NextGrid.Columns.Count) do

       begin

         if c <> 0 then

           s := s + ListSeparator + EscapeSeparator(NextGrid.Columns[c].Header.Caption)

         else

           s := EscapeSeparator(NextGrid.Columns[c].Header.Caption);

       end;

     sl.Add(s);

   end;



 for r := 0 to Pred(NextGrid.RowCount) do

   if selected and NextGrid.Selected[r] then

     begin

       s := '';

       for c := 0 to Pred(NextGrid.Columns.Count) do

         begin

           if c <> 0 then

             s := s + ListSeparator + EscapeSeparator(NextGrid.Cell[c, r].AsString)

           else

             s := EscapeSeparator(NextGrid.Cell[c, r].AsString);

         end;

       sl.Add(s);

     end;



 Result := sl.Text;

 sl.Free;

end;



procedure NG_ExportToXml(const NextGrid: TNextGrid; 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

 //&#x3C; 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('<NextGrid version = "%s">', ['2.4.1']));                       //Should be stVersion!



 sl.Add(' <Columns>');

 for c := 0 to Pred(NextGrid.Columns.Count) do

   begin

   //Use Attributes to Export Column Dependend settings like min/max values.

     sl.Add(Format('  <Column Name="%s" ColumnClass="%s">', [NextGrid.Columns[c].Name, NextGrid.Columns[c].ClassName]));

     sl.Add('    ' + EscapeValue(NextGrid.Columns[c].Header.Caption));

     sl.Add('  </Column>');

   end;

 sl.Add(' </Columns>');



 sl.Add(' <Rows>');

 for r := 0 to Pred(NextGrid.RowCount) do

   begin

     sl.Add('  <Row>');

     for c := 0 to Pred(NextGrid.Columns.Count) do

       begin

         sl.Add('   <Cell>');

        {if not (NextGrid.Columns[c].ClassNameIs('TGraphicColumn') or

           NextGrid.Columns[c].ClassNameIs('TImageColumn')) then}

         sl.Add('    ' + EscapeValue(NextGrid.Cell[c, r].AsString));

         sl.Add('   </Cell>');

       end;

     sl.Add('   </Row>');

   end;

 sl.Add(' </Rows>');



 sl.Add('</NextGrid>');



 sl.SaveToFile(fn);

 sl.Free;

end;



procedure NG_ImportFromXml(var NextGrid: TNextGrid; 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, xmlNextGrid, xmlColumns, xmlColumn, xmlRows, xmlRow, xmlCells, xmlCell);



var

 r, c              : Integer;

 i                 : Integer;

 s                 : string;

 state             : states;

 a                 : TStringList;



begin

 sl := TStringList.Create;



 NextGrid.ClearRows;

 for i := 0 to Pred(NextGrid.Columns.Count) do

   NextGrid.Columns[i].Header.Caption := '';

 NextGrid.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, '<NextGrid version = "2.4.1">') = 0) then           //Process NextGrid Tag

     state := xmlNextGrid



   else if (CompareText(s, '<Columns>') = 0) then                              //Process Columns Tag

     begin

     //sl.Add(Format('  <Column Name="%s" ColumnClass="%s">', [NextGrid.Columns[c].Name, NextGrid.Columns[c].ClassName]));

     //sl.Add('    ' + EscapeValue(NextGrid.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);

       NextGrid.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 := xmlNextGrid;

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

       NextGrid.AddRow();

       c := 0;

       State := xmlRows;

     end

   else if AnsiStartsText('<Cell>', s) then                                    //Process Cell Tag

     begin

       State := xmlCell;

       NextGrid.Cell[c, Pred(NextGrid.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 := xmlNextGrid;

     end

   else if (CompareText(s, '</NextGrid>') = 0) then                            //Finished Processing NextGrid Tag

     state := xmlNone;



 until sl.Count = 0;



 sl.Free;

end;



procedure NG_MoveSelectionUp(var NextGrid: TNextGrid);

var

 i, j              : Integer;

begin

 //determine if we can move or condense any further upwards

 for i := 0 to Pred(NextGrid.SelectedCount) do

   if not (NextGrid.Selected[i]) then

     begin

       for j := i to Pred(NextGrid.RowCount) do

         if (NextGrid.Selected[j]) then

           NextGrid.MoveRow(j, Pred(j));

       Break;

     end;

end;



procedure NG_MoveSelectionDown(var NextGrid: TNextGrid);

var

 i, j              : Integer;

begin

 //determine if we can move or condense any further downwards

 for i := Pred(NextGrid.RowCount) downto (NextGrid.RowCount - NextGrid.SelectedCount) do

   if not (NextGrid.Selected[i]) then

     begin

       for j := i downto 0 do

         if (NextGrid.Selected[j]) then

           NextGrid.MoveRow(j, Succ(j));

       Break;

     end;

end;



procedure NG_AddRowWithValues(var NextGrid: TNextGrid; const columnnames, columnvalues: array of OleVariant);

var

 i                 : Integer;

begin



//Sample Usage:

//       AddRowWithValues(NextGrid1, ['Columnname1','ColumnName2'], ['aValue',25]);



 if (Length(columnnames) = Length(columnvalues)) then

   begin

     NextGrid.AddRow();

     for i := 0 to Pred(Length(columnnames)) do

       NextGrid.CellByName[columnnames[i], 'last'].AsString := columnvalues[i];

   end;

end;



function NG_LookupValue(const NextGrid: TNextGrid; const lookupcolumnname, lookupvalue, valuecolumnname: OleVariant): OleVariant;

var

 i                 : Integer;

begin



//Sample Usage:

//       value:=LookupValue(NextGrid2, 'ParameterNames', 'aKey', 'ParameterValues');



 Result := '';

 with NextGrid 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 NG_InserNextGridTable(const NextGrid: TNextGrid): 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(NextGrid.Columns.Count) do

   sl.Add(Format('   <TH>%s</TH>', [NextGrid.Columns[c].Header.Caption]));

 sl.Add('</TR>');



 for r := 0 to Pred(NextGrid.RowCount) do

   begin

     sl.Add('<TR ALIGN="left" VALIGN="middle">');

     for c := 0 to Pred(NextGrid.Columns.Count) do

       begin

         if (NextGrid.Columns.Item[c] is TNxNumberColumn) then

           sl.Add(Format('   <TD ALIGN="right">%s</TD>', [NextGrid.Cells[c, r]]))

         else

           sl.Add(Format('   <TD>%s</TD>', [NextGrid.Cells[c, r]]));

       end;

     sl.Add('</TR>');

   end;

 sl.Add('</TABLE>');

 Result := sl.Text;

 sl.Free;

end;



procedure NG_SaveGridData(const NextGrid: TNextGrid; const FileName: string; const Prefix: string = '');

var

 IniFile           : TIniFile;

 Section           : string;

 Data              : TStringList;

 i, j              : Integer;

begin

 Section := Format('%sData', [Prefix]);



 with NextGrid 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 NG_RestoreGridData(var NextGrid: TNextGrid; const FileName: string; const Prefix: string = '');

var

 IniFile           : TIniFile;

 Layout            : TStringList;

 Section           : string;

 Cols, Rows,

   i, j            : Integer;

begin

 Section := Format('%sData', [Prefix]);



 with NextGrid 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;



function NG_LocateGrid(const NextGrid: TNextGrid; colnames, values: array of

 string): Integer;

var

 i                 : Integer;

 j                 : Integer;

 match             : Boolean;

begin

 Result := -1;



 if (High(colnames) <> High(Values)) then exit;



 with NextGrid do

   for i := 0 to Pred(RowCount) do

     begin

       match := True;

       for j := 0 to High(colnames) do

         if not SameText(CellByName[colnames[j], i].AsString, values[j]) then

           begin

             match := False;

             break;

           end;

       if match then

         begin

           Result := i;

           break;

         end;



     end;

end;



function NG_LookupGrid(const NextGrid: TNextGrid; colnames: array of string;

 values: array of variant; return: string): string;

var

 i                 : Integer;

 j                 : Integer;

 match             : Boolean;

begin

 Result := '';



 if (High(colnames) <> High(Values)) then exit;



 with NextGrid do

   for i := 0 to Pred(RowCount) do

     begin

       match := True;

       for j := 0 to High(colnames) do

         if not SameText(CellByName[colnames[j], i].AsString, VarToStr(values[j])) then

           begin

             match := False;

             break;

           end;

       if match then

         begin

           Result := CellByName[return, i].AsString;

           break;

         end;

     end;

end;



end.

G.W. van der Vegt

#2 Boki (Berg)

Boki (Berg)

    Boki (Berg)

  • Forum Admin
  • PipPipPipPipPip
  • 8,191 posts
  • Gender:Male

Posted 26 May 2005 - 09:50 PM

Thank you Wim again for your contribution. smile.gif

regards
boki@bergsoft.net | LinkedIn Profile
--
BergSoft Home Page: www.bergsoft.net
Users Section: users.bergsoft.net
Articles and Tutorials: help.bergsoft.net (Developers Network)
--
BergSoft Facebook page
--
Send us applications made with our components and we will submit them on: www.bergsoft.net/apps.htm. Link to this page will be also set on home page too.

#3 PatVdv

PatVdv
  • Members
  • 10 posts
  • Location:Belgium
  • Interests:Computer... Computer...

Posted 17 June 2005 - 09:39 PM

Thanks a lot for your sources.

laugh.gif

Regards

#4 wvd_vegt

wvd_vegt

    Master Member

  • Honorable Members
  • PipPipPipPipPip
  • 710 posts
  • Gender:Male
  • Location:the Netherlands

Posted 19 June 2005 - 06:22 PM

Hi,

No problem, i just like sharing code.
G.W. van der Vegt




1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users