首页 文章

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

提问于
浏览
0

我有一个工作簿,我需要能够点击工作表的单个单元格并点击我的命令按钮 . 它将单元格值复制并粘贴到同一工作簿中不同工作表上的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 回答

  • 2

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

    • Stop using Select访问单元格

    • 使用 Application.Range("E4")Sheets("Draft").Range("E4")ActiveSheet.Range("E4")Worksheet 对象中执行代码时,对 Range("E4") 的调用进行限定

    • 将代码移动到 ThisWorkbook 或代码模块,并从事件中调用 Sub .


    这是一个冗长的部分,试图解释为什么你的代码不起作用 .

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

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

    • ThisWorkbook 和一个代码模块将在 ActiveSheet 上执行 Range ,这是 Draft ,因为你刚刚调用 Select .

    • 内部 Draft 将在 Draft 的上下文中执行 Range ,这是可以接受的,因为那是 ActiveSheet 以及您尝试获取单元格 E4 的位置 .

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

    鉴于那张表,现在发生了什么?您对 Range 的调用现在在 ActiveSheet 的工作表 WHERE_THE_BUTTON_IS regardless 或您在 Range 调用之外执行的任何其他操作中执行 . 这是因为对 Range 的调用是不合格的 . 也就是说,没有对象为调用提供范围,因此它在当前范围内运行,即 Worksheet .

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

    您不能在工作表上选择不是ActiveSheet的单元格

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

    • Stop using Select to manipulate cells . 这远离了上面引用的主要问题 . 这假设您的按钮与 Selection 位于同一工作表上以进行复制/粘贴 .

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

    • Qualify the call to 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
    

    • 将代码移回 Worksheet 对象之外的 Sub ,并从 CommandButton1_Click 事件中调用它 .
  • 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 ) .

相关问题