I want to give a "Timepoint" value (which I call a scanRank in the code below) to all the rows in this table based on "Subject ID".
In this example, the first subject is already completed.
| Subject ID | Group Info | Scan date | Timepoint |
|---|---|---|---|
| 1 | group 1 | 20250225 | 1 |
| 1 | group 1 | 20250305 | 2 |
| 1 | group 1 | 20250320 | 3 |
| 1 | group 1 | 20250404 | 4 |
| 1 | group 1 | 20250404 | 4 |
| 1 | group 1 | 20250404 | 4 |
| 1 | group 1 | 20250404 | 4 |
| 3 | group 2 | 20250225 | |
| 4 | group 3 | 20250225 | |
| 4 | group 3 | 20250305 | |
| 4 | group 3 | 20250321 | |
| 4 | group 3 | 20250321 | |
| 4 | group 3 | 20250407 | |
| 4 | group 3 | 20250407 | |
| 4 | group 3 | 20250407 | |
| 4 | group 3 | 20250407 | |
| 5 | group 3 | 20250227 | |
| 5 | group 3 | 20250227 | |
| 5 | group 3 | 20250306 |
I want VBA to recognize the first row and the last row for each common Subject ID, to stop the range when the Subject ID changes.
Once the macro has cell addresses for the start and end, then it can run the for loop to get the "timepoints" for each Subject ID then move on to the next Subject ID.
In the code below, I don't know how to code the "startSubID", "endSubID", "scanRow", or "prevscanRow" variables. I was thinking of a Do loop.
Private Sub CommandButton1_Click()
Dim ws4 As Worksheet
Set ws4 = ThisWorkbook.Sheets("Sheet1") ' Change "Sheet1" to your sheet name
Dim ScanDates As Range, SingScanDate As Range
Dim SubIDs As Range, UniqueSubID As Range
lastrow = ws4.Cells(ws4.Rows.Count, 3).End(xlUp).Row
Set SubIDs = ws4.Range("C12:C" & lastrow)
For Each UniqueSubID In SubIDs
' startSubID = ??? starting row based on Subject ID in Column C
' endSubID = ??? ending row based on Subject ID in Column C
Set ScanDates = ws4.Range(ws4.Cells(startSubID, 6), ws4.Cells(endSubID, 6))
scanRank = 1
scanRow = startSubID.Address
prevscanRow = startSubID.Address.Offset(1, 0)
For Each SingScanDate In ScanDates
ws4.Cells(scanRow, 6).Value = scanRank
If ws4.Cells(scanRow, 5).Value = ws4.Cells(prevscanRow, 5).Value Then
ws4.Cells(scanRow, 6).Value = ws4.Cells(prevscanRow, 6).Value
End If
scanRow = scanRow + 1
prevscanRow = prevscanRow + 1
scanRank = scanRank + 1
Next SingScanDate
UniqueSubID = endSubID + 1
Next UniqueSubID
End Sub