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