bob*_*722 6 excel-formula openpyxl
当我将以下公式添加到单元格时,单元格的值在打印到控制台时看起来不错。但是,在保存文件后,公式在“=”之后插入了“@”(为简单起见,我提供了控制台的输出):
>>> from openpyxl import Workbook
>>> wb = Workbook()
>>> ws = wb.active
>>> ws['A1'] = '=CONCAT("Week ",TEXT(MID(' + get_column_letter(9) + '1,6,2)+ 1, "##"))'
>>> ws['A1'].value
'=CONCAT("Week ",TEXT(MID(I1,6,2)+ 1, "##"))'
>>> wb.save('formula.xlsx')
>>>
Run Code Online (Sandbox Code Playgroud)
在“formula.xlsx”文件中,公式如下所示:
=@CONCAT("Week ",TEXT(MID(I1,6,2)+ 1, "##"))
Run Code Online (Sandbox Code Playgroud)
但是,如果我指定“=SUM()”而不是“=CONCAT()”,则它会按预期保存,即不插入“@”。
我正在使用 openpyxl 3.0.3 和 Python 3.8。
非常感谢
-------- 更新 --------
我查看了“formula.xlsx”的 XML 代码;但在此之前,我在 Excel 中打开它,将单元格 A1 复制到单元格 D1 中,并从单元格 D1 中的公式中删除“@”,之后 D1 开始显示正确的值,而 A1 仍然显示“#NAME?” 错误。
因此,在单元格 D1 中进行更改后,工作表的 XML 代码显示如下:
<row r="1" spans="1:9" x14ac:dyDescent="0.45">
<c r="A1" t="e"><f ca="1">_xludf.CONCAT("Week ",TEXT(MID(I1,6,2)+ 1, "##"))</f><v>#NAME?</v></c>
<c r="D1" t="str"><f>_xlfn.CONCAT("Week ",TEXT(MID(I1,6,2)+ 1, "##"))</f><v>Week 68</v></c>
<c r="I1"><v>12345678</v></c>
</row>
Run Code Online (Sandbox Code Playgroud)
openpyxl 在上面的单元格 A1 中用于 CONCAT 的 _xludf 前缀在https://learn.microsoft.com/en-us/office/client-developer/excel/xludf上被描述为“用户定义函数” 。
这是否意味着该库无法将 CONCAT 识别为标准 Excel 函数,因此使用 _xludf 而不是 _xlfn?
-----更新结束---
正如 openpyxl文档中所指定的,只需插入公式名称即可使用已知公式。
\n\n一个可以用
\n\n>>> from openpyxl.utils import FORMULAE\n>>> "CONCAT" in FORMULAE\nFalse\nRun Code Online (Sandbox Code Playgroud)\n\n检查该公式在 openpyxl 中是否已知。如果公式不是,您需要_xlfn.在公式名称之前添加,如下所示:
>>> ws[\'A1\'] = \'=_xlfn.CONCAT("Week ",TEXT(MID(\' + get_column_letter(9) + \'1,6,2)+ 1, "##"))\nRun Code Online (Sandbox Code Playgroud)\n\n文档中也提到了:
\n\n\n\n如果您\xe2\x80\x99 尝试使用\xe2\x80\x99 未知的公式,则可能\n 因为您\xe2\x80\x99\n 使用的公式未包含在初始规范中。此类公式必须带有前缀
\n_xlfn.才能工作。
在 python 代码中显式指定 _xlfn 前缀可以解决该问题:
>>> ws['A1'] = '=_xlfn.CONCAT("Week ",TEXT(MID(' + get_column_letter(9) + '1,6,2)+ 1, "##"))'
Run Code Online (Sandbox Code Playgroud)
感谢 Dror Av。寻求指导!