问题描述:我一直在手动使用与excel加载项配合使用的电子表格。我正在尝试使用win32com和python使其自动化。我可以将值输入到输入单元格中,但是工作表不会重新计算。当我尝试读取输出单元格时,出现如下所述的错误。另外,在运行下面的代码之后,当我手动打开工作表时,我看到计算出的单元格都说#VALUE!。手动,我可以按CTRL + ALT + F9,然后重新计算工作表,不留下#VALUE!细胞。请注意,当我说“计算单元格”时,这些单元格依赖于VBA宏/外接程序一部分的功能。
主要问题:如何从python强制重新计算工作表?
代码:
import win32com.client
import win32api
def open_util():
excel = win32com.client.Dispatch("Excel.Application")
wb1 = excel.Workbooks.Open(r'C:\...the add-in.xla')
wb = excel.Workbooks.Open(r'C:\...the file name.xlsm')
ws = wb.Worksheets('the sheet name')
# get the values from two cells.
myInput = ws.Cells(1,1).Value # this is an input cell, not calculated
myOutput = ws.Cells(1,2).Value # this cell is calculated
print("The original value of myOutput is : ", myOutput)
# put a new value into the input cell.
newInput = 42
ws.Cells(1,1).Value = newInput
# Now I want the sheet to recalculate and give me a new output.
# (when manually operating this spreadsheet, I just input a new value,
# and the whole sheet automatically recalculates)
# Note: these two lines of code appear not to have any effect.
ws.EnableCalculation = True
ws.Calculate()
# get the new output
newOutput = ws.Cells(1,2).Value
wb.Close(True)
print("newOutput is : ", newOutput)
return True # I haven't finished writing the function... no return value yet.
输出:
The original value of myOutput is : 10 # this is fine.
newOutput is : -2146826273 # when I open the spreadsheet, this cell now says #VALUE!
关于插件:我正在使用与化学相关的软件,该软件基本上是一个复杂的电子表格和execel插件。代码中的输出单元格显示“ #VALUE!”:它们使用命名的公式,这些公式位于我看不到的宏中(我想不放弃与化学相关的软件的代码)。>
类似的问题:我发现了this similar question。就我而言,我不确定加载项是否包含在计算单元中。无论如何,我尝试添加答案中建议的代码:
def open_util():
excel = win32com.client.Dispatch("Excel.Application")
excel.AddIns.Add("rC:\...\add-in.xla").Installed = True # <-- This is the line I added.
...
但是,这只会生成一条错误消息:
Traceback (most recent call last):
File "C:\...\my_program_name.py", line 246, in <module>
open_util()
File "C:\...\my_program_name.py", line 216, in open_util
excel.AddIns.Add("C:\...\add-in.xla").Installed = True
File "C:\Users\00168070\AppData\Local\Programs\Python\Python36-32\lib\site-packages\win32com\gen_py\00020813-0000-0000-C000-000000000046x0x1x9\AddIns.py", line 35, in Add
, CopyFile)
pywintypes.com_error: (-2147352567, '例外が発生しました。', (0, 'Microsoft Excel', 'Add method of AddIns class failed', 'xlmain11.chm', 0, -2146827284), None)
(注意:我认为日语的意思是“发生了异常”。)
其他问题:是否有关于excel可用的python / win32com函数以及如何使用它们编写程序的文档? (例如,直到在别人的代码的碎片中看到它,我才知道我需要代码行“ ws.EnableCalculation = True”。)我只找到了一些教程。
答案 0 :(得分:0)
有点晚了,但是我遇到了类似的问题。我也在使用第三方加载项。我相信这是造成问题的原因。
测试用例以查看
ws.EnableCalculation = True
ws.Calculate()
正在工作
import time
import win32com.client
xlApp = win32com.client.Dispatch("Excel.Application")
xlApp.Visible = True # so we can see what is happening
wb = xlApp.Workbooks.Open(excel_wb) # make excel wb a saved file where A1 = A2 + A3
ws = wb.ActiveSheet
for x in range(9):
ws.EnableCalculation = False
ws.Range('A2').Value = x
ws.Range('A3').Value = 2 * x
print(ws.Range('A1').Value) # value in A1 should remain the same
time.sleep(10)
ws.EnableCalculation = True
ws.Calculate()
# value in A1 should update
print(ws.Range('A1').Value) # value in A1 should be updated
这对我来说很好。我们的预期输出为0、3、3、6、6、9等,因为它在更新前保持不变。
要解决此问题,请2a。使用finally语句在程序和2b的结尾处关闭excel。在主函数的开头显式添加一个命令行excel kill
2a。
def quit_xl(xlApp, xlWB=None, save=True):
if xlWB is not None:
xlWB.Close(save)
xlApp.Quit()
del xlApp
2b。
import subprocess # be careful - make sure that an outside user can't pass anything in
def kill_xl():
try:
kill_excel = """"“taskkill / f / im
excel.exe”""" # command prompt to kill all excel instances
subprocess.run(kill_excel, shell=True)
return 0
except Exception as e:
return 1
放在一起:
def main():
kill_xl()
xlApp = win32com.client.Dispatch("Excel.Application")
try:
pass # main part of function
except Exception as e:
pass # if something goes wrong
finally:
quit_xl(xlApp)