首页 文章

从python运行excel宏

提问于
浏览
1

我正在使用以下代码从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文件,我只得到一个灰色的窗口:

enter image description here

知道为什么会这样吗?另外我如何在Excel中添加一些只打开文件的代码? (不是为了获取信息,而是在Excel中打开该文件)

额外的问题:如何解决所有打开的Excel文件?

EDIT :我刚检查了宏,这很好用,问题似乎来自于我运行代码时 .

NEW EDIT:

这是宏的代码:

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

2 回答

  • 4

    我已经花了将近一周的时间来获得此奖金,而且我真的不知道之前有多少人遇到过这个问题 . 把头发撕了一个多星期,考虑多次跳出办公室的窗户后,我想出了问题所在 .

    你问题不在python(有点),但主要是在VBA代码上,我刚刚补充说

    Application.ScreenUpdating = True
    

    在最后,问题停止了 . 不确定是否在宏完成时没有更新的excel错误或者一旦宏完成就不允许屏幕更新的python错误 . 但是这样做之后一切都很好 .

    谢谢!!

  • 0

    您需要在调度后将Visibility设置为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
    

    运行宏没有't been implemented yet, but there' s issue为此打开 . 在此期间,您可以通过执行此操作(从上面开始):

    wb.xl_app.Run("macro_name")
    

相关问题