IFDEF équivalent en VBA
-
06-09-2019 - |
Question
J'ai le code qui doit fonctionner à la fois Excel 2003 et Excel 2007, et il y a quelques endroits où des changements dans les versions provoquent le code à arrêter. J'ai essayé la séparation de ces lignes avec des déclarations Sinon si, mais le code ne compilera pas sur soit parce qu'il ne reconnaît pas le code utilisé pour l'autre. Est-il possible que je pourrais dire une version à ignorer un bloc de code, semblable à un C ou C ++ - le style #ifdef, dans VBA
?La solution
Ceci est un bon point de départ, mais il ne fonctionne pas avec la version d'Excel que son exécution sur, puisque ce ne peut être compris au moment de l'exécution, pas la compilation.
Si vous devez ramifier votre code en fonction des informations que découvrable au moment de l'exécution, vous pourriez envisager la liaison tardive comme une solution. Il y a deux façons dont vous pouvez glisser autour des problèmes de version.
La première peut être utilisé si vous avez besoin d'accéder à une propriété ou une méthode qui existe seulement dans certaines versions, vous pouvez utiliser CallByName. L'avantage de l'appel par le nom est qu'il vous permet de conserver la liaison anticipée (et IntelliSense) pour vos objets autant que possible.
Pour donner un exemple, Excel 2007 a une nouvelle propriété TintAndShade. Si vous voulez changer la couleur d'une gamme, et pour Excel 2007 également veiller à ce TintAndShade a été fixé à 0 vous des ennuis parce que votre code ne sera pas compilé dans Excel 2003 qui ne dispose pas TintAndShade comme propriété de l'objet de la plage. Si vous accédez à la propriété que vous savez pas dans toutes les versions en utilisant CallByName, vous codez compilera dans toutes les versions fines, mais ne fonctionne que dans les versions que vous spécifiez. Voir ci-dessous:
Sub Test()
ColorRange Selection, Excel.Application.version, 6
End Sub
Sub ColorRange(rng As Excel.Range, version As Double, ParamArray args() As Variant)
With rng.Interior
.colorIndex = 6
.Pattern = xlSolid
If version >= 12# Then
'Because the property name is stored in a string this will still compile.
'And it will only get called if the correct version is in use.
CallByName rng.Interior, "TintAndShade", VbLet, 0
End If
End With
End Sub
La seconde est pour les classes qui doivent être instancié via « Nouveau » et n'existent même pas dans les anciennes versions. Vous ne rencontrerez pas ce problème avec Excel, mais je vais donner une démonstration quickie afin que vous puissiez voir ce que je veux dire:
Imaginez que vous vouliez faire fichier IO, et pour une raison bizarre pas tous les ordinateurs avaient le Microsoft Scripting Runtime sur eux. Mais pour une raison tout aussi bizarre que vous vouliez vous assurer qu'il a été utilisé à chaque fois qu'il était disponible. Si définir une référence à et utiliser une liaison anticipée dans votre code, le code ne compile pas sur les systèmes qui ne sont pas le fichier. Donc, vous utilisez la liaison tardive à la place:
Public Sub test()
Dim strMyString As String
Dim strMyPath As String
strMyPath = "C:\Test\Junk.txt"
strMyString = "Foo"
If LenB(Dir("C:\Windows\System32\scrrun.dll")) Then
WriteString strMyPath, strMyString
Else
WriteStringNative strMyPath, strMyString
End If
End Sub
Public Sub WriteString(ByVal path As String, ByVal value As String)
Dim fso As Object '<-Use generic object
'This is late binding:
Set fso = CreateObject("Scripting.FileSystemObject")
fso.CreateTextFile(path, True, False).Write value
End Sub
Public Sub WriteStringNative(ByVal path As String, ByVal value As String)
Dim lngFileNum As Long
lngFileNum = FreeFile
If LenB(Dir(path)) Then Kill path
Open path For Binary Access Write Lock Read Write As #lngFileNum
Put #lngFileNum, , value
Close #lngFileNum
End Sub
Il y a une liste complète de tous les ajouts et modifications à Excel Object Model depuis 2003:
http://msdn.microsoft.com/en-us/library/bb149069. ASPX
Pour les changements entre 1997 et 2000 vont ici:
http://msdn.microsoft.com/en-us /library/aa140068(office.10).aspx
Autres conseils
Oui, il est possible de faire la compilation conditionnelle dans Excel VBA. Voici une brève ressource et quelques exemples de code: compilation conditionnelle
#If Win32 Then
' Profile String functions:
Private Declare Function WritePrivateProfileString Lib "KERNEL32" Alias "WritePrivateProfileStringA" (ByVal lpApplicationName As String, ByVal lpKeyName As Any, ByVal lpString As Any, ByVal lpFileName As String) As Long
Private Declare Function GetPrivateProfileString Lib "KERNEL32" Alias "GetPrivateProfileStringA" (ByVal lpApplicationName As Any, ByVal lpKeyName As Any, ByVal lpDefault As Any, ByVal lpReturnedString As String, ByVal nSize As Long, ByVal lpFileName As String) As Long
#Else
' Profile String functions:
Private Declare Function WritePrivateProfileString Lib "Kernel" (ByVal lpApplicationName As String, ByVal lpKeyName As Any, ByVal lpString As Any, ByVal lpFileName As String) As Integer
Private Declare Function GetPrivateProfileString Lib "Kernel" (ByVal lpApplicationName As String, ByVal lpKeyName As Any, ByVal lpDefault As Any, ByVal lpReturnedString As String, ByVal nSize As Integer, ByVal lpFileName As String) As Integer
#End If
Pouvez-vous afficher les lignes incriminées de code?
S'il est une constante comme vbYes ou xlFileFormat ou autre, utilisez la valeur numérique correspondante.
Montrez-moi ce que tu as, je vais voir si je peux le refactoriser.
Bill