Views

Histats

Vitrine

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


TagsVBA, 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)

LinkWithinBrazilVBAExcelSpecialist

Related Posts Plugin for WordPress, Blogger...