我正在使用以下代码从Python运行Excel宏:
import pymysql
import datetime
import csv
import math
import os
import glob
import sys
import win32com.client
import numpy
from tkinter import *
from tkinter import ttk
import tkinter.messagebox
def run_macro():
print('macro')
#this if is here because if an executable is created, __file__ doesn't work
if getattr(sys, 'frozen', False):
name = (os.path.dirname(sys.executable) + '\\Forecast template.xlsm')
else:
name = str(os.path.dirname(os.path.realpath(__file__)) + '\\Forecast template.xlsm')
print(name)
#this part runs the macro from excel
if os.path.exists(name):
xl=win32com.client.Dispatch("Excel.Application")
xl.Workbooks.Open(Filename=name, ReadOnly=1)
xl.Application.Run("ThisWorkbook.LoopFilesInFolder")
xl.Application.Quit() # Comment this out if your excel script closes
del xl
print('File refreshed!')
我似乎遇到了这个问题,在运行之后,我打开任何excel文件,我只得到一个灰色的窗口:
知道为什么会这样吗?另外我如何在Excel中添加一些只打开文件的代码? (不是为了获取信息,而是在Excel中打开该文件)
额外的问题:如何解决所有打开的Excel文件?
编辑:我刚检查了宏,这很好用,问题似乎来自于我运行代码时。
新编辑:
这是宏的代码:
Sub LoopFilesInFolder()
Dim wb1 As Workbook
Dim wb2 As Workbook
Dim path As String
Dim file As String
Dim extension As String
Dim myFileName As String
Application.ScreenUpdating = False
Application.DisplayAlerts = False
Set wb1 = ActiveWorkbook
path = ActiveWorkbook.path & "\csvs\"
extension = "*.csv"
file = Dir(path & extension)
Do While file <> ""
Set wb2 = Workbooks.Open(Filename:=path & file)
wb2.Activate
'this section is for the avail heads file, basically it just opens it and copies the info to the template
If wb2.Name = "avail_heads.csv" Then
Range("A1").Select
Range(Selection, Selection.End(xlDown)).Select
Range(Selection, Selection.End(xlToRight)).Select
Selection.Copy
wb1.Activate
Worksheets("raw data").Range("B88").PasteSpecial xlPasteValues
End If
'this section is for the forecast file, basically it just opens it and copies the info to the template
If wb2.Name = "forecast.csv" Then
Range("A1").Select
Range(Selection, Selection.End(xlDown)).Select
Range(Selection, Selection.End(xlToRight)).Select
Selection.Copy
wb1.Activate
Worksheets("raw data").Range("B74").PasteSpecial xlPasteValues
End If
'this section is for the income file, basically it just opens it and copies the info to the template
If wb2.Name = "income volume.csv" Then
Range("A1").Select
Range(Selection, Selection.End(xlDown)).Select
Range(Selection, Selection.End(xlToRight)).Select
Selection.Copy
wb1.Activate
Worksheets("raw data").Range("B3").PasteSpecial xlPasteValues
End If
'this section is for the outgoing volume file, basically it just opens it and copies the info to the template
If wb2.Name = "outgoing_volume.csv" Then
Range("A1").Select
Range(Selection, Selection.End(xlDown)).Select
Range(Selection, Selection.End(xlToRight)).Select
Selection.Copy
wb1.Activate
Worksheets("raw data").Range("B36").PasteSpecial xlPasteValues
End If
'this section is for the required heads file, basically it just opens it and copies the info to the template
If wb2.Name = "required_heads.csv" Then
Range("A1").Select
Range(Selection, Selection.End(xlDown)).Select
Range(Selection, Selection.End(xlToRight)).Select
Selection.Copy
wb1.Activate
Worksheets("raw data").Range("B102").PasteSpecial xlPasteValues
End If
wb2.Close
file = Dir
Loop
'myFileName = ActiveWorkbook.path & "\forecast_for_w" & Format(Now, "ww") + 1
myFileName = ActiveWorkbook.path & "\yoda_forecast"
ActiveWorkbook.SaveAs Filename:=myFileName, FileFormat:=xlWorkbookNormal
'MsgBox "Done!"
Application.DisplayAlerts = True
End Sub
答案 0 :(得分:4)
我在赏金上花了差不多一个星期,我真的不知道之前有多少人遇到过这个问题。把头发撕了一个多星期,考虑多次跳出办公室的窗户后,我想出了问题所在。
你的问题不在python(有点),但主要是在VBA代码上,我刚刚添加了
Application.ScreenUpdating = True
最后,问题停止了。不确定是否在宏完成时没有更新的excel错误或者一旦宏完成就不允许屏幕更新的python错误。但是在这之后一切都很好。
谢谢!
答案 1 :(得分:0)
您需要在调度后将可见性设置为True:
xl = win32com.client.Dispatch("Excel.Application")
xl.Application.Visible = True
另外,调用宏不应该需要ThisWorkbook
:
xl.Application.Run("LoopFilesInFolder")
为了能够再次关闭工作簿,您需要将其分配给变量:
wb = xl.Workbooks.Open(Filename=name, ReadOnly=1)
wb.Close(SaveChanges=False)
我编写了包xlwings以简化操作:
from xlwings import Workbook, Range
wb = Workbook(r'C:\path\to\workbook.xlsx') # open a workbook if not open yet
Range('A1').value = 123 # Write a value to cell A1
wb.close() # close the workbook again
运行宏还没有实现,但是issue已经开放了。在此期间,您可以通过执行此操作(从上面开始):
wb.xl_app.Run("macro_name")