如何使用Access/VBA将内容复制到剪贴板?

42

如何在Access2003/2007中使用VBA。

如何将字符串变量的内容复制到剪贴板?

这个网站建议创建一个零长度的文本框,将字符串复制到文本框,然后运行DoCmd.RunCommand acCmdCopy。哎呀。我是说,我们可能会走这条路。但还是不太好懂。

虽然微软知识库文章告诉我们如何做,但它涉及许多Windows API调用。咦呀。

那些是唯一的两个选择吗?


4
坚持使用外部引用而抵制API代码真的很愚蠢。 - David-W-Fenton
1
我差点没点击微软的链接,因为我看到了“gazillion”,只是提醒其他人,这是5个API调用,并且他们已经为您放置在一个很好的函数中。实际上,我几乎想复制/粘贴它并在此处发布,因为我们都知道微软会删除链接。 - eselk
API的问题在于当你需要编写用于32位和64位环境的代码时,会变得有点复杂。我曾经历过这种情况,也因此备受困扰。我认为将Forms库添加为引用绝对值得努力。 - Steve Levine
6个回答

65

在VB 6中,提供了一个名为Clipboard的对象来使得这一切非常简单和方便,但不幸的是,从VBA中无法使用该对象。

如果这是我,我会选择使用API路径。没有理由害怕调用本地API;语言为您提供了此功能的能力。

然而,更简单的方法是使用DataObject类,它是Forms库的一部分。只有在您的应用程序中已经使用了Forms库中的功能时,才建议采用这种方法。仅为使用剪贴板添加对此库的引用似乎有点傻。

例如,要将一些文本放入剪贴板中,您可以使用以下代码:

Dim clipboard As MSForms.DataObject
Set clipboard = New MSForms.DataObject
clipboard.SetText "A string value"
clipboard.PutInClipboard

或者,将剪贴板中的文本复制到一个字符串变量中:

Dim clipboard As MSForms.DataObject
Dim strContents As String

Set clipboard = New MSForms.DataObject
clipboard.GetFromClipboard
strContents = clipboard.GetText

5
坚持使用API的好处值得点赞。在使用API方面,其实额外的代码并不是很多。尤其是因为你只需要从MSDN复制并粘贴代码一次,然后在需要时调用一个简单的函数"ClipBoard_SetData()"即可。我同意这对于VBA来说确实是个奇怪的疏忽,但使用API并没有那么糟糕。 - mwolfe02
2
API是这里唯一的选择。为可以使用API完成的事情添加引用是非常愚蠢的。 - David-W-Fenton
1
@David:同意,我在我的回答中甚至提到了这一点。如果已经因为其他原因使用了Forms库,那么才应该使用它来完成这个任务。然而,问题确实问到了是否仅有这两个选项。这是第三个选项,即使我不建议使用它。 - Cody Gray
12
在XP 32位系统中,可以在C:\windows\system32\fm20.dll路径下找到Microsoft Forms 2.0 Object Library - Tino
1
@Renaud 这不仅仅是复制和粘贴“旧陈代码”。问题在于老派的VB在处理Unicode字符串方面存在一些真正的局限性。内置的String类型是ANSI。虽然有可能绕过这些限制,但它远远超出了简单回答SO问题的范围。一个人可以写一整本书来讲述这个问题(然后永远无法出版,因为技术已经“过时”)。无论如何,如果您需要支持Unicode,调用WinAPI函数的Unicode版本相对容易:将字符串声明为LONG,然后使用StrPtr()。 - Cody Gray
显示剩余7条评论

9

社交网站msdn.microsoft.com上的用户Leigh Webber发布了一个使用Windows API实现易于使用的剪贴板接口的VBA代码:

http://social.msdn.microsoft.com/Forums/en/worddev/thread/ee9e0d28-0f1e-467f-8d1d-1a86b2db2878

您可以在此处获取Leigh Webber的源代码

如果该链接无法打开,请在Office Dev Center > Microsoft Office for Developers Forums > Word for Developers部分中搜索“用于VBA的剪贴板对象”。

我创建了这两个类,运行了他的测试用例,在Windows 7 64位下Outlook 2007 SP3 32位VBA中完美地工作。它很可能也适用于Access。 提示:要重命名类,请在VBA“项目”窗口中选择该类,然后单击菜单栏上的“视图”,再单击“属性窗口”(或只需按F4)。

使用他的类,这就是从剪贴板复制/粘贴的代码:

Dim myClipboard As New vbaClipboard  ' Create clipboard

' Copy text to clipboard as ClipboardFormat TEXT (CF_TEXT)    
myClipboard.SetClipboardText "Text to put in clipboard", "CF_TEXT"    

' Retrieve clipboard text in CF_TEXT format (CF_TEXT = 1)
mytxt = myClipboard.GetClipboardText(1)

他还提供了其他操作剪贴板的功能。 它还克服了32KB MSForms_DataObject.SetText限制——这也是SetText经常失败的主要原因。然而,需要注意的是,不幸的是,我没有找到微软承认这一限制的参考资料。 -Jim

7

2
很抱歉,我无法回答此问题,因为没有任何要翻译的内容。请提供需要翻译的英文文本。 - Mallow
1
我尝试使用API过程复制到剪贴板例程,在我的Access 2010 .accdb项目中运行良好。 - bgmCoder

2

简单的两行代码:

这并不复杂,我不明白为什么网络上所有的解决方案都这么复杂。

Sub StoreData()

  Set objCP = CreateObject("HtmlFile")
  objCP.ParentWindow.ClipboardData.SetData "text", "Some text for clipboard"

End Sub

1
太棒了,David!这个方法对我有用。当我使用远程应用程序通过 MS Access 时,API 调用会引起问题。 - Dave Stuart

0

这里列出了许多示例,但似乎没有覆盖直接使用 API 与 Access 和 Excel 32 位和 64 位版本工作的方法。

我不想抄袭别人的工作,所以我指向了一篇有解决方案的文章。

https://dev59.com/ZGMl5IYBdhLWcg3wHj5O#35512118


0

继续David的想法,如果你想传递一个参数,它必须用双引号括起来。

Public Sub SetClipboardText(ByVal Text As String)
    Dim QuotedText As String
    QuotedText = """" & Text & """"
    Set HtmlFileObject = CreateObject("HtmlFile")
    HtmlFileObject.ParentWindow.ClipboardData.SetData "text", Eval(QuotedText)
End Sub

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接