I have an array of non-ordered integers, and I am trying to return a TRUE or FALSE based on if x consecutive numbers can be found within the array
Example array in A1:A8 [20,17,13,16,21,22,19,18]
In B1 is [5], requiring the function to find 5 consecutive numbers.
No VBAs please
Based on similar queries and answers on this website, the best I came up with was
=AND(IF(SUM(--(A1:A8=TRANSPOSE(A1:A8)+1)),TRUE,FALSE),IF(SUM(--(A1:A8=TRANSPOSE(A1:A8)+2)),TRUE,FALSE),IF(SUM(--(A1:A8=TRANSPOSE(A1:A8)+3)),TRUE,FALSE),IF(SUM(--(A1:A8=TRANSPOSE(A1:A8)+4)),TRUE,FALSE))
I tried to mimic one of the answers from below
How to determine if a range of cells contain consecutive numbers?
=LET(ζ,UNIQUE(A1:A8),ISNUMBER(FIND(REPT(1,B1-1),CONCAT(N(MMULT(LARGE(ζ,SEQUENCE(ROWS(ζ)-1)+{0,1}),{1;-1})=1)))))
If you're not using an English-language version of Excel then the separators within the two array constants, i.e.
{0,1} and {1;-1}
may require amendment.
This issue can be circumvented - albeit at the cost of formula brevity - with the following locale-independent version:
=LET(ζ,UNIQUE(A1:A8),ISNUMBER(FIND(REPT(1,B1-1),CONCAT(N(MMULT(LARGE(ζ,SEQUENCE(ROWS(ζ)-1)+SEQUENCE(,2,0)),SEQUENCE(2,,1,-2))=1)))))
As per some of the solutions in the link you posted, a more concise solution will almost certainly be available if we employ a pair of offset ranges (for example, A1:A7 and A2:A8), though personally I try to avoid such referencing (imagine replacing the range A1:A8 with a Structured Table column reference, for example - generating the equivalents of A1:A7 and A2:A8 would then be cumbersome).
Related
To simplify the screening of candidates for a college program, we created an Excel sheet compiling information provided by candidates.
They had to select one or more academic achievements from a droplist (some have none, some have 25).
The result in the Excel file is a cell for each student/row where the achievements are separated by line breaks.
We have a table where each of the possible achievement is worth a certain number of points.
For instance, a master's degree is worth 4, a published article is worth 2, etc.
We want to add a column that states the number of points a candidate has based on the cell that contains one or more achievements.
How can we do that with Excel?
Thank you!
Table with weighted value of achievement
Desired result
Ideally, some students have multiple occurrences of an achievement and we would want to take it into account (for instance, published two articles = 6 points) but that's a nice-to-have.
As of now, I have tried:
Combining SUM and VLOOKUP function, but I can only seem to recognize one value per cell
Experimenting with the SUMIF function, but that did not seem to work for me
Experimenting with nested conditions
Adapting solutions that require multiple criteria in multiple cell (for instance, return price if the row contains dress and blue, but none seem to apply for the situation when there are multiple strings in a single cell.
VLOOKUP works but you have use an array for lookup_value consisting of each achievement. Since the achievements are from a drop-down, we can assume they are spelled correctly.
We can use FILTERXML to split the entry by the line-feeds into an array of separate nodes, and then use that to find the appropriate values.
FILTERXML is in Windows Excel 2013+ but not available in Excel for MAC or online. If necessary, I can supply a different function to do the splitting.
For example:
=SUM(VLOOKUP( FILTERXML("<t><s>"& SUBSTITUTE(E2,CHAR(10),"</s><s>") & "</s></t>","//s"),AchieveTbl,2,FALSE))
AchieveTbl
Results
Alternatively you could use =SUM((LEN(SUBSTITUTE(E2,$A$2:$A$8,$A$2:$A$8&"_"))-LEN(E2))*$B$2:$B$8)
This is based on an answer here
I have a large table of 12 digit numbers and associated info
I have a small list of 10 and 11 digit numbers (the first and/or last digits were cut off) - I'm attempting to cross these two lists to identify the items on the small list
normally, I'd use an index match to bring the associated info out of the table into the list, but because today I have only partial numbers in my list, I can't get the formula to work
I've seen other examples here that search for partial text strings contained within a range, but I haven't been able to adapt those formulas to my data. wildcards don't seem to work with numbers.
Many thanks for your input, and apologies in advance if I failed to find an existing solution on the site.
To match partial numbers inside a number range, like you do with strings, you can use an array formula with INDEX/MATCH, by composing a temporary array that converts the numbers into strings.
Say column A is your 12 digit numbers column, and you want to match the sequence 1234567890 and retrieve the value from column B, This CSE formula works:
=INDEX($B$2:$B$9999, MATCH("*1234567890*",""&$A$2:$A$9999,0))
CtrlShiftEnter
Although you can use full columns A:A and B:B, this should be avoided as much as possible with array formulas, because they're slow. Full columns mean computing and operating arrays of more than a million entries, so avoid it. Also note the "expensive" conversion from numbers to strings (all numbers in the $A$2:$A$9999 are converted to strings here).
To use a cell reference, say D2, instead of the harcoded 1234567890, the formula should be used like this:
=INDEX($B$2:$B$9999,MATCH("*"&D2&"*",""&$A$2:$A$9999,0))
I have a cell which needs to sum together 3 different values, but I don't want to use relative/absolute cell references because the source data changes every year so the cell references would need re-pointing every year.
I've used VLOOKUPs for cells which only need to show 1 value and that's all fine, but I cannot find a way to add together the outcomes of 2 or more VLOOKUPs. Also, each of the 3 values have different criteria, and I think I therefore need 3 separate VLOOKUP functions.
Is there a way of doing this?
This is the formula I've used, which returns a '#N/A' error:
=vlookup("10000",datatable,3,false)+vlookup("10001",datatable,3,false)+vlookup("10002"),datatable,3,false)+...etc etc etc.
Many thanks in advance
Rob
Here is a simple example of summing 3 VLOOKUPs:
=SUM(VLOOKUP("A",A1:B3,2,FALSE),VLOOKUP("E",A5:B7,2,FALSE),VLOOKUP("I",A9:B11,2,FALSE))
I put 3 simple tables, each 3 rows and 2 columns, and added the lookup values together. So I look up A and return 1, E and return 5, I and return 9. Then I sum them and return 15. :-)
Providing the only part to vary is the lookup_value (as appears to be so in your case) then, instead of writing multiple distinct VLOOKUP clauses followed by summing them (which could result in an extremely long construction indeed), you can use a single, equivalent VLOOKUP set-up.
So instead of, for example:
=VLOOKUP("X",DataTable,3,FALSE)+VLOOKUP("Y",DataTable,3,FALSE)+VLOOKUP("Z",DataTable,3,FALSE)
we can use the shorter:
=SUM(VLOOKUP(T(IF(1,{"X","Y","Z"})),DataTable,3,FALSE))
or, for more flexibility, if we have "X", "Y" and "Z" within a contiguous range somewhere within the worksheet, e.g. H1:H3, then:
=SUM(VLOOKUP(T(IF({1},H1:H3)),DataTable,3,FALSE))
If the criteria are not text strings, but numerics, then we can use N instead of T: for example, if we were looking for, not "X", "Y" and "Z", but 1, 2 and 3, then we would use:
=SUM(VLOOKUP(N(IF(1,{1,2,3})),DataTable,3,FALSE))
or:
=SUM(VLOOKUP(N(IF({1},H1:H3)),DataTable,3,FALSE))
If our criteria comprise a mixture of text and numerics, e.g. "X", 2 and "Z", then we need a slightly different approach, though I will leave that to another post!
References:
https://excelxor.com/2014/09/05/index-returning-an-array-of-values/
Regards
Good heavens. Stop using VLOOKUP, everyone. INDEXtogether with MATCH is cleaner, neater and less prone to errors.
Now, for what you are doing, you don't need either. Why not check out SUMIFS
In your case it would look something like this
=SUMIFS(Sumcolumn;Criteriacolumn;10000;Criteriacolumn2;10001,...)
And, even if your sumcolumns are different from each other - it is still easier to sum several sumifs than it is to sum several vlookups, since vlookup will throw a #N/A if empty reference, whereas sumifs will return 0. If you have a desire to be extra efficient with just one formula, use SUMPRODUCT - however that is a formula that needs some practice to write.
On the illustration all formulas are array. The range that each formula spans is bordered, and the first formula on each block is written on the top of that block.
Range A4:A103 is an input vector (which is numeric), range C4:G23 is a given (input) permutation of the rows of A4:A103 (necessarily positive non-zero integer numbers not greater then the length of the input vector).
Let us I interpret the permutation matrix as set of rows.
How to compute for each row in a constant number of cells the minimal number in the input vector? By the constant number of cells, I mean solution, that would require fixed number of cells for each row, regardless of the number of columns in permutation. (In the production case each dimension is much, much bigger; there is about 100 columns in the permutation matrix.)
I don't ask for VBA solutions. If it is necessary the solution can use a free and publicly available Excel add-on, like MoreFunc, but I'd prefer to keep it vanilla Excel 2007 or later.
I thought that the formula {=MIN(INDEX(INDIRECT($A$2);$C4:$G4))} would solve my problem. Surprisingly, Excel seems to not take into account the array nature of the formula, and evaluates it as if it was written as =MIN(INDEX(INDIRECT($A$2);$C4) which is equivalent to dysfunctional =INDEX(INDIRECT($A$2);$C4).
On the other hand, we can see the argument to the MIN is understood as array in the range I4:M4.
INDEX works in some strange ways!
Normally INDEX can't return an array - although you seem to have found the one exception to that - when it's an array formula entered in a range.
You should be able to use OFFSET to return the required array that will work within MIN, i.e. with this formula
=MIN(N(OFFSET(INDIRECT($A$2);$C4:$G4-1;0)))
confirmed with CTRL+SHIFT+ENTER
(A) SumProduct( A1:A3,B1:B3) == A1*B1 + A2*B2 + A3*B3
Instead, what I'm after is
(B) SumProduct( A1:A3, Reverse(B1:B3)) == A1*B3 + A2*B2 + A3*B1
Is there a clean way to achieve this in excel 2003 / excel 2007 ? The natural ordering of these values is A1->A3 and B1->B3, so reversing the meanings of the cells is unsatisfactory; but creating a reversed copy of B1:B3 elsewhere in the worksheet seems clumsy.
Check the topic "Transposing A List Of Data" in http://www.cpearson.com/EXCEL/lists.htm
I chanced upon this question because I was trying to find an answer to this very question, in particular a solution to be used with SUMPRODUCT.
Previous post with link was useful, and the following has been devised. Please, note that for simplicity and clarity original references have been changed to make spreadsheet formulas easier to understand. Necessary changes can be achieved by using INDIRECT and R1C1 reference style if reversal needs to be applied to columns (INDIRECT, COLUMN and COLUMNS function documentation would prove useful).
In Excel (checked in Excel 2010), the formula that SUMPRODUCTs an array in A6:A8 with the reversal of the array in B6:B8 (let's say B8:B6) could be
=SUMPRODUCT(A6:A8,N(OFFSET(B6:B8,ROWS(B6:B8)-ROW(INDIRECT("A1:A"& ROWS(B6:B8))),0)))
The reversing part for Excel is N(OFFSET(B6:B8,ROWS(B6:B8)-ROW(INDIRECT("A1:A"& ROWS(B6:B8))),0)), it can also be used as a multi-cell array formula (ctrl-shift-enter) anywhere - the array to be reversed is in B6:B8.
Brief explanation: N() is necessary to convert the references returned by OFFSET into an array of values that can be used inside SUMPRODUCT. (OFFSET without N() render the formula inoperative within SUMPRODUCT, and it converts most non numbers into 0, as expected it converts TRUE to 1.)
OFFSET takes the array on the spreadsheet and puts the values in reverse order. (In this case, offset original at 3-1=2 goes new array position 0, 3-2=1 goes to 1, and finally 3-3=0 goes to 2.) ROW() function creates an array of consecutive numbers that can be subtracted from the length of the total array [please note, no final S, and A1:A3 has been used to obtain {1,2,...}, up to the number of rows in the original array/range.]
This formula does NOT work in OpenOffice/LibreOffice spreadsheet application. But INDEX can with an analogue approach becoming even more flexible.
OpenOffice/LibreOffice can use the same approach but with the INDEX function. OpenOffice/LibreOffice solution does not work in Excel as Excel does not accept arrays in INDEX's row_num/col_num (any array as argument there becomes the single top element of the array).
In OpenOffice/LibreOffice (checked in Apache OpenOffice 4), the formula that SUMPRODUCTs an array in A6:A8 with the reversal of the array in B6:B8 could be
=SUMPRODUCT(A6:A8,INDEX(B6:B8,1+ROWS(B6:B8)-ROW(INDIRECT("A1:A"& ROWS(B6:B8))),0))
The reversing part for OpenOffice is INDEX(B6:B8,1+ROWS(B6:B8)-ROW(INDIRECT("A1:A"& ROWS(B6:B8))),0), it can also be used as a multi-cell array formula (ctrl-shift-enter) anywhere - the array to be reversed is in B6:B8.
Excel version with this approach (thanks, XOR LX: see here) which might be very useful as INDEX can take arrays whereas OFFSET can only take references to a worksheet:
=SUMPRODUCT(A6:A8,INDEX(B6:B8,N(INDEX(1+ROWS(B6:B8)-ROW(INDIRECT("A1:A"& ROWS(B6:B8))),,)),0))
[As it happens with Excel's OFFSET version above, the formula with the N(INDEX([...],,)) modification does not work in OpenOffice, the wrapping function must be taken out if using that application.]
The approach is analogue to the one used in Excel for OFFSET. Take into account that INDEX uses indexes starting with 1 whereas OFFSET starts with 0. As it happens with the previous case, an array is dynamically created from the row numbers in A1:A3 to be used as both template for the array and position change index.
This very late answer is unlikely to help the original poster, but it might save time to future users with a similar question.
I cannot see a solution that doesn't involve (a) custom functions in VBA (or similar) or (b) an extra column with partial results.
If you don't like column C becoming a (hidden) reverse list, would you accept column C becoming a list like: A1*B3, A2*B2, A3*B1, which could then be summed? It would be possible to use a similar formula to the one mentioned in #e.tadeu's answer to obtain this (using OFFET and ROW functions.)