home *** CD-ROM | disk | FTP | other *** search
/ Chip 2002 October / Chip_2002-10_cd1.bin / zkuste / delphi / kolekce / d56 / FLEXCEL.ZIP / OLEAdapter / OLEAdapter.pas < prev   
Pascal/Delphi Source File  |  2002-07-02  |  20KB  |  620 lines

  1. unit OLEAdapter;
  2.  
  3. interface
  4.  
  5. uses
  6.   Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, 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;
  10.  
  11. type
  12.   //We need 2 sets, It's too big for one
  13.   TExcelSaveFormatBasic= (
  14.     saCSV, saCSVMSDOS, saCSVWindows, saCSVMac,
  15.     saDBF4, saDIF,
  16.     saCurrentPlatformText, saTextMSDOS, saTextWindows, saTextMac,
  17.     saExcel5, saExcel7, saExcel9795,
  18.     saWorkbookNormal, saSYLK, saTemplate
  19.     {$IFNDEF Excel97}
  20.       , saUnicodeText, saHtml
  21.     {$ENDIF}
  22.     );
  23.  
  24.   TExcelSaveFormatExtended= (
  25.     saExcel2, saExcel2FarEast, saExcel3, saExcel4,
  26.     saDBF2, saDBF3,
  27.     saExcel4Workbook, saIntlAddIn, saIntlMacro, saTextPrinter,
  28.     saWJ2WD1, saWK1, saWK1ALL, saWK1FMT, saWK3, saWK4, saWK3FM3, saWKS, saWorks2FarEast,
  29.     saWQ1, saWJ3, saWJ3FJ3);
  30.  
  31.   TSetOfExcelSaveFormatBasic = Set Of TExcelSaveFormatBasic;
  32.   TSetOfExcelSaveFormatExtended = Set Of TExcelSaveFormatExtended;
  33.  
  34. type
  35.   TOLEAdapter = class(TExcelAdapter)
  36.   private
  37.     FDisplayAlerts: boolean;
  38.     FBlockSize: integer;
  39.     FSaveFormatBasic: TSetOfExcelSaveFormatBasic;
  40.     FSaveFormatExtended: TSetOfExcelSaveFormatExtended;
  41.     { Private declarations }
  42.   protected
  43.     { Protected declarations }
  44.   public
  45.     constructor Create(AOwner:TComponent);override;
  46.     function GetWorkbook: TExcelFile;override;
  47.     { Public declarations }
  48.   published
  49.     property BlockSize: integer read FBlockSize write FBlockSize default 100;
  50.     property DisplayAlerts: boolean read FDisplayAlerts write FDisplayAlerts default true;
  51.     property SaveFormatBasic: TSetOfExcelSaveFormatBasic read FSaveFormatBasic write FSaveFormatBasic default [saExcel9795];
  52.     property SaveFormatExtended: TSetOfExcelSaveFormatExtended read FSaveFormatExtended write FSaveFormatExtended;
  53.     { Published declarations }
  54.   end;
  55.  
  56.   TOLEFile = class(TExcelFile)
  57.   private
  58.     FExcelApplication : TExcelApplication;
  59.     FExcelWorkbook : TExcelWorkbook;
  60.     FExcelWorksheet : TExcelWorksheet;
  61.  
  62.     FAdapter: TOleAdapter;
  63.     FLCID: integer;
  64.  
  65.     RowComments: TRowComments;
  66.  
  67.     FActiveSheet: integer;
  68.  
  69.     FirstColumn, LastColumn: integer;
  70.     WorkRange: Range;
  71.     OldCellData, NewCellData, BlockData: Variant;
  72.     NewDataOffset, OldDataOffset: integer;
  73.  
  74.     procedure ParseComments;
  75.   protected
  76.     function GetActiveSheet: byte; override;
  77.     procedure SetActiveSheet(const Value: byte); override;
  78.     function GetActiveSheetName: WideString; override;
  79.     procedure SetActiveSheetName(const Value: WideString); override;
  80.   public
  81.     property ExcelApplication : TExcelApplication read FExcelApplication;
  82.     property ExcelWorkbook : TExcelWorkbook read FExcelWorkbook;
  83.     property ExcelWorksheet : TExcelWorksheet read FExcelWorksheet;
  84.     property LCID:integer read FLCID;
  85.  
  86.     constructor Create(const aAdapter: TOleAdapter );
  87.     destructor Destroy; override;
  88.  
  89.     procedure Connect;override;
  90.     procedure Disconnect;override;
  91.  
  92.     procedure OpenFile(const FileName: TFileName);override;
  93.     procedure CloseFile; override;
  94.  
  95.     procedure InsertAndCopySheets (const CopyFrom, InsertBefore, SheetCount: byte);override;
  96.     function SheetCount: byte;override;
  97.     procedure SelectSheet(const SheetNo:integer); override;
  98.  
  99.     procedure DeleteMarkedRows(const Mark: widestring);override;
  100.     procedure RefreshPivotTables;override;
  101.  
  102.     procedure Save(const AutoClose: boolean; const FileName: string; const OnGetFileName: TOnGetFileNameEvent);override;
  103.  
  104.     procedure InsertAndCopyRows(const FirstRow, LastRow, DestRow, aCount: integer; const OnlyFormulas: boolean);override;
  105.     procedure DeleteRows(const aRow, aCount: word);override;
  106.  
  107.     procedure BeginSheet;override;
  108.     procedure EndSheet(const RowOffset: integer);override;
  109.  
  110.     function CanOptimizeRead: boolean;override;
  111.  
  112.     function GetCommentsCount(Row: integer): integer; override;
  113.     function GetCommentText(Row, aPos: integer): widestring; override;
  114.     function GetPictureName(Row, aPos: integer): widestring;  override;
  115.     function GetPicturesCount(Row: integer): integer;  override;
  116.  
  117.     function GetExcelNameCount: integer;  override;
  118.     function GetRangeName(index: integer): widestring;  override;
  119.     function GetRangeR1(index: integer): integer; override;
  120.     function GetRangeR2(index: integer): integer; override;
  121.     function GetRangeC1(index: integer): integer; override;
  122.     function GetRangeC2(index: integer): integer; override;
  123.     function GetRangeSheet(index: integer): integer; override;
  124.     procedure AssignPicture(const Row, aPos: integer; const Pic: string; const PicType: TXlsImgTypes); override;
  125.     procedure AssignComment(const Row, aPos: integer; const Comment: widestring); override;
  126.  
  127.     function CellCount(const aRow: integer): integer;override;
  128.     function GetCellData(const aRow, aColOffset: integer): variant;override;
  129.     function GetCellDataX(const aRow, aColOffset: integer): TXlsCellValue;override;
  130.     procedure AssignCellData(const aRow, aColOffset: integer; const Value: variant);override;
  131.     procedure AssignCellDataX(const aRow, aColOffset: integer; const Value: TXlsCellValue);override;
  132.     function MaxRow: integer; override;
  133.     function IsEmptyRow(const aRow: integer): boolean; override;
  134.     function GetCellValue(aRow, aCol: integer): Variant; override;
  135.     procedure SetCellValue(aRow, aCol: integer; const Value: Variant); override;
  136.  
  137.  
  138.     procedure SetBounds(const aRangePos: integer);override;
  139.  
  140.     procedure PrepareBlockData(const R1,C1,R2,C2: integer);override;
  141.     procedure AssignBlockData(const Row,Col: integer; const v: variant);override;
  142.     procedure PasteBlockData;override;
  143.  
  144.  
  145.   end;
  146.  
  147. procedure Register;
  148.  
  149. implementation
  150. {$R IOLEAdapter}
  151. const
  152.   SaveFormatBasicConvert: Array[TExcelSaveFormatBasic] of integer= (
  153.     xlCSV, xlCSVMSDOS, xlCSVWindows, xlCSVMac,
  154.     xlDBF4, xlDIF,
  155.     integer(xlCurrentPlatformText), xlTextMSDOS, xlTextWindows, xlTextMac,
  156.     xlExcel5, xlExcel7, xlExcel9795,
  157.     integer(xlWorkbookNormal), xlSYLK, xlTemplate
  158.     {$IFNDEF Excel97}
  159.       , xlUnicodeText, xlHtml
  160.     {$ENDIF}
  161.     );
  162.  
  163.   SaveFormatExtendedConvert: Array[TExcelSaveFormatExtended] of integer= (
  164.     xlExcel2, xlExcel2FarEast, xlExcel3, xlExcel4,
  165.     xlDBF2, xlDBF3,
  166.     xlExcel4Workbook, xlIntlAddIn, xlIntlMacro, xlTextPrinter,
  167.     xlWJ2WD1, xlWK1, xlWK1ALL, xlWK1FMT, xlWK3, xlWK4, xlWK3FM3, xlWKS, xlWorks2FarEast,
  168.     xlWQ1, xlWJ3, xlWJ3FJ3);
  169.  
  170. procedure Register;
  171. begin
  172.   RegisterComponents('FlexCel', [TOLEAdapter]);
  173. end;
  174.  
  175. { TOLEAdapter }
  176.  
  177. constructor TOLEAdapter.Create(AOwner: TComponent);
  178. begin
  179.   inherited;
  180.   FDisplayAlerts:=true;
  181.   FSaveFormatBasic:=[saExcel9795];
  182.   FSaveFormatExtended:=[];
  183.   FBlockSize:=100;
  184. end;
  185.  
  186. function TOLEAdapter.GetWorkbook: TExcelFile;
  187. begin
  188.   Result:= TOLEFile.Create(Self);
  189. end;
  190.  
  191. { TOLEFile }
  192.  
  193. constructor TOLEFile.Create(const aAdapter: TOleAdapter);
  194. begin
  195.   inherited Create;
  196.   FExcelApplication := TExcelApplication.Create(nil);
  197.   FExcelWorkbook := TExcelWorkbook.Create(nil);
  198.   FExcelWorksheet := TExcelWorksheet.Create(nil);
  199.  
  200.   FAdapter:= aAdapter;
  201.  
  202.   FLCID :=   LOCALE_USER_DEFAULT;
  203. end;
  204.  
  205. destructor TOLEFile.Destroy;
  206. begin
  207.   FreeAndNil(RowComments);
  208.   FreeAndNil(FExcelApplication);
  209.   FreeAndNil(FExcelWorkbook);
  210.   FreeAndNil(FExcelWorksheet);
  211.   inherited;
  212. end;
  213.  
  214. procedure TOLEFile.Connect;
  215. begin
  216.   // Try to connect to Excel and create new Worksheet
  217.   FExcelApplication.ConnectKind := ckRunningOrNew;
  218.   FExcelApplication.Connect;
  219.  
  220.   FExcelApplication.DisplayAlerts[FLCID] := FAdapter.DisplayAlerts;
  221.   FExcelApplication.Visible[FLCID]:=false;
  222.   FExcelApplication.ScreenUpdating[FLCID] := false;
  223.  
  224. end;
  225.  
  226. procedure TOLEFile.Disconnect;
  227. begin
  228.   FExcelApplication.ScreenUpdating[FLCID] := true;
  229.   FExcelApplication.Visible[FLCID]:=true;
  230.  
  231.   FExcelWorksheet.Disconnect;
  232.   FExcelWorkbook.Disconnect;
  233.   FExcelApplication.Disconnect;
  234. end;
  235.  
  236. procedure TOLEFile.CloseFile;
  237. begin
  238.   FExcelWorkbook.Close(False);
  239. end;
  240.  
  241. procedure TOLEFile.OpenFile(const FileName: TFileName);
  242. begin
  243.   FExcelWorkbook.ConnectTo(FExcelApplication.Workbooks.Add(SearchPathStr(FileName), FLCID));
  244. end;
  245.  
  246. procedure TOLEFile.InsertAndCopySheets(const CopyFrom, InsertBefore,
  247.   SheetCount: byte);
  248. var
  249.   Ws: _Worksheet;
  250.   WsDest: _Worksheet;
  251.   i: integer;
  252. begin
  253.   Ws:=(FExcelWorkbook.Worksheets[CopyFrom] as _Worksheet);
  254.   if InsertBefore< FExcelWorkbook.Worksheets.Count then
  255.   begin
  256.     WsDest:=(FExcelWorkbook.Worksheets[InsertBefore] as _Worksheet);
  257.     for i:=0 to SheetCount-1 do Ws.Copy(WsDest, EmptyParam,FLCID);
  258.   end else
  259.   begin
  260.     WsDest:=(FExcelWorkbook.Worksheets[InsertBefore-1] as _Worksheet);
  261.     for i:=0 to SheetCount-1 do Ws.Copy(EmptyParam,WsDest,FLCID);
  262.   end;
  263. end;
  264.  
  265. function TOLEFile.SheetCount: byte;
  266. begin
  267.   Result:=FExcelWorkbook.Worksheets.Count;
  268. end;
  269.  
  270. procedure TOLEFile.DeleteMarkedRows(const Mark: widestring);
  271. var
  272.   r: OleVariant;
  273.   Empty: boolean;
  274. begin
  275.   repeat
  276.     r := FExcelWorksheet.UsedRange[FLCID].Resize[EmptyParam,1];
  277.    // We dont use early binding in 'Find' method because incompatibilities between d5 & d6 & excel97 & excel2000...
  278.     r :=r.Find(Mark, EmptyParam, integer(xlValues), xlWhole, EmptyParam, xlNext, true, EmptyParam);
  279.     // This is VarIsEmpty... If it just worked in D6...
  280.     Empty:= ((TVarData(r).VType = varDispatch) or (TVarData(r).VType = varUnknown)) and (TVarData(r).VDispatch = nil);
  281.     if not Empty then r.EntireRow.Delete(Integer(xlShiftUp));
  282.   until Empty;
  283. end;
  284.  
  285. procedure TOLEFile.RefreshPivotTables;
  286. var
  287.   k, l, m: integer;
  288.   Pvts, Pvt, PvtField, PvtItem: OleVariant;
  289. begin
  290.   Pvts:=FExcelWorksheet.PivotTables;
  291.   for k:=1 to Pvts.Count do
  292.   begin
  293.     Pvt:= FExcelWorksheet.PivotTables(k, FLCID);
  294.     FExcelApplication.DisplayAlerts[FLCID]:=False; //Here there is a warning we dont want...
  295.     try
  296.       Pvt.PivotCache.Refresh;
  297.     except
  298.       //Nothing, probably there are no rows
  299.     end; //Except
  300.     FExcelApplication.DisplayAlerts[FLCID]:=FAdapter.DisplayAlerts;
  301.  
  302.     for l:=1 to Pvt.PivotFields.Count do
  303.       begin
  304.         PvtField:= Pvt.PivotFields(l);
  305.         for m:=PvtField.PivotItems.Count downto 1 do
  306.         begin
  307.           try
  308.             PvtItem:=PvtField.PivotItems(m);
  309.             if (PvtItem.RecordCount = 0) and not (PvtItem.IsCalculated) then PvtItem.Delete;
  310.           except
  311.             //Nothing
  312.           end; //except
  313.         end;
  314.       end;
  315.   end;
  316. end;
  317.  
  318. function TOLEFile.GetActiveSheetName: WideString;
  319. begin
  320.   Result:= FExcelWorksheet.Name;
  321. end;
  322.  
  323. procedure TOLEFile.SetActiveSheetName(const Value: WideString);
  324. begin
  325.   FExcelWorksheet.Name:= Value;
  326. end;
  327.  
  328. function TOLEFile.GetActiveSheet: byte;
  329. begin
  330.   if FActiveSheet=0 then FActiveSheet:=(FExcelWorkbook.ActiveSheet as _WorkSheet).Index[FLCID]; //First time
  331.   Result:=FActiveSheet;
  332. end;
  333.  
  334. procedure TOLEFile.SetActiveSheet(const Value: byte);
  335. begin
  336.   FExcelWorksheet.ConnectTo(FExcelWorkbook.Worksheets[Value] as _Worksheet);
  337.   FActiveSheet:=Value;
  338. end;
  339.  
  340. procedure TOLEFile.SelectSheet(const SheetNo:integer);
  341. begin
  342.   (FExcelWorkbook.Worksheets.Item [SheetNo] as _Worksheet).Activate(FLCID);
  343.   ActiveSheet:= SheetNo;
  344. end;
  345.  
  346. procedure TOLEFile.Save(const AutoClose: boolean; const FileName: string; const OnGetFileName: TOnGetFileNameEvent);
  347. var
  348.   SaveFB: TExcelSaveFormatBasic;
  349.   SaveFE: TExcelSaveFormatExtended;
  350.   aFileName: TFileName;
  351. begin
  352.   if (AutoClose) then
  353.   begin
  354.     for SaveFB:= Low(TExcelSaveFormatBasic) to High(TExcelSaveFormatBasic) do
  355.       if SaveFB in FAdapter.SaveFormatBasic then
  356.       begin
  357.         aFileName:=Filename;
  358.         if Assigned (OnGetFileName) then OnGetFileName(Self,SaveFormatBasicConvert[SaveFB],aFilename);
  359.         FExcelWorkbook.SaveAs(aFileName,SaveFormatBasicConvert[SaveFB],EmptyParam,EmptyParam,EmptyParam,EmptyParam,xlExclusive,EmptyParam,EmptyParam,EmptyParam,EmptyParam,FLCID);
  360.       end;
  361.     for SaveFE:= Low(TExcelSaveFormatExtended) to High(TExcelSaveFormatExtended) do
  362.       if SaveFE in FAdapter.SaveFormatExtended then
  363.       begin
  364.         aFileName:=Filename;
  365.         if Assigned (OnGetFileName) then OnGetFileName(Self,SaveFormatExtendedConvert[SaveFE],aFilename);
  366.         FExcelWorkbook.SaveAs(aFileName, SaveFormatExtendedConvert[SaveFE], EmptyParam, EmptyParam, EmptyParam, EmptyParam, xlExclusive, EmptyParam, EmptyParam, EmptyParam, EmptyParam, FLCID);
  367.       end;
  368.   end
  369.  
  370. end;
  371.  
  372. procedure TOLEFile.DeleteRows(const aRow, aCount: word);
  373. var
  374.   NewRange: Range;
  375. begin
  376.   NewRange:=FExcelWorksheet.Range['A'+IntToStr(aRow), 'A'+IntToStr(aRow+aCount-1)].EntireRow;
  377.   NewRange.Delete(Integer(xlShiftUp));
  378. end;
  379.  
  380. procedure TOLEFile.InsertAndCopyRows(const FirstRow, LastRow, DestRow, aCount: integer; const OnlyFormulas: boolean);
  381. var
  382.   OldRange, NewRange: Range;
  383. begin
  384.   NewRange:=FExcelWorksheet.Range['A'+IntToStr(DestRow), 'A'+IntToStr(DestRow+aCount*(LastRow-FirstRow+1)-1)].EntireRow;
  385.   NewRange.Insert( integer(xlDown));
  386.   NewRange := NewRange.Offset[-(aCount*(LastRow-FirstRow+1)),0];
  387.   OldRange := FExcelWorksheet.Range['A'+IntToStr(FirstRow), 'A'+IntToStr(LastRow)].EntireRow; //We need the entire row to copy row height!
  388.   OldRange.Copy (NewRange);
  389. end;
  390.  
  391. procedure TOLEFile.AssignComment(const Row, aPos: integer;
  392.   const Comment: Widestring);
  393. begin
  394.   if Comment='' then
  395.   begin
  396.     FExcelWorksheet.Comments[RowComments[Row][aPos]].Delete;
  397.     RowComments.Delete(Row,aPos);
  398.   end else
  399.   FExcelWorksheet.Comments[RowComments[Row][aPos]].Text(Comment, EmptyParam, EmptyParam);
  400. end;
  401.  
  402. procedure TOLEFile.AssignPicture(const Row, aPos: integer;
  403.   const Pic: string; const PicType: TXlsImgTypes);
  404. begin
  405.   //Not implemented
  406. end;
  407.  
  408. procedure TOLEFile.ParseComments;
  409. var
  410.   i:integer;
  411. begin
  412.   FreeAndNil(RowComments);
  413.   RowComments:= TRowComments.Create;
  414.   for i:=1 to FExcelWorksheet.Comments.Count do
  415.     RowComments.Add(FExcelWorksheet.Comments[i].Shape.TopLeftCell.Row, i);
  416. end;
  417.  
  418. procedure TOLEFile.BeginSheet;
  419. begin
  420.   //Parse comments into corresponding rows
  421.   ParseComments;
  422.  
  423.   //Prepare Matrix to handle Data Transfer
  424.   NewCellData:=VarArrayCreate([1,FAdapter.BlockSize,FirstColumn,LastColumn],varVariant);
  425.   WorkRange:=FExcelWorksheet.Range[
  426.     FExcelWorksheet.Cells.Item[1, FirstColumn],
  427.     FExcelWorksheet.Cells.Item[1+FAdapter.BlockSize-1, LastColumn]
  428.     ];
  429.   OldCellData:=Unassigned;
  430.   OldDataOffset:=-1;
  431.  
  432. end;
  433.  
  434. procedure TOLEFile.EndSheet(const RowOffset: integer);
  435. var
  436.   Size:integer;
  437. begin
  438.   try
  439.     //Flush final data
  440.     Size:=RowOffset-1-NewDataOffset;
  441.     if Size<0 then exit;
  442.     WorkRange:=FExcelWorksheet.Range[
  443.       FExcelWorksheet.Cells.Item[1, FirstColumn],
  444.       FExcelWorksheet.Cells.Item[1+Size, LastColumn]
  445.       ];
  446.     WorkRange.Offset[NewDataOffset,0].FormulaLocal:=NewCellData;
  447.   finally
  448.     WorkRange:=nil; //This is needed so we don't keep any reference to Excel.
  449.   end; //finally
  450. end;
  451.  
  452. function TOLEFile.GetCommentsCount(Row: integer): integer;
  453. begin
  454.   Result:=RowComments[Row].Count;
  455. end;
  456.  
  457. function TOLEFile.GetCommentText(Row, aPos: integer): Widestring;
  458. begin
  459.   Result:=FExcelWorksheet.Comments[RowComments[Row][aPos]].Text(EmptyParam, EmptyParam, EmptyParam);
  460. end;
  461.  
  462. function TOLEFile.GetExcelNameCount: integer;
  463. begin
  464.   Result:=FExcelWorkbook.Names.Count;
  465. end;
  466.  
  467. function TOLEFile.GetPictureName(Row, aPos: integer): Widestring;
  468. begin
  469.    Result:=''; //Not implemented
  470. end;
  471.  
  472. function TOLEFile.GetPicturesCount(Row: integer): integer;
  473. begin
  474.   Result:=0; //Not implemented
  475. end;
  476.  
  477. function TOLEFile.GetRangeName(index: integer): Widestring;
  478. begin
  479.   Result:=FExcelWorkbook.Names.Item(index, EmptyParam, EmptyParam).Name_;
  480. end;
  481.  
  482. function TOLEFile.GetRangeR1(index: integer): integer;
  483. begin
  484.   Result:=FExcelWorkbook.Names.Item(index, EmptyParam, EmptyParam).RefersToRange.Row;
  485. end;
  486.  
  487. function TOLEFile.GetRangeR2(index: integer): integer;
  488. begin
  489.   Result:=GetRangeR1(Index)+FExcelWorkbook.Names.Item(index, EmptyParam, EmptyParam).RefersToRange.Rows.Count-1;
  490. end;
  491.  
  492. function TOLEFile.GetRangeC1(index: integer): integer;
  493. begin
  494.   Result:=FExcelWorkbook.Names.Item(index, EmptyParam, EmptyParam).RefersToRange.Column;
  495. end;
  496.  
  497. function TOLEFile.GetRangeC2(index: integer): integer;
  498. begin
  499.   Result:=GetRangeC1(Index)+FExcelWorkbook.Names.Item(index, EmptyParam, EmptyParam).RefersToRange.Columns.Count-1;
  500. end;
  501.  
  502. function TOLEFile.GetRangeSheet(index: integer): integer;
  503. var
  504.   w:OleVariant; //Cant get to use _Worksheet
  505. begin
  506.   try
  507.     w:=FExcelWorkbook.Names.Item(index, EmptyParam, EmptyParam).RefersToRange.Worksheet;
  508.     result:=w.Index;
  509.   except //Err in range
  510.     result:=-1;
  511.   end; //Except
  512. end;
  513.  
  514. procedure TOLEFile.AssignCellData(const aRow, aColOffset: integer; const Value: variant);
  515. var
  516.   i,j:integer;
  517. begin
  518.   if aRow-NewDataOffset > FAdapter.BlockSize then
  519.   begin
  520.     //Flush Data
  521.     WorkRange.Offset[NewDataOffset,0].FormulaLocal:=NewCellData;
  522.     NewDataOffset:=aRow-1;
  523.     for i:=VarArrayLowBound(NewCellData,1) to VarArrayHighBound(NewCellData,1) do
  524.       for j:=VarArrayLowBound(NewCellData,2) to VarArrayHighBound(NewCellData,2) do
  525.         NewCellData[i,j]:=unassigned;
  526.   end;
  527.   NewCellData[aRow-NewDataOffset,aColOffset+FirstColumn]:=Value;
  528. end;
  529.  
  530. procedure TOLEFile.AssignCellDataX(const aRow, aColOffset: integer; const Value: TXlsCellValue);
  531. begin
  532.   AssignCellData(aRow, aColOffset, Value.Value);
  533. end;
  534.  
  535. function TOLEFile.CellCount(const aRow: integer): integer;
  536. begin
  537.   Result:= LastColumn-FirstColumn+1;
  538. end;
  539.  
  540. function TOLEFile.GetCellData(const aRow, aColOffset: integer): variant;
  541. begin
  542.   if (OldDataOffset<0)or (aRow-OldDataOffset>FAdapter.BlockSize) then
  543.   begin
  544.     OldDataOffset:=aRow-1;
  545.     OldCellData:= WorkRange.Offset[OldDataOffset,0].FormulaLocal;
  546.   end;
  547.   GetCellData:=OldCellData[aRow-OldDataOffset,aColOffset+1];
  548. end;
  549.  
  550. function TOLEFile.GetCellDataX(const aRow, aColOffset: integer): TXlsCellValue;
  551. begin
  552.   Result.Value:=GetCellData(aRow,aColOffset);
  553.   Result.Xf:=-1; //Not implemented
  554.   Result.IsFormula:=false; //not implemented
  555. end;
  556.  
  557. procedure TOLEFile.SetBounds(const aRangePos: integer);
  558. var
  559.   CellRange: Range;
  560. begin
  561.   CellRange:=FExcelWorkbook.Names.Item(aRangePos, EmptyParam, EmptyParam).RefersToRange;
  562.   FirstColumn:=CellRange.Column;
  563.   LastColumn:=CellRange.Column+CellRange.Columns.Count-1;
  564.   NewDataOffset:=CellRange.Row-1;
  565. end;
  566.  
  567. procedure TOLEFile.AssignBlockData(const Row, Col: integer; const v: variant);
  568. begin
  569.   BlockData[Row,FirstColumn+Col]:=v;
  570. end;
  571.  
  572. procedure TOLEFile.PasteBlockData;
  573. var
  574.   R1, R2, C1, C2: integer;
  575. begin
  576.   R1:=VarArrayLowBound(BlockData,1);
  577.   R2:=VarArrayHighBound(BlockData,1);
  578.   C1:=VarArrayLowBound(BlockData,2);
  579.   C2:=VarArrayHighBound(BlockData,2);
  580.   FExcelWorksheet.Range[
  581.       FExcelWorksheet.Cells.Item[R1, C1],
  582.       FExcelWorksheet.Cells.Item[R2, C2]
  583.       ].FormulaLocal:=BlockData;
  584.   BlockData:=unassigned;
  585. end;
  586.  
  587. procedure TOLEFile.PrepareBlockData(const R1, C1, R2, C2: integer);
  588. begin
  589.   BlockData:= VarArrayCreate([R1,R2,FirstColumn+C1,FirstColumn+C2],varVariant);
  590. end;
  591.  
  592. function TOLEFile.MaxRow: integer;
  593. begin
  594.   Result:= FExcelWorksheet.UsedRange[FLCID].Row-1 + FExcelWorksheet.UsedRange[FLCID].Rows.Count;
  595. end;
  596.  
  597. function TOLEFile.GetCellValue(aRow, aCol: integer): Variant;
  598. begin
  599.   Result:=FExcelWorksheet.Cells.Item[aRow, aCol].Value;
  600.  
  601. end;
  602.  
  603. procedure TOLEFile.SetCellValue(aRow, aCol: integer; const Value: Variant);
  604. begin
  605.   FExcelWorksheet.Cells.Item[aRow, aCol]:= Value;
  606. end;
  607.  
  608. function TOLEFile.IsEmptyRow(const aRow: integer): boolean;
  609. begin
  610.   Result:=(aRow<1) or (aRow>MaxRow);
  611. end;
  612.  
  613. function TOLEFile.CanOptimizeRead: boolean;
  614. begin
  615.   Result:=false;
  616. end;
  617.  
  618.  
  619. end.
  620.