正在分析公式

openpyxl 支持对单元格中嵌入的公式进行有限的分析。这个 openpyxl.formula 包中包含 Tokenizer 类将公式分解为其组成的标记。用法如下:

>>> from openpyxl.formula import Tokenizer
>>> tok = Tokenizer("""=IF($A$1,"then True",MAX(DEFAULT_VAL,'Sheet 2'!B1))""")
>>> print("\n".join("%12s%11s%9s" % (t.value, t.type, t.subtype) for t in tok.items))
         IF(       FUNC     OPEN
        $A$1    OPERAND    RANGE
           ,        SEP      ARG
 "then True"    OPERAND     TEXT
           ,        SEP      ARG
        MAX(       FUNC     OPEN
 DEFAULT_VAL    OPERAND    RANGE
           ,        SEP      ARG
'Sheet 2'!B1    OPERAND    RANGE
           )       FUNC    CLOSE
           )       FUNC    CLOSE

如上所示,令牌具有三个感兴趣的属性:

  • .value :生成此标记的公式的子字符串

  • .type :表示的令牌类型。可以是其中之一

    • Token.LITERAL :如果单元格不包含公式,则其值由单个 LITERAL 令牌。

    • Token.OPERAND :Excel公式中任何值的通用术语。(见 .subtype 详情请参见下文)。

    • Token.FUNC :函数调用被分解为开放器的标记(例如, SUM( ,后面是参数,后面是闭门器(即, ) )函数名和左括号一起构成一个 FUNC 标记,匹配的括号形成另一个 FUNC 令牌。

    • Token.ARRAY :数组文本(括在大括号之间)获取两个 ARRAY 每个代币,一个用于开场 {{ 最后一个 }} .

    • Token.PAREN :当用于分组子表达式(而不是表示函数调用)时,括号标记为 PAREN 令牌(每个字符一个)。

    • Token.SEP :这些标记是从逗号创建的 (, )或分号 (; )逗号创建 SEP 用于分隔函数参数(例如, SUM(a,b) )或者当它们用于分离数组元素时(例如, {{a,b}} )(它们还有另一个用途,用作连接范围的中缀运算符)。分号始终用于分隔数组文本中的行,因此始终创建 SEP 令牌。

    • Token.OP_PRE: Designates a prefix unary operator. Its value is always + or -

    • Token.OP_IN: Designates an infix binary operator. Possible values are >=, <=, <>, =, >, <, *, /, `` + -^& .

    • Token.OP_POST :指定后缀一元运算符。它的价值总是 % .

    • Token.WSPACE :为遇到的任何空白创建。它的值总是一个空格,不管找到多少空白。

  • .subtype :上面的某些令牌类型使用子类型提供有关令牌的其他信息。可能的子类型包括:

    • Token.TEXTToken.NUMBERToken.LOGICALToken.ERRORToken.RANGE :这些子类型描述了 OPERAND 在公式中找到。 LOGICAL 要么是 TRUEFALSERANGE 是命名范围或对另一个范围的直接引用。 TEXTNUMBERERROR 全部引用公式中的文字值

    • Token.OPENToken.CLOSE :这两个子类型由使用 PARENFUNCARRAY ,以描述令牌是打开新的子表达式还是关闭它。

    • Token.ARG and Token.ROW: are used by the SEP tokens, to distinguish between the comma and semicolon. Commas produce tokens of subtype ARG whereas semicolons produce tokens of subtype ROW

将公式从一个位置转换到另一个位置

可以使用 openpyxl.formulas.translate.Translator 班级。例如,有一系列单元格 B2:E7 列中每行的和 F ::

>>> from openpyxl.formula.translate import Translator
>>> ws['F2'] = "=SUM(B2:E2)"
>>> # move the formula one colum to the right
>>> ws['G2'] = Translator("=SUM(B2:E2)", origin="F2").translate_formula("G2")
>>> ws['G2'].value
'=SUM(C2:F2)'

注解

这仅限于公式的相同一般限制: A1 仅单元格引用,不支持已定义的名称。