Você precisa enviar dados de uma macro VBA do Word para um script PowerShell e receber os resultados de volta. Isso é comum quando o VBA não consegue realizar operações de arquivo, como renomear vários documentos ou consultar serviços do sistema. O desafio é que o VBA e o PowerShell não compartilham memória ou variáveis diretamente. Este artigo explica três métodos confiáveis para passar parâmetros entre VBA do Word e PowerShell: argumentos de linha de comando, arquivos de texto temporários e a área de transferência.
Principais Conclusões: Passar Parâmetros Entre VBA do Word e PowerShell
- Argumentos de linha de comando com Shell.Run: Passe um parâmetro de string diretamente para um script PowerShell sem criar arquivos intermediários.
- Arquivo de texto temporário via FileSystemObject do VBA: Troque dados estruturados como arrays ou objetos entre VBA e PowerShell quando os argumentos excederem 8191 caracteres.
- Área de transferência via VBA do Word e Get-Clipboard: Compartilhe valores pequenos e simples, como um nome de documento ou caminho, sem gravar em disco.
Por Que a Passagem Direta de Parâmetros Não Funciona Entre VBA e PowerShell
O VBA do Word é executado dentro do processo do Word. O PowerShell é executado em um processo separado. Eles não podem chamar as funções um do outro nem compartilhar variáveis. O VBA pode iniciar um processo PowerShell usando a função Shell ou o método Shell.Run, mas não pode ler a saída do PowerShell diretamente sem etapas extras. A mesma limitação se aplica ao contrário: um script PowerShell não pode modificar variáveis do VBA nem chamar funções do VBA.
Para passar parâmetros do VBA para o PowerShell, você deve usar um destes métodos de comunicação entre processos:
- Argumentos de linha de comando: Passe dados como uma string ao iniciar o processo PowerShell. O script os lê do array $args ou de um parâmetro nomeado.
- Arquivo temporário: O VBA grava dados em um arquivo de texto. O PowerShell lê esse arquivo, processa os dados e grava a saída em outro arquivo que o VBA lê.
- Área de transferência: O VBA copia texto para a área de transferência. O PowerShell o recupera com Get-Clipboard. Isso funciona apenas para pequenas quantidades de texto.
Cada método tem um limite máximo de tamanho de dados. Os argumentos de linha de comando são limitados a 8191 caracteres no Windows. A área de transferência é limitada pela memória disponível, mas é impraticável para mais de alguns kilobytes. Um arquivo temporário não tem limite prático.
Método 1: Passar Parâmetros Via Argumentos de Linha de Comando
Este é o método mais simples. Você passa um ou mais valores como argumentos ao iniciar o PowerShell a partir do VBA. O script os lê do array automático $args ou de parâmetros nomeados definidos com param().
- Crie o script PowerShell
Abra o Bloco de Notas e salve como C:\Scripts\ProcessDoc.ps1:param([string]$docPath, [string]$action)
Write-Host "Processando $docPath com ação $action"
# Seu código de processamento aqui - Escreva a macro VBA no Word
Pressione Alt+F11 para abrir o editor VBA. Insira um novo módulo e cole:Sub ExecutarPowerShellComArgs()
Dim psCmd As String
Dim docPath As String
Dim action As String
docPath = ActiveDocument.FullName
action = "ConverterParaPDF"
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 - Execute a macro
Pressione F5 no editor VBA. O PowerShell abre, executa o script e fecha. O script recebe o caminho do documento e a ação como strings.
Use Chr(34) para envolver cada argumento em aspas duplas. Isso evita erros quando o caminho contém espaços. A flag -ExecutionPolicy Bypass permite que o script seja executado mesmo se a política de execução do PowerShell estiver restrita.
Método 2: Passar Parâmetros Via um Arquivo de Texto Temporário
Use um arquivo temporário quando precisar passar dados complexos como arrays, vários caminhos de arquivo ou dados estruturados. O VBA grava os dados em um arquivo na pasta Temp do usuário. O PowerShell lê esse arquivo, processa os dados e grava os resultados em um segundo arquivo. O VBA então lê o arquivo de saída.
- Crie o script PowerShell
Salve como C:\Scripts\BatchProcess.ps1:param([string]$inputFile, [string]$outputFile)
$data = Get-Content $inputFile
$results = @()
foreach ($line in $data) {
$results += "Processado: $line"
}
$results | Out-File $outputFile - Escreva a macro VBA
No editor VBA, insira um novo módulo e cole:Sub ExecutarPowerShellComArquivo()
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) ' Pasta Temp
inputFile = tempFolder & "\vba_input.txt"
outputFile = tempFolder & "\vba_output.txt"
' Gravar dados no arquivo de entrada
fileList = "C:\Docs\Relatorio1.docx" & vbCrLf & "C:\Docs\Relatorio2.docx"
fso.CreateTextFile(inputFile).Write fileList
' Executar 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
' Aguardar o script terminar
Application.Wait Now + TimeValue("0:00:02")
' Ler arquivo de saída
Dim result As String
result = fso.OpenTextFile(outputFile).ReadAll
MsgBox result
End Sub - Execute a macro
Pressione F5. A macro grava a lista de arquivos em vba_input.txt, executa o PowerShell, aguarda dois segundos e exibe os resultados de vba_output.txt.
A linha Application.Wait dá tempo para o PowerShell terminar. Para scripts mais longos, use um loop que verifica se o arquivo de saída existe antes de lê-lo.
Método 3: Passar Parâmetros Via Área de Transferência
Use a área de transferência para um único valor pequeno, como um nome de documento ou caminho de pasta. O VBA copia o texto para a área de transferência. O PowerShell o recupera com Get-Clipboard. Este método não cria arquivos temporários.
- Crie o script PowerShell
Salve como C:\Scripts\ClipboardProcess.ps1:$clipText = Get-Clipboard
Write-Host "A área de transferência contém: $clipText"
# Seu código de processamento aqui - Escreva a macro VBA
No editor VBA, insira um novo módulo e cole:Sub ExecutarPowerShellComClipboard()
Dim psCmd As String
' Copiar caminho do documento para a área de transferência
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 - Habilite a biblioteca Microsoft Forms 2.0 Object Library
No editor VBA, clique em Ferramentas > Referências. Marque Microsoft Forms 2.0 Object Library. Isso adiciona a classe DataObject usada para acesso à área de transferência.
O método da área de transferência sobrescreve o que o usuário tiver na área de transferência. Use-o apenas quando você controlar todo o fluxo de trabalho e o usuário não estiver copiando outros dados.
Problemas Comuns ao Passar Parâmetros Entre VBA e PowerShell
O script PowerShell não executa ou não mostra saída
A causa mais comum é a política de execução do PowerShell. Por padrão, o Windows bloqueia a execução de scripts. Sempre inclua -ExecutionPolicy Bypass na linha de comando. Se o script ainda não executar, abra o PowerShell como administrador e execute Set-ExecutionPolicy RemoteSigned para permitir scripts locais permanentemente.
Espaços em caminhos de arquivo quebram o comando
Quando um caminho de arquivo contém espaços, o PowerShell interpreta o caminho como vários argumentos. Envolva cada argumento de caminho em aspas duplas usando Chr(34) no VBA. Por exemplo: """" & docPath & """" produz uma string entre aspas.
A macro VBA termina antes do PowerShell concluir
A função Shell executa o PowerShell de forma assíncrona. O VBA continua para a próxima linha imediatamente. Para aguardar o PowerShell terminar, use o método Run do objeto WScript.Shell com o parâmetro wait definido como True: CreateObject("WScript.Shell").Run psCmd, 0, True. O terceiro parâmetro True faz o VBA esperar até que o processo termine.
O script PowerShell não consegue acessar objetos do Word
O PowerShell é executado em um processo separado. Ele não pode chamar o modelo de objetos do Word diretamente, a menos que use o objeto COM do Word dentro do PowerShell. Se você precisar que o PowerShell interaja com o Word, adicione isto ao script: $word = New-Object -ComObject Word.Application; $doc = $word.Documents.Open($docPath). Passe o caminho do documento como um parâmetro conforme descrito no Método 1.
| Item | Argumentos de Linha de Comando | Arquivo de Texto Temporário | Área de Transferência |
|---|---|---|---|
| Limite de dados | 8191 caracteres no total | Sem limite prático | Limitado pela memória, impraticável acima de 10 KB |
| Velocidade | Mais rápido, sem E/S de disco | Mais lento devido à leitura/gravação de arquivo | Rápido, sem E/S de disco |
| Suporte a dados complexos | Apenas strings simples | Arrays, texto estruturado, JSON | String de texto única |
| Área de transferência do usuário sobrescrita | Não | Não | Sim |
| Melhor caso de uso | Um ou dois parâmetros de string curtos | Vários caminhos de arquivo, dados grandes ou resultados necessários de volta no VBA | Transferência rápida de valor único em um fluxo de trabalho controlado |
Agora você pode passar parâmetros do VBA do Word para o PowerShell usando argumentos de linha de comando, arquivos temporários ou a área de transferência. Cada método atende a um requisito diferente de tamanho e complexidade de dados. Comece com argumentos de linha de comando para tarefas simples. Mude para um arquivo temporário quando precisar trocar arrays ou grandes conjuntos de dados. Use a área de transferência apenas para transferências pequenas de valor único em fluxos de trabalho onde você controla o conteúdo da área de transferência. Para ir além, considere escrever a saída do PowerShell em um arquivo XML e analisá-lo no VBA com o objeto MSXML2.DOMDocument para troca de dados estruturados.