Search in sources :

Example 1 with NameXPtg

use of org.apache.poi.ss.formula.ptg.NameXPtg in project poi by apache.

the class FormulaParser method parseRangeable.

/**
     * Parses area refs (things which could be the operand of ':') and simple factors
     * Examples
     * <pre>
     *   A$1
     *   $A$1 :  $B1
     *   A1 .......    C2
     *   Sheet1 !$A1
     *   a..b!A1
     *   'my sheet'!A1
     *   .my.sheet!A1
     *   'my sheet':'my alt sheet'!A1
     *   .my.sheet1:.my.sheet2!$B$2
     *   my.named..range.
     *   'my sheet'!my.named.range
     *   .my.sheet!my.named.range
     *   foo.bar(123.456, "abc")
     *   123.456
     *   "abc"
     *   true
     *   [Foo.xls]!$A$1
     *   [Foo.xls]'my sheet'!$A$1
     *   [Foo.xls]!my.named.range
     * </pre>
     *
     */
private ParseNode parseRangeable() {
    SkipWhite();
    int savePointer = _pointer;
    SheetIdentifier sheetIden = parseSheetName();
    if (sheetIden == null) {
        resetPointer(savePointer);
    } else {
        SkipWhite();
        savePointer = _pointer;
    }
    SimpleRangePart part1 = parseSimpleRangePart();
    if (part1 == null) {
        if (sheetIden != null) {
            if (look == '#') {
                // error ref like MySheet!#REF!
                return new ParseNode(ErrPtg.valueOf(parseErrorLiteral()));
            } else {
                // Is it a named range?
                String name = parseAsName();
                if (name.length() == 0) {
                    throw new FormulaParseException("Cell reference or Named Range " + "expected after sheet name at index " + _pointer + ".");
                }
                Ptg nameXPtg = _book.getNameXPtg(name, sheetIden);
                if (nameXPtg == null) {
                    throw new FormulaParseException("Specified name '" + name + "' for sheet " + sheetIden.asFormulaString() + " not found");
                }
                return new ParseNode(nameXPtg);
            }
        }
        return parseNonRange(savePointer);
    }
    boolean whiteAfterPart1 = IsWhite(look);
    if (whiteAfterPart1) {
        SkipWhite();
    }
    if (look == ':') {
        int colonPos = _pointer;
        GetChar();
        SkipWhite();
        SimpleRangePart part2 = parseSimpleRangePart();
        if (part2 != null && !part1.isCompatibleForArea(part2)) {
            // second part is not compatible with an area ref e.g. S!A1:S!B2
            // where S might be a sheet name (that looks like a column name)
            part2 = null;
        }
        if (part2 == null) {
            // second part is not compatible with an area ref e.g. A1:OFFSET(B2, 1, 2)
            // reset and let caller use explicit range operator
            resetPointer(colonPos);
            if (!part1.isCell()) {
                String prefix = "";
                if (sheetIden != null) {
                    prefix = "'" + sheetIden.getSheetIdentifier().getName() + '!';
                }
                throw new FormulaParseException(prefix + part1.getRep() + "' is not a proper reference.");
            }
        }
        return createAreaRefParseNode(sheetIden, part1, part2);
    }
    if (look == '.') {
        GetChar();
        int dotCount = 1;
        while (look == '.') {
            dotCount++;
            GetChar();
        }
        boolean whiteBeforePart2 = IsWhite(look);
        SkipWhite();
        SimpleRangePart part2 = parseSimpleRangePart();
        String part1And2 = _formulaString.substring(savePointer - 1, _pointer - 1);
        if (part2 == null) {
            if (sheetIden != null) {
                throw new FormulaParseException("Complete area reference expected after sheet name at index " + _pointer + ".");
            }
            return parseNonRange(savePointer);
        }
        if (whiteAfterPart1 || whiteBeforePart2) {
            if (part1.isRowOrColumn() || part2.isRowOrColumn()) {
                // and there's no other valid expression that fits this grammar
                throw new FormulaParseException("Dotted range (full row or column) expression '" + part1And2 + "' must not contain whitespace.");
            }
            return createAreaRefParseNode(sheetIden, part1, part2);
        }
        if (dotCount == 1 && part1.isRow() && part2.isRow()) {
            // actually, this is looking more like a number
            return parseNonRange(savePointer);
        }
        if (part1.isRowOrColumn() || part2.isRowOrColumn()) {
            if (dotCount != 2) {
                throw new FormulaParseException("Dotted range (full row or column) expression '" + part1And2 + "' must have exactly 2 dots.");
            }
        }
        return createAreaRefParseNode(sheetIden, part1, part2);
    }
    if (part1.isCell() && isValidCellReference(part1.getRep())) {
        return createAreaRefParseNode(sheetIden, part1, null);
    }
    if (sheetIden != null) {
        throw new FormulaParseException("Second part of cell reference expected after sheet name at index " + _pointer + ".");
    }
    return parseNonRange(savePointer);
}
Also used : NumberPtg(org.apache.poi.ss.formula.ptg.NumberPtg) ArrayPtg(org.apache.poi.ss.formula.ptg.ArrayPtg) AttrPtg(org.apache.poi.ss.formula.ptg.AttrPtg) PercentPtg(org.apache.poi.ss.formula.ptg.PercentPtg) RangePtg(org.apache.poi.ss.formula.ptg.RangePtg) AddPtg(org.apache.poi.ss.formula.ptg.AddPtg) EqualPtg(org.apache.poi.ss.formula.ptg.EqualPtg) UnaryMinusPtg(org.apache.poi.ss.formula.ptg.UnaryMinusPtg) NameXPtg(org.apache.poi.ss.formula.ptg.NameXPtg) RefPtg(org.apache.poi.ss.formula.ptg.RefPtg) DividePtg(org.apache.poi.ss.formula.ptg.DividePtg) GreaterThanPtg(org.apache.poi.ss.formula.ptg.GreaterThanPtg) MultiplyPtg(org.apache.poi.ss.formula.ptg.MultiplyPtg) StringPtg(org.apache.poi.ss.formula.ptg.StringPtg) ErrPtg(org.apache.poi.ss.formula.ptg.ErrPtg) Ptg(org.apache.poi.ss.formula.ptg.Ptg) NamePtg(org.apache.poi.ss.formula.ptg.NamePtg) MemAreaPtg(org.apache.poi.ss.formula.ptg.MemAreaPtg) NotEqualPtg(org.apache.poi.ss.formula.ptg.NotEqualPtg) ValueOperatorPtg(org.apache.poi.ss.formula.ptg.ValueOperatorPtg) ConcatPtg(org.apache.poi.ss.formula.ptg.ConcatPtg) UnaryPlusPtg(org.apache.poi.ss.formula.ptg.UnaryPlusPtg) GreaterEqualPtg(org.apache.poi.ss.formula.ptg.GreaterEqualPtg) LessThanPtg(org.apache.poi.ss.formula.ptg.LessThanPtg) BoolPtg(org.apache.poi.ss.formula.ptg.BoolPtg) IntersectionPtg(org.apache.poi.ss.formula.ptg.IntersectionPtg) AbstractFunctionPtg(org.apache.poi.ss.formula.ptg.AbstractFunctionPtg) IntPtg(org.apache.poi.ss.formula.ptg.IntPtg) LessEqualPtg(org.apache.poi.ss.formula.ptg.LessEqualPtg) UnionPtg(org.apache.poi.ss.formula.ptg.UnionPtg) FuncVarPtg(org.apache.poi.ss.formula.ptg.FuncVarPtg) SubtractPtg(org.apache.poi.ss.formula.ptg.SubtractPtg) FuncPtg(org.apache.poi.ss.formula.ptg.FuncPtg) OperandPtg(org.apache.poi.ss.formula.ptg.OperandPtg) MissingArgPtg(org.apache.poi.ss.formula.ptg.MissingArgPtg) MemFuncPtg(org.apache.poi.ss.formula.ptg.MemFuncPtg) OperationPtg(org.apache.poi.ss.formula.ptg.OperationPtg) PowerPtg(org.apache.poi.ss.formula.ptg.PowerPtg) AreaPtg(org.apache.poi.ss.formula.ptg.AreaPtg) ParenthesisPtg(org.apache.poi.ss.formula.ptg.ParenthesisPtg)

Example 2 with NameXPtg

use of org.apache.poi.ss.formula.ptg.NameXPtg in project poi by apache.

the class InternalWorkbook method getNameXPtg.

/**
     *
     * @param name the  name of an external function, typically a name of a UDF
     * @param sheetRefIndex the sheet ref index, or -1 if not known
     * @param udf  locator of user-defiend functions to resolve names of VBA and Add-In functions
     * @return the external name or null
     */
public NameXPtg getNameXPtg(String name, int sheetRefIndex, UDFFinder udf) {
    LinkTable lnk = getOrCreateLinkTable();
    NameXPtg xptg = lnk.getNameXPtg(name, sheetRefIndex);
    if (xptg == null && udf.findFunction(name) != null) {
        // the name was not found in the list of external names
        // check if the Workbook's UDFFinder is aware about it and register the name if it is
        xptg = lnk.addNameXPtg(name);
    }
    return xptg;
}
Also used : NameXPtg(org.apache.poi.ss.formula.ptg.NameXPtg)

Example 3 with NameXPtg

use of org.apache.poi.ss.formula.ptg.NameXPtg in project poi by apache.

the class LinkTable method addNameXPtg.

/**
     * Register an external name in this workbook
     *
     * @param name  the name to register
     * @return a NameXPtg describing this name 
     */
public NameXPtg addNameXPtg(String name) {
    int extBlockIndex = -1;
    ExternalBookBlock extBlock = null;
    // find ExternalBlock for Add-In functions and remember its index
    for (int i = 0; i < _externalBookBlocks.length; i++) {
        SupBookRecord ebr = _externalBookBlocks[i].getExternalBookRecord();
        if (ebr.isAddInFunctions()) {
            extBlock = _externalBookBlocks[i];
            extBlockIndex = i;
            break;
        }
    }
    // An ExternalBlock for Add-In functions was not found. Create a new one.
    if (extBlock == null) {
        extBlock = new ExternalBookBlock();
        extBlockIndex = extendExternalBookBlocks(extBlock);
        // add the created SupBookRecord before ExternSheetRecord
        int idx = findFirstRecordLocBySid(ExternSheetRecord.sid);
        _workbookRecordList.add(idx, extBlock.getExternalBookRecord());
        // register the SupBookRecord in the ExternSheetRecord
        // -2 means that the scope of this name is Workbook and the reference applies to the entire workbook.
        _externSheetRecord.addRef(_externalBookBlocks.length - 1, -2, -2);
    }
    // create a ExternalNameRecord that will describe this name
    ExternalNameRecord extNameRecord = new ExternalNameRecord();
    extNameRecord.setText(name);
    // The docs don't explain why Excel set the formula to #REF!
    extNameRecord.setParsedExpression(new Ptg[] { ErrPtg.REF_INVALID });
    int nameIndex = extBlock.addExternalName(extNameRecord);
    int supLinkIndex = 0;
    // the created ExternalNameRecord will be appended to it
    for (Iterator<Record> iterator = _workbookRecordList.iterator(); iterator.hasNext(); supLinkIndex++) {
        Record record = iterator.next();
        if (record instanceof SupBookRecord) {
            if (((SupBookRecord) record).isAddInFunctions())
                break;
        }
    }
    int numberOfNames = extBlock.getNumberOfNames();
    // a new name is inserted in the end of the SupBookRecord, after the last name
    _workbookRecordList.add(supLinkIndex + numberOfNames, extNameRecord);
    int fakeSheetIdx = -2;
    /* the scope is workbook*/
    int ix = _externSheetRecord.getRefIxForSheet(extBlockIndex, fakeSheetIdx, fakeSheetIdx);
    return new NameXPtg(ix, nameIndex);
}
Also used : ExternalNameRecord(org.apache.poi.hssf.record.ExternalNameRecord) SupBookRecord(org.apache.poi.hssf.record.SupBookRecord) NameXPtg(org.apache.poi.ss.formula.ptg.NameXPtg) CRNCountRecord(org.apache.poi.hssf.record.CRNCountRecord) Record(org.apache.poi.hssf.record.Record) SupBookRecord(org.apache.poi.hssf.record.SupBookRecord) CRNRecord(org.apache.poi.hssf.record.CRNRecord) ExternalNameRecord(org.apache.poi.hssf.record.ExternalNameRecord) NameRecord(org.apache.poi.hssf.record.NameRecord) CountryRecord(org.apache.poi.hssf.record.CountryRecord) NameCommentRecord(org.apache.poi.hssf.record.NameCommentRecord) ExternSheetRecord(org.apache.poi.hssf.record.ExternSheetRecord)

Example 4 with NameXPtg

use of org.apache.poi.ss.formula.ptg.NameXPtg in project poi by apache.

the class TestLinkTable method testAddNameX.

public void testAddNameX() {
    WorkbookRecordList wrl = new WorkbookRecordList();
    wrl.add(0, new BOFRecord());
    wrl.add(1, new CountryRecord());
    wrl.add(2, EOFRecord.instance);
    int numberOfSheets = 3;
    LinkTable tbl = new LinkTable(numberOfSheets, wrl);
    // creation of a new LinkTable insert two new records: SupBookRecord followed by ExternSheetRecord
    // assure they are in place:
    //    [BOFRecord]
    //    [CountryRecord]
    //    [SUPBOOK Internal References  nSheets= 3]
    //    [EXTERNSHEET]
    //    [EOFRecord]
    assertEquals(5, wrl.getRecords().size());
    assertTrue(wrl.get(2) instanceof SupBookRecord);
    SupBookRecord sup1 = (SupBookRecord) wrl.get(2);
    assertEquals(numberOfSheets, sup1.getNumberOfSheets());
    assertTrue(wrl.get(3) instanceof ExternSheetRecord);
    ExternSheetRecord extSheet = (ExternSheetRecord) wrl.get(3);
    assertEquals(0, extSheet.getNumOfRefs());
    assertNull(tbl.getNameXPtg("ISODD", -1));
    //still have five records
    assertEquals(5, wrl.getRecords().size());
    // adds two new rercords
    NameXPtg namex1 = tbl.addNameXPtg("ISODD");
    assertEquals(0, namex1.getSheetRefIndex());
    assertEquals(0, namex1.getNameIndex());
    assertEquals(namex1.toString(), tbl.getNameXPtg("ISODD", -1).toString());
    // Can only find on the right sheet ref, if restricting
    assertEquals(namex1.toString(), tbl.getNameXPtg("ISODD", 0).toString());
    assertNull(tbl.getNameXPtg("ISODD", 1));
    assertNull(tbl.getNameXPtg("ISODD", 2));
    // assure they are in place:
    //    [BOFRecord]
    //    [CountryRecord]
    //    [SUPBOOK Internal References  nSheets= 3]
    //    [SUPBOOK Add-In Functions nSheets= 1]
    //    [EXTERNALNAME .name    = ISODD]
    //    [EXTERNSHEET]
    //    [EOFRecord]
    assertEquals(7, wrl.getRecords().size());
    assertTrue(wrl.get(3) instanceof SupBookRecord);
    SupBookRecord sup2 = (SupBookRecord) wrl.get(3);
    assertTrue(sup2.isAddInFunctions());
    assertTrue(wrl.get(4) instanceof ExternalNameRecord);
    ExternalNameRecord ext1 = (ExternalNameRecord) wrl.get(4);
    assertEquals("ISODD", ext1.getText());
    assertTrue(wrl.get(5) instanceof ExternSheetRecord);
    assertEquals(1, extSheet.getNumOfRefs());
    //check that
    assertEquals(0, tbl.resolveNameXIx(namex1.getSheetRefIndex(), namex1.getNameIndex()));
    assertEquals("ISODD", tbl.resolveNameXText(namex1.getSheetRefIndex(), namex1.getNameIndex(), null));
    assertNull(tbl.getNameXPtg("ISEVEN", -1));
    // adds two new rercords
    NameXPtg namex2 = tbl.addNameXPtg("ISEVEN");
    assertEquals(0, namex2.getSheetRefIndex());
    // name index increased by one
    assertEquals(1, namex2.getNameIndex());
    assertEquals(namex2.toString(), tbl.getNameXPtg("ISEVEN", -1).toString());
    assertEquals(8, wrl.getRecords().size());
    // assure they are in place:
    //    [BOFRecord]
    //    [CountryRecord]
    //    [SUPBOOK Internal References  nSheets= 3]
    //    [SUPBOOK Add-In Functions nSheets= 1]
    //    [EXTERNALNAME .name    = ISODD]
    //    [EXTERNALNAME .name    = ISEVEN]
    //    [EXTERNSHEET]
    //    [EOFRecord]
    assertTrue(wrl.get(3) instanceof SupBookRecord);
    assertTrue(wrl.get(4) instanceof ExternalNameRecord);
    assertTrue(wrl.get(5) instanceof ExternalNameRecord);
    assertEquals("ISODD", ((ExternalNameRecord) wrl.get(4)).getText());
    assertEquals("ISEVEN", ((ExternalNameRecord) wrl.get(5)).getText());
    assertTrue(wrl.get(6) instanceof ExternSheetRecord);
    assertTrue(wrl.get(7) instanceof EOFRecord);
    assertEquals(0, tbl.resolveNameXIx(namex2.getSheetRefIndex(), namex2.getNameIndex()));
    assertEquals("ISEVEN", tbl.resolveNameXText(namex2.getSheetRefIndex(), namex2.getNameIndex(), null));
}
Also used : ExternalNameRecord(org.apache.poi.hssf.record.ExternalNameRecord) EOFRecord(org.apache.poi.hssf.record.EOFRecord) ExternSheetRecord(org.apache.poi.hssf.record.ExternSheetRecord) SupBookRecord(org.apache.poi.hssf.record.SupBookRecord) NameXPtg(org.apache.poi.ss.formula.ptg.NameXPtg) BOFRecord(org.apache.poi.hssf.record.BOFRecord) CountryRecord(org.apache.poi.hssf.record.CountryRecord)

Aggregations

NameXPtg (org.apache.poi.ss.formula.ptg.NameXPtg)4 CountryRecord (org.apache.poi.hssf.record.CountryRecord)2 ExternSheetRecord (org.apache.poi.hssf.record.ExternSheetRecord)2 ExternalNameRecord (org.apache.poi.hssf.record.ExternalNameRecord)2 SupBookRecord (org.apache.poi.hssf.record.SupBookRecord)2 BOFRecord (org.apache.poi.hssf.record.BOFRecord)1 CRNCountRecord (org.apache.poi.hssf.record.CRNCountRecord)1 CRNRecord (org.apache.poi.hssf.record.CRNRecord)1 EOFRecord (org.apache.poi.hssf.record.EOFRecord)1 NameCommentRecord (org.apache.poi.hssf.record.NameCommentRecord)1 NameRecord (org.apache.poi.hssf.record.NameRecord)1 Record (org.apache.poi.hssf.record.Record)1 AbstractFunctionPtg (org.apache.poi.ss.formula.ptg.AbstractFunctionPtg)1 AddPtg (org.apache.poi.ss.formula.ptg.AddPtg)1 AreaPtg (org.apache.poi.ss.formula.ptg.AreaPtg)1 ArrayPtg (org.apache.poi.ss.formula.ptg.ArrayPtg)1 AttrPtg (org.apache.poi.ss.formula.ptg.AttrPtg)1 BoolPtg (org.apache.poi.ss.formula.ptg.BoolPtg)1 ConcatPtg (org.apache.poi.ss.formula.ptg.ConcatPtg)1 DividePtg (org.apache.poi.ss.formula.ptg.DividePtg)1