Search code examples
excelvbalookupoffset

See if word in column B on sheet 1 is 1 or 0, if 1 lookup word in sheet 2 in row 3 and return list below that word


I have tried to fix a code from the answers that I have found in the forum, but I can't manage.

My issue is:

I have a list of recipes names in the sheet weeks, and I want to decide with a 1 or a 0 which ones I want to meal prep for next week. In sheet Recipes, I have the Recipes listed with their ingredients list below. I would like to have an output of what I need to shop in Sheet 5. In sheet Weeks If column B = 1, take recipe name in column A; Hlookup recipe name in sheet Recipes row 3, and return list of ingredients below to sheet 3 (the shopping list).

Sub Output_Shoopinglist()

    Dim ws As Worksheet  ' define worksheet
    Set ws = ThisWorkbook.Worksheets("Weeks")
    
    Dim LastRow As Long  ' get last used row in column b
    LastRow = ws.Cells(ws.Rows.Count, "B").End(xlUp).Row
    
    Dim DataRange As Range  ' get data range
    Set DataRange = ws.Range("B3", "C20" & LastRow)
    
    Dim DataArray() As Variant  ' read data into an array (for fast processing)
    DataArray = DataRange.Value
    
    Dim OutputData As Collection  ' create a collection where we collect all desired data
    Set OutputData = New Collection
    
    ' check each data row and if desired add to collection
    Dim iRow As Long
    For iRow = LBound(DataArray, 1) To UBound(DataArray, 1)
        If DataArray(iRow, 2) = 1 Then
            OutputData.Add DataArray(iRow, 1)
        End If
    Next iRow
    
    
    Dim wsTemplate As Worksheet
    Set wsTemplate = ThisWorkbook.Worksheets("Recipes")
    
    Dim wsVolume As Worksheet
    Set wsVolume = ThisWorkbook.Worksheets("Shopping list")
    
    'Lookup Value in Tab Recipes in row 3, and return Ingrediants list one below the other in tab Shopping list in Column B

'Here I am missing code:
              

End Sub

Here are some screenshots: enter image description here

enter image description here

enter image description here


Solution

  • I have left comments in few area to explain what the code is doing in general.

    As mentioned in the comment - The basic idea is to perform a Find method along the row containing the recipe name and if it is found, the column number of the found cell will be used to pull out the list of ingredients (and the amount that is 1 column before) that is written below the recipe names.

    Once the list has been retrieved in an array, it will be used to write into the shopping list worksheet at once.

    Option Explicit
    
    Const WSNAME_WEEK As String = "Weeks"
    Const WSNAME_RECIPES As String = "Recipes"
    Const WSNAME_SHOPPING As String = "Shopping list"
    
    Sub Output_Shoppinglist()
    
        Dim ws As Worksheet  ' define worksheet
        Set ws = ThisWorkbook.Worksheets(WSNAME_WEEK)
        
        Dim lastRow As Long  ' get last used row in column b
        lastRow = ws.Cells(ws.Rows.Count, "B").End(xlUp).Row
        
        Dim DataRange As Range  ' get data range
        Set DataRange = ws.Range("B4:C" & lastRow)
        
        Dim DataArray() As Variant  ' read data into an array (for fast processing)
        DataArray = DataRange.Value
        
        Dim OutputData As Collection  ' create a collection where we collect all desired data
        Set OutputData = New Collection
        
        ' check each data row and if desired add to collection
        Dim iRow As Long
        For iRow = LBound(DataArray, 1) To UBound(DataArray, 1)
            If DataArray(iRow, 2) = 1 Then
                OutputData.Add DataArray(iRow, 1)
            End If
        Next iRow
            
        If OutputData.Count <> 0 Then
    '        Uncomment if you need to clear the shopping list prior to inserting this batch of list of ingredients
    '        With ThisWorkbook.Worksheets(WSNAME_SHOPPING)
    '            Dim shoppingLastRow As Long
    '            shoppingLastRow = .Cells(.Rows.Count, 2).Row
    '            .Range("A2:B" & shoppingLastRow).Value = ""
    '        End With
                    
            '1. Loop through the collection,
            '2. Pass the recipe name to GetIngredients to retrieve the list of ingredients (in an array) from Recipes worksheet
            '3. Pass the array to WriteToShoppingList for writing into the Shopping list worksheet
            Dim i As Long
            For i = 1 To OutputData.Count
                'Get the ingredient list from Recipes sheet
                Dim ingredList As Variant
                ingredList = GetIngredients(OutputData(i))
                
                If Not IsEmpty(ingredList) Then WriteToShoppingList ingredList
            Next i
        End If
        
        MsgBox "Done!"
    End Sub
    
    Function GetIngredients(argRecipeName As String) As Variant
        Const firstRow As Long = 7 'Change this to whichever row the first ingredient should be on
        Const recipesNameRow As Long = 3
        
        Dim wsTemplate As Worksheet
        Set wsTemplate = ThisWorkbook.Worksheets(WSNAME_RECIPES)
                
        '==== Do a Find on row with the recipe names
        Dim findCell As Range
        Set findCell = wsTemplate.Rows(recipesNameRow).Find(argRecipeName, LookIn:=xlValues, LookAt:=xlWhole)
                
        If Not findCell Is Nothing Then
            '==== If found, assign the value of the ingredients (from firstRow to the last row) into an array
            
            Dim lastRow As Long
            lastRow = wsTemplate.Cells(firstRow, findCell.Column).End(xlDown).Row
            
            Dim ingredRng As Range
            Set ingredRng = wsTemplate.Range(wsTemplate.Cells(firstRow, findCell.Column), wsTemplate.Cells(lastRow, findCell.Column)).Offset(, -1).Resize(, 2)
                            
            Dim ingredList As Variant
            ingredList = ingredRng.Value
    
            GetIngredients = ingredList
        End If        
    End Function
    
    Sub WriteToShoppingList(argIngredients As Variant)
        Dim wsVolume As Worksheet
        Set wsVolume = ThisWorkbook.Worksheets(WSNAME_SHOPPING)
        
        Dim lastRow As Long
        lastRow = wsVolume.Cells(wsVolume.Rows.Count, 2).End(xlUp).Row
        
        wsVolume.Cells(lastRow + 1, 1).Resize(UBound(argIngredients, 1), 2).Value = argIngredients
    End Sub