7 votes

comment rendre le code VBA compatible avec office 2010 - version 64 bit et les versions plus anciennes d'office

J'ai observé un problème avec l'appel de fonction ci-dessous lorsque nous avons migré vers la version Office 2010-64 bit.

Private Declare Sub CopyMem Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)

Selon les informations disponibles sur http://msdn.microsoft.com/en-us/library/ee691831.aspx lien. J'ai changé l'appel ci-dessus comme ci-dessous et cela a bien fonctionné sur la version 64 bits d'Office 2010.

Private Declare PtrSafe Sub CopyMem Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)

Le problème est que j'ai besoin de faire le même appel pour travailler sur des versions plus anciennes d'Office et qu'il y a une erreur de compilation sur les anciennes versions.

Est-ce que quelqu'un a une idée de comment faire fonctionner cet appel pour Office 2010 et les versions plus anciennes d'Office.

14voto

Charles Williams Points 9147

Comme le dit l'article de MSDN, utilisez la compilation conditionnelle : cela fonctionne bien pour moi dans Excel 97 jusqu'à Excel 2010 32-bit & 64-bit.

#If VBA7 Then
Private Declare PtrSafe Sub CopyMem Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)
#Else
Private Declare Sub CopyMem Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)
#End if

3voto

JamieG Points 85

Je trouve que l'utilisation de ce VBA7 Une constante du compilateur est mentionnée partout sur Internet en relation avec la compatibilité d'Office 64 bits, mais contrairement à ce qui est souvent dit, cette constante du compilateur détecte les installations d'Office utilisant VBA7, par exemple à partir d'Office 2010, et non Office 64 bits. Ce qui est déroutant, c'est que si vous avez besoin de déterminer si vous utilisez la version 64 bits de l'application Office, vous devez utiliser la fonction Win64 constant !

Essayez ceci sur les versions 32 et 64 bits d'Office et vous verrez ce que je veux dire :

Sub DemoCompilerConstants()

    #If VBA7 Then
        MsgBox "VBA7"
    #Else
        MsgBox "Not VBA7"
    #End If

    #If Win64 Then
        MsgBox "Win64"
    #Else
        MsgBox "NOT Win64"
    #End If

End Sub

Merci à Steve Rindsberg pour m'avoir éclairé sur ce point ! Steve a également ajouté :

Win64 vous indique si la version de votre application Office est 64 bits ou non. est 64 bits. Si vous devez prendre en charge d'anciennes versions d'Office, vous pouvez combiner cela avec une vérification VBA7 pour les cas spéciaux. de votre application Office qui ne comprendrait pas les nouvelles directives du compilateur. compilateur. Mais si votre code échoue sur une version 32 bits de l'application de l'application Office, il se peut que ce soit parce qu'il rencontre la directive compilateur, qu'il trouve que oui, il y a VBA7 et qu'il essaie d'exécuter l'appel API l'appel de l'API 64 bits, ce qui ne fonctionnera pas car il s'agit d'une application Office 32 bits.

Cela devrait donc être l'approche correcte pour combiner VBA7 et la compatibilité avec Office 64 bits :

#If VBA7 Then
  #If Win64 Then ' Declare using PtrSafe for Office 64 bit
    Declare PtrSafe Function ....
  #Else ' Declare for Office 32 bit
    Declare Function ....
  #End If
#Else ' Declare for Office 32 bit
  Declare Function ....
#End If

0voto

Daniel Scott Points 23

Affiner l'excellente information/réponse de Jamie Garroch (qui explique comment la constante du compilateur VBA7 ne vous indique pas avec certitude si votre code s'exécute dans une application Office 64 bits), la constante du compilateur VBA #if peut gérer la directive And opérateurs.

Cela signifie que vous n'avez pas besoin de répéter vos déclarations de fonctions 32 bits. Vous pouvez simplement faire ceci :

    #If VBA7 And Win64 Then ...
        '64 Bit Declarations: for example ...
        Private Declare PtrSafe Sub API\_CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (dest As Any, source As Any, ByVal bytes As Long)
    #Else
        '32 Bit Declarations: for example ...
        Public Declare Sub API\_CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (dest As Any, source As Any, ByVal bytes As Long)
    #End If

0voto

DMike92 Points 31

Si vous utilisez Office 2003, alors utilisez :

#If VBA7 Then
Private Declare PtrSafe Sub CopyMem Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As
Long)
#Else
Private Declare Sub CopyMem Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)
#End if

Fonctionne mais lorsque vous sauvegardez votre classeur et le rouvrez, seul le code correspondant à votre OS est conservé. Les #If then #Else et #End if ont disparu.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X