Transpose data.

harzer

Board Regular
Joined
Dec 15, 2021
Messages
148
Office Version
  1. 2016
Platform
  1. Windows
Hello everyone,
I present to you my problem which I cannot solve given my level in VBA, I will explain the details to enable you to resolve it:
In my sheet "Sheet1" I have 5 groups, each group consists of 3 lines, sometimes more, in our case here all groups consist of three lines.
The group numbers are in column “A”.
For greater visibility of the different groups, I colored each group a different color.

If the subject sought (in column "F") is in the first line of the group, then the position will be "Position 1" = column "M", likewise, if the subject is in the 2nd line of the group, this means that the position will be "position 2" = column "N" and finally if the subject is in row 3, then the position will be "Position 3" = column "O".

The desired final result is in the range ("M2:O9"). Here is how we will proceed:
To begin, we will create a list without duplicates from all the elements of column "F" to place it in column "L".
To explain it to you better, we will take an example, here we go:
We go through the column "L" on all the cells that make it up from "L2" to "L9", the first cell encountered is "AE27-022/2022 M", we will look for the same value in column " F", we find it in cell "F2" and "F13":
F2: is located in the first line of our Group, therefore Position 1, we will retrieve the value of column "A" from the same line = (Group 1) which we will write in "M2".
F13: is located in the 3rd line of our Group, therefore Position 3, we will retrieve the value of column "A" from the same line = (Group 4) which we will write in "O2".

We continue with the next cell in column "L", this is cell "5919-001/2023 M", we find this value in "F3".
F3: is located in the 2nd line of our Group, therefore Position 2, we will retrieve the value of column "A" from the same line = (Group 1) which we will write in "N3"

We continue in the same way for all the cells in column “L” and look for matches in column “F” and “A”
Information: If we are faced with the possibility of having several pieces of information in the same cell, it would be desirable to separate the groups with a hyphen (-)
I hope I have been clear enough in my explanations, if necessary, I remain at your disposal.
Thank you for your propositions.

Classeur1
ABCDEFGHIJKLMNO
1Groupes :FemaleFatherMotherMaleFatherMotherList Without duplicatesPosition 1Position 2Position 3
2Groupe 1MN96-010/2021 FMN96-002/2020 MMN96-020/2020 FAE27-022/2022 MAE27-049/2021 MAE27-003/2021 FAE27-022/2022 MGroupe 1Groupe 4
35919-001/2023 M3024-058/2020 M3024-011/2022 F5919-001/2023 MGroupe 1
4AE27-035/2022 MGroupe 2
5Groupe 2MN96-034/2021 FMN96-050/2020 MMN96-013/2019 FAE27-035/2022 MMN96-005/2021 MAE27-068/2021 FAE27-069/2023 MGroupe 3Groupe 2
6AE27-069/2023 MAE27-018/2022 MMN96-045/2022 FMN96-008/2021 MGroupe 2 - Groupe 3 - Groupe 5
7MN96-008/2021 MMN96-002/2020 MMN96-020/2020 FAE27-033/2022 MGroupe 4Groupe 4
8Groupe 3AE27-026/2022 FMN96-046/2019 MMN96-036/2021 FAE27-069/2023 MAE27-018/2022 MMN96-045/2022 FMN96-020/2023 MGroupe 5
9MN96-008/2021 MMN96-002/2020 MMN96-020/2020 FAE27-010/2021 MGroupe 5
10
11Groupe 4AE27-037/2022 FMN96-005/2021 MAE27-068/2021 FAE27-033/2022 MAE27-010/2021 MMN96-034/2021 F
12AE27-033/2022 MAE27-010/2021 MMN96-034/2021 F
13AE27-022/2022 MAE27-049/2021 MAE27-003/2021 F
14Groupe 5AE27-038/2022 FMN96-005/2021 MAE27-068/2021 FMN96-020/2023 MMN96-011/2022 MMN96-020/2021 F
15AE27-010/2021 MAE27-015/2020 MAE27-021/2020 F
16MN96-008/2021 MMN96-002/2020 MMN96-020/2020 F
Sheet1
 

Excel Facts

Formula for Yesterday
Name Manager, New Name. Yesterday =TODAY()-1. OK. Then, use =YESTERDAY in any cell. Tomorrow could be =TODAY()+1.
Try on a copy.
VBA Code:
Sub FindGroup()
    Dim a, b, dict As Object, key As Variant
    Dim i As Long, j As Long, k As Long, m As Long, n As Long
    Dim ws As Worksheet
    Dim numRow As Long
    
    Set ws = ThisWorkbook.Worksheets("Sheet1") 'Change sheet name as needed
    numRow = ws.Cells(ws.Rows.Count, "H").End(xlUp).Row
    a = ws.Range("A2:I" & numRow).Value
    j = 1

    'Assign index
    For i = 1 To numRow - 1
        If a(i, 1) > 0 Then
            j = 1
            a(i, 9) = j
        Else
            j = j + 1
            a(i, 9) = j
        End If
    Next i
    
    ' Find max number of position
    Dim maxPos As Long
    maxPos = a(1, 9)
    For i = 1 To UBound(a, 1)
        If a(i, 9) > maxPos Then
            maxPos = a(i, 9)
        End If
    Next i
    'Fill in Groups
    For k = 1 To numRow - 1
        If k > 1 Then
            If a(k, 1) = "" Then a(k, 1) = a(k - 1, 1)
        End If
    Next k
    
    ' Create a dictionary object to store unique non-blank values from column F
    Set dict = CreateObject("Scripting.Dictionary")
    For i = 1 To numRow - 1
        If Not dict.exists(a(i, 6)) And a(i, 6) <> "" Then
            dict.Add a(i, 6), a(i, 6)
        End If
    Next i
 
    ReDim b(1 To dict.Count, 1 To maxPos + 1)
    i = 1
    For Each key In dict.Keys
        b(i, 1) = key
        i = i + 1
    Next key
    ' Concatenate values based on conditions
    For n = 1 To UBound(a, 1)
        For m = 1 To UBound(b, 1)
            If b(m, 1) = a(n, 6) Then
                If b(m, 1 + a(n, 9)) = "" Then
                    b(m, 1 + a(n, 9)) = a(n, 1)
                Else
                    b(m, 1 + a(n, 9)) = b(m, 1 + a(n, 9)) & "-" & a(n, 1)
                End If
            End If
        Next m
    Next n
    ' Output to sheet
    ws.Range("L2").Resize(UBound(b, 1), UBound(b, 2)).Value = b
End Sub
 
Upvote 0
Hello Cubist and the forum,
Thank you for your feedback, in fact, the code put in place works very, very well and very quickly, it completely satisfies me, Thank you very much.
May I allow myself to ask you one very last thing to close this project, namely to write the headers according to the number of existing positions, we will have the following representations:

If the position number is 3, then we will have this in the range "L1" to "O1":

demande MrExcel.xlsm
LMNO
1ListPosition 1Position 2Position 3
Sheet1


If the number of positions is 4, then we will have this in the range "L1" to "P1":

demande MrExcel.xlsm
LMNOP
1ListPosition 1Position 2Position 3Position 4
Sheet1


Thank you so much.
Friendships.
 
Upvote 0
How about
VBA Code:
Sub FindGroup()
    Dim a, b, dict As Object, key As Variant, headers As Variant
    Dim i As Long, j As Long, k As Long, m As Long, n As Long
    Dim ws As Worksheet
    Dim numRow As Long
  
    Set ws = ThisWorkbook.Worksheets("Sheet1") 'Change sheet name as needed
    numRow = ws.Cells(ws.Rows.Count, "H").End(xlUp).Row
    a = ws.Range("A2:I" & numRow).Value
    j = 1

    'Assign index
    For i = 1 To numRow - 1
        If a(i, 1) > 0 Then
            j = 1
            a(i, 9) = j
        Else
            j = j + 1
            a(i, 9) = j
        End If
    Next i
  
    ' Find max number of position
    Dim maxPos As Long
    maxPos = a(1, 9)
    For i = 1 To UBound(a, 1)
        If a(i, 9) > maxPos Then
            maxPos = a(i, 9)
        End If
    Next i
    'Fill in Groups
    For k = 1 To numRow - 1
        If k > 1 Then
            If a(k, 1) = "" Then a(k, 1) = a(k - 1, 1)
        End If
    Next k
  
    ' Create a dictionary object to store unique non-blank values from column F
    Set dict = CreateObject("Scripting.Dictionary")
    For i = 1 To numRow - 1
        If Not dict.exists(a(i, 6)) And a(i, 6) <> "" Then
            dict.Add a(i, 6), a(i, 6)
        End If
    Next i
 
    ReDim b(1 To dict.Count, 1 To maxPos + 1)
    i = 1
    For Each key In dict.Keys
        b(i, 1) = key
        i = i + 1
    Next key
    ' Concatenate values based on conditions
    For n = 1 To UBound(a, 1)
        For m = 1 To UBound(b, 1)
            If b(m, 1) = a(n, 6) Then
                If b(m, 1 + a(n, 9)) = "" Then
                    b(m, 1 + a(n, 9)) = a(n, 1)
                Else
                    b(m, 1 + a(n, 9)) = b(m, 1 + a(n, 9)) & "-" & a(n, 1)
                End If
            End If
        Next m
    Next n
  'headers
    ReDim headers(1 To 1, 1 To maxPos + 1)
  headers(1, 1) = "List"
   For i = 1 To maxPos
        headers(1, i + 1) = "Position " & i
  Next i

    ' Output to sheet
    ws.Range("L1").Resize(UBound(headers, 1), UBound(headers, 2)).Value = headers
    ws.Range("L2").Resize(UBound(b, 1), UBound(b, 2)).Value = b
End Sub
 
Upvote 0
Solution
Hello Cubist and the Forum,
Thank you very much for updating the code as per my last request, the code works beautifully.
Bravo and thank you again for your support and availability.
Friendships.
 
Upvote 0

Forum statistics

Threads
1,223,162
Messages
6,170,431
Members
452,326
Latest member
johnshaji

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