0% found this document useful (2 votes)
2K views16 pages

Import An Excel Table To A TStringgrid

1. The document discusses several ways to export data from a TStringGrid to Excel or Word: importing an Excel table to a string grid, exporting a string grid to a Word table, and exporting a string grid to an Excel file using OLE automation or without OLE. 2. It also provides a code sample to rotate text in a form's paint event by modifying the font's lfEscapement and lfOrientation values using the LOGFONT structure. 3. Additional details are given on using OLE variants and automation to interface with Excel and Word, accessing cell values, and looping through rows and columns to transfer data.

Uploaded by

Bogdan Vicol
Copyright
© Attribution Non-Commercial (BY-NC)
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (2 votes)
2K views16 pages

Import An Excel Table To A TStringgrid

1. The document discusses several ways to export data from a TStringGrid to Excel or Word: importing an Excel table to a string grid, exporting a string grid to a Word table, and exporting a string grid to an Excel file using OLE automation or without OLE. 2. It also provides a code sample to rotate text in a form's paint event by modifying the font's lfEscapement and lfOrientation values using the LOGFONT structure. 3. Additional details are given on using OLE variants and automation to interface with Excel and Word, accessing cell values, and looping through rows and columns to transfer data.

Uploaded by

Bogdan Vicol
Copyright
© Attribution Non-Commercial (BY-NC)
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 16

..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 row s // 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 einfgen NewDoc := WordApp.Documents.Add; // Get number of columns, rows // Spalten, Reihen ermitteln iCols := StringGrid1.ColCount; iRows := StringGrid1.RowCount; // Add a Table // Tabelle einfgen

WordTable := NewDoc.Tables.Add(WordApp.Selection.Range, iCols, iRows); // Fill up the word table with the Stringgrid contents // Tabelle ausfllen 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 fr StringGridToExcelSheet // Helper function for StringGridToExcelSheet function 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 Excel function StringGridToExcelSheet(Grid: TStringGrid; SheetName, FileName: strin g; 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 hinzufgen 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 befllen

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], varVaria nt); 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; //Example procedure 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.x ls', 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: lfEscapement The angle between the font's baseline and escapement vectors, in units of 1/10 degrees. Windows 95, 98: This must be equal to lfOrientation. lfOrientation The 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 lfWeight One of the following flags specifying the boldness (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.

lfItalic A non-zero value if the font is italicized, 0 if not. lfUnderline A non-zero value if the font is underlined, 0 if not. lfStrikeOut A 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 TPaperNam e; 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;

You might also like