Sort data without changing the set of each data (using VBA)

feni1388

Board Regular
Joined
Feb 19, 2018
Messages
133
Office Version
  1. 2021
Platform
  1. Windows
Hello everyone...
I have data that needs to be sorted based on date and its number of occurance.
The user copy and paste one set of data one by one using VBA. So the date is random. Can be 2024/6/12 at the end of the rows or perhaps in the middle.
So I need to sort it first by date and then the number of occurance. But I still can't find a way to sort it without changing the set of each data.
I don't know how to do it manually, let alone using VBA.
Any idea how to do this?
Please help.

Book1
ABCDEF
1DateCustomer codeNo. of itemsItem codeQtyNumber of occurance
22024/6/14CHO010181GH07101
32GL781 
43GH731 
52024/6/13CMX010271GH07101
62GL781 
73GH731 
84GL832 
92024/6/14CNB010641BM43152
Sheet1
Cell Formulas
RangeFormula
C2,C5,C9C2=IFERROR(IF(D2<>"",1,""),"")
C3:C4,C6:C8C3=IF(D3="","",IF(AND(D3<>"",C2=""),1,C2+1))
F2:F9F2=IF(A2="","",IF(A2=A2,COUNTIF($A$2:A2,A2),""))


I want it to be like below

Book1
ABCDEF
1DateCustomer codeNo. of itemsItem codeQtyNumber of occurance
22024/6/14CHO010181GH07101
32GL781 
43GH731 
52024/6/14CNB010641BM43152
62024/6/13CMX010271GH07101
72GL781 
83GH731 
94GL832 
Sheet1
Cell Formulas
RangeFormula
C2,C5:C6C2=IFERROR(IF(D2<>"",1,""),"")
C3:C4,C7:C9C3=IF(D3="","",IF(AND(D3<>"",C2=""),1,C2+1))
F2:F9F2=IF(A2="","",IF(A2=A2,COUNTIF($A$2:A2,A2),""))
 

Excel Facts

Can you AutoAverage in Excel?
There is a drop-down next to the AutoSum symbol. Open the drop-down to choose AVERAGE, COUNT, MAX, or MIN
try
Code:
Sub test()
    Dim a, e, i&, ii&, n&, temp, dic As Object
    Set dic = CreateObject("Scripting.Dictionary")
    With [a1].CurrentRegion
        a = .FormulaR1C1
        For i = 2 To UBound(a, 1)
            If a(i, 1) <> "" Then temp = a(i, 1)
            If Not dic.exists(temp) Then
                ReDim w(1 To UBound(a, 2), 1 To 1)
            Else
                w = dic(temp)
                ReDim Preserve w(1 To UBound(a, 2), 1 To UBound(w, 2) + 1)
            End If
            For ii = 1 To UBound(a, 2)
                w(ii, UBound(w, 2)) = a(i, ii)
            Next
            dic(temp) = w
        Next
        mySort dic
        ReDim a(1 To UBound(a, 1), 1 To UBound(a, 2))
        For Each e In dic
            For ii = 1 To UBound(dic(e), 2)
                n = n + 1
                For i = 1 To UBound(dic(e), 1)
                    a(n, i) = dic(e)(i, ii)
                Next
            Next
        Next
        .Rows(2).Resize(n) = a
    End With
End Sub

Sub mySort(dic As Object)
    Dim i As Long, ii As Long, temp
    For i = 0 To dic.Count - 2
        For ii = i + 1 To dic.Count - 1
            If UBound(dic.items()(i), 2) > UBound(dic.items()(ii), 2) Then
                temp = dic.items()(i)
                dic.items()(i) = dic.items()(ii)
                dic.items()(ii) = temp
            End If
        Next
    Next
End Sub
 
Upvote 0
Solution
try
Code:
Sub test()
    Dim a, e, i&, ii&, n&, temp, dic As Object
    Set dic = CreateObject("Scripting.Dictionary")
    With [a1].CurrentRegion
        a = .FormulaR1C1
        For i = 2 To UBound(a, 1)
            If a(i, 1) <> "" Then temp = a(i, 1)
            If Not dic.exists(temp) Then
                ReDim w(1 To UBound(a, 2), 1 To 1)
            Else
                w = dic(temp)
                ReDim Preserve w(1 To UBound(a, 2), 1 To UBound(w, 2) + 1)
            End If
            For ii = 1 To UBound(a, 2)
                w(ii, UBound(w, 2)) = a(i, ii)
            Next
            dic(temp) = w
        Next
        mySort dic
        ReDim a(1 To UBound(a, 1), 1 To UBound(a, 2))
        For Each e In dic
            For ii = 1 To UBound(dic(e), 2)
                n = n + 1
                For i = 1 To UBound(dic(e), 1)
                    a(n, i) = dic(e)(i, ii)
                Next
            Next
        Next
        .Rows(2).Resize(n) = a
    End With
End Sub

Sub mySort(dic As Object)
    Dim i As Long, ii As Long, temp
    For i = 0 To dic.Count - 2
        For ii = i + 1 To dic.Count - 1
            If UBound(dic.items()(i), 2) > UBound(dic.items()(ii), 2) Then
                temp = dic.items()(i)
                dic.items()(i) = dic.items()(ii)
                dic.items()(ii) = temp
            End If
        Next
    Next
End Sub
Wow..........Thank you.... it's very close, except June 13th became at the end instead of the beginning.
I tried to undertand the code and change it myself, but it's really beyond me.
Which part should I change to make it right?

Book1
ABCDEF
1DateCustomer codeNo. of itemsItem codeQtyNumber of occurance
22024/6/14CHO010181GH07101
32GL781 
43GH731 
52024/6/14CNB010641BM43152
62024/6/13CMX010271GH07101
72GL781 
83GH731 
94GL832 
Sheet1
Cell Formulas
RangeFormula
F2:F9F2=IF(A2="","",IF(A2=A2,COUNTIF($A$2:A2,A2),""))
 
Upvote 0
???
The result shows exactly the same as your result in your post #1.(2nd table)
Am I missing something?
 
Upvote 0
???
The result shows exactly the same as your result in your post #1.(2nd table)
Am I missing something?
Sorry.........sorry....... I got completely confused. You're right.
I mixed it up with getting the data ascending instead of descending.
Your current code it's alright..... Thank you so much.....
 
Upvote 0
I did another test again. It seems that I need to separate the first code and your code.
If there's a way to combine it, it'd be great.
 
Upvote 0
Do you mean "Sub CopyData"?
try change
1)
Code:
Dim LastRow As Long

Sheets("Searh").Select
Range("C6:G31").Select
Selection.Copy


LastRow = Sheets("NextPO").Cells(Rows.Count, "D").End(xlUp).Row
LastRow = LastRow + 1
Sheets("NextPO").Range("A" & LastRow).PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks:=False, Transpose:=False
Application.CutCopyMode = False
to
Code:
Sheets("Searh").Range("C6:G31").Copy
Sheets("NextPO").Range("A1").PasteSpecial xlValues
2) delete
Code:
            Range("F:F").Value = Range("F:F").Value

And see how it goes.
 
Upvote 0
try
Code:
Sub test()
    Dim a, e, i&, ii&, n&, temp, dic As Object
    Set dic = CreateObject("Scripting.Dictionary")
    With [a1].CurrentRegion
        a = .FormulaR1C1
        For i = 2 To UBound(a, 1)
            If a(i, 1) <> "" Then temp = a(i, 1)
            If Not dic.exists(temp) Then
                ReDim w(1 To UBound(a, 2), 1 To 1)
            Else
                w = dic(temp)
                ReDim Preserve w(1 To UBound(a, 2), 1 To UBound(w, 2) + 1)
            End If
            For ii = 1 To UBound(a, 2)
                w(ii, UBound(w, 2)) = a(i, ii)
            Next
            dic(temp) = w
        Next
        mySort dic
        ReDim a(1 To UBound(a, 1), 1 To UBound(a, 2))
        For Each e In dic
            For ii = 1 To UBound(dic(e), 2)
                n = n + 1
                For i = 1 To UBound(dic(e), 1)
                    a(n, i) = dic(e)(i, ii)
                Next
            Next
        Next
        .Rows(2).Resize(n) = a
    End With
End Sub

Sub mySort(dic As Object)
    Dim i As Long, ii As Long, temp
    For i = 0 To dic.Count - 2
        For ii = i + 1 To dic.Count - 1
            If UBound(dic.items()(i), 2) > UBound(dic.items()(ii), 2) Then
                temp = dic.items()(i)
                dic.items()(i) = dic.items()(ii)
                dic.items()(ii) = temp
            End If
        Next
    Next
End Sub
Sorry to bother you again.

Your code was working fine and suddenly from yesterday it doesn't work as you can see from the table below.
I tried to look for the cause, but I still can't find any.
Maybe you have something in mind that might cause it.

I tried adding a record and it added to the correct place, but it didn't sort the whole record at the end.


Book2
ABCDEF
1DateCustomer codeNo. of itemsItem codeQtyNumber of occurance
22024/6/25FMS010101GL4451
32GL432
42024/6/25SBD040631JS1412
52JS207
62024/6/25KYS010111GL99403
72GL4420
82024/6/25SBD02A031GL91104
92024/6/25NKK010011BM4415
102GH231
113GL071
124GM742
132024/6/25KSS010681KJ1016
142024/6/25FMS010101GL4457
152GL432
162024/6/25SBD040631JS1418
172JS207
182024/6/25SMJ023711GL4339
192024/6/26MFJ010041GK9331
202024/6/26TKH010861JS1132
212024/6/26SSS018011BM9313
222024/6/26MRE020061BM43304
232024/6/26SSS01B161JT0915
242024/7/1KOG060061MX7361
252MX451
262024/7/1AES030951GL23102
272024/7/1MGS010021JS1753
282024/7/1KOU010171BM73184
292024/7/3KOU010071GL0711
302024/7/3MFJ010041GK9332
312024/7/3RUG030391GA02303
322024/7/4RUG040351JT12121
332024/6/28MRW010201GS9311
342GL481
352024/6/28TKN010181BM4312
362024/6/28NEC010151TU3513
372TU501
Sheet2
 
Upvote 0
Ahhh,
This should do.
Code:
Sub test()
    Dim a, i&, temp
    Application.ScreenUpdating = False
    a = Range("a2", Range("a" & Rows.Count).End(xlUp)).Value
    For i = 1 To UBound(a, 1)
        If a(i, 1) <> "" Then temp = CLng(a(i, 1))
        a(i, 1) = temp + i / (UBound(a, 1) * 100)
    Next
    Columns(1).Insert
    Columns(1).NumberFormat = ""
    [a2].Resize(UBound(a, 1)) = a
    [a1].CurrentRegion.Sort [a1], 1, , , , , , 1
    Columns(1).Delete
    Application.ScreenUpdating = True
End Sub
 
Upvote 0

Forum statistics

Threads
1,223,885
Messages
6,175,178
Members
452,615
Latest member
bogeys2birdies

We've detected that you are using an adblocker.

We have a great community of people providing Excel help here, but the hosting costs are enormous. You can help keep this site running by allowing ads on MrExcel.com.
Allow Ads at MrExcel

Which adblocker are you using?

Disable AdBlock

Follow these easy steps to disable AdBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the icon in the browser’s toolbar.
2)Click on the "Pause on this site" option.
Go back

Disable AdBlock Plus

Follow these easy steps to disable AdBlock Plus

1)Click on the icon in the browser’s toolbar.
2)Click on the toggle to disable it for "mrexcel.com".
Go back

Disable uBlock Origin

Follow these easy steps to disable uBlock Origin

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back

Disable uBlock

Follow these easy steps to disable uBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back
Back
Top