Views

...

Important:

Quaisquer soluções e/ou desenvolvimento de aplicações pessoais, ou da empresa, que não constem neste Blog podem ser tratados como consultoria freelance.

E-mails

Deixe seu e-mail para receber atualizações...

eBook Promo

VBA Tips - Compatibilidade entre as API 32-Bits (x86) e 64-Bits (x64) no VBA

Inline image 1
| Blog Office VBA | Blog Excel | Blog Access |

Utilizar APIs tem se tornado uma complicação para alguns e isso deve-se ao fato de ser necessário compatibilizar as versões do MS Office e seus respectivos VBEs (ambientes de desenvolvimento).

A versão MS Office 2010, introduziu a plataforma 64 bits e a nova versão 7.0 do VBA.

Isso requer que todos aqueles que desenvolvem no ambiente MS Office atentem-se para manter a compatibilidade dos seus códigos em todas as plataformas, seja 32 Bits ou 64 Bits ou mesmo em versões anteriores. Prá quem já desenvolve a muito tempo isso não é novidade nenhuma, mas para os neofitos essa dica é bem relevante.

Lembrem-se desses ínfimos detalhes:

A versão do MS Office 2010 é a 14.0
A versão do MS Office 2007 é o 12.0
A versão do MS Office 2003 (XP) é o 11.0

O VBA tem a sua própria versão contida nos diferentes pacotes:

A versão VBA do MS Office 2007 é a 6.0
A versão VBA do MS Office 2010 é a 7.0

Divertido não?

Não fiquem demasiadamente preocupados com isso. O VBA 6.0 oferece uma ótima compatibilidade com as edições anteriores. Mas o VBA 7.0, do MS Office 2010 não.

Em tempo, faz-se necessário comentar que o cenário pode ser um pouco mais complexo quando nos referimos as versões 64 bits do MS Office, as quais foram introduzidas a partir do MS Office 2010. Estas não estão totalmente compatíveis com as versões 32 Bits do MS Office 2010.

Resumindo para os menos atentos:

MS Office 2010 64 bits
- VBA 7.0 - 64 bits

MS Office 2010 32 bits
- VBA 7.0 - 32 bits

MS Office 2007
ou anterior - VBA 6.0 ou anterior - 32 bits

E agora, quem poderá nos proteger?

Condicionais de Compilação
Os Condicionais de Compilação são instruções compiladas somente se o critério atender a condição. Possuem em seu prefixo o caractere #.

#If VBA7
Then
    ' Compilado somente no VBA do Office 2010, tanto nas versão 32 Bits, quanto na versão 64 Bits
     
     #If Win64 Then
        ' Compilado somente no VBA do Office 2010, na versão 64 Bits
     
     #Else
        ' Compilado somente no VBA do Office 2010, na versão 32 Bits
     #End If

#Else
    ' Compilado somente no VBA do Office 2007 ou inferior

#End If

Obs: Apesar do termo compilado as Condicionais podem ser inseridas dentro dos Procedimentos e podem ser depuradas.

Você que é desenvolvedor VBA, foque bem a sua atenção:

As suas declarações API devem ser cautelosas, veja o exemplo prático abaixo:

#If VBA7 Then
   Declare PtrSafe Function GetActiveWindow Lib "user32" () As LongPtr

   #If Win64 Then
      Declare PtrSafe Function GetTickCount64 Lib "kernel32" () As LongLong

   #Else
      Declare PtrSafe Function GetTickCount Lib "kernel32" () As Long

   #End If
#Else

   Declare Function GetActiveWindow Lib "user32" () As Long
   Declare Function GetTickCount Lib "kernel32" () As Long
#End If

Nesse exemplo, estamos usando as APIs GetActiveWindow e GetTickCount. Da forma como foram declaradas acima, são executadas em qualquer versão do MS Office. Perceba que deve efetuar as seguintes considerações caso a versão do VBA seja 7.0:

Veja detalhes aqui:

Adicionar o parâmetro PtrSafe entre Declare e Function (ou Sub)

Substituir Long por LongPtr

Observe que ao contrário da GetActiveWindow, a API GetTickCount deve ser declarada separadamente para as versões de 32 e 64 bits do Office 2010 (observe o sufixo 64 em GetTickCount64). Para APIs que estejam dentro do bloco Win64, a troca de variáveis tipo Long deve ser por LongLong, que é um novo tipo de inteiro de 64 bits que trabalha em ambiente 32 bits.

A parte difícil vem agora: nem todos os tipos Long devem ser convertidos. Numa explicação curta, podemos dizer que as APIs são definidas em linguagem C++, e nesta plataforma existem dois tipos numéricos não presentes no VBA: ponteiros e handles. Apenas ponteiros e handles devem ser transformados de Long para LongPtr. Como saber quais Long são handles e ponteiros? Teoricamente, o usuário deverá entrar na documentação da função no site da MSDN da Microsoft e ver quais são os parâmetros da função API desejada. Isso é um custo muito alto para o programador, e devido à reclamações da comunidade, a Microsoft lançou uma lista com as novas API para a plataforma 32 e 64 bits já corrigidas, que pode ser acessada através deste link.

Outro exemplo para o seu deleite:

Inline image 3

' A user-defined type to store the window dimensions.

Type RECT
    Left As Long
    Top As Long
    Right As Long
    Bottom As Long
End Type

' Test which version of VBA you are using.

#If VBA7 Then
   ' API function to locate a window.
   Declare PtrSafe Function FindWindow Lib "user32" _
      Alias "FindWindowA" ( _
      ByVal lpClassName As String, _
      ByVal lpWindowName As String) As LongPtr
    
   ' API function to retrieve a window's dimensions.
   Declare PtrSafe Function GetWindowRect Lib "user32" ( _
      ByVal hwnd As LongPtr, _
      lpRect As RECT) As Long

#Else
   ' API function to locate a window.
   Declare Function FindWindow Lib "user32" _
      Alias "FindWindowA" ( _
      ByVal lpClassName As String, _
      ByVal lpWindowName As String) As Long
    
   ' API function to retrieve a window's dimensions.
   Declare Function GetWindowRect Lib "user32" ( _
      ByVal hwnd As Long, _
      lpRect As RECT) As Long
#End If

Sub DisplayExcelWindowSize()
   Dim hwnd As Long, uRect As RECT
   
   ' Get the handle identifier of the main Excel window.
   hwnd = FindWindow("XLMAIN", Application.Caption)
   
   ' Get the window's dimensions into the RECT UDT.
   GetWindowRect hwnd, uRect
   
   ' Display the result.
   MsgBox "The Excel window has these dimensions:" & _
      vbCrLf & " Left: " & uRect.Left & _
      vbCrLf & " Right: " & uRect.Right & _
      vbCrLf & " Top: " & uRect.Top & _
      vbCrLf & " Bottom: " & uRect.Bottom & _
      vbCrLf & " Width: " & (uRect.Right - uRect.Left) & _
      vbCrLf & " Height: " & (uRect.Bottom - uRect.Top)
   
End Sub

Reference:


André Luiz Bernardes


Tags: VBA, Office, API, 32 Bits, 64 Bits, compatibilidade, VBA 6.0, VBA 7.0, MS Office 2003, MS Office 2007, MS Office 2010, MS Office 2010 32 Bits, MS Office 2010 64 Bits,  32-bit (x86), 64-bit (x64)

eBooks VBA na AMAZOM.com.br

LinkWithinBrazilVBAExcelSpecialist

Related Posts Plugin for WordPress, Blogger...

Vitrine