VBAでIFDEF相当
-
06-09-2019 - |
質問
私は、Excel 2003とExcel 2007の両方で実行するために必要なコードを持っている、そしてバージョンの変化が停止するコードを引き起こすいくつかのスポットがあります。私は、もし-else文でこれらの行を分離しようとしたが、それは他のために使用されるコードを認識しないためのコードのいずれかでコンパイルされません。 VBAでのスタイルの#ifdef、
- ?私はCまたはC ++のようなコードのブロックを、無視する1つのバージョンを言うことができる方法はあります解決
あなたは実行時にのみ発見の情報に基づいてコードを分岐する必要がある場合は、これは良い出発点ですが、それだけの時間をコンパイルし、実行時にではないに把握することができるからです。
それは、その上で実行されているが、Excelのバージョンでは動作しません。
あなたは解決策として、遅延バインディング考えるかもしれません。あなたはバージョンの問題を中心にこっそりことができる2つの方法があります。
最初の方法は、あなたが唯一の特定のバージョンに存在するプロパティやメソッドにアクセスする必要がある場合、あなたはCallByNameを使用することができます使用することができます。名前によるコールの利点は、それはあなたが可能な限り、あなたのオブジェクトの事前バインディング(とインテリセンス)保存することができるということです。
の例を与えるために、Excel 2007が新しいTintAndShade性を有しています。あなたが範囲の色を変更したい場合は、およびExcel 2007のためにもTintAndShadeはあなたのコードは、範囲オブジェクトのプロパティとしてTintAndShadeていないExcel 2003でコンパイルされませんので、あなたがトラブルに実行します0に設定したことを確認。あなたが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
すべて追加し、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または何のような定数である場合は、対応する数値を使用します。
私はそれをリファクタリングすることができます場合、私は参照してくださいよ、あなたが得たものを見せてくれます。
ビル