titulo.jpg

Home

Principal

Assinar

 

Dicas

Excel

Word

Outlook

Office/VBA

Suplementos

Vídeos

Outros

Busque neste site:

Loading
 

Abrir Arquivos Programaticamente

Última atualização: 26/06/2012

Introdução

O Comando Shell

  -Executar Shell Sincronicamente

O Comando ShellExecute

Comentários

Referências

 

Introdução

Esta página descreve como se abre um arquivo programaticamente através do VBA.

 

O Comando Shell

O exemplo abaixo abre a calculadora do Windows:

Sub TesteShell()
    Shell ("c:\windows\system32\calc.exe")
End Sub

No entanto, a limitação desse comando é ele abrir somente arquivos executáveis. Por exemplo, se você quiser abrir uma Pasta de Trabalho específica do Excel, terá que fazer algo do tipo:

Sub TesteShell2()
    Shell ("C:\Program Files\Microsoft Office\Office14\EXCEL.EXE " & """C:\temp\Pasta1.xlsm""")
End Sub

Note que isso gera um desconforto, pois se o arquivo fosse um Documento de Word, a primeira parte da expressão teria que ser o caminho da Aplicação de Word. Se o arquivo fosse um .pdf, o caminho teria que ser do Adobe Reader e assim por diante. O comando ShellExecute, apresentado a seguir, contorna essa situação.

 

Executar Shell Sincronicamente

O comando Shell é, por padrão, assíncrono. Isto é, sua rotina em VBA continua sua execução ao abrir o arquivo desejado. É possível você executá-lo sincronicamente, isto é, interromper a execução do VBA enquanto o programa chamado não for finalizado. Use a rotina abaixo:

Private Const conUseShowWindow = &H1&
Private Const conNormalPriority = &H20&
Private Const conInfinite = -1&
 
'Prefixo de variáveis Windows API
'cb = Count of Bytes (32-bit)
'w  = Word (16-bit)
'dw = Double Word (32-bit)
'lp = Long Pointer (32-bit)
'b  = Boolean (32-bit)
'h  = Handle (32-bit)
'ul = Unsigned Long (32-bit)
 
Private Type typStartupInfo
    cbLen As Long
    lpReserved As String
    lpDesktop As String
    lpTitle As String
    dwX As Long
    dwY As Long
    dwXSize As Long
    dwYSize As Long
    dwXCount As Long
    dwYCount As Long
    dwFillAtt As Long
    dwFlags As Long
    wShowWindow As Integer
    cbReserved2 As Integer
    lpReserved2 As Long
    hStdIn As Long
    hStdOut As Long
    hStdErr As Long
End Type
 
Private Type typProcInfo
    hProc As Long
    hThread As Long
    dwProcID As Long
    dwThreadID As Long
End Type
 
Private Declare Function CreateProcessA Lib "kernel32" ( _
    ByVal lpApplicationName As Long, _
    ByVal lpCommandLine As String, _
    ByVal lpProcessAttributes As Long, _
    ByVal lpThreadAttributes As Long, _
    ByVal bInheritHandles As Long, _
    ByVal dwCreationFlags As Long, _
    ByVal lpEnvironment As Long, _
    ByVal lpCurrentDirectory As Long, _
    lpStartupInfo As typStartupInfo, _
    lpProcessInformation As typProcInfo) As Long
Private Declare Function WaitForSingleObject Lib "kernel32" ( _
    ByVal hHandle As Long, _
    ByVal dwMilliseconds As Long) As Long
Private Declare Function CloseHandle Lib "kernel32" ( _
    ByVal hObject As Long) As Long
 
Sub Testar()
    ShellWait "C:\Windows\System32\calc.exe"
End Sub

Public Sub ShellWait(strCommand As String, _
                     Optional intWinStyle As VbAppWinStyle = vbNormalFocus)
    Dim objProcInfo As typProcInfo
    Dim objStart As typStartupInfo
 
    'A estrutura de typStartupInfo:
    With objStart
        .cbLen = Len(objStart)
        .dwFlags = conUseShowWindow
        .wShowWindow = intWinStyle
    End With
    'Executa a aplicação:
    Call CreateProcessA(lpApplicationName:=0&, _
                        lpCommandLine:=strCommand, _
                        lpProcessAttributes:=0&, _
                        lpThreadAttributes:=0&, _
                        bInheritHandles:=1&, _
                        dwCreationFlags:=conNormalPriority, _
                        lpEnvironment:=0&, _
                        lpCurrentDirectory:=0&, _
                        lpStartupInfo:=objStart, _
                        lpProcessInformation:=objProcInfo)
    'Aguarda o término da aplicação:
    Call WaitForSingleObject(hHandle:=objProcInfo.hProc, _
                             dwMilliseconds:=conInfinite)
    Call CloseHandle(hObject:=objProcInfo.hProc)
End Sub

 

O Comando ShellExecute

O ShellExecute pode ser interpretado como se o usuário desse um duplo clique num arquivo, a partir do Windows Explorer. Logo, o arquivo alvo será aberto pela associação padrão que o mesmo possui no registro do Windows.

ShellExecute é uma chamada API. A declaração dela apresentada a seguir é compatível com versões 32 e 64 bits. Para saber mais sobre esse assunto, clique aqui.

Const SW_SHOWMAXIMIZED = 3

#If VBA7 Then
    Private Declare PtrSafe Function ShellExecute Lib "Shell32.dll" Alias "ShellExecuteA" _
      (ByVal hwnd As LongPtr, _
      ByVal lpOperation As String, _
      ByVal lpFile As String, _
      ByVal lpParameters As String, _
      ByVal lpDirectory As String, _
      ByVal nShowCmd As LongPtr) As LongPtr
#Else
    Private Declare Function ShellExecute Lib "Shell32.dll" Alias "ShellExecuteA" _
      (ByVal hwnd As Long, _
      ByVal lpOperation As String, _
      ByVal lpFile As String, _
      ByVal lpParameters As String, _
      ByVal lpDirectory As String, _
      ByVal nShowCmd As Long) As Long
#End If

Sub TesteShellExecute()
    ShellExecute Application.hwnd, "open", "C:\temp\Pasta1.xlsm", vbNullString, "C:\", SW_SHOWMAXIMIZED
End Sub

Observe que o parâmetro de interesse é o caminho do arquivo. Basta replicar o código acima mudando apenas o caminho e o arquivo abrirá na Aplicação registrada correspondente no Windows.

No entanto, há outro parâmetro que pode nos interessar, que é como o arquivo será aberto (último parâmetro). No exemplo acima, o arquivo abrirá sempre em tela cheia. Para saber os valores das outras constantes e alternativas de estado da janela, consulte http://msdn.microsoft.com/en-us/library/bb762153(v=vs.85).aspx.

Você pode também usar o ShellExecute como uma função e atribuir uma variável a ele, como mostrado no exemplo a seguir:

Const SW_SHOWMAXIMIZED = 3
Const ERROR_FILE_NOT_FOUND = 2

#If VBA7 Then
    Private Declare PtrSafe Function ShellExecute Lib "Shell32.dll" Alias "ShellExecuteA" _
      (ByVal hwnd As LongPtr, _
      ByVal lpOperation As String, _
      ByVal lpFile As String, _
      ByVal lpParameters As String, _
      ByVal lpDirectory As String, _
      ByVal nShowCmd As LongPtr) As LongPtr
#Else
    Private Declare Function ShellExecute Lib "Shell32.dll" Alias "ShellExecuteA" _
      (ByVal hwnd As Long, _
      ByVal lpOperation As String, _
      ByVal lpFile As String, _
      ByVal lpParameters As String, _
      ByVal lpDirectory As String, _
      ByVal nShowCmd As Long) As Long
#End If

Sub TesteShellExecute2()
    
    Dim se
    
    se = ShellExecute(Application.hwnd, "open", "C:\tempo\Pasta1.xlsm", vbNullString, "C:\", SW_SHOWMAXIMIZED)
    
    Select Case se
        Case ERROR_FILE_NOT_FOUND
            MsgBox "Atenção: caminho não encontrado."
        Case Is > 32
            MsgBox "Arquivo aberto com sucesso."
    End Select
    
End Sub

Para saber sobre os códigos de erro ou de operação bem sucedida, verifique http://msdn.microsoft.com/en-us/library/bb762153(v=vs.85).aspx

 

Comentários

A desvantagem dos métodos apresentados é que, uma vez o arquivo/aplicação for aberto, não será possível manipulá-los programaticamente. Se o desejo do usuário for esse, consulte como atribuir variáveis à Aplicações conforme mostrado em:

Criar uma Instância do Excel pelo VBA

Criar uma Instância do Word pelo VBA

 

Referências

Bytes.com: http://bytes.com/topic/access/insights/841878-shellwait-function

Microsoft: http://msdn.microsoft.com/en-us/library/bb762153(v=vs.85).aspx

Download: Para baixar um arquivo de exemplo pronto, clique aqui.

 

---

Site de Felipe Costa Gualberto.

Belo Horizonte, Brasil, 2009-2013.

felipe@ambienteoffice.com.br