2009-05-29 4 views
4

Excel 2003과 Excel 2007에서 모두 실행해야하는 코드가 있으며 버전이 변경되어 코드가 중단되는 경우가 있습니다. If-Else 문을 사용하여이 행을 분리하려고 시도했지만 다른 행에 사용 된 코드를 인식하지 못하기 때문에 코드가 컴파일되지 않습니다. 한 버전에서 VBA에서 C 또는 C++ 스타일의 #ifdef와 비슷한 코드 블록을 무시하도록 지시 할 수있는 방법이 있습니까?VBA의 IFDEF

답변

4

이 좋은 출발점이 될 것입니다,하지만 만 생각 할 수 있기 때문에 그것이, 그것의 실행중인 Excel 버전에서는 작동하지 않습니다 시간을 컴파일하지 않고 런타임에 종료합니다.

런타임에만 검색 가능한 정보를 기반으로 코드를 분기해야하는 경우 후기 바인딩을 솔루션으로 간주 할 수 있습니다. 버전 문제를 몰래 빠져 나갈 수있는 두 가지 방법이 있습니다.

특정 버전에만 존재하는 속성이나 메서드에 액세스해야하는 경우 첫 번째 방법을 사용할 수 있습니다. CallByName을 사용할 수 있습니다. 호출의 장점은 가능한 한 객체에 대한 초기 바인딩 (및 인텔리 센스)을 유지할 수 있다는 것입니다.

예를 들어, Excel 2007에는 새로운 TintAndShade 속성이 있습니다. 범위의 색을 변경하고 Excel 2007에서 TintAndShade가 0으로 설정되어 있는지 확인하려면 TintAndShade가 범위 개체의 속성으로없는 Excel 2003에서는 코드가 컴파일되지 않으므로 문제가 발생할 수 있습니다. 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 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 

포괄적 인 2003 년 이후 Excel 개체 모델에 대한 모든 추가 및 변경 목록이있다 : 1997 년과 2000 년 사이의 변화를
http://msdn.microsoft.com/en-us/library/bb149069.aspx 은 여기 :
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

이것은 필요하지 않습니다. 코드가 매크로로 생성되었으며 2007 년에는 2003 년 코드가 정상적으로 작동하므로 2007 코드를 폐기했습니다. –