VBA 中的 IFDEF 等效项

And*_*lli 4 excel vba office-2007 office-2003

我的代码需要在 Excel 2003 和 Excel 2007 上运行,并且在某些地方版本中的更改会导致代码停止。我尝试使用 If-Else 语句将这些行分开,但代码无法在其中任何一个上编译,因为它无法识别用于另一个的代码。有什么方法可以让一个版本忽略 VBA 中的代码块(类似于 C 或 C++ 风格的 #ifdef)吗?

Oor*_*ang 5

这是一个很好的起点,但它不适用于运行它的 Excel 版本,因为它只能在运行时而不是编译时计算出来。

如果您需要根据仅在运行时可发现的信息对代码进行分支,您可能会考虑将后期绑定作为解决方案。有两种方法可以绕过版本问题。

可以使用第一种方式,如果需要访问只存在于某些版本的属性或方法,可以使用CallByName。按名称调用的优点是它允许您尽可能保留对象的早期绑定(和智能感知)。

举个例子,Excel 2007 有一个新的 TintAndShade 属性。如果您想更改某个范围的颜色,并且对于 Excel 2007,还要确保 TintAndShade 设置为 0,您会遇到麻烦,因为您的代码无法在 Excel 2003 中编译,因为 Excel 2003 没有 TintAndShade 作为范围对象的属性。如果您使用 CallByName 访问您知道并非在所有版本中的属性,则您的代码将在所有版本中正常编译,但仅在您指定的版本中运行。见下文:

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 
Run Code Online (Sandbox Code Playgroud)

第二种方法适用于必须通过“New”实例化的类,并且在旧版本中甚至不存在。使用 Excel 不会遇到这个问题,但我将提供一个快速演示,以便您明白我的意思:

想象一下,您想要执行文件 IO,但由于某些奇怪的原因,并非所有计算机都安装了 Microsoft Scripting Runtime。但由于一些同样奇怪的原因,您想确保它在可用时被使用。如果设置对其的引用并在代码中使用早期绑定,则代码将无法在没有该文件的系统上编译。所以你改用后期绑定:

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
Run Code Online (Sandbox Code Playgroud)

有一个完整的列表,列出了自 2003 年以来对 Excel 对象模型的所有添加和更改: http:
//msdn.microsoft.com/en-us/library/bb149069.aspx 有关 1997 年至 2000 年之间的更改,请访问此处:
http://msdn .microsoft.com/en-us/library/aa140068(office.10).aspx