internal static string AsString(TParsedTokenList Tokens, int CellRow, int CellCol, ICellList CellList, TWorkbookGlobals Globals, int MaxStringConstantLen, bool WritingXlsx, bool SkipEqual) { string StartFormula = fts(TFormulaToken.fmStartFormula); //Formulas do not always begin with "=". Array formulas begin with "{", and they override this var to empty. TFormulaStack ParsedStack = new TFormulaStack(); bool R1C1 = false; if (Globals != null && !WritingXlsx) { R1C1 = Globals.Workbook.FormulaReferenceStyle == TReferenceStyle.R1C1; } Tokens.ResetPositionToStart(); while (!Tokens.Eof()) { TBaseParsedToken Token = Tokens.ForwardPop(); ptg BaseToken = Token.GetBaseId; Evaluate(Token, R1C1, CellRow, CellCol, BaseToken, Tokens, CellList, Globals, ParsedStack, ref StartFormula, MaxStringConstantLen, WritingXlsx); } //while if (WritingXlsx || SkipEqual) { StartFormula = String.Empty; } if (ParsedStack.Count == 0) { return(String.Empty); //StartFormula + TFormulaMessages.ErrString(TFlxFormulaErrorValue.ErrRef); This is needed for deleted named ranges. } return(StartFormula + ParsedStack.Pop()); }
public virtual void Parse() { LastRefOp = -1; FHasErrors = false; FParsedDataBuilder = new TParsedTokenListBuilder(); try { Go(); FParsedData = FParsedDataBuilder.ToParsedTokenList(); FParsedData.TextLenght = FormulaText.Length; } finally { FParsedDataBuilder = null; } //Try to decode what we encoded //something like "= >" will be encoded nicely, but will crash when decoded /*try * { * FParsedData.ResetPositionToLast(); * FParsedData.Flush(); * if (!FParsedData.Bof())FlxMessages.ThrowException(FlxErr.ErrFormulaInvalid, FormulaText); * } * catch (Exception) * { * FlxMessages.ThrowException(FlxErr.ErrFormulaInvalid,FormulaText); * }*/ }
/// <summary> /// FmlaWithoutArrayLen might be less than the total array len /// </summary> internal static byte[] GetTokenData(TNameRecordList Names, TParsedTokenList Tokens, TFormulaType FmlaType, out int FmlaLenWithoutArray) { // Remember to ungrow maxrow and maxcol from 2007 too biff8 // Tokens that grow are ptgref, area, 3dref and 3darea. All of them (and nothing else) should ungrow. using (MemoryStream Data = new MemoryStream()) { using (MemoryStream ArrayData = new MemoryStream()) { int[] TokenOffset = new int[Tokens.Count + 1]; TTokenOffset StreamPos = new TTokenOffset(); Int32List FuturePos = new Int32List(); Tokens.ResetPositionToStart(); while (!Tokens.Eof()) { TBaseParsedToken Token = Tokens.ForwardPop(); TokenOffset[Tokens.SavePosition()] = (int)Data.Position; ptg BaseToken = Token.GetBaseId; Add(Data, ArrayData, Token, BaseToken, Tokens, StreamPos, FmlaType, FuturePos); } //while TokenOffset[Tokens.Count] = (int)Data.Position; FixFutureFunctions(Names, FuturePos, Tokens, Data, TokenOffset, ref StreamPos); FixGotoAndMemTokens(Tokens, Data, TokenOffset, StreamPos); ArrayData.Position = 0; Data.Position = Data.Length; //FixGoto will change this. FmlaLenWithoutArray = (int)Data.Length; ArrayData.WriteTo(Data); return(Data.ToArray()); } } }
internal TSharedFormula(TNameRecordList Names, UInt64 aKey, byte[] aData, int start, int len) { Key = aKey; TFormulaConvertBiff8ToInternal p = new TFormulaConvertBiff8ToInternal(); Data = p.ParseRPN(Names, -1, -1, aData, start, len, true); //no real need for relative since shared formulas can't be 3d, and we only need relative for the non-existing tokens ptgarea3dn and ptgref3dn. }
internal override object Evaluate(TParsedTokenList FTokenList, TWorkbookInfo wi, TBaseAggregate f, TCalcState STotal, TCalcStack CalcStack) { TValueAndXF val = new TValueAndXF(); val.FullDataSetColumnIndex = wi.FullDataSetIndex; val.Workbook = wi.Xls; val.DebugStack = wi.DebugStack; Data.Evaluate(wi.Row, wi.Col, wi.RowOfs, wi.ColOfs, val); return(ConvertToAllowedObject(val.Value)); }
internal static string AsString(TParsedTokenList Tokens, int CellRow, int CellCol, ICellList CellList) { TWorkbookGlobals Globals = null; if (CellList != null) { Globals = CellList.Globals; } return(AsString(Tokens, CellRow, CellCol, CellList, Globals, -1, false)); }
internal static int TotalSizeWithArray(TParsedTokenList Data, TFormulaType FmlaType) { if (Data.TextLenght > FlxConsts.Max_FormulaLen97_2003) { FlxMessages.ThrowException(FlxErr.ErrFormulaTooLong, TFormulaConvertInternalToText.AsString(Data, 0, 0, null)); } int DataLenNoArray; byte[] bData = TFormulaConvertInternalToBiff8.GetTokenData(null, Data, FmlaType, out DataLenNoArray); return(bData.Length); }
internal TRPNExpression(string Condition, ExcelFile Xls, TBand CurrentBand, FlexCelReport fr, TStackData Stack) { if (Condition != null && !Condition.StartsWith(TFormulaMessages.TokenString(TFormulaToken.fmStartFormula))) { Condition = TFormulaMessages.TokenString(TFormulaToken.fmStartFormula) + Condition; } TFormulaConvertTextWithTagsToInternal Parser = new TFormulaConvertTextWithTagsToInternal(Xls, Condition, CurrentBand, fr, Stack); wi = new TWorkbookInfo(Xls, Xls.ActiveSheet, 0, 0, 0, 0, 0, 0, false); Parser.Parse(); Fmla = Parser.GetTokens(); }
private static bool BackFromFutureToUserDef(Stream Data, TParsedTokenList Tokens, Int32List FuturePos, TBaseFunctionToken ft, TCellFunctionData fd) { string FutureName = fd.FutureName; if (FutureName != null) { Data.WriteByte((byte)(ft.ArgumentCount + 1)); WriteWord(Data, 0xFF); //User def... FuturePos.Add(Tokens.SavePosition()); return(true); } return(false); }
static TToken[] Convert(TParsedTokenList Tokens) { TToken[] Result = new TToken[Tokens.Count]; Tokens.ResetPositionToStart(); int i = 0; while (!Tokens.Eof()) { TBaseParsedToken tk = Tokens.ForwardPop(); Result[i] = GetPublicToken(tk); i++; } return(Result); }
internal static void ArrangeSharedFormulas(TParsedTokenList Data, int Row, int Col, bool FromBiff8) { Data.ResetPositionToLast(); while (!Data.Bof()) { TBaseParsedToken r = Data.LightPop(); switch (r.GetBaseId) { case ptg.RefN: case ptg.AreaN: Data.UnShare(Row, Col, FromBiff8); break; } } }
private void CheckFutureFunction(TParsedTokenListBuilder TokenBuilder, ref int np, TNameRecordList Names, ref TCellFunctionData fd2, TTokenOffset TokenOffset, ref bool HasAggregate) { //We need to recursively read parameters in back order to find out the name, which is stored as far as possible from the function :( TParsedTokenList ParsedList = TokenBuilder.ToParsedTokenList(); ParsedList.ResetPositionToLast(); for (int i = 0; i < np; i++) //np is +1. But we will move below the name, then inc 1, so we know there isn't a "neutral" token like parent or memarea, intead of the real thing. { ParsedList.Flush(); } ParsedList.MoveBack(); TNameToken bp = ParsedList.ForwardPop() as TNameToken; if (bp is TNameXToken) { return; //This name isn't an internal 2007 name. } if (bp == null) { return; } if (bp.NameIndex <= 0 || bp.NameIndex > Names.Count) { return; } string FunctionName = Names[bp.NameIndex - 1].Name; if (FunctionName.StartsWith("_xlfn.", StringComparison.InvariantCultureIgnoreCase)) { TCellFunctionData fn = TXlsFunction.GetData(FunctionName.Substring("_xlfn.".Length)); if (fn != null) { if (fn.Index == (int)TFutureFunctions.Aggregate) { HasAggregate = true; } fd2 = fn; int tPos = ParsedList.SavePosition(); TokenBuilder.RemoveAt(tPos); TokenOffset.RemoveToken(tPos); np--; } } }
internal static bool HasExternRefs(TParsedTokenList Data) { Data.ResetPositionToLast(); while (!Data.Bof()) { TBaseParsedToken r = Data.LightPop(); ptg id = r.GetBaseId; // This check is a little simplistic because an Area3d or Ref3d might in fact refer to the same sheet. But then, the externsheet is not copied so // the reference will be invalid anyway. The "right" thing to do would be to convert external refs to the same sheet to external refs on the new sheet. if (id == ptg.Area3d || id == ptg.Ref3d || id == ptg.NameX) { return(true); } } return(false); }
internal static void UpdateDeletedRanges(TParsedTokenList Data, TDeletedRanges DeletedRanges) { Data.ResetPositionToLast(); while (!Data.Bof()) { TBaseParsedToken tk = Data.LightPop(); TBaseFunctionToken ft = tk as TBaseFunctionToken; if (ft != null) { //we need to ensure we don't delete the used _xlfn. ranges. Used def fn don't need to check, because they use the name in the tokenlist. if (ft.GetFunctionData().FutureInXls) { int NameId = DeletedRanges.Names.GetNamePos(-1, ft.GetFunctionData().FutureName); if (NameId >= 0) { DeletedRanges.Reference(NameId); //No need for recursion here, this name can't use anything else. Also, we don't need to update refs to this range. } } continue; } TNameToken r = tk as TNameToken; //this includes namex if (r == null) { continue; } if (r.GetBaseId == ptg.NameX && !DeletedRanges.References.IsLocalSheet(r.ExternSheet)) { return; //This name does not point to a name in the NAME table. } if (DeletedRanges.Update) { UpdateRange(r, DeletedRanges); } else { FindReferences(r, DeletedRanges); } } }
private static void FixGotoAndMemTokens(TParsedTokenList Tokens, MemoryStream Data, int[] TokenOffset, TTokenOffset StreamPos) { foreach (int streamofs in StreamPos.Keys) { TBaseParsedToken Token = Tokens.GetToken(StreamPos[streamofs]); Data.Position = streamofs; TAttrOptIfToken oiftk = Token as TAttrOptIfToken; if (oiftk != null) { WriteWord(Data, TokenOffset[oiftk.PositionOfNextPtg] - (streamofs + 2)); continue; } TAttrOptChooseToken ctk = Token as TAttrOptChooseToken; if (ctk != null) { for (int i = 0; i < ctk.PositionOfNextPtg.Length; i++) { WriteWord(Data, TokenOffset[ctk.PositionOfNextPtg[i]] - streamofs); } continue; } TAttrGotoToken gtk = Token as TAttrGotoToken; if (gtk != null) { WriteWord(Data, TokenOffset[gtk.PositionOfNextPtg] - (streamofs + 2) - 1); continue; } TSimpleMemToken memtk = Token as TSimpleMemToken; if (memtk != null) { WriteWord(Data, TokenOffset[memtk.PositionOfNextPtg] - (streamofs + 2)); continue; } } }
internal static bool HasExternLinks(TParsedTokenList Data, TReferences References) { Data.ResetPositionToLast(); while (!Data.Bof()) { TBaseParsedToken r = Data.LightPop(); ptg id = r.GetBaseId; if (id == ptg.Area3d || id == ptg.Ref3d || id == ptg.NameX) { if (References != null) { int ExternSheet = r.ExternSheet; if (!References.IsLocalSheet(ExternSheet)) { return(true); } } } } return(false); }
private static void Add(Stream Data, Stream ArrayData, TBaseParsedToken Token, ptg BaseToken, TParsedTokenList Tokens, TTokenOffset StreamPos, TFormulaType FmlaType, Int32List FuturePos) { if (IsError(BaseToken, FmlaType)) { Data.WriteByte(0x1C); //PtgErr Data.WriteByte(0x2A); return; } Data.WriteByte((byte)Token.GetId); switch (BaseToken) { case ptg.Exp: TExp_Token exp = (TExp_Token)Token; Biff8Utils.CheckRow(exp.Row); Biff8Utils.CheckCol(exp.Col); WriteWord(Data, exp.Row); WriteWord(Data, exp.Col); break; case ptg.Tbl: TTableObjToken tblo = Token as TTableObjToken; if (tblo != null) { //no biff8 checks here. This numbers might be anything. WriteWord(Data, tblo.Row); WriteWord(Data, tblo.Col); } else { TTableToken tbl = (TTableToken)Token; Biff8Utils.CheckRow(tbl.Row); Biff8Utils.CheckCol(tbl.Col); WriteWord(Data, tbl.Row); WriteWord(Data, tbl.Col); } break; case ptg.Add: case ptg.Sub: case ptg.Mul: case ptg.Div: case ptg.Power: case ptg.Concat: case ptg.LT: case ptg.LE: case ptg.EQ: case ptg.GE: case ptg.GT: case ptg.NE: case ptg.Isect: case ptg.Union: case ptg.Range: case ptg.Uplus: case ptg.Uminus: case ptg.Percent: case ptg.Paren: case ptg.MissArg: break; case ptg.Str: { TStrDataToken tkd = Token as TStrDataToken; string s = tkd.GetData(); if (s.Length > FlxConsts.Max_FormulaStringConstant) { FlxMessages.ThrowException(FlxErr.ErrStringConstantInFormulaTooLong, s, String.Empty); } TExcelString Xs = new TExcelString(TStrLenLength.is8bits, s, null, false); byte[] b = new byte[Xs.TotalSize()]; Xs.CopyToPtr(b, 0); Data.Write(b, 0, b.Length); break; } case ptg.Attr: WriteAttr(Data, Token, StreamPos, Tokens.SavePosition()); break; /* * case ptg.Sheet: //Can't happen, ConvertBiff8ToInternal skips them. * case ptg.EndSheet: //Can't happen, ConvertBiff8ToInternal skips them. * break;*/ case ptg.Err: { Data.WriteByte((byte)((TErrDataToken)Token).GetData()); break; } case ptg.Bool: { if (((TBoolDataToken)Token).GetData()) { Data.WriteByte(1); } else { Data.WriteByte(0); } break; } case ptg.Int: { UInt16 a = (UInt16)((TIntDataToken)Token).GetData(); WriteWord(Data, a); break; } case ptg.Num: { double d = ((TNumDataToken)Token).GetData(); Data.Write(BitConverter.GetBytes(d), 0, 8); break; } case ptg.Array: { Data.Write(new byte[7], 0, 7); TArrayDataToken tk = (TArrayDataToken)Token; object[,] Arr = tk.GetData; int ColCount = Arr.GetLength(1) - 1; if (ColCount < 0 || ColCount > FlxConsts.Max_Columns97_2003) { FlxMessages.ThrowException(FlxErr.ErrInvalidCols, ColCount, FlxConsts.Max_Columns97_2003 + 1); } ArrayData.WriteByte((byte)(ColCount)); int RowCount = Arr.GetLength(0) - 1; if (RowCount < 0 || RowCount > FlxConsts.Max_Rows) { FlxMessages.ThrowException(FlxErr.ErrInvalidRows, RowCount, FlxConsts.Max_Rows + 1); } WriteWord(ArrayData, RowCount); for (int r = 0; r <= RowCount; r++) { for (int c = 0; c <= ColCount; c++) { WriteArrayObject(ArrayData, Arr[r, c]); } } break; } case ptg.Func: { TBaseFunctionToken ft = (TBaseFunctionToken)Token; TCellFunctionData fd = ft.GetFunctionData(); WriteWord(Data, fd.Index); break; } case ptg.FuncVar: { TBaseFunctionToken ft = (TBaseFunctionToken)Token; TCellFunctionData fd = ft.GetFunctionData(); if (!BackFromFutureToUserDef(Data, Tokens, FuturePos, ft, fd)) { Data.WriteByte((byte)ft.ArgumentCount); WriteWord(Data, fd.Index); } break; } case ptg.Name: WriteWord(Data, ((TNameToken)Token).NameIndex); WriteWord(Data, 0); break; case ptg.Ref: case ptg.RefN: case ptg.RefErr: { TRefToken reft = (TRefToken)Token; WriteRef(Data, reft.CanHaveRelativeOffsets, reft.Row, reft.RowAbs, reft.Col, reft.ColAbs); break; } case ptg.Area: case ptg.AreaN: case ptg.AreaErr: { TAreaToken areat = (TAreaToken)Token; WriteArea(Data, areat.CanHaveRelativeOffsets, areat.Row1, areat.RowAbs1, areat.Col1, areat.ColAbs1, areat.Row2, areat.RowAbs2, areat.Col2, areat.ColAbs2); break; } case ptg.MemArea: { WriteWord(Data, 0); WriteWord(Data, 0); StreamPos.Add((int)Data.Position, Tokens.SavePosition()); WriteWord(Data, 0); TRefRange[] Range = ((TMemAreaToken)Token).Data; WriteWord(ArrayData, Range.Length); foreach (TRefRange OneRef in Range) { int r1 = Biff8Utils.CheckAndContractBiff8Row(OneRef.FirstRow); int r2 = Biff8Utils.CheckAndContractBiff8Row(OneRef.LastRow); int c1 = Biff8Utils.CheckAndContractBiff8Col(OneRef.FirstCol); int c2 = Biff8Utils.CheckAndContractBiff8Col(OneRef.LastCol); WriteWord(ArrayData, r1); WriteWord(ArrayData, r2); WriteWord(ArrayData, c1); WriteWord(ArrayData, c2); } break; } case ptg.MemErr: case ptg.MemNoMem: WriteWord(Data, 0); WriteWord(Data, 0); StreamPos.Add((int)Data.Position, Tokens.SavePosition()); WriteWord(Data, 0); break; case ptg.MemFunc: case ptg.MemAreaN: case ptg.MemNoMemN: StreamPos.Add((int)Data.Position, Tokens.SavePosition()); WriteWord(Data, 0); break; case ptg.NameX: TNameXToken NameX = (TNameXToken)Token; WriteWord(Data, NameX.FExternSheet); WriteWord(Data, NameX.NameIndex); WriteWord(Data, 0); break; case ptg.Ref3dErr: case ptg.Ref3d: TRef3dToken reft3d = (TRef3dToken)Token; WriteWord(Data, reft3d.FExternSheet); WriteRef(Data, reft3d.CanHaveRelativeOffsets, reft3d.Row, reft3d.RowAbs, reft3d.Col, reft3d.ColAbs); break; case ptg.Area3d: case ptg.Area3dErr: TArea3dToken areat3d = (TArea3dToken)Token; WriteWord(Data, areat3d.FExternSheet); WriteArea(Data, areat3d.CanHaveRelativeOffsets, areat3d.Row1, areat3d.RowAbs1, areat3d.Col1, areat3d.ColAbs1, areat3d.Row2, areat3d.RowAbs2, areat3d.Col2, areat3d.ColAbs2); break; default: XlsMessages.ThrowException(XlsErr.ErrInternal); //All tokens here should exist break; } }
private static void Evaluate(TBaseParsedToken Token, bool R1C1, int CellRow, int CellCol, ptg BaseToken, TParsedTokenList RPN, ICellList CellList, TWorkbookGlobals Globals, TFormulaStack ParsedStack, ref string StartFormula, int MaxStringConstantLen, bool WritingXlsx) { string s1; string s2; string s3; switch (BaseToken) { case ptg.Exp: AddArray(Token, CellRow, CellCol, CellList, Globals, ParsedStack, MaxStringConstantLen, WritingXlsx); StartFormula = String.Empty; break; case ptg.Tbl: AddTable(R1C1, Token, CellList, ParsedStack); StartFormula = String.Empty; break; case ptg.Add: s2 = ParsedStack.Pop(); s1 = ParsedStack.Pop(); ParsedStack.Push(s1 + ParsedStack.FmSpaces + fts(TFormulaToken.fmPlus) + s2); break; case ptg.Sub: s2 = ParsedStack.Pop(); s1 = ParsedStack.Pop(); ParsedStack.Push(s1 + ParsedStack.FmSpaces + fts(TFormulaToken.fmMinus) + s2); break; case ptg.Mul: s2 = ParsedStack.Pop(); s1 = ParsedStack.Pop(); ParsedStack.Push(s1 + ParsedStack.FmSpaces + fts(TFormulaToken.fmMul) + s2); break; case ptg.Div: s2 = ParsedStack.Pop(); s1 = ParsedStack.Pop(); ParsedStack.Push(s1 + ParsedStack.FmSpaces + fts(TFormulaToken.fmDiv) + s2); break; case ptg.Power: s2 = ParsedStack.Pop(); s1 = ParsedStack.Pop(); ParsedStack.Push(s1 + ParsedStack.FmSpaces + fts(TFormulaToken.fmPower) + s2); break; case ptg.Concat: s2 = ParsedStack.Pop(); s1 = ParsedStack.Pop(); ParsedStack.Push(s1 + ParsedStack.FmSpaces + fts(TFormulaToken.fmAnd) + s2); break; case ptg.LT: s2 = ParsedStack.Pop(); s1 = ParsedStack.Pop(); ParsedStack.Push(s1 + ParsedStack.FmSpaces + fts(TFormulaToken.fmLT) + s2); break; case ptg.LE: s2 = ParsedStack.Pop(); s1 = ParsedStack.Pop(); ParsedStack.Push(s1 + ParsedStack.FmSpaces + fts(TFormulaToken.fmLE) + s2); break; case ptg.EQ: s2 = ParsedStack.Pop(); s1 = ParsedStack.Pop(); ParsedStack.Push(s1 + ParsedStack.FmSpaces + fts(TFormulaToken.fmEQ) + s2); break; case ptg.GE: s2 = ParsedStack.Pop(); s1 = ParsedStack.Pop(); ParsedStack.Push(s1 + ParsedStack.FmSpaces + fts(TFormulaToken.fmGE) + s2); break; case ptg.GT: s2 = ParsedStack.Pop(); s1 = ParsedStack.Pop(); ParsedStack.Push(s1 + ParsedStack.FmSpaces + fts(TFormulaToken.fmGT) + s2); break; case ptg.NE: s2 = ParsedStack.Pop(); s1 = ParsedStack.Pop(); ParsedStack.Push(s1 + ParsedStack.FmSpaces + fts(TFormulaToken.fmNE) + s2); break; case ptg.Isect: s2 = ParsedStack.Pop(); s1 = ParsedStack.Pop(); ParsedStack.Push(s1 + ParsedStack.FmSpaces + fts(TFormulaToken.fmIntersect) + s2); break; case ptg.Union: s2 = ParsedStack.Pop(); s1 = ParsedStack.Pop(); ParsedStack.Push(s1 + ParsedStack.FmSpaces + fts(TFormulaToken.fmUnion) + s2); break; case ptg.Range: s2 = ParsedStack.Pop(); s1 = ParsedStack.Pop(); ParsedStack.Push(s1 + ParsedStack.FmSpaces + fts(TFormulaToken.fmRangeSep) + s2); break; case ptg.Uplus: s1 = ParsedStack.Pop(); ParsedStack.Push(ParsedStack.FmSpaces + fts(TFormulaToken.fmPlus) + s1); break; case ptg.Uminus: s1 = ParsedStack.Pop(); ParsedStack.Push(ParsedStack.FmSpaces + fts(TFormulaToken.fmMinus) + s1); break; case ptg.Percent: s1 = ParsedStack.Pop(); ParsedStack.Push(s1 + ParsedStack.FmSpaces + fts(TFormulaToken.fmPercent)); break; case ptg.Paren: s1 = ParsedStack.Pop(); ParsedStack.Push(ParsedStack.FmPreSpaces + fts(TFormulaToken.fmOpenParen) + s1 + ParsedStack.FmPostSpaces + fts(TFormulaToken.fmCloseParen)); break; case ptg.MissArg: ParsedStack.Push(ParsedStack.FmSpaces); break; case ptg.Str: ParsedStack.Push(ParsedStack.FmSpaces + fts(TFormulaToken.fmStr) + GetString(((TStrDataToken)Token).GetData(), MaxStringConstantLen) + fts(TFormulaToken.fmStr)); break; case ptg.Attr: ProcessAttr(Token, ParsedStack); break; case ptg.Sheet: break; case ptg.EndSheet: break; case ptg.Err: ParsedStack.Push(ParsedStack.FmSpaces + GetErrorText(((TErrDataToken)Token).GetData())); break; case ptg.Bool: ParsedStack.Push(ParsedStack.FmSpaces + GetBoolText(((TBoolDataToken)Token).GetData())); break; case ptg.Int: ParsedStack.Push(ParsedStack.FmSpaces + TFormulaMessages.FloatToString(((TIntDataToken)Token).GetData())); break; case ptg.Num: ParsedStack.Push(ParsedStack.FmSpaces + TFormulaMessages.FloatToString(((TNumDataToken)Token).GetData())); break; case ptg.Array: ParsedStack.Push(ParsedStack.FmSpaces + GetArrayText(((TArrayDataToken)Token).GetData, MaxStringConstantLen)); break; case ptg.Func: case ptg.FuncVar: int ArgCount; bool IsAddin; StringBuilder sb = new StringBuilder(); TBaseFunctionToken FunctionTk = Token as TBaseFunctionToken; s3 = ParsedStack.FmSpaces + GetFuncName(FunctionTk, out ArgCount, WritingXlsx, out IsAddin); if (ArgCount > 0) { sb.Append(ParsedStack.Pop()); } for (int i = 2; i <= ArgCount; i++) { s1 = ParsedStack.Pop(); sb.Insert(0, s1 + fts(TFormulaToken.fmFunctionSep)); } if (IsAddin) { s3 += ConvertInternalFunctionName(Globals, ParsedStack.Pop()); } ParsedStack.Push(s3 + fts(TFormulaToken.fmOpenParen) + ParsedStack.FmPreSpaces + sb.ToString() + ParsedStack.FmPostSpaces + fts(TFormulaToken.fmCloseParen)); break; case ptg.Name: ParsedStack.Push(ParsedStack.FmSpaces + GetName(((TNameToken)Token).NameIndex, -1, Globals, WritingXlsx)); break; case ptg.RefN: case ptg.Ref: ParsedStack.Push(ParsedStack.FmSpaces + GetRef(R1C1, (TRefToken)Token, CellRow, CellCol)); break; case ptg.AreaN: case ptg.Area: ParsedStack.Push(ParsedStack.FmSpaces + GetArea(R1C1, (TAreaToken)Token, CellRow, CellCol)); break; case ptg.MemArea: break; case ptg.MemErr: break; case ptg.MemNoMem: break; case ptg.MemFunc: break; case ptg.RefErr: ParsedStack.Push(ParsedStack.FmSpaces + TFormulaMessages.ErrString(TFlxFormulaErrorValue.ErrRef)); break; case ptg.AreaErr: ParsedStack.Push(ParsedStack.FmSpaces + TFormulaMessages.ErrString(TFlxFormulaErrorValue.ErrRef)); break; case ptg.MemAreaN: break; case ptg.MemNoMemN: break; case ptg.NameX: ParsedStack.Push(ParsedStack.FmSpaces + GetNameX((TNameXToken)Token, Globals, WritingXlsx)); break; case ptg.Ref3d: ParsedStack.Push(ParsedStack.FmSpaces + GetRef3D(R1C1, (TRef3dToken)Token, CellRow, CellCol, Globals, false, WritingXlsx)); break; case ptg.Area3d: ParsedStack.Push(ParsedStack.FmSpaces + GetArea3D(R1C1, (TArea3dToken)Token, CellRow, CellCol, Globals, false, WritingXlsx)); break; case ptg.Ref3dErr: ParsedStack.Push(ParsedStack.FmSpaces + GetRef3D(R1C1, (TRef3dToken)Token, -1, -1, Globals, true, WritingXlsx)); break; case ptg.Area3dErr: ParsedStack.Push(ParsedStack.FmSpaces + GetArea3D(R1C1, (TArea3dToken)Token, CellRow, CellCol, Globals, true, WritingXlsx)); break; default: XlsMessages.ThrowException(XlsErr.ErrBadToken, Token); break; } }
internal static void SaveToStream(TNameRecordList Names, IDataStream Workbook, TFormulaType FmlaType, TParsedTokenList Data, bool WriteLen) { if (Data.TextLenght > FlxConsts.Max_FormulaLen97_2003) { FlxMessages.ThrowException(FlxErr.ErrFormulaTooLong, TFormulaConvertInternalToText.AsString(Data, 0, 0, null)); } int FmlaNoArrayLen; byte[] bData = TFormulaConvertInternalToBiff8.GetTokenData(Names, Data, FmlaType, out FmlaNoArrayLen); if (WriteLen) { Workbook.Write16((UInt16)FmlaNoArrayLen); } Workbook.Write(bData, bData.Length); }
internal static string AsString(TParsedTokenList Tokens, int CellRow, int CellCol, ICellList CellList, TWorkbookGlobals Globals, int MaxStringConstantLen, bool WritingXlsx) { return(AsString(Tokens, CellRow, CellCol, CellList, Globals, MaxStringConstantLen, WritingXlsx, false)); }
internal static void ArrangeInsertAndCopyRange(TParsedTokenList Data, TXlsCellRange CellRange, int FmlaRow, int FmlaCol, int aRowCount, int aColCount, int CopyRowOffset, int CopyColOffset, TSheetInfo SheetInfo, bool aAllowedAbsolute, TFormulaBounds Bounds) { new TInsertTokens(CellRange, aRowCount, aColCount, CopyRowOffset, CopyColOffset, SheetInfo, false, aAllowedAbsolute, FmlaRow, FmlaCol, Bounds).Go(Data, SheetInfo.SourceFormulaSheet == SheetInfo.InsSheet); }
internal static void ArrangeMoveRange(TParsedTokenList Data, TXlsCellRange CellRange, int FmlaRow, int FmlaCol, int NewRow, int NewCol, TSheetInfo SheetInfo, TFormulaBounds Bounds) { new TMoveTokens(CellRange, FmlaRow, FmlaCol, NewRow, NewCol, SheetInfo, Bounds).Go(Data, SheetInfo.SourceFormulaSheet == SheetInfo.InsSheet); }
protected override void DoMemArea(TParsedTokenList Tokens, TMemAreaToken areat, bool RefIsInInsertingSheet) { //Instead of trying to keep this list of areas synchronized, merging ranges that are together, etc, we will just remove this token. It isn't really needed anyway. Tokens.RemoveToken(); Tokens.MoveBack(); //We can't call LightPop here to go back, since it would raise an Exception if at first token. }
internal static void ArrangeInsertSheets(TParsedTokenList Data, TSheetInfo SheetInfo) { new TInsertTokens(new TXlsCellRange(0, 0, -1, -1), 0, 0, 0, 0, SheetInfo, true, true, 0, 0, null).Go(Data, SheetInfo.SourceFormulaSheet == SheetInfo.InsSheet); }
private static void FixFutureFunctions(TNameRecordList Names, Int32List FuturePos, TParsedTokenList Tokens, MemoryStream Data, int[] TokenOffset, ref TTokenOffset StreamPos) { if (FuturePos.Count == 0) { return; } List <byte> NewData = new List <byte>(Data.ToArray()); //we need to insert in any order for (int i = 0; i < FuturePos.Count; i++) { Tokens.MoveTo(FuturePos[i]); TBaseFunctionToken FuncToken = (TBaseFunctionToken)Tokens.GetToken(FuturePos[i]); for (int k = 0; k < FuncToken.ArgumentCount; k++) //this doesn't include the name. { Tokens.Flush(); } int TokPos = Tokens.SavePosition(); while (TokPos > 0) { if (!(Tokens.GetToken(TokPos - 1) is TIgnoreInCalcToken) || Tokens.GetToken(TokPos - 1) is TAttrToken) { break; } TokPos--; } int ofs = TokenOffset[TokPos]; WriteFutureName(NewData, ofs, FindName(Names, FuncToken.GetFunctionData().FutureName)); for (int k = TokPos; k < TokenOffset.Length; k++) { TokenOffset[k] += 5; } TTokenOffset NewStreamPos = new TTokenOffset(); foreach (int streamofs in StreamPos.Keys) { int sofs = streamofs; if (sofs >= ofs) { sofs += 5; } NewStreamPos.Add(sofs, StreamPos[streamofs]); } StreamPos = NewStreamPos; } Data.SetLength(0); Data.Write(NewData.ToArray(), 0, NewData.Count); }
internal void ChangeFmla(ExcelFile Workbook, TEscherClientDataRecord Cd, TCellAddress LinkedCellAddress, TParsedTokenList LinkedCellFmla, bool ReadingXlsx) { //The line below would interfere with xlsx loading since it would build the tree and maybe remove links //before group boxes have been created. if (!ReadingXlsx) { BuildTree(Workbook); //This avoids that 2 calls to different objects could have no secuential effects. } TRadioGroupCache rgc; if (!RadioButtonsById.TryGetValue(Cd.ObjId, out rgc)) { //It is not in the built part. (Cd.ClientData as TMsObj).SetObjFormulaLink(Workbook, LinkedCellAddress, LinkedCellFmla); return; } (rgc.Buttons[0].ClientData as TMsObj).SetObjFormulaLink(Workbook, LinkedCellAddress, LinkedCellFmla); }
protected abstract void DoMemArea(TParsedTokenList Tokens, TMemAreaToken areat, bool RefIsInInsertingSheet);
internal void Go(TParsedTokenList Data, bool RefIsInInsertingSheet) { Data.ResetPositionToStart(); while (!Data.Eof()) { TBaseParsedToken r = Data.ForwardPop(); ptg id = r.GetBaseId; switch (id) { case ptg.Exp: DoArrayFmla((TExp_Token)r); break; case ptg.Tbl: TTableToken tbl = r as TTableToken; if (tbl != null) //might be also TTableObjToken { DoTable(tbl); } break; case ptg.Name: DoName((TNameToken)r); break; case ptg.RefErr: case ptg.Ref: case ptg.RefN: DoRef((TRefToken)r, RefIsInInsertingSheet); break; case ptg.AreaErr: case ptg.Area: case ptg.AreaN: DoArea((TAreaToken)r, RefIsInInsertingSheet); break; case ptg.MemArea: DoMemArea(Data, (TMemAreaToken)r, RefIsInInsertingSheet); break; case ptg.NameX: { //We'll do Do3d only for local names. //bool ThisRefIsInInsertingSheet; //Do3D(r, out ThisRefIsInInsertingSheet); DoNameX((TNameXToken)r); } break; case ptg.Ref3d: case ptg.Ref3dErr: { bool ThisRefIsInInsertingSheet; Do3D(r, out ThisRefIsInInsertingSheet); DoRef((TRef3dToken)r, ThisRefIsInInsertingSheet); break; } case ptg.Area3dErr: case ptg.Area3d: { bool ThisRefIsInInsertingSheet; Do3D(r, out ThisRefIsInInsertingSheet); DoArea((TArea3dToken)r, ThisRefIsInInsertingSheet); } break; } } }