Hi kschaefer,
. The code from Bailey_Thomas came very close. (That syntax error was obvious: just an extra line there in between. - As it was one code line separated with a _ there must not be any empty line between the two parts of the same code line.
.anyways here is my go. It seems to work. There are a lot of messy green comments on it, mainly for my benefit as I am learning as I go along answering these sort of Threads. But you can easily edit them off and edit other bits as you chose
.
Option Explicit 'Not necerssary but good practice to keep computer memery usage to minimum (and helps show up errors)
Sub PatientSortin()
Dim wks1 As Worksheet: Set wks1 = ThisWorkbook.Worksheets("Original"): wks1.AutoFilterMode = False
' 'Delete all sheets except Sheet1 option
' Dim wsTemp As Worksheet
' Application.DisplayAlerts = False
' For Each wsTemp In ActiveWorkbook.Worksheets
' If wsTemp.Name <> wks1.Name Then wsTemp.Delete
' Next
' Application.DisplayAlerts = True
'Make Array of unique Patient names----
Const TempVertClm = 11 'Temporary Column to use for unique array (will be deleted later)
Const VLkUpClm = 1 'Look Up Column for Unique values (Patient Numbers in this case are in First column)
Let wks1.Cells(1, TempVertClm).Value = "Patient NUMBER" 'Just for fun Put "patient NUMBER"
Dim sht1Rows As Long 'Rows in First Sheet
Dim lr As Long: Let lr = wks1.Cells.Find(What:="*", After:=wks1.Cells(1, 1), Lookat:=xlPart, LookIn:=xlFormulas, SearchOrder:=xlByRows, SearchDirection:=xlPrevious).Row ' You start at first cell then go backwards (which effectively starts at end of sheet. This allows for different excel versions with different available Row numbers)
For sht1Rows = 2 To lr 'Go througth all rows in sheet1
On Error Resume Next
If wks1.Cells(sht1Rows, VLkUpClm).Value <> "" And Application.WorksheetFunction.Match(wks1.Cells(sht1Rows, VLkUpClm), wks1.Columns(TempVertClm), 0) = 0 Then 'If grub Row is not empty and that value does not (yet) match any same value in entire Column of tempory vertical column
wks1.Cells(wks1.Rows.Count, TempVertClm).End(xlUp).Offset(1).Value = wks1.Cells(sht1Rows, VLkUpClm).Value 'Then put that value in the tempory Column at next free Row
End If
Next sht1Rows
Dim UniqueArr() As Variant 'Must be variant as it sees Object Application initially in next line
Let UniqueArr() = wks1.Range("A1").Range(wks1.Cells(1, TempVertClm), wks1.Cells(wks1.Cells(wks1.Rows.Count, TempVertClm).End(xlUp).Row, TempVertClm)).Value
Let UniqueArr() = Application.WorksheetFunction.Transpose(UniqueArr)
'Let UniqueArr = Application.WorksheetFunction.Transpose(wks1.Columns(TempVertClm).SpecialCells(xlCellTypeConstants)) 'This transposes the Array to give a list of columns. .SpecialCells(xlCellTypeConstants) is convenient way to get rid of the empty rows. I DO NOT UNDERSTAND IT YET
wks1.Columns(TempVertClm).Delete 'Delete is better than clear to avoid possble pronlems later >> http://www.mrexcel.com/forum/excel-questions/787428-clear-delete-shift-%3Dxlup-let-y-%3D-y-%96-1-usedrange-rows-count-anomale.html
'End of making Patient name list-------
Dim ArrClm As Long 'Row from Temp Unique Column transposed as columns (= patient numbe +1 as array has Header in)
Dim NewStRw As Long, OldStRw As Long: Let OldStRw = 2 'Variables for current and last rows where transposed list should go. Is also variables for range start and stop cell for Filtered list
For ArrClm = 2 To UBound(UniqueArr) 'Going through every Patient Unique Number (from second to last entry in the patient Number array
wks1.Range("a1:j" & lr & "").AutoFilter Field:=VLkUpClm, Criteria1:="" & UniqueArr(ArrClm) & "" 'This results in only Records with critical value in column 1 being seen in main sheet
wks1.Range("a1:j" & lr & "").SpecialCells(xlCellTypeVisible).Copy Destination:=wks1.Range("K" & OldStRw - 1 & "") ', 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
wks1.AutoFilterMode = False 'This makes everything visible again in main sheet. - (Usually done once at the end, but useful for debuggung purposes to do within loop)
Let NewStRw = wks1.Cells(Rows.Count, 11).End(xlUp).Row
wks1.Range("T" & OldStRw & ":T" & NewStRw & "").Copy 'Copy
wks1.Range("U" & OldStRw & "").PasteSpecial Transpose:=True 'Paste:=xlPasteAll, Operation:=xlNone, SkipBlanks:= False, Transpose:=True
Let OldStRw = NewStRw + 1 'Next patient DX codes will start in row after the last patients DX codes
Next ArrClm 'Go to next patient
'wks1.AutoFilterMode = False'This is where it is usually done.
wks1.Columns("J:T").Delete Shift:=xlToLeft
wks1.Range("J1").Value = "DX" 'oops I chopped the DX off- so I put it back!!
End Sub 'PatientSortin
and here is your returned file (Saved on XL2007 as .xlsm ) Macro in Macro Module Alan:
https://app.box.com/s/7idndjz9x6wszm85fnw2
.. also attatched..
..
Hi Bailey_Thomas,
. I work through a lot of peoples codes, learning as I go along. I learnt a new way to get at the unique values with the .RemoveDuplicates, bit. Thanks. I learn the most from Threads where people give different solutions to the same problem. (Amazingly close effort as you were not at your computer!)
Bookmarks