【问题标题】:Copying text to clipboard using VBA使用 VBA 将文本复制到剪贴板
【发布时间】:2013-05-28 07:34:39
【问题描述】:

在 MS Excel 2010 中,我尝试使用 SendKeys 将一些文本复制到剪贴板。但是,它不起作用。

这是 Microsoft 为防止人们创建欺诈性宏而采取的某种安全措施吗?这是一些代码,显示了我正在尝试做的事情(假设您在 vba 窗口中并选择了一些文本):

Public Sub CopyToClipboardAndPrint()
    Call SendKeys("^(C)", True)
    Dim Clip As MSForms.DataObject
    Set Clip = New MSForms.DataObject
    Clip.GetFromClipboard
    Debug.Print Clip.GetText
End Sub

请注意,要使用 MSForms.DataObject,您必须引用 %windir%\system32\FM20.DLL(即 Microsoft Forms 2.0 对象库)。


编辑: 我要复制的文本是 not 在文档窗口中,而是在 vba 项目窗口的即时窗口中!所以 Selection.Copy 在这里不起作用。

【问题讨论】:

  • 打不通Clip.SetText("Some Text", 1)Clip.PutInClipboard有什么原因吗?
  • 在运行时之前我不知道"Some Text" 是什么。我真的需要获取已在焦点窗口中选择的文本。
  • 你试过SendKeys "^g^c"吗?
  • 我确实选择了带有"^g" 的即时窗口,是的。在单独的 SendKeys 中,我尝试过 "^c""^C""^(c)""^(C)"
  • 这可能有点跑题了,但是...如果您立即有一些数据,我想您是从任何其他子例程那里编写的。你不能用任何公共变量而不是读取即时窗口来捕捉这些数据吗?你确定你已经探索了所有可能的方法......

标签: vba excel excel-2010


【解决方案1】:

以下代码使用 Windows API 中的 SendInput 函数来模拟 Control-C 组合键,以便将当前文本选择复制到剪贴板。

复制/打印子例程(代码中的最后一个过程)调用两个实用函数来触发必要的按键操作,然后使用您准备的代码从剪贴板中检索文本。

我已经在即时窗口、代码编辑器窗格和工作表中测试了代码。

  Option Explicit

  'adapted from:
  '  http://www.mrexcel.com/forum/excel-questions/411552-sendinput-visual-basic-applications.html

  Const VK_CONTROL = 17       'keycode for Control key
  Const VK_C = 67             'keycode for "C"
  Const KEYEVENTF_KEYUP = &H2
  Const INPUT_KEYBOARD = 1

  Private Type KEYBDINPUT
      wVK As Integer
      wScan As Integer
      dwFlags As Long
      time As Long
      dwExtraInfo As Long
  End Type

  Private Type GENERALINPUT
      dwType As Long
      xi(0 To 23) As Byte
  End Type

  Private Declare Function SendInput Lib "user32.dll" _
      (ByVal nInputs As Long, _
      pInputs As GENERALINPUT, _
      ByVal cbSize As Long) As Long

  Private Declare Sub CopyMemory Lib "kernel32" _
      Alias "RtlMoveMemory" _
      (pDst As Any, _
      pSrc As Any, _
      ByVal ByteLen As Long)

  Private Sub KeyDown(bKey As Byte)
      Dim GInput(0 To 1) As GENERALINPUT
      Dim KInput As KEYBDINPUT
      KInput.wVK = bKey
      KInput.dwFlags = 0
      GInput(0).dwType = INPUT_KEYBOARD
      CopyMemory GInput(0).xi(0), KInput, Len(KInput)
      Call SendInput(1, GInput(0), Len(GInput(0)))
  End Sub

  Private Sub KeyUp(bKey As Byte)
      Dim GInput(0 To 1) As GENERALINPUT
      Dim KInput As KEYBDINPUT
      KInput.wVK = bKey
      KInput.dwFlags = KEYEVENTF_KEYUP
      GInput(0).dwType = INPUT_KEYBOARD
      CopyMemory GInput(0).xi(0), KInput, Len(KInput)
     Call SendInput(1, GInput(0), Len(GInput(0)))
  End Sub

  Sub CopyToClipboardAndPrint()
      Dim str As String

      'Simulate control-C to copy selection to clipboard
      KeyDown VK_CONTROL
      KeyDown VK_C
      KeyUp VK_C
      KeyUp VK_CONTROL

      DoEvents

      Dim Clip As MSForms.DataObject
      Set Clip = New MSForms.DataObject
      Clip.GetFromClipboard
      Debug.Print Clip.GetText
  End Sub

【讨论】:

  • 感谢您对此进行调查,但这在我的情况下不起作用,因为我没有从文档中复制(未选择单元格)。查看我的编辑。
  • 请看我修改后的答案,Alexander。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-03-19
  • 2010-12-01
  • 2011-10-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多