fpspreadsheet: Add method TsWorksheet.MoveCell (forum https://forum.lazarus.freepascal.org/index.php/topic,59137).
git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@8260 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
parent
b4ac1e075d
commit
02bd21629c
@ -197,6 +197,8 @@ type
|
||||
function FindFormula(ARow, ACol: Cardinal): PsFormula; overload;
|
||||
procedure FixReferences(AIndex: Cardinal; IsRow, IsDeleting: Boolean;
|
||||
InSheet: TsBasicWorksheet);
|
||||
procedure FixReferenceToMovedCell(ACell: PCell; AToRow, AToCol: Cardinal;
|
||||
ASheet: TsBasicWorksheet);
|
||||
// enumerators
|
||||
function GetEnumerator: TsFormulaEnumerator;
|
||||
end;
|
||||
@ -474,6 +476,26 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure FixFormulaToMovedCell(AExprNode: TsExprNode; AData1, AData2: Pointer;
|
||||
var MustRebuildFormulas: Boolean);
|
||||
var
|
||||
oldCell, newCell: PCell;
|
||||
begin
|
||||
oldCell := PCell(AData1);
|
||||
newCell := PCell(AData2);
|
||||
if AExprNode is TsCellExprNode then
|
||||
begin
|
||||
if (oldCell^.Worksheet = TsCellExprNode(AExprNode).GetSheet) and
|
||||
(oldCell^.Row = TsCellExprNode(AExprNode).Row) and
|
||||
(oldCell^.Col = TsCellExprNode(AExprNode).Col) then
|
||||
begin
|
||||
TsCellExprNode(AExprNode).Row := newCell^.Row;
|
||||
TsCellExprNode(AExprNode).Col := newCell^.Col;
|
||||
MustRebuildFormulas := true;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
{==============================================================================}
|
||||
{ TsRowColEnumerator }
|
||||
@ -1571,6 +1593,24 @@ begin
|
||||
formula^.Text := formula^.Parser.Expression[fdExcelA1];
|
||||
end;
|
||||
|
||||
{ A cell in the specified sheet has been moved from its old location at AFromRow/
|
||||
AFromCol to a new location at AToRow/AToCol. If the cell is referenced by
|
||||
a formula the formula must be adjusted such it points to the new location.
|
||||
However, this occurs only when the reference is a single cell, not a cell range.}
|
||||
procedure TsFormulas.FixReferenceToMovedCell(
|
||||
ACell: PCell; AToRow, AToCol: Cardinal; ASheet: TsBasicWorksheet);
|
||||
var
|
||||
formula: PsFormula;
|
||||
newCell: TCell;
|
||||
begin
|
||||
newCell := ACell^;
|
||||
newCell.Row := AToRow;
|
||||
newCell.Col := AToCol;
|
||||
for formula in self do
|
||||
if formula^.Parser.IterateNodes(@FixFormulaToMovedCell, ACell, @newCell) then
|
||||
formula^.Text := formula^.Parser.Expression[fdExcelA1];
|
||||
end;
|
||||
|
||||
// Formula enumerators (use in "for ... in" syntax)
|
||||
function TsFormulas.GetEnumerator: TsFormulaEnumerator;
|
||||
begin
|
||||
|
@ -458,6 +458,8 @@ type
|
||||
function GetCell(AddressStr: String): PCell; overload;
|
||||
function GetCellCount: Cardinal;
|
||||
|
||||
procedure MoveCell(ACell: PCell; AToRow, AToCol: Cardinal);
|
||||
|
||||
function FindNextCellInCol(ARow, ACol: Cardinal): PCell;
|
||||
function FindNextCellInRow(ARow, ACol: Cardinal): PCell;
|
||||
function FindPrevCellInCol(ARow, ACol: Cardinal): PCell;
|
||||
@ -2257,6 +2259,50 @@ begin
|
||||
Result := FCells.Count;
|
||||
end;
|
||||
|
||||
{@@ ----------------------------------------------------------------------------
|
||||
Moves a cell to a different location.
|
||||
|
||||
All additional data (comments, format, hyperlinks, formulas) are moved to the
|
||||
new location. If the old location was referenced by a formula then the formula
|
||||
is adjusted so that it points to the new location, however, only if the
|
||||
formula references a single cell, not a cell range.
|
||||
|
||||
@param ACell Cell to be moved
|
||||
@param AToRow Row index of the new location
|
||||
@param AToCol Column index of the new location
|
||||
-------------------------------------------------------------------------------}
|
||||
procedure TsWorksheet.MoveCell(ACell: PCell; AToRow, AToCol: Cardinal);
|
||||
var
|
||||
fromRow, fromCol: Cardinal;
|
||||
sheet: TsWorksheet;
|
||||
i: Integer;
|
||||
begin
|
||||
if ACell = nil then
|
||||
exit;
|
||||
|
||||
// Store old location
|
||||
fromRow := ACell^.Row;
|
||||
fromCol := ACell^.Col;
|
||||
|
||||
// Copy cell to new location
|
||||
CopyCell(fromRow, fromCol, AToRow, AToCol);
|
||||
|
||||
// Fix formula references to this cell
|
||||
for i := 0 to FWorkbook.GetWorksheetcount-1 do begin
|
||||
sheet := FWorkbook.GetWorksheetByIndex(i);
|
||||
sheet.Formulas.FixReferenceToMovedCell(ACell, AToRow, AToCol, self);
|
||||
end;
|
||||
|
||||
// Delete cell at old location
|
||||
DeleteCell(ACell);
|
||||
|
||||
// Notify visual controls of changes
|
||||
ChangedCell(AToRow, AToCol);
|
||||
|
||||
// Notify visual controls of possibly changed row heights.
|
||||
ChangedFont(AToRow, AToCol);
|
||||
end;
|
||||
|
||||
{@@ ----------------------------------------------------------------------------
|
||||
Determines the number of decimals displayed for the number in the cell
|
||||
|
||||
@ -5585,12 +5631,7 @@ var
|
||||
i: Integer;
|
||||
rng: PsCellRange;
|
||||
sheet: TsWorksheet;
|
||||
wasAutoCalculating: Boolean;
|
||||
begin
|
||||
// Turn off auto-calculation of formulas
|
||||
wasAutoCalculating := (boAutoCalc in Workbook.Options);
|
||||
//Workbook.Options := Workbook.Options - [boAutoCalc];
|
||||
|
||||
// Update row indexes of cell comments
|
||||
FComments.InsertRowOrCol(AIndex, IsRow);
|
||||
|
||||
@ -5685,13 +5726,6 @@ begin
|
||||
|
||||
ChangedCell(0, AIndex);
|
||||
end;
|
||||
|
||||
// Calculate formulas
|
||||
if wasAutoCalculating then
|
||||
begin
|
||||
//Workbook.Options := Workbook.Options + [boAutoCalc];
|
||||
//CalcFormulas;
|
||||
end;
|
||||
end;
|
||||
|
||||
{@@ ----------------------------------------------------------------------------
|
||||
|
Loading…
Reference in New Issue
Block a user