Upload
bogdan-vicol
View
371
Download
0
Embed Size (px)
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;