I have 140 unique numbers and trying to find that through the list which can be used in vba
The formula works fine till 64 ifs are used, later I am having a trouble
=IFERROR(IFERROR(IFERROR(IFERROR(IFERROR(IFERROR(IFERROR(IFERROR(IFERROR(IFERROR(IFERROR(IFERROR(IFERROR(IFERROR(IFERROR(IFERROR(IFERROR(IFERROR(IFERROR(IFERROR(IFERROR(IFERROR(IFERROR(IFERROR(IFERROR(IFERROR(IFERROR(IFERROR(IFERROR(IFERROR(IFERROR(IFERROR(IFERROR(IFERROR(IFERROR(IFERROR(IFERROR(IFERROR(IFERROR(IFERROR(IFERROR(IFERROR(IFERROR(IFERROR(IFERROR(IFERROR(IFERROR(IFERROR(IFERROR(IFERROR(IFERROR(IFERROR(IFERROR(IFERROR(IFERROR(IFERROR(IFERROR(IFERROR(IFERROR(IFERROR(IFERROR(IFERROR(IFERROR(IFERROR(IFERROR(IFERROR(IFERROR(IFERROR(IFERROR(IFERROR(IFERROR(IFERROR(IFERROR(IFERROR(IFERROR(IFERROR(IFERROR(IFERROR(IFERROR(IFERROR(IFERROR(IFERROR(IFERROR(IFERROR(IFERROR(IFERROR(IFERROR(IFERROR(IFERROR(IFERROR(IFERROR(IFERROR(IFERROR(IFERROR(IFERROR(IFERROR(IFERROR(IFERROR(IFERROR(IFERROR(IFERROR(IFERROR(IFERROR(IFERROR(IFERROR(IFERROR(IFERROR(IFERROR(IFERROR(IFERROR(IFERROR(IFERROR(IFERROR(IFERROR(IFERROR(IFERROR(IFERROR(IFERROR(IFERROR(IFERROR(IFERROR(IFERROR(IF(FIND("5216",A2,1)>0,"00000A-5216",""),IF(FIND("5140",A2,1)>0,"00000B-5140","")),IF(FIND("5148",A2,1)>0,"00000C-5148","")),IF(FIND("5117",A2,1)>0,"00000D-5117","")),IF(FIND("5204",A2,1)>0,"00000E-5204","")),IF(FIND("5238",A2,1)>0,"00000F-5238","")),IF(FIND("5203",A2,1)>0,"00000G-5203","")),IF(FIND("5237",A2,1)>0,"00000H-5237","")),IF(FIND("5051",A2,1)>0,"5051","")),IF(FIND("0101",A2,1)>0,"0101","")),IF(FIND("0700",A2,1)>0,"0700","")),IF(FIND("3208",A2,1)>0,"3208","")),IF(FIND("3209",A2,1)>0,"3209","")),IF(FIND("3900",A2,1)>0,"3900","")),IF(FIND("3901",A2,1)>0,"3901","")),IF(FIND("5029",A2,1)>0,"5029","")),IF(FIND("5030",A2,1)>0,"5030","")),IF(FIND("5032",A2,1)>0,"5032","")),IF(FIND("5033",A2,1)>0,"5033","")),IF(FIND("5036",A2,1)>0,"5036","")),IF(FIND("5049",A2,1)>0,"5049","")),IF(FIND("5067",A2,1)>0,"5067","")),IF(FIND("5068",A2,1)>0,"5068","")),IF(FIND("5069",A2,1)>0,"5069","")),IF(FIND("5072",A2,1)>0,"5072","")),IF(FIND("5073",A2,1)>0,"5073","")),IF(FIND("5075",A2,1)>0,"5075","")),IF(FIND("5076",A2,1)>0,"5076","")),IF(FIND("5078",A2,1)>0,"5078","")),
IF(FIND("5079",A2,1)>0,"5079","")),IF(FIND("5080",A2,1)>0,"5080","")),IF(FIND("5081",A2,1)>0,"5081","")),IF(FIND("5082",A2,1)>0,"5082","")),IF(FIND("5083",A2,1)>0,"5083","")),IF(FIND("5090",A2,1)>0,"5090","")),IF(FIND("5094",A2,1)>0,"5094","")),IF(FIND("5095",A2,1)>0,"5095","")),IF(FIND("5100",A2,1)>0,"5100","")),IF(FIND("5106",A2,1)>0,"5106","")),IF(FIND("5124",A2,1)>0,"5124","")),IF(FIND("5125",A2,1)>0,"5125","")),IF(FIND("5126",A2,1)>0,"5126","")),IF(FIND("5147",A2,1)>0,"5147","")),IF(FIND("5150",A2,1)>0,"5150","")),IF(FIND("5151",A2,1)>0,"5151","")),IF(FIND("5155",A2,1)>0,"5155","")),IF(FIND("5156",A2,1)>0,"5156","")),IF(FIND("5157",A2,1)>0,"5157","")),IF(FIND("5158",A2,1)>0,"5158","")),IF(FIND("5159",A2,1)>0,"5159","")),IF(FIND("5194",A2,1)>0,"5194","")),IF(FIND("5195",A2,1)>0,"5195","")),IF(FIND("5196",A2,1)>0,"5196","")),IF(FIND("5205",A2,1)>0,"5205","")),IF(FIND("5227",A2,1)>0,"5227","")),IF(FIND("5228",A2,1)>0,"5228",""))IF(FIND("5229",A2,1)>0,"5229","")),IF(FIND("5234",A2,1)>0,"5234","")),IF(FIND("5241",A2,1)>0,"5241","")),IF(FIND("5242",A2,1)>0,"5242","")),IF(FIND("5243",A2,1)>0,"5243","")),IF(FIND("5244",A2,1)>0,"5244","")),IF(FIND("5254",A2,1)>0,"5254","")),IF(FIND("5255",A2,1)>0,"5255","")),IF(FIND("5267",A2,1)>0,"5267","")),IF(FIND("5269",A2,1)>0,"5269","")),IF(FIND("5271",A2,1)>0,"5271","")),IF(FIND("5278",A2,1)>0,"5278","")),IF(FIND("5280",A2,1)>0,"5280","")),IF(FIND("5286",A2,1)>0,"5286","")),IF(FIND("5297",A2,1)>0,"5297","")),IF(FIND("5305",A2,1)>0,"5305","")),IF(FIND("5306",A2,1)>0,"5306","")),IF(FIND("5310",A2,1)>0,"5310","")),IF(FIND("5315",A2,1)>0,"5315","")),IF(FIND("5316",A2,1)>0,"5316","")),IF(FIND("5318",A2,1)>0,"5318","")),IF(FIND("5321",A2,1)>0,"5321","")),IF(FIND("5322",A2,1)>0,"5322","")),IF(FIND("5324",A2,1)>0,"5324","")),IF(FIND("5325",A2,1)>0,"5325","")),IF(FIND("5326",A2,1)>0,"5326","")),IF(FIND("5327",A2,1)>0,"5327","")),IF(FIND("5328",A2,1)>0,"5328","")),IF(FIND("5336",A2,1)>0,"5336","")),IF(FIND("5337",A2,1)>0,"5337","")),IF(FIND("5339",A2,1)>0,"5339","")),IF(FIND("5341",A2,1)>0,"5341","")),IF(FIND("5350",A2,1)>0,"5350",""))IF(FIND("5351",A2,1)>0,"5351","")),IF(FIND("5352",A2,1)>0,"5352","")),IF(FIND("5353",A2,1)>0,"5353","")),IF(FIND("5356",A2,1)>0,"5356","")),IF(FIND("5357",A2,1)>0,"5357","")),IF(FIND("5358",A2,1)>0,"5358","")),IF(FIND("5359",A2,1)>0,"5359","")),IF(FIND("5360",A2,1)>0,"5360","")),IF(FIND("5361",A2,1)>0,"5361","")),IF(FIND("5362",A2,1)>0,"5362","")),IF(FIND("5363",A2,1)>0,"5363","")),IF(FIND("5378",A2,1)>0,"5378","")),IF(FIND("5379",A2,1)>0,"5379","")),IF(FIND("5380",A2,1)>0,"5380","")),IF(FIND("5381",A2,1)>0,"5381","")),IF(FIND("5382",A2,1)>0,"5382","")),IF(FIND("5383",A2,1)>0,"5383","")),IF(FIND("5389",A2,1)>0,"5389",""))IF(FIND("5390",A2,1)>0,"5390","")),IF(FIND("5392",A2,1)>0,"5392","")),IF(FIND("6000",A2,1)>0,"6000","")),IF(FIND("6001",A2,1)>0,"6002","""")),IF(FIND("6003",A2,1)>0,"6003","")),IF(FIND("6004",A2,1)>0,"6004","")),IF(FIND("6005",A2,1)>0,"6005","")),IF(FIND("6006",A2,1)>0,"6006","")),IF(FIND("6653",A2,1)>0,"6653","")),IF(FIND("6654",A2,1)>0,"6654","")),IF(FIND("6655",A2,1)>0,"6655","")),IF(FIND("6656",A2,1)>0,"6656","")),IF(FIND("6657",A2,1)>0,"6657","")),IF(FIND("9202",A2,1)>0,"9202","")),IF(FIND("9401",A2,1)>0,"9401","")),RIGHT(A2,3,4))"
the result should return the number mentioned and I am planning to sort them in ascending order.
The value in A2 looks like PMGAG5216GC, PMG005216GC, PMGVV5140GC, PMG005140GC, PMGVV5148GCW, PMGAG5117GCW, PMG005117GCW, PMGAG5204GCB, PMG005204GCB, PMGAG5238GCB, PMGVV5238GCB, PMG005238GCB, PMGAG5203GCB, etc. these are some sample order numbers that are being updated and the numbers 5238 is a number that I have to find from that order to sort them in ascending order. In the same way, I have 140 numbers that have to found to sort them accordingly. The 4 digit numbers are fixed in the orders and it should be one from the 140 number list that I had mentioned
Rule of thumb, if you see yourself nesting anything deeper than 5 or 6 levels, stop and take the time to see if there wouldn't be a more easily maintainable way to do the same thing. Hitting hard limits (e.g. 64 levels of nesting) is rarely a sign that things are done in an optimal fashion.
PMGAG5216GC PMG005216GC PMGVV5140GC PMG005140GC PMGVV5148GCW PMGAG5117GCW PMG005117GCW PMGAG5204GCB PMG005204GCB PMGAG5238GCB PMGVV5238GCB PMG005238GCB PMGAG5203GCB
Assuming the format is consistently the same, you can grab the 4 characters starting at the 6th position, and then verify if these 4 characters exist in a lookup table that contains the 140 values you're interested in. The MID function can be used to do this.
You could leverage the fact that VLOOKUP in the first column of the lookup table would return the lookup value itself, and a lookup failure would be #N/A, so wrapping it with IFERROR to turn that into an empty string would look like this:
=IFERROR(VLOOKUP(MID(A2,6,4),theLookupTable[TheLookupColumn],1,FALSE),"")
Now, if looks like some of the values need a prefix e.g. "00000A-"; include that prefix (with the dash, so you don't have to conditionally add it in the formula) in the lookup table (say, in some [Prefix] column) where it's needed, and just concatenate it after the lookup.
=IFERROR(VLOOKUP(MID(A2,6,4),theLookupTable[TheLookupColumn],1,FALSE) & VLOOKUP(MID(A2,6,4),theLookupTable[#[TheLookupColumn]:[ThePrefixColumn]],2,FALSE),"")
Better if you can turn the MID(A2,6,4) part into a helper cell instead of computing it twice - use that MID function on your source data to populate the lookup table.
The lookup table might look like this:
TheLookupColumn ThePrefixColumn
5216 00000A-
5140 00000B-
5148 00000C-
...
3901
...
Sort the table by TheLookupColumn, and the lookups should be pretty fast.
If you just want to show the first number from your lookup list which is contained in any given order number you can do something like this:
It's an array formula so you need to enter it using Ctrl + Shift + Enter
Assumes there can be only one match per order number and that none of the items in your lookup list are substrings of another item (though a workaround for that would be to sort your lookup list in descending order of item length)
Abridged Question:
If I have a concatenated string of "|#|#|#|...|#|", how can I apply a multiplier to each of the numbers and update the concatenated text? For example, for |4|12|8|, multiply by a factor of 2 and update the concatenated text to |8|24|16|.
Background
I have three columns of interest. The first column contains a date, the second an amount or factor, and the third column concatenates data into the format "|#|#|...|#|" (e.g., |2|5|, |2|5|12|, |4|12|, etc.). At times, a multiplying factor needs to be applied to the concatenated data, and the individual numbers would need to be updated accordingly.
An example would be—
Date Amt Concatenated Data
01/01/18 2 |2|
01/05/18 5 |2|5|
02/06/18 12 |2|5|12|
03/25/18 -3 |4|12|
03/31/18 8 |4|12|8|
04/01/18 F2 |8|24|16| (factor of 2 applied)
04/15/18 12 |8|24|16|12|
04/01/18 F1/4 |2|6|4|3| (factor of 1/4 applied)
With a formula, how can I apply the factor to the concatenated data, and update the individual numbers?
I'm bound by the following conditions:
Excel 2007, so no TEXTJOIN function
No VBA or UDFs (due to security policies)
Individual numbers are dynamic (i.e., I can't use a static value for the "old_text" parameter of the SUBSTITUTE formula)
Amount of individual numbers within concatenated data is also dynamic (may contain one number, or may contain dozens of different numbers)
I can pull out the individual numbers using an array formula. I can even then multiply those numbers by the factor to produce an array result. However, I can't rebuild the concatenated data, because CONCATENATE doesn't work on an array. I've also tried SUBSTITUTE, but I can't iterate through the "|" separators. I can only substitute a given segment (e.g., change all entries of "|2|" to "|4|"). Nesting SUBSTITUTE or using individual columns won't work, since it could potentially involve dozens of instances.
Just to add some info on the concatenated data:
Amt>0, then value is concatenated to the end of the previous concatenated value
Amt<0, begin reducing individual numbers in concatenated value (CV) until reduction amount reached (e.g., for |2|5|12| and Amt=-3, reduce CV to |4|12|, which is -2 from the first segment and -1 from the second segment)
Amt reduction is limited to the sum of the previous CV's individual numbers (e.g., for |4|12|, the reduction cannot exceed 16)
Amt=F#, indicates a multiplying factor, and the CV's numbers need to be updated
The CV has no max (could have dozens to hundreds of individual numbers, with numbers going from 1 to 100,000+), other than any max applied by Excel itself on string length
HIGH LEVEL
Four parts to this solution
They satisfy pre-requisites (2007 compatibility, no VB, no Office 365 requirement, no custom VB functions, provide for complete 'dynamic' nature of variable length of cells to concatenate)
Caveat: to best knowledge / research, there is no parsimonious single-cell function & therefore an interim step has been proposed)
One more caveat: I imagine the simple 'hack' of wrapping a graph around the delimited data is out of question (see 'Other/Various' below ☺)
PARTS 1-4
Accompanying parts 1-4 below are functions which relate to the following screenshot:
I have also uploaded / amended to meet requirements of Google Sheets (see here)
Parts 1 & 2:
Similar in that they rely upon FilterXML technique to count component / terms, and split cells respectively:
Part 1:
=COUNT(2*TRANSPOSE(FILTERXML("<AllText><Num>"&SUBSTITUTE(LEFT(MID(D12,2,LEN(D12)-1),LEN(MID(D12,2,LEN(D12)-1))-1),"|","</Num><Num>")&"</Num></AllText>","//Num")))
Note: google sheets doesn't recognise FilterXML, so have amended technique/functions accordingly. For instance, above can be determined using counta on the split cells in Part 2 (easier / much more simpler than proposed approach above, albeit less robust given any cells lying to the right of the split cells will interfere with ordinary functionality of this approach).
Part 2:
It's either a manual approach, a fancy series of 'mid' &/or substitute / left/right functions, or the following FilterXML code which, per various sources (e.g. here) should be compatible with Excel 2007:
=IF(LEFT(C12,1)="F",1*SUBSTITUTE(C12,"F",""),1)*TRANSPOSE(FILTERXML("<AllText><Num>"&SUBSTITUTE(LEFT(MID(D12,2,LEN(D12)-1),LEN(MID(D12,2,LEN(D12)-1))-1),"|","</Num><Num>")&"</Num></AllText>","//Num"))
Commonality with Part 1 (re: FilterXML) can be seen - the only difference is that the count(Part 1) has been replaced with the transformation (multiplicative factor, as given in O.P's Q).
Part 3
Nothing fancy here - a simple concatenation (which is a far cry from a 'recursive' substitution function, I know, but hey - it does the trick and can always be placed in a mirror copy of the original sheet to avoid space issues/cell interaction issues)
=IF(H12="","",IF(G24="","|","")&G24&H12&"|")
Part 4
Thanks to the number of terms derived in Part 1, an offset function can easily determine the final cell pertaining to the concatenated 'build up' of 'transformed' values (per Part 3):
=OFFSET(H31,0,E31-1,1,1)
OTHER / VARIOUS
Various other proposals and 'workarounds' exist; unfortunately, these appear to fall short in one way or another of the pre-requisites set forth, videlicit:
a) Function/formula based
b) No VB
c) Excel 2007
d) Dynamic (variable/unknown number of terms)
Manual: e.g. function = concatenate(transpose(desired range)), and then components of the concatenate function and pressing F9 to convert to calculated values, which are readily applicable in the concatenate function. Disadvantage: time consuming in relation to 'automated solution' (needs to be done for each applicable toy). Advantage: no additional 'spreadsheet real estate' required, quicker/straightforward implementation in first instance.
Variants of the 'build-up' method: e.g. per Part 3, however, this alone does not ensure for an automated approach across an unknown number of terms in the original concatenated list.
Have mentioned in a previous solution (here), but may be case that you are eligible for Office 365 functionality whilst on a previous version of Excel (see Office Insider here)
Other proposals (above/below in this forum mind you) propose textjoin (so not sure if this is a comprehension issue or what ☺)
And yes, as alluded to at outset, you can easily achieve the desired outcome using a simple graph! Just for fun then, sort the data in reverse order, and include the split/delimited values as a bar graphs' "x-values" (which, by defn. for this type of graph, will now appear along the ordinary Cartesian 'y/vertical' axis)...
Zero points for this but thought it was an interesting discovery on my part!
(and if still in doubt, here's what the 'graph' would look like if I didn't kill everything except for the axis labels...):
Numerous references for relevant other items above, including research areas, as follows:
Excel Champs
StackOverflow - alternative applications for FilterXML
JUST ONE MORE THING...
In true Columbo style modus operandi, other ideas/approaches considered:
Application of pivot table?
Constructing matrices: I got a solution with a series of offset functions, but couldn't think of a feasible way to implement given space issues
Converting the split cells into a long digit through summation: e.g. 8 22 16 = 80 000 + 22 00 + 16. Using a substitute function with text (long digit, "General") I was able to successfully introduce the delimiter character ('|') for pairs of adjacent 'tuples' (e.g. I could get '8|2216', '822|16', but then a 'build up' formula where one cell depends upon converted values of the previous and so one was required once more, which landed me back to the proposal I have set out above
fyi - the matrix consideration only solves tuples of 2, for n-dimensional /combination one would need to 'pass' a string of characters over its mirror copy - e.g. {6,10,22} would pass over {6,10,22}, ignoring duplicate values would yield a trapezium as follows:
6
10
22
6
10
22
6
10
22
after the copy has 'passed' over the original (first row), we have the desired combination (22,10,6) (on the 'diagonal' such a matrix). This is akin to how Fourier Transforms work (kind of); but that aside, it was tempting to construct a matrix like this, but couldn't be bothered at this stage.
Will probably turn out to be a far simpler way that someone comes up with (I won't be the only person surprised based upon the various sources I've considered...)