4

VBADebug.Printでは、イミディエイト ウィンドウに出力されます。

セミコロン ( ) を使用すると、キャレット/テキスト カーソル;の位置に印刷されることがわかりましたが、これは奇妙に思えます。

Debug.Print "a" & "b" & "c"
Debug.Print ; "a"; "b"; "c"
Debug.Print "a", "b", "c"

以下を印刷します。

abc
abc
a             b             c

ドキュメントでそれを見つけてもう少し理解する前に、それが私の主な質問でした。

表示されている最後の文字の直後に挿入ポイントを配置するには、セミコロン (;) を使用します。

私の質問は、次のような名前付き引数を使用できるかどうかです。

Debug.Print object:="..."

Intellisense は通常、引数の名前を見つけるのに役立ちますが、一覧には表示されません。

ドキュメントに示されているように試してみobjectましoutputlistたが、エラーがスローされます。

Debug.Printその点で違いますか?

4

1 に答える 1

8

Debugステートメントは実際、他のすべてのものとは異なります。オブジェクト ブラウザDebugでモジュールを探しても、非表示のクラスとメンバーが表示されていても見つかりません。

Debug.PrintおよびDebug.Assertステートメントは文字通り言語 [パーサー] 自体に焼き付けられます。ここでのコンマは「引数区切り」を意味するのではなく、[明らかに]Printメソッド用に予約されている特別な形式の構文です (注: VBA ユーザー コードはPrint、メソッド名、予約済み)。

したがって、Debugステートメントは基本的に特別な種類のキーワードです。引数リストの構文要素について IntelliSense / パラメーターのクイック インフォが表示されますが、構文的には、a の「引数」Debug.Print出力リストであり、 Print ステートメントとまったく同じです。

VBE は自動的に?トークンをPrintステートメントに変換することに注意してください。

Debug.? --> Debug.Print

にはかなりの歴史的な手荷物がありPrintます: キーワード/コマンド (およびその?省略形) は、古い BASIC 方言で、物事を画面に出力するために使用されていました... または実際の [ドット マトリックス!] プリンター。

簡単に言えば、Debugステートメントはメンバー呼び出しではなく、キーワードで作成されます。これが、引数がないため、IntelliSenseが使用されない理由です。

ラバーダックプロジェクトには、これらのステートメントに関する面白い話があります... 典型的なDebug.Printステートメントを他の暗黙的なステートメントとまったく異なる方法で解析することは実際には不可能であるためcallStmt(つまり、他のプロシージャ コールのように見えて解析する)、ステートメントを指定する必要がありました。独自の専用パーサー ルールを作成し、偽のDebugClassモジュールを「宣言」してPrint、その「クラス」の「メソッド」を作成して、他の事前バインドされた識別子参照で行うように使用を追跡できるようにします。

VBE7.DLL;VBA.DebugClass.Print (手順)

しかし、実際にはそのようなことはありません。出力リストを含むステートメントは、パーサーとコンパイラのレベルで言語に焼き付けられますが、文字通り、VBA でこれまでに行った他のすべてのメンバー呼び出しは、何らかのモジュールのメンバーでした。F2 を押して、 VBA 標準ライブラリのメンバー:CLng型変換、Now日付DateAdd/時刻関数、MsgBoxDoEvents、およびその他多数の関数が見つかります。これらはすべて、何らかのモジュールに属しています。ただし、DebugステートメントはStoporResumeキーワードに近く、下位レベルで処理されます。


C# で記述された COM 可視クラスをコンパイルすると、VBE のデフォルトの構文強調表示が明るいキーワード青の両方Debugで強調表示されるという単純な事実を除いて、目に見える以上のものがあることをさらに証明します。Print

[ComVisible(true)]
[InterfaceType(ComInterfaceType.InterfaceIsDual)]
[Guid("6F25002E-2C9F-4D77-8CCB-A9C0E4FB2EF1")]
public interface ITestClass
{
    [DispId(1)]
    void Print(string value);
    [DispId(2)]
    void DoSomething();
}

[ComVisible(true)]
[ComDefaultInterface(typeof(ITestClass))]
[ClassInterface(ClassInterfaceType.None)]
[Guid("6F25002E-2C9F-4D77-9624-6CA79D4F088A")]
[ProgId("PrintTest.Class1")]
[EditorBrowsable(EditorBrowsableState.Always)]
public class Class1 : ITestClass
{
    public void Print(string value)
    {
        /* no-op */
    }

    public void DoSomething()
    {
        /* no-op */
    }
}

..そして、VBA コードから呼び出します...

PrintMethodTest クライアント コード

メソッドを呼び出すことはDoSomethingできますが、Printメソッドはエラー 438 をスローしますDebug。では、どうしてPrintAccess レポートのコード ビハインドで機能するのでしょうか。

インターフェイスは文書化されていないため、これは純粋な憶測ですが、IVBPrintVBA が探しているものと非常によく似たインターフェイスがあります。

[
  odl,
  uuid(000204F0-0000-0000-C000-000000000046),
  nonextensible
]
interface IVBPrint : IUnknown {
    HRESULT _stdcall WriteText([in] BSTR strText);
    [propput]
    HRESULT _stdcall Column([in] long retVal);
    [propget]
    HRESULT _stdcall Column([out, retval] long* retVal);
};

その場合、エラー 438 は、「IVBPrint の実装が見つかりません」という VBA の言い方です。

于 2019-07-22T15:39:57.327 に答える