예제 #1
0
  /**
   * Generates the variable function ptg for the formula.
   *
   * <p>For IF Formulas, additional PTGs are added to the tokens
   *
   * @param name a {@link NamePtg} or {@link NameXPtg} or <code>null</code>
   * @return Ptg a null is returned if we're in an IF formula, it needs extreme manipulation and is
   *     handled in this function
   */
  private ParseNode getFunction(String name, Ptg namePtg, ParseNode[] args) {

    FunctionMetadata fm = FunctionMetadataRegistry.getFunctionByName(name.toUpperCase());
    int numArgs = args.length;
    if (fm == null) {
      if (namePtg == null) {
        throw new IllegalStateException("NamePtg must be supplied for external functions");
      }
      // must be external function
      ParseNode[] allArgs = new ParseNode[numArgs + 1];
      allArgs[0] = new ParseNode(namePtg);
      System.arraycopy(args, 0, allArgs, 1, numArgs);
      return new ParseNode(FuncVarPtg.create(name, numArgs + 1), allArgs);
    }

    if (namePtg != null) {
      throw new IllegalStateException("NamePtg no applicable to internal functions");
    }
    boolean isVarArgs = !fm.hasFixedArgsLength();
    int funcIx = fm.getIndex();
    if (funcIx == FunctionMetadataRegistry.FUNCTION_INDEX_SUM && args.length == 1) {
      // Excel encodes the sum of a single argument as tAttrSum
      // POI does the same for consistency, but this is not critical
      return new ParseNode(AttrPtg.getSumSingle(), args);
      // The code below would encode tFuncVar(SUM) which seems to do no harm
    }
    validateNumArgs(args.length, fm);

    AbstractFunctionPtg retval;
    if (isVarArgs) {
      retval = FuncVarPtg.create(name, numArgs);
    } else {
      retval = FuncPtg.create(funcIx);
    }
    return new ParseNode(retval, args);
  }
예제 #2
0
  /** @return <code>true</code> if the specified name is a valid cell reference */
  private boolean isValidCellReference(String str) {
    // check range bounds against grid max
    boolean result = CellReference.classifyCellReference(str, _ssVersion) == NameType.CELL;

    if (result) {
      /**
       * Check if the argument is a function. Certain names can be either a cell reference or a
       * function name depending on the contenxt. Compare the following examples in Excel 2007: (a)
       * LOG10(100) + 1 (b) LOG10 + 1 In (a) LOG10 is a name of a built-in function. In (b) LOG10 is
       * a cell reference
       */
      boolean isFunc = FunctionMetadataRegistry.getFunctionByName(str.toUpperCase()) != null;
      if (isFunc) {
        int savePointer = _pointer;
        resetPointer(_pointer + str.length());
        SkipWhite();
        // open bracket indicates that the argument is a function,
        // the returning value should be false, i.e. "not a valid cell reference"
        result = look != '(';
        resetPointer(savePointer);
      }
    }
    return result;
  }