Import an Excel Table to a TStringgrid

Preview:

DESCRIPTION

Import an Excel Table to a TStringgrid

Citation preview

..import an Excel Table to a TStringgrid?

uses  ComObj;

function Xls_To_StringGrid(AGrid: TStringGrid; AXLSFile: string): Boolean;const  xlCellTypeLastCell = $0000000B;var  XLApp, Sheet: OLEVariant;  RangeMatrix: Variant;  x, y, k, r: Integer;begin  Result := False;  // Create Excel-OLE Object  XLApp := CreateOleObject('Excel.Application');  try    // Hide Excel    XLApp.Visible := False;

    // Open the Workbook    XLApp.Workbooks.Open(AXLSFile);

    // Sheet := XLApp.Workbooks[1].WorkSheets[1];    Sheet := XLApp.Workbooks[ExtractFileName(AXLSFile)].WorkSheets[1];

    // In order to know the dimension of the WorkSheet, i.e the number of rows    // and the number of columns, we activate the last non-empty cell of it

    Sheet.Cells.SpecialCells(xlCellTypeLastCell, EmptyParam).Activate;    // Get the value of the last row    x := XLApp.ActiveCell.Row;    // Get the value of the last column    y := XLApp.ActiveCell.Column;

    // Set Stringgrid's row &col dimensions.

    AGrid.RowCount := x;    AGrid.ColCount := y;

    // Assign the Variant associated with the WorkSheet to the Delphi Variant

    RangeMatrix := XLApp.Range['A1', XLApp.Cells.Item[X, Y]].Value;    //  Define the loop for filling in the TStringGrid    k := 1;    repeat      for r := 1 to y do        AGrid.Cells[(r - 1), (k - 1)] := RangeMatrix[K, R];      Inc(k, 1);      AGrid.RowCount := k + 1;    until k > x;    // Unassign the Delphi Variant Matrix    RangeMatrix := Unassigned;

  finally    // Quit Excel

    if not VarIsEmpty(XLApp) then    begin      // XLApp.DisplayAlerts := False;      XLApp.Quit;      XLAPP := Unassigned;      Sheet := Unassigned;      Result := True;    end;  end;end;

procedure TForm1.Button1Click(Sender: TObject);begin  if Xls_To_StringGrid(StringGrid1, 'C:\Table1.xls') then    ShowMessage('Table has been exported!');end;

..export a TStringGrid to a MS Word table?

uses  ComObj;

procedure TForm1.Button1Click(Sender: TObject);var  WordApp, NewDoc, WordTable: OLEVariant;  iRows, iCols, iGridRows, jGridCols: Integer;begin  try    // Create a Word Instance    // Word Instanz erzeugen    WordApp := CreateOleObject('Word.Application');  except    // Error...    // Fehler....    Exit;  end;

  // Show Word  // Word anzeigen  WordApp.Visible := True;

  // Add a new Doc  // Neues Dok einfügen  NewDoc := WordApp.Documents.Add;

  // Get number of columns, rows  // Spalten, Reihen ermitteln  iCols := StringGrid1.ColCount;  iRows := StringGrid1.RowCount;

  // Add a Table  // Tabelle einfügen  WordTable := NewDoc.Tables.Add(WordApp.Selection.Range, iCols, iRows);

  // Fill up the word table with the Stringgrid contents  // Tabelle ausfüllen mit Stringgrid Daten  for iGridRows := 1 to iRows do    for jGridCols := 1 to iCols do      WordTable.Cell(iGridRows, jGridCols).Range.Text :=        StringGrid1.Cells[jGridCols - 1, iGridRows - 1];

  // Here you might want to Save the Doc, quit Word...  // Hier evtl Word Doc speichern, beenden...

  // ...    // Cleanup...  WordApp := Unassigned;  NewDoc := Unassigned;  WordTable := Unassigned;end;

...export a StringGrid to an Excel-File?

{1. With OLE Automation }

uses  ComObj;

function RefToCell(ARow, ACol: Integer): string;begin  Result := Chr(Ord('A') + ACol - 1) + IntToStr(ARow);end;

function SaveAsExcelFile(AGrid: TStringGrid; ASheetName, AFileName: string): Boolean;const  xlWBATWorksheet = -4167;var  Row, Col: Integer;  GridPrevFile: string;  XLApp, Sheet, Data: OLEVariant;  i, j: Integer;begin  // Prepare Data  Data := VarArrayCreate([1, AGrid.RowCount, 1, AGrid.ColCount], varVariant);  for i := 0 to AGrid.ColCount - 1 do    for j := 0 to AGrid.RowCount - 1 do      Data[j + 1, i + 1] := AGrid.Cells[i, j];  // Create Excel-OLE Object  Result := False;  XLApp := CreateOleObject('Excel.Application');  try    // Hide Excel    XLApp.Visible := False;    // Add new Workbook    XLApp.Workbooks.Add(xlWBatWorkSheet);    Sheet := XLApp.Workbooks[1].WorkSheets[1];    Sheet.Name := ASheetName;

    // Fill up the sheet    Sheet.Range[RefToCell(1, 1), RefToCell(AGrid.RowCount,      AGrid.ColCount)].Value := Data;    // Save Excel Worksheet    try      XLApp.Workbooks[1].SaveAs(AFileName);      Result := True;    except      // Error ?    end;  finally    // Quit Excel    if not VarIsEmpty(XLApp) then    begin      XLApp.DisplayAlerts := False;      XLApp.Quit;      XLAPP := Unassigned;      Sheet := Unassigned;    end;  end;end;

// Example:

procedure TForm1.Button1Click(Sender: TObject);begin  if SaveAsExcelFile(stringGrid1, 'My Stringgrid Data', 'c:\MyExcelFile.xls') then    ShowMessage('StringGrid saved!');end;

{**************************************************************}{2. Without OLE }

procedure XlsWriteCellLabel(XlsStream: TStream; const ACol, ARow: Word;  const AValue: string);var  L: Word;const  {$J+}  CXlsLabel: array[0..5] of Word = ($204, 0, 0, 0, 0, 0);  {$J-}begin  L := Length(AValue);  CXlsLabel[1] := 8 + L;  CXlsLabel[2] := ARow;  CXlsLabel[3] := ACol;  CXlsLabel[5] := L;  XlsStream.WriteBuffer(CXlsLabel, SizeOf(CXlsLabel));  XlsStream.WriteBuffer(Pointer(AValue)^, L);end;

function SaveAsExcelFile(AGrid: TStringGrid; AFileName: string): Boolean;const  {$J+} CXlsBof: array[0..5] of Word = ($809, 8, 00, $10, 0, 0); {$J-}

  CXlsEof: array[0..1] of Word = ($0A, 00);var  FStream: TFileStream;  I, J: Integer;begin  Result := False;  FStream := TFileStream.Create(PChar(AFileName), fmCreate or fmOpenWrite);  try    CXlsBof[4] := 0;    FStream.WriteBuffer(CXlsBof, SizeOf(CXlsBof));    for i := 0 to AGrid.ColCount - 1 do      for j := 0 to AGrid.RowCount - 1 do        XlsWriteCellLabel(FStream, I, J, AGrid.cells[i, j]);    FStream.WriteBuffer(CXlsEof, SizeOf(CXlsEof));    Result := True;  finally    FStream.Free;  end;end;

// Example:

procedure TForm1.Button2Click(Sender: TObject);begin  if SaveAsExcelFile(StringGrid1, 'c:\MyExcelFile.xls') then    ShowMessage('StringGrid saved!');end;

{**************************************************************}{3. Code by Reinhard Schatzl }

uses  ComObj;

// Hilfsfunktion für StringGridToExcelSheet// Helper function for StringGridToExcelSheetfunction RefToCell(RowID, ColID: Integer): string;var  ACount, APos: Integer;begin  ACount := ColID div 26;  APos := ColID mod 26;  if APos = 0 then  begin    ACount := ACount - 1;    APos := 26;  end;

  if ACount = 0 then    Result := Chr(Ord('A') + ColID - 1) + IntToStr(RowID);

  if ACount = 1 then    Result := 'A' + Chr(Ord('A') + APos - 1) + IntToStr(RowID);

  if ACount > 1 then    Result := Chr(Ord('A') + ACount - 1) + Chr(Ord('A') + APos - 1) + IntToStr(RowID);

end;

// StringGrid Inhalt in Excel exportieren// Export StringGrid contents to Excelfunction StringGridToExcelSheet(Grid: TStringGrid; SheetName, FileName: string;  ShowExcel: Boolean): Boolean;const  xlWBATWorksheet = -4167;var  SheetCount, SheetColCount, SheetRowCount, BookCount: Integer;  XLApp, Sheet, Data: OLEVariant;  I, J, N, M: Integer;  SaveFileName: string;begin  //notwendige Sheetanzahl feststellen  SheetCount := (Grid.ColCount div 256) + 1;  if Grid.ColCount mod 256 = 0 then    SheetCount := SheetCount - 1;  //notwendige Bookanzahl feststellen  BookCount := (Grid.RowCount div 65536) + 1;  if Grid.RowCount mod 65536 = 0 then    BookCount := BookCount - 1;

  //Create Excel-OLE Object  Result := False;  XLApp  := CreateOleObject('Excel.Application');  try    //Excelsheet anzeigen    if ShowExcel = False then      XLApp.Visible := False    else      XLApp.Visible := True;    //Workbook hinzufügen    for M := 1 to BookCount do    begin      XLApp.Workbooks.Add(xlWBATWorksheet);      //Sheets anlegen      for N := 1 to SheetCount - 1 do      begin        XLApp.Worksheets.Add;      end;    end;    //Sheet ColAnzahl feststellen    if Grid.ColCount <= 256 then      SheetColCount := Grid.ColCount    else      SheetColCount := 256;    //Sheet RowAnzahl feststellen    if Grid.RowCount <= 65536 then      SheetRowCount := Grid.RowCount    else      SheetRowCount := 65536;

    //Sheets befüllen    for M := 1 to BookCount do    begin

      for N := 1 to SheetCount do      begin        //Daten aus Grid holen        Data := VarArrayCreate([1, Grid.RowCount, 1, SheetColCount], varVariant);        for I := 0 to SheetColCount - 1 do          for J := 0 to SheetRowCount - 1 do            if ((I + 256 * (N - 1)) <= Grid.ColCount) and              ((J + 65536 * (M - 1)) <= Grid.RowCount) then              Data[J + 1, I + 1] := Grid.Cells[I + 256 * (N - 1), J + 65536 * (M - 1)];        //-------------------------        XLApp.Worksheets[N].Select;        XLApp.Workbooks[M].Worksheets[N].Name := SheetName + IntToStr(N);        //Zellen als String Formatieren        XLApp.Workbooks[M].Worksheets[N].Range[RefToCell(1, 1),          RefToCell(SheetRowCount, SheetColCount)].Select;        XLApp.Selection.NumberFormat := '@';        XLApp.Workbooks[M].Worksheets[N].Range['A1'].Select;        //Daten dem Excelsheet übergeben        Sheet := XLApp.Workbooks[M].WorkSheets[N];        Sheet.Range[RefToCell(1, 1), RefToCell(SheetRowCount, SheetColCount)].Value :=          Data;      end;    end;    //Save Excel Worksheet    try      for M := 1 to BookCount do      begin        SaveFileName := Copy(FileName, 1,Pos('.', FileName) - 1) + IntToStr(M) +          Copy(FileName, Pos('.', FileName),          Length(FileName) - Pos('.', FileName) + 1);        XLApp.Workbooks[M].SaveAs(SaveFileName);      end;      Result := True;    except      // Error ?    end;  finally    //Excel Beenden    if (not VarIsEmpty(XLApp)) and (ShowExcel = False) then    begin      XLApp.DisplayAlerts := False;      XLApp.Quit;      XLAPP := Unassigned;      Sheet := Unassigned;    end;  end;end;

//Exampleprocedure TForm1.Button1Click(Sender: TObject);begin  //StringGrid inhalt in Excel exportieren  //Grid : stringGrid, SheetName : stringgrid Print, Pfad : c:\Test\

ExcelFile.xls, Excelsheet anzeigen  StringGridToExcelSheet(StringGrid, 'Stringgrid Print', 'c:\Test\ExcelFile.xls', True);end;

...rotate Text?

procedure TForm1.FormPaint(Sender: TObject);var  lf: TLogFont;  tf: TFont;begin  with Form1.Canvas do  begin    Font.Name := 'Arial';    Font.Size := 24;    tf        := TFont.Create;    try      tf.Assign(Font);      GetObject(tf.Handle, SizeOf(lf), @lf);      lf.lfEscapement  := 320;      lf.lfOrientation := 320;      SetBkMode(Handle, TRANSPARENT);      tf.Handle := CreateFontIndirect(lf);      Font.Assign(tf);    finally      tf.Free;    end;    TextOut(10, Height div 2, 'Your Rotated Text!');  end;end;

The LOGFONT structure holds information about a logical font.The various members of the structure specify properties of the logical font:

lfEscapementThe angle between the font's baseline and escapement vectors,in units of 1/10 degrees.Windows 95, 98: This must be equal to lfOrientation.

lfOrientationThe angle between the font's baseline and the device's x-axis,in units of 1/10 degrees.Windows 95, 98: This must be equal to lfEscapement.

lfWidth

The average width of the font's characters.If 0, the font mapper tries to determine the best value

lfWeightOne of the following flags specifying theboldness (weight) of the font:

FW_DONTCARE = 0 Default weight.FW_THIN = 100 Thin weight.FW_EXTRALIGHT = 200 Extra-light weight.FW_LIGHT = 300 Light weight.FW_NORMAL = 400 Normal weight.FW_MEDIUM = 500 Medium weight.FW_SEMIBOLD = 600 Semi-bold weight.FW_BOLD = 700 bold weight.FW_EXTRABOLD = 800 Extra-bold weight.FW_HEAVY = 900 Heavy weight.

lfItalicA non-zero value if the font is italicized, 0 if not.

lfUnderlineA non-zero value if the font is underlined, 0 if not.

lfStrikeOutA non-zero value if the font is striked out, 0 if not.

...determine if a printer is a Dot-Matrix or Laser (or InkJet) ?

{$APPTYPE CONSOLE}

uses Windows, Printers, WinSpool, Variants;{ Using only API calls, determinate which type is the active printer: Dot-Matrix or Laser (or InkJet)

 This example is distributed "AS IS", WITHOUT WARRANTY OF ANY KIND, either express or implied. You use it at your own risk!}

function IsPrinterMatrix: Boolean;var  DeviceMode: THandle;  Device, Driver, Port: array [0..79] of Char;  pDevice, pDriver, pPort: PChar;begin

  // Determinate that active printer is a Dot-Marix  Result:= False;  pDevice := @Device;  pDriver := @Driver;  pPort   := @Port;

  Device  := #0;  Driver  := #0;  Port    := #0;

  Printer.GetPrinter(pDevice, pDriver, pPort, DeviceMode);

  // Printer can be dot-matrix when number of colors is maximum 16  // and when printer is capable to print only for TRUETYPE  // fonts as graphics (dot-matrix and PCL printers are capable for that).

  if (GetDeviceCaps(Printer.Handle,NUMCOLORS)<=16) and     (DeviceCapabilities(pDevice, pPort,DC_TRUETYPE,nil,nil) = DCTT_BITMAP)  then    Result := True;end;

begin  writeln ('Active printer is ', Printer.Printers[Printer.PrinterIndex]);

  if IsPrinterMatrix then    writeln('This is a Dot-Matrix printer')  else    writeln('This is a LaserJet or InkJet printer');end.

...list all paper names supported by a printer?

uses

  Printers, WinSpool;

procedure GetPapernames(sl: TStrings);type  TPaperName      = array [0..63] of Char;  TPaperNameArray = array [1..High(Word) div SizeOf(TPaperName)] of TPaperName;  PPapernameArray = ^TPaperNameArray;var  Device, Driver, Port: array [0..255] of Char;  hDevMode: THandle;  i, numPaperformats: Integer;  pPaperFormats: PPapernameArray;begin  Printer.PrinterIndex := -1; // Standard printer  Printer.GetPrinter(Device, Driver, Port, hDevmode);  numPaperformats := WinSpool.DeviceCapabilities(Device, Port, DC_PAPERNAMES, nil, nil);  if numPaperformats  0 then   begin    GetMem(pPaperformats, numPaperformats * SizeOf(TPapername));    try      WinSpool.DeviceCapabilities(Device, Port, DC_PAPERNAMES,        PChar(pPaperFormats), nil);      sl.Clear;      for i := 1 to numPaperformats do sl.Add(pPaperformats^[i]);    finally      FreeMem(pPaperformats);    end;  end;end;

procedure TForm1.Button1Click(Sender: TObject);begin  GetPapernames(memo1.Lines);end;

..print a TStringGrid?

uses  Printers;

procedure PrintGrid(sGrid: TStringGrid; sTitle: string);var  X1, X2: Integer;  Y1, Y2: Integer;  TmpI: Integer;  F: Integer;  TR: TRect;begin  Printer.Title := sTitle;  Printer.BeginDoc;  Printer.Canvas.Pen.Color  := 0;  Printer.Canvas.Font.Name  := 'Times New Roman';  Printer.Canvas.Font.Size  := 12;  Printer.Canvas.Font.Style := [fsBold, fsUnderline];  Printer.Canvas.TextOut(0, 100, Printer.Title);  for F := 1 to sGrid.ColCount - 1 do   begin    X1 := 0;    for TmpI := 1 to (F - 1) do      X1 := X1 + 5 * (sGrid.ColWidths[TmpI]);    Y1 := 300;    X2 := 0;    for TmpI := 1 to F do      X2 := X2 + 5 * (sGrid.ColWidths[TmpI]);    Y2 := 450;    TR := Rect(X1, Y1, X2 - 30, Y2);    Printer.Canvas.Font.Style := [fsBold];    Printer.Canvas.Font.Size := 7;    Printer.Canvas.TextRect(TR, X1 + 50, 350, sGrid.Cells[F, 0]);    Printer.Canvas.Font.Style := [];    for TmpI := 1 to sGrid.RowCount - 1 do     begin      Y1 := 150 * TmpI + 300;      Y2 := 150 * (TmpI + 1) + 300;      TR := Rect(X1, Y1, X2 - 30, Y2);      Printer.Canvas.TextRect(TR, X1 + 50, Y1 + 50, sGrid.Cells[F, TmpI]);    end;  end;  Printer.EndDoc;end;

//Examplem, Beispiel:

procedure TForm1.Button1Click(Sender: TObject);begin  PrintGrid(StringGrid1, 'Print Stringgrid');end;

..get the available printers?

uses  printers;

ComboBox1.Items.Assign(Printer.Printers);

...determine if a printer is a Dot-Matrix or Laser (or InkJet) ?

{$APPTYPE CONSOLE}

uses Windows, Printers, WinSpool, Variants;{ Using only API calls, determinate which type is the active printer: Dot-Matrix or Laser (or InkJet)

 This example is distributed "AS IS", WITHOUT WARRANTY OF ANY KIND, either express or implied. You use it at your own risk!}

function IsPrinterMatrix: Boolean;var  DeviceMode: THandle;  Device, Driver, Port: array [0..79] of Char;  pDevice, pDriver, pPort: PChar;begin

  // Determinate that active printer is a Dot-Marix  Result:= False;  pDevice := @Device;  pDriver := @Driver;  pPort   := @Port;

  Device  := #0;  Driver  := #0;  Port    := #0;

  Printer.GetPrinter(pDevice, pDriver, pPort, DeviceMode);

  // Printer can be dot-matrix when number of colors is maximum 16  // and when printer is capable to print only for TRUETYPE  // fonts as graphics (dot-matrix and PCL printers are capable for that).

  if (GetDeviceCaps(Printer.Handle,NUMCOLORS)<=16) and     (DeviceCapabilities(pDevice, pPort,DC_TRUETYPE,nil,nil) = DCTT_BITMAP)  then

    Result := True;end;

begin  writeln ('Active printer is ', Printer.Printers[Printer.PrinterIndex]);

  if IsPrinterMatrix then    writeln('This is a Dot-Matrix printer')  else    writeln('This is a LaserJet or InkJet printer');end.

function IsCellSelected(StringGrid: TStringGrid; X, Y: Longint): Boolean; begin Result := False; try if (X >= StringGrid.Selection.Left) and (X <= StringGrid.Selection.Right) and (Y >= StringGrid.Selection.Top) and (Y <= StringGrid.Selection.Bottom) then Result := True; except end; end;

procedure TForm1.Button1Click(Sender: TObject); begin if IsCellSelected(stringgrid1, 2, 2) then ShowMessage('Cell (2,2) is selected.'); end;

procedure SortStringGrid(var GenStrGrid: TStringGrid; ThatCol: Integer); const TheSeparator = '@'; var CountItem, I, J, K, ThePosition: integer; MyList: TStringList; MyString, TempString: string; begin CountItem := GenStrGrid.RowCount; MyList := TStringList.Create; MyList.Sorted := False; try begin for I := 1 to (CountItem - 1) do

MyList.Add(GenStrGrid.Rows[I].Strings[ThatCol] + TheSeparator + GenStrGrid.Rows[I].Text); Mylist.Sort; for K := 1 to Mylist.Count do begin MyString := MyList.Strings[(K - 1)]; ThePosition := Pos(TheSeparator, MyString); TempString := ''; {Eliminate the Text of the column on which we have sorted the StringGrid} TempString := Copy(MyString, (ThePosition + 1), Length(MyString)); MyList.Strings[(K - 1)] := ''; MyList.Strings[(K - 1)] := TempString; end; for J := 1 to (CountItem - 1) do GenStrGrid.Rows[J].Text := MyList.Strings[(J - 1)]; end; finally MyList.Free; end; end;

procedure TForm1.Button1Click(Sender: TObject); begin SortStringGrid(StringGrid1, 1); end;

procedure GridDeleteRow(RowNumber: Integer; Grid: TstringGrid); var i: Integer; begin Grid.Row := RowNumber; if (Grid.Row = Grid.RowCount - 1) then { On the last row} Grid.RowCount := Grid.RowCount - 1 else begin { Not the last row} for i := RowNumber to Grid.RowCount - 1 do Grid.Rows[i] := Grid.Rows[i + 1]; Grid.RowCount := Grid.RowCount - 1; end; end;

procedure TForm1.Button1Click(Sender: TObject); begin

GridDeleteRow(3, stringGrid1); end;

procedure TForm1.Button1Click(Sender: TObject); var Field: TField; i: Integer; begin Table1.Active:=False; for i:=0 to Table1.FieldDefs.Count-1 do Field:=Table1.FieldDefs[i].CreateField(Table1);

Field:=TStringField.Create(Table1); with Field do begin FieldName:='New Field'; Calculated:=True; DataSet:=Table1; end; Table1.Active:=True; end;

Recommended