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

我有一个工作簿,我需要能够单击工作表的单个单元格,然后点击我的命令button。 将单元格的值复制并粘贴到同一工作簿中不同工作表上列E中的第一个空白单元格。 当我自己运行macros时,它工作正常。 但是,当我将代码粘贴到一个命令button,它给了我几个运行时错误1004年。 最常见的错误是“select范围类失败的方法”,并引用指示它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 

TL; DR ,夫妇的select来解决这个,按照优先顺序:

  1. 停止使用Select来访问单元格
  2. 使用Application.Range("E4")Sheets("Draft").Range("E4")ActiveSheet.Range("E4")执行Worksheet对象中的代码时,限定对Range("E4")
  3. 将代码移到ThisWorkbook或代码模块,并从事件中调用该Sub

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

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

您的原始代码可能运行在ThisWorkbook ,代码模块,或可能在表单Draft的代码文件Draft 。 我为什么猜这个? 因为在所有这些地方调用Range("E4")是可以接受的单张Draft单元格E4 。 案例:

  • ThisWorkbook和一个代码模块将在ActiveSheet上执行Range ,因为您只需调用Select就可以了。
  • 内部Draft将在Draft的上下文中执行Range是可以接受的,因为这是ActiveSheet和您试图获得单元格E4

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

鉴于该表,现在发生了什么? 您对Range调用现在在表WHERE_THE_BUTTON_IS的上下文中执行, 而不pipe ActiveSheet或您在调用Range之外做的任何事情。 这是因为对Range的调用是不合格的 。 也就是说,没有任何对象为调用提供作用域,所以它在当前的作用域范围内运行。

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

不要在不是ActiveSheetWorksheetSelect一个单元格

所有这一切,我们如何解决这个问题? 有几个出路:

  1. 停止使用Select操作单元格 。 上面引用的这个问题摆脱了这个主要问题。 这假定您的button与Selection复制/粘贴在同一张纸上。

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

  1. 限定对Range的调用,以便在正确的上下文中执行并select正确的单元格。 您可以使用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事件调用它。
 Private Sub CommandButton1_Click() Sheets("Draft").Range("E4").End(xlDown).Offset(1).Value2 = ActiveCell.Value2 End Sub 

我的座右铭:如果它没有Select方法,它不能有一个Select方法错误。
有趣的事实:即使它正常工作,如果E4是空的,它将取代你现有的值。 我build议使用LastRow (我喜欢Range("E:E").Find最多)。