从 sheet 1 复制范围并粘贴到循环中下一个 sheet 的下一个空行

Copy a range from sheet 1 and paste to next empty row on next sheets in loop

我正在尝试在名为“模板”的 sheet 上复制一个范围,转到下一个 sheet,找到下一个可用行并粘贴复制的范围。然后向上 7 行,select 向下 7 行以隐藏这些行,因此只有我粘贴的新 7 行可见。但我需要排除 sheet 称为“模板”和一个称为“时间卡” 谢谢你的帮助。所有部分都工作正常,但它不会进入下一个工作sheet,它停留在“模板”上(sheet 我正在从中复制范围)。这是我目前所拥有的:

Sub TimeCardReset()
Dim sh As Worksheet

Sheets("Template").Activate
Range("A3:G9").Select
Selection.Copy
            
For Each sh In ThisWorkbook.Worksheets
        If sh.Name = "TEMPLATE" Then
        ' do nothing
        ElseIf sh.Name = "TimeCard" Then
        ' do nothing
        Else
           Range("A" & Rows.Count).End(xlUp).Select
           ActiveCell.Offset(1, 0).Select
           ActiveSheet.Paste
           ActiveCell.Offset(-7, 0).Select
           '   Select current row through 6 rows and hide those rows
           ActiveCell.Resize(7, 1).EntireRow.Hidden = True
        End If
Next sh
Application.CutCopyMode = False
End Sub

这是一个示例(未经测试),其中考虑了上述评论中提到的一些项目。 (随着对您的特定文件和用例的更多了解,它可以进一步完善)。

Sub TimeCardReset()
    Dim sh As Worksheet
    Dim sSourceSheet$, sSourceRange$
    Const cTEMPLATE = "TEMPLATE" as string
    Const cTIMECARD = "TimeCard" as string

    sSourceSheet = "Template"
    sSourceRange = "A3:G9"

    Sheets(sSourceSheet).Range(sSourceRange).Copy
            
    For Each sh In ThisWorkbook.Worksheets
        If (not(sh.Name = cTEMPLATE) and not(sh.Name = cTIMECARD)) Then
           Sheets(sh).Range("A" & Rows.Count).End(xlUp).Select
           ActiveCell.Offset(1, 0)..Paste
           ActiveCell.Offset(-7, 0)..Resize(7, 1).EntireRow.Hidden = True
        End If
    Next sh
    Application.CutCopyMode = False
End Sub

我不确定你的工作簿中到底是什么在推动 Sheets(sh).Range("A" & Rows.Count).End(xlUp).Select 行后面的决策,所以把它留给 'select' 然后 'active cell'

您会看到,对于 future-proofing,我还将一些输入项移到了变量或常量上,您可以对偏移量和调整大小值 (6, 7, 1, 0, -1) 和目的地的第一列 (A) sheet。 (这些步骤是可选的)。

调整大小位是否对您要实现的目标至关重要,或者它只是构成录制宏的一部分的 non-critical 操作?

注意:如果您可以在没有 Select 和 ActiveCell 的情况下执行操作,此功能将 运行 快得多,其中 sheet 全部由代码更改而无需物理导航到一路上的他们。如果有很多 sheet,这可能是相关的。

另外:考虑包括所有相关的 sheet,而不是排除两个你知道不相关的。这样,稍后为其他目的添加新的 sheet 不太可能破坏代码。

将范围复制到多个工作表

  • 第一个 Sub 将只复制值,但使用数组来提高效率。
  • 2nd Sub 将 copy 'whole thing',包括值、公式、格式...
  • 还有第三种可能性,使用 PasteSpecial, when there are more possibilities 要复制的内容。

代码

Option Explicit

' If only values are to be copied:
Sub TimeCardReset()
    
    ' Constants (adjust if necessary)
    Const wsName As String = "Template"
    Const CopyRangeAddress As String = "A3:G9"
    Const LastRowColumn As Variant = "A" ' e.g. 1 or "A"
    Dim Exceptions As Variant
    Exceptions = Array("Template", "TimeCard") ' Add more...
    Dim wb As Workbook: Set wb = ThisWorkbook
    
    ' Write values of Copy Range to array (Data).
    Dim Data As Variant
    Data = wb.Worksheets(wsName).Range(CopyRangeAddress).Value
    
    ' Calculate number of rows and columns in array (of Copy Range).
    Dim ubr As Long: ubr = UBound(Data)
    Dim ubc As Long: ubc = UBound(Data, 2)
    
    Dim ws As Worksheet, cel As Range, PasteRange As Range
    ' Loop through all worksheets in workbook.
    For Each ws In ThisWorkbook.Worksheets
        ' Check if name of current worksheet is not contained
        ' in Exceptions array.
        If IsError(Application.Match(ws.Name, Exceptions, 0)) Then
            ' Define first empty cell (cel) in LastRowColumn.
            Set cel = ws.Cells(ws.Rows.Count, LastRowColumn).End(xlUp).Offset(1)
            ' Define Paste Range.
            Set PasteRange = cel.Resize(ubr, ubc)
            ' Write values of array to Paste Range.
            PasteRange.Value = Data
            ' Check if hiding is possible.
            If PasteRange.Row > ubr Then
                ' Hide rows of previous Paste Range in current worksheet.
                PasteRange.Offset(-ubr).Rows.EntireRow.Hidden = True
            Else
                ' The following line would be very annoying if many sheets.
                'MsgBox "There isn't enough rows above.", vbExclamation, "Fail"
            End If
        End If
    Next ws

    ' Inform user
    MsgBox "Operation finished successfully.", vbInformation, "Success"

End Sub

' If values, formulas, formats... are to be copied:
Sub TimeCardResetAll()
    
    ' Constants (adjust if necessary)
    Const wsName As String = "Template"
    Const CopyRangeAddress As String = "A3:G9"
    Const LastRowColumn As Variant = "A" ' e.g. 1 or "A"
    Dim Exceptions As Variant
    Exceptions = Array("Template", "TimeCard") ' Add more...
    Dim wb As Workbook: Set wb = ThisWorkbook
    
    ' Define Copy Range.
    Dim CopyRange As Range
    Set CopyRange = wb.Worksheets(wsName).Range(CopyRangeAddress)
    
    ' Calculate number of rows and columns of Copy Range.
    Dim ubr As Long: ubr = CopyRange.Rows.Count
    Dim ubc As Long: ubc = CopyRange.Columns.Count
    
    Dim ws As Worksheet, PasteCell As Range
    ' Loop through all worksheets in workbook.
    For Each ws In ThisWorkbook.Worksheets
        ' Check if name of current worksheet is not contained
        ' in Exceptions array.
        If IsError(Application.Match(ws.Name, Exceptions, 0)) Then
            ' Define first empty cell (PasteCell) in LastRowColumn.
            Set PasteCell = _
              ws.Cells(ws.Rows.Count, LastRowColumn).End(xlUp).Offset(1)
            ' Copy from Copy Range to Paste Cell (formulas, formats... incl.).
            CopyRange.Copy PasteCell
            ' Check if hiding is possible.
            If PasteCell.Row > ubr Then
                ' Hide rows of previous Paste Range in current worksheet.
                PasteCell.Resize(ubr).Offset(-ubr).EntireRow.Hidden = True
            Else
                ' The following line would be very annoying if many sheets.
                'MsgBox "There isn't enough rows above.", vbExclamation, "Fail"
            End If
        'Else ' Current worksheet name is contained in Exceptions array.
        End If
    Next ws

    ' Inform user
    MsgBox "Operation finished successfully.", vbInformation, "Success"

End Sub

简化您的代码;使用 With 语句,去掉 SelectActivateActiveSheet。如果您只想将值复制到另一个工作表,则不需要使用数组或过多的变量来完成您的任务,您只需将目标范围设置为等于源范围即可,这样速度更快,因为它绕过了完全剪贴板。 lRow 变量用作两行代码的参考点。

Dim ws As Worksheet, lRow As Long

    For Each ws In ThisWorkbook.Sheets 'loop through all the worksheets
        If ws.Name <> "Template" And ws.Name <> "TimeCard" Then 'skip these worksheets
            
            With ws 'to avoid using Select, ActiveCell, and ActiveSheet

                lRow = .Cells(.Rows.Count, 1).End(xlUp).Row 'Set the last row for the current ws
              
                'Added - This line will copy both formulas and values
                ThisWorkbook.Sheets("Template").Range("A3:G9").Copy Destination:=.Cells(lRow, "A").Offset(1)
                
                'Deleted - use lRow, Offset, and Resize to set the range on destination sheet to match the range on the "Template" worksheet
                'Deleted - .Cells(lRow, "A").Offset(1).Resize(7, 7).Value = ThisWorkbook.Sheets("Template").Range("A3:G9").Value
                
                'Use lRow, Offset and Resize to to select the rows you want to hide
                .Cells(lRow, "A").Offset(-6).Resize(7).EntireRow.Hidden = True
            End With
        End If
    Next ws