Sort/Arrange Rows based on Cell Value in Range VBA

crp

New Member
Joined
Jul 30, 2021
Messages
18
Office Version
  1. 365
Platform
  1. Windows
I have a series of data compiled into one excel sheet. The order of the data depends on each row's association to other rows, based on their LinkTo values. Below is an example of before, and how I need the data to be organized. I'd like for this to be automated in VBA.

Example Raw Data
IDCategoryLinkTo
1Fruit
2Onion4
3Apple1
4Vegetable
5Banana1
6Red Apple3

Example Desired Result
IDCategoryLinkTo
1Fruit
3Apple1
6Red Apple3
5Banana1
4Vegetable
2Onion4
 
How far does your actual data range extend that has row highlighting?
 
Upvote 0

Excel Facts

Save Often
If you start asking yourself if now is a good time to save your Excel workbook, the answer is Yes
Change

Set r = Range(Cells(1, 1), Cells(lRow, "N"))

To

Set r = Range(Cells(1, 1), Cells(lRow, "X"))
 
Upvote 0
I'm getting a debug run-time error ' 13': Type Mismatch at this line:

m = Application.Match(Cells(2, "N").Value, r, 0) + 2

It is showing that m = 0.
 
Upvote 0
That means it didn't find a match for the LinkTo ID. Check your data.
 
Upvote 0
In the cases of the Fruit and Vegetable rows that do not have links, are they overlooked? In my data, I do have rows that have links, but their links are not listed in the dataset.

Example: the Fruit/Vegetable rows would be linked to say 1234-0 “Food”, but this row is not included in the spreadsheet. What would happen in this case?
 
Upvote 0
That was not what you represented in your initial request. Things would go MUCH smoother if you disclosed ALL the requirements up front. Please post a true representation of the ALL the data.
 
Upvote 0
That should be the only other thing I can think of that isn’t already represented. Therefore, if a row has a link to a value that isn’t represented in the spreadsheet, what would change in the code? With my data, if this occurs, I think it would be accurate to just bypass this row and continue on.
 
Upvote 0
I think I solved it.

Assumptions
1. Any invalid LinkTo id will be skipped (placement may change due to other rows being moved
2. There are NO duplicates of the Major Categories (i.e. Fruit, Vegetable, etc)
3. Items with multiple LinkTo ids will keep all LinkTo ids and be inserted under each matching LinkTo id item found

VBA Code:
Sub LinkSort()
    Dim lRow As Long, match As Long, noIDs As Long, iD As Long, idPos As Long, cRow As Long, endLoop As Long
    Dim multIDs As Long
    Dim str As String, replaced As String, LnkID As String
    Dim rng As Range
     
     'Get last row of data in column "A"
    lRow = Cells(Rows.Count, 1).End(xlUp).Row
    
    'Set r to the data in column "A" so we can search for LinkTo ID's
    Set rng = Range(Cells(1, 1), Cells(lRow, 1))
    
    'Set loop variables
    endLoop = rng.Rows.Count
    cRow = 2
    multIDs = 0
    
    'Loop through the data and find a match for the LinkTo ID
    While cRow <= endLoop
        str = Cells(cRow, "N").Value
        replaced = Replace(str, "-", "")
        noIDs = Len(str) - Len(replaced)
               
        Select Case noIDs
        
            Case Is = 1 'Move the item below the matching LinkTo ID
                On Error Resume Next 'in case no match found match = 0
                match = Application.match(Cells(cRow, "N").Value, rng, 0) + 1
                If match <> 0 And cRow <> match Then
                    On Error GoTo 0
                    Rows(cRow & ":" & cRow).Cut
                    Rows(match & ":" & match).Insert Shift:=xlDown
                    If match > rng.Rows.Count Then ' if match + 1 is greater than the number of rows we need to extend the range by 1 row
                        Set rng = Range(Cells(1, 1), Cells(Cells(Rows.Count, 1).End(xlUp).Row, 1))
                    End If
                    match = 0
                Else
                    cRow = cRow + 1
                    match = 0
                End If
                
            Case Is > 1 'Move the item to the bottom of the list and increment multIDs and reduce endLoop by 1
                multIDs = multIDs + 1
                Rows(cRow & ":" & cRow).Cut
                Rows(Cells(Rows.Count, 1).End(xlUp).Row + 1 & ":" & Cells(Rows.Count, 1).End(xlUp).Row + 1).Insert Shift:=xlDown
                Set rng = Range(Cells(1, 1), Cells(Cells(Rows.Count, 1).End(xlUp).Row, 1))
                endLoop = endLoop - 1
                match = 0
            
            Case Is = 0 'No Id indicates bad data so we will skip this item
                cRow = cRow + 1
                match = 0
        End Select
        On Error GoTo 0
   Wend
   
   'Here is where we will deal with all the items with multiple LinkTo ids
   If multIDs <> 0 Then
        cRow = endLoop + 1
        endLoop = endLoop + multIDs
        For cRow = cRow To endLoop
            str = Cells(cRow, "N").Value
            replaced = Replace(str, "-", "")
            noIDs = Len(str) - Len(replaced)
            Rows(cRow & ":" & cRow).Copy
            Rows(cRow + 1 & ":" & cRow + noIDs - 1).Insert Shift:=xlDown
            Application.CutCopyMode = False
            Set rng = Range(Cells(1, 1), Cells(Cells(Rows.Count, 1).End(xlUp).Row, 1))
            endLoop = endLoop + noIDs - 1
            LnkID = Cells(cRow, "N").Value
            
            idPos = 0
            
            For iD = 1 To noIDs
                idPos = InStr(idPos + 1, LnkID, "-", vbTextCompare)
                If idPos <> 0 Then
                    On Error Resume Next
                    match = Application.match(Mid(LnkID, idPos - 4, 6), rng, 0)
                    If match <> 0 And cRow <> match + 1 Then
                        On Error GoTo 0
                        Rows(cRow & ":" & cRow).Cut
                        Rows(match + 1 & ":" & match + 1).Insert Shift:=xlDown
                        If cRow > match + 1 Then cRow = cRow + 1
                    End If
                End If
            Next iD
        Next cRow
    End If

End Sub
 
Upvote 0
I agree with the assumptions. This is very close. It is organizing most of the data. One issue is the compiled data before running has a major category (Fruit) with no valid LinkTos as the first row below the header. Once I run the program, it duplicates this one row a couple thousand times. It also sometimes places the first LinkTo item directly below what it's linked to (Apple directly below Fruit), but sometimes it places items in between those that are linked (Fruit - Onion - Apple).
 
Upvote 0

Forum statistics

Threads
1,223,236
Messages
6,170,917
Members
452,366
Latest member
TePunaBloke

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