VBA 言語の機能のうち、文書化されていないもの、またはあまり使用されていないものはどれですか?
16 に答える
このトリックは Access VBA、Excel でのみ機能し、他のユーザーは許可しません。ただし、モジュール名の前にアンダースコアを付けることで、標準モジュールをオブジェクト ブラウザから非表示にすることができます。非表示のオブジェクトを表示するようにオブジェクト ブラウザを変更した場合にのみ、モジュールが表示されます。
このトリックは、VBA のすべての vb6 ベース バージョンの Enum で機能します。Enum の隠しメンバーを作成するには、その名前を角かっこで囲み、その前にアンダースコアを付けます。例:
Public Enum MyEnum
meDefault = 0
meThing1 = 1
meThing2 = 2
meThing3 = 3
[_Min] = meDefault
[_Max] = meThing3
End Enum
Public Function IsValidOption(ByVal myOption As MyEnum) As Boolean
If myOption >= MyEnum.[_Min] Then IsValidOption myOption <= MyEnum.[_Max]
End Function
Excel-VBA では、セルを角かっこで囲むことでセルを参照できます。角かっこは評価コマンドとしても機能し、式の構文を評価できます。
Public Sub Example()
[A1] = "Foo"
MsgBox [VLOOKUP(A1,A1,1,0)]
End Sub
また、LSet を同じサイズのユーザー定義型と組み合わせることで、MemCopy (RtlMoveMemory) を使用せずに生データを渡すことができます。
Public Sub Example()
Dim b() As Byte
b = LongToByteArray(8675309)
MsgBox b(1)
End Sub
Private Function LongToByteArray(ByVal value As Long) As Byte()
Dim tl As TypedLong
Dim bl As ByteLong
tl.value = value
LSet bl = tl
LongToByteArray = bl.value
End Function
8 進数と 16 進数のリテラルは実際には符号なしの型であり、どちらも -32768 を出力します。
Public Sub Example()
Debug.Print &H8000
Debug.Print &O100000
End Sub
前述のように、括弧内に変数を渡すと、ByVal が渡されます。
Sub PredictTheOutput()
Dim i&, j&, k&
i = 10: j = i: k = i
MySub (i)
MySub j
MySub k + 20
MsgBox Join(Array(i, j, k), vbNewLine), vbQuestion, "Did You Get It Right?"
End Sub
Public Sub MySub(ByRef foo As Long)
foo = 5
End Sub
文字列をバイト配列に直接代入したり、その逆を行ったりできます。
Public Sub Example()
Dim myString As String
Dim myBytArr() As Byte
myBytArr = "I am a string."
myString = myBytArr
MsgBox myString
End Sub
"Mid" も演算子です。これを使用すると、VBA の遅いことで有名な文字列連結を使用せずに、文字列の特定の部分を上書きできます。
Public Sub Example1()
''// This takes about 47% of time Example2 does:
Dim myString As String
myString = "I liek pie."
Mid(myString, 5, 2) = "ke"
Mid(myString, 11, 1) = "!"
MsgBox myString
End Sub
Public Sub Example2()
Dim myString As String
myString = "I liek pie."
myString = "I li" & "ke" & " pie" & "!"
MsgBox myString
End Sub
これは機能ではありませんが、VBA (および VB6) で何度も間違っているのを見てきました: メソッド呼び出しに追加された括弧は、セマンティクスを変更します:
Sub Foo()
Dim str As String
str = "Hello"
Bar (str)
Debug.Print str 'prints "Hello" because str is evaluated and a copy is passed
Bar str 'or Call Bar(str)
Debug.Print str 'prints "Hello World"
End Sub
Sub Bar(ByRef param As String)
param = param + " World"
End Sub
隠された機能
- 「基本」ですが、OOP(クラスとオブジェクト)を使用できます
- API呼び出しを行うことができます
おそらく、VBA で最も文書化されていない機能は、VBA オブジェクト ブラウザーで [非表示のメンバーを表示] を選択することによってのみ公開できる機能です。非表示のメンバーは、VBA にあるがサポートされていない関数です。それらを使用することはできますが、Microsoft はいつでもそれらを削除する可能性があります。ドキュメントは提供されていませんが、ウェブ上でいくつか見つけることができます。おそらく、これらの隠れた機能の中で最も話題になっているのは、VBA のポインターへのアクセスを提供することです。まともな記事については、チェックしてください。それほど軽量ではない - Shlwapi.dll
文書化されていますが、おそらくもっとあいまいです (とにかく Excel で) ExecuteExcel4Macro を使用して、特定のワークブックではなく、Excel アプリケーション インスタンス全体に属する非表示のグローバル名前空間にアクセスします。
辞書。それらがなければ、VBA は実質的に価値がありません。
Microsoft Scripting Runtime を参照し、Scripting.Dictionary
十分に複雑なタスクに使用して、その後ずっと幸せに暮らしてください。
Scripting Runtime は、FileSystemObject も提供します。これも強くお勧めします。
ここから始めて、少し掘り下げて...
http://msdn.microsoft.com/en-us/library/aa164509%28office.10%29.aspx
Implements
キーワードを使用してインターフェイスを実装できます。
入力VBA.
すると、すべての組み込み関数と定数の Intellisense リストが表示されます。
少しの作業で、次のようなカスタムコレクションを繰り返すことができます。
' Write some text in Word first.'
Sub test()
Dim c As New clsMyCollection
c.AddItems ActiveDocument.Characters(1), _
ActiveDocument.Characters(2), _
ActiveDocument.Characters(3), _
ActiveDocument.Characters(4)
Dim el As Range
For Each el In c
Debug.Print el.Text
Next
Set c = Nothing
End Sub
カスタムコレクションコード(と呼ばれるクラス内clsMyCollection
):
Option Explicit
Dim m_myCollection As Collection
Public Property Get NewEnum() As IUnknown
' This property allows you to enumerate
' this collection with the For...Each syntax
' Put the following line in the exported module
' file (.cls)!'
'Attribute NewEnum.VB_UserMemId = -4
Set NewEnum = m_myCollection.[_NewEnum]
End Property
Public Sub AddItems(ParamArray items() As Variant)
Dim i As Variant
On Error Resume Next
For Each i In items
m_myCollection.Add i
Next
On Error GoTo 0
End Sub
Private Sub Class_Initialize()
Set m_myCollection = New Collection
End Sub
debug.? xxx
の代わりに入力することで、4 つのキーストローク全体を節約できますdebug.print xxx
。enum foo: me=0: end enum
他のコードを含むモジュールの先頭に: を追加してクラッシュさせます。
(少なくとも前世紀には) ローカライズされた値を使用した式をサポートしていた、ローカライズされたバージョンのサポート。True の Pravda やポーランド語の False の Fałszywy (よくわかりませんが、少なくとも面白い L がありました) のように... 実際、英語版はどの言語でもマクロを読み取って、その場で変換できます。ただし、他のローカライズされたバージョンはそれを処理しません。
不合格。
VBE(Visual Basic Extensibility)オブジェクトモデルは、あまり知られていないか、十分に活用されていない機能です。これにより、VBAコード、モジュール、およびプロジェクトを操作するためのVBAコードを記述できます。私はかつて、モジュールファイルのグループから他のExcelプロジェクトを組み立てるExcelプロジェクトを作成しました。
オブジェクトモデルは、VBScriptおよびHTAからも機能します。一度にHTAを作成して、多数のWord、Excel、およびAccessプロジェクトを追跡できるようにしました。プロジェクトの多くは共通のコードモジュールを使用し、モジュールが1つのシステムで「成長」してから、他のシステムに移行する必要があるのは簡単でした。私のHTAを使用すると、プロジェクト内のすべてのモジュールをエクスポートし、それらを共通フォルダー内のバージョンと比較して、更新されたルーチンをマージし(BeyondCompareを使用)、更新されたモジュールを再インポートできます。
VBEオブジェクトモデルは、Word、Excel、Accessで動作が少し異なり、残念ながらOutlookではまったく動作しませんが、コードを管理するための優れた機能を提供します。
IsDate("13.50")
戻るTrue
がIsDate("12.25.2010")
戻るFalse
これは、IsDate
より正確に名前を付けることができるためIsDateTime
です。また、ピリオド ( .
) は日付の区切り記号ではなく時間の区切り記号として扱われるためです。完全な説明については、こちらを参照してください。
VBA は、2 つの値の 2 進数 (ビット) を比較するためのビット演算子をサポートしています。たとえば、式 4 And 7 は、4 (0100) と 7 (0111) のビット値を評価し、4 (両方の数値でオンになっているビット) を返します。同様に、式 4 Or 8 は、4 (0100) のビット値を評価します。 ) と 8 (1000) を返し、12 (1100) を返します。つまり、どちらかが真のビットです。
残念ながら、ビット単位の演算子の論理比較演算子の名前は、And、Eqv、Imp、Not、Or、および Xor と同じです。これはあいまいさ、さらには矛盾した結果につながる可能性があります。
例として、イミディエイト ウィンドウ (Ctrl+G) を開き、次のように入力します。(2 And 4) 2 (0010) と 4 (0100) の間に共通のビットがないため、これはゼロを返します。
この機能は、おそらく下位互換性のために存在します。またはどうしようもなく難読化されたスパゲッティ コードを記述すること。あなたの選択。