2009-05-29 84 views
4

我有需要在Excel 2003和Excel 2007上運行的代碼,並且有幾個版本中的更改導致代碼停止的位置。我試着用If-Else語句將這些行分開,但是代碼不能編譯,因爲它不能識別用於其他代碼的代碼。有沒有什麼辦法可以告訴一個版本忽略VBA中類似於C或C++風格#ifdef的一段代碼?在VBA中的IFDEF等效

回答

4

這是一個很好的起點,但它不會與它運行的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 

第二種方法是類,必須通過「新建」實例化,甚至不存在舊版本。你不會遇到Excel的這個問題,但我會給你一個快速演示,讓你明白我的意思:

想象一下,你想做文件IO,並且出於一些奇怪的原因,並非所有的計算機都有他們的Microsoft腳本運行時。但是對於一些同樣奇怪的原因,你想確保它在任何時候都可以使用。如果設置了引用並在代碼中使用了早期綁定,則代碼將不會在沒有該文件的系統上編譯。所以,你使用後期綁定,而不是:

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 

有自2003年以來的所有添加和變更到Excel對象模型的完整列表:
http://msdn.microsoft.com/en-us/library/bb149069.aspx 對於1997年至2000年間的變化去這裏:
http://msdn.microsoft.com/en-us/library/aa140068(office.10).aspx

2

是的,可以在Excel VBA中進行條件編譯。下面是一個簡單的資源和一些示例代碼: Conditional Compilation

#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 
+0

這是一個很好的起點,但它不會與它運行的Excel版本的工作,因爲只能在運行時可以想通了,不編譯時間。 – 2009-05-29 17:42:42

+0

沒有回答這個問題,雖然這將適用於一般編譯指令,但問題指出如何檢查應用程序版本的Excel。 – 2010-09-27 22:34:06

0

你能發佈有問題的代碼行嗎?

如果它是一個常量,如vbYes或xlFileFormat或其他,請使用相應的數值。

讓我看看你有什麼,我會看看我是否可以重構它。

比爾