【问题标题】:Excel VBA: Why is API better than SendKeys?Excel VBA:为什么 API 比 SendKeys 更好?
【发布时间】:2016-05-10 09:00:23
【问题描述】:

我目前正在 Excel 中处理一个 VBA 项目,我需要解锁一个 VBProject 并锁定另一个 VBProject。到目前为止,我一直在使用 SendKeys 进行此操作,但我一直在读到这不是一个好方法,而且那个 API 更好? (例如在这个线程中:Unprotect VBProject from VB code

但是,在我的研究过程中,我找不到任何关于原因的详细信息。

谁能告诉我为什么 SendKeys 不好?有哪些可能出错的地方? (请注意,我的 SendKeys 序列最多只有 1.5 秒长。) 另外,为什么 API 是更好的方法?

谢谢! :)

【问题讨论】:

  • SendKeys 是不可靠的,因为它确实将命令发送到活动窗口,并且并不总是可以保证那是预期的窗口。
  • 正确。它只是sending key strokes(由@ojf 解释)。现在想象一下您的 Excel 代码正在运行,并且有人试图在代码运行时完成一些浏览...按下键并将活动窗口更改为浏览器。
  • API 有很大的优势,您可以指定正在处理的对象。您可以根据需要指定 Excel 实例,但更常见的是指定 workbook 和/或 worksheet,因为这样会自动找到正确的实例。
  • 试试看。我不记得发送密钥的单一应用程序不是脆弱和不可靠的。尝试使用它进行编码几乎总是一种恶化的练习。花一个小时试图让它(某种)工作足以让任何程序员相信SendKeys是最后的工具。
  • 想想经典的《辛普森一家》剧集,胖荷马在去看下午的电影日场时,用一个浮游鸟玩具不断敲击“确定”。这就是 SendKeys,通常会产生类似的结果。

标签: vba api excel sendkeys


【解决方案1】:

WinAPI 使用诸如窗口句柄之类的东西(您之前可能在代码中看到过hWnd?)来定位特定的窗口。一旦有了这个,您就可以向该窗口发送和接收消息,而不管它的窗口状态(活动/非活动)等。

您正在直接处理对象,这是编程应该的方式。

SendKeys() 方法只是模拟用户在键盘上敲击键,而不管打开的窗口和位置如何 - 因此它自然地将输出发送到任何处于活动状态并能够接收它的对象。


另一种思考方式

如果您正在编写代码以在 VBA 中某个工作表上的单元格中放置一个值,您可以执行以下操作:

Range("A1").Value = "Foo"

这一切都很好,但它假设我们想要的工作表是当时的活动工作表。如果不是,则将填充错误工作表上的错误单元格。这实际上就是您使用 SendKeys() 所做的事情

另一方面:

Workbooks("Target Workbook.xlsx").Sheets("Target Sheet").Range("A1").Value = "Foo"

指定确切的单元格,在确切的工作表中,在我们想要定位的确切工作簿中 - 所以如果该工作表在那个时间点不活动,那么不用担心!它仍然会去正确的地方(这就是你使用 API 所做的事情)


注意事项

在 VBA 中使用 WinAPI 可能如果您不知道自己在做什么,可能会有风险 - 这些方法的代码是在外部库中预编译的,这意味着您的 VBE 错误处理程序是不会有任何用处。如果您在 API 上犯了错误,则可能会损坏您的工作簿(或者更糟,具体取决于您实际在做什么)。

您还需要查看 VBA 中的条件编译,因为您必须根据使用的是 32 位还是 64 位版本来不同地声明函数和参数。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-04-27
    • 1970-01-01
    • 2013-03-18
    • 1970-01-01
    • 1970-01-01
    • 2018-03-22
    • 1970-01-01
    • 2012-02-04
    相关资源
    最近更新 更多