Pergunta

Eu tenho o código que precisa ser executado em ambos Excel 2003 e Excel 2007, e há alguns pontos onde as mudanças nas versões causar o código de parada. Tentei separar estas linhas com declarações if-else, mas o código não irá compilar em ambos, porque ele não reconhece o código usado para o outro. Existe alguma maneira eu poderia dizer uma versão para ignorar um bloco de código, semelhante a um C ou C ++ -? #Ifdef estilo, em VBA

Foi útil?

Solução

Este é um bom ponto de partida, mas não vai funcionar com a versão do Excel que a sua execução em, uma vez que só pode ser descoberto em tempo de execução, não tempo de compilação.

Se você precisa de diversificar o seu código baseado em informações apenas detectável em tempo de execução que você pode considerar a ligação tardia como uma solução. Há duas maneiras que você pode esgueirar-se em torno de problemas de versão.

A primeira forma pode ser usado se você precisar acessar uma propriedade ou método que só existe em algumas versões, você pode usar CallByName. A vantagem de chamar pelo nome é que ele permite que você preserve ligação antecipada (e intellisense) para seus objetos, tanto quanto possível.

Para dar um exemplo, Excel 2007 tem uma nova propriedade TintAndShade. Se você quiser alterar a cor de um intervalo, e para o Excel 2007 também garantir TintAndShade foi definido como 0 você seria executado em apuros porque seu código não será compilado no Excel 2003 que não tem TintAndShade como uma propriedade do objeto range. Se você acessar a propriedade que você sabe que não é em todas as versões usando CallByName, você código irá compilar em todas as versões bem, mas só correr nas versões que você especificar. Veja abaixo:

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 

A segunda maneira é para as classes que têm de ser instanciado via "New" e nem sequer existem em versões antigas. Você não vai executar para esse problema com o Excel, mas vou dar uma demonstração rapidinha para que você possa ver o que eu quero dizer:

Imagine que você queria fazer Arquivo IO, e por algum motivo bizarro nem todos os computadores tinham o Microsoft Scripting Runtime sobre eles. Mas, por alguma razão igualmente bizarra que você queria ter certeza de que foi usado sempre que estava disponível. Se definir uma referência a ele e usar ligação inicial no seu código, o código não será compilado em sistemas que não possuem o arquivo. Então você usar ligação tardia em vez disso:

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

Há uma lista abrangente de todas Adds and Changes para Excel Object Model desde 2003:
http://msdn.microsoft.com/en-us/library/bb149069. aspx Para alterações entre 1997 e 2000 vão aqui:
http://msdn.microsoft.com/en-us /library/aa140068(office.10).aspx

Outras dicas

Sim, é possível fazer a compilação condicional no Excel VBA. Abaixo está um recurso breve e alguns códigos de exemplo: compilação condicional

#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

Você pode postar as linhas ilícito de código?

Se for uma constante como vbYes ou xlFileFormat ou qualquer outra coisa, use o valor numérico correspondente.

Mostre-me o que você tem, eu vou ver se eu posso refatorar-lo.

Bill

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top