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

时间:2015-06-12 16:42:49

标签: excel excel-vba excel-2010 vba

我有一个工作簿,我需要能够单击工作表的单个单元格并点击我的命令按钮。它将单元格值复制并粘贴到同一工作簿中不同工作表上的E列中的第一个空白单元格。当我只是自己运行宏时,它工作正常。但是当我将代码粘贴到命令按钮时,它会给我一些运行时错误1004。最常见的错误是“选择范围类失败的方法”,并引用告诉它选择范围(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

2 个答案:

答案 0 :(得分:2)

TL; DR ,按优先顺序选择解决此问题的选项:

  1. Stop using Select访问单元格
  2. 使用Range("E4")WorksheetApplication.Range("E4")
  3. Sheets("Draft").Range("E4")对象中执行代码时,对ActiveSheet.Range("E4")的来电有资格
  4. 将代码移至ThisWorkbook或代码模块,并从活动中调用Sub
  5. 这是一个冗长的部分,试图解释为什么你的代码不起作用。

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

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

    • ThisWorkbook并且代码模块将在Range ActiveSheet上执行Draft,因为您刚刚调用了Select
    • 内部Draft将在Range的上下文中执行Draft这是可以接受的,因为那是ActiveSheet以及您尝试获取单元格的地方{{1} }}。

    现在,当我们向混合添加ActiveX E4时会发生什么?那么代码被添加到它所在的CommandButton。这意味着按钮的代码可能在与以前不同的上下文中执行。唯一的例外是,如果按钮和代码都在工作表Worksheet上,我认为不是因为您Drafts该工作表。对于演示,假设该按钮位于工作表Select上。

    鉴于那张表,现在发生了什么?现在,WHERE_THE_BUTTON_IS RangeWHERE_THE_BUTTON_IS 表格的执行情况执行ActiveSheet或<{1}}或Range以外的任何其他操作}。这是因为对Range的调用是不合格的。也就是说,没有对象为调用提供范围,因此它在当前作用域Worksheet中运行。

    现在,我们在工作表Range("E4")中调用WHERE_THE_BUTTON_IS,试图Select该单元格。这是禁止的,因为工作表DraftActiveSheet

      

    您不能Select Worksheet上不是ActiveSheet 的单元格

    所有这一切,我们如何解决这个问题?有几种方法可以解决:

    1. Stop using Select to manipulate cells 即可。这远离了上面引用的主要问题。这假设您的按钮与要复制/粘贴的Selection位于同一张纸上。
    2. 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工作。
      2. 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. 将代码移回Sub对象之外的Worksheet,并从CommandButton1_Click事件中调用它。

答案 1 :(得分:1)

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)。