VBA根据数据值将数据从主表格复制并粘贴到另一个表格中
我有一个名为Mainsheet
的主表和另外12个表,每个月一个。
我的Mainsheet
可能有一月或二月或三月的数据等。我需要复制反映在我的mainsheet
的数据,并粘贴到1 Jan
或Feb
之一,具体取决于哪个月。
这是我到目前为止..
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
然后粘贴在那里,并用target
replaceSheets("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
指令限定了所有使用点的地方.
与该工作表对象。
合格的东西是重要的:当它没有一个明确的工作表引用, Range
, Cells
, Rows
, Columns
,…他们都隐式引用ActiveSheet
– 当您使用任何工作表不是活动工作表,隐含地要求激活表意味着麻烦。
我用#
代替#date literal#
,而不是"
– 这是string文字。通过使用#date literal#
Date
#date literal#
你避免从String
到Date
的隐式转换,因为.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
操作仍然没有做你想做的事情 – 但是,唉,这个答案已经够长了! 祝你好运!