home *** CD-ROM | disk | FTP | other *** search
/ Chip 2003 January / Chip_2003-01_cd1.bin / zkuste / delphi / kolekce / d567 / FLEXCEL.ZIP / XLSAdapter / UXlsRowColEntries.pas < prev    next >
Encoding:
Pascal/Delphi Source File  |  2002-10-03  |  13.7 KB  |  463 lines

  1. unit UXlsRowColEntries;
  2.  
  3. interface
  4. uses Classes, SysUtils, UXlsBaseRecords, UXlsBaseRecordLists, UXlsOtherRecords,
  5.      XlsMessages, UXlsRangeRecords, UXlsBaseList, UXlsCellRecords, UXlsFormula,
  6.      {$IFDEF ConditionalExpressions}{$if CompilerVersion >= 14} variants,{$IFEND}{$ENDIF} //Delphi 6 or above
  7.      UXlsSST, UFlxMessages, UXlsColInfo;
  8.  
  9. type
  10.   TListClass= class of TBaseRowColRecordList;
  11.  
  12.   TBaseRowColList = class(TBaseList) //records are TBaseRowColRecordList
  13.     {$INCLUDE TBaseRowColListHdr.inc}
  14.   protected
  15.     ListClass: TListClass;
  16.   public
  17.     procedure AddRecord(const aRecord: TBaseRowColRecord; const aRow: integer);
  18.  
  19.     procedure CopyFrom(const aList: TBaseRowColList);
  20.  
  21.     procedure SaveToStream(const DataStream: TStream);
  22.     function TotalSize: int64;
  23.  
  24.     procedure InsertAndCopyRows(const FirstRow, LastRow, DestRow, aCount: integer; const SheetInfo: TSheetInfo; const OnlyFormulas: boolean);
  25.     procedure DeleteRows(const aRow, aCount: word; const SheetInfo: TSheetInfo);
  26.     procedure ArrangeInsert(const InsPos, InsCount: integer; const SheetInfo: TSheetInfo);
  27.  
  28.     constructor Create(const aListClass: TListClass);
  29.   end;
  30.  
  31.   TCellList = class (TBaseRowColList)//records are TCellRecordList
  32.   private
  33.     FSST: TSST;
  34.     FRowRecordList: TRowRecordList;
  35.     FColInfoList: TColInfoList;
  36.  
  37.     function GetValue(Row, Col: integer): TXlsCellValue;
  38.     procedure SetValue(Row, Col: integer; const Value: TXlsCellValue);
  39.     procedure FixFormulaTokens(const Formula: TFormulaRecord; const ShrFmlas: TShrFmlaRecordList);
  40.     function GetMaxCol(Row: integer): integer;
  41.     {$INCLUDE TCellListHdr.inc}
  42.   public
  43.     constructor Create(const aSST: TSST; const aRowRecordList: TRowRecordList; const aColInfoList: TColInfoList);
  44.     property Value[Row,Col:integer]:TXlsCellValue  read GetValue write SetValue;
  45.     property MaxCol[Row: integer]: integer read GetMaxCol;
  46.  
  47.     procedure FixFormulas(const ShrFmlas: TShrFmlaRecordList);
  48.   end;
  49.  
  50.   TCells = class
  51.   private
  52.     FRowList: TRowRecordList;
  53.     FCellList: TCellList;
  54.   public
  55.     constructor Create(const aSST: TSST; const aColInfoList: TColInfoList);
  56.     destructor Destroy; override;
  57.  
  58.     procedure Clear;
  59.     procedure CopyFrom(const aList: TCells);
  60.  
  61.     procedure SaveToStream(const DataStream: TStream);
  62.     function TotalSize: int64;
  63.  
  64.     procedure InsertAndCopyRows(const FirstRow, LastRow, DestRow, aCount: integer; const SheetInfo: TSheetInfo; const OnlyFormulas: boolean);
  65.     procedure DeleteRows(const aRow, aCount: word; const SheetInfo: TSheetInfo);
  66.     procedure ArrangeInsert(const InsPos, InsCount: integer; const SheetInfo: TSheetInfo);
  67.  
  68.     procedure AddRow(const aRecord: TRowRecord);
  69.     procedure AddCell(const aRecord: TCellRecord;  const aRow: integer);
  70.     procedure AddMultipleCells(const aRecord: TMultipleValueRecord);
  71.  
  72.     property CellList: TCellList read FCellList;
  73.     property RowList: TRowRecordList read FRowList;
  74.   end;
  75.  
  76.  
  77.   TRangeList = class(TBaseList) //records are TRangeEntry
  78.     {$INCLUDE TRangeListHdr.inc}
  79.     procedure CopyFrom(const aRangeList: TRangeList);
  80.  
  81.     procedure SaveToStream(const DataStream: TStream);
  82.     function TotalSize: int64;
  83.  
  84.     procedure InsertAndCopyRows(const FirstRow, LastRow, DestRow, aCount: integer; const SheetInfo: TSheetInfo);
  85.     procedure DeleteRows(const aRow, aCount: word; const SheetInfo: TSheetInfo);
  86.  
  87.   end;
  88.  
  89. implementation
  90. { TBaseRowColList }
  91.  
  92. {$INCLUDE TBaseRowColListImp.inc}
  93.  
  94. procedure TBaseRowColList.AddRecord(const aRecord: TBaseRowColRecord; const aRow: integer);
  95. var
  96.   i:integer;
  97. begin
  98.   for i:= Count to aRow do Add(ListClass.Create);
  99.   Items[aRow].Add(aRecord);
  100. end;
  101.  
  102. procedure TBaseRowColList.ArrangeInsert(const InsPos, InsCount: integer; const SheetInfo: TSheetInfo);
  103. var
  104.   i:integer;
  105. begin
  106.   for i:=0 to Count-1 do Items[i].ArrangeInsert(InsPos, InsCount, SheetInfo);
  107. end;
  108.  
  109. procedure TBaseRowColList.CopyFrom(const aList: TBaseRowColList);
  110. var
  111.   i: integer;
  112.   Tr: TBaseRowColRecordList;
  113. begin
  114.   for i:=0 to aList.Count - 1 do
  115.   begin
  116.     Tr:= ListClass.Create;
  117.     Tr.CopyFrom(aList[i]);
  118.     Add(Tr);
  119.   end;
  120. end;
  121.  
  122. constructor TBaseRowColList.Create(const aListClass: TListClass);
  123. begin
  124.   inherited Create(true);
  125.   ListClass:=aListClass;
  126. end;
  127.  
  128. procedure TBaseRowColList.DeleteRows(const aRow, aCount: word; const SheetInfo: TSheetInfo);
  129. var
  130.   i, Max: integer;
  131. begin
  132.   Max:=aRow+aCount ; if Max>Count then Max:= Count;
  133.   for i:= Max-1 downto aRow do Delete(i);
  134.   //Delete the cells. we have to look at all the formulas, not only those below arow
  135.   ArrangeInsert(aRow, -aCount, SheetInfo);
  136.  
  137. end;
  138.  
  139. procedure TBaseRowColList.InsertAndCopyRows(const FirstRow, LastRow, DestRow,
  140.   aCount: integer; const SheetInfo: TSheetInfo; const OnlyFormulas: boolean);
  141. var
  142.   i, k, z, a, CopyOffs, MyDestRow: integer;
  143.   aRecordList: TBaseRowColRecordList;
  144. begin
  145.   // Insert the cells. we have to look at all the formulas, not only those below destrow
  146.   ArrangeInsert(DestRow, aCount*(LastRow-FirstRow+1), SheetInfo);
  147.  
  148.   //Copy the cells
  149.   MyDestRow:=DestRow;
  150.   CopyOffs:=0;
  151.   for k:=1 to aCount do
  152.     for i:=FirstRow to LastRow do
  153.     begin
  154.       aRecordList:= ListClass.Create;
  155.       try
  156.         if i+CopyOffs<Count then
  157.         begin
  158.           if OnlyFormulas then
  159.           begin
  160.             for a:=0 to Items[i+CopyOffs].Count-1 do
  161.               if (Items[i+CopyOffs][a] is TFormulaRecord) then
  162.                 aRecordList.Add(Items[i+CopyOffs][a].CopyTo as TBaseRowColRecord);
  163.           end else aRecordList.CopyFrom(Items[i+CopyOffs]);
  164.  
  165.           aRecordList.ArrangeCopyRows(MyDestRow);
  166.         end;
  167.         for z:= Count to MyDestRow-1 do Add(ListClass.Create);
  168.         Insert(MyDestRow, aRecordList);
  169.         aRecordList:=nil;
  170.       finally
  171.         FreeAndNil(aRecordList);
  172.       end; //finally
  173.       Inc(MyDestRow);
  174.       if FirstRow>=DestRow then Inc(CopyOffs);
  175.     end;
  176.  
  177. end;
  178.  
  179. procedure TBaseRowColList.SaveToStream(const DataStream: TStream);
  180. var
  181.   i:integer;
  182. begin
  183.   for i:=0 to Count-1 do Items[i].SaveToStream(DataStream);
  184. end;
  185.  
  186. function TBaseRowColList.TotalSize: int64;
  187. var
  188.   i:integer;
  189. begin
  190.   Result:=0;
  191.   for i:=0 to Count-1 do Result:=Result+Items[i].TotalSize;
  192. end;
  193.  
  194. { TCellList }
  195. {$INCLUDE TCellListImp.inc}
  196.  
  197. constructor TCellList.Create(const aSST: TSST; const aRowRecordList: TRowRecordList; const aColInfoList: TColInfoList);
  198. begin
  199.   inherited Create(TCellRecordList);
  200.   FSST:= aSST;
  201.   FRowRecordList:=aRowRecordList;
  202.   FColInfoList:=aColInfoList;
  203. end;
  204.  
  205. function TCellList.GetValue(Row, Col: integer): TXlsCellValue;
  206. var
  207.   Index: integer;
  208. begin
  209.   if (Row<0) or (Row>Max_Rows) then raise Exception.CreateFmt(ErrInvalidRow,[Row]);
  210.   if (Col>Max_Columns)or (Col<0) then raise Exception.CreateFmt(ErrInvalidCol,[Col]);
  211.   if Row>=Count then begin; Result.Value:=Unassigned; Result.XF:=-1; Result.IsFormula:=false; exit; end;
  212.   if Items[Row].Find(Col,Index) then
  213.   begin
  214.     Result.Value:=Items[Row][Index].Value;
  215.     Result.XF:=Items[Row][Index].XF;
  216.     Result.IsFormula:=Items[Row][Index] is TFormulaRecord;
  217.   end else
  218.   begin
  219.     Result.Value:=Unassigned;
  220.     Result.XF:=-1;
  221.     Result.IsFormula:=false;
  222.   end;
  223. end;
  224.  
  225. procedure TCellList.SetValue(Row, Col: integer; const Value: TXlsCellValue);
  226. var
  227.   Index: integer;
  228.   XF, DefaultXF: integer;
  229.   Found: boolean;
  230.   Cell: TCellRecord;
  231. begin
  232.   if (Row<0) or (Row>Max_Rows) then raise Exception.CreateFmt(ErrInvalidRow,[Row]);
  233.   if (Col>Max_Columns)or (Col<0) then raise Exception.CreateFmt(ErrInvalidCol,[Col]);
  234.  
  235.   FRowRecordList.AddRow(Row);
  236.  
  237.   DefaultXF:=FRowRecordList[Row].XF;
  238.   if DefaultXF<=0 then if FColInfoList.Find(Col, Index) then DefaultXF:=FColInfoList[Index].XF;
  239.  
  240.   Cell:=nil;
  241.   Found:=(Row<Count) and Items[Row].Find(Col,Index);
  242.   XF:=DefaultXF;
  243.   if Found then XF:=Items[Row][Index].XF;
  244.   if Value.XF>=0 then XF:=Value.XF;
  245.  
  246.   case VarType(Value.Value) of
  247.     varEmpty,
  248.     varNull      : if (XF<>DefaultXF) then Cell:= TBlankRecord.CreateFromData(Row,Col,XF);
  249.  
  250.     varByte,
  251.     varSmallint,
  252.     varInteger,
  253.     varSingle,
  254.     varDouble,
  255.    {$IFDEF ConditionalExpressions}{$if CompilerVersion >= 14} varInt64,{$IFEND}{$ENDIF} //Delphi 6 or above
  256.  
  257.     varCurrency : if IsRK(Value.Value) then Cell:= TRKRecord.CreateFromData(Row,Col,XF)
  258.                                  else Cell:= TNumberRecord.CreateFromData(Row,Col,XF);
  259.  
  260.     varDate     : Cell:= TLabelSSTRecord.CreateFromData(Row,Col,XF,FSST);
  261.  
  262.     varOleStr,
  263.     varStrArg,
  264.     varString   : if (Value.Value='') then
  265.                   begin
  266.                     if (XF<>DefaultXF) then Cell:= TBlankRecord.CreateFromData(Row,Col,XF);
  267.                   end
  268.                   else Cell:= TLabelSSTRecord.CreateFromData(Row,Col,XF,FSST);
  269.  
  270.     varBoolean    : Cell:= TBoolErrRecord.CreateFromData(Row,Col,XF);
  271.   end; //case
  272.  
  273.   if Found then Items[Row].Delete(Index);
  274.   if Cell=nil then exit;
  275.   if Col+1> FRowRecordList[Row].MaxCol then FRowRecordList[Row].MaxCol:=Col+1;
  276.   if Col< FRowRecordList[Row].MinCol then FRowRecordList[Row].MinCol:=Col;
  277.   Cell.Value:=Value.Value;
  278.   if Row>=Count then AddRecord(Cell, Row) else Items[Row].Insert(Index, Cell);
  279. end;
  280.  
  281. procedure TCellList.FixFormulaTokens(const Formula: TFormulaRecord; const ShrFmlas: TShrFmlaRecordList);
  282. var
  283.   Key: Cardinal;
  284.   Index: integer;
  285. begin
  286.   if not Formula.IsExp(Key) then exit;
  287.   if not ShrFmlas.Find(Key, Index) then raise Exception.Create(ErrShrFmlaNotFound);
  288.   Formula.MixShared(ShrFmlas[Index].Data, ShrFmlas[Index].DataSize);
  289. end;
  290.  
  291. procedure TCellList.FixFormulas(const ShrFmlas: TShrFmlaRecordList);
  292. var
  293.   i, k: integer;
  294.   it: TCellRecordList;
  295.   OldFormulaSize: integer;
  296. begin
  297.   for i:=0 to Count-1 do
  298.   begin
  299.     it:=Items[i];
  300.     for k:=0 to it.Count-1 do
  301.       if it.Items[k] is TFormulaRecord then
  302.       begin
  303.         OldFormulaSize:=(it.Items[k] as TFormulaRecord).DataSize;
  304.         FixFormulaTokens(it.Items[k] as TFormulaRecord, ShrFmlas);
  305.         it.AdaptSize((it.Items[k] as TFormulaRecord).DataSize-OldFormulaSize);
  306.       end;
  307.   end;
  308. end;
  309.  
  310. function TCellList.GetMaxCol(Row: integer): integer;
  311. begin
  312.   if (Row>=Count) or (Row<0) or (Items[Row].Count<=0)then begin; Result:=0; exit; end;
  313.   Result:= Items[Row][Items[Row].Count-1].Column;
  314.  
  315. end;
  316.  
  317. { TCells }
  318.  
  319. procedure TCells.AddCell(const aRecord: TCellRecord; const aRow: integer);
  320. begin
  321.   FCellList.AddRecord(aRecord, aRow);
  322. end;
  323.  
  324. procedure TCells.AddMultipleCells(const aRecord: TMultipleValueRecord);
  325. var
  326.   OneRec: TCellRecord;
  327. begin
  328.   while not aRecord.Eof do
  329.   begin
  330.     OneRec:=aRecord.ExtractOneRecord;
  331.     FCellList.AddRecord( OneRec, OneRec.Row);
  332.   end;
  333. end;
  334.  
  335. procedure TCells.AddRow(const aRecord: TRowRecord);
  336. begin
  337.   FRowList.AddRecord(aRecord);
  338. end;
  339.  
  340. procedure TCells.ArrangeInsert(const InsPos, InsCount: integer;
  341.   const SheetInfo: TSheetInfo);
  342. begin
  343.   FRowList.ArrangeInsert(InsPos, InsCount, SheetInfo);
  344.   FCellList.ArrangeInsert(InsPos, InsCount, SheetInfo);
  345. end;
  346.  
  347. procedure TCells.Clear;
  348. begin
  349.   if FRowList<>nil then FRowList.Clear;
  350.   if FCellList<>nil then FCellList.Clear;
  351. end;
  352.  
  353. procedure TCells.CopyFrom(const aList: TCells);
  354. begin
  355.   FRowList.CopyFrom(aList.FRowList);
  356.   FCellList.CopyFrom(aList.FCellList);
  357. end;
  358.  
  359. constructor TCells.Create(const aSST: TSST; const aColInfoList: TColInfoList);
  360. begin
  361.   inherited Create;
  362.   FRowList:=TRowRecordList.Create;
  363.   FCellList:=TCellList.Create(aSST, FRowList, aColInfoList);
  364. end;
  365.  
  366. procedure TCells.DeleteRows(const aRow, aCount: word; const SheetInfo: TSheetInfo);
  367. begin
  368.   FRowList.DeleteRows(aRow, aCount, SheetInfo);
  369.   FCellList.DeleteRows(aRow, aCount, SheetInfo);
  370. end;
  371.  
  372. destructor TCells.Destroy;
  373. begin
  374.   FreeAndNil(FRowList);
  375.   FreeAndNil(FCellList);
  376.   inherited;
  377. end;
  378.  
  379. procedure TCells.InsertAndCopyRows(const FirstRow, LastRow, DestRow,
  380.   aCount: integer; const SheetInfo: TSheetInfo; const OnlyFormulas: boolean);
  381. begin
  382.   FRowList.InsertAndCopyRows(FirstRow, LastRow, DestRow, aCount, SheetInfo);
  383.   FCellList.InsertAndCopyRows(FirstRow, LastRow, DestRow, aCount, SheetInfo, OnlyFormulas);
  384. end;
  385.  
  386. procedure TCells.SaveToStream(const DataStream: TStream);
  387. var
  388.   i,k,j, Written :integer;
  389. begin
  390.   if FRowList.Count< FCellList.Count then raise Exception.Create(ErrBadRowCount);
  391.   if FRowList.Count=0 then exit;
  392.   i:=0;
  393.   while (i<FrowList.Count) do
  394.   begin
  395.     k:=0;Written:=0;
  396.     while (Written<32) and (k+i<FRowList.Count) do
  397.     begin
  398.       if FRowList.HasRow(k+i) then
  399.       begin
  400.         FRowList[k+i].SaveToStream(DataStream);
  401.         inc(Written);
  402.       end;
  403.       inc(k);
  404.     end;
  405.  
  406.     for j:= i to k+i-1 do
  407.       if (j<FCellList.Count) then FCellList[j].SaveToStream(DataStream);
  408.  
  409.     inc(i, k);
  410.   end;
  411.  
  412. end;
  413.  
  414. function TCells.TotalSize: int64;
  415. begin
  416.   TotalSize:= FRowList.TotalSize + FCellList.TotalSize;
  417. end;
  418.  
  419. { TRangeList }
  420.  
  421. {$INCLUDE TRangeListImp.inc}
  422.  
  423. procedure TRangeList.CopyFrom(const aRangeList: TRangeList);
  424. var
  425.   i: integer;
  426. begin
  427.   for i:=0 to aRangeList.Count - 1 do
  428.     Add(aRangeList.Items[i].CopyTo);
  429. end;
  430.  
  431. procedure TRangeList.DeleteRows(const aRow, aCount: word;
  432.   const SheetInfo: TSheetInfo);
  433. var
  434.   i: integer;
  435. begin
  436.   for i:=0 to Count-1 do Items[i].DeleteRows(aRow, aCount, SheetInfo);
  437. end;
  438.  
  439. procedure TRangeList.InsertAndCopyRows(const FirstRow, LastRow, DestRow,
  440.   aCount: integer; const SheetInfo: TSheetInfo);
  441. var
  442.   i: integer;
  443. begin
  444.   for i:=0 to Count-1 do Items[i].InsertAndCopyRows(FirstRow, LastRow, DestRow, aCount, SheetInfo);
  445. end;
  446.  
  447. procedure TRangeList.SaveToStream(const DataStream: TStream);
  448. var
  449.   i:integer;
  450. begin
  451.   for i:=0 to Count-1 do Items[i].SaveToStream(DataStream);
  452. end;
  453.  
  454. function TRangeList.TotalSize: int64;
  455. var
  456.   i:integer;
  457. begin
  458.   Result:=0;
  459.   for i:=0 to Count-1 do Result:=Result+Items[i].TotalSize;
  460. end;
  461.  
  462. end.
  463.