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()); }
/// <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()); } } }
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); }
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 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; } } }