macros用正确的第一个单元格复制和粘贴行

我有一个包含大量表单和数据的电子表格,每行的第一个单元格总是一个date。 我制作了一个控制表(Control CUSTOM),其中用户在单元格B3和C3中input两个date,然后macros将search工作簿中所有工作表中具有第一个单元格值BETWEEN这些date的行,然后复制并粘贴行到汇总表(Data CUSTOM)。

然而,它并不按照预期工作。 macros设法find正确的行并复制它们,但它总是将它们粘贴到同一行,因此覆盖自身。 它也将它们粘贴到错误的工作表(Control CUSTOM)。

到目前为止,我的代码如下所示:

Sub DataSearch() Dim lngLastRow As Long, lngRow As Long Dim strColumn As String Dim WS_Count As Integer Dim I As Integer Dim NextRow As Variant Dim Date1 As Variant Dim Date2 As Variant Date1 = Sheets("Control CUSTOM").Range("B3") Date2 = Sheets("Control CUSTOM").Range("C3") ' Set correct row for paste, always the next empty row ' Set WS_Count equal to the number of worksheets in the active workbook. WS_Count = ActiveWorkbook.Worksheets.Count ' Begin the loop. For I = 1 To WS_Count strColumn = "A" With ActiveWorkbook.Worksheets(I) lngLastRow = .Cells(.Rows.Count, strColumn).End(xlUp).Row For lngRow = 2 To lngLastRow Set NextRow = Range("A" & Sheets("Data CUSTOM").UsedRange.Rows.Count + 1) If IsDate(.Cells(lngRow, strColumn).Value) And .Cells(lngRow, strColumn).Value >= Date1 And .Cells(lngRow, strColumn).Value <= Date2 Then .Rows(lngRow).Copy NextRow.PasteSpecial Paste:=xlValues, Transpose:=False Application.CutCopyMode = False End If Next lngRow End With Next I End Sub 

希望你们能帮助我。 我有一些与VBA有关的经验,但是这些可能需要的多重循环只是在我头上。

如果你用你的NextRow范围variables解决这两个问题,你的代码应该没问题。

对于性能,您可能需要考虑自动筛选行并在块中进行复制,而不是逐行testing。

您也可能希望从macros中排除您的两个控制表,以便进行良好的编码练习。

Dim NextRow As Variant

Dim NextRow As Range

并改变
NextRow.PasteSpecial Paste:=xlValues, Transpose:=False

Set NextRow = Sheets("Data Custom").Range("A" & Sheets("Data CUSTOM").UsedRange.Rows.Count + 1)

正如brettdj提到的,要解决这个问题,你应该添加

Sheets("Data Custom").

Set NextRow = Range("A" & Sheets("Data CUSTOM").UsedRange.Rows.Count + 1)

所以它写道:

Set NextRow = Sheets("Data Custom").Range("A" & Sheets("Data CUSTOM").UsedRange.Rows.Count + 1)

通过添加Sheets("Data Custom"). 你告诉macros,这个范围不在当前工作表上(这是固有的假设)。

另外,我build议一些额外的调整:

最佳实践/潜在问题

  • 使用ThisWorkbook而不是ActiveWorkbook以确保您没有意外激活另一个工作簿
  • 尽量不要使用.UsedRange属性… EVER。 当你走的时候增加一个计数器或者做一些类似于你之前用lngLastRow = .Cells(.Rows.Count, strColumn).End(xlUp).Row 。 这是因为Excel根据格式化和最大范围等因素定义了.UsedRange 。 因此,如果您有一堆范围内的值,然后清除最后一行的值,则仍然将其视为已使用范围的一部分。
  • 我build议将Dim NextRow As Variant改为Dim NextRow As Range因为NextRow总是一个Range对象,不会改变。 (由brettdj提供)
  • 您也可能希望从循环中排除您的两个控制表,以便在整个过程中不对其进行评估。 这可能会导致潜在的问题(由brettdj提供)

性能

  • 对于性能,您可能需要考虑自动筛选行并在块中进行复制,而不是逐行testing。 (由brettdj提供)
  • 将下面的代码添加到方法的开头(获取date值之后):

     Application.ScreenUpdating = False Application.Calculation = xlCalculationManual 

    在sub的结尾之前:

     Application.ScreenUpdating = True Application.Calculation = xlCalculationAutomatic 

    这告诉Excel停止显示正在对工作簿进行的更改,并停止更新/计算任何公式,直到完成运行macros。 这将是一个巨大的性能增益。