diff --git a/components/fpspreadsheet/source/common/fpsclasses.pas b/components/fpspreadsheet/source/common/fpsclasses.pas index 5feb28f04..567ca642c 100644 --- a/components/fpspreadsheet/source/common/fpsclasses.pas +++ b/components/fpspreadsheet/source/common/fpsclasses.pas @@ -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) diff --git a/components/fpspreadsheet/source/common/fpsexprparser.pas b/components/fpspreadsheet/source/common/fpsexprparser.pas index a2b5b489a..10a99c72c 100644 --- a/components/fpspreadsheet/source/common/fpsexprparser.pas +++ b/components/fpspreadsheet/source/common/fpsexprparser.pas @@ -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, diff --git a/components/fpspreadsheet/source/common/fpsopendocument.pas b/components/fpspreadsheet/source/common/fpsopendocument.pas index 596d6647b..eb23b4387 100644 --- a/components/fpspreadsheet/source/common/fpsopendocument.pas +++ b/components/fpspreadsheet/source/common/fpsopendocument.pas @@ -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 diff --git a/components/fpspreadsheet/source/common/fpspreadsheet.pas b/components/fpspreadsheet/source/common/fpspreadsheet.pas index d76ae4164..91b95c873 100644 --- a/components/fpspreadsheet/source/common/fpspreadsheet.pas +++ b/components/fpspreadsheet/source/common/fpspreadsheet.pas @@ -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; diff --git a/components/fpspreadsheet/source/common/fpstypes.pas b/components/fpspreadsheet/source/common/fpstypes.pas index db4c0f4f5..85b9f1a9a 100644 --- a/components/fpspreadsheet/source/common/fpstypes.pas +++ b/components/fpspreadsheet/source/common/fpstypes.pas @@ -229,7 +229,7 @@ type TsRPNFormula = array of TsFormulaElement; {@@ Formula dialect } - TsFormulaDialect = (fdExcelA1, fdExcelR1C1, fdOpenDocument); + TsFormulaDialect = (fdExcelA1, fdExcelR1C1, fdOpenDocument, fdLocalized); {@@ Describes the type of content in a cell of a TsWorksheet } TCellContentType = (cctEmpty, cctFormula, cctNumber, cctUTF8String, diff --git a/components/fpspreadsheet/source/common/xlscommon.pas b/components/fpspreadsheet/source/common/xlscommon.pas index 484f67f50..97e353753 100644 --- a/components/fpspreadsheet/source/common/xlscommon.pas +++ b/components/fpspreadsheet/source/common/xlscommon.pas @@ -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 diff --git a/components/fpspreadsheet/source/visual/fpspreadsheetctrls.pas b/components/fpspreadsheet/source/visual/fpspreadsheetctrls.pas index 84dad2c65..d950564a1 100644 --- a/components/fpspreadsheet/source/visual/fpspreadsheetctrls.pas +++ b/components/fpspreadsheet/source/visual/fpspreadsheetctrls.pas @@ -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; diff --git a/components/fpspreadsheet/source/visual/fpspreadsheetgrid.pas b/components/fpspreadsheet/source/visual/fpspreadsheetgrid.pas index 13bf667ef..27ea1e369 100644 --- a/components/fpspreadsheet/source/visual/fpspreadsheetgrid.pas +++ b/components/fpspreadsheet/source/visual/fpspreadsheetgrid.pas @@ -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;