0

I want to loop through rows and columns in VBA.

I have a table of recipes for ceramic glazes:
[image of db]
Not all recipes have the same amount of ingredients.
These recipes aren't real.

I want to generate a list of recipes with the title of the recipe followed by the ingredients and the amount of each ingredient:
[image with sample recipes]

I modified a code snippet found here:

Sub ExtractRecipes()

    Dim wsSrc As Worksheet: Set wsSrc = Worksheets("cone6")
    Dim wsDest As Worksheet: Set wsDest = Worksheets("output")
    Dim LastRow As Long: LastRow = wsSrc.UsedRange.Find("*", SearchOrder:=xlByRows, SearchDirection:=xlPrevious).row
    Dim LastCol As Long: LastCol = wsSrc.UsedRange.Find("*", SearchOrder:=xlByColumns, SearchDirection:=xlPrevious).Column
    Dim i As Long, j As Long, RowCounter As Long: RowCounter = 1
    On Error Resume Next

    With wsDest
        For i = 1 To LastRow
            .Cells(RowCounter, 1) = wsSrc.ListObjects("testTable").ListColumns("recipe").DataBodyRange.Cells(i)
            For j = 1 To LastCol
                If wsSrc.ListObjects("testTable").DataBodyRange.Cells(i, j) <> "" Then
                    .Cells(RowCounter + 1, 1) = wsSrc.ListObjects("testTable").ListColumns("material_" & j).DataBodyRange.Cells(i)
                    .Cells(RowCounter + 1, 2) = wsSrc.ListObjects("testTable").ListColumns("material_amount_" & j).DataBodyRange.Cells(i)
                    .Cells(RowCounter + 1, 3) = Err.Description
                    RowCounter = RowCounter + 1
                End If
            Next j
        Next i
    End With

End Sub

I get an error

subscript out of range

Current output:
[output]

3
  • 1
    Can you remove the On Error Resume Next and see what line is failing. At a guess it's the j variable goes to 8 but your labeling scheme goes to 4, so there is no material_7 for instance. Commented Mar 21, 2024 at 14:53
  • 1
    Besides, the error is not cleared, so once it appears, it stays until the end. Commented Mar 21, 2024 at 15:01
  • @Warcupine sure, the line that's failing is at .Cells(RowCounter + 1, 1) = wsSrc.ListObjects("testTable").ListColumns("material_" & j).DataBodyRange.Cells(i) Commented Mar 21, 2024 at 15:09

1 Answer 1

2

Untested but something like this should work:

Sub ExtractRecipes()

    Dim wsSrc As Worksheet, wsDest As Worksheet, lo As ListObject, col As Long
    Dim RowCounter As Long, rw As Range, rec, mat, amt
    
    Set wsSrc = Worksheets("cone6")
    Set lo = wsSrc.ListObjects("testTable")
    
    Set wsDest = Worksheets("output")
    RowCounter = 1
    
    For Each rw In lo.DataBodyRange.Rows   'loop rows in listobject
        rec = rw.Cells(1).Value            'recipe
        If Len(rec) > 0 Then               'have entry?
            wsDest.Cells(RowCounter, 1).Value = rec
            For col = 2 To lo.ListColumns.Count Step 2
                mat = rw.Cells(col).Value
                amt = rw.Cells(col + 1).Value
                If Len(mat) > 0 Then '+ test amount?
                    RowCounter = RowCounter + 1
                    wsDest.Cells(RowCounter, 1).Resize(1, 2).Value = Array(mat, amt)
                End If
            Next col
            RowCounter = RowCounter + 1 'add empty row between
        End If
    Next rw
End Sub
Sign up to request clarification or add additional context in comments.

2 Comments

Works perfectly! Thank you so much :) I'm guessing what's happening here is there's a step to count how many columns have a value?
Yes - If Len(mat) > 0 checks to see if there's any material entered in that column.

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.