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,
|
||||
ttPlus, ttMinus, ttMul, ttDiv, ttConcat, ttPercent, ttPower, ttLeft, ttRight,
|
||||
ttLessThan, ttLargerThan, ttEqual, ttNotEqual, ttLessThanEqual, ttLargerThanEqual,
|
||||
ttListSep, ttTrue, ttFalse, ttMissingArg, ttError, ttEOF
|
||||
ttListSep, ttQuote, ttTrue, ttFalse, ttMissingArg, ttError, ttEOF
|
||||
);
|
||||
|
||||
TsExprFloat = Double;
|
||||
@ -563,6 +563,7 @@ type
|
||||
function GetCol: Cardinal;
|
||||
function GetRow: Cardinal;
|
||||
procedure GetNodeValue(out AResult: TsExpressionResult); override;
|
||||
function GetQuotedSheetName: String;
|
||||
public
|
||||
constructor Create(AParser: TsExpressionParser; AWorksheet: TsBasicWorksheet;
|
||||
ASheetName: String; ARow, ACol: Cardinal; AFlags: TsRelFlags);
|
||||
@ -1110,12 +1111,15 @@ function TsExpressionScanner.DoIdentifier: TsTokenType;
|
||||
var
|
||||
C: Char;
|
||||
S: String;
|
||||
isQuoted: Boolean;
|
||||
begin
|
||||
C := CurrentChar;
|
||||
while (not IsWordDelim(C)) and (C <> cNULL) do
|
||||
isQuoted := C = '''';
|
||||
while ((not IsWordDelim(C)) or IsQuoted) and (C <> cNULL) do
|
||||
begin
|
||||
FToken := FToken + C;
|
||||
C := NextPos;
|
||||
if C = '''' then isQuoted := false;
|
||||
end;
|
||||
|
||||
if ParseCellRangeString(FToken, FSheet1, FSheet2,
|
||||
@ -1311,7 +1315,7 @@ begin
|
||||
Result := DoNumber
|
||||
else if (C = cError) then
|
||||
Result := DoError
|
||||
else if IsAlpha(C) or (C = '$') then
|
||||
else if IsAlpha(C) or (C = '$') or (C = '''') then
|
||||
Result := DoIdentifier
|
||||
else
|
||||
ScanError(Format(rsUnknownCharacter, [FPos, C]));
|
||||
@ -3922,17 +3926,17 @@ begin
|
||||
|
||||
r := Getrow;
|
||||
c := GetCol;
|
||||
if Has3dLink then
|
||||
if Has3dLink then begin
|
||||
case FParser.Dialect of
|
||||
fdExcelA1:
|
||||
Result := Format('%s!%s', [GetSheetName, GetCellString(r, c, FFlags)]);
|
||||
Result := Format('%s!%s', [GetQuotedSheetName, GetCellString(r, c, FFlags)]);
|
||||
fdExcelR1C1:
|
||||
Result := Format('%s!%s', [GetSheetName,
|
||||
Result := Format('%s!%s', [GetQuotedSheetName,
|
||||
GetCellString_R1C1(r, c, FFlags, FParser.FSourceCell^.Row, FParser.FSourceCell^.Col)]);
|
||||
fdOpenDocument:
|
||||
Result := Format('[%s.%s]', [GetSheetName, GetCellString(r, c, FFlags)]);
|
||||
Result := Format('[%s.%s]', [GetQuotedSheetName, GetCellString(r, c, FFlags)]);
|
||||
end
|
||||
else
|
||||
end else
|
||||
case FParser.Dialect of
|
||||
fdExcelA1:
|
||||
Result := GetCellString(GetRow, GetCol, FFlags);
|
||||
@ -4002,6 +4006,12 @@ begin
|
||||
AResult.Worksheet := GetSheet;
|
||||
end;
|
||||
|
||||
function TsCellExprNode.GetQuotedSheetName: String;
|
||||
begin
|
||||
Result := GetSheetName;
|
||||
if SheetNameNeedsQuotes(Result) then
|
||||
Result := QuotedStr(Result);
|
||||
end;
|
||||
|
||||
{ See: GetCol }
|
||||
function TsCellExprNode.GetRow: Cardinal;
|
||||
@ -4168,10 +4178,14 @@ begin
|
||||
s1 := FWorksheet.Name
|
||||
else
|
||||
s1 := (Workbook as TsWorkbook).GetWorksheetByIndex(FSheetIndex[1]).Name;
|
||||
if SheetNameNeedsQuotes(s1) then s1 := QuotedStr(s1);
|
||||
|
||||
if FSheetIndex[2] = -1 then
|
||||
s2 := FWorksheet.Name
|
||||
else
|
||||
s2 := (Workbook as TsWorkbook).GetWorksheetByIndex(FSheetIndex[2]).Name;
|
||||
if SheetNameNeedsQuotes(s2) then s2 := QuotedStr(s2);
|
||||
|
||||
r1 := GetRow(1);
|
||||
c1 := GetCol(1);
|
||||
r2 := GetRow(2);
|
||||
|
@ -112,7 +112,9 @@ function GetCellRangeString_R1C1(ASheet1, ASheet2: String;
|
||||
ARow1, ACol1, ARow2, ACol2: Cardinal; AFlags: TsRelFlags = [rfRelRow, rfRelCol];
|
||||
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;
|
||||
AFlags: TsRelFlags = rfAllRel): String; overload;
|
||||
function GetCellRangeString_ODS(ARow1, ACol1, ARow2, ACol2: Cardinal;
|
||||
@ -944,10 +946,10 @@ begin
|
||||
s2 := Copy(AStr, p+1, MaxInt);
|
||||
p := pos(':', s1);
|
||||
if p = 0 then
|
||||
ASheet1 := s1
|
||||
ASheet1 := UnquoteStr(s1)
|
||||
else begin
|
||||
ASheet1 := copy(s1, 1, p-1);
|
||||
ASheet2 := copy(s1, p+1, MaxInt);
|
||||
ASheet1 := UnquoteStr(copy(s1, 1, p-1));
|
||||
ASheet2 := UnquoteStr(copy(s1, p+1, MaxInt));
|
||||
end;
|
||||
end;
|
||||
|
||||
@ -1162,20 +1164,32 @@ begin
|
||||
]);
|
||||
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;
|
||||
AFlags: TsRelFlags = rfAllRel; Compact: Boolean = false): String;
|
||||
var
|
||||
s: String;
|
||||
begin
|
||||
s := GetCellRangeString(ARow1, ACol1, ARow2, ACol2, AFlags, Compact);
|
||||
Result := GetCellRangeString(ARow1, ACol1, ARow2, ACol2, AFlags, Compact);
|
||||
if (ASheet1 = '') and (ASheet2 = '') then
|
||||
Result := s
|
||||
else if ASheet2 = '' then
|
||||
Result := Format('%s!%s', [ASheet1, s])
|
||||
exit;
|
||||
|
||||
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
|
||||
Result := Format('%s!%s', [ASheet1, s])
|
||||
Result := Format('%s!%s', [ASheet1, Result])
|
||||
else
|
||||
Result := Format('%s:%s!%s', [ASheet1, ASheet2, s]);
|
||||
Result := Format('%s:%s!%s', [ASheet1, ASheet2, Result]);
|
||||
end;
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user