2009-05-29 3 views
4

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

ответ

4

Это хорошая отправная точка, но она не будет работать с версией 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 

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

Представьте, что вы хотели сделать File IO, и по какой-то странной причине не все компьютеры имели Runtime Microsoft Scripting на них. Но для какой-то столь же причудливой причины вы хотели убедиться, что она использовалась всякий раз, когда она была доступна. Если установить ссылку на него и использовать раннее связывание в коде, код не будет компилироваться в системах, у которых нет файла. Таким образом, вы используете позднее связывание вместо:

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 Object Model с 2003 года:
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, что его работает на, так что может быть просчитан только во время выполнения, а не во время компиляции. –

+0

не отвечает на вопрос, в то время как это будет работать для общих директив компиляции, в этом вопросе говорится, как проверить версию Excel в аппликации. –

0

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

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

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

Билл

+0

Это не нужно - код был сгенерирован макрокомандой, а код с 2003 года отлично работает в 2007 году, поэтому я просто отказался от кода 2007 года. –

Смежные вопросы