在VBA中进行Debug.Print

use*_*973 4 excel vba debug-print

在VBA中,Debug.Print打印到立即窗口。

我刚刚发现,使用分号(;)可以将其打印在插入符号/文本光标的位置,这似乎很奇怪。

Debug.Print "a" & "b" & "c"
Debug.Print ; "a"; "b"; "c"
Debug.Print "a", "b", "c"
Run Code Online (Sandbox Code Playgroud)

打印以下内容。

abc
abc
a             b             c
Run Code Online (Sandbox Code Playgroud)

这是我在文档中找到并进一步了解之前的主要问题。

使用分号(;)将插入点放置在最后一个显示的字符之后。

我现在的问题是是否可以使用这样的命名参数

Debug.Print object:="..."
Run Code Online (Sandbox Code Playgroud)

Intellisense通常有助于查找参数的名称,但不会列出任何名称。

我也尝试过objectoutputlist喜欢它在文档中显示,但它引发了错误。

Debug.Print在这方面有什么不同?

Mat*_*don 8

Debug陈述确实与其他所有陈述不同。如果Debug对象浏览器中寻找模块,即使显示隐藏的类和成员,也找不到。

Debug.PrintDebug.Assert语句实际上是烘焙到[parser]语言中的-此处的逗号并不表示“参数分隔符”,而是[显然]为Print方法保留的一种特殊形式的语法(注意:VBA用户代码不能Print用于方法名称,它是保留的)。

因此,Debug语句基本上是特殊的关键字。对于参数列表语法元素显示了IntelliSense / parameter quick-info ,但从语法上讲,a的“参数” Debug.Print输出列表,就像Print语句一样。

请注意,VBE自动将?令牌转换为Print语句:

Debug.? --> Debug.Print
Run Code Online (Sandbox Code Playgroud)

有很多历史包bag Print:关键字/命令(及其?缩写)在旧的BASIC方言中用于将内容输出到屏幕...或实际的[点矩阵!]打印机。

因此,简短的答案是,Debug语句是使用关键字而不是成员调用来编写的-这就是为什么IntelliSense与它们没有任何用处的原因,因为它没有任何参数。

Rubberduck项目有一个有趣的故事,这些语句...因为它是不是真的有可能来分析一个典型的Debug.Print比任何不同语句中的任何其他隐callStmt(即它看起来像任何其他程序调用解析),我们不得不放弃声明它自己的专用解析器规则,并“声明”一个假DebugClass模块并Print对该“类” 进行“方法”,以便能够像对其他早期绑定的标识符引用一样跟踪使用情况:

VBE7.DLL; VBA.DebugClass.Print(过程)

但是实际上并没有这样的东西:带有输出列表的语句在解析器和编译器级别被烘焙到语言中,而实际上,您在VBA中进行的每个其他成员调用都是某个模块的成员 -点击F2并浏览VBA的标准库的成员:你会发现CLng类型转换,NowDateAdd日期/时间函数,MsgBoxDoEvents,和许多其他人-都属于一些模块。但是Debug语句更接近于StopResume关键字,在较低级别上进行处理。


进一步证明,有更多比遇见眼睛-比简单的事实,即默认语法在VBE强调将突出两个其他DebugPrint在明亮的关键字蓝色,如果您编译C#编写一个COM可见的类:

Debug.? --> Debug.Print
Run Code Online (Sandbox Code Playgroud)

..然后从VBA代码中调用它...

PrintMethodTest客户端代码

DoSomething可以调用该方法,但是该Print方法将引发错误438-就像您尝试使用以外的任何其他方法来限定它一样Debug。那么,如何Print在Access报表的代码后面工作呢?

该接口未记录,因此仅是推测,但是有一个IVBPrint接口看起来非常像VBA正在寻找的东西:

[
  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);
};
Run Code Online (Sandbox Code Playgroud)

如果真是这样,那么错误438就是VBA所说的“找不到IVBPrint实现”的方式

  • @ user7393973注意,我不了解VBA解析器/编译器的工作原理-只是在Rubberduck开发人员聊天并深入了解VBA规范并尝试使Rubberduck的解析器/解析器“查看” VBA代码为尽可能接近VBE如何“看到”该代码,我们提出了有关手工制作的VBA解析器实际工作原理的理论,“ Debug”语句是我记得的一个讨论的一部分-“ Debug”。正在编译的Print必须产生与“标准”调用语句的操作码不同的特定操作码。 (3认同)
  • 感谢您的见解。这绝对是无论我搜索多少都找不到的信息类型,它比文档中的大多数内容都更有趣。 (2认同)