Pregunta

Tengo una macro VBA de Excel que tengo que correr al acceder al archivo desde un archivo por lotes, pero no cada vez que lo abro (por lo tanto no utiliza el archivo abierto de eventos).Es allí una manera de ejecutar la macro desde la línea de comandos o un archivo por lotes?Yo no estoy familiarizado con dicho comando.

Asumir un entorno de Windows NT.

¿Fue útil?

Solución

Puede iniciar Excel, abra el libro y ejecutar la macro desde un archivo VBScript.

Copia el código siguiente en el Bloc de notas.

Actualizar el ' MyWorkbook.xls ' y ' MiMacro ' parámetros.

Guardar con una extensión VBS y ejecutarlo.

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 

La línea clave que se ejecuta la macro es:

xlApp.Run "MiMacro"

Otros consejos

La forma más sencilla de hacerlo es:

1) Iniciar Excel de su archivo por lotes para abrir el libro que contiene la macro:

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

2) Llame a su macro de evento Workbook_Open del libro de trabajo, como por ejemplo:

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

Esto ahora devolverá el control a su archivo por lotes para hacer otro tipo de elaboración.

El método se muestra a continuación permite ejecutar macro Excel definido de archivo por lotes, que utiliza variable de entorno para pasar nombre de macro de lote a Excel.

Pon este código al archivo por lotes (utilizar sus caminos a EXCEL.EXE y al libro):

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

Pon este código a Excel VBA ThisWorkbook del objeto:

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

Y poner su código a Excel VBA módulo, como la siguiente:

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

Iniciar el archivo por lotes y obtener el resultado:

 di&aacute;logo de macro

En el caso en el que no tiene intención de ejecutar cualquier macro sólo hay que poner el valor Set MacroName= vacío al lote.

se podría escribir un VBScript para crear una instancia de Excel mediante el método CreateObject (), a continuación, abrir el libro y ejecutar la macro. Se podría llamar a la VBScript directamente, o llame a la VBScript desde un archivo por lotes.

Aquí es un recurso Me tropecé al otro lado: http://www.codeguru.com/forum/showthread.php?t= 376401

Siempre he probado el número de libros abiertos en Workbook_Open (). Si es 1, entonces se abrió el libro por la línea de comandos (o el usuario cierra todos los libros, entonces abierto éste).

If Workbooks.Count = 1 Then

    ' execute the macro or call another procedure - I always do the latter  
    PublishReport

    ThisWorkbook.Save

    Application.Quit

End If

Si usted es más cómodo trabajando dentro de Excel / VBA, utilice el evento abierto y probar el entorno:. O bien tienen un archivo de señal, una entrada de registro o una variable de entorno que controla lo que hace el evento abierto

Puede crear el archivo / ajuste exterior y el interior de la prueba (GetEnviromentVariable utilizar para env-VARs) y la prueba con facilidad. He escrito VBScript, pero las similitudes con VBA me causan más angustia que la facilidad ..

[más]

A mi entender el problema, desea utilizar una hoja de cálculo normalmente la mayor parte / parte del tiempo sin embargo, hacer que se ejecute en el lote y hacer algo extra / diferente. Puede abrir la hoja desde la línea de comandos excel.exe pero no se puede controlar lo que hace a menos que sepa dónde está. El uso de una variable de entorno es relativamente simple y hace que las pruebas de la hoja de cálculo fácil.

Para aclarar, utilice la función siguiente para examinar el medio ambiente. En un declarar módulo:

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

En el evento abierto libro de trabajo (como otros):

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

Añadir en el código activo según sea el caso. En el archivo por lotes, utilice

set InBatch=TRUE

En lugar de comparar directamente las cuerdas (VB no encontrarlos igual desde GetEnvironmentVariable devuelve una cadena de longitud 255) escribir lo siguiente:

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 

@ Robert:He tratado de adaptar su código con la ruta de acceso relativa, y crea un archivo por lotes para ejecutar el VBS.

El VBS que se inicia y se cierra pero no se inicia la macro...Alguna idea de donde podría ser el problema?

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

He quitado de la Aplicación".Dejar de fumar" porque mi macro es llamar a un formulario de usuario de tomar el cuidado de él.

Saludos

EDITAR

En realidad he trabajado a cabo, en caso de que alguien quiere ejecutar un formulario de usuario "por igual" una aplicación independiente:

Problemas en los que estaba enfrentando:

1 - yo no quería utilizar el Evento Workbook_Open como el excel está bloqueado en sólo lectura.2 - El comando de proceso por lotes está limitado que el hecho de que (a mi conocimiento) no puede llamar a la macro.

Por primera vez me escribió una macro para el lanzamiento de mi formulario de usuario y ocultar la aplicación:

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

Entonces creé un vbs para el lanzamiento de este macro (hacerlo con una ruta de acceso relativa ha sido difícil):

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"

Y finalmente me hice un archivo por lotes para ejecutar el VBS...

@echo off
pushd %~dp0
cscript Add_Client.vbs

Tenga en cuenta que también he incluido el "volver a Establecer visible" en mi Userform_QueryClose:

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

De todos modos, gracias por tu ayuda, y espero que esto ayude si alguien lo necesita

Puede comprobar si Excel ya está abierto. No hay necesidad de crear otra 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

Soy parcial a C #. Me encontré con la siguiente usando LINQPad. Pero podría fácilmente ser compilado con CSC y corrió a través de la llamada desde la línea de comandos.

No se olvide de añadir paquetes de Excel para espacio de nombres.

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;
    }
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top