首页 文章

从命令行或批处理文件运行Excel宏的方法?

提问于
浏览
61

我有一个Excel VBA宏,我需要在从批处理文件访问文件时运行,但不是每次我打开它(因此不使用打开的文件事件) . 有没有办法从命令行或批处理文件运行宏?我不熟悉这样的命令 .

假设一个Windows NT环境 .

10 回答

  • 1

    您可以检查Excel是否已打开 . 没有必要创建另一个isntance

    If CheckAppOpen("excel.application")  Then
               'MsgBox "App Loaded"
                Set xlApp = GetObject(, "excel.Application")   
       Else
                ' MsgBox "App Not Loaded"
                Set  wrdApp = CreateObject(,"excel.Application")   
       End If
    
  • 2

    您可以启动Excel,打开工作簿并从VBScript文件运行宏 .

    将下面的代码复制到记事本中 .

    更新“MyWorkbook.xls ' and ' MyMacro”参数 .

    使用vbs扩展名保存并运行它 .

    Option Explicit
    
    On Error Resume Next
    
    ExcelMacroExample
    
    Sub ExcelMacroExample() 
    
      Dim xlApp 
      Dim xlBook 
    
      Set xlApp = CreateObject("Excel.Application") 
      Set xlBook = xlApp.Workbooks.Open("C:\MyWorkbook.xls", 0, True) 
      xlApp.Run "MyMacro"
      xlApp.Quit 
    
      Set xlBook = Nothing 
      Set xlApp = Nothing 
    
    End Sub
    

    运行宏的关键是:

    xlApp.Run "MyMacro"

  • 4

    最简单的方法是:

    1)从批处理文件启动Excel以打开包含宏的工作簿:

    EXCEL.EXE /e "c:\YourWorkbook.xls"
    

    2)从工作簿的 Workbook_Open 事件中调用您的宏,例如:

    Private Sub Workbook_Open()
        Call MyMacro1          ' Call your macro
        ActiveWorkbook.Save    ' Save the current workbook, bypassing the prompt
        Application.Quit       ' Quit Excel
    End Sub
    

    现在,这将把控件返回到批处理文件以进行其他处理 .

  • 2

    你可以编写一个vbscript来通过createobject()方法创建一个excel实例,然后打开工作簿并运行宏 . 您可以直接调用vbscript,也可以从批处理文件中调用vbscript .

    这是一个我偶然发现的资源:http://www.codeguru.com/forum/showthread.php?t=376401

  • 3

    下面显示的方法允许从批处理文件运行定义的Excel宏,它使用环境变量将宏名称从批处理传递到Excel .

    将此代码放入批处理文件(使用 EXCEL.EXE 和工作簿的路径):

    Set MacroName=MyMacro
    "C:\Program Files\Microsoft Office\Office15\EXCEL.EXE" "C:\MyWorkbook.xlsm"
    

    将此代码放入Excel VBA ThisWorkBook对象:

    Private Sub Workbook_Open()
        Dim strMacroName As String
        strMacroName = CreateObject("WScript.Shell").Environment("process").Item("MacroName")
        If strMacroName <> "" Then Run strMacroName
    End Sub
    

    并将您的代码放入Excel VBA模块,如下所示:

    Sub MyMacro()
        MsgBox "MyMacro is running..."
    End Sub
    

    启动批处理文件并获取结果:

    macro's dialog

    对于不打算运行任何宏的情况,只需将空值 Set MacroName= 放入批处理中 .

  • 0

    如果您更熟悉在Excel / VBA中工作,请使用open事件并测试环境:要么具有信号文件,注册表项或控制open事件所执行操作的环境变量 .

    你可以在外面创建文件/设置并在里面测试(使用GetEnviromentVariable for env-vars)并轻松测试 . 我写了VBScript,但与VBA的相似之处让我更加焦虑而不是轻松 .

    [更多]

    正如我所理解的那样,您希望通常使用电子表格大部分/部分时间,然后批量运行并执行额外/不同的操作 . 您可以从excel.exe命令行打开工作表,但除非知道它在哪里,否则无法控制它的功能 . 使用环境变量相对简单,可以轻松测试电子表格 .

    为了澄清,请使用以下功能检查环境 . 在模块中声明:

    Private Declare Function GetEnvVar Lib "kernel32" Alias "GetEnvironmentVariableA" _
        (ByVal lpName As String, ByVal lpBuffer As String, ByVal nSize As Long) As Long
    
    Function GetEnvironmentVariable(var As String) As String
    Dim numChars As Long
    
        GetEnvironmentVariable = String(255, " ")
    
        numChars = GetEnvVar(var, GetEnvironmentVariable, 255)
    
    End Function
    

    在工作簿公开活动中(与其他人一样):

    Private Sub Workbook_Open()
        If GetEnvironmentVariable("InBatch") = "TRUE" Then
            Debug.Print "Batch"
        Else
            Debug.Print "Normal"
        End If
    End Sub
    

    根据需要添加活动代码 . 在批处理文件中,使用

    set InBatch=TRUE
    
  • 16

    而不是直接比较字符串(VB将找不到它们相同,因为GetEnvironmentVariable返回长度为255的字符串),写下:

    Private Sub Workbook_Open()     
        If InStr(1, GetEnvironmentVariable("InBatch"), "TRUE", vbTextCompare) Then
            Debug.Print "Batch"  
            Call Macro
        Else    
            Debug.Print "Normal"     
        End If 
    
    End Sub
    
  • 2

    我一直在Workbook_Open()中测试打开的工作簿的数量 . 如果为1,则命令行打开工作簿(或者用户关闭所有工作簿,然后打开此工作簿) .

    If Workbooks.Count = 1 Then
    
        ' execute the macro or call another procedure - I always do the latter  
        PublishReport
    
        ThisWorkbook.Save
    
        Application.Quit
    
    End If
    
  • 2

    @Robert:我试图用相对路径调整你的代码,并创建一个批处理文件来运行VBS .

    VBS启动和关闭,但没有启动宏...任何想法问题在哪里?

    Option Explicit
    
    On Error Resume Next
    
    ExcelMacroExample
    
    Sub ExcelMacroExample() 
    
      Dim xlApp 
      Dim xlBook 
    
      Set xlApp = CreateObject("Excel.Application")
      Set objFSO = CreateObject("Scripting.FileSystemObject")
      strFilePath = objFSO.GetAbsolutePathName(".") 
      Set xlBook = xlApp.Workbooks.Open(strFilePath, "Excels\CLIENTES.xlsb") , 0, True) 
      xlApp.Run "open_form"
    
    
      Set xlBook = Nothing 
      Set xlApp = Nothing 
    
    End Sub
    

    我删除了“Application.Quit”,因为我的宏正在调用userform来处理它 .

    干杯

    EDIT

    我实际上已经解决了这个问题,以防万一有人想要运行一个“相似”的用户表单:一个独立的应用程序:

    我面临的问题:

    1 - 我不想使用Workbook_Open事件,因为excel被锁定为只读 . 2 - 批处理命令受限于(据我所知)它无法调用宏的事实 .

    我首先写了一个宏来启动我的userform同时隐藏应用程序:

    Sub open_form()
     Application.Visible = False
     frmAddClient.Show vbModeless
    End Sub
    

    然后我创建了一个vbs来启动这个宏(用相对路径做这件事很棘手):

    dim fso
    dim curDir
    dim WinScriptHost
    set fso = CreateObject("Scripting.FileSystemObject")
    curDir = fso.GetAbsolutePathName(".")
    set fso = nothing
    
    Set xlObj = CreateObject("Excel.application")
    xlObj.Workbooks.Open curDir & "\Excels\CLIENTES.xlsb"
    xlObj.Run "open_form"
    

    我终于做了一个批处理文件来执行VBS ......

    @echo off
    pushd %~dp0
    cscript Add_Client.vbs
    

    请注意,我还在 Userform_QueryClose 中包含了"Set back to visible":

    Private Sub cmdClose_Click()
    Unload Me
    End Sub
    
    Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer)
        ThisWorkbook.Close SaveChanges:=True
        Application.Visible = True
        Application.Quit
    End Sub
    

    无论如何,感谢您的帮助,我希望如果有人需要,这将有所帮助

  • 72

    我偏爱C# . 我使用linqpad运行以下命令 . 但它可以很容易地用csc编译并从命令行运行调用 .

    不要忘记将excel包添加到命名空间 .

    void Main()
    {
        var oExcelApp = (Microsoft.Office.Interop.Excel.Application)System.Runtime.InteropServices.Marshal.GetActiveObject("Excel.Application");
        try{
            var WB = oExcelApp.ActiveWorkbook;
            var WS = (Worksheet)WB.ActiveSheet;
            ((string)((Range)WS.Cells[1,1]).Value).Dump("Cell Value"); //cel A1 val
            oExcelApp.Run("test_macro_name").Dump("macro");
        }
        finally{
            if(oExcelApp != null)
                System.Runtime.InteropServices.Marshal.ReleaseComObject(oExcelApp);
            oExcelApp = null;
        }
    }
    

相关问题