You may try the following:
Sub rearrange()
Const dates = "C", fromcolumn = "A", numcolumns = 5, fromrow = 1
Dim rearrangements As Long, i As Long, lastrow As Long, movement As Long, counter As Long
Application.ScreenUpdating = False
lastrow = Cells(Rows.Count, dates).End(xlUp).Row
Do
counter = counter + 1
rearrangements = 0
For i = fromrow To lastrow - 1
If Cells(i, dates).Value = Cells(i + 1, dates).Value Then
movement = Round((1.5 + Rnd * (lastrow - fromrow) / 3) * IIf((i - fromrow) > (lastrow - fromrow) / 2, -1, 1))
' Debug.Print "row: " & i, "moved to: " & i + 1 + movement
Cells(i, fromcolumn).Resize(1, numcolumns).Cut
Cells(i + 1 + movement, fromcolumn).Resize(1, numcolumns).Insert shift:=xlDown
rearrangements = rearrangements + 1
Application.CutCopyMode = False
End If
Next i
' Debug.Print "attempt: " & counter, "swaps done: " & rearrangements
Loop Until rearrangements = 0 Or counter >= Sqr(lastrow - fromrow)
If rearrangements <> 0 Then MsgBox "During last run there was still " & _
rearrangements & vbCrLf & "to be done", vbInformation, "Very tough dataset!"
End Sub
change the constants at the beginning - column where your dates areL dates = "C"
column where data sits - may be left from column with dates or if dates are leftmost write the same, for instance: fromcolumn = "C"
numcolumns = 5 (so in my example I tested it on data written in A:E). If you have only dates column (no other info associated with date then use 1
and finally: where real information starts - in test file I had no header, so fromrow = 1 was just what was needed.
Enjoy
Bookmarks