Вопрос

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

Это было полезно?

Решение

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

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

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

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

Представьте, что вы хотели выполнить ввод-вывод файлов, и по какой-то странной причине не на всех компьютерах была установлена среда выполнения 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

Существует полный список всех дополнений и изменений в объектной модели Excel с 2003 года:
http://msdn.microsoft.com/en-us/library/bb149069.aspx Об изменениях за период с 1997 по 2000 год читайте здесь:
http://msdn.microsoft.com/en-us/library/aa140068 (office.10).aspx

Другие советы

Да, можно выполнить условную компиляцию в 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

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

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

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

Счет

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top