VBA根据数据值将数据从主表格复制并粘贴到另一个表格中

我有一个名为Mainsheet的主表和另外12个表,每个月一个。

我的Mainsheet可能有一月或二月或三月的数据等。我需要复制反映在我的mainsheet的数据,并粘贴到1 JanFeb之一,具体取决于哪个月。

这是我到目前为止..

 Sub Macro1() Dim i, LastRow LastRow = Sheets("Mainsheet").Range("A" & Rows.Count).End(xlUp).Row For i = 5 To LastRow If Sheets("Mainsheet").Cells(i, "E").Value = "1/20/2017" Then Sheets("Mainsheet").Cells(i, "A").EntireRow.Copy Destination:=Sheets("Jan").Range("A" & Rows.Count).End(xlUp).Offset(1) End If Next i End Sub 

我的问题是如果数据是Feb月份而不是Jan月份,我该如何继续macros观? 我怎样才能指定Jan的月份,而不是一个特定的date,如1/20/2017在我的代码?

另外,我怎样才能复制范围从A5:M5加上行直到最后填充单元格,而不是复制从A:5的整个范围,直到最后一列使用?

做得好! 您已经编写了处理一个月工作表的代码!

现在拿这个块,复制它 – 而不是粘贴在下面,用"Feb"replace"Jan"等等… 12次….做到这一点:

 Private Sub UpdateMonthlyData(ByVal target As Worksheet) End Sub 

然后粘贴在那里,并用targetreplaceSheets("Jan") 。 你留下这个:

 Private Sub UpdateMonthlyData(ByVal target As Worksheet) Dim i, LastRow LastRow = Sheets("Mainsheet").Range("A" & Rows.Count).End(xlUp).Row For i = 5 To LastRow If Sheets("Mainsheet").Cells(i, "E").Value = "1/20/2017" Then Sheets("Mainsheet").Cells(i, "A").EntireRow.Copy Destination:=target.Range("A" & target.Rows.Count).End(xlUp).Offset(1) End If Next i End Sub 

让我们清理一下 – 双击Project Explorer中Mainsheet (Sheet1)对象(Ctrl + R – 用Rubberduck调出代码pipe理器 ),然后点击F4打开它的属性。 将Sheet1(Name)属性更改为MainSheet 。 现在你可以做到这一点:

 Private Sub UpdateMonthlyData(ByVal target As Worksheet) With MainSheet Dim lastRow As Long lastRow = .Range("A" & .Rows.Count).End(xlUp).Row Dim i As Long For i = 5 To lastRow If .Cells(i, "E").Value = #1/20/2017# Then .Cells(i, "A").EntireRow.Copy target.Range("A" & target.Rows.Count).End(xlUp).Offset(1) End If Next End With End Sub 

MainSheet是通过将其(Name)属性设置为MainSheet而获得的“free”全局作用域对象variables – VBA创build一个以该(Name)命名的全局作用域对象,并且您可以在代码中的任何位置使用它来引用表。

那么我们到了什么地方? 我们得到一个monthSheet参数,这是我们正在复制的工作表:找出它是另一个问题,我们不需要为此烦恼。 我把声明移到了他们使用的地方,并且声明了一个明确的types, With MainSheet指令限定了所有使用点的地方.该工作表对象。

合格的东西是重要的:当它没有一个明确的工作表引用, RangeCellsRowsColumns ,…他们都隐式引用ActiveSheet – 当您使用任何工作表不是活动工作表,隐含地要求激活表意味着麻烦。

我用#代替#date literal# ,而不是" – 这是string文字。通过使用#date literal# Date #date literal#你避免从StringDate的隐式转换,因为.Cells(i, "E").Value应该是一个Variant/Date

接下来我们参数化月份并推断工作表:

 Private Sub UpdateMonthlyData(ByVal monthIndex As Long) With MainSheet On Error GoTo ErrHandler Dim name As String name = MonthName(monthIndex, True) Dim target As Worksheet target = ThisWorkbook.Worksheets(name) On Error GoTo 0 'from this point onward any error bubbles up to the caller Dim lastRow As Long lastRow = .Range("A" & .Rows.Count).End(xlUp).Row Dim i As Long For i = 5 To lastRow Dim monthCell As Range monthCell = .Cells(i, "E") If Not IsError(monthCell.Value) Then If CStr(monthCell.Value) = name Then .Cells(i, "A").EntireRow.Copy target.Range("A" & target.Rows.Count).End(xlUp).Offset(1) End If Else Debug.Print "Cell " & monthCell.Address & " contains an error value and cannot be processed." End If Next End With Exit Sub ErrHandler: Debug.Print "Could not find a worksheet for month " & monthIndex & "." End Sub 

现在,调用者只需要运行从1到12的循环来处理所有表单:

 For i = 1 To 12 UpdateMonthlyData i Next 

它并没有比我想象的更清洁:)

现在, .Copy操作仍然没有做你想做的事情 – 但是,唉,这个答案已经够长了! 祝你好运!