home *** CD-ROM | disk | FTP | other *** search
/ Chip 2003 January / Chip_2003-01_cd1.bin / zkuste / delphi / kolekce / d567 / FLEXCEL.ZIP / OLEAdapter / OLEAdapter.pas < prev   
Encoding:
Pascal/Delphi Source File  |  2002-10-10  |  28.1 KB  |  900 lines

  1. unit OLEAdapter;
  2.  
  3. interface
  4.  
  5. uses
  6.   Windows, SysUtils, Classes,UFlxMessages,
  7.   {$IFDEF Excel97} Excel97,{$ELSE} Excel2000,{$ENDIF}
  8.   {$IFDEF ConditionalExpressions}{$if CompilerVersion >= 14} variants,{$IFEND}{$ENDIF} //Delphi 6 or above
  9.   UExcelAdapter, OleServer, UFlxRowComments, UFlxFormats;
  10.  
  11. {$IFDEF ConditionalExpressions}{$if CompilerVersion >= 14}
  12.   {$WARN SYMBOL_PLATFORM OFF}
  13. {$IFEND}{$ENDIF} //Delphi 6 or above
  14.  
  15. type
  16.   //We need 2 sets, It's too big for one
  17.   TExcelSaveFormatBasic= (
  18.     saCSV, saCSVMSDOS, saCSVWindows, saCSVMac,
  19.     saDBF4, saDIF,
  20.     saCurrentPlatformText, saTextMSDOS, saTextWindows, saTextMac,
  21.     saExcel5, saExcel7, saExcel9795,
  22.     saWorkbookNormal, saSYLK, saTemplate
  23.     {$IFNDEF Excel97}
  24.       , saUnicodeText, saHtml
  25.     {$ENDIF}
  26.     );
  27.  
  28.   TExcelSaveFormatExtended= (
  29.     saExcel2, saExcel2FarEast, saExcel3, saExcel4,
  30.     saDBF2, saDBF3,
  31.     saExcel4Workbook, saIntlAddIn, saIntlMacro, saTextPrinter,
  32.     saWJ2WD1, saWK1, saWK1ALL, saWK1FMT, saWK3, saWK4, saWK3FM3, saWKS, saWorks2FarEast,
  33.     saWQ1, saWJ3, saWJ3FJ3);
  34.  
  35.   TSetOfExcelSaveFormatBasic = Set Of TExcelSaveFormatBasic;
  36.   TSetOfExcelSaveFormatExtended = Set Of TExcelSaveFormatExtended;
  37.  
  38. type
  39.   {$IFDEF ConditionalExpressions}{$if CompilerVersion >= 15} Range=ExcelRange;{$IFEND}{$ENDIF} //Delphi 7 or above
  40.  
  41.  
  42.   TOLEAdapter = class(TExcelAdapter)
  43.   private
  44.     FDisplayAlerts: boolean;
  45.     FBlockSize: integer;
  46.     FSaveFormatBasic: TSetOfExcelSaveFormatBasic;
  47.     FSaveFormatExtended: TSetOfExcelSaveFormatExtended;
  48.     { Private declarations }
  49.   protected
  50.     { Protected declarations }
  51.   public
  52.     constructor Create(AOwner:TComponent);override;
  53.     function GetWorkbook: TExcelFile;override;
  54.     { Public declarations }
  55.   published
  56.     property BlockSize: integer read FBlockSize write FBlockSize default 100;
  57.     property DisplayAlerts: boolean read FDisplayAlerts write FDisplayAlerts default true;
  58.     property SaveFormatBasic: TSetOfExcelSaveFormatBasic read FSaveFormatBasic write FSaveFormatBasic default [saExcel9795];
  59.     property SaveFormatExtended: TSetOfExcelSaveFormatExtended read FSaveFormatExtended write FSaveFormatExtended;
  60.     { Published declarations }
  61.   end;
  62.  
  63.   TOLEFile = class(TExcelFile)
  64.   private
  65.     FExcelApplication : TExcelApplication;
  66.     FExcelWorkbook : TExcelWorkbook;
  67.     FExcelWorksheet : TExcelWorksheet;
  68.  
  69.     FAdapter: TOleAdapter;
  70.     FLCID: integer;
  71.  
  72.     RowComments: TRowComments;
  73.  
  74.     FActiveSheet: integer;
  75.  
  76.     FirstColumn, LastColumn: integer;
  77.     WorkRange: Range;
  78.     OldCellData, NewCellData, BlockData: Variant;
  79.     NewDataOffset, OldDataOffset: integer;
  80.  
  81.     procedure ParseComments;
  82.   protected
  83.     function GetCellValue(aRow, aCol: integer): Variant; override;
  84.     procedure SetCellValue(aRow, aCol: integer; const Value: Variant); override;
  85.     function GetCellValueX(aRow, aCol: integer): TXlsCellValue; override;
  86.     procedure SetCellValueX(aRow, aCol: integer; const Value: TXlsCellValue); override;
  87.  
  88.     function GetCommentsCount(Row: integer): integer; override;
  89.     function GetCommentText(Row, aPos: integer): widestring; override;
  90.     function GetPictureName(Row, aPos: integer): widestring;  override;
  91.     function GetPicturesCount(Row: integer): integer;  override;
  92.  
  93.     function GetExcelNameCount: integer;  override;
  94.     function GetRangeName(index: integer): widestring;  override;
  95.     function GetRangeR1(index: integer): integer; override;
  96.     function GetRangeR2(index: integer): integer; override;
  97.     function GetRangeC1(index: integer): integer; override;
  98.     function GetRangeC2(index: integer): integer; override;
  99.     function GetRangeSheet(index: integer): integer; override;
  100.  
  101.     function GetActiveSheet: integer; override;
  102.     procedure SetActiveSheet(const Value: integer); override;
  103.     function GetActiveSheetName: WideString; override;
  104.     procedure SetActiveSheetName(const Value: WideString); override;
  105.  
  106.     function GetColumnWidth(aCol: integer): integer;override;
  107.     function GetRowHeight(aRow: integer): integer;override;
  108.     procedure SetColumnWidth(aCol: integer; const Value: integer);override;
  109.     procedure SetRowHeight(aRow: integer; const Value: integer);override;
  110.  
  111.     function GetDefaultColWidth: integer;override;
  112.     function GetDefaultRowHeight: integer;override;
  113.  
  114.     function GetAutoRowHeight(Row: integer): boolean;override;
  115.     procedure SetAutoRowHeight(Row: integer; const Value: boolean);override;
  116.  
  117.     function GetColumnFormat(aColumn: integer): integer; override;
  118.     function GetRowFormat(aRow: integer): integer;override;
  119.     procedure SetColumnFormat(aColumn: integer; const Value: integer);override;
  120.     procedure SetRowFormat(aRow: integer; const Value: integer);override;
  121.  
  122.     function GetColorPalette(Index: TColorPaletteRange): LongWord; override;
  123.     procedure SetColorPalette(Index: TColorPaletteRange; const Value: LongWord); override;
  124.  
  125.     function GetFormatList(index: integer): TFlxFormat; override;
  126.  
  127.     function GetShowGridLines: boolean; override;
  128.     procedure SetShowGridLines(const Value: boolean); override;
  129.  
  130.     function GetCellMergedBounds(aRow, aCol: integer): TXlsCellRange; override;
  131.  
  132.   public
  133.     property ExcelApplication : TExcelApplication read FExcelApplication;
  134.     property ExcelWorkbook : TExcelWorkbook read FExcelWorkbook;
  135.     property ExcelWorksheet : TExcelWorksheet read FExcelWorksheet;
  136.     property LCID:integer read FLCID;
  137.  
  138.     constructor Create(const aAdapter: TOleAdapter );
  139.     destructor Destroy; override;
  140.  
  141.     procedure Connect;override;
  142.     procedure Disconnect;override;
  143.  
  144.     procedure OpenFile(const FileName: TFileName);override;
  145.     procedure CloseFile; override;
  146.  
  147.     procedure InsertAndCopySheets (const CopyFrom, InsertBefore, SheetCount: integer);override;
  148.     function SheetCount: integer;override;
  149.     procedure SelectSheet(const SheetNo:integer); override;
  150.  
  151.     procedure DeleteMarkedRows(const Mark: widestring);override;
  152.     procedure MakePageBreaks(const Mark: widestring);override;
  153.     procedure RefreshPivotTables;override;
  154.     procedure RefreshChartRanges(const VarStr: string);override;
  155.  
  156.     procedure Save(const AutoClose: boolean; const FileName: string; const OnGetFileName: TOnGetFileNameEvent);override;
  157.  
  158.     procedure InsertAndCopyRows(const FirstRow, LastRow, DestRow, aCount: integer; const OnlyFormulas: boolean);override;
  159.     procedure DeleteRows(const aRow, aCount: integer);override;
  160.  
  161.     procedure BeginSheet;override;
  162.     procedure EndSheet(const RowOffset: integer);override;
  163.  
  164.     function CanOptimizeRead: boolean;override;
  165.  
  166.     procedure AssignPicture(const Row, aPos: integer; const Pic: string; const PicType: TXlsImgTypes); override;
  167.     procedure GetPicture(const Row, aPos: integer; const Pic: TStream; var PicType: TXlsImgTypes; var Anchor: TClientAnchor); override; //use row < 0 to return all
  168.     procedure AssignComment(const Row, aPos: integer; const Comment: widestring); override;
  169.  
  170.     function CellCount(const aRow: integer): integer;override;
  171.     function GetCellData(const aRow, aColOffset: integer): variant;override;
  172.     function GetCellDataX(const aRow, aColOffset: integer): TXlsCellValue;override;
  173.     procedure AssignCellData(const aRow, aColOffset: integer; const Value: variant);override;
  174.     procedure AssignCellDataX(const aRow, aColOffset: integer; const Value: TXlsCellValue);override;
  175.     function MaxRow: integer; override;
  176.     function MaxCol: integer; override;
  177.     function IsEmptyRow(const aRow: integer): boolean; override;
  178.  
  179.     function ColByIndex(const Row, ColIndex: integer): integer;override;
  180.     function ColIndexCount(const Row: integer): integer; override;
  181.     function ColIndex(const Row, Col: integer): integer;override;
  182.  
  183.     function FormatListCount: integer;override;
  184.  
  185.     procedure SetBounds(const aRangePos: integer);override;
  186.     function GetFirstColumn: integer; override;
  187.  
  188.     procedure PrepareBlockData(const R1,C1,R2,C2: integer);override;
  189.     procedure AssignBlockData(const Row,Col: integer; const v: variant);override;
  190.     procedure PasteBlockData;override;
  191.  
  192.     function IsWorksheet(const index: integer): boolean; override;
  193.  
  194.   end;
  195.  
  196. procedure Register;
  197.  
  198. implementation
  199. {$R IOLEAdapter}
  200. const
  201.   SaveFormatBasicConvert: Array[TExcelSaveFormatBasic] of integer= (
  202.     xlCSV, xlCSVMSDOS, xlCSVWindows, xlCSVMac,
  203.     xlDBF4, xlDIF,
  204.     integer(xlCurrentPlatformText), xlTextMSDOS, xlTextWindows, xlTextMac,
  205.     xlExcel5, xlExcel7, xlExcel9795,
  206.     integer(xlWorkbookNormal), xlSYLK, xlTemplate
  207.     {$IFNDEF Excel97}
  208.       , xlUnicodeText, xlHtml
  209.     {$ENDIF}
  210.     );
  211.  
  212.   SaveFormatExtendedConvert: Array[TExcelSaveFormatExtended] of integer= (
  213.     xlExcel2, xlExcel2FarEast, xlExcel3, xlExcel4,
  214.     xlDBF2, xlDBF3,
  215.     xlExcel4Workbook, xlIntlAddIn, xlIntlMacro, xlTextPrinter,
  216.     xlWJ2WD1, xlWK1, xlWK1ALL, xlWK1FMT, xlWK3, xlWK4, xlWK3FM3, xlWKS, xlWorks2FarEast,
  217.     xlWQ1, xlWJ3, xlWJ3FJ3);
  218.  
  219. procedure Register;
  220. begin
  221.   RegisterComponents('FlexCel', [TOLEAdapter]);
  222. end;
  223.  
  224. { TOLEAdapter }
  225.  
  226. constructor TOLEAdapter.Create(AOwner: TComponent);
  227. begin
  228.   inherited;
  229.   FDisplayAlerts:=true;
  230.   FSaveFormatBasic:=[saExcel9795];
  231.   FSaveFormatExtended:=[];
  232.   FBlockSize:=100;
  233. end;
  234.  
  235. function TOLEAdapter.GetWorkbook: TExcelFile;
  236. begin
  237.   Result:= TOLEFile.Create(Self);
  238. end;
  239.  
  240. { TOLEFile }
  241.  
  242. constructor TOLEFile.Create(const aAdapter: TOleAdapter);
  243. begin
  244.   inherited Create;
  245.   FExcelApplication := TExcelApplication.Create(nil);
  246.   FExcelWorkbook := TExcelWorkbook.Create(nil);
  247.   FExcelWorksheet := TExcelWorksheet.Create(nil);
  248.  
  249.   FAdapter:= aAdapter;
  250.  
  251.   FLCID :=   LOCALE_USER_DEFAULT;
  252. end;
  253.  
  254. destructor TOLEFile.Destroy;
  255. begin
  256.   FreeAndNil(RowComments);
  257.   FreeAndNil(FExcelApplication);
  258.   FreeAndNil(FExcelWorkbook);
  259.   FreeAndNil(FExcelWorksheet);
  260.   inherited;
  261. end;
  262.  
  263. procedure TOLEFile.Connect;
  264. begin
  265.   // Try to connect to Excel and create new Worksheet
  266.   FExcelApplication.ConnectKind := ckRunningOrNew;
  267.   FExcelApplication.Connect;
  268.  
  269.   FExcelApplication.DisplayAlerts[FLCID] := FAdapter.DisplayAlerts;
  270.   FExcelApplication.Visible[FLCID]:=false;
  271.   FExcelApplication.ScreenUpdating[FLCID] := false;
  272.  
  273. end;
  274.  
  275. procedure TOLEFile.Disconnect;
  276. begin
  277.   FExcelApplication.ScreenUpdating[FLCID] := true;
  278.   FExcelApplication.Visible[FLCID]:=true;
  279.  
  280.   FExcelWorksheet.Disconnect;
  281.   FExcelWorkbook.Disconnect;
  282.   FExcelApplication.Disconnect;
  283. end;
  284.  
  285. procedure TOLEFile.CloseFile;
  286. begin
  287.   FExcelWorkbook.Close(False);
  288. end;
  289.  
  290. procedure TOLEFile.OpenFile(const FileName: TFileName);
  291. begin
  292.   FExcelWorkbook.ConnectTo(FExcelApplication.Workbooks.Add(SearchPathStr(FileName), FLCID));
  293. end;
  294.  
  295. procedure TOLEFile.InsertAndCopySheets(const CopyFrom, InsertBefore,
  296.   SheetCount: integer);
  297. var
  298.   Ws: _Worksheet;
  299.   WsDest: OleVariant;
  300.   i: integer;
  301. begin
  302.   Ws:=(FExcelWorkbook.Sheets[CopyFrom] as _Worksheet);
  303.   if InsertBefore< FExcelWorkbook.Sheets.Count then
  304.   begin
  305.     WsDest:=(FExcelWorkbook.Sheets[InsertBefore]);
  306.     for i:=0 to SheetCount-1 do Ws.Copy(WsDest, EmptyParam,FLCID);
  307.   end else
  308.   begin
  309.     WsDest:=(FExcelWorkbook.Sheets[InsertBefore-1]);
  310.     for i:=0 to SheetCount-1 do Ws.Copy(EmptyParam,WsDest,FLCID);
  311.   end;
  312. end;
  313.  
  314. function TOLEFile.SheetCount: integer;
  315. begin
  316.   Result:=FExcelWorkbook.Sheets.Count;
  317. end;
  318.  
  319. procedure TOLEFile.DeleteMarkedRows(const Mark: widestring);
  320. var
  321.   r: OleVariant;
  322.   Empty: boolean;
  323. begin
  324.   repeat
  325.     r := FExcelWorksheet.UsedRange[FLCID].Resize[EmptyParam,1];
  326.    // We dont use early binding in 'Find' method because incompatibilities between d5 & d6 & excel97 & excel2000...
  327.     r :=r.Find(Mark, EmptyParam, integer(xlValues), xlWhole, EmptyParam, xlNext, true, EmptyParam);
  328.     // This is VarIsEmpty... If it just worked in D6...
  329.     Empty:= ((TVarData(r).VType = varDispatch) or (TVarData(r).VType = varUnknown)) and (TVarData(r).VDispatch = nil);
  330.     if not Empty then r.EntireRow.Delete(Integer(xlShiftUp));
  331.   until Empty;
  332. end;
  333.  
  334. procedure TOLEFile.MakePageBreaks(const Mark: widestring);
  335. var
  336.   r: OleVariant;
  337.   Empty: boolean;
  338. begin
  339.   repeat
  340.     r := FExcelWorksheet.UsedRange[FLCID].Resize[EmptyParam,1];
  341.    // We dont use early binding in 'Find' method because incompatibilities between d5 & d6 & excel97 & excel2000...
  342.     r :=r.Find(Mark, EmptyParam, integer(xlValues), xlWhole, EmptyParam, xlNext, true, EmptyParam);
  343.     // This is VarIsEmpty... If it just worked in D6...
  344.     Empty:= ((TVarData(r).VType = varDispatch) or (TVarData(r).VType = varUnknown)) and (TVarData(r).VDispatch = nil);
  345.     if not Empty then
  346.     begin
  347.       try
  348.         r.EntireRow.Clear;
  349.         FExcelWorksheet.HPageBreaks.Add( r.EntireRow );
  350.       except
  351.         //nothing
  352.       end; //Except
  353.     end;
  354.   until Empty;
  355. end;
  356.  
  357. procedure TOLEFile.RefreshPivotTables;
  358. var
  359.   k, l, m: integer;
  360.   Pvts, Pvt, PvtField, PvtItem: OleVariant;
  361. begin
  362.   Pvts:=FExcelWorksheet.PivotTables;
  363.   for k:=1 to Pvts.Count do
  364.   begin
  365.     Pvt:= FExcelWorksheet.PivotTables(k, FLCID);
  366.     FExcelApplication.DisplayAlerts[FLCID]:=False; //Here there is a warning we dont want...
  367.     try
  368.       Pvt.PivotCache.Refresh;
  369.     except
  370.       //Nothing, probably there are no rows
  371.     end; //Except
  372.     FExcelApplication.DisplayAlerts[FLCID]:=FAdapter.DisplayAlerts;
  373.  
  374.     for l:=1 to Pvt.PivotFields.Count do
  375.       begin
  376.         PvtField:= Pvt.PivotFields(l);
  377.         for m:=PvtField.PivotItems.Count downto 1 do
  378.         begin
  379.           try
  380.             PvtItem:=PvtField.PivotItems(m);
  381.             if (PvtItem.RecordCount = 0) and not (PvtItem.IsCalculated) then PvtItem.Delete;
  382.           except
  383.             //Nothing
  384.           end; //except
  385.         end;
  386.       end;
  387.   end;
  388. end;
  389.  
  390. function TOLEFile.GetActiveSheetName: WideString;
  391. begin
  392.   Result:= FExcelWorksheet.Name;
  393. end;
  394.  
  395. procedure TOLEFile.SetActiveSheetName(const Value: WideString);
  396. begin
  397.   FExcelWorksheet.Name:= Value;
  398. end;
  399.  
  400. function TOLEFile.GetActiveSheet: integer;
  401. begin
  402.   if FActiveSheet=0 then FActiveSheet:=(FExcelWorkbook.ActiveSheet as _WorkSheet).Index[FLCID]; //First time
  403.   Result:=FActiveSheet;
  404. end;
  405.  
  406. procedure TOLEFile.SetActiveSheet(const Value: integer);
  407. begin
  408.   if IsWorksheet(Value) then
  409.   begin
  410.     FExcelWorksheet.ConnectTo(FExcelWorkbook.Sheets[Value] as _Worksheet);
  411.     FActiveSheet:=Value;
  412.   end;
  413. end;
  414.  
  415. procedure TOLEFile.SelectSheet(const SheetNo:integer);
  416. var
  417.   v: variant;
  418. begin
  419.   v:=(FExcelWorkbook.Sheets.Item [SheetNo]);
  420.   v.Activate;
  421.   ActiveSheet:= SheetNo;
  422. end;
  423.  
  424. procedure TOLEFile.Save(const AutoClose: boolean; const FileName: string; const OnGetFileName: TOnGetFileNameEvent);
  425. var
  426.   SaveFB: TExcelSaveFormatBasic;
  427.   SaveFE: TExcelSaveFormatExtended;
  428.   aFileName: TFileName;
  429. begin
  430.   if (AutoClose) then
  431.   begin
  432.     for SaveFB:= Low(TExcelSaveFormatBasic) to High(TExcelSaveFormatBasic) do
  433.       if SaveFB in FAdapter.SaveFormatBasic then
  434.       begin
  435.         aFileName:=Filename;
  436.         if Assigned (OnGetFileName) then OnGetFileName(Self,SaveFormatBasicConvert[SaveFB],aFilename);
  437.         FExcelWorkbook.SaveAs(aFileName,SaveFormatBasicConvert[SaveFB],EmptyParam,EmptyParam,EmptyParam,EmptyParam,xlExclusive,EmptyParam,EmptyParam,EmptyParam,EmptyParam,FLCID);
  438.       end;
  439.     for SaveFE:= Low(TExcelSaveFormatExtended) to High(TExcelSaveFormatExtended) do
  440.       if SaveFE in FAdapter.SaveFormatExtended then
  441.       begin
  442.         aFileName:=Filename;
  443.         if Assigned (OnGetFileName) then OnGetFileName(Self,SaveFormatExtendedConvert[SaveFE],aFilename);
  444.         FExcelWorkbook.SaveAs(aFileName, SaveFormatExtendedConvert[SaveFE], EmptyParam, EmptyParam, EmptyParam, EmptyParam, xlExclusive, EmptyParam, EmptyParam, EmptyParam, EmptyParam, FLCID);
  445.       end;
  446.   end
  447.  
  448. end;
  449.  
  450. procedure TOLEFile.DeleteRows(const aRow, aCount: integer);
  451. var
  452.   NewRange: Range;
  453. begin
  454.   NewRange:=FExcelWorksheet.Range['A'+IntToStr(aRow), 'A'+IntToStr(aRow+aCount-1)].EntireRow;
  455.   NewRange.Delete(Integer(xlShiftUp));
  456. end;
  457.  
  458. procedure TOLEFile.InsertAndCopyRows(const FirstRow, LastRow, DestRow, aCount: integer; const OnlyFormulas: boolean);
  459. var
  460.   OldRange, NewRange: Range;
  461. begin
  462.   NewRange:=FExcelWorksheet.Range['A'+IntToStr(DestRow), 'A'+IntToStr(DestRow+aCount*(LastRow-FirstRow+1)-1)].EntireRow;
  463.   NewRange.Insert( integer(xlDown));
  464.   NewRange := NewRange.Offset[-(aCount*(LastRow-FirstRow+1)),0];
  465.   OldRange := FExcelWorksheet.Range['A'+IntToStr(FirstRow), 'A'+IntToStr(LastRow)].EntireRow; //We need the entire row to copy row height!
  466.   OldRange.Copy (NewRange);
  467.  
  468. end;
  469.  
  470. procedure TOLEFile.AssignComment(const Row, aPos: integer;
  471.   const Comment: Widestring);
  472. begin
  473.   if Comment='' then
  474.   begin
  475.     FExcelWorksheet.Comments[RowComments[Row][aPos]].Delete;
  476.     RowComments.Delete(Row,aPos);
  477.   end else
  478.   FExcelWorksheet.Comments[RowComments[Row][aPos]].Text(Comment, EmptyParam, EmptyParam);
  479. end;
  480.  
  481. procedure TOLEFile.AssignPicture(const Row, aPos: integer;
  482.   const Pic: string; const PicType: TXlsImgTypes);
  483. begin
  484.   //Not implemented
  485. end;
  486.  
  487. procedure TOLEFile.ParseComments;
  488. var
  489.   i:integer;
  490. begin
  491.   FreeAndNil(RowComments);
  492.   RowComments:= TRowComments.Create;
  493.   for i:=1 to FExcelWorksheet.Comments.Count do
  494.     RowComments.Add(FExcelWorksheet.Comments[i].Shape.TopLeftCell.Row, i);
  495. end;
  496.  
  497. procedure TOLEFile.BeginSheet;
  498. begin
  499.   //Parse comments into corresponding rows
  500.   ParseComments;
  501.  
  502.   //Prepare Matrix to handle Data Transfer
  503.   NewCellData:=VarArrayCreate([1,FAdapter.BlockSize,FirstColumn,LastColumn],varVariant);
  504.   WorkRange:=FExcelWorksheet.Range[
  505.     FExcelWorksheet.Cells.Item[1, FirstColumn],
  506.     FExcelWorksheet.Cells.Item[1+FAdapter.BlockSize-1, LastColumn]
  507.     ];
  508.   OldCellData:=Unassigned;
  509.   OldDataOffset:=-1;
  510.  
  511. end;
  512.  
  513. procedure TOLEFile.EndSheet(const RowOffset: integer);
  514. var
  515.   Size:integer;
  516. begin
  517.   try
  518.     //Flush final data
  519.     Size:=RowOffset-1-NewDataOffset;
  520.     if Size<0 then exit;
  521.     WorkRange:=FExcelWorksheet.Range[
  522.       FExcelWorksheet.Cells.Item[1, FirstColumn],
  523.       FExcelWorksheet.Cells.Item[1+Size, LastColumn]
  524.       ];
  525.     WorkRange.Offset[NewDataOffset,0].FormulaLocal:=NewCellData;
  526.   finally
  527.     WorkRange:=nil; //This is needed so we don't keep any reference to Excel.
  528.   end; //finally
  529. end;
  530.  
  531. function TOLEFile.GetCommentsCount(Row: integer): integer;
  532. begin
  533.   Result:=RowComments[Row].Count;
  534. end;
  535.  
  536. function TOLEFile.GetCommentText(Row, aPos: integer): Widestring;
  537. begin
  538.   Result:=FExcelWorksheet.Comments[RowComments[Row][aPos]].Text(EmptyParam, EmptyParam, EmptyParam);
  539. end;
  540.  
  541. function TOLEFile.GetExcelNameCount: integer;
  542. begin
  543.   Result:=FExcelWorkbook.Names.Count;
  544. end;
  545.  
  546. function TOLEFile.GetPictureName(Row, aPos: integer): Widestring;
  547. begin
  548.    Result:=''; //Not implemented
  549. end;
  550.  
  551. function TOLEFile.GetPicturesCount(Row: integer): integer;
  552. begin
  553.   Result:=0; //Not implemented
  554. end;
  555.  
  556. function TOLEFile.GetRangeName(index: integer): Widestring;
  557. begin
  558.   Result:=FExcelWorkbook.Names.Item(index, EmptyParam, EmptyParam).Name_;
  559. end;
  560.  
  561. function TOLEFile.GetRangeR1(index: integer): integer;
  562. begin
  563.   Result:=FExcelWorkbook.Names.Item(index, EmptyParam, EmptyParam).RefersToRange.Row;
  564. end;
  565.  
  566. function TOLEFile.GetRangeR2(index: integer): integer;
  567. begin
  568.   Result:=GetRangeR1(Index)+FExcelWorkbook.Names.Item(index, EmptyParam, EmptyParam).RefersToRange.Rows.Count-1;
  569. end;
  570.  
  571. function TOLEFile.GetRangeC1(index: integer): integer;
  572. begin
  573.   Result:=FExcelWorkbook.Names.Item(index, EmptyParam, EmptyParam).RefersToRange.Column;
  574. end;
  575.  
  576. function TOLEFile.GetRangeC2(index: integer): integer;
  577. begin
  578.   Result:=GetRangeC1(Index)+FExcelWorkbook.Names.Item(index, EmptyParam, EmptyParam).RefersToRange.Columns.Count-1;
  579. end;
  580.  
  581. function TOLEFile.GetRangeSheet(index: integer): integer;
  582. var
  583.   w:OleVariant; //Cant get to use _Worksheet
  584. begin
  585.   try
  586.     w:=FExcelWorkbook.Names.Item(index, EmptyParam, EmptyParam).RefersToRange.Worksheet;
  587.     result:=w.Index;
  588.   except //Err in range
  589.     result:=-1;
  590.   end; //Except
  591. end;
  592.  
  593. procedure TOLEFile.AssignCellData(const aRow, aColOffset: integer; const Value: variant);
  594. var
  595.   i,j:integer;
  596. begin
  597.   if aRow-NewDataOffset > FAdapter.BlockSize then
  598.   begin
  599.     //Flush Data
  600.     WorkRange.Offset[NewDataOffset,0].FormulaLocal:=NewCellData;
  601.     NewDataOffset:=aRow-1;
  602.     for i:=VarArrayLowBound(NewCellData,1) to VarArrayHighBound(NewCellData,1) do
  603.       for j:=VarArrayLowBound(NewCellData,2) to VarArrayHighBound(NewCellData,2) do
  604.         NewCellData[i,j]:=unassigned;
  605.   end;
  606.   NewCellData[aRow-NewDataOffset,aColOffset+FirstColumn]:=Value;
  607. end;
  608.  
  609. procedure TOLEFile.AssignCellDataX(const aRow, aColOffset: integer; const Value: TXlsCellValue);
  610. begin
  611.   AssignCellData(aRow, aColOffset, Value.Value);
  612. end;
  613.  
  614. function TOLEFile.CellCount(const aRow: integer): integer;
  615. begin
  616.   Result:= LastColumn-FirstColumn+1;
  617. end;
  618.  
  619. function TOLEFile.GetCellData(const aRow, aColOffset: integer): variant;
  620. begin
  621.   if (OldDataOffset<0)or (aRow-OldDataOffset>FAdapter.BlockSize) then
  622.   begin
  623.     OldDataOffset:=aRow-1;
  624.     OldCellData:= WorkRange.Offset[OldDataOffset,0].FormulaLocal;
  625.   end;
  626.   GetCellData:=OldCellData[aRow-OldDataOffset,aColOffset+1];
  627. end;
  628.  
  629. function TOLEFile.GetCellDataX(const aRow, aColOffset: integer): TXlsCellValue;
  630. begin
  631.   Result.Value:=GetCellData(aRow,aColOffset);
  632.   Result.Xf:=-1; //Not implemented
  633.   Result.IsFormula:=false; //not implemented
  634. end;
  635.  
  636. procedure TOLEFile.SetBounds(const aRangePos: integer);
  637. var
  638.   CellRange: Range;
  639. begin
  640.   CellRange:=FExcelWorkbook.Names.Item(aRangePos, EmptyParam, EmptyParam).RefersToRange;
  641.   FirstColumn:=CellRange.Column;
  642.   LastColumn:=CellRange.Column+CellRange.Columns.Count-1;
  643.   NewDataOffset:=CellRange.Row-1;
  644. end;
  645.  
  646. procedure TOLEFile.AssignBlockData(const Row, Col: integer; const v: variant);
  647. begin
  648.   BlockData[Row,FirstColumn+Col]:=v;
  649. end;
  650.  
  651. procedure TOLEFile.PasteBlockData;
  652. var
  653.   R1, R2, C1, C2: integer;
  654. begin
  655.   R1:=VarArrayLowBound(BlockData,1);
  656.   R2:=VarArrayHighBound(BlockData,1);
  657.   C1:=VarArrayLowBound(BlockData,2);
  658.   C2:=VarArrayHighBound(BlockData,2);
  659.   FExcelWorksheet.Range[
  660.       FExcelWorksheet.Cells.Item[R1, C1],
  661.       FExcelWorksheet.Cells.Item[R2, C2]
  662.       ].FormulaLocal:=BlockData;
  663.   BlockData:=unassigned;
  664. end;
  665.  
  666. procedure TOLEFile.PrepareBlockData(const R1, C1, R2, C2: integer);
  667. begin
  668.   BlockData:= VarArrayCreate([R1,R2,FirstColumn+C1,FirstColumn+C2],varVariant);
  669. end;
  670.  
  671. function TOLEFile.MaxRow: integer;
  672. begin
  673.   Result:= FExcelWorksheet.UsedRange[FLCID].Row-1 + FExcelWorksheet.UsedRange[FLCID].Rows.Count;
  674. end;
  675.  
  676. function TOLEFile.MaxCol: integer;
  677. begin
  678.   Result:= FExcelWorksheet.UsedRange[FLCID].Column-1 + FExcelWorksheet.UsedRange[FLCID].Columns.Count;
  679. end;
  680.  
  681. function TOLEFile.GetCellValue(aRow, aCol: integer): Variant;
  682. begin
  683.   Result:=FExcelWorksheet.Cells.Item[aRow, aCol].Value;
  684. end;
  685.  
  686. procedure TOLEFile.SetCellValue(aRow, aCol: integer; const Value: Variant);
  687. begin
  688.   FExcelWorksheet.Cells.Item[aRow, aCol]:= Value;
  689. end;
  690.  
  691. function TOLEFile.IsEmptyRow(const aRow: integer): boolean;
  692. begin
  693.   Result:=(aRow<1) or (aRow>MaxRow);
  694. end;
  695.  
  696. function TOLEFile.CanOptimizeRead: boolean;
  697. begin
  698.   Result:=false;
  699. end;
  700.  
  701.  
  702. procedure TOLEFile.RefreshChartRanges(const VarStr: string);
  703. var
  704.   i, k: integer;
  705.   s: widestring;
  706.   R: Range;
  707.   Charts: ChartObjects;
  708.   xlDir: integer;
  709.   SaveXVal: OleVariant;
  710.   st:string;
  711.   Local: boolean;
  712. begin
  713.   Charts:=ChartObjects(FExcelWorksheet.ChartObjects);
  714.   for i:=1 to Charts.Count do
  715.   begin
  716.     s:=ChartObject(Charts.Item(i)).Name;
  717.     if copy(s,1, length(VarStr)) = VarStr then
  718.     begin
  719.       s:=copy(s,Length(VarStr)+1, length(s));
  720.       st:=copy(s,pos(VarStr,s+VarStr)+Length(VarStr),Length(s));
  721.       s:=copy(s,1,pos(VarStr,s+VarStr)-1);
  722.  
  723.       Local:=true;
  724.       //First try to find it in local range.
  725.       try
  726.         R:=FExcelWorksheet.Names.Item(s, EmptyParam, EmptyParam).RefersToRange;
  727.       except
  728.         Local:=false;
  729.       end;
  730.  
  731.       if not Local then R:=FExcelWorkbook.Names.Item(s,EmptyParam, EmptyParam).RefersToRange;
  732.       if UpperCase(st)='C' then xlDir:=xlColumns else xlDir:=xlRows;
  733.       ChartObject(Charts.Item(i)).Activate;
  734.       SaveXVal:=unassigned;
  735.       if (FExcelWorkbook.ActiveChart.SeriesCollection(EmptyParam, LCID) as SeriesCollection).Count>0 then
  736.         SaveXVal:=(FExcelWorkbook.ActiveChart.SeriesCollection(1, LCID) as Series).XValues;
  737.       FExcelWorkbook.ActiveChart.SetSourceData(R, xlDir);
  738.       if not varIsEmpty(SaveXVal) then
  739.         for k:= 1 to (FExcelWorkbook.ActiveChart.SeriesCollection(EmptyParam, LCID) as SeriesCollection).Count do
  740.         try
  741.           (FExcelWorkbook.ActiveChart.SeriesCollection(k, LCID) as Series).XValues:= SaveXVal;
  742.         except
  743.           //nothing
  744.         end; //except
  745.     end;
  746.   end;
  747. end;
  748.  
  749. function TOLEFile.IsWorksheet(const index: integer): boolean;
  750. var
  751.   Dummy: _Worksheet;
  752. begin
  753.   Result:=Supports(FExcelWorkbook.Sheets[index],_Worksheet, dummy);
  754. end;
  755.  
  756. function TOLEFile.GetColumnWidth(aCol: integer): integer;
  757. begin
  758.   Result:=FExcelWorksheet.Cells.Item[1, aCol].ColumnWidth*256;
  759. end;
  760.  
  761. function TOLEFile.GetRowHeight(aRow: integer): integer;
  762. begin
  763.   Result:=FExcelWorksheet.Cells.Item[aRow, 1].RowHeight*20;
  764. end;
  765.  
  766. procedure TOLEFile.SetColumnWidth(aCol: integer; const Value: integer);
  767. begin
  768.   FExcelWorksheet.Cells.Item[EmptyParam, aCol].ColumnWidth:=Value/256;
  769. end;
  770.  
  771. procedure TOLEFile.SetRowHeight(aRow: integer; const Value: integer);
  772. begin
  773.   FExcelWorksheet.Rows.Item[aRow, EmptyParam].RowHeight:=Value/20;
  774. end;
  775.  
  776. function TOLEFile.GetFirstColumn: integer;
  777. begin
  778.   Result:=FirstColumn;
  779. end;
  780.  
  781. function TOLEFile.GetCellValueX(aRow, aCol: integer): TXlsCellValue;
  782. begin
  783.   Result.Value:=GetCellValue(aRow,aCol);
  784.   Result.Xf:=-1; //Not implemented
  785.   Result.IsFormula:=false; //not implemented
  786. end;
  787.  
  788. procedure TOLEFile.SetCellValueX(aRow, aCol: integer;
  789.   const Value: TXlsCellValue);
  790. begin
  791.   SetCellValue(aRow, aCol, Value.Value);
  792. end;
  793.  
  794. function TOLEFile.GetAutoRowHeight(Row: integer): boolean;
  795. begin
  796.   Result:=true; //not implemented
  797. end;
  798.  
  799. procedure TOLEFile.SetAutoRowHeight(Row: integer; const Value: boolean);
  800. begin
  801.   FExcelWorksheet.Rows.Item[Row, EmptyParam].AutoFit;
  802.  
  803. end;
  804.  
  805. function TOLEFile.GetColorPalette(Index: TColorPaletteRange): LongWord;
  806. begin
  807.   Result:=FExcelWorkbook.Colors[Index,LCID];
  808. end;
  809.  
  810. procedure TOLEFile.SetColorPalette(Index: TColorPaletteRange;
  811.   const Value: LongWord);
  812. begin
  813.   FExcelWorkbook.Colors[Index,LCID]:=LongInt(Value);
  814. end;
  815.  
  816. function TOLEFile.GetColumnFormat(aColumn: integer): integer;
  817. begin
  818.   Result:=0; //not implemented
  819. end;
  820.  
  821. function TOLEFile.GetRowFormat(aRow: integer): integer;
  822. begin
  823.   Result:=0; //Not implemented
  824. end;
  825.  
  826. procedure TOLEFile.SetColumnFormat(aColumn: integer; const Value: integer);
  827. begin
  828.   //Not implemented
  829. end;
  830.  
  831. procedure TOLEFile.SetRowFormat(aRow: integer; const Value: integer);
  832. begin
  833.   //Not Implemented
  834. end;
  835.  
  836. function TOLEFile.FormatListCount: integer;
  837. begin
  838.   Result:=1; //Not Implemented
  839. end;
  840.  
  841. function TOLEFile.GetFormatList(index: integer): TFlxFormat;
  842. begin
  843.   //Not implemented
  844. end;
  845.  
  846. function TOLEFile.GetShowGridLines: boolean;
  847. begin
  848.   Result:=true;
  849.   //Not implemented
  850. end;
  851.  
  852. procedure TOLEFile.SetShowGridLines(const Value: boolean);
  853. begin
  854.  //Not implemented
  855. end;
  856.  
  857. function TOLEFile.GetDefaultColWidth: integer;
  858. begin
  859.   Result:=Round(FExcelWorksheet.StandardWidth[LCID]);
  860. end;
  861.  
  862. function TOLEFile.GetDefaultRowHeight: integer;
  863. begin
  864.   Result:=Round(FExcelWorksheet.StandardHeight[LCID]);
  865. end;
  866.  
  867. function TOLEFile.ColByIndex(const Row, ColIndex: integer): integer;
  868. begin
  869.   Result:=0; //Not implemented
  870. end;
  871.  
  872. function TOLEFile.ColIndex(const Row, Col: integer): integer;
  873. begin
  874.   Result:=0; //Not implemented
  875. end;
  876.  
  877. function TOLEFile.ColIndexCount(const Row: integer): integer;
  878. begin
  879.   Result:=0; //Not implemented
  880. end;
  881.  
  882. procedure TOLEFile.GetPicture(const Row, aPos: integer; const Pic: TStream;
  883.   var PicType: TXlsImgTypes; var Anchor: TClientAnchor);
  884. begin
  885.   //Not implemented
  886. end;
  887.  
  888. function TOLEFile.GetCellMergedBounds(aRow, aCol: integer): TXlsCellRange;
  889. var
  890.   R: Range;
  891. begin
  892.   R:=FExcelWorksheet.Range[FExcelWorksheet.Cells.Item[aRow, aCol],FExcelWorksheet.Cells.Item[aRow, aCol]].MergeArea;
  893.   Result.Left:= R.Column;
  894.   Result.Top:= R.Row;
  895.   Result.Right:= Result.Left + R.Columns.Count-1;
  896.   Result.Bottom:= Result.Top + R.Rows.Count;
  897. end;
  898.  
  899. end.
  900.