0

Trying to create all unique combinations of values for each row given the fact that each each cell may or may not have multiple nested values. The goal is to interpret each row and write a new line for each unique combination of the values.

Sub combo(x As Integer, splitCell As Boolean, lastcol As Long)
Dim cellArray() As String
Dim ws As Worksheet
Set ws = ThisWorkbook.Worksheets("Test")

    For y = lastcol To 2 Step -1
    Dim counter As Integer
    counter = 0
        cellValue = ws.Cells(x, y).Value
        cellArray() = Split(cellValue, Chr(10))
        Debug.Print cellValue
        If UBound(cellArray()) > LBound(cellArray()) Then
           Debug.Print "Splitting " & x, y

           For t = UBound(cellArray()) To LBound(cellArray()) Step -1

                Rows(x + counter).Offset(1).EntireRow.Insert
                counter = counter + 1

                For a = lastcol To 1 Step -1
                If a = y Then
                    ws.Cells(x + counter, a).Value = cellArray(t)
                    splitCell = True
                    rowToDel = x
                Else
                    ws.Cells(x + counter, a).Value = ws.Cells(x, a).Value
                    splitCell = True
                End If

                Next a
           Next t
        End If
    x = x + counter
    Next y
    If splitCell = True Then
            Rows(rowToDel).EntireRow.Delete
    End If
x = x - 1
lastRow = ws.Cells(Rows.Count, 1).End(xlUp).Row



End Sub

This code currently works for the case of having one cell with nested values versus single entries in other cells in that row. However, there are cases of up to three columns each with nested values that unique entries should be made for.

1
  • Welcome to StackOverflow, broonz. Do you have a screenshot and possibly some sample data you can add to the post? Currently, I am having difficulties visualizing the data you wish you process. Also, what are the admissible permutations (including repetition)? It might help to read the following link on How do I Ask a Good Question and also how to create a Minimal, Complete, and Verifiable example (MCVE). Commented Aug 8, 2016 at 17:01

1 Answer 1

1

In the below comments I pretend that the data you are splitting is comma-delimited. I did that simply because it is easier to show examples using commas than using tabs. The code included is still using tab as the delimiter.

If I understand your problem correctly, when you have a value of (for instance) "1,4,67" in column Q, your code is correctly generating extra rows - one with "1" in column Q, one with "4" in column Q, and one with "67" in column Q, with all other columns copied from the original line.

However, when you have a second cell with multiple comma-separated values, say "A,B" in column T, that "A,B" is still appearing on each of the first two generated rows, and is only being split on the third row - thus creating a total of 4 rows. But you want six rows generated instead (one for each value of "A,B" with each value of "1,4,67").

I'm also assuming you are calling the subroutine for each row in the original data.

The following code will process a line, expanding each of the values so that you get every combination:

Sub combo(x As Integer, splitCell As Boolean, lastcol As Long)
    Dim cellArray() As String
    Dim ws As Worksheet
    Set ws = ThisWorkbook.Worksheets("Sheet1")
    Dim t As Long
    Dim y As Long
    Dim a As Long
    Dim cellValue
    Dim dstRow As Integer
    Dim srcRow As Integer
    Dim aCellWasSplit As Boolean

    srcRow = x
    dstRow = x
    splitCell = False
    Do While srcRow <= dstRow
        aCellWasSplit = False
        For y = lastcol To 2 Step -1
            cellValue = ws.Cells(x, y).Value
            cellArray() = Split(cellValue, Chr(10))
            Debug.Print cellValue
            If UBound(cellArray()) > LBound(cellArray()) Then
               Debug.Print "Splitting " & x, y
               aCellWasSplit = True

               For t = UBound(cellArray()) To LBound(cellArray()) Step -1

                    dstRow = dstRow + 1
                    Rows(dstRow).EntireRow.Insert

                    For a = lastcol To 1 Step -1
                        If a = y Then
                            ws.Cells(dstRow, a).Value = cellArray(t)
                        Else
                            ws.Cells(dstRow, a).Value = ws.Cells(srcRow, a).Value
                        End If
                    Next a
               Next t
               Exit For
            End If
        Next y
        If aCellWasSplit Then
            ws.Rows(srcRow).EntireRow.Delete
            dstRow = dstRow - 1
            splitCell = True
        Else
            srcRow = srcRow + 1
        End If
    Loop
    x = dstRow + 1
End Sub

And the following code can be used to test it:

Sub test()
    Dim anythingProcessed As Boolean
    Dim currentRow As Integer
    Dim lastCol As Long
    currentRow = 1
    lastCol = 5
    Do While currentRow <= ThisWorkbook.Worksheets("Sheet1").Cells(Rows.Count, 1).End(xlUp).Row
        combo currentRow, anythingProcessed, lastCol
    Loop
End Sub
Sign up to request clarification or add additional context in comments.

2 Comments

Perfect, this worked appropriately for the use case :)
Appreciate your correctly understanding OP requirement and providing an appropriate solution.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.