Conditional concatenate cell content across rows

6

I have a worksheet with thousands of rows which contain a unique ID A, and one 3 different error codes M. Each individual ID may have 1, 2 or 3 errors. They will always be in the same order.

I have typed by hand and in N what the desired output is. I have written a formula like this one in cols O, P, Q with the text of the error:

=IF(IFERROR(SEARCH("Brand is not valid", M42), "") <> "", "Brand", "")

I tried something like this in R but it's not working correctly for obvious reasons. Is there a way to do this so that R looks like N?

=CONCATENATE(O42,"/", P42,"/",Q42)

If not possible to do with Excel formula, is there perhaps a VBA way?

concat

Phrancis

Posted 2015-06-02T17:26:29.433

Reputation: 165

Will there always be 3 entries per unique ID, or up to 3 entries? – FreeMan – 2015-06-02T17:37:26.430

Your CONCATENATE formula is working properly, there just isn't any data in the other cells of the row (P42 & Q42 are blank) to give the desired results. – CharlieRB – 2015-06-02T17:43:48.217

@FreeMan there can be 1, 2 or 3 errors per unique ID, with a random distribution – Phrancis – 2015-06-02T17:44:39.287

@CharlieRB right, I realize that. Can you think of a different way to do this perhaps? – Phrancis – 2015-06-02T17:45:16.303

Is there a way to get O, P, & OEM in the same column? Will they always be in that order; brand, product, OEM? Or could it be a different order? – CharlieRB – 2015-06-02T18:01:49.270

The order will always be the same - Brand, Product, OEM, however, it may not necessarily have a Brand to start with (for example rows 48-49 in screenshot), or even a Product (see row 41) – Phrancis – 2015-06-02T18:03:30.443

Answers

3

OK, took some head scratching, but I've got it:

Columns O, P & Q as you have them, titled Brand, Product & OEM. Turn the whole thing into a table with Ctrl-T (not required, but handy, and my column R relies on it, but you can use column references if you want)

Column R:

=IF(LEN([Brand])>0,[Brand],IF(LEN([Product])>0,[Product],IF(LEN([OEM])>0,[OEM],"")))

Column S:

=IF(A2=A4,F2&"/"&F3&"/"&F4,IF(A2=A1,"",IF(A2=A3,F2&"/"&F3,F2)))

Unfortunately, it seems the only way to use table references to a different row is to use Offset, so to keep it simpler, I went back to cell references. That kinda negates the cool/handy factor of turning the whole thing into a table in the first place, but, whatever...

And... Here's a picture of what it looks like:

enter image description here

FreeMan

Posted 2015-06-02T17:26:29.433

Reputation: 241

3Wow... I got an Are you a bot? CAPCHA to fill out after submitting that. Weird... – FreeMan – 2015-06-02T18:39:17.293

3Now that I think about it, if we have bots producing answers like this, I say "Bring 'em on!" – FreeMan – 2015-06-02T19:29:33.117

1that solution works beautifully, thank you so much! – Phrancis – 2015-06-02T19:37:36.893

3

I would start by optimizing your O, P, and Q formulas.  You currently have

=IF(IFERROR(SEARCH("Brand is not valid", M42), "") <> "", "Brand", "")

IFERROR is a great function for displaying a sanitized version of a computed value that might be an error code; I use it, and recommend it in answers on Super User, frequently.  As you probably know,

  • IFERROR(calculated_value, default_value)

is short for

  • IF(ISERROR(calculated_value), default_value, calculated_value)

But using IFERROR to create a sanitized version of some value and then testing that value to do something conditionally is an unnecessarily awkward way of using IFERROR.  The above formula can be simplified to

=IF(ISERROR(SEARCH("Brand is not valid", M42)), "", "Brand")

And, as I’m sure you know, SEARCH("Brand is not valid", M42) tests to see whether M42 contains Brand is not valid.  But, as long as Column M can contain only your three error strings, this can be shortened to

=IF(ISERROR(SEARCH("Brand", M42)), "", "Brand")

or simplified to

=IF(M42 = "Brand is not valid", "Brand", "")

OK, now I’ll make the O, P, and Q formulas a little more complicated:

  • O42=IF($A42=$A41, O41, "") & IF(ISERROR(SEARCH("Brand", $M42)), "", "Brand")
  • P42=IF($A42=$A41, P41, "") & IF(ISERROR(SEARCH("Product", $M42)), "", "Product")
  • Q42=IF($A42=$A41, Q41, "") & IF(ISERROR(SEARCH("OEM", $M42)), "", "OEM")

The formula for O42 says,

If this is the second or third row for this ID (Column A), look at the cell above this one (i.e., the Column O cell for the previous row) to see whether we’ve already established that this thing has an invalid brand.  Also, look at Column M for this row to see whether it is Brand is not valid.  Then concatenate the results.

Since a unique ID will never be listed twice with the same error (right?), these two sub-results will never both be non-empty, so this is essentially doing an “OR”:

Show a value of Brand if this row, OR one of the previous row(s) for this ID, contains the invalid brand error.

This has the effect or dragging the O, P, and Q values down to the last row for each ID:

Note that rows 41, 44, 47, and 49 each shows the short forms of all errors that apply to their respective IDs in Columns O, P, and Q.

I’ve defined Column R the same way you did.  See Generate a comma-separated list of cell contents, excluding blanks for techniques to eliminate the unwanted slashes from this.

If having the desired concatenation only in rows 41, 44, 47, and 49 is good enough, you’re done.  Otherwise, define N42 as

=IF($A22=$A23, N23, R22)

or

=IF($A22<>$A23, R22, N23)

This is almost exactly the same trick I used in Columns O, P, and Q, but going in the opposite direction:

If this is the last row for this ID (i.e., if this is row 41, 44, 47, or 49), use the concatenation of the values from this row (which is the complete collection of error codes for this ID).  Otherwise, look at the cell below this one (i.e., the Column N cell for the next row), which will have the correct answer.

In other words, the desired values percolate up to the first row for each ID.

Scott

Posted 2015-06-02T17:26:29.433

Reputation: 17 653

1Very nice, I learned something today! – FreeMan – 2015-06-03T17:36:58.263

1@Scott that's a great answer! Have you considered checking out the Code Review site? This kind of answer would definitely shine through there! – Phrancis – 2015-06-03T18:04:40.027

@FreeMan: I'm glad to help you learn something.  If you want more interesting information on Excel, search Super User for [microsoft-excel], [worksheet-function], and, if you're so inclined, [vba].  Of course, a lot of what you find will be dull and boring; some will be enigmatic and unexplained; and some will be outright wrong.  You may get best results by focusing on answers written by these people.

– Scott – 2015-06-04T21:20:00.263