IFDEF эквивалент в VBA - PullRequest
4 голосов
/ 29 мая 2009

У меня есть код, который должен выполняться как в Excel 2003, так и в Excel 2007, и есть несколько мест, где изменения в версиях приводят к остановке кода. Я попытался отделить эти строки с помощью операторов If-Else, но код также не скомпилируется, потому что он не распознает код, используемый для другого. Можно ли как-то сказать одной версии игнорировать блок кода, похожий на #ifdef в стиле C или C ++, в VBA?

Ответы [ 3 ]

4 голосов
/ 29 мая 2009

Это хорошая отправная точка, но она не будет работать с версией Excel, на которой она запущена, поскольку это можно выяснить только во время выполнения, а не во время компиляции.

Если вам нужно разветвить свой код на основе информации, которую можно обнаружить только во время выполнения, вы можете рассмотреть позднюю привязку как решение. Есть два способа обойти проблемы с версиями.

Первый способ может быть использован, если вам нужно получить доступ к свойству или методу, который существует только в определенных версиях, вы можете использовать CallByName. Преимущество вызова по имени заключается в том, что он позволяет максимально сохранить раннее связывание (и intellisense) для ваших объектов.

Например, в Excel 2007 есть новое свойство TintAndShade. Если вы хотите изменить цвет диапазона, а для Excel 2007 также убедитесь, что для TintAndShade установлено значение 0, у вас возникнут проблемы, поскольку ваш код не будет компилироваться в 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 

Второй способ - для классов, которые должны быть созданы с помощью «New» и даже не существуют в старых версиях. Вы не столкнетесь с этой проблемой в Excel, но я дам краткую демонстрацию, чтобы вы поняли, что я имею в виду:

Представьте, что вы хотите выполнить File 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 голосов
/ 29 мая 2009

Да, можно делать условную компиляцию в Excel VBA. Ниже приведен краткий ресурс и пример кода: Условная компиляция

#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 голосов
/ 31 мая 2009

Можете ли вы опубликовать оскорбительные строки кода?

Если это константа, такая как vbYes или xlFileFormat или что-то еще, используйте соответствующее числовое значение.

Покажи мне, что у тебя есть, я посмотрю, смогу ли я сделать рефакторинг.

Bill

...