Concatenate cells within Excel row based off variable start and end columns - excel

I have a dataset which looks like the following:
A
B
C
D
E
1
4
5
2
3
6
1
3
I need to create a column which concatenates the cells in each row from the first cell with a value, to the last cell with a value, even if there are blanks in the middle. These need to be separated by a semi-colon. So the output for the first row would be 1; ;4;5. Second row would be 2;3; ;6. Third row would be 1; ; ; ;3.
As it stands I have managed to add a couple of formulas which identify the start and end column references within the range for each row (i.e. first row starts column 1, ends column 4).
The formula for finding first non-blank cell ref in row:
={MATCH(FALSE(ISBLANK(H6:AB6),0)}
The formula for finding last non-blank cell ref in row:
=AGGREGATE(14,6,(COLUMN(H6:AB6)-COLUMN(H6+1)/(H6:AB6<>""),1)
I am struggling with how to get the formula to use the starting column number for that row and pull back subsequent cell values with the ; separator until it gets to and includes the last column reference number.

A FILTERXML() alternative:
Formula in G1:
=TEXTJOIN(";",0,IFERROR(FILTERXML("<t><s>"&TEXTJOIN("</s><s>",0,A1:E1)&"</s></t>","//s[.!='' or (following::*!='' and preceding::*!='')]"),""))

Use in J1 or Any of your Required Cell
=IF(AND(A1="",B1="",C1="",D1="",E1=""),"",CONCATENATE(A1,IF(AND(B1="",C1="",D1="",E1=""),".",IF(A1="",""," ;")),B1,IF(AND(C1="",D1="",E1=""),IF(AND(B1="",C1="",D1="",E1=""),"","."),IF(AND(A1="",B1=""),""," ;")),C1,IF(AND(D1="",E1=""),IF(AND(C1="",D1="",E1=""),"","."),IF(AND(A1="",B1="",C1=""),""," ;")),D1,IF(E1="",IF(AND(D1="",E1=""),"","."),IF(AND(A1="",B1="",C1="",D1=""),""," ;")),E1,IF(E1="","",IF(E1="","","."))))
Hope Thats what you actually want.

Just to answer the part of your question that asks about how to use the column number of first and last non-blank cell to get the result without leading and trailing semicolons, your formula would look like this:
=TEXTJOIN(";",0,INDEX(1:1,MATCH(FALSE,ISBLANK(A1:E1),0)):INDEX(1:1,AGGREGATE(14,6,(COLUMN(A1:E1)-COLUMN(A1)+1)/(A1:E1<>""),1)))
or shorter:
=TEXTJOIN(";",0,INDEX(1:1,MATCH(FALSE,ISBLANK(A1:E1),0)):INDEX(1:1,LOOKUP(2,1/(A1:E1<>""),COLUMN(A1:E1))))
The only advantage of using aggregate is that you don't need to array-enter it in earlier versions of Excel, but you don't need to array-enter the lookup formula either so I would tend to use that (and anyway in this case you probably need to array-enter the whole formula pre Excel-365).
This isn't too bad, but unfortunately if you wanted to make blanks into zeroes you would have to repeat most of the formula, unless you have Excel 365 and can use Let:
=TEXTJOIN(";",0,IF(INDEX(1:1,MATCH(FALSE,ISBLANK(A1:E1),0)):INDEX(1:1,LOOKUP(2,1/(A1:E1<>""),COLUMN(A1:E1)))="",0,
INDEX(1:1,MATCH(FALSE,ISBLANK(A1:E1),0)):INDEX(1:1,LOOKUP(2,1/(A1:E1<>""),COLUMN(A1:E1))) ))
If you have Excel 365, you can search from the end of the array using Xmatch:
=TEXTJOIN(";",0,INDEX(1:1,XMATCH(TRUE,A1:E1<>"")):INDEX(1:1,XMATCH(TRUE,A1:E1<>"",0,-1)))

Related

Excel Auto number row based on criteria

I'm trying to create a spreadsheet in excel which creates a sequential number in a column (B) depending on the contents of another column. Currently, there are two possibilities of what could be in Column A ("BI" or "GF"). So I want the data to look like this
COL A COLB
BI 1
BI 2
GF 1
BI 3
GF 2
GF 3
BI 4
BI 5
I've tried several attempts to do this but can't seem to find a solution. Any help would be greatly appreciated.
In B2, try this formula:
=CountIf(A$2:A2,A2)
Try to use the offset equation.
The first cell in COL B will look similar to this:
=COUNTIFS(OFFSET(A$1$1:A1,0,0),A1)
The second should look like this:
=COUNTIFS(OFFSET(A$1$1:A2,0,0),A2)
Drag this down in Col B as far as desired. If you are using a table this should autofill.
Explanation:
Essentially you are using the OFFSET formula to create a dynamic range.
The A$1$ serves as the start of your range by making this an absolute reference and the A1 will serve as the end of your range.
By making the ending cell a relative reference, the array the COUNTIFS function search will never go beyond the row the of the cell the formula is relative of.
In your example, the formula in the first row in Col B would result in 1. The reason is the OFFSET returns the array of A$1$:A1 and the COUNTIFS searches through that array and returns a count of all cells equal to A1 which is "BI".
The second row retains the original starting cell for the array of A$1$ however the end of the array is A2. So the COUNTIFS function sees the new array to search through to be A$1$:A2. The COUNTIFS then searchs through each cell equal to A2 which like A1 is "BI". There are two cells equal to "BI" in the new array and thus the reult is 2.
How this works like you want is displayed in the third row of Col B.
The OFFSET functions simply expands the array size to A$1$:A3. The COUNTIFS will work as it normally does, it takes the array, called the criteriarange in Excel, and performs a count for all items that equal A3. A3 in this case is equal to "GF" and in the array A$1$:A3 there are two cells equal to "BF" and one equal to "GF".
Hope this helps!

Count number of blank cells in row between last cell and next non-blank cell

Is it possible (with a formula preferably) to count the number of blank cells in row, where the counting starts at a given column and counts going backward (e.g. right to left) the number of blank cells until a non-blank cell is found? In the example below, the counting begins at Column H and proceeds leftward. Using COUNTA or COUNTIF seem like reasonable tools to use, but I am unsure on how to terminate the counting once a non-blank cell is found.
You can use something like this if the values in your table are all text:
=COUNTBLANK(INDIRECT(CHAR(97+MATCH("zzzz",B2:H2))&ROW()&":H"&ROW()))
MATCH("zzzz",B2:H2) returns the column number in which the last non-blank cell is.
CHAR(97+ column number) returns the letter of that column.
Append it to the row number to give the reference where the COUNTBLANK has to start with &ROW()
&":H"&ROW()) gives the reference of the last cell, which is H plus the row number.
INDIRECT turns the concatenated text into a range that Excel can evaluate.
Try this formula
=COLUMNS(B2:H2)-MATCH("zzzz",B2:H2)
You could use nested if statements
=IF(ISBLANK(H2),IF(ISBLANK(G2),IF(ISBLANK(F2),IF(ISBLANK(E2),IF(ISBLANK(D2),IF(ISBLANK(C2),IF(ISBLANK(B2),IF(ISBLANK(A2),8,7),6),5),4),3),2),1),0)

Excel: Find intersection of a row and a column

My question is how can I find an intersecting cell of a specific column and row number?
My situation is this: with some calculations I find two cells, lets say B6 and E1. I know that I need a row of the first one and a column of the second one. So I could just use ROW and COLUMN functions to get the numbers. After that, I need to find an intersecting cell. Which would be E6 in this example.
I would just use INDEX(A1:Z100;ROW;COLUMN) but I don't know the exact area that I'm going to need - it depends on other stuff. I could use something like A1:XFG65000 but that is way too lame. I could also use a combination of INDIRECT(ADDRESS()) but I'm pulling data from a closed workbook so INDIRECT will not work.
If this would help to know what is this all for - here's a concrete example:
I need to find limits of a section of a sheet that I would work with. I know that it starts from the column B and goes all the way down to the last non-empty cell in this column. This range ends with a last column that has any value in first row. So to define it - I need to find the intersection of this last column and the last row with values in B column.
I use this array formula to find the last column:
INDEX(1:1;MAX((1:1<>"")*(COLUMN(1:1))))
And this array formula to find the last row:
INDEX(B:B;MAX((B:B<>"")*(ROW(B:B)))
Last column results in E1 and last row results in B6. Now I need to define my range as B1:E6, how can I get E6 out of this all to put into the resulting formula? I've been thinking for a while now and not being and Excel expert - I couldn't come up with anything. So any help would really be appreciated. Thanks!
You can use an Index/Match combination and use the Match to find the relevant cell. Use one Match() for the row and one Match() for the column.
The index/match function to find the last cell in a sheet where
column B is the leftmost table column
row 1 is the topmost table row
data in column B and in row 1 can be a mix of text and numbers
there can be empty cells in column B and row 1
the last populated cell in column B marks the last row of the table
the last populated cell in row 1 marks the last column of the table
With these premises, the following will return correct results, used in a Sum() with A1 as the starting cell and Index to return the lower right cell of the range:
=SUM(A1:INDEX(1:1048576,MAX(IFERROR(MATCH(99^99,B:B,1),0),IFERROR(MATCH("zzzz",B:B,1),0)),MAX(IFERROR(MATCH(99^99,1:1,1),0),IFERROR(MATCH("zzzz",1:1,1),0))))
Since you seem to be on a system with the semicolon as the list delimiter, here is the formula with semicolons:
=SUM(A1:INDEX(1:1048576;MAX(IFERROR(MATCH(99^99;B:B;1);0);IFERROR(MATCH("zzzz";B:B;1);0));MAX(IFERROR(MATCH(99^99;1:1;1);0);IFERROR(MATCH("zzzz";1:1;1);0))))
Offset would seem to be the way to go
=OFFSET($A$1,ROW(CELL1)-1,COLUMN(CELL2)-1)
(The -1 is needed because we already have 1 column and 1 row in A1)
in your example, =OFFSET($A$1,ROW(B6)-1,COLUMN(E1)-1) would give the value in E6
There is also ADDRESSS if you want the location: =ADDRESS(ROW(B6),COLUMN(E1)) gives the answer $E$6
The following webpage has a much easier solution, and it seems to work.
https://trumpexcel.com/intersect-operator-in-excel/
For example, in a cell, type simply: =C:C 6:6. Be sure to include one space between the column designation and the row designation. The result in your cell will be the value of cell C6. Of course, you can use more limited ranges, such as =C2:C13 B5:D5 (as shown on the webpage).
As I was searching for the answer to the same basic question, it astounded me that there is no INTERSECT worksheet function in Excel. There is an INTERSECT feature in VBA (I think), but not a worksheet function.
Anyway, the simple spacing method shown above seems to work, at least in straightforward cases.

Check the number of unique cells in a range

I have an excel sheet.
Under column E, I have 425 cells with data. I want to check if the same data (i.e. text inside the cell) is repeated anywhere else in any of the remaining 424 cells under column E. How do I do this?
For example, in E54 I have
Hello Jack
How would I check this value to see if it was in any other of these cells?
You could use
=SUMPRODUCT(1/COUNTIF(E1:E425,E1:E425))
to count the number of unique cells in E1:425
An answer of 425 means all the values are unique.
An answer of 421 means 4 values are duplicates of other value(s)
Use Conditional Formatting on all the cells that will highlight based on this formula:
COUNTIF(E:E,E1) <> 1
This is based on the column being E, and starting on E1, modify otherwise.
In Excel 2010 it's even easier, just go into Conditional Formatting and choose
Format only unique or duplicate values
If you have to compensate for blank cells, take the formula supplied above by #brettdj and,
Adjust the numerator of your count unique to check for non-blanks.
Add a zero-length string to the COUNTIFS's criteria arguement.
=SUMPRODUCT((E1:E425<>"")/COUNTIF(E1:E425,E1:E425&""))
Checking for non-blank cells in the numerator means that any blank cell will return a zero. Any fraction with a zero in its numerator will be zero no matter what the denominator is. The empty string appended to the criteria portion of the COUNTIF is sufficient to avoid #DIV/0! errors.
More information at Count Unique with SUMPRODUCT() Breakdown.
This formula outputs "unique" or "duplicates" depending if the column values are all unique or not:
{=IF(
SUM(IF(ISBLANK(E1:E425),0,ROW(E1:E425)))
=
SUM(IF(ISBLANK(E1:E425),0,MATCH(E1:E425,E1:E425,0)))
,"unique","duplicates")}
This is an array formula. You don't type the enclosing {} explicitly. Instead you enter the formula without {} and then press cmd-enter (or something else if not a Mac - go look it up!) If you want to split your formula over multiples lines for readability, use cmd-ctrl-return on a Mac.
The formula works by comparing two SUM() results. If they are equal, all the nonblank entries (numeric or text) are unique. If they are not equal there are some duplicates. The formula does not tell you where the duplicates are.
The first sum is what you get by adding up the row numbers of every non-blank entry.
The second sum does a lookup of each nonblank entry using MATCH(). If all entries are unique, MATCH() finds each entry at its own position, and the result is the same as the first sum. But if there are duplicate entries then a later duplicate will match an earlier duplicate and the later duplicate will contribute a different value to the sum, and the sums won't match.
You might have to adjust this formula:
if you want cells containing "" to count as blank, then use LEN(...)=0 for ISBLANK(...). I suppose you could put other tests in there if you wanted, but I have not tried that.
if you want to test an array not starting at row 1, then you should subtract a constant from ROW(...).
if you have a huge column of cells, you might get integer overflow when computing this sum. I don't have a solution to that.
It's a shame that Excel does not have an ISUNIQUE() function!
This may be a simpler solution. Assume column A contains data in question. Sort on that column. Then, starting in B2 (or first non-blank cell, use the following formula:
=IF(A2=A1,1,0).
Than sum on that column. When sum = 0, all values are unique.
highlight E and on the home tab select conditional formatting > Highlight Cell Rules > Duplicate Values...
It will then highlight everything that is repeated.

How to use IF and SUM in excel to count unique entries in a row?

Basically I have a large set of data in excel, and I was wondering how to count across a row how many cells are not #N/A?? I think it should be possible with IF and SUM but I'm not entirely certain.
To count all values except blanks and #N/A errors try COUNTIFS like this for data in row 2
=COUNTIFS(2:2,"<>#N/A",2:2,"<>")
If you don't want to count duplicates then this version will give you a count of all different values (except blanks and errors)
=SUM(IF(1-ISERROR(2:2),(2:2<>"")/COUNTIF(2:2,2:2&"")))
that's an "array formula" that needs to be confirmed with CTRL+SHIFT+ENTER
Note that the first formula uses COUNTIFS function and therefore will not work in versions of excel before 2007 - this is an alternative that will work in those versions
=COUNTA(2:2)-COUNTIF(2:2,"#N/A")
Try using =COUNTIF(RANGE, VALUE), here's an example that will count the numer
=COUNTIF(A:A, "Yes")
or
=COUNTIF(A1:D16, "Yes")
To count the cells that contain a value (I.E., are not empty) then use `=COUNTA(A:A)
When you want to "mark" the duplicates, use this in an empty column:
=COUNTIF($A$2:$A2,A2)>1
Puth the formula is row 2 and copy this all the way down to the last used row.
(What I usually do: Somewhere in column A, press [Ctrl]+[Down], to jump to the last item, then move sideways to the column where you want to put your formula in and put something e.g. an "X". Then jump all the way up [Ctrl]+[Up], put the formula in row 2, copy it and press [Shift]+[Ctrl]+[Down] to mark the wole range in this column from row 2 to the last used row, and press [Enter] to paste your formula.)
In this formula, the search area increases, the further you copy this down.
So this first time a duplicate item is found, the value will be 1 (i.e. false) the second, third or more times this duplicate item is found, the value will be greater than 1 and give a value of true.

Resources