Numeric Identifiers for Multiple Groups (vba?)

ajcormac

New Member
Joined
May 26, 2014
Messages
10
Hi there,

Currently I have a set of data consisting of an unique identifier (ID), four product properties (Brand.1.1, Brand.1.2, ...), and a preference.

What I would like to do is for each product category (i.e. Brand, Price, and Preference) is assign numeric identifiers to values - that is, common values will be assigned the same identifier within each category. If possible, I would also like a legend to be created automatically. It is possible that the same input exists in different categories, but they should not be seen as equivalent to each other.

My current method involves creating a chart of unique values for each category and using lookup functions but this is a slow process when I have multiple product categories to go through (Size, Price, Brand, Warranty, Features, Delivery, etc.).

Example:
[TABLE="class: grid, width: 500"]
<tbody>[TR]
[TD]ID[/TD]
[TD]Brand.1.1[/TD]
[TD]Brand.1.2[/TD]
[TD]Price.1.1[/TD]
[TD]Price.1.2[/TD]
[TD]Preference[/TD]
[/TR]
[TR]
[TD]ID001[/TD]
[TD]Apple[/TD]
[TD]Cereal[/TD]
[TD]50[/TD]
[TD]25[/TD]
[TD]Cereal[/TD]
[/TR]
[TR]
[TD]ID002[/TD]
[TD]Cereal[/TD]
[TD]Bread[/TD]
[TD]32[/TD]
[TD]41[/TD]
[TD]Cereal[/TD]
[/TR]
[TR]
[TD]ID003[/TD]
[TD]Bread[/TD]
[TD]Apple[/TD]
[TD]50[/TD]
[TD]32[/TD]
[TD]Apple[/TD]
[/TR]
[TR]
[TD]ID004[/TD]
[TD]Cereal[/TD]
[TD]Eggs[/TD]
[TD]41[/TD]
[TD]25[/TD]
[TD]Eggs[/TD]
[/TR]
</tbody>[/TABLE]

Assign numeric values:
[TABLE="class: grid, width: 500"]

<tbody>[TR]
[TD][/TD]
[TD]Brand.1.1[/TD]
[TD]Brand.1.2[/TD]
[TD]Price.1.1[/TD]
[TD]Price.1.2[/TD]
[TD]Preference[/TD]
[/TR]
[TR]
[TD]ID001[/TD]
[TD]1[/TD]
[TD]3[/TD]
[TD]1[/TD]
[TD]2[/TD]
[TD]1[/TD]
[/TR]
[TR]
[TD]ID002[/TD]
[TD]3[/TD]
[TD]2[/TD]
[TD]3[/TD]
[TD]4[/TD]
[TD]1[/TD]
[/TR]
[TR]
[TD]ID003[/TD]
[TD]2[/TD]
[TD]1[/TD]
[TD]1[/TD]
[TD]3[/TD]
[TD]2[/TD]
[/TR]
[TR]
[TD]ID004[/TD]
[TD]3[/TD]
[TD]4[/TD]
[TD]4[/TD]
[TD]2[/TD]
[TD]3[/TD]
[/TR]
</tbody>
[/TABLE]



Legend:
Brand:
Apple - 1
Bread - 2
Cereal - 3
Eggs -4

Price:
$50 - 1
$25 -2
$32 -3
$41 -4

Preference: (Notice how it has same values as Brand but doesn't necessarily assign same numbers since it's a different category)
Cereal -1
Apple -2
Eggs -3

I imagine VBA will be required but any thoughts/help would be appreciated.
 
This will do the trick, I have addded a lot of comments to make clear how it works:

<font face=Courier New><SPAN style="color:#00007F">Sub</SPAN> GetIdentifiers()<br><SPAN style="color:#007F00">'</SPAN><br><SPAN style="color:#007F00">' Sub to make copy of input table and replace Brand, Price _<br>  and Preference with index numbers. Then output legend to _<br>  these numbers</SPAN><br><SPAN style="color:#007F00">'===========================================================</SPAN><br>    <SPAN style="color:#00007F">Dim</SPAN> colBrand <SPAN style="color:#00007F">As</SPAN> Collection, colPrice <SPAN style="color:#00007F">As</SPAN> Collection, _<br>        colPref <SPAN style="color:#00007F">As</SPAN> Collection<br>    <SPAN style="color:#00007F">Dim</SPAN> rIn <SPAN style="color:#00007F">As</SPAN> Range, rOut <SPAN style="color:#00007F">As</SPAN> Range, rC <SPAN style="color:#00007F">As</SPAN> Range<br>    <SPAN style="color:#00007F">Dim</SPAN> vArr <SPAN style="color:#00007F">As</SPAN> <SPAN style="color:#00007F">Variant</SPAN><br>    <SPAN style="color:#00007F">Dim</SPAN> lR <SPAN style="color:#00007F">As</SPAN> <SPAN style="color:#00007F">Long</SPAN><br>    <br>    <SPAN style="color:#00007F">Set</SPAN> colBrand = <SPAN style="color:#00007F">New</SPAN> Collection<br>    <SPAN style="color:#00007F">Set</SPAN> colPrice = <SPAN style="color:#00007F">New</SPAN> Collection<br>    <SPAN style="color:#00007F">Set</SPAN> colPref = <SPAN style="color:#00007F">New</SPAN> Collection<br>    <br>    <SPAN style="color:#007F00">' get unique Brands</SPAN><br>    <SPAN style="color:#00007F">Set</SPAN> rIn = Range("C3")   <SPAN style="color:#007F00">' first Brand cell below header</SPAN><br>    <SPAN style="color:#00007F">Set</SPAN> colBrand = FillCollection(rIn, 2)<br>    <SPAN style="color:#007F00">' get unique Prices</SPAN><br>    <SPAN style="color:#00007F">Set</SPAN> rIn = Range("E3")   <SPAN style="color:#007F00">' first Price cell below header</SPAN><br>    <SPAN style="color:#00007F">Set</SPAN> colPrice = FillCollection(rIn, 2)<br>    <SPAN style="color:#007F00">' get Preferences</SPAN><br>    <SPAN style="color:#00007F">Set</SPAN> rIn = Range("G3")   <SPAN style="color:#007F00">' first Preference cell below header</SPAN><br>    <SPAN style="color:#00007F">Set</SPAN> colPref = FillCollection(rIn, 1)<br>    <br>    <SPAN style="color:#007F00">' Create Numeric Table</SPAN><br>    <SPAN style="color:#00007F">Set</SPAN> rIn = rIn.CurrentRegion<br>    <SPAN style="color:#00007F">Set</SPAN> rOut = rIn.Offset(rIn.Cells(1, 1).Row + rIn.Rows.Count + 2, 0)<br>    <SPAN style="color:#007F00">'expand rOut to same size as rIn</SPAN><br>    <SPAN style="color:#00007F">Set</SPAN> rOut = rOut.Resize(rIn.Rows.Count, rIn.Columns.Count)<br>    <SPAN style="color:#007F00">'copy values to array for fast processing</SPAN><br>    vArr = rIn.Value<br>    <br>    <SPAN style="color:#007F00">'now replace values in vArr with index numbers</SPAN><br>    GetIndexintoArray vArr, colBrand, 2, 2<br>    GetIndexintoArray vArr, colPrice, 4, 2<br>    GetIndexintoArray vArr, colPref, 6, 1<br>    <br>    <SPAN style="color:#007F00">' then output the vArr</SPAN><br>    rOut.Value = vArr<br>    <br>    <SPAN style="color:#007F00">' Now the Legend, two columns right of output table</SPAN><br>    <SPAN style="color:#00007F">Set</SPAN> rOut = rOut.Cells(1, rOut.Columns.Count).Offset(0, 2)<br>    lR = Application.WorksheetFunction.Max(colBrand.Count, _<br>                        colPrice.Count, colPref.Count)<br>    <SPAN style="color:#00007F">ReDim</SPAN> vArr(1 <SPAN style="color:#00007F">To</SPAN> lR + 2, 1 <SPAN style="color:#00007F">To</SPAN> 8) <SPAN style="color:#007F00">' reset array to correct _<br>                                      size for legend table</SPAN><br>    <br>    vArr(1, 1) = "Legend"<br>    vArr(2, 1) = "Brand:"<br>    vArr(2, 4) = "Price:"<br>    vArr(2, 7) = "Preference:"<br>    <SPAN style="color:#00007F">For</SPAN> lR = 1 <SPAN style="color:#00007F">To</SPAN> colBrand.Count<br>        vArr(lR + 2, 1) = colBrand.Item(lR)<br>        vArr(lR + 2, 2) = lR<br>    <SPAN style="color:#00007F">Next</SPAN> lR<br>    <SPAN style="color:#00007F">For</SPAN> lR = 1 <SPAN style="color:#00007F">To</SPAN> colPrice.Count<br>        vArr(lR + 2, 4) = colPrice.Item(lR)<br>        vArr(lR + 2, 5) = lR<br>    <SPAN style="color:#00007F">Next</SPAN> lR<br>    <SPAN style="color:#00007F">For</SPAN> lR = 1 <SPAN style="color:#00007F">To</SPAN> colPref.Count<br>        vArr(lR + 2, 7) = colPref.Item(lR)<br>        vArr(lR + 2, 8) = lR<br>    <SPAN style="color:#00007F">Next</SPAN> lR<br>    <br>    <SPAN style="color:#007F00">'print out the legend</SPAN><br>    rOut.Resize(UBound(vArr, 1), <SPAN style="color:#00007F">UBound</SPAN>(vArr, 2)).Value = vArr<br>    <br><SPAN style="color:#00007F">End</SPAN> <SPAN style="color:#00007F">Sub</SPAN><br><br><SPAN style="color:#00007F">Function</SPAN> FillCollection(<SPAN style="color:#00007F">ByVal</SPAN> rStart <SPAN style="color:#00007F">As</SPAN> Range, <SPAN style="color:#00007F">ByVal</SPAN> lCol <SPAN style="color:#00007F">As</SPAN> <SPAN style="color:#00007F">Long</SPAN>) _<br>        <SPAN style="color:#00007F">As</SPAN> Collection<br><SPAN style="color:#007F00">'</SPAN><br><SPAN style="color:#007F00">' Function to get unique items into a collection.</SPAN><br><SPAN style="color:#007F00">' Returns the collection.</SPAN><br><SPAN style="color:#007F00">' Input: rStart is the first cell of range to get items from. _<br>         lCol is the number of columns to use for input</SPAN><br><SPAN style="color:#007F00">'====================================================================</SPAN><br>    <SPAN style="color:#00007F">Dim</SPAN> colCollection <SPAN style="color:#00007F">As</SPAN> Collection<br>    <SPAN style="color:#00007F">Dim</SPAN> vArr <SPAN style="color:#00007F">As</SPAN> <SPAN style="color:#00007F">Variant</SPAN><br>    <SPAN style="color:#00007F">Dim</SPAN> lR <SPAN style="color:#00007F">As</SPAN> <SPAN style="color:#00007F">Long</SPAN>, lC <SPAN style="color:#00007F">As</SPAN> <SPAN style="color:#00007F">Long</SPAN>, lRows <SPAN style="color:#00007F">As</SPAN> <SPAN style="color:#00007F">Long</SPAN><br>    <br>    <SPAN style="color:#00007F">Set</SPAN> colCollection = <SPAN style="color:#00007F">New</SPAN> Collection<br>    lRows = rStart.CurrentRegion.Rows.Count - 1<br>    vArr = rStart.Resize(lRows, lCol) <SPAN style="color:#007F00">' read values into array from rIn extended to end of table for lCol columns</SPAN><br>    <br>    <SPAN style="color:#007F00">' now loop through all elements in the array and add them to the  collection. Only unique values will be added if we add the item twice first as the item, then as the key</SPAN><br>    <SPAN style="color:#00007F">On</SPAN> <SPAN style="color:#00007F">Error</SPAN> <SPAN style="color:#00007F">Resume</SPAN> <SPAN style="color:#00007F">Next</SPAN>    <SPAN style="color:#007F00">' to avoid error when encountering duplicate</SPAN><br>    <SPAN style="color:#00007F">For</SPAN> lR = <SPAN style="color:#00007F">LBound</SPAN>(vArr, 1) <SPAN style="color:#00007F">To</SPAN> <SPAN style="color:#00007F">UBound</SPAN>(vArr, 1)<br>        <SPAN style="color:#00007F">For</SPAN> lC = <SPAN style="color:#00007F">LBound</SPAN>(vArr, 2) <SPAN style="color:#00007F">To</SPAN> <SPAN style="color:#00007F">UBound</SPAN>(vArr, 2)<br>            colCollection.Add vArr(lR, lC), <SPAN style="color:#00007F">CStr</SPAN>(vArr(lR, lC))<br>        <SPAN style="color:#00007F">Next</SPAN> lC<br>    <SPAN style="color:#00007F">Next</SPAN> lR<br>    <SPAN style="color:#00007F">On</SPAN> <SPAN style="color:#00007F">Error</SPAN> <SPAN style="color:#00007F">GoTo</SPAN> 0 <SPAN style="color:#007F00">' reset error behaviour</SPAN><br>    <SPAN style="color:#00007F">Set</SPAN> FillCollection = colCollection<br><SPAN style="color:#00007F">End</SPAN> <SPAN style="color:#00007F">Function</SPAN><br><br><SPAN style="color:#00007F">Sub</SPAN> GetIndexintoArray(vArr <SPAN style="color:#00007F">As</SPAN> <SPAN style="color:#00007F">Variant</SPAN>, <SPAN style="color:#00007F">ByVal</SPAN> colColl <SPAN style="color:#00007F">As</SPAN> Collection, _<br>            <SPAN style="color:#00007F">ByVal</SPAN> lCol <SPAN style="color:#00007F">As</SPAN> <SPAN style="color:#00007F">Long</SPAN>, <SPAN style="color:#00007F">ByVal</SPAN> lColCount <SPAN style="color:#00007F">As</SPAN> <SPAN style="color:#00007F">Long</SPAN>)<br><SPAN style="color:#007F00">'</SPAN><br><SPAN style="color:#007F00">' Sub to change the values in array with the relevant index _<br>  numbers taken from collection. _<br>  Input: vArr is array with values, these will be replaced _<br>         colColl is Collection with unique values _<br>         lCol is start column in vArr to be processed _<br>         lColCount is number of columns to be processed</SPAN><br><SPAN style="color:#007F00">'====================================================================</SPAN><br>         <br>    <SPAN style="color:#00007F">Dim</SPAN> lR <SPAN style="color:#00007F">As</SPAN> <SPAN style="color:#00007F">Long</SPAN>, lC <SPAN style="color:#00007F">As</SPAN> <SPAN style="color:#00007F">Long</SPAN>, lRows <SPAN style="color:#00007F">As</SPAN> <SPAN style="color:#00007F">Long</SPAN>, lIndx <SPAN style="color:#00007F">As</SPAN> <SPAN style="color:#00007F">Long</SPAN><br>    <br>    <SPAN style="color:#007F00">' first row in vArr holds heading, don't process</SPAN><br>    <br>    <SPAN style="color:#00007F">For</SPAN> lR = <SPAN style="color:#00007F">LBound</SPAN>(vArr, 1) + 1 <SPAN style="color:#00007F">To</SPAN> UBound(vArr, 1)<br>        <SPAN style="color:#00007F">For</SPAN> lC = lCol <SPAN style="color:#00007F">To</SPAN> lCol + lColCount - 1<br>            <SPAN style="color:#00007F">For</SPAN> lIndx = 1 <SPAN style="color:#00007F">To</SPAN> colColl.Count<br>                <SPAN style="color:#00007F">If</SPAN> colColl.Item(lIndx) = vArr(lR, lC) <SPAN style="color:#00007F">Then</SPAN><br>                    vArr(lR, lC) = lIndx<br>                    <SPAN style="color:#00007F">Exit</SPAN> <SPAN style="color:#00007F">For</SPAN><br>                <SPAN style="color:#00007F">End</SPAN> <SPAN style="color:#00007F">If</SPAN><br>            <SPAN style="color:#00007F">Next</SPAN> lIndx<br>        <SPAN style="color:#00007F">Next</SPAN> lC<br>    <SPAN style="color:#00007F">Next</SPAN> lR<br><SPAN style="color:#00007F">End</SPAN> <SPAN style="color:#00007F">Sub</SPAN></FONT>
 
Upvote 0

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