| 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.0A versão do MS Office 2007 é o 12.0A 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.0A versão VBA do MS Office 2010 é a 7.0Divertido 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:- VBA 7.0 - 64 bitsMS Office 2010 64 bits- VBA 7.0 - 32 bitsMS Office 2010 32 bitsou anterior - VBA 6.0 ou anterior - 32 bitsMS Office 2007E agora, quem poderá nos proteger?Condicionais de CompilaçãoOs Condicionais de Compilação são instruções compiladas somente se o critério atender a condição. Possuem em seu prefixo o caractere #.Then#If VBA7' 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 IfObs: 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 ThenDeclare PtrSafe Function GetActiveWindow Lib "user32" () As LongPtr#If Win64 ThenDeclare PtrSafe Function GetTickCount64 Lib "kernel32" () As LongLong#ElseDeclare PtrSafe Function GetTickCount Lib "kernel32" () As Long#End If#ElseDeclare Function GetActiveWindow Lib "user32" () As LongDeclare Function GetTickCount Lib "kernel32" () As Long#End IfNesse 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
Reference: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:' A user-defined type to store the window dimensions.Type RECTLeft As LongTop As LongRight As LongBottom As LongEnd 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 IfSub 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
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)