基于日期数据复制和粘贴行的 VBA 代码

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/27655528/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-12 05:38:39  来源:igfitidea点击:

VBA Code to Copy & Paste Rows based on Date data

excel-vbavbaexcel

提问by Jeff

Im new to VBA, so I will geve you some context and purpose of what I hope to achieve. I am copying data from another program (no issues), I then paste it into a WorkSheet that I have coded the formate for the incoming data to nest where I want it to be (looks pretty), I paste by using a UserForm I created (still no issues). I then created another UserForm and use this to sort the data for number of days between date ranges (used VBA with formula) and if no date is present then I assign todays date (Date) all the above works great. My issue is when the user has completed the above, another UserForm pops up to ask if they want to add the overdue data to the report sheet, this is supposed to copy any rows that have todays date (Date) in Column "G" and then paste it to the report sheet row "A1" down

我是 VBA 的新手,所以我会给你一些我希望实现的背景和目的。我正在从另一个程序复制数据(没有问题),然后将其粘贴到工作表中,我已将传入数据的格式编码到我想要的位置(看起来很漂亮),我使用我创建的用户窗体粘贴(仍然没有问题)。然后我创建了另一个用户窗体并使用它来对日期范围之间的天数数据进行排序(使用带有公式的 VBA),如果没有日期,那么我分配今天的日期(日期)以上所有工作都很好。我的问题是,当用户完成上述操作后,会弹出另一个用户窗体询问他们是否要将过期数据添加到报告表中,这应该复制列“G”中具有今天日期(日期)的任何行和然后将其粘贴到报告表行“A1”向下

I would appreciate the help, I have tried a few options and searched high and wide on the net, with the following code so far it looks down column 7, currently I have 15 row items to sort through and two of them have todays date. I keep only getting the last of the two required rows with todays date to paste into the report sheet from the data sheet?

我很感激您的帮助,我尝试了一些选项并在网上进行了广泛搜索,到目前为止,使用以下代码向下查看第 7 列,目前我有 15 个行项目要排序,其中两个有今天的日期。我一直只获取具有今天日期的两个必需行中的最后一行,以便从数据表粘贴到报告表中?

Here is the full code so far with your additional code (the first part formates the destination sheet and as you can see it ensures that destination sheet column "G" is set to format "dd/mm/yyyy":

这是到目前为止的完整代码以及您的附加代码(第一部分格式化目标工作表,如您所见,它确保目标工作表列“G”设置为格式“dd/mm/yyyy”:

Private Sub CommandButton1_Click()
Me.Hide
If Sheets("Masri").Visible Then
  Sheet10.Activate
  Sheet10.Cells.Clear
  Sheet10.Cells.ClearFormats
   Range("A1:I2").Select
    With Selection
        .HorizontalAlignment = xlCenter
        .VerticalAlignment = xlBottom
        .WrapText = False
        .Orientation = 0
        .AddIndent = False
        .IndentLevel = 0
        .ShrinkToFit = False
        .ReadingOrder = xlContext
        .MergeCells = False
    End With
    Selection.Merge
    With Selection
        .HorizontalAlignment = xlCenter
        .VerticalAlignment = xlCenter
        .WrapText = False
        .Orientation = 0
        .AddIndent = False
        .IndentLevel = 0
        .ShrinkToFit = False
        .ReadingOrder = xlContext
        .MergeCells = True
    End With
    With Selection.Interior
        .Pattern = xlSolid
        .PatternColorIndex = xlAutomatic
        .ThemeColor = xlThemeColorDark2
        .TintAndShade = -0.499984740745262
        .PatternTintAndShade = 0
    End With
    With Selection.Font
        .ThemeColor = xlThemeColorDark1
        .TintAndShade = 0
    End With
    Selection.Font.Bold = True
    Range("A1:I2").Select
    ActiveCell.FormulaR1C1 = _
        "Number of Days between ANSI's Aproved But not Catalogued"
    Range("A3:I3").Select
    With Selection
        .HorizontalAlignment = xlCenter
        .VerticalAlignment = xlBottom
        .WrapText = False
        .Orientation = 0
        .AddIndent = False
        .IndentLevel = 0
        .ShrinkToFit = False
        .ReadingOrder = xlContext
        .MergeCells = False
    End With
    Selection.Merge
    With Selection
        .HorizontalAlignment = xlCenter
        .VerticalAlignment = xlCenter
        .WrapText = False
        .Orientation = 0
        .AddIndent = False
        .IndentLevel = 0
        .ShrinkToFit = False
        .ReadingOrder = xlContext
        .MergeCells = True
    End With
    With Selection.Interior
        .Pattern = xlSolid
        .PatternColorIndex = xlAutomatic
        .ThemeColor = xlThemeColorDark2
        .TintAndShade = -0.249977111117893
        .PatternTintAndShade = 0
    End With
    Range("A3:I3").Select
    ActiveCell.FormulaR1C1 = "MASRI"
    Range("A4").Select
    ActiveCell.FormulaR1C1 = "Progress"
    Selection.Font.Bold = True
    Range("B4").Select
    ActiveCell.FormulaR1C1 = "ANSI#"
    Selection.Font.Bold = True
     Range("C4").Select
    ActiveCell.FormulaR1C1 = "Area"
    Selection.Font.Bold = True
     Range("D4").Select
    ActiveCell.FormulaR1C1 = "Supplier"
    Selection.Font.Bold = True
     Range("E4").Select
    ActiveCell.FormulaR1C1 = "Description"
    Selection.Font.Bold = True
     Range("F4").Select
    ActiveCell.FormulaR1C1 = "Approved Date"
    Selection.Font.Bold = True
     Range("G4").Select
    ActiveCell.FormulaR1C1 = "Catalogued Date"
    Selection.Font.Bold = True
     Range("H4").Select
    ActiveCell.FormulaR1C1 = "Approved By"
    Selection.Font.Bold = True
     Range("I4").Select
    ActiveCell.FormulaR1C1 = "Days Overdue"
    Selection.Font.Bold = True
    Range("A4:I4").Select
    With Selection
        .HorizontalAlignment = xlCenter
        .VerticalAlignment = xlBottom
        .WrapText = False
        .Orientation = 0
        .AddIndent = False
        .IndentLevel = 0
        .ShrinkToFit = False
        .ReadingOrder = xlContext
        .MergeCells = False
    End With
    Range("A4:I4").Select
    With Selection.Interior
        .Pattern = xlSolid
        .PatternColorIndex = xlAutomatic
        .ThemeColor = xlThemeColorLight2
        .TintAndShade = 0.599993896298105
        .PatternTintAndShade = 0
    End With
    Range("A1:I4").Select
    Selection.Borders(xlDiagonalDown).LineStyle = xlNone
    Selection.Borders(xlDiagonalUp).LineStyle = xlNone
    With Selection.Borders(xlEdgeLeft)
        .LineStyle = xlContinuous
        .ColorIndex = 0
        .TintAndShade = 0
        .Weight = xlThin
    End With
    With Selection.Borders(xlEdgeTop)
        .LineStyle = xlContinuous
        .ColorIndex = 0
        .TintAndShade = 0
        .Weight = xlThin
    End With
    With Selection.Borders(xlEdgeBottom)
        .LineStyle = xlContinuous
        .ColorIndex = 0
        .TintAndShade = 0
        .Weight = xlThin
    End With
    With Selection.Borders(xlEdgeRight)
        .LineStyle = xlContinuous
        .ColorIndex = 0
        .TintAndShade = 0
        .Weight = xlThin
    End With
    With Selection.Borders(xlInsideVertical)
        .LineStyle = xlContinuous
        .ColorIndex = 0
        .TintAndShade = 0
        .Weight = xlThin
    End With
    With Selection.Borders(xlInsideHorizontal)
        .LineStyle = xlContinuous
        .ColorIndex = 0
        .TintAndShade = 0
        .Weight = xlThin
    End With
    Range("G5:G40").NumberFormat = "dd/mm/yyyy"
    Columns("A:A").ColumnWidth = 18.43
    Columns("B:B").ColumnWidth = 12
    Columns("C:C").ColumnWidth = 4.43
    Columns("D:D").ColumnWidth = 34.86
    Columns("E:E").ColumnWidth = 60.71
    Columns("F:F").ColumnWidth = 15.14
    Columns("G:G").ColumnWidth = 15.14
    Columns("H:H").ColumnWidth = 20.57
    Columns("I:I").ColumnWidth = 37.86
    ActiveSheet.Shapes.Range(Array("Rounded Rectangle 1")).Select
    Range("A1:I2").Select
    ActiveSheet.Shapes.Range(Array("Rounded Rectangle 1")).Select
    Selection.ShapeRange.IncrementLeft -2.25
    Selection.ShapeRange.IncrementTop 0.75
    Selection.ShapeRange.IncrementLeft 2.25
    Selection.ShapeRange.IncrementTop -0.75
    Sheets("Masri").Select
    Dim FinalRow As Long, lastTargetRow As Long, lastCol As Long, tRow As Long
    Dim source As String, target As String
    Dim ThisValue As Date
     source = "Masri"        'Define your source sheet
     target = "Reports"      'Define Target sheet
     FinalRow = Sheets(source).Range("G" & Rows.Count).End(xlUp).Row
     lastCol = Sheets(source).Cells(1, Columns.Count).End(xlToLeft).Column   'If header in Row 1
     lastTargetRow = Sheets(target).Range("G" & Rows.Count).End(xlUp).Row
     tRow = lastTargetRow + 1
    For lRow = 2 To FinalRow
     ThisValue = Sheets(source).Cells(lRow, 7).Value
        If ThisValue = tempDate Then
         For lCol = 1 To lastCol  'Copy entire row
                Sheets(target).Cells(tRow, lCol).Value = Sheets(source).Cells(lRow, lCol).Value
            Next lCol
            tRow = tRow + 1         'THIS IS THE KEY TO NOT JUST COPYING THE LAST RECORD
        End If
    Next lRow
    End If
End Sub

回答by peege

It looks like your problem is that you are copying the last record over top of the previous one. If you step through your code, you can confirm that theory or not.

看起来您的问题是您将最后一条记录复制到前一条记录之上。如果您单步执行代码,则可以确认该理论与否。

Of course, you probably have more code above what was included in your question, judging by the lingering "End If" before the "End Sub". I'm just going to treat this as a stand alone, for the sake of Declaring the Variables, so you know what type they are.

当然,根据“End Sub”之前挥之不去的“End If”判断,您可能在问题中包含的代码之上有更多代码。为了声明变量,我只是将其视为一个独立的部分,以便您知道它们是什么类型。

Look at this code, which simplifies things by setting the values, instead of copying and pasting.

看看这段代码,它通过设置值来简化事情,而不是复制和粘贴。

It loops through the source sheet, the same way your code does, using a For Loop.
Then performs a conditional test. If the match is found, a nested Loop through all the columns setting the values on the target sheet from the values on the source sheet is done.

它使用 For 循环循环遍历源表,就像您的代码所做的那样。
然后执行条件测试。如果找到匹配项,则通过所有列的嵌套循环从源工作表上的值设置目标工作表上的值。

note: the last row is being checked by column "C", (3) because your code was showing that.

注意:最后一行正在由列“C”(3)检查,因为您的代码显示了这一点。

Sub ConditionalCopy()

Dim FinalRow As Long, lastTargetRow As Long, lastCol As Long, tRow As Long
Dim source As String, target As String
Dim ThisValue As Date

source = "Masri"        'Define your source sheet
target = "Reports"      'Define Target sheet

FinalRow = Sheets(source).Range("C" & Rows.count).End(xlUp).row
lastCol = Sheets(source).Cells(1, Columns.count).End(xlToLeft).column   'If header in Row 1

lastTargetRow = Sheets(target).Range("C" & Rows.count).End(xlUp).row
tRow = lastTargetRow + 1

    For lRow = 2 To FinalRow

        ThisValue = Sheets(source).Cells(lRow, 7).Value

        If ThisValue = Date() Then
            For lCol = 1 To lastCol  'Copy entire row
                Sheets(target).Cells(tRow, lCol).Value = Sheets(source).Cells(lRow, lCol).Value
            Next lCol
            tRow = tRow + 1         'THIS IS THE KEY TO NOT JUST COPYING THE LAST RECORD
        End If
    Next lRow
End Sub

UPDATE: After seeing the rest of the code, I'd strongly recommend reducing any select statements.

更新:在看到其余的代码后,我强烈建议减少任何选择语句。

Here is an example:

下面是一个例子:

Range("F4").Select
ActiveCell.FormulaR1C1 = "Approved Date"

This is not required, and is extra work, because you don't need to select the Range to set its formula or any other property. The reason they are there is probably because of a macro being recorded, which is a good place to start. It is simulating you USING the worksheet, instead of just performing the required operations, with a small sheet, you might not notice the difference, other than the screen flicking all over, but in a large sheet, it would definitely cause problems. It's also just not a good practice.

这不是必需的,并且是额外的工作,因为您不需要选择范围来设置其公式或任何其他属性。它们在那里的原因可能是因为正在录制一个宏,这是一个很好的起点。它是在模拟你使用工作表,而不是仅仅执行所需的操作,在一张小工作表上,你可能不会注意到区别,除了屏幕到处闪烁,但在一张大工作表中,它肯定会引起问题。这也不是一个好习惯。

Consider this:

考虑一下:

Range("F4").FormulaR1C1 = "Approved Date"

Another example:

另一个例子:

Range("A1:I2").Select
With Selection
    .HorizontalAlignment = xlCenter
    .VerticalAlignment = xlBottom
    .WrapText = False
    .Orientation = 0
    .AddIndent = False
    .IndentLevel = 0
    .ShrinkToFit = False
    .ReadingOrder = xlContext
    .MergeCells = False
End With

Would be revised as this:

将修改为:

With Range("A1:I2")
    .HorizontalAlignment = xlCenter
    .VerticalAlignment = xlBottom
    .WrapText = False
    .Orientation = 0
    .AddIndent = False
    .IndentLevel = 0
    .ShrinkToFit = False
    .ReadingOrder = xlContext
    .MergeCells = False
End With

This link How to avoid using Select in Excel Macrosprovides MORE examples. You can access any property like Selection.Interior, just use the actual selection NAME instead of "Selection". To merge a range, you just say

此链接如何避免在 Excel 宏中使用 Select提供了更多示例。您可以访问任何属性,如 Selection.Interior,只需使用实际选择名称而不是“选择”。要合并范围,您只需说

Range("A1:I2").Merge
'or
Range("A1:I2").Unmerge