You've already forked lazarus-ccr
fpspreadsheet: Refactor dialects in formula parser.
git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@7067 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
@ -1551,8 +1551,8 @@ begin
|
||||
proc := @fixInsertedCol;
|
||||
|
||||
for formula in self do
|
||||
if formula^.Parser.IterateNodes(proc, Pointer(PtrInt(AIndex)), InSheet) then
|
||||
formula^.Text := formula^.Parser.Expression;
|
||||
if formula^.Parser.IterateNodes(proc, {%H-}Pointer(PtrInt(AIndex)), InSheet) then
|
||||
formula^.Text := formula^.Parser.Expression[fdExcelA1];
|
||||
end;
|
||||
|
||||
// Formula enumerators (use in "for ... in" syntax)
|
||||
|
@ -673,6 +673,7 @@ type
|
||||
end;
|
||||
|
||||
EExprScanner = class(Exception);
|
||||
PFormatSettings = ^TFormatSettings;
|
||||
|
||||
{ TsExpressionParser }
|
||||
TsExpressionParser = class
|
||||
@ -695,25 +696,27 @@ type
|
||||
function GetAsFloat: TsExprFloat;
|
||||
function GetAsInteger: Int64;
|
||||
function GetAsString: String;
|
||||
function GetDecimalSeparator: Char;
|
||||
function GetExpression(ADialect: TsFormulaDialect): String;
|
||||
function GetFormatSettings: TFormatSettings;
|
||||
function GetR1C1Expression(ACell: PCell): String;
|
||||
function GetRPNFormula: TsRPNFormula;
|
||||
procedure SetBuiltIns(const AValue: TsBuiltInExprCategories);
|
||||
procedure SetDialect(const AValue: TsFormulaDialect);
|
||||
procedure SetExpression(ADialect: TsFormulaDialect; const AValue: String);
|
||||
procedure SetIdentifiers(const AValue: TsExprIdentifierDefs);
|
||||
procedure SetR1C1Expression(ACell: PCell; const AValue: String);
|
||||
procedure SetRPNFormula(const AFormula: TsRPNFormula);
|
||||
|
||||
protected
|
||||
FFormatSettings: TFormatSettings;
|
||||
FFormatSettings: PFormatSettings;
|
||||
FContains3DRef: Boolean;
|
||||
class function BuiltinExpressionManager: TsBuiltInExpressionManager;
|
||||
function BuildStringFormula: String;
|
||||
procedure ParserError(Msg: String);
|
||||
function GetExpression: String;
|
||||
function GetLocalizedExpression(const AFormatSettings: TFormatSettings): String; virtual;
|
||||
function GetR1C1Expression(ACell: PCell): String;
|
||||
procedure SetExpression(const AValue: String);
|
||||
procedure SetLocalizedExpression(const AFormatSettings: TFormatSettings;
|
||||
const AValue: String); virtual;
|
||||
procedure SetR1C1Expression(ACell: PCell; const AValue: String);
|
||||
//function GetLocalizedExpression: String; virtual;
|
||||
procedure InternalSetExpression(ADialect: TsFormulaDialect; const AValue: String);
|
||||
// procedure SetLocalizedExpression(const AValue: String); virtual;
|
||||
procedure UpdateExprFormatSettings;
|
||||
|
||||
procedure CheckResultType(const Res: TsExpressionResult;
|
||||
@ -753,14 +756,22 @@ type
|
||||
property AsString: String read GetAsString;
|
||||
property AsBoolean: Boolean read GetAsBoolean;
|
||||
property AsDateTime: TDateTime read GetAsDateTime;
|
||||
|
||||
// The expression to parse
|
||||
property Expression: String read GetExpression write SetExpression;
|
||||
property ListSeparator: Char read FListSep;
|
||||
property LocalizedExpression[AFormatSettings: TFormatSettings]: String
|
||||
property Expression[ADialect: TsFormulaDialect]: String
|
||||
read GetExpression write SetExpression;
|
||||
{
|
||||
property LocalizedExpression: String
|
||||
read GetLocalizedExpression write SetLocalizedExpression;
|
||||
}
|
||||
property R1C1Expression[ACell: PCell]: String
|
||||
read GetR1C1Expression write SetR1C1Expression;
|
||||
property RPNFormula: TsRPNFormula read GetRPNFormula write SetRPNFormula;
|
||||
property RPNFormula: TsRPNFormula
|
||||
read GetRPNFormula write SetRPNFormula;
|
||||
|
||||
property DecimalSeparator: Char read GetDecimalSeparator;
|
||||
property ListSeparator: Char read FListSep;
|
||||
property FormatSettings: TFormatSettings read GetFormatSettings;
|
||||
property Identifiers: TsExprIdentifierDefs read FIdentifiers write SetIdentifiers;
|
||||
property BuiltIns: TsBuiltInExprCategories read FBuiltIns write SetBuiltIns;
|
||||
property Worksheet: TsBasicWorksheet read FWorksheet;
|
||||
@ -1197,7 +1208,7 @@ var
|
||||
begin
|
||||
C := CurrentChar;
|
||||
prevC := #0;
|
||||
while (not IsWordDelim(C) or (prevC = 'E') or (C = FParser.FFormatSettings.DecimalSeparator)) and (C <> cNull) do
|
||||
while (not IsWordDelim(C) or (prevC = 'E') or (C = FParser.DecimalSeparator)) and (C <> cNull) do
|
||||
begin
|
||||
if not ( IsDigit(C)
|
||||
or ((FToken <> '') and (Upcase(C) = 'E'))
|
||||
@ -1209,7 +1220,7 @@ begin
|
||||
prevC := Upcase(C);
|
||||
C := NextPos;
|
||||
end;
|
||||
if not TryStrToFloat(FToken, X, FParser.FFormatSettings) then
|
||||
if not TryStrToFloat(FToken, X, FParser.FFormatSettings^) then
|
||||
ScanError(Format(rsInvalidNumber, [FToken]));
|
||||
Result := ttNumber;
|
||||
end;
|
||||
@ -1382,7 +1393,7 @@ end;
|
||||
|
||||
function TsExpressionScanner.IsDigit(C: Char): Boolean;
|
||||
begin
|
||||
Result := (C in Digits) or (C = FParser.FFormatSettings.DecimalSeparator);
|
||||
Result := (C in Digits) or (C = FParser.DecimalSeparator);
|
||||
end;
|
||||
|
||||
function TsExpressionScanner.IsWordDelim(C: Char): Boolean;
|
||||
@ -1440,8 +1451,12 @@ begin
|
||||
FIdentifiers.FParser := Self;
|
||||
FScanner := TsExpressionScanner.Create(self);
|
||||
FHashList := TFPHashObjectList.Create(False);
|
||||
SetDialect(fdExcelA1);
|
||||
FFormatSettings := InitFormatSettings(TsWorksheet(FWorksheet).Workbook);
|
||||
|
||||
// Prepare for ExcelA1 dialect which is the default dialect. Can't call
|
||||
// SetDialect(fdExcelA1) because it exits immediately at default dialect.
|
||||
FDialect := fdExcelA1;
|
||||
FListSep := ',';
|
||||
FFormatSettings := @ExprFormatSettings;
|
||||
UpdateExprFormatSettings;
|
||||
end;
|
||||
|
||||
@ -1616,23 +1631,6 @@ begin
|
||||
Result := Res.ResString;
|
||||
end;
|
||||
|
||||
{ Returns the expression in R1C1 notation.
|
||||
ACell is the cell to which the expression is assumed to be relative. }
|
||||
function TsExpressionParser.GetR1C1Expression(ACell: PCell): String;
|
||||
var
|
||||
oldDialect: TsFormulaDialect;
|
||||
begin
|
||||
oldDialect := FDialect;
|
||||
try
|
||||
FDialect := fdExcelR1C1;
|
||||
PrepareCopyMode(ACell, ACell);
|
||||
Result := Expression;
|
||||
finally
|
||||
PrepareCopyMode(nil, nil);
|
||||
FDialect := oldDialect;
|
||||
end;
|
||||
end;
|
||||
|
||||
function TsExpressionParser.GetRPNFormula: TsRPNFormula;
|
||||
begin
|
||||
Result := CreateRPNFormula(FExprNode.AsRPNItem(nil), true);
|
||||
@ -1877,7 +1875,7 @@ begin
|
||||
if TryStrToInt64(CurrentToken, I) then
|
||||
Result := TsConstExprNode.CreateInteger(self, I)
|
||||
else
|
||||
if TryStrToFloat(CurrentToken, X, FFormatSettings) then
|
||||
if TryStrToFloat(CurrentToken, X, FFormatSettings^) then
|
||||
Result := TsConstExprNode.CreateFloat(self, X)
|
||||
else
|
||||
ParserError(Format(rsInvalidFloat, [CurrentToken]));
|
||||
@ -2007,19 +2005,61 @@ begin
|
||||
FDirty := true;
|
||||
end;
|
||||
|
||||
function TsExpressionParser.GetExpression: String;
|
||||
function TsExpressionParser.GetDecimalSeparator: Char;
|
||||
begin
|
||||
Result := BuildStringFormula; //(FFormatSettings);
|
||||
Result := FFormatSettings^.DecimalSeparator;
|
||||
end;
|
||||
|
||||
function TsExpressionParser.GetLocalizedExpression(const AFormatSettings: TFormatSettings): String;
|
||||
{ Builds an expression string for the currently loaded parser tree. The string
|
||||
is created for the specified formula dialect. The formula dialect used by
|
||||
the parser is restored afterwards. }
|
||||
function TsExpressionParser.GetExpression(ADialect: TsFormulaDialect): String;
|
||||
var
|
||||
oldDialect: TsFormulaDialect;
|
||||
begin
|
||||
// ExprFormatSettings := AFormatSettings;
|
||||
FFormatSettings := AFormatSettings;
|
||||
UpdateExprFormatSettings;
|
||||
Result := BuildStringFormula; //(AFormatSettings);
|
||||
if ADialect = fdExcelR1C1 then
|
||||
raise Exception.Create('Please use R1C1Expression');
|
||||
|
||||
oldDialect := FDialect;
|
||||
try
|
||||
SetDialect(ADialect);
|
||||
Result := BuildStringFormula;
|
||||
finally
|
||||
SetDialect(oldDialect);
|
||||
end;
|
||||
end;
|
||||
|
||||
function TsExpressionParser.GetFormatSettings: TFormatSettings;
|
||||
begin
|
||||
Result := FFormatSettings^;
|
||||
end;
|
||||
|
||||
{ Builds an expression string for the currently loaded parser tree. The string
|
||||
is created for Excel's R1C1 notation. ACell points to the cell to which cell
|
||||
references are relative. The formula dialect used by the parser is
|
||||
restored afterwards. }
|
||||
function TsExpressionParser.GetR1C1Expression(ACell: PCell): String;
|
||||
var
|
||||
oldDialect: TsFormulaDialect;
|
||||
begin
|
||||
oldDialect := FDialect;
|
||||
try
|
||||
SetDialect(fdExcelR1C1);
|
||||
PrepareCopyMode(ACell, ACell);
|
||||
Result := BuildStringFormula;
|
||||
finally
|
||||
PrepareCopyMode(nil, nil);
|
||||
SetDialect(oldDialect);
|
||||
end;
|
||||
end;
|
||||
|
||||
{
|
||||
function TsExpressionParser.GetLocalizedExpression: String;
|
||||
begin
|
||||
SetDialect(fdLocalized);
|
||||
Result := BuildStringFormula;
|
||||
end;
|
||||
}
|
||||
function TsExpressionParser.Has3DLinks: Boolean;
|
||||
begin
|
||||
Result := FExprNode.Has3DLink;
|
||||
@ -2034,42 +2074,73 @@ end;
|
||||
|
||||
procedure TsExpressionParser.SetDialect(const AValue: TsFormulaDialect);
|
||||
begin
|
||||
if FDialect = AValue then
|
||||
exit;
|
||||
|
||||
FDialect := AValue;
|
||||
case FDialect of
|
||||
fdExcelA1,
|
||||
fdExcelR1C1 : FListSep := ',';
|
||||
fdOpenDocument : FListSep := ';'
|
||||
fdExcelR1C1:
|
||||
begin
|
||||
FListSep := ',';
|
||||
FFormatSettings := @ExprFormatSettings;
|
||||
UpdateExprFormatSettings;
|
||||
end;
|
||||
fdOpenDocument:
|
||||
begin
|
||||
FListSep := ';';
|
||||
FFormatSettings := @ExprFormatSettings;
|
||||
UpdateExprFormatSettings;
|
||||
end;
|
||||
fdLocalized:
|
||||
begin
|
||||
FFormatSettings := @TsWorksheet(FWorksheet).Workbook.FormatSettings;
|
||||
FListSep := FFormatSettings^.ListSeparator;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TsExpressionParser.SetExpression(const AValue: String);
|
||||
begin
|
||||
SetLocalizedExpression(FFormatSettings, AValue);
|
||||
end;
|
||||
|
||||
procedure TsExpressionParser.SetLocalizedExpression(const AFormatSettings: TFormatSettings;
|
||||
procedure TsExpressionParser.InternalSetExpression(ADialect: TsFormulaDialect;
|
||||
const AValue: String);
|
||||
begin
|
||||
if FExpression = AValue then
|
||||
exit;
|
||||
FFormatSettings := AFormatSettings;
|
||||
UpdateExprFormatSettings;
|
||||
|
||||
FExpression := AValue;
|
||||
if (AValue <> '') and (AValue[1] = '=') then
|
||||
FScanner.Source := Copy(AValue, 2, Length(AValue))
|
||||
else
|
||||
FScanner.Source := AValue;
|
||||
Delete(FExpression, 1, 1);
|
||||
|
||||
SetDialect(ADialect);
|
||||
|
||||
FreeAndNil(FExprNode);
|
||||
if (FExpression <> '') then
|
||||
begin
|
||||
FScanner.Source := FExpression;
|
||||
if FExpression <> '' then begin
|
||||
GetToken;
|
||||
FExprNode := Level1;
|
||||
if (TokenType <> ttEOF) then
|
||||
ParserError(Format(rsUnterminatedExpression, [Scanner.Pos, CurrentToken]));
|
||||
if TokenType <> ttEOF then
|
||||
ParserError(Format(rsUnTerminatedExpression, [Scanner.Pos, CurrentToken]));
|
||||
FExprNode.Check;
|
||||
end;
|
||||
end;
|
||||
|
||||
{ Makes the parser analyze the given expression string. The expression string
|
||||
is assumed to be valid for the specified formula dialect. }
|
||||
procedure TsExpressionParser.SetExpression(ADialect: TsFormulaDialect;
|
||||
const AValue: String);
|
||||
begin
|
||||
if FDialect = fdExcelR1C1 then
|
||||
raise Exception.Create('Please use R1C1Expression');
|
||||
|
||||
InternalSetExpression(ADialect, AValue);
|
||||
end;
|
||||
(*
|
||||
{ Sets a localized Excel expression in A1 syntax. The format settings needed
|
||||
for localization are taken from the workbook. }
|
||||
procedure TsExpressionParser.SetLocalizedExpression(const AValue: String);
|
||||
begin
|
||||
InternalSetExpression(fdLocalized, AValue);
|
||||
end; *)
|
||||
|
||||
procedure TsExpressionParser.SetIdentifiers(const AValue: TsExprIdentifierDefs);
|
||||
begin
|
||||
FIdentifiers.Assign(AValue)
|
||||
@ -2078,16 +2149,11 @@ end;
|
||||
{ Parses an expression in which cell references are given in Excel's R1C1 notation
|
||||
ACell is the cell to which the created expression will be relative. }
|
||||
procedure TsExpressionParser.SetR1C1Expression(ACell: PCell; const AValue: String);
|
||||
var
|
||||
oldDialect: TsFormulaDialect;
|
||||
begin
|
||||
oldDialect := FDialect;
|
||||
PrepareCopyMode(ACell, ACell);
|
||||
try
|
||||
FDialect := fdExcelR1C1;
|
||||
PrepareCopyMode(ACell, ACell);
|
||||
Expression := AValue;
|
||||
InternalSetExpression(fdExcelR1C1, AValue);
|
||||
finally
|
||||
FDialect := oldDialect;
|
||||
PrepareCopyMode(nil, nil);
|
||||
end;
|
||||
end;
|
||||
@ -2554,7 +2620,7 @@ end;
|
||||
|
||||
function TsExprIdentifierDef.GetFormatSettings: TFormatSettings;
|
||||
begin
|
||||
Result := TsExprIdentifierDefs(Collection).Parser.FFormatSettings;
|
||||
Result := TsExprIdentifierDefs(Collection).Parser.FFormatSettings^;
|
||||
end;
|
||||
|
||||
function TsExprIdentifierDef.GetResultType: TsResultType;
|
||||
@ -3017,9 +3083,9 @@ begin
|
||||
case NodeType of
|
||||
rtString : Result := cDoubleQuote + FValue.ResString + cDoubleQuote;
|
||||
rtInteger : Result := IntToStr(FValue.ResInteger);
|
||||
rtDateTime : Result := '''' + FormatDateTime('cccc', FValue.ResDateTime, Parser.FFormatSettings) + ''''; // Probably wrong !!!
|
||||
rtDateTime : Result := '''' + FormatDateTime('cccc', FValue.ResDateTime, Parser.FFormatSettings^) + ''''; // Probably wrong !!!
|
||||
rtBoolean : if FValue.ResBoolean then Result := 'TRUE' else Result := 'FALSE';
|
||||
rtFloat : Result := FloatToStr(FValue.ResFloat, Parser.FFormatSettings);
|
||||
rtFloat : Result := FloatToStr(FValue.ResFloat, Parser.FFormatSettings^);
|
||||
rtError : Result := GetErrorValueStr(FValue.ResError);
|
||||
end;
|
||||
end;
|
||||
@ -4039,7 +4105,7 @@ begin
|
||||
c := GetCol;
|
||||
if Has3dLink then begin
|
||||
case FParser.Dialect of
|
||||
fdExcelA1:
|
||||
fdExcelA1, fdLocalized:
|
||||
Result := Format('%s!%s', [GetQuotedSheetName, GetCellString(r, c, FFlags)]);
|
||||
fdExcelR1C1:
|
||||
Result := Format('%s!%s', [GetQuotedSheetName,
|
||||
@ -4053,7 +4119,7 @@ begin
|
||||
end
|
||||
end else
|
||||
case FParser.Dialect of
|
||||
fdExcelA1:
|
||||
fdExcelA1, fdLocalized:
|
||||
Result := GetCellString(GetRow, GetCol, FFlags);
|
||||
fdExcelR1C1:
|
||||
Result := GetCellString_R1C1(GetRow, GetCol, FFlags, FParser.FSourceCell^.Row, FParser.FSourceCell^.Col);
|
||||
@ -4308,7 +4374,7 @@ begin
|
||||
|
||||
if F3dRange then
|
||||
case FParser.Dialect of
|
||||
fdExcelA1:
|
||||
fdExcelA1, fdLocalized:
|
||||
Result := GetCellRangeString(s1, s2, r1, c1, r2, c2, FFlags, true);
|
||||
fdExcelR1C1:
|
||||
Result := GetCellRangeString_R1C1(s1, s2, r1, c1, r2, c2, FFlags,
|
||||
@ -4322,7 +4388,7 @@ begin
|
||||
end
|
||||
else
|
||||
case FParser.Dialect of
|
||||
fdExcelA1:
|
||||
fdExcelA1, fdLocalized:
|
||||
Result := GetCellRangeString(r1, c1, r2, c2, FFlags, true);
|
||||
fdExcelR1C1:
|
||||
Result := GetCellRangeString_R1C1(r1, c1, r2, c2, FFlags,
|
||||
|
@ -2482,23 +2482,14 @@ begin
|
||||
Delete(formulaStr, 1, p);
|
||||
end;
|
||||
|
||||
// ... and store in cell's FormulaValue field.
|
||||
// ... and store in cell's FormulaValue field. Convert from ODS to ExcelA1 dialect.
|
||||
formula := TsWorksheet(FWorksheet).Formulas.AddFormula(ARow, ACol);
|
||||
formula^.Parser := TsSpreadsheetParser.Create(FWorksheet);
|
||||
formula^.Parser.Dialect := fdOpenDocument; // Parse in ODS dialect
|
||||
formula^.Parser.Expression := formulaStr;
|
||||
formula^.Parser.Dialect := fdExcelA1; // Convert formula to Excel A1 dialect
|
||||
formula^.Text := formula^.Parser.Expression;
|
||||
formula^.Parser.Expression[fdOpenDocument] := formulaStr; // Parse in ODS dialect
|
||||
formula^.Text := formula^.Parser.Expression[fdExcelA1]; // Convert to Excel A1 dialect
|
||||
cell^.Flags := cell^.Flags + [cfHasFormula];
|
||||
hasFormula := true;
|
||||
|
||||
{
|
||||
cell^.FormulaValue := formula;
|
||||
// Note: This formula is still in OpenDocument dialect. Conversion to
|
||||
// ExcelA1 dialect (used by fps) is postponed until all sheets have beeon
|
||||
// read (--> FixFormulas) because of possible references to other sheets
|
||||
// which might not have been loaded yet at this moment.
|
||||
}
|
||||
{$IFDEF FPSpreadDebug}
|
||||
DebugLn(' Formula found: ' + formula);
|
||||
{$ENDIF}
|
||||
@ -7834,30 +7825,18 @@ begin
|
||||
valueStr := '';
|
||||
if formula^.Parser = nil then begin
|
||||
formula^.Parser := TsSpreadsheetParser.Create(FWorksheet);
|
||||
formula^.Parser.Expression := formula^.Text;
|
||||
formula^.Parser.Expression[fdExcelA1] := formula^.Text; // the formula text is in ExcelA1 dialect
|
||||
end;
|
||||
// Convert string formula to the format needed by ods
|
||||
oldDialect := formula^.Parser.Dialect;
|
||||
try
|
||||
formula^.Parser.Dialect := fdOpenDocument;
|
||||
formulaStr := formula^.Parser.Expression; // Formula converted to ODS dialect
|
||||
formulaStr := formula^.Parser.Expression[fdOpenDocument]; // Formula converted to ODS dialect
|
||||
if (formulaStr <> '') and (formulastr[1] <> '=') then
|
||||
formulaStr := '=' + formulaStr;
|
||||
finally
|
||||
formula^.Parser.Dialect := oldDialect;
|
||||
end;
|
||||
{
|
||||
parser := TsSpreadsheetParser.Create(FWorksheet);
|
||||
try
|
||||
parser.Expression := ACell^.FormulaValue; // Formula still in Excel dialect
|
||||
parser.Dialect := fdOpenDocument; // Now convert to ODS dialect
|
||||
formula := Parser.LocalizedExpression[FPointSeparatorSettings];
|
||||
if (formula <> '') and (formula[1] <> '=') then
|
||||
formula := '=' + formula;
|
||||
finally
|
||||
parser.Free;
|
||||
end;
|
||||
}
|
||||
|
||||
case ACell^.ContentType of
|
||||
cctNumber:
|
||||
begin
|
||||
|
@ -1274,7 +1274,7 @@ begin
|
||||
if AFormula^.Parser = nil then begin
|
||||
parser := TsSpreadsheetParser.Create(self);
|
||||
try
|
||||
parser.Expression := AFormula^.Text;
|
||||
parser.Expression[fdExcelA1] := AFormula^.Text;
|
||||
AFormula^.Parser := parser;
|
||||
except
|
||||
on E:ECalcEngine do begin
|
||||
@ -1288,7 +1288,7 @@ begin
|
||||
try
|
||||
res := AFormula^.Parser.Evaluate;
|
||||
if AFormula^.Text = '' then
|
||||
AFormula^.Text := AFormula^.Parser.Expression;
|
||||
AFormula^.Text := AFormula^.Parser.Expression[fdExcelA1];
|
||||
except
|
||||
on E: ECalcEngine do
|
||||
begin
|
||||
@ -2049,7 +2049,7 @@ begin
|
||||
end;
|
||||
end;
|
||||
destFormula^.Parser.RPNFormula := rpn;
|
||||
destFormula^.Text := destFormula^.Parser.Expression;
|
||||
destFormula^.Text := destFormula^.Parser.Expression[fdExcelA1];
|
||||
UseFormulaInCell(AToCell, destFormula);
|
||||
finally
|
||||
srcFormula^.Parser.PrepareCopyMode(nil, nil);
|
||||
@ -2987,9 +2987,9 @@ begin
|
||||
if HasFormula(ACell) then begin
|
||||
formula := FFormulas.FindFormula(ACell^.Row, ACell^.Col);
|
||||
if ALocalized then
|
||||
Result := formula^.Parser.LocalizedExpression[Workbook.FormatSettings]
|
||||
Result := formula^.Parser.Expression[fdLocalized]
|
||||
else
|
||||
Result := formula^.Parser.Expression;
|
||||
Result := formula^.Parser.Expression[fdExcelA1];
|
||||
end;
|
||||
end;
|
||||
|
||||
@ -3029,7 +3029,6 @@ end;
|
||||
function TsWorksheet.ConvertFormulaDialect(ACell: PCell;
|
||||
ADialect: TsFormulaDialect): String;
|
||||
var
|
||||
oldDialect: TsFormulaDialect;
|
||||
formula: PsFormula;
|
||||
begin
|
||||
Result := '';
|
||||
@ -3037,17 +3036,10 @@ begin
|
||||
exit;
|
||||
|
||||
formula := FFormulas.FindFormula(ACell^.Row, ACell^.Col);
|
||||
oldDialect := formula^.Parser.Dialect;
|
||||
if oldDialect <> ADialect then begin
|
||||
try
|
||||
formula^.Parser.Dialect := ADialect;
|
||||
formula^.Parser.PrepareCopyMode(ACell, nil);
|
||||
Result := formula^.Parser.Expression;
|
||||
finally
|
||||
formula^.Parser.PrepareCopyMode(nil, nil);
|
||||
formula^.Parser.Dialect := oldDialect;
|
||||
end;
|
||||
end;
|
||||
if ADialect = fdExcelR1C1 then
|
||||
Result := formula^.Parser.R1C1Expression[ACell]
|
||||
else
|
||||
Result := formula^.Parser.Expression[ADialect];
|
||||
end;
|
||||
|
||||
{@@ ----------------------------------------------------------------------------
|
||||
@ -3066,7 +3058,7 @@ begin
|
||||
parser := TsSpreadsheetParser.Create(self);
|
||||
try
|
||||
parser.RPNFormula := AFormula;
|
||||
Result := parser.Expression;
|
||||
Result := parser.Expression[fdExcelA1];
|
||||
finally
|
||||
parser.Free;
|
||||
end;
|
||||
@ -3751,7 +3743,7 @@ begin
|
||||
Result := formula^.Text;
|
||||
|
||||
if (Result = '') and (formula^.Parser <> nil) then
|
||||
Result := formula^.Parser.Expression;
|
||||
Result := formula^.Parser.Expression[fdExcelA1];
|
||||
end;
|
||||
|
||||
{@@ ----------------------------------------------------------------------------
|
||||
@ -5913,13 +5905,14 @@ begin
|
||||
parser := TsSpreadsheetParser.Create(self);
|
||||
try
|
||||
if ALocalized then
|
||||
parser.LocalizedExpression[Workbook.FormatSettings] := AFormula
|
||||
parser.Expression[fdLocalized] := AFormula
|
||||
else
|
||||
if R1C1Mode then
|
||||
parser.R1C1Expression[ACell] := AFormula
|
||||
else
|
||||
parser.Expression := AFormula;
|
||||
AFormula := parser.Expression;
|
||||
parser.Expression[fdExcelA1] := AFormula;
|
||||
|
||||
AFormula := parser.Expression[fdExcelA1];
|
||||
|
||||
formula := FFormulas.AddFormula(ACell^.Row, ACell^.Col, AFormula);
|
||||
except
|
||||
@ -6201,7 +6194,7 @@ begin
|
||||
formula^.Parser := TsSpreadsheetParser.Create(self);
|
||||
end;
|
||||
formula^.Parser.RPNFormula := ARPNFormula;
|
||||
formula^.Text := formula^.Parser.Expression;
|
||||
formula^.Text := formula^.Parser.Expression[fdExcelA1];
|
||||
UseFormulaInCell(ACell, formula);
|
||||
ACell^.ContentType := cctFormula;
|
||||
|
||||
@ -8500,7 +8493,7 @@ var
|
||||
begin
|
||||
Unused(Arg);
|
||||
for formula in TsWorksheet(Data).Formulas do
|
||||
formula^.Text := formula^.Parser.Expression;
|
||||
formula^.Text := formula^.Parser.Expression[fdExcelA1];
|
||||
end;
|
||||
|
||||
|
||||
|
@ -229,7 +229,7 @@ type
|
||||
TsRPNFormula = array of TsFormulaElement;
|
||||
|
||||
{@@ Formula dialect }
|
||||
TsFormulaDialect = (fdExcelA1, fdExcelR1C1, fdOpenDocument);
|
||||
TsFormulaDialect = (fdExcelA1, fdExcelR1C1, fdOpenDocument, fdLocalized);
|
||||
|
||||
{@@ Describes the <b>type of content</b> in a cell of a TsWorksheet }
|
||||
TCellContentType = (cctEmpty, cctFormula, cctNumber, cctUTF8String,
|
||||
|
@ -3016,7 +3016,7 @@ begin
|
||||
formula^.Parser := TsSpreadsheetParser.Create(FWorksheet);
|
||||
end;
|
||||
formula^.Parser.RPNFormula := rpnFormula;
|
||||
formula^.Text := formula^.Parser.Expression;
|
||||
formula^.Text := formula^.Parser.Expression[fdExcelA1];
|
||||
TsWorksheet(FWorksheet).UseFormulaInCell(ACell, formula);
|
||||
{
|
||||
if formula^.Parser.Has3dLinks then
|
||||
|
@ -2266,6 +2266,8 @@ end;
|
||||
Checks valididty of the provided formula and creates a corresponding
|
||||
error message.
|
||||
|
||||
It is assumed that the formula is localized.
|
||||
|
||||
Returns TRUE if the provided string is a valid formula or no formula, FALSE
|
||||
otherwise. In the latter case an error message string is returned as well.
|
||||
-------------------------------------------------------------------------------}
|
||||
@ -2281,7 +2283,7 @@ begin
|
||||
parser := TsSpreadsheetParser.Create(Worksheet);
|
||||
try
|
||||
try
|
||||
parser.LocalizedExpression[Workbook.FormatSettings] := AFormula;
|
||||
parser.Expression[fdLocalized] := AFormula;
|
||||
except
|
||||
on E: Exception do begin
|
||||
AErrMsg := E.Message;
|
||||
|
@ -6200,9 +6200,11 @@ begin
|
||||
Result := GetTextRotation(ALeft, ATop);
|
||||
textrot := Result;
|
||||
for c := ALeft to ARight do
|
||||
for r := ATop to ABottom do begin
|
||||
for r := ATop to ABottom do
|
||||
begin
|
||||
Result := GetTextRotation(c, r);
|
||||
if Result <> textrot then begin
|
||||
if Result <> textrot then
|
||||
begin
|
||||
Result := trHorizontal;
|
||||
exit;
|
||||
end;
|
||||
@ -6212,7 +6214,8 @@ end;
|
||||
function TsCustomWorksheetGrid.GetWorkbookSource: TsWorkbookSource;
|
||||
begin
|
||||
if FWorkbookSource <> nil then
|
||||
Result := FWorkbookSource else
|
||||
Result := FWorkbookSource
|
||||
else
|
||||
Result := FInternalWorkbookSource;
|
||||
end;
|
||||
|
||||
@ -6221,7 +6224,8 @@ var
|
||||
cell: PCell;
|
||||
begin
|
||||
Result := vaDefault;
|
||||
if Assigned(Worksheet) then begin
|
||||
if Assigned(Worksheet) then
|
||||
begin
|
||||
cell := Worksheet.FindCell(GetWorksheetRow(ARow), GetWorksheetCol(ACol));
|
||||
Result := Worksheet.ReadVertAlignment(cell);
|
||||
end;
|
||||
@ -7089,7 +7093,7 @@ begin
|
||||
parser := TsSpreadsheetParser.Create(Worksheet);
|
||||
try
|
||||
try
|
||||
parser.LocalizedExpression[Worksheet.FormatSettings] := AExpression;
|
||||
parser.Expression[fdLocalized] := AExpression;
|
||||
except
|
||||
on E: Exception do begin
|
||||
AErrMsg := E.Message;
|
||||
|
Reference in New Issue
Block a user