为啥 Excel vba 复制到剪贴板不一致?

Posted

技术标签:

【中文标题】为啥 Excel vba 复制到剪贴板不一致?【英文标题】:Why does Excel vba copy to clipboard inconsistently?为什么 Excel vba 复制到剪贴板不一致? 【发布时间】:2015-11-30 19:24:00 【问题描述】:

我有一个 excel 宏,它可以做两件非常简单的事情:

    它在一个小窗口中显示当前日期和时间。 它将显示复制为文本字符串,以便根据需要粘贴到其他应用程序中。

显示的单元格中包含以下公式:

=TEXT(NOW(),"yyyy.MM.dd hh:mm:ss")

每 5 秒,宏刷新时间,时钟滴答作响。

我的问题是,当我从单元格中复制时间时,我无法始终将内容粘贴到剪贴板。有时单元格内容会发布到剪贴板。我不知道为什么它有时会起作用,而其他时候却不起作用,因为没有太多事情发生。它应该总是有效的。

我知道数据不在剪贴板上,因为我可以尝试将剪贴板粘贴到不同的程序(如记事本和其他文本应用程序)中,但没有任何反应。

整个代码都在一个模块中。

     Dim stopSwitch As Integer
     Dim NextTick
     Sub myupdate()
        If ActiveCell.Address = "$B$1" Then
            growWindow ' resize window beyond just clock display
            stopTime '
            Exit Sub ' stop updating
        End If

        Range("a1").Select
        Calculate

        DoEvents
        If ActiveWorkbook.Name = "calendar clock.xlsb" Then shrinkWindow
        NextTick = Now + TimeValue("00:00:05") ' give me 5 seconds to copy/paste
        Application.OnTime NextTick, "myupdate"
        ThisWorkbook.Save ' futile attempt to prevent save dialog
    End Sub

    Sub auto_open()
    ' to stop clock, tap right arrow to select cell b1 when workbook is active
     Range("a1").Select
     myupdate

    End Sub

    Sub growWindow()
        Application.Width = 768
        Application.Height = 621.75
      ThisWorkbook.Save
    End Sub

    Sub shrinkWindow()
      ' strip decorations so window is as small as possible
      Application.DisplayFormulaBar = False
      ActiveWindow.DisplayGridlines = False
      ActiveWindow.DisplayHeadings = False

      ' move window to second monitor and size to single cell display
      Application.WindowState = xlNormal
      Application.Top = 0
      Application.Left = -720
      Application.Width = 174
      Application.Height = 127
      ActiveWindow.WindowState = xlMaximized
    End Sub

    Sub stopTime() ' called when workbook is closed
        On Error Resume Next
        Application.OnTime NextTick, "myupdate", schedule:=False
        Range("b1").Select
    End Sub

    Sub copyTime()
      Range("a1").Copy ' copy time
      Range("f5").PasteSpecial xlPasteValues ' strip formatting
      Range("f5").Copy ' copy time as text
      DoEvents ' hack to attempt to make copy work consistently
    End Sub

以上代码调整窗口大小,每 5 秒更新一次时钟。

要将时钟作为文本复制到剪贴板,我在工作簿中有以下代码

Private Sub Workbook_Activate()
   Application.OnKey "^c", "module1.copyTime"
End Sub

Private Sub Workbook_Deactivate()
   Application.OnKey "^c"
End Sub

Private Sub Workbook_BeforeClose(Cancel As Boolean)
   ' turn off auto update
   Module1.stopTime

   ' resize window so if I open another spreadsheet, it's a reasonable size
   Application.WindowState = xlNormal
   Application.Width = 768
   Application.Height = 621.75
   Application.OnKey "^c" 

   ThisWorkbook.Save ' try to prevent save dialog at close
End Sub

我修改了 copyTime 函数以通过选择未格式化的单元格来验证 ^C 是否可见,并且我可以看到数据始终进入单元格,所以我知道我的问题不在于 Range("a1").copy进入复制时间或粘贴特殊到单元格 f5。

这使得 range("a5").copy 命令在复制失败时成为坏角色,这很奇怪。只要数据保存在电子表格中,就好像复制工作但无法一致地更新外部剪贴板。

这个观察让我尝试将 application.cutcopymode 设置为 xlcopy,判断是否有帮助。我从尝试所有设置中看到的唯一效果是我是否看到 f5 是否用选取框突出显示 - 没有任何设置强制复制到外部剪贴板。

我尝试在复制之前等待时钟滴答,看看是否有东西在复制之后清除剪贴板,如果是时候更新时钟了。这似乎有所帮助,但又不是始终如一。

那么为什么副本无法​​总是更新剪贴板呢?为什么它不起作用时不起作用,而起作用时起作用?更好的是,如何修改此代码使其始终导出到外部剪贴板?

【问题讨论】:

可惜不是司福。不过还是谢谢。 Steven Martin 使用 msforms 的 putinclipboard 方法的解决方案似乎很可靠。 【参考方案1】:

试试这个方法,对我来说总是可靠的

Dim TimeInClip As MSForms.DataObject
Set TimeInClip = New MSForms.DataObject
TimeInClip.SetText Range("A1").Value
TimeInClip.PutInClipboard

【讨论】:

在 2015.11.30 19:53:04,我停止尝试破坏您的解决方案。有用!谢谢!【参考方案2】:

试试

Sub copyTime()
  Range("a1").Copy ' copy time
  Range("f5").PasteSpecial xlPasteValues ' strip formatting
  Application.CutCopyMode = False ' Clear Excel clipboard
  Range("f5").Copy ' copy time as text
  DoEvents ' hack to attempt to make copy work consistently
End Sub

你说你试过Application.CutCopyMode,但你有没有这样试过? 它只会强制应用程序在复制其他内容之前清除剪贴板,然后在新的剪贴板上正确复制。

【讨论】:

是的。我试过=假,=真,和=复制。我看到的唯一效果是选框是否会显示。否则副本不一致。我希望微软能记录下该模式的目的是什么,而不是仅仅说它允许的值是什么。

以上是关于为啥 Excel vba 复制到剪贴板不一致?的主要内容,如果未能解决你的问题,请参考以下文章

vba 怎么读取系统剪贴板中的图片到image控件?

vbscript 在Excel VBA中复制和粘贴的三种方法。请注意,`Range.Copy`和`Range.PasteSpecial`使用剪贴板,因此请避免复制任何内容

在工作簿关闭的Excel VBA中禁用剪贴板提示

VBA PPT复制/粘贴图表不一致

使用 VBA 宏选择和复制 Outlook 电子邮件正文

用VB实现复制粘贴