[color=blue]Option[/color] [color=blue]Explicit[/color]
[color=blue]Sub[/color] ArmyGeezerUniqueSheet()
Application.ScreenUpdating = [color=blue]False[/color] [color=lightgreen]'Not necerssary but speeds things up a bit, by turning screen updating off. Usually best to 'Comment it out initially to see a bit better wot is going on.[/color]
[color=blue]Dim[/color] wksMasta [color=blue]As[/color] Worksheet: [color=blue]Set[/color] wksMasta = ThisWorkbook.Worksheets("Master Sheet") [color=lightgreen]'Give abbreviations the Methods, properties, sub-Objects through dot of Worksheets Object[/color]
[color=blue]On[/color] [color=blue]Error[/color] [color=blue]GoTo[/color] TheEnd [color=lightgreen]'If anything goes wrong go to the End instead of crashing.[/color]
[color=lightgreen]'1) Start Bit option to Delete Sheets / Tabs------------[/color]
[color=blue]Dim[/color] ws [color=blue]As[/color] Worksheet [color=lightgreen]'ws now has Methods and Properties of Worksheets obtained with typing . dot after it![/color]
Application.DisplayAlerts = [color=blue]False[/color] [color=lightgreen]'Prevents being asked everytime if you really want to delete the Workbook[/color]
[color=blue]For[/color] [color=blue]Each[/color] ws [color=blue]In[/color] ActiveWorkbook.Worksheets
[color=blue]If[/color] ws.Name <> "Master Sheet" And ws.Name <> "Masta sheet" And ws.Name <> "AnySheetYouWantToKeep" [color=blue]Then[/color]
ws.Delete
[color=blue]Else[/color] [color=lightgreen]'Presumably then the worksheet name is any one you want to keep so...[/color]
[color=lightgreen]'....do nothing (Don't delete it!)[/color]
[color=blue]End[/color] [color=blue]If[/color]
[color=blue]Next[/color]
Application.DisplayAlerts = [color=blue]True[/color] [color=lightgreen]'Turn it back on[/color]
[color=lightgreen]'End Bit to delete new Sheets / Tabs------------[/color]
[color=lightgreen]'2) Bit to make new (Temporary) column for Picked out bits from long string in Column D[/color]
wksMasta.Columns("E:E").Insert Shift:=xlToRight [color=lightgreen]'This inserts a new Column after Column D[/color]
[color=blue]Dim[/color] lrMasta [color=blue]As[/color] [color=blue]Long[/color] [color=lightgreen]'last Roww in Masta Sheet. Long is a Big whole Number limit (-2,147,483,648 to 2,147,483,647). Smaller numbers such as Byte, Integer etc. are typically converted to long in the computer so there are no Memory advantages of Dimensioning smaller.. http://www.mrexcel.com/forum/excel-questions/803662-byte-backward-loop-4.html[/color]
[color=blue]Let[/color] lrMasta = wksMasta.Cells.Find(What:="*", after:=wksMasta.Cells(1, 1), Lookat:=xlPart, LookIn:=xlFormulas, SearchOrder:=xlByRows, SearchDirection:=xlPrevious).Row [color=lightgreen]'Get last Row with entry anywhere for Sheet1. Method: You start at first cell then go backwards (which effectively starts at end of sheet), sercching for anything ( = * ) by rows, then get the row number. This allows for different excel versions with different available Row numbers) Just a different method here for fun- finds last row in sheet rather than row for last entry in particular cell[/color]
[color=blue]Let[/color] lrMasta = wksMasta.Cells(Rows.Count, 4).End(xlUp).Row [color=lightgreen]'Better alternative for single column work. - Starting at last Spreadsheet Row in column 4 (D), quasi "go back up" / return the last cell with entry in it as a Range object using .End Property and obtain rows from the .Rows Property of that returned Range Object[/color]
[color=blue]Dim[/color] rngD [color=blue]As[/color] Range: [color=blue]Set[/color] rngD = wksMasta.Range("D3:D" & lrMasta & "") [color=lightgreen]'Data Column range .. Give abbreviations >>>[/color]
[color=blue]Let[/color] rngD.Offset(0, 1).Value = UDArmyGeezerPickOutBit(rngD, "OU=Groups,OU=", ",") [color=lightgreen]'Our UDF is set to work with our Range in Column D. The Offset Property bit is just a neat - here it returns a range that is one place to the right. That saves us having to Dimension and set a rngE to use in an alternative code line RngE = UDArmyGeezerPickOutBit(rngD, "OU=Groups,OU=", ",")[/color]
[color=lightgreen]'End bit to make Temporary column[/color]
[color=lightgreen]'3)Add new Worksheets----------------------------------[/color]
[color=lightgreen]'3a)First make 1 tempory sheet For Unique Sheet Names.[/color]
[color=blue]Let[/color] Worksheets.Add(after:=Worksheets(1)).Name = "Unique1" [color=lightgreen]'Add a Worksheet (after the First ever added or there), named Unique1 for now[/color]
[color=blue]Let[/color] wksMasta.Range("E1").Value = "Temp Heading" [color=lightgreen]'An annoying characteristic of advanced Filter is that it Requires a Heading (which it always copies with the other filtered cells)[/color]
wksMasta.Range("E1:E" & lrMasta & "").AdvancedFilter Action:=xlFilterCopy, CopyToRange:=Worksheets("Unique1").Range("A1"), Unique:=[color=blue]True[/color] [color=lightgreen]'Copies entire E Column to first column in sheet2 (Tempory made "Unique1" sheet), The important bit is Unique:=True - that only copies unique bits[/color]
[color=lightgreen]'---------------------[/color]
[color=blue]Dim[/color] LastUnqRow [color=blue]As[/color] [color=blue]Long[/color], UqeRow [color=blue]As[/color] [color=blue]Long[/color] [color=lightgreen]'Rows in Tempory Unique sheet. As before unless if you need sort of validation (i.e. the value should only be within the range of a Byte/Integer) there's no point using anything but Long.-- 'saving' memory and using the smallest bit. But upon/after 32-bit, by all I have read, Integers (Short) need converted internally anyways, so a Long is actually faster. http://www.mrexcel.com/forum/excel-questions/803662-byte-backward-loop-4.html[/color]
[color=blue]Let[/color] LastUnqRow = Worksheets("Unique1").Cells.Find(What:="*", after:=Worksheets("Unique1").Cells(1, 1), Lookat:=xlPart, LookIn:=xlFormulas, SearchOrder:=xlByRows, SearchDirection:=xlPrevious).Row [color=lightgreen]'Get last Unique Row for use in next loop. method: You starta at first cell then go backwards (which effectively starts at end of sheet. This allows for different excel versions with different available Row numbers)[/color]
[color=lightgreen]'3b)go through making new sheets and copying filtered data to them[/color]
[color=blue]Dim[/color] TempShtName [color=blue]As[/color] [color=blue]String[/color] [color=lightgreen]'Temporary Sheet Name for newly made sheet, not kept constant, used / updated in looping[/color]
[color=blue]For[/color] UqeRow = 2 [color=blue]To[/color] LastUnqRow [color=blue]Step[/color] 1 [color=lightgreen]'[/color]
'Make new sheets-----------------------
[color=blue]If[/color] Sheets("Unique1").Cells(UqeRow, 1).Text <> "" [color=blue]Then[/color] [color=lightgreen]'Assuming a Record is there[/color]
[color=blue]Let[/color] TempShtName = Sheets("Unique1").Cells(UqeRow, 1).Text [color=lightgreen]'Put name in Record variable[/color]
[color=blue]Let[/color] Worksheets.Add(after:=Worksheets(1)).Name = TempShtName [color=lightgreen]'Add new worksheet with name TempShtName[/color]
[color=blue]With[/color] wksMasta [color=lightgreen]'Copying data to new sheet----[/color]
.UsedRange.AutoFilter Field:=5, Criteria1:=TempShtName [color=lightgreen]'Filter out everything except with that with the appropriate Record (makes visible based on the criteria (Column 5 (E)) only the stuff you want??)....[/color]
.UsedRange.SpecialCells(xlCellTypeVisible).Copy [color=lightgreen]'Destination:=Worksheets(TempShtName).Range("A1") ', then combine it with SpecialCells to just copy that wot you see, (and then send it to the relavent new sheet , name n).. ( Idid notice that it works the same without the .SpecialCells(xlCellTypeVisible) bit, - but that mayjust be Excel “guessing wot you want” as it does, that is to say it copies by default wot is visible?- not too sure on that one yet.)[/color]
Worksheets(TempShtName).Range("A1").PasteSpecial Paste:=xlPasteFormulas [color=lightgreen]'This is necerssary to "ensure" formulas are copied. Comment out Destination:= above if you out use this http://www.mrexcel.com/forum/excel-questions/828241-visual-basic-applications-autofilter-specialcells-xlcelltypevisible-copy-only-values-not-formulas.html[/color]
[color=lightgreen]'Worksheets(TempShtName).Range("A1").PasteSpecial Paste:=xlPasteAllUsingSourceTheme 'This is necerssary to "ensure" "everything" is copied. Comment out Destination:= above if you use this For example http://www.excelforum.com/excel-new-users-basics/1063110-sheet-range-object-item-list-reorder.html[/color]
[color=blue]End[/color] [color=blue]With[/color] [color=lightgreen]'----------------------------------[/color]
Application.DisplayAlerts = [color=blue]True[/color] [color=lightgreen]'This is normally just done once at the end, but is useful for debugging purposes to do here. It makes all of Master sheet re visible[/color]
[color=blue]With[/color] Sheets(TempShtName).UsedRange [color=lightgreen]'Bit of simple Format Tidying up[/color]
.WrapText = [color=blue]False[/color]
.Columns.AutoFit
[color=blue]End[/color] [color=blue]With[/color]
[color=blue]Else[/color]
[color=lightgreen]'Do nothing if no Record given[/color]
[color=blue]End[/color] [color=blue]If[/color]
[color=lightgreen]'-----------------------------[/color]
[color=blue]Next[/color] UqeRow [color=lightgreen]'Go back and make another new sheet[/color]
[color=lightgreen]'------------------------------------------------------------[/color]
wksMasta.AutoFilterMode = [color=blue]False[/color] [color=lightgreen]'Make everything visible in the First Master Sheet[/color]
Application.DisplayAlerts = [color=blue]False[/color] [color=lightgreen]'Prevent being asked if you really want to delete Temporary Unique sheet[/color]
Worksheets("Unique1").Delete [color=lightgreen]' delete the Temporary the filtered name sheet as you do not need it any more[/color]
wksMasta.Columns("E:E").Delete [color=lightgreen]'Delete Tempory Column E (If you wont too!! - might want to comment this out if you want to keep it?)[/color]
Application.DisplayAlerts = [color=blue]True[/color]
Application.ScreenUpdating = [color=blue]True[/color] [color=lightgreen]'Turn screen "back on" or screen is "dead"[/color]
[color=blue]Exit[/color] [color=blue]Sub[/color] [color=lightgreen]'We stop code here assuming it worked (or at least did not crash!)[/color]
TheEnd:
Application.ScreenUpdating = [color=blue]True[/color] [color=lightgreen]'Important to do this here so if anything goes wrong then the screen updating is turned back on, ohterwisee the screen is dead[/color]
MsgBox (Err.Description) [color=lightgreen]'Print out error message in Message Box[/color]
[color=blue]End[/color] [color=blue]Sub[/color] [color=lightgreen]'ArmyGeezerUniqueSheet[/color]
[color=lightgreen]'[/color]
'
[color=blue]Public[/color] [color=blue]Function[/color] UDArmyGeezerPickOutBit(LongStrings [color=blue]As[/color] Range, StartString [color=blue]As[/color] String, StopString [color=blue]As[/color] String)
[color=blue]Dim[/color] vOut() [color=blue]As[/color] [color=blue]Variant[/color] [color=lightgreen]' Array but individual elements Has to be variant as it sees the Functions below[/color]
[color=blue]Dim[/color] x [color=blue]As[/color] [color=blue]Long[/color], y [color=blue]As[/color] Long
[color=blue]Dim[/color] TempString [color=blue]As[/color] String [color=lightgreen]'Tempory Strings used along the way[/color]
[color=blue]ReDim[/color] vOut(1 [color=blue]To[/color] LongStrings.Rows.Count, 1 [color=blue]To[/color] LongStrings.Columns.Count)
[color=blue]For[/color] x = 1 [color=blue]To[/color] LongStrings.Rows.Count
[color=blue]For[/color] y = 1 [color=blue]To[/color] LongStrings.Columns.Count
[color=blue]Let[/color] TempString = Replace(Replace(LongStrings(x, y).Value, StartString, "|", 1), StopString, "|", InStr(1, Replace(LongStrings(x, y).Value, StartString, "|", 1), "|") + 1)
vOut(x, y) = Mid(TempString, 1, InStr(1, TempString, "|") - 1)
[color=blue]Next[/color] y
[color=blue]Next[/color] x
UDArmyGeezerPickOutBit = vOut
[color=blue]End[/color] [color=blue]Function[/color] [color=lightgreen]'UDArmyGeezerPickOutBit[/color]