从一个工作表复制粘贴到另一个工作表的宏

Macro to copy and paste from one worksheet to another

我有一个工作簿,我需要在其中单击工作表的单个单元格并按下命令按钮。这会将单元格值复制并粘贴到同一工作簿中不同工作表上 E 列的第一个空白单元格。当我只 运行 宏本身时,它工作正常。但是当我将代码粘贴到命令按钮时,它给了我几个 运行 时间错误 1004。最常见的错误是 "Select method of range class failed",它指的是告诉它 select 范围 (E4) 的代码行。这是代码:

Private Sub CommandButton1_Click()

' Choose player from Player list and  paste to Draft list.

    Sheets("Players").Select
    Selection.Select
    Selection.Copy

    Sheets("Draft").Select
    Range("E4").Select
    Selection.End(xlDown).Select
    ActiveCell.Offset(1).Select
    Selection.PasteSpecial _ 
        Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks:=False, Transpose:=False

End Sub
Private Sub CommandButton1_Click()
     Sheets("Draft").Range("E4").End(xlDown).Offset(1).Value2 = ActiveCell.Value2
End Sub

我的座右铭:如果它没有 Select 方法,它就不会有 Select 方法错误。
有趣的事实:即使它工作正常,如果 E4 为空,它也会替换您现有的值。我建议改用 LastRow(我最喜欢 Range("E:E").Find)。

TL;DR,解决此问题的几个选项,按优先顺序排列:

  1. Stop using Select 访问单元格
  2. 通过使用 Application.Range("E4")Sheets("Draft").Range("E4")ActiveSheet.Range("E4")
  3. Worksheet 对象中执行代码时限定对 Range("E4") 的调用
  4. 将代码移至 ThisWorkbook 或代码模块并从事件中调用 Sub

这是试图解释为什么您的代码不起作用的冗长部分。

这一切归结为:代码在哪里执行?当您使用对 Cells Range 和许多其他函数的非限定引用时,不同的执行上下文会有不同的行为。

您的原始代码可能 运行 在 ThisWorkbook 中,一个代码模块中,或者可能在 sheet Draft 的代码文件中。为什么我会这么猜?因为在所有这些地方都可以调用 Range("E4") 来获取 sheet Draft 上的单元格 E4。案例:

  • ThisWorkbook 并且代码模块将在 ActiveSheet 上执行 Range,这是 Draft,因为您刚刚在其上调用了 Select
  • Inside Draft 将在 Draft 的上下文中执行 Range 这是可以接受的,因为那是 ActiveSheet 和您尝试获取单元格 E4.

现在,当我们将 ActiveX CommandButton 添加到组合中时会发生什么?好吧,该代码已添加到它所在的 Worksheet 中。这意味着按钮的代码可能会在与以前不同的上下文中执行。唯一的例外是如果按钮和代码都在 sheet Drafts 上,我认为这不是因为你 Select 那 sheet。为了演示,假设按钮位于 sheet WHERE_THE_BUTTON_IS.

鉴于sheet,现在发生了什么?您对 Range 的调用现在在 sheet WHERE_THE_BUTTON_IS 的上下文中执行,而不管 ActiveSheet 或您在对 Range 的调用。这是因为对 Range 的调用是 不合格的 。也就是说,没有对象为调用提供范围,因此它在当前范围内运行,即 Worksheet.

所以现在我们在 sheet WHERE_THE_BUTTON_IS 中调用了 Range("E4"),它正在尝试 Select 单元格。这是被禁止的,因为 sheet DraftActiveSheet

Thou shalt not Select a cell on a Worksheet that is not the ActiveSheet

那么面对所有这些,我们如何解决这个问题?有几个出路:

  1. Stop using Select to manipulate cells。这摆脱了上面引用的主要问题。这假设您的按钮与 Selection 到 copy/paste.
  2. 处于相同的 sheet

Private Sub CommandButton1_Click()

    Sheets("Draft").Range("E4").End(xlDown).Offset(1).Value = Selection.Value

End Sub

  1. 限定对 Range 的调用,以便它在正确的上下文中执行并选择正确的单元格。您可以使用 Sheets("Draft").Range 对象来限定此或 Application.Range 而不是裸 Range。我强烈推荐选项 1,而不是试图弄清楚如何使 Select 工作。

Private Sub CommandButton1_Click()
    Sheets("Players").Select
    Selection.Copy

    Sheets("Draft").Select

    'could also use Application.Range here
    Sheets("Draft").Range("E4").Select
    Selection.End(xlDown).Select
    ActiveCell.Offset(1).Select

    Selection.PasteSpecial _
        Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks:=False, Transpose:=False
End Sub

  1. 将代码移回 Worksheet 对象之外的 Sub 并从 CommandButton1_Click 事件中调用它。