You've already forked lazarus-ccr
fpspreadsheet: Fix cell ranges in ods formula parser. --> 3d single-sheet references (Sheet1!A1;B4) working for all ODS now for both reading and writing. PageLayout broken for BIFF5 at the moment.
git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@6409 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
@ -152,6 +152,10 @@ msgstr "grün"
|
|||||||
msgid "Header"
|
msgid "Header"
|
||||||
msgstr "Kopfzeile"
|
msgstr "Kopfzeile"
|
||||||
|
|
||||||
|
#: fpsstrings.rsillegalodscellrange
|
||||||
|
msgid "Illegal structure of an OpenDocument cell range."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: fpsstrings.rsimageformatnotsupported
|
#: fpsstrings.rsimageformatnotsupported
|
||||||
msgid "Image format not supported."
|
msgid "Image format not supported."
|
||||||
msgstr "Bild-Format nicht unterstützt."
|
msgstr "Bild-Format nicht unterstützt."
|
||||||
@ -333,9 +337,14 @@ msgid "red"
|
|||||||
msgstr "rot"
|
msgstr "rot"
|
||||||
|
|
||||||
#: fpsstrings.rsrightbracketexpected
|
#: fpsstrings.rsrightbracketexpected
|
||||||
|
#, fuzzy,badformat
|
||||||
msgid "Expected right bracket at position %d, but got %s"
|
msgid "Expected right bracket at position %d, but got %s"
|
||||||
msgstr "Rechte Klammer erwartet an Position, aber %s gefunden."
|
msgstr "Rechte Klammer erwartet an Position, aber %s gefunden."
|
||||||
|
|
||||||
|
#: fpsstrings.rsrightsquarebracketexpected
|
||||||
|
msgid "Expected right square bracket at positon %d, but got %s"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: fpsstrings.rsrowstylenotfound
|
#: fpsstrings.rsrowstylenotfound
|
||||||
msgid "Row style not found."
|
msgid "Row style not found."
|
||||||
msgstr "Zeilenstil nicht gefunden."
|
msgstr "Zeilenstil nicht gefunden."
|
||||||
@ -435,3 +444,4 @@ msgstr "Die Datei kann nicht geschrieben werden, weil der Name des Arbeitsblatte
|
|||||||
#: fpsstrings.rsyellow
|
#: fpsstrings.rsyellow
|
||||||
msgid "yellow"
|
msgid "yellow"
|
||||||
msgstr "gelb"
|
msgstr "gelb"
|
||||||
|
|
||||||
|
@ -141,6 +141,10 @@ msgstr "vihreä"
|
|||||||
msgid "Header"
|
msgid "Header"
|
||||||
msgstr "Otsikko"
|
msgstr "Otsikko"
|
||||||
|
|
||||||
|
#: fpsstrings.rsillegalodscellrange
|
||||||
|
msgid "Illegal structure of an OpenDocument cell range."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: fpsstrings.rsimageformatnotsupported
|
#: fpsstrings.rsimageformatnotsupported
|
||||||
msgid "Image format not supported."
|
msgid "Image format not supported."
|
||||||
msgstr "Kuvatiedostoformaattia ei ole tuettu"
|
msgstr "Kuvatiedostoformaattia ei ole tuettu"
|
||||||
@ -325,6 +329,10 @@ msgstr "punainen"
|
|||||||
msgid "Expected right bracket at position %d, but got %s"
|
msgid "Expected right bracket at position %d, but got %s"
|
||||||
msgstr "Odotettiin oikeata suljetta kohdassa %d mutta saatiin %s"
|
msgstr "Odotettiin oikeata suljetta kohdassa %d mutta saatiin %s"
|
||||||
|
|
||||||
|
#: fpsstrings.rsrightsquarebracketexpected
|
||||||
|
msgid "Expected right square bracket at positon %d, but got %s"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: fpsstrings.rsrowstylenotfound
|
#: fpsstrings.rsrowstylenotfound
|
||||||
msgid "Row style not found."
|
msgid "Row style not found."
|
||||||
msgstr "Rivin tyyliä ei löydetty."
|
msgstr "Rivin tyyliä ei löydetty."
|
||||||
|
@ -151,6 +151,10 @@ msgstr "zöld"
|
|||||||
msgid "Header"
|
msgid "Header"
|
||||||
msgstr "Fejléc"
|
msgstr "Fejléc"
|
||||||
|
|
||||||
|
#: fpsstrings.rsillegalodscellrange
|
||||||
|
msgid "Illegal structure of an OpenDocument cell range."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: fpsstrings.rsimageformatnotsupported
|
#: fpsstrings.rsimageformatnotsupported
|
||||||
msgid "Image format not supported."
|
msgid "Image format not supported."
|
||||||
msgstr "A kép formátuma nincs támogatva."
|
msgstr "A kép formátuma nincs támogatva."
|
||||||
@ -296,13 +300,13 @@ msgid "Only one image per %s section allowed."
|
|||||||
msgstr "Csak egy kép lehet %s szakaszonként."
|
msgstr "Csak egy kép lehet %s szakaszonként."
|
||||||
|
|
||||||
#: fpsstrings.rsoperationexceedscolcount
|
#: fpsstrings.rsoperationexceedscolcount
|
||||||
#, fuzzy
|
#, fuzzy,badformat
|
||||||
#| msgid "This operation exceeds the range of defined grid columns."
|
#| msgid "This operation exceeds the range of defined grid columns."
|
||||||
msgid "This operation at index %d exceeds the range of defined grid columns (%d)."
|
msgid "This operation at index %d exceeds the range of defined grid columns (%d)."
|
||||||
msgstr "A művelet túllépi a rács oszlopainak tartományát."
|
msgstr "A művelet túllépi a rács oszlopainak tartományát."
|
||||||
|
|
||||||
#: fpsstrings.rsoperationexceedsrowcount
|
#: fpsstrings.rsoperationexceedsrowcount
|
||||||
#, fuzzy
|
#, fuzzy,badformat
|
||||||
#| msgid "This operation exceeds the range of defined grid rows."
|
#| msgid "This operation exceeds the range of defined grid rows."
|
||||||
msgid "This operation at index %d exceeds the range of defined grid rows (%d)."
|
msgid "This operation at index %d exceeds the range of defined grid rows (%d)."
|
||||||
msgstr "A művelet túllépi a rács sorainak tartományát."
|
msgstr "A művelet túllépi a rács sorainak tartományát."
|
||||||
@ -339,6 +343,10 @@ msgstr "piros"
|
|||||||
msgid "Expected right bracket at position %d, but got %s"
|
msgid "Expected right bracket at position %d, but got %s"
|
||||||
msgstr "Jobb oldali zárójel szükséges a(z) %d. pozícióban, de %s található"
|
msgstr "Jobb oldali zárójel szükséges a(z) %d. pozícióban, de %s található"
|
||||||
|
|
||||||
|
#: fpsstrings.rsrightsquarebracketexpected
|
||||||
|
msgid "Expected right square bracket at positon %d, but got %s"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: fpsstrings.rsrowstylenotfound
|
#: fpsstrings.rsrowstylenotfound
|
||||||
msgid "Row style not found."
|
msgid "Row style not found."
|
||||||
msgstr "Sor stílus nem található."
|
msgstr "Sor stílus nem található."
|
||||||
@ -364,6 +372,7 @@ msgid "transparent"
|
|||||||
msgstr "átlátszó"
|
msgstr "átlátszó"
|
||||||
|
|
||||||
#: fpsstrings.rstruncatetoolongcelltext
|
#: fpsstrings.rstruncatetoolongcelltext
|
||||||
|
#, fuzzy,badformat
|
||||||
msgid "Text value exceeds the %d character limit in cell %s and has been truncated."
|
msgid "Text value exceeds the %d character limit in cell %s and has been truncated."
|
||||||
msgstr "A szöveg hosszabb mint a(z) 15 karakteres korlát a(z) %s cellában, ezért csonkolva lett."
|
msgstr "A szöveg hosszabb mint a(z) 15 karakteres korlát a(z) %s cellában, ezért csonkolva lett."
|
||||||
|
|
||||||
|
@ -141,6 +141,10 @@ msgstr ""
|
|||||||
msgid "Header"
|
msgid "Header"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#: fpsstrings.rsillegalodscellrange
|
||||||
|
msgid "Illegal structure of an OpenDocument cell range."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: fpsstrings.rsimageformatnotsupported
|
#: fpsstrings.rsimageformatnotsupported
|
||||||
msgid "Image format not supported."
|
msgid "Image format not supported."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
@ -325,6 +329,10 @@ msgstr ""
|
|||||||
msgid "Expected right bracket at position %d, but got %s"
|
msgid "Expected right bracket at position %d, but got %s"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#: fpsstrings.rsrightsquarebracketexpected
|
||||||
|
msgid "Expected right square bracket at positon %d, but got %s"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: fpsstrings.rsrowstylenotfound
|
#: fpsstrings.rsrowstylenotfound
|
||||||
msgid "Row style not found."
|
msgid "Row style not found."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
@ -141,6 +141,10 @@ msgstr "зелёный"
|
|||||||
msgid "Header"
|
msgid "Header"
|
||||||
msgstr "Заголовок"
|
msgstr "Заголовок"
|
||||||
|
|
||||||
|
#: fpsstrings.rsillegalodscellrange
|
||||||
|
msgid "Illegal structure of an OpenDocument cell range."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: fpsstrings.rsimageformatnotsupported
|
#: fpsstrings.rsimageformatnotsupported
|
||||||
msgid "Image format not supported."
|
msgid "Image format not supported."
|
||||||
msgstr "Формат изображения не поддерживается"
|
msgstr "Формат изображения не поддерживается"
|
||||||
@ -286,13 +290,13 @@ msgid "Only one image per %s section allowed."
|
|||||||
msgstr "Разрешено только одно изображения для секции %s."
|
msgstr "Разрешено только одно изображения для секции %s."
|
||||||
|
|
||||||
#: fpsstrings.rsoperationexceedscolcount
|
#: fpsstrings.rsoperationexceedscolcount
|
||||||
#, fuzzy
|
#, fuzzy,badformat
|
||||||
#| msgid "This operation exceeds the range of defined grid columns."
|
#| msgid "This operation exceeds the range of defined grid columns."
|
||||||
msgid "This operation at index %d exceeds the range of defined grid columns (%d)."
|
msgid "This operation at index %d exceeds the range of defined grid columns (%d)."
|
||||||
msgstr "Эта операция превышает диапазон определенных столбцов таблицы"
|
msgstr "Эта операция превышает диапазон определенных столбцов таблицы"
|
||||||
|
|
||||||
#: fpsstrings.rsoperationexceedsrowcount
|
#: fpsstrings.rsoperationexceedsrowcount
|
||||||
#, fuzzy
|
#, fuzzy,badformat
|
||||||
#| msgid "This operation exceeds the range of defined grid rows."
|
#| msgid "This operation exceeds the range of defined grid rows."
|
||||||
msgid "This operation at index %d exceeds the range of defined grid rows (%d)."
|
msgid "This operation at index %d exceeds the range of defined grid rows (%d)."
|
||||||
msgstr "Эта операция превышает диапазон определенных столбцов таблицы"
|
msgstr "Эта операция превышает диапазон определенных столбцов таблицы"
|
||||||
@ -329,6 +333,10 @@ msgstr "красный"
|
|||||||
msgid "Expected right bracket at position %d, but got %s"
|
msgid "Expected right bracket at position %d, but got %s"
|
||||||
msgstr "Ожидается правая скобка в позиции %d, но найдено %s"
|
msgstr "Ожидается правая скобка в позиции %d, но найдено %s"
|
||||||
|
|
||||||
|
#: fpsstrings.rsrightsquarebracketexpected
|
||||||
|
msgid "Expected right square bracket at positon %d, but got %s"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: fpsstrings.rsrowstylenotfound
|
#: fpsstrings.rsrowstylenotfound
|
||||||
msgid "Row style not found."
|
msgid "Row style not found."
|
||||||
msgstr "Стиль строки не найден"
|
msgstr "Стиль строки не найден"
|
||||||
|
@ -57,7 +57,7 @@ type
|
|||||||
{ Tokens }
|
{ Tokens }
|
||||||
|
|
||||||
TsTokenType = (
|
TsTokenType = (
|
||||||
ttCell, ttCellRange, ttSheetName,
|
ttCell, ttCellRange, ttSheetName, ttCellRangeODS,
|
||||||
ttNumber, ttString, ttIdentifier,
|
ttNumber, ttString, ttIdentifier,
|
||||||
ttPlus, ttMinus, ttMul, ttDiv, ttConcat, ttPercent, ttPower, ttLeft, ttRight,
|
ttPlus, ttMinus, ttMul, ttDiv, ttConcat, ttPercent, ttPower, ttLeft, ttRight,
|
||||||
ttLessThan, ttLargerThan, ttEqual, ttNotEqual, ttLessThanEqual, ttLargerThanEqual,
|
ttLessThan, ttLargerThan, ttEqual, ttNotEqual, ttLessThanEqual, ttLargerThanEqual,
|
||||||
@ -672,6 +672,8 @@ type
|
|||||||
function IsAlpha(C: Char): Boolean; // inline;
|
function IsAlpha(C: Char): Boolean; // inline;
|
||||||
public
|
public
|
||||||
constructor Create(AParser: TsExpressionParser);
|
constructor Create(AParser: TsExpressionParser);
|
||||||
|
procedure GetCellRangeParamsODS(out ASheet1, ASheet2: String;
|
||||||
|
out ARow1, ACol1, ARow2, ACol2: Cardinal; out AFlags: TsRelFlags);
|
||||||
function GetToken: TsTokenType;
|
function GetToken: TsTokenType;
|
||||||
property Token: String read FToken;
|
property Token: String read FToken;
|
||||||
property TokenType: TsTokenType read FTokenType;
|
property TokenType: TsTokenType read FTokenType;
|
||||||
@ -1015,11 +1017,13 @@ begin
|
|||||||
if C = FSheetNameTerminator then C := NextPos;
|
if C = FSheetNameTerminator then C := NextPos;
|
||||||
while (not IsWordDelim(C)) and (C <> cNull) and (C <> FSheetNameTerminator) do
|
while (not IsWordDelim(C)) and (C <> cNull) and (C <> FSheetNameTerminator) do
|
||||||
begin
|
begin
|
||||||
|
{
|
||||||
if ((FParser.Dialect = fdOpenDocument) and (C = ']')) then begin
|
if ((FParser.Dialect = fdOpenDocument) and (C = ']')) then begin
|
||||||
C := NextPos;
|
C := NextPos;
|
||||||
FSheetNameTerminator := FSavedSheetNameTerminator;
|
FSheetNameTerminator := FSavedSheetNameTerminator;
|
||||||
break;
|
break;
|
||||||
end;
|
end;
|
||||||
|
}
|
||||||
FToken := FToken + C;
|
FToken := FToken + C;
|
||||||
C := NextPos;
|
C := NextPos;
|
||||||
end;
|
end;
|
||||||
@ -1068,9 +1072,101 @@ begin
|
|||||||
ScanError(Format(rsInvalidNumber, [FToken]));
|
ScanError(Format(rsInvalidNumber, [FToken]));
|
||||||
Result := ttNumber;
|
Result := ttNumber;
|
||||||
end;
|
end;
|
||||||
(*
|
|
||||||
{ Scans until closing square bracket is reached. In OpenDocument, this is
|
{ Scans until closing square bracket is reached. In OpenDocument, this is
|
||||||
a cell or cell range identifier. }
|
a cell or cell range identifier.
|
||||||
|
It has the structure [sheet1.C1R1:sheet2.C2R2] }
|
||||||
|
procedure TsExpressionScanner.GetCellRangeParamsODS(
|
||||||
|
out ASheet1, ASheet2: String; out ARow1, ACol1, ARow2, ACol2: Cardinal;
|
||||||
|
out AFlags: TsRelFlags);
|
||||||
|
type
|
||||||
|
TScannerStateODS = (ssSheet1, ssCol1, ssRow1, ssSheet2, ssCol2, ssRow2);
|
||||||
|
var
|
||||||
|
C: Char;
|
||||||
|
prevC: Char;
|
||||||
|
state: TScannerStateODS;
|
||||||
|
val: Integer;
|
||||||
|
begin
|
||||||
|
ASheet1 := '';
|
||||||
|
ASheet2 := '';
|
||||||
|
ARow1 := Cardinal(-1);
|
||||||
|
ACol1 := Cardinal(-1);
|
||||||
|
ARow2 := Cardinal(-1);
|
||||||
|
ACol2 := Cardinal(-1);
|
||||||
|
AFlags := rfAllRel;
|
||||||
|
|
||||||
|
state := ssSheet1;
|
||||||
|
FToken := '';
|
||||||
|
C := NextPos;
|
||||||
|
prevC := #0;
|
||||||
|
while (C <> ']') and (C <> cNULL) do begin
|
||||||
|
case C of
|
||||||
|
cNULL: ScanError(rsUnexpectedEndOfExpression);
|
||||||
|
'.': begin
|
||||||
|
if (state = ssSheet1) then
|
||||||
|
begin
|
||||||
|
ASheet1 := FToken;
|
||||||
|
state := ssCol1;
|
||||||
|
end else
|
||||||
|
if (state = ssSheet2) then
|
||||||
|
begin
|
||||||
|
ASheet2 := FToken;
|
||||||
|
state := ssCol2;
|
||||||
|
end else
|
||||||
|
ScanError(rsIllegalODSCellRange);
|
||||||
|
FToken := '';
|
||||||
|
val := 0;
|
||||||
|
end;
|
||||||
|
':': if (state = ssRow1) then
|
||||||
|
begin
|
||||||
|
ARow1 := val-1;
|
||||||
|
state := ssSheet2;
|
||||||
|
FToken := '';
|
||||||
|
end else
|
||||||
|
ScanError(rsIllegalODSCellRange);
|
||||||
|
'$': case state of
|
||||||
|
ssCol1: if prevC = '.' then Exclude(AFlags, rfRelCol) else Exclude(AFlags, rfRelRow);
|
||||||
|
ssCol2: if prevC = '.' then Exclude(AFlags, rfRelCol2) else Exclude(AFlags, rfRelRow2);
|
||||||
|
end;
|
||||||
|
else
|
||||||
|
if (state in [ssSheet1, ssSheet2]) then
|
||||||
|
FToken := FToken + C
|
||||||
|
else
|
||||||
|
case C of
|
||||||
|
'A'..'Z':
|
||||||
|
val := val*10 + ord(C) - ord('A');
|
||||||
|
'a'..'z':
|
||||||
|
val := val*10 + ord(C) - ord('a');
|
||||||
|
'0'..'9':
|
||||||
|
if state = ssCol1 then begin
|
||||||
|
ACol1 := val;
|
||||||
|
val := ord(C) - ord('0');
|
||||||
|
state := ssRow1;
|
||||||
|
end else
|
||||||
|
if state = ssCol2 then begin
|
||||||
|
ACol2 := val;
|
||||||
|
val := ord(C) - ord('0');
|
||||||
|
state := ssRow2;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
prevC := C;
|
||||||
|
C := NextPos;
|
||||||
|
end;
|
||||||
|
if C <> ']' then
|
||||||
|
ScanError(Format(rsRightSquareBracketExpected, [FPos, C]));
|
||||||
|
case state of
|
||||||
|
ssRow1:
|
||||||
|
if val > 0 then ARow1 := val - 1 else ScanError(rsIllegalODSCellRange);
|
||||||
|
ssRow2:
|
||||||
|
if val > 0 then ARow2 := val - 1 else ScanError(rsIllegalODSCellRange);
|
||||||
|
end;
|
||||||
|
if ACol2 = Cardinal(-1) then Exclude(AFlags, rfRelCol2);
|
||||||
|
if ARow2 = Cardinal(-1) then Exclude(AFlags, rfRelRow2);
|
||||||
|
C := NextPos;
|
||||||
|
end;
|
||||||
|
|
||||||
|
(*
|
||||||
function TsExpressionScanner.DoSquareBracket: TsTokenType;
|
function TsExpressionScanner.DoSquareBracket: TsTokenType;
|
||||||
var
|
var
|
||||||
C: Char;
|
C: Char;
|
||||||
@ -1161,13 +1257,8 @@ begin
|
|||||||
FToken := '';
|
FToken := '';
|
||||||
SkipWhiteSpace;
|
SkipWhiteSpace;
|
||||||
C := FChar^;
|
C := FChar^;
|
||||||
if (FParser.Dialect = fdOpenDocument) and (C = '[') then begin
|
if {(FParser.Dialect = fdOpenDocument) and }(C = '[') then
|
||||||
FSavedSheetNameTerminator := FSheetNameTerminator;
|
Result := ttCellRangeODS
|
||||||
FSheetNameTerminator := '.';
|
|
||||||
C := NextPos;
|
|
||||||
Result := DoIdentifier
|
|
||||||
// Result := DoSquareBracket
|
|
||||||
end
|
|
||||||
else if C = cNull then
|
else if C = cNull then
|
||||||
Result := ttEOF
|
Result := ttEOF
|
||||||
else if IsDelim(C) then
|
else if IsDelim(C) then
|
||||||
@ -1647,7 +1738,9 @@ var
|
|||||||
optional: Boolean;
|
optional: Boolean;
|
||||||
token: String;
|
token: String;
|
||||||
prevTokenType: TsTokenType;
|
prevTokenType: TsTokenType;
|
||||||
sheetname: String;
|
sheetname, sheetname2: String;
|
||||||
|
r1, c1, r2, c2: Cardinal;
|
||||||
|
flags: TsRelFlags;
|
||||||
sheet: TsWorksheet;
|
sheet: TsWorksheet;
|
||||||
begin
|
begin
|
||||||
{$ifdef debugexpr} Writeln('Primitive : ',TokenName(TokenType),': ',CurrentToken);{$endif debugexpr}
|
{$ifdef debugexpr} Writeln('Primitive : ',TokenName(TokenType),': ',CurrentToken);{$endif debugexpr}
|
||||||
@ -1672,7 +1765,26 @@ begin
|
|||||||
Result := TsCellExprNode.Create(self, FWorksheet, CurrentToken, false)
|
Result := TsCellExprNode.Create(self, FWorksheet, CurrentToken, false)
|
||||||
else if (TokenType = ttCellRange) then
|
else if (TokenType = ttCellRange) then
|
||||||
Result := TsCellRangeExprNode.Create(self, FWorksheet, CurrentToken)
|
Result := TsCellRangeExprNode.Create(self, FWorksheet, CurrentToken)
|
||||||
else if (TokenType = ttSheetName) then begin
|
else if (TokenType = ttCellRangeODS) then
|
||||||
|
begin
|
||||||
|
FScanner.GetCellRangeParamsODS(sheetname, sheetname2, r1, c1, r2, c2, flags);
|
||||||
|
if (sheetname2 = '') and (r2 = cardinal(-1)) and (c2 = cardinal(-1)) then
|
||||||
|
begin
|
||||||
|
if sheetname = '' then
|
||||||
|
Result := TsCellExprNode.Create(self, FWorksheet, r1, c1, flags, false)
|
||||||
|
else begin
|
||||||
|
sheet := FWorksheet.Workbook.GetWorksheetByName(sheetName);
|
||||||
|
if sheet = nil then
|
||||||
|
sheet := FWorksheet.Workbook.AddWorksheet(sheetname, true);
|
||||||
|
Result := TsCellExprNode.Create(self, sheet, r1, c1, flags, true);
|
||||||
|
end;
|
||||||
|
end
|
||||||
|
else
|
||||||
|
Result := TsCellRangeExprNode.Create(self, FWorksheet, sheetname, sheetname2,
|
||||||
|
r1, c1, r2, c2, flags, (sheetname <> ''));
|
||||||
|
end
|
||||||
|
else if (TokenType = ttSheetName) then
|
||||||
|
begin
|
||||||
sheetName := CurrentToken;
|
sheetName := CurrentToken;
|
||||||
GetToken;
|
GetToken;
|
||||||
if TokenType = ttCell then begin
|
if TokenType = ttCell then begin
|
||||||
@ -3887,93 +3999,21 @@ begin
|
|||||||
FParser := AParser;
|
FParser := AParser;
|
||||||
FWorksheet := AWorksheet;
|
FWorksheet := AWorksheet;
|
||||||
FSheet[1] := GetWorkbook.GetWorksheetIndex(ASheet1);
|
FSheet[1] := GetWorkbook.GetWorksheetIndex(ASheet1);
|
||||||
if ASheet2 = '' then
|
if ASheet2 = '' then FSheet[2] := FSheet[1] else FSheet[2] := GetWorkbook.GetWorksheetIndex(ASheet2);
|
||||||
FSheet[2] := FSheet[1]
|
|
||||||
else
|
|
||||||
FSheet[2] := GetWorkbook.GetWorksheetIndex(ASheet2);
|
|
||||||
FRow[1] := ARow1;
|
FRow[1] := ARow1;
|
||||||
FCol[1] := ACol1;
|
FCol[1] := ACol1;
|
||||||
FRow[2] := ARow2;
|
if ARow2 = Cardinal(-1) then FRow[2] := FRow[1] else FRow[2] := ARow2;
|
||||||
FCol[2] := ACol2;
|
if ACol2 = Cardinal(-1) then FCol[2] := FCol[1] else FCol[2] := ACol2;
|
||||||
FFlags := AFlags;
|
FFlags := AFlags;
|
||||||
F3dRange := Is3dRange;
|
F3dRange := Is3dRange;
|
||||||
end;
|
end;
|
||||||
(*
|
|
||||||
|
|
||||||
constructor TsCellRangeExprNode.Create(AParser: TsExpressionParser;
|
|
||||||
AWorksheet: TsWorksheet; ACellRangeString: String; OnOtherSheet: Boolean);
|
|
||||||
var
|
|
||||||
r1, c1, r2, c2: Cardinal;
|
|
||||||
flags: TsRelFlags;
|
|
||||||
begin
|
|
||||||
if pos(':', ACellRangeString) = 0 then
|
|
||||||
begin
|
|
||||||
ParseCellString(ACellRangeString, r1, c1, flags);
|
|
||||||
if rfRelRow in flags then Include(flags, rfRelRow2);
|
|
||||||
if rfRelCol in flags then Include(flags, rfRelCol2);
|
|
||||||
Create(AParser, AWorksheet, r1, c1, r1, c1, flags, OnOtherSheet);
|
|
||||||
end else
|
|
||||||
begin
|
|
||||||
ParseCellRangeString(ACellRangeString, r1, c1, r2, c2, flags);
|
|
||||||
Create(AParser, AWorksheet, r1, c1, r2, c2, flags, OnOtherSheet);
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
|
|
||||||
constructor TsCellRangeExprNode.Create(AParser: TsExpressionParser;
|
|
||||||
AWorksheet: TsWorksheet; ARow1,ACol1,ARow2,ACol2: Cardinal;
|
|
||||||
AFlags: TsRelFlags; OnOtherSheet: Boolean);
|
|
||||||
begin
|
|
||||||
FParser := AParser;
|
|
||||||
FWorksheet := AWorksheet;
|
|
||||||
FRow[1] := ARow1;
|
|
||||||
FCol[1] := ACol1;
|
|
||||||
FRow[2] := ARow2;
|
|
||||||
FCol[2] := ACol2;
|
|
||||||
FFlags := AFlags;
|
|
||||||
FOnOtherSheet := OnOtherSheet;
|
|
||||||
end;
|
|
||||||
|
|
||||||
constructor TsCellRangeExprNode.Create(AParser: TsExpressionParser;
|
|
||||||
AWorksheet1, AWorksheet2: TsWorksheet; ACellRangeString: String);
|
|
||||||
var
|
|
||||||
r1, c1, r2, c2: Cardinal;
|
|
||||||
flags: TsRelFlags;
|
|
||||||
begin
|
|
||||||
if pos(':', ACellRangeString) = 0 then
|
|
||||||
begin
|
|
||||||
ParseCellString(ACellRangeString, r1, c1, flags);
|
|
||||||
if rfRelRow in flags then Include(flags, rfRelRow2);
|
|
||||||
if rfRelCol in flags then Include(flags, rfRelCol2);
|
|
||||||
Create(AParser, AWorksheet1, AWorksheet2, r1, c1, r1, c1, flags);
|
|
||||||
end else
|
|
||||||
begin
|
|
||||||
ParseCellRangeString(ACellRangeString, r1, c1, r2, c2, flags);
|
|
||||||
Create(AParser, AWorksheet1, AWorksheet2, r1, c1, r2, c2, flags);
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
|
|
||||||
constructor TsCellRangeExprNode.Create(AParser: TsExpressionParser;
|
|
||||||
AWorksheet1, AWorksheet2: TsWorksheet; ARow1,ACol1,ARow2,ACol2: Cardinal;
|
|
||||||
AFlags: TsRelFlags);
|
|
||||||
begin
|
|
||||||
FParser := AParser;
|
|
||||||
FWorksheet := AWorksheet1;
|
|
||||||
FWorksheet2 := AWorksheet2;
|
|
||||||
FRow[1] := ARow1;
|
|
||||||
FCol[1] := ACol1;
|
|
||||||
FRow[2] := ARow2;
|
|
||||||
FCol[2] := ACol2;
|
|
||||||
FFlags := AFlags;
|
|
||||||
FOnOtherSheet := true;
|
|
||||||
end;
|
|
||||||
*)
|
|
||||||
|
|
||||||
function TsCellRangeExprNode.AsRPNItem(ANext: PRPNItem): PRPNItem;
|
function TsCellRangeExprNode.AsRPNItem(ANext: PRPNItem): PRPNItem;
|
||||||
begin
|
begin
|
||||||
if F3dRange then
|
if F3dRange then
|
||||||
Result := RPNCellRange3D(
|
Result := RPNCellRange3D(
|
||||||
FSheet[1], GetRow(1), GetCol(1),
|
FSheet[1], GetRow(1), Integer(GetCol(1)),
|
||||||
FSheet[2], GetRow(2), GetCol(2),
|
FSheet[2], GetRow(2), Integer(GetCol(2)),
|
||||||
FFlags, ANext
|
FFlags, ANext
|
||||||
)
|
)
|
||||||
else
|
else
|
||||||
@ -3989,8 +4029,14 @@ var
|
|||||||
r1, c1, r2, c2: Cardinal;
|
r1, c1, r2, c2: Cardinal;
|
||||||
s1, s2: String;
|
s1, s2: String;
|
||||||
begin
|
begin
|
||||||
s1 := Workbook.GetWorksheetByIndex(FSheet[1]).Name;
|
if FSheet[1] = -1 then
|
||||||
s2 := Workbook.GetWorksheetByIndex(FSheet[2]).Name;
|
s1 := FWorksheet.Name
|
||||||
|
else
|
||||||
|
s1 := Workbook.GetWorksheetByIndex(FSheet[1]).Name;
|
||||||
|
if FSheet[2] = -1 then
|
||||||
|
s2 := FWorksheet.Name
|
||||||
|
else
|
||||||
|
s2 := Workbook.GetWorksheetByIndex(FSheet[2]).Name;
|
||||||
r1 := GetRow(1);
|
r1 := GetRow(1);
|
||||||
c1 := GetCol(1);
|
c1 := GetCol(1);
|
||||||
r2 := GetRow(2);
|
r2 := GetRow(2);
|
||||||
@ -4014,7 +4060,7 @@ begin
|
|||||||
Result := GetCellRangeString_R1C1(r1, c1, r2, c2, FFlags,
|
Result := GetCellRangeString_R1C1(r1, c1, r2, c2, FFlags,
|
||||||
FParser.FSourceCell^.Row, FParser.FSourceCell^.Col);
|
FParser.FSourceCell^.Row, FParser.FSourceCell^.Col);
|
||||||
fdOpenDocument:
|
fdOpenDocument:
|
||||||
Result := GetCellRangeString(r1, c1, r2, c2, FFlags, true);
|
Result := GetCellRangeString_ODS(r1, c1, r2, c2, FFlags, true);
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
@ -7565,8 +7565,8 @@ begin
|
|||||||
// Convert string formula to the format needed by ods: semicolon list separators!
|
// Convert string formula to the format needed by ods: semicolon list separators!
|
||||||
parser := TsSpreadsheetParser.Create(FWorksheet);
|
parser := TsSpreadsheetParser.Create(FWorksheet);
|
||||||
try
|
try
|
||||||
parser.Dialect := fdOpenDocument;
|
parser.Expression := ACell^.FormulaValue; // Formula still in Excel dialect
|
||||||
parser.Expression := ACell^.FormulaValue;
|
parser.Dialect := fdOpenDocument; // Now convert to ODS dialect
|
||||||
formula := Parser.LocalizedExpression[FPointSeparatorSettings];
|
formula := Parser.LocalizedExpression[FPointSeparatorSettings];
|
||||||
if (formula <> '') and (formula[1] <> '=') then
|
if (formula <> '') and (formula[1] <> '=') then
|
||||||
formula := '=' + formula;
|
formula := '=' + formula;
|
||||||
|
@ -104,6 +104,7 @@ resourcestring
|
|||||||
'of type %s: %s';
|
'of type %s: %s';
|
||||||
rsNoVariable = 'Identifier %s is not a variable';
|
rsNoVariable = 'Identifier %s is not a variable';
|
||||||
rsRightBracketExpected = 'Expected right bracket at position %d, but got %s';
|
rsRightBracketExpected = 'Expected right bracket at position %d, but got %s';
|
||||||
|
rsRightSquareBracketExpected = 'Expected right square bracket at positon %d, but got %s';
|
||||||
rsUnexpectedEndOfExpression = 'Unexpected end of expression';
|
rsUnexpectedEndOfExpression = 'Unexpected end of expression';
|
||||||
rsUnknownCharacter = 'Unknown character at pos %d: "%s"';
|
rsUnknownCharacter = 'Unknown character at pos %d: "%s"';
|
||||||
rsUnknownComparison = 'Internal error: Unknown comparison';
|
rsUnknownComparison = 'Internal error: Unknown comparison';
|
||||||
@ -112,6 +113,7 @@ resourcestring
|
|||||||
rsUnknownTokenAtPos = 'Unknown token at pos %d : %s';
|
rsUnknownTokenAtPos = 'Unknown token at pos %d : %s';
|
||||||
rsUnterminatedExpression = 'Badly terminated expression. Found token at '+
|
rsUnterminatedExpression = 'Badly terminated expression. Found token at '+
|
||||||
'position %d : %s';
|
'position %d : %s';
|
||||||
|
rsIllegalODSCellRange = 'Illegal structure of an OpenDocument cell range.';
|
||||||
|
|
||||||
{ -- currently not used:
|
{ -- currently not used:
|
||||||
SErrNoLeftOperand = 'No left operand for binary operation %s';
|
SErrNoLeftOperand = 'No left operand for binary operation %s';
|
||||||
|
@ -116,7 +116,7 @@ function GetCellRangeString_R1C1(ASheet1, ASheet2: String;
|
|||||||
function GetCellRangeString_ODS(ASheet1, ASheet2: String; ARow1, ACol1, ARow2, ACol2: Cardinal;
|
function GetCellRangeString_ODS(ASheet1, ASheet2: String; ARow1, ACol1, ARow2, ACol2: Cardinal;
|
||||||
AFlags: TsRelFlags = rfAllRel): String; overload;
|
AFlags: TsRelFlags = rfAllRel): String; overload;
|
||||||
function GetCellRangeString_ODS(ARow1, ACol1, ARow2, ACol2: Cardinal;
|
function GetCellRangeString_ODS(ARow1, ACol1, ARow2, ACol2: Cardinal;
|
||||||
AFlags: TsRelFlags = rfAllRel): String; overload;
|
AFlags: TsRelFlags = rfAllRel; Compact: Boolean = false): String; overload;
|
||||||
function GetCellRangeString_ODS(ARange: TsCellRange;
|
function GetCellRangeString_ODS(ARange: TsCellRange;
|
||||||
AFlags: TsRelFlags = rfAllRel; Compact: Boolean = false): String; overload;
|
AFlags: TsRelFlags = rfAllRel; Compact: Boolean = false): String; overload;
|
||||||
|
|
||||||
@ -1209,29 +1209,37 @@ begin
|
|||||||
if (ASheet1 = '') and (ASheet2 = '') then
|
if (ASheet1 = '') and (ASheet2 = '') then
|
||||||
begin
|
begin
|
||||||
if s1 = s2 then
|
if s1 = s2 then
|
||||||
Result := s1
|
Result := '[.' + s1 + ']' // --> [.A1]
|
||||||
else
|
else
|
||||||
Result := Format('%s:%s', [s1, s2])
|
Result := Format('[.%s:.%s]', [s1, s2]) // --> [.A1:.B3]
|
||||||
end else
|
end else
|
||||||
if (ASheet2 = '') or (ASheet1 = ASheet2) then begin
|
if (ASheet2 = '') or (ASheet1 = ASheet2) then begin
|
||||||
if s1 = s2 then
|
if s1 = s2 then
|
||||||
Result := Format('%s.%s', [ASheet1, s1])
|
Result := Format('[%s.%s]', [ASheet1, s1]) // [Sheet1.A1]
|
||||||
else
|
else
|
||||||
Result := Format('%s.%s:.%s', [ASheet1, s1, s2]); // Sheet1.A1:.B2
|
Result := Format('[%s.%s:.%s]', [ASheet1, s1, s2]); // [Sheet1.A1:.B2]
|
||||||
end else
|
end else
|
||||||
Result := Format('%s.%s:%s.%s', [ASheet1, s1, ASheet2, s2]); // Sheet.A1:Sheet2.B2
|
Result := Format('[%s.%s:%s.%s]', [ASheet1, s1, ASheet2, s2]); // [Sheet.A1:Sheet2.B2]
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function GetCellRangeString_ODS(ARow1, ACol1, ARow2, ACol2: Cardinal;
|
function GetCellRangeString_ODS(ARow1, ACol1, ARow2, ACol2: Cardinal;
|
||||||
AFlags: TsRelFlags = rfAllRel): String;
|
AFlags: TsRelFlags = rfAllRel; Compact: Boolean = false): String;
|
||||||
begin
|
begin
|
||||||
Result := GetCellRangeString(ARow1, ACol1, ARow2, ACol2, AFlags, true);
|
if Compact and (ARow1 = ARow2) and (ACol1 = ACol2) then
|
||||||
|
Result := Format('[.%s]', [GetCellString(ARow1, ACol1, AFlags)])
|
||||||
|
else
|
||||||
|
Result := Format('[.%s%s%s%d:.%s%s%s%d]', [
|
||||||
|
RELCHAR[rfRelCol in AFlags], GetColString(ACol1),
|
||||||
|
RELCHAR[rfRelRow in AFlags], ARow1 + 1,
|
||||||
|
RELCHAR[rfRelCol2 in AFlags], GetColString(ACol2),
|
||||||
|
RELCHAR[rfRelRow2 in AFlags], ARow2 + 1
|
||||||
|
]);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function GetCellRangeString_ODS(ARange: TsCellRange;
|
function GetCellRangeString_ODS(ARange: TsCellRange;
|
||||||
AFlags: TsRelFlags = rfAllRel; Compact: Boolean = false): String;
|
AFlags: TsRelFlags = rfAllRel; Compact: Boolean = false): String;
|
||||||
begin
|
begin
|
||||||
Result := GetCellRangeString(ARange, AFlags, true);
|
Result := GetCellRangeString_ODS(ARange, AFlags, true);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
@ -42,10 +42,12 @@ type
|
|||||||
procedure SumRange_BIFF5;
|
procedure SumRange_BIFF5;
|
||||||
procedure SumRange_BIFF8;
|
procedure SumRange_BIFF8;
|
||||||
procedure SumRange_OOXML;
|
procedure SumRange_OOXML;
|
||||||
|
procedure SumRange_ODS;
|
||||||
|
|
||||||
procedure SumSheetRange_BIFF5; // no 3d ranges for BIFF2
|
procedure SumSheetRange_BIFF5; // no 3d ranges for BIFF2
|
||||||
procedure SumSheetRange_BIFF8;
|
procedure SumSheetRange_BIFF8;
|
||||||
procedure SumSheetRange_OOXML;
|
procedure SumSheetRange_OOXML;
|
||||||
|
procedure SumSheetRange_ODS;
|
||||||
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -230,6 +232,11 @@ begin
|
|||||||
TestFloatFormula('SUM(C3:C5)', 0.5, ftkCellRange, sfOOXML);
|
TestFloatFormula('SUM(C3:C5)', 0.5, ftkCellRange, sfOOXML);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TSpreadSingleFormulaTests.SumRange_ODS;
|
||||||
|
begin
|
||||||
|
TestFloatFormula('SUM(C3:C5)', 0.5, ftkCellRange, sfOpenDocument);
|
||||||
|
end;
|
||||||
|
|
||||||
{ ---- }
|
{ ---- }
|
||||||
|
|
||||||
procedure TSpreadSingleFormulaTests.SumSheetRange_BIFF5;
|
procedure TSpreadSingleFormulaTests.SumSheetRange_BIFF5;
|
||||||
@ -247,6 +254,11 @@ begin
|
|||||||
TestFloatFormula('SUM(Sheet2!C3:C5)', 5.0, ftkCellRangeSheet, sfOOXML);
|
TestFloatFormula('SUM(Sheet2!C3:C5)', 5.0, ftkCellRangeSheet, sfOOXML);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TSpreadSingleFormulaTests.SumSheetRange_ODS;
|
||||||
|
begin
|
||||||
|
TestFloatFormula('SUM(Sheet2!C3:C5)', 5.0, ftkCellRangeSheet, sfOpenDocument);
|
||||||
|
end;
|
||||||
|
|
||||||
{ ---- }
|
{ ---- }
|
||||||
|
|
||||||
|
|
||||||
|
@ -180,7 +180,6 @@
|
|||||||
</Debugging>
|
</Debugging>
|
||||||
</Linking>
|
</Linking>
|
||||||
<Other>
|
<Other>
|
||||||
<CustomOptions Value="-dFormulaDebug"/>
|
|
||||||
<OtherDefines Count="1">
|
<OtherDefines Count="1">
|
||||||
<Define0 Value="FormulaDebug"/>
|
<Define0 Value="FormulaDebug"/>
|
||||||
</OtherDefines>
|
</OtherDefines>
|
||||||
|
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user