Может быть, что-то подобное тоже будет работать.(Это может быть немного быстрее, чем циклически проходить по каждой строке.)
Если вы попробуете это и получите слишком много окон сообщений (из-за несуществующих листов), возможно, просто добавьте некоторую другую логику в Else
ветвь оператора If
.
Option Explicit
Private Sub CopyPasteToCorrespondingSheets()
With ThisWorkbook.Worksheets("XL Detail")
If .AutoFilterMode Then .Cells.AutoFilter ' Do this here before lastRow
Dim lastRow As Long
lastRow = .Cells(.Rows.Count, "C").End(xlUp).Row
Dim rangeContainingIdentifiers As Range
Set rangeContainingIdentifiers = .Range("C2:C" & lastRow)
End With
Dim uniqueIdentifers As Collection
Set uniqueIdentifers = UniqueValuesInRange(rangeContainingIdentifiers)
Dim uniqueSheetName As Variant
Dim sheetToPasteTo As Worksheet
' Not sure if there is a better way to include the row immediately above the first row of a particular range
With rangeContainingIdentifiers.Offset(-1, 0).Resize(1 + rangeContainingIdentifiers.Rows.Count, 1)
For Each uniqueSheetName In uniqueIdentifers
On Error Resume Next
Set sheetToPasteTo = ThisWorkbook.Worksheets(uniqueSheetName)
On Error GoTo 0
If Not (sheetToPasteTo Is Nothing) Then
lastRow = sheetToPasteTo.Cells(sheetToPasteTo.Rows.Count, "C").End(xlUp).Row
.AutoFilter Field:=1, Criteria1:=uniqueSheetName
rangeContainingIdentifiers.SpecialCells(xlCellTypeVisible).EntireRow.Copy
sheetToPasteTo.Cells(lastRow + 1, "C").EntireRow.PasteSpecial xlPasteValuesAndNumberFormats
Set sheetToPasteTo = Nothing
Else
MsgBox ("No sheet named '" & uniqueSheetName & "' was found. Code will continue running (for rest of unique identifiers).")
End If
Next uniqueSheetName
.AutoFilter
End With
Application.CutCopyMode = False
End Sub
Private Function UniqueValuesInRange(ByRef rangeToCheck As Range, Optional rowsToSkip As Long = 0) As Collection
Dim inputArray() As Variant
inputArray = rangeToCheck.Value2
Dim outputCollection As Collection ' Will not differentiate between "10" and 10
Set outputCollection = New Collection
Dim rowIndex As Long
Dim collectionKey As String
For rowIndex = (LBound(inputArray, 1) + rowsToSkip) To UBound(inputArray, 1)
collectionKey = CStr(inputArray(rowIndex, 1))
' Only look at first column.
On Error Resume Next
outputCollection.Add Item:=collectionKey, Key:=collectionKey
On Error GoTo 0
Next rowIndex
Set UniqueValuesInRange = outputCollection
End Function