Cómo pasar parámetros entre macros de Word VBA y powershell
🔍 WiseChecker

Cómo pasar parámetros entre macros de Word VBA y powershell

Necesita enviar datos desde una macro de Word VBA a un script de PowerShell y recibir resultados de vuelta. Esto es común cuando VBA no puede realizar operaciones de archivo como renombrar muchos documentos o consultar servicios del sistema. El desafío es que VBA y PowerShell no comparten memoria ni variables directamente. Este artículo explica tres métodos confiables para pasar parámetros entre Word VBA y PowerShell: argumentos de línea de comandos, archivos de texto temporales y el portapapeles.

Puntos clave: Pasar parámetros entre Word VBA y PowerShell

  • Argumentos de línea de comandos con Shell.Run: Pase un parámetro de cadena directamente a un script de PowerShell sin crear archivos intermedios.
  • Archivo de texto temporal mediante VBA FileSystemObject: Intercambie datos estructurados como matrices u objetos entre VBA y PowerShell cuando los argumentos superen los 8191 caracteres.
  • Portapapeles mediante Word VBA y Get-Clipboard: Comparta valores pequeños y simples como un nombre de documento o una ruta sin escribir en el disco.

ADVERTISEMENT

Por qué el paso directo de parámetros no funciona entre VBA y PowerShell

Word VBA se ejecuta dentro del proceso de Word. PowerShell se ejecuta en un proceso separado. No pueden llamar a las funciones del otro ni compartir variables. VBA puede iniciar un proceso de PowerShell usando la función Shell o el método Shell.Run, pero no puede leer la salida de PowerShell directamente sin pasos adicionales. La misma limitación se aplica a la inversa: un script de PowerShell no puede modificar variables de VBA ni llamar a funciones de VBA.

Para pasar parámetros de VBA a PowerShell, debe usar uno de estos métodos de comunicación entre procesos:

  • Argumentos de línea de comandos: Pase datos como una cadena al iniciar el proceso de PowerShell. El script los lee desde la matriz $args o un parámetro con nombre.
  • Archivo temporal: VBA escribe datos en un archivo de texto. PowerShell lee ese archivo, procesa los datos y escribe la salida en otro archivo que VBA lee.
  • Portapapeles: VBA copia texto al portapapeles. PowerShell lo recupera con Get-Clipboard. Esto solo funciona para pequeñas cantidades de texto.

Cada método tiene un límite máximo de tamaño de datos. Los argumentos de línea de comandos están limitados a 8191 caracteres en Windows. El portapapeles está limitado por la memoria disponible, pero no es práctico para más de unos pocos kilobytes. Un archivo temporal no tiene límite práctico.

Método 1: Pasar parámetros mediante argumentos de línea de comandos

Este es el método más simple. Pase uno o más valores como argumentos al iniciar PowerShell desde VBA. El script los lee desde la matriz automática $args o desde parámetros con nombre definidos con param().

  1. Cree el script de PowerShell
    Abra el Bloc de notas y guarde esto como C:\Scripts\ProcessDoc.ps1:
    param([string]$docPath, [string]$action)
    Write-Host "Processing $docPath with action $action"
    # Your processing code here
  2. Escriba la macro de VBA en Word
    Presione Alt+F11 para abrir el editor de VBA. Inserte un nuevo módulo y pegue:
    Sub RunPowerShellWithArgs()
    Dim psCmd As String
    Dim docPath As String
    Dim action As String
    docPath = ActiveDocument.FullName
    action = "ConvertToPDF"
    psCmd = "powershell.exe -ExecutionPolicy Bypass -File " & Chr(34) & _
    "C:\Scripts\ProcessDoc.ps1" & Chr(34) & " -docPath " & Chr(34) & _
    docPath & Chr(34) & " -action " & Chr(34) & action & Chr(34)
    Shell psCmd, vbHide
    End Sub
  3. Ejecute la macro
    Presione F5 en el editor de VBA. PowerShell se abre, ejecuta el script y sale. El script recibe la ruta del documento y la acción como cadenas.

Use Chr(34) para envolver cada argumento entre comillas dobles. Esto evita errores cuando la ruta contiene espacios. El indicador -ExecutionPolicy Bypass permite que el script se ejecute incluso si la política de ejecución de PowerShell está restringida.

ADVERTISEMENT

Método 2: Pasar parámetros mediante un archivo de texto temporal

Use un archivo temporal cuando necesite pasar datos complejos como matrices, múltiples rutas de archivos o datos estructurados. VBA escribe los datos en un archivo en la carpeta Temp del usuario. PowerShell lee ese archivo, procesa los datos y escribe los resultados en un segundo archivo. Luego VBA lee el archivo de salida.

  1. Cree el script de PowerShell
    Guarde esto como C:\Scripts\BatchProcess.ps1:
    param([string]$inputFile, [string]$outputFile)
    $data = Get-Content $inputFile
    $results = @()
    foreach ($line in $data) {
    $results += "Processed: $line"
    }
    $results | Out-File $outputFile
  2. Escriba la macro de VBA
    En el editor de VBA, inserte un nuevo módulo y pegue:
    Sub RunPowerShellWithFile()
    Dim fso As Object
    Dim tempFolder As String
    Dim inputFile As String
    Dim outputFile As String
    Dim psCmd As String
    Dim fileList As String
    Set fso = CreateObject("Scripting.FileSystemObject")
    tempFolder = fso.GetSpecialFolder(2) ' Temp folder
    inputFile = tempFolder & "\vba_input.txt"
    outputFile = tempFolder & "\vba_output.txt"
    ' Write data to input file
    fileList = "C:\Docs\Report1.docx" & vbCrLf & "C:\Docs\Report2.docx"
    fso.CreateTextFile(inputFile).Write fileList
    ' Run PowerShell
    psCmd = "powershell.exe -ExecutionPolicy Bypass -File " & Chr(34) & _
    "C:\Scripts\BatchProcess.ps1" & Chr(34) & _
    " -inputFile " & Chr(34) & inputFile & Chr(34) & _
    " -outputFile " & Chr(34) & outputFile & Chr(34)
    Shell psCmd, vbHide
    ' Wait for script to finish
    Application.Wait Now + TimeValue("0:00:02")
    ' Read output file
    Dim result As String
    result = fso.OpenTextFile(outputFile).ReadAll
    MsgBox result
    End Sub
  3. Ejecute la macro
    Presione F5. La macro escribe la lista de archivos en vba_input.txt, ejecuta PowerShell, espera dos segundos y muestra los resultados de vba_output.txt.

La línea Application.Wait le da tiempo a PowerShell para terminar. Para scripts más largos, use un bucle que verifique si el archivo de salida existe antes de leerlo.

Método 3: Pasar parámetros mediante el portapapeles

Use el portapapeles para un único valor pequeño, como un nombre de documento o una ruta de carpeta. VBA copia el texto al portapapeles. PowerShell lo recupera con Get-Clipboard. Este método no crea archivos temporales.

  1. Cree el script de PowerShell
    Guarde esto como C:\Scripts\ClipboardProcess.ps1:
    $clipText = Get-Clipboard
    Write-Host "Clipboard contains: $clipText"
    # Your processing code here
  2. Escriba la macro de VBA
    En el editor de VBA, inserte un nuevo módulo y pegue:
    Sub RunPowerShellWithClipboard()
    Dim psCmd As String
    ' Copy document path to clipboard
    With New DataObject
    .SetText ActiveDocument.FullName
    .PutInClipboard
    End With
    psCmd = "powershell.exe -ExecutionPolicy Bypass -File " & Chr(34) & _
    "C:\Scripts\ClipboardProcess.ps1" & Chr(34)
    Shell psCmd, vbHide
    End Sub
  3. Habilite la Biblioteca de objetos de Microsoft Forms 2.0
    En el editor de VBA, haga clic en Herramientas > Referencias. Marque Biblioteca de objetos de Microsoft Forms 2.0. Esto agrega la clase DataObject utilizada para el acceso al portapapeles.

El método del portapapeles sobrescribe lo que el usuario tenga en el portapapeles. Úselo solo cuando controle todo el flujo de trabajo y el usuario no esté copiando otros datos.

ADVERTISEMENT

Problemas comunes al pasar parámetros entre VBA y PowerShell

El script de PowerShell no se ejecuta o no muestra salida

La causa más común es la política de ejecución de PowerShell. De forma predeterminada, Windows bloquea la ejecución de scripts. Incluya siempre -ExecutionPolicy Bypass en la línea de comandos. Si el script aún no se ejecuta, abra PowerShell como administrador y ejecute Set-ExecutionPolicy RemoteSigned para permitir scripts locales de forma permanente.

Los espacios en las rutas de archivo rompen el comando

Cuando una ruta de archivo contiene espacios, PowerShell interpreta la ruta como múltiples argumentos. Envuelva cada argumento de ruta entre comillas dobles usando Chr(34) en VBA. Por ejemplo: """" & docPath & """" produce una cadena entre comillas.

La macro de VBA termina antes de que PowerShell complete

La función Shell ejecuta PowerShell de forma asíncrona. VBA continúa a la siguiente línea inmediatamente. Para esperar a que PowerShell termine, use el método Run del objeto WScript.Shell con el parámetro wait establecido en True: CreateObject("WScript.Shell").Run psCmd, 0, True. El tercer parámetro True hace que VBA espere hasta que el proceso salga.

El script de PowerShell no puede acceder a los objetos de Word

PowerShell se ejecuta en un proceso separado. No puede llamar al modelo de objetos de Word directamente a menos que use el objeto COM de Word dentro de PowerShell. Si necesita que PowerShell interactúe con Word, agregue esto al script: $word = New-Object -ComObject Word.Application; $doc = $word.Documents.Open($docPath). Pase la ruta del documento como parámetro como se describe en el Método 1.

Elemento Argumentos de línea de comandos Archivo de texto temporal Portapapeles
Límite de datos 8191 caracteres en total Sin límite práctico Limitado por la memoria, poco práctico por encima de 10 KB
Velocidad Más rápido, sin E/S de disco Más lento debido a la lectura/escritura de archivos Rápido, sin E/S de disco
Compatibilidad con datos complejos Solo cadenas simples Matrices, texto estructurado, JSON Una sola cadena de texto
Portapapeles del usuario sobrescrito No No Sí
Mejor caso de uso Uno o dos parámetros de cadena cortos Múltiples rutas de archivo, datos grandes o resultados que se necesitan de vuelta en VBA Transferencia rápida de un solo valor en un flujo de trabajo controlado

Ahora puede pasar parámetros desde Word VBA a PowerShell usando argumentos de línea de comandos, archivos temporales o el portapapeles. Cada método sirve a un requisito diferente de tamaño y complejidad de datos. Comience con argumentos de línea de comandos para tareas simples. Cambie a un archivo temporal cuando necesite intercambiar matrices o conjuntos de datos grandes. Use el portapapeles solo para transferencias pequeñas de un solo valor en flujos de trabajo donde controle el contenido del portapapeles. Para ampliar esto aún más, considere escribir la salida de PowerShell en un archivo XML y analizarlo en VBA con el objeto MSXML2.DOMDocument para el intercambio de datos estructurados.

ADVERTISEMENT