Forum Discussion

SreekanthG's avatar
SreekanthG
Copper Contributor
Nov 03, 2024

Group items based on criteria

Hi,

I have different items which needs to be packed in different bags based on the following criteria. I have an itemized spreadsheet with the weight of each item (attached in link). I am looking for a solution to get the items packed in bags, fulfilling the criteria as mentioned below. For that reason, I would like to get which bag can contain how many items

- packet of items to be randomly packed in each bag such a way that the total weight shall not exceed 2.5 kg.
- each bag shall have mix of items from each category with at least 2 category items in each bag.
- Bag numbers shall be sequentially assigned in column F based on the first number which is manually assigned. (in example the bag number starts with 4001),

To achieve the desired result can formula be used or VBA is required? Appreciate, any ideas /solution to get the desired result.

Thanks in advance. https://1drv.ms/x/c/5184dd66ded11ae2/EbsnMRLq3VBNnhyOCHn1Fj0BpqL0z-uH3nsfZHQVnB2yRQ?e=poC4A4 

  • peiyezhu's avatar
    peiyezhu
    Bronze Contributor

    SreekanthG 

    create temp table aa2 as
    select rowid old_rowid,row_number() over ( partition by Category) grp,* from Sheet1;
    create temp table aa3 as
    select * from aa2 order by grp;
    create temp table aa as
    select *,sum(weight) over (order by rowid) acc from aa3 ;
    //select * from aa limit 20;
    create temp table bb as
    select acc from aa union select rowid*2500 acc from aa;
    create temp table cc as
    select * from bb left join aa using(acc);
    select *,'400'||iif(acc%2500=0,0,1)+acc/2500 bags from cc where old_rowid is not null;

     

    ā€ƒ

  • NikolinoDE's avatar
    NikolinoDE
    Gold Contributor

    SreekanthG 

    Here is a VBA approach, maybe it will help you.

    The link was not opened for personal security reasons.

    The VBA code is untested, please save your file in advance.

     

    Sub PackItemsIntoBags()
        Dim ws As Worksheet
        Dim lastRow As Long, row As Long
        Dim startBagNumber As Long
        Dim currentBagNumber As Long
        Dim currentBagWeight As Double
        Dim itemCategories As Object
        Dim currentBagItems As Object
        
        ' Define the starting bag number and initialize variables
        startBagNumber = 4001
        currentBagNumber = startBagNumber
        currentBagWeight = 0
        
        ' Define category minimum requirement
        Set itemCategories = CreateObject("Scripting.Dictionary")
        Set currentBagItems = CreateObject("Scripting.Dictionary")
        
        ' Set worksheet and find the last row of data
        Set ws = ThisWorkbook.Sheets("Sheet1")
        lastRow = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row
        
        ' Clear any previous bag numbers in Column F
        ws.Range("F2:F" & lastRow).ClearContents
        
        ' Loop through each item
        For row = 2 To lastRow
            Dim itemWeight As Double
            Dim itemCategory As String
            
            ' Get item weight and category
            itemWeight = ws.Cells(row, "D").Value
            itemCategory = ws.Cells(row, "C").Value
            
            ' Check if adding this item would exceed the bag's weight limit or not meet category mix
            If currentBagWeight + itemWeight > 2.5 Or (currentBagItems.Count >= 1 And Not currentBagItems.Exists(itemCategory)) Then
                ' Check if we have at least two categories in the current bag
                If currentBagItems.Count >= 2 Then
                    ' Move to the next bag
                    currentBagNumber = currentBagNumber + 1
                    currentBagWeight = 0
                    Set currentBagItems = CreateObject("Scripting.Dictionary") ' Reset the category mix for the new bag
                End If
            End If
            
            ' Assign the item to the current bag
            ws.Cells(row, "F").Value = currentBagNumber
            currentBagWeight = currentBagWeight + itemWeight
            
            ' Add item category to the current bag's categories if not already added
            If Not currentBagItems.Exists(itemCategory) Then
                currentBagItems.Add itemCategory, 1
            End If
        Next row
        
        ' Release memory
        Set itemCategories = Nothing
        Set currentBagItems = Nothing
        
        MsgBox "Items have been packed into bags."
    End Sub

     

    My answers are voluntary and without guarantee!

     

    Hope this will help you.

     

Resources