【问题标题】:How can I get python generated excel document to correctly calculate array formulas如何让 python 生成的 excel 文档正确计算数组公式
【发布时间】:2017-08-11 12:45:10
【问题描述】:

我正在使用 python 3.6 和 openpyxl 生成一些 excel 文件。

在某一时刻,我必须计算一部分数据的标准偏差。在 excel 中,这是通过数组公式完成的。编写正确的公式很容易,但是当我要求 excel 计算时 - 它显示“#NAME?”,除非我手动输入每个单元格并按 CTRL+SHIFT+ENTER。
但是,在这样做之前,公式显示了正确的大括号,所以我不确定我在改变什么。 由于我们正在谈论相当多的单元格,因此手动输入每个单元格是不可行的。有没有办法让 excel 或 Python 在 excel 中正确执行公式?如有必要,我愿意使用其他库或编写 VB 脚本。

下面是一个在 python 中工作的最小可行示例:

from openpyxl import Workbook
from openpyxl.utils.cell import get_column_letter
from random import random
from random import randrange

wb = Workbook()
ws = wb.create_sheet()
ws.title = 'Data'

#generate random data
for i in range(100):
    ws.cell(column=1, row=1+i, value=random()*100)
    ws.cell(column=2, row=1+i, value=randrange(1,5))

#calculate standard deviations for specific integer values
for i in range(4):
    ws.cell(column=4+i, row=1, value='STDEV {0}'.format(i+1))
    ws.cell(column=4+i, row=2, value='=STDEV.P(IF(B1:B100={0},A1:A100," "))'.format(i+1))
    targetVal = '{0}2'.format(get_column_letter(4+i))
    ws.formula_attributes[targetVal] = {'t': 'array', 'ref': targetVal}

#cleaning up
ws = wb.get_sheet_by_name("Sheet")
wb.remove_sheet(ws)

wb.save("fTest.xlsx")

示例的快速解释:我在 A 列中生成 0 到 100 之间的 100 个随机数,在 B 列中生成 1 到 4(含)之间的整数。 在包含 STDEV 1 的单元格下方,我计算 A 列中所有 B 列中为 1 的值的标准偏差,其他 STDEV 列也是如此。
生成的excel文档应该有“#NAME?”如果您的 excel 设置为自动计算,请在 STDEV.P 单元格中。如果您输入公式并使用 CTRL+SHIFT+ENTER 执行,则公式将正确执行。

【问题讨论】:

    标签: python excel


    【解决方案1】:

    open-pyxl 的 STDEV.P 函数存在错误。像这样添加全名:

    ws.cell(column=4+i, row=2, value='=_xlfn.STDEV.P(IF(B1:B100={},A1:A100,0))'.format(i+1))
    

    它会正常工作。

    你也可以看到Here

    您可以在documentation 中看到并非所有公式都包含在内:

    如果您尝试使用未知的公式,这可能是因为您使用的公式未包含在初始规范中。此类公式必须以 xlfn 为前缀。工作

    要检查是否包含公式,您可以使用:

    from openpyxl.utils import FORMULAE
    
    print "STDEV.P" in FORMULAE
    

    如果为 false,则应将_xlfn. 放在公式名称之前以使其起作用。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-08-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多