You've already forked lazarus-ccr
fpspreadsheet: Fix bug in formula parser when scanning of ods cell addresses (incorrect extraction of row index).
git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@6577 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
@ -953,7 +953,7 @@ end;
|
|||||||
It has the structure [sheet1.C1R1:sheet2.C2R2] }
|
It has the structure [sheet1.C1R1:sheet2.C2R2] }
|
||||||
function TsExpressionScanner.DoCellRangeODS: TsTokenType;
|
function TsExpressionScanner.DoCellRangeODS: TsTokenType;
|
||||||
type
|
type
|
||||||
TScannerStateODS = (ssSheet1, ssCol1, ssRow1, ssSheet2, ssCol2, ssRow2);
|
TScannerStateODS = (ssInSheet1, ssInCol1, ssInRow1, ssInSheet2, ssInCol2, ssInRow2);
|
||||||
var
|
var
|
||||||
C: Char;
|
C: Char;
|
||||||
prevC: Char;
|
prevC: Char;
|
||||||
@ -968,7 +968,7 @@ begin
|
|||||||
FCellRange.Col2 := Cardinal(-1);
|
FCellRange.Col2 := Cardinal(-1);
|
||||||
FFlags := rfAllRel;
|
FFlags := rfAllRel;
|
||||||
|
|
||||||
state := ssSheet1;
|
state := ssInSheet1;
|
||||||
FToken := '';
|
FToken := '';
|
||||||
C := NextPos;
|
C := NextPos;
|
||||||
prevC := #0;
|
prevC := #0;
|
||||||
@ -976,33 +976,33 @@ begin
|
|||||||
case C of
|
case C of
|
||||||
cNULL: ScanError(rsUnexpectedEndOfExpression);
|
cNULL: ScanError(rsUnexpectedEndOfExpression);
|
||||||
'.': begin
|
'.': begin
|
||||||
if (state = ssSheet1) then
|
if (state = ssInSheet1) then
|
||||||
begin
|
begin
|
||||||
FSheet1 := FToken;
|
FSheet1 := FToken;
|
||||||
state := ssCol1;
|
state := ssInCol1;
|
||||||
end else
|
end else
|
||||||
if (state = ssSheet2) then
|
if (state = ssInSheet2) then
|
||||||
begin
|
begin
|
||||||
FSheet2 := FToken;
|
FSheet2 := FToken;
|
||||||
state := ssCol2;
|
state := ssInCol2;
|
||||||
end else
|
end else
|
||||||
ScanError(rsIllegalODSCellRange);
|
ScanError(rsIllegalODSCellRange);
|
||||||
FToken := '';
|
FToken := '';
|
||||||
val := 0;
|
val := 0;
|
||||||
end;
|
end;
|
||||||
':': if (state = ssRow1) then
|
':': if (state = ssInRow1) then
|
||||||
begin
|
begin
|
||||||
FCellRange.Row1 := val-1;
|
FCellRange.Row1 := val-1;
|
||||||
state := ssSheet2;
|
state := ssInSheet2;
|
||||||
FToken := '';
|
FToken := '';
|
||||||
end else
|
end else
|
||||||
ScanError(rsIllegalODSCellRange);
|
ScanError(rsIllegalODSCellRange);
|
||||||
'$': case state of
|
'$': case state of
|
||||||
ssCol1: if prevC = '.' then Exclude(FFlags, rfRelCol) else Exclude(FFlags, rfRelRow);
|
ssInCol1: if prevC = '.' then Exclude(FFlags, rfRelCol) else Exclude(FFlags, rfRelRow);
|
||||||
ssCol2: if prevC = '.' then Exclude(FFlags, rfRelCol2) else Exclude(FFlags, rfRelRow2);
|
ssInCol2: if prevC = '.' then Exclude(FFlags, rfRelCol2) else Exclude(FFlags, rfRelRow2);
|
||||||
end;
|
end;
|
||||||
else
|
else
|
||||||
if (state in [ssSheet1, ssSheet2]) then
|
if (state in [ssInSheet1, ssInSheet2]) then
|
||||||
FToken := FToken + C
|
FToken := FToken + C
|
||||||
else
|
else
|
||||||
case C of
|
case C of
|
||||||
@ -1011,16 +1011,21 @@ begin
|
|||||||
'a'..'z':
|
'a'..'z':
|
||||||
val := val*10 + ord(C) - ord('a');
|
val := val*10 + ord(C) - ord('a');
|
||||||
'0'..'9':
|
'0'..'9':
|
||||||
if state = ssCol1 then begin
|
if state = ssInCol1 then begin
|
||||||
FCellRange.Col1 := val;
|
FCellRange.Col1 := val;
|
||||||
val := ord(C) - ord('0');
|
val := (ord(C) - ord('0'));
|
||||||
state := ssRow1;
|
state := ssInRow1;
|
||||||
end else
|
end else
|
||||||
if state = ssCol2 then begin
|
if state = ssInRow1 then
|
||||||
|
val := val*10 + (ord(C) - ord('0'))
|
||||||
|
else
|
||||||
|
if state = ssInCol2 then begin
|
||||||
FCellRange.Col2 := val;
|
FCellRange.Col2 := val;
|
||||||
val := ord(C) - ord('0');
|
val := (ord(C) - ord('0'));
|
||||||
state := ssRow2;
|
state := ssInRow2;
|
||||||
end;
|
end else
|
||||||
|
if state = ssInRow2 then
|
||||||
|
val := val*10 + (ord(C) - ord('0'));
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
prevC := C;
|
prevC := C;
|
||||||
@ -1029,9 +1034,9 @@ begin
|
|||||||
if C <> ']' then
|
if C <> ']' then
|
||||||
ScanError(Format(rsRightSquareBracketExpected, [FPos, C]));
|
ScanError(Format(rsRightSquareBracketExpected, [FPos, C]));
|
||||||
case state of
|
case state of
|
||||||
ssRow1:
|
ssInRow1:
|
||||||
if val > 0 then FCellRange.Row1 := val - 1 else ScanError(rsIllegalODSCellRange);
|
if val > 0 then FCellRange.Row1 := val - 1 else ScanError(rsIllegalODSCellRange);
|
||||||
ssRow2:
|
ssInRow2:
|
||||||
if val > 0 then FCellRange.Row2 := val - 1 else ScanError(rsIllegalODSCellRange);
|
if val > 0 then FCellRange.Row2 := val - 1 else ScanError(rsIllegalODSCellRange);
|
||||||
end;
|
end;
|
||||||
if FCellRange.Col2 = Cardinal(-1) then Exclude(FFlags, rfRelCol2);
|
if FCellRange.Col2 = Cardinal(-1) then Exclude(FFlags, rfRelCol2);
|
||||||
|
@ -2463,8 +2463,10 @@ begin
|
|||||||
hasFormula := false;
|
hasFormula := false;
|
||||||
|
|
||||||
// Read formula results
|
// Read formula results
|
||||||
if hasFormula then TsWorkbook(FWorkbook).LockFormulas;
|
|
||||||
|
|
||||||
|
// Prevent formulas from being erased when formula results are written to cells
|
||||||
|
TsWorkbook(FWorkbook).LockFormulas;
|
||||||
|
try
|
||||||
valueType := GetAttrValue(ACellNode, 'office:value-type');
|
valueType := GetAttrValue(ACellNode, 'office:value-type');
|
||||||
valueStr := GetAttrValue(ACellNode, 'office:value');
|
valueStr := GetAttrValue(ACellNode, 'office:value');
|
||||||
calcExtValueType := GetAttrValue(ACellNode, 'calcext:value-type');
|
calcExtValueType := GetAttrValue(ACellNode, 'calcext:value-type');
|
||||||
@ -2527,10 +2529,12 @@ begin
|
|||||||
if (valueStr <> '') then
|
if (valueStr <> '') then
|
||||||
TsWorksheet(FWorksheet).WriteText(cell, valueStr);
|
TsWorksheet(FWorksheet).WriteText(cell, valueStr);
|
||||||
|
|
||||||
if hasFormula then TsWorkbook(FWorkbook).UnlockFormulas;
|
|
||||||
|
|
||||||
if FIsVirtualMode then
|
if FIsVirtualMode then
|
||||||
TsWorkbook(Workbook).OnReadCellData(Workbook, ARow, ACol, cell);
|
TsWorkbook(Workbook).OnReadCellData(Workbook, ARow, ACol, cell);
|
||||||
|
|
||||||
|
finally
|
||||||
|
TsWorkbook(FWorkbook).UnlockFormulas;
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TsSpreadOpenDocReader.ReadFromStream(AStream: TStream;
|
procedure TsSpreadOpenDocReader.ReadFromStream(AStream: TStream;
|
||||||
|
Reference in New Issue
Block a user