2016-09-19 69 views
0

试图在列B中查找唯一名称,并将具有所述名称的任何行复制到新工作表。VBA唯一字词排序

即Alex本周计时两次,他将用数据填充两行,我想将他的两行数据移动到他们自己的工作表中。弗雷德只钟点一次并创建1行数据,我想将他的行移动到新的工作表中。

问题,那就是复制第2行到新的工作表

链接到我的文件的多个:https://docs.google.com/spreadsheets/d/1JZla8ySwEotn91m8trh2_2fNLBNak-of98HQJ0YCP_0/edit?usp=sharing

代码我使用至今:

Sub Copy_To_Worksheets() 
'Note: This macro use the function LastRow 
Dim My_Range As Range 
Dim FieldNum As Long 
Dim CalcMode As Long 
Dim ViewMode As Long 
Dim ws2 As Worksheet 
Dim Lrow As Long 
Dim cell As Range 
Dim CCount As Long 
Dim WSNew As Worksheet 
Dim ErrNum As Long 

'Set filter range on ActiveSheet: A1 is the top left cell of your filter range 
'and the header of the first column, D is the last column in the filter range. 
'You can also add the sheet name to the code like this : 
'Worksheets("Sheet1").Range("A1:D" & LastRow(Worksheets("Sheet1"))) 
'No need that the sheet is active then when you run the macro when you use this. 
Set My_Range = Range("A2:E" & LastRow(ActiveSheet)) 
My_Range.Parent.Select 

If ActiveWorkbook.ProtectStructure = True Or _ 
    My_Range.Parent.ProtectContents = True Then 
    MsgBox "Sorry, not working when the workbook or worksheet is protected", _ 
      vbOKOnly, "Copy to new worksheet" 
    Exit Sub 
End If 

'This example filters on the first column in the range(change the field if needed) 
'In this case the range starts in A so Field:=1 is column A, 2 = column B, ...... 
FieldNum = 2 

'Turn off AutoFilter 
My_Range.Parent.AutoFilterMode = False 

'Change ScreenUpdating, Calculation, EnableEvents, .... 
With Application 
    CalcMode = .Calculation 
    .Calculation = xlCalculationManual 
    .ScreenUpdating = False 
    .EnableEvents = False 
End With 
ViewMode = ActiveWindow.View 
ActiveWindow.View = xlNormalView 
ActiveSheet.DisplayPageBreaks = False 

'Add a worksheet to copy the a unique list and add the CriteriaRange 
Set ws2 = Worksheets.Add 

With ws2 
    'first we copy the Unique data from the filter field to ws2 
    My_Range.Columns(FieldNum).AdvancedFilter _ 
      Action:=xlFilterCopy, _ 
      CopyToRange:=.Range("A1"), Unique:=True 

    'loop through the unique list in ws2 and filter/copy to a new sheet 
    Lrow = .Cells(.Rows.Count, "A").End(xlUp).Row 
    For Each cell In .Range("A1:A" & Lrow) 

     'Filter the range 
     My_Range.AutoFilter Field:=FieldNum, Criteria1:="=" & _ 
     Replace(Replace(Replace(cell.Value, "~", "~~"), "*", "~*"), "?", "~?") 

     'Check if there are no more then 8192 areas(limit of areas) 
     CCount = 0 
     On Error Resume Next 
     CCount = My_Range.Columns(1).SpecialCells(xlCellTypeVisible) _ 
       .Areas(1).Cells.Count 
     On Error GoTo 0 
     If CCount = 0 Then 
      MsgBox "There are more than 8192 areas for the value : " & cell.Value _ 
       & vbNewLine & "It is not possible to copy the visible data." _ 
       & vbNewLine & "Tip: Sort your data before you use this macro.", _ 
        vbOKOnly, "Split in worksheets" 
     Else 
      'Add a new worksheet 
      Set WSNew = Worksheets.Add(After:=Sheets(Sheets.Count)) 
      On Error Resume Next 
      WSNew.Name = cell.Value 
      If Err.Number > 0 Then 
       ErrNum = ErrNum + 1 
       WSNew.Name = "Error_" & Format(ErrNum, "0000") 
       Err.Clear 
      End If 
      On Error GoTo 0 

      'Copy the visible data to the new worksheet 
      My_Range.SpecialCells(xlCellTypeVisible).Copy 
      With WSNew.Range("A1") 
       ' Paste:=8 will copy the columnwidth in Excel 2000 and higher 
       ' Remove this line if you use Excel 97 
       .PasteSpecial Paste:=8 
       .PasteSpecial xlPasteValues 
       .PasteSpecial xlPasteFormats 
       Application.CutCopyMode = False 
       .Select 
      End With 
     End If 

     'Show all data in the range 
     My_Range.AutoFilter Field:=FieldNum 

    Next cell 

    'Delete the ws2 sheet 
    On Error Resume Next 
    Application.DisplayAlerts = False 
    .Delete 
    Application.DisplayAlerts = True 
    On Error GoTo 0 

End With 

'Turn off AutoFilter 
My_Range.Parent.AutoFilterMode = False 

If ErrNum > 0 Then 
    MsgBox "Rename every WorkSheet name that start with ""Error_"" manually" _ 
     & vbNewLine & "There are characters in the name that are not allowed" _ 
     & vbNewLine & "in a sheet name or the worksheet already exist." 
End If 

'Restore ScreenUpdating, Calculation, EnableEvents, .... 
My_Range.Parent.Select 
ActiveWindow.View = ViewMode 
With Application 
    .ScreenUpdating = True 
    .EnableEvents = True 
    .Calculation = CalcMode 
End With 

End Sub 


Function LastRow(sh As Worksheet) 
On Error Resume Next 
LastRow = sh.Cells.Find(What:="*", _ 
         After:=sh.Range("A1"), _ 
         Lookat:=xlPart, _ 
         LookIn:=xlValues, _ 
         SearchOrder:=xlByRows, _ 
         SearchDirection:=xlPrevious, _ 
         MatchCase:=False).Row 
On Error GoTo 0 

End Function 
+4

这个职位似乎是你之前交的副本[VBA搜索栏独特的价值,将含有发现价值到新的工作表中的所有行(http://stackoverflow.com/questions/39578305/vba -Search换唯一值-在列 - 移动 - 所有含发现的值对n行-)。请避免多次发布相同的问题或解释此帖子如何偏离之前的帖子。 – Ralph

回答

0

我可能会做这样,但这需要更多的错误检查。

Option Explicit 


Sub MovePeeps() 

Dim emp As New Collection 
Dim ws, tmpWs, tw As Worksheet 
Dim wb As Workbook 
Dim empExist As Boolean 
Dim i, j, k, m As Integer 

Set wb = ThisWorkbook 
Set ws = wb.ActiveSheet 
empExist = False 

'get unique employee names into the emp collection 
'cycle through the used range - i= column of names 
For i = 2 To ws.UsedRange.Rows.Count 
    'cycle through all peopel in the emp collection 
    For j = 1 To emp.Count 
     'check if person in cell = person in emp collection 
     If ws.Cells(i, 2) = emp(j) Then 
      empExist = True 
      Exit For 
     End If 
    Next j 
    'if person is in emp collection already reset empExist and exit loop without adding again 
    If empExist = True Then 
     empExist = False 
     Exit For 
    End If 
    'otherwise add that person to the collection 
    emp.Add ws.Cells(i, 2) 
Next i 
'create a worksheet named after each item in the emp collection 
For i = 1 To emp.Count 
    wb.Worksheets.Add After:=wb.Worksheets(wb.Worksheets.Count) 
    Set tmpWs = wb.Worksheets(wb.Worksheets.Count) 
    tmpWs.Name = emp(i) 
    'add header row to each sheet 
    ws.Cells(1, 2).EntireRow.Copy Destination:=tmpWs.Cells(1, 1) 
Next i 
'copy all data to the new sheets 
m = 1 
For j = 1 To emp.Count 
    For Each tw In wb.Worksheets 
     'if the worksheet (tw) is the same name as the person in emp(j) then set the tmpWS variable 
     If tw.Name = emp(j) Then 
      Set tmpWs = tw 
      Exit For 
     End If 
    Next tw 
    For i = 2 To ws.UsedRange.Rows.Count 
     If ws.Cells(i, 2) = emp(j) Then 
      'find blank row on the sheet we are copying to 
      Do While tmpWs.Cells(m, 2) <> "" 
       m = m + 1 
      Loop 
      'copy the row to the tmpWS 
      ws.Cells(i, 2).EntireRow.Copy Destination:=tmpWs.Cells(m, 1) 
     End If 
    Next i 
    'reset our blank row counter. 
    m = 1 
Next j 

End Sub