You've already forked lazarus-ccr
fpspreadsheet: Quote sheet names if they contain illegal characters for the expression parser.
git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@6607 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
@ -61,7 +61,7 @@ type
|
|||||||
ttNumber, ttString, ttIdentifier, ttSpreadsheetAddress,
|
ttNumber, ttString, ttIdentifier, ttSpreadsheetAddress,
|
||||||
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,
|
||||||
ttListSep, ttTrue, ttFalse, ttMissingArg, ttError, ttEOF
|
ttListSep, ttQuote, ttTrue, ttFalse, ttMissingArg, ttError, ttEOF
|
||||||
);
|
);
|
||||||
|
|
||||||
TsExprFloat = Double;
|
TsExprFloat = Double;
|
||||||
@ -563,6 +563,7 @@ type
|
|||||||
function GetCol: Cardinal;
|
function GetCol: Cardinal;
|
||||||
function GetRow: Cardinal;
|
function GetRow: Cardinal;
|
||||||
procedure GetNodeValue(out AResult: TsExpressionResult); override;
|
procedure GetNodeValue(out AResult: TsExpressionResult); override;
|
||||||
|
function GetQuotedSheetName: String;
|
||||||
public
|
public
|
||||||
constructor Create(AParser: TsExpressionParser; AWorksheet: TsBasicWorksheet;
|
constructor Create(AParser: TsExpressionParser; AWorksheet: TsBasicWorksheet;
|
||||||
ASheetName: String; ARow, ACol: Cardinal; AFlags: TsRelFlags);
|
ASheetName: String; ARow, ACol: Cardinal; AFlags: TsRelFlags);
|
||||||
@ -1110,12 +1111,15 @@ function TsExpressionScanner.DoIdentifier: TsTokenType;
|
|||||||
var
|
var
|
||||||
C: Char;
|
C: Char;
|
||||||
S: String;
|
S: String;
|
||||||
|
isQuoted: Boolean;
|
||||||
begin
|
begin
|
||||||
C := CurrentChar;
|
C := CurrentChar;
|
||||||
while (not IsWordDelim(C)) and (C <> cNULL) do
|
isQuoted := C = '''';
|
||||||
|
while ((not IsWordDelim(C)) or IsQuoted) and (C <> cNULL) do
|
||||||
begin
|
begin
|
||||||
FToken := FToken + C;
|
FToken := FToken + C;
|
||||||
C := NextPos;
|
C := NextPos;
|
||||||
|
if C = '''' then isQuoted := false;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
if ParseCellRangeString(FToken, FSheet1, FSheet2,
|
if ParseCellRangeString(FToken, FSheet1, FSheet2,
|
||||||
@ -1311,7 +1315,7 @@ begin
|
|||||||
Result := DoNumber
|
Result := DoNumber
|
||||||
else if (C = cError) then
|
else if (C = cError) then
|
||||||
Result := DoError
|
Result := DoError
|
||||||
else if IsAlpha(C) or (C = '$') then
|
else if IsAlpha(C) or (C = '$') or (C = '''') then
|
||||||
Result := DoIdentifier
|
Result := DoIdentifier
|
||||||
else
|
else
|
||||||
ScanError(Format(rsUnknownCharacter, [FPos, C]));
|
ScanError(Format(rsUnknownCharacter, [FPos, C]));
|
||||||
@ -3922,17 +3926,17 @@ begin
|
|||||||
|
|
||||||
r := Getrow;
|
r := Getrow;
|
||||||
c := GetCol;
|
c := GetCol;
|
||||||
if Has3dLink then
|
if Has3dLink then begin
|
||||||
case FParser.Dialect of
|
case FParser.Dialect of
|
||||||
fdExcelA1:
|
fdExcelA1:
|
||||||
Result := Format('%s!%s', [GetSheetName, GetCellString(r, c, FFlags)]);
|
Result := Format('%s!%s', [GetQuotedSheetName, GetCellString(r, c, FFlags)]);
|
||||||
fdExcelR1C1:
|
fdExcelR1C1:
|
||||||
Result := Format('%s!%s', [GetSheetName,
|
Result := Format('%s!%s', [GetQuotedSheetName,
|
||||||
GetCellString_R1C1(r, c, FFlags, FParser.FSourceCell^.Row, FParser.FSourceCell^.Col)]);
|
GetCellString_R1C1(r, c, FFlags, FParser.FSourceCell^.Row, FParser.FSourceCell^.Col)]);
|
||||||
fdOpenDocument:
|
fdOpenDocument:
|
||||||
Result := Format('[%s.%s]', [GetSheetName, GetCellString(r, c, FFlags)]);
|
Result := Format('[%s.%s]', [GetQuotedSheetName, GetCellString(r, c, FFlags)]);
|
||||||
end
|
end
|
||||||
else
|
end else
|
||||||
case FParser.Dialect of
|
case FParser.Dialect of
|
||||||
fdExcelA1:
|
fdExcelA1:
|
||||||
Result := GetCellString(GetRow, GetCol, FFlags);
|
Result := GetCellString(GetRow, GetCol, FFlags);
|
||||||
@ -4002,6 +4006,12 @@ begin
|
|||||||
AResult.Worksheet := GetSheet;
|
AResult.Worksheet := GetSheet;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function TsCellExprNode.GetQuotedSheetName: String;
|
||||||
|
begin
|
||||||
|
Result := GetSheetName;
|
||||||
|
if SheetNameNeedsQuotes(Result) then
|
||||||
|
Result := QuotedStr(Result);
|
||||||
|
end;
|
||||||
|
|
||||||
{ See: GetCol }
|
{ See: GetCol }
|
||||||
function TsCellExprNode.GetRow: Cardinal;
|
function TsCellExprNode.GetRow: Cardinal;
|
||||||
@ -4168,10 +4178,14 @@ begin
|
|||||||
s1 := FWorksheet.Name
|
s1 := FWorksheet.Name
|
||||||
else
|
else
|
||||||
s1 := (Workbook as TsWorkbook).GetWorksheetByIndex(FSheetIndex[1]).Name;
|
s1 := (Workbook as TsWorkbook).GetWorksheetByIndex(FSheetIndex[1]).Name;
|
||||||
|
if SheetNameNeedsQuotes(s1) then s1 := QuotedStr(s1);
|
||||||
|
|
||||||
if FSheetIndex[2] = -1 then
|
if FSheetIndex[2] = -1 then
|
||||||
s2 := FWorksheet.Name
|
s2 := FWorksheet.Name
|
||||||
else
|
else
|
||||||
s2 := (Workbook as TsWorkbook).GetWorksheetByIndex(FSheetIndex[2]).Name;
|
s2 := (Workbook as TsWorkbook).GetWorksheetByIndex(FSheetIndex[2]).Name;
|
||||||
|
if SheetNameNeedsQuotes(s2) then s2 := QuotedStr(s2);
|
||||||
|
|
||||||
r1 := GetRow(1);
|
r1 := GetRow(1);
|
||||||
c1 := GetCol(1);
|
c1 := GetCol(1);
|
||||||
r2 := GetRow(2);
|
r2 := GetRow(2);
|
||||||
|
@ -112,7 +112,9 @@ function GetCellRangeString_R1C1(ASheet1, ASheet2: String;
|
|||||||
ARow1, ACol1, ARow2, ACol2: Cardinal; AFlags: TsRelFlags = [rfRelRow, rfRelCol];
|
ARow1, ACol1, ARow2, ACol2: Cardinal; AFlags: TsRelFlags = [rfRelRow, rfRelCol];
|
||||||
ARefRow: Cardinal = Cardinal(-1); ARefCol: Cardinal = Cardinal(-1)): String; overload;
|
ARefRow: Cardinal = Cardinal(-1); ARefCol: Cardinal = Cardinal(-1)): String; overload;
|
||||||
|
|
||||||
// OpenDocument Syntax
|
function SheetNameNeedsQuotes(ASheet: String): Boolean;
|
||||||
|
|
||||||
|
// OpenDocument Syntax
|
||||||
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;
|
||||||
@ -944,10 +946,10 @@ begin
|
|||||||
s2 := Copy(AStr, p+1, MaxInt);
|
s2 := Copy(AStr, p+1, MaxInt);
|
||||||
p := pos(':', s1);
|
p := pos(':', s1);
|
||||||
if p = 0 then
|
if p = 0 then
|
||||||
ASheet1 := s1
|
ASheet1 := UnquoteStr(s1)
|
||||||
else begin
|
else begin
|
||||||
ASheet1 := copy(s1, 1, p-1);
|
ASheet1 := UnquoteStr(copy(s1, 1, p-1));
|
||||||
ASheet2 := copy(s1, p+1, MaxInt);
|
ASheet2 := UnquoteStr(copy(s1, p+1, MaxInt));
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -1162,20 +1164,32 @@ begin
|
|||||||
]);
|
]);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function SheetNameNeedsQuotes(ASheet: String): Boolean;
|
||||||
|
begin
|
||||||
|
if ASheet <> '' then begin
|
||||||
|
Result := true;
|
||||||
|
if (ASheet[1] in ['0'..'9', '.']) then exit;
|
||||||
|
if (pos(' ', ASheet) > 0) then exit;
|
||||||
|
end;
|
||||||
|
Result := false;
|
||||||
|
end;
|
||||||
|
|
||||||
function GetCellRangeString(ASheet1, ASheet2: String; ARow1, ACol1, ARow2, ACol2: Cardinal;
|
function GetCellRangeString(ASheet1, ASheet2: String; ARow1, ACol1, ARow2, ACol2: Cardinal;
|
||||||
AFlags: TsRelFlags = rfAllRel; Compact: Boolean = false): String;
|
AFlags: TsRelFlags = rfAllRel; Compact: Boolean = false): String;
|
||||||
var
|
|
||||||
s: String;
|
|
||||||
begin
|
begin
|
||||||
s := GetCellRangeString(ARow1, ACol1, ARow2, ACol2, AFlags, Compact);
|
Result := GetCellRangeString(ARow1, ACol1, ARow2, ACol2, AFlags, Compact);
|
||||||
if (ASheet1 = '') and (ASheet2 = '') then
|
if (ASheet1 = '') and (ASheet2 = '') then
|
||||||
Result := s
|
exit;
|
||||||
else if ASheet2 = '' then
|
|
||||||
Result := Format('%s!%s', [ASheet1, s])
|
if SheetNameNeedsQuotes(ASheet1) then ASheet1 := QuotedStr(ASheet1);
|
||||||
|
if SheetNameNeedsQuotes(ASheet2) then ASheet2 := QuotedStr(ASheet2);
|
||||||
|
|
||||||
|
if ASheet2 = '' then
|
||||||
|
Result := Format('%s!%s', [ASheet1, Result])
|
||||||
else if Compact and (ASheet1 = ASheet2) then
|
else if Compact and (ASheet1 = ASheet2) then
|
||||||
Result := Format('%s!%s', [ASheet1, s])
|
Result := Format('%s!%s', [ASheet1, Result])
|
||||||
else
|
else
|
||||||
Result := Format('%s:%s!%s', [ASheet1, ASheet2, s]);
|
Result := Format('%s:%s!%s', [ASheet1, ASheet2, Result]);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user