Hi;
I have a sheet which has 4 columns ;
Column A and C have product numbers
Column B and D are for detail of the products.
What i'm trying to do is ; If a number in column A match with a number in column C then i want to take the value (product details) of B to column E. but if the number repeats then at second row and match again with that number in column C then i want to that the new value to column F.
It's a really particular problem for us. We are trying to create a new sql database for our new web page and we have to convert all data like this.
I tried it with =vlookup formula in Excel but it didn't work. i think this problem can solve only with macros. (If i'm not wrong...)
PS_ Please check the image, it's even hard to explain in my mother language.
Thanks
If you have less than 2000-3000 rows of data, this can be accomplished with some array formulas. If you have much more than that, a VBA solution would be better suited. These array formulas eat up calculation load exponentially as the ranges they refer to grow larger. At some point it simply isn't worth waiting for and a VBA solution would be better.
The array formula in F2 is,
=IF(LEN(F1), IFERROR(INDEX(A$1:A$999, MATCH(0, IF(LEN(A$1:A$999), COUNTIF(F$1:F1, A$1:A$999&""), 1), 0)), IFERROR(INDEX(C$1:C$999, MATCH(0, IF(LEN(C$1:C$999), COUNTIF(F$1:F1, C$1:C$999&""), 1), 0)), "")), "")
Note that this requires a header column label in F1. It cannot be put into F1. Array formulas need to be finalized with Ctrl+Shift+Enter↵. Once entered correctly, fill down to pick up a unique list of all the part numbers from columns A and C.
The array formula in G2 is,
=IF(LEN($F2), IFERROR(INDEX($B$1:$B$999, MATCH(0, IF($A$1:$A$999=$F2, COUNTIF($F2:F2, $B$1:$B$999&""), 1), 0)), IFERROR(INDEX($D$1:$D$999, MATCH(0, IF($C$1:$C$999=$F2, COUNTIF($F2:F2, $D$1:$D$999&""), 1), 0)), "")), "")
This also requires finalizing with Ctrl+Shift+Enter↵. Once entered correctly, fill right several columns and then fill all of the formula down to match the entries retrieved in column F.
I've left those formulas to cover 999 rows. You may need to adjust those upwards if your needs exceed that range. A search for $999 and replace with $1999 can quickly accomplish that.
That is all there is to it. Make sure you leave a few rows at the bottom in case another file has more rows and a few columns to the right for teh same reason.
If the order is not critical, a possible alternative with formulae only would be to append the second two columns to the first two (in a copy), add a blank Row1 and in ColumnC:
=IF(COLUMN()<=COUNTIF($A:$A,$A2)+2,INDIRECT("$B"&(COLUMN()-3+ROW())),"")
copied across and down to suit and in another column:
=A1=A2
copied down to suit. Hide ColumnB and filter the other column to select FALSE. Select Row2 to end and Paste Special, Values into F1 of original sheet.
Related
In Excel 2016, I have a "Brands" column, each of its rows containing a string. The set of possible string values is limited, and they may appear more than once.
There is related data in another column, "Models". Each model value is always different.
How can I get Excel to generate a column for each existing brand and populate it with the corresponding Models in an automatic way?
My problem is that I can't do it manually because for each analysis, the amount of Brands is different and I don't know it beforehand.
This would be the input:
And this is the expected output:
Any ideas?
Thank you in advance!
Try using an array formula. First, put the distinct brand values on row 1, starting in column D. You can use column C if you want, but I like to have an empty column between the data and the desired results.
D1 = Apple, E1 = Nokia, F1 = Samsung, G1 = Xiaomi
Then, just below Apple in cell D2, paste this formula:
=IFERROR(INDEX($B$2:$B$9999, SMALL(IF(D$1=$A$2:$A$9999, ROW($A$2:$A$9999)-ROW($A$2)+1), ROW(1:1))),"")
If you have more than 9999 rows, then adjust as needed in the formula.
With the cursor still in the formula, make it an array by simultaneously pressing CTRL-SHIFT-ENTER.
Copy the formula across to cells E2, F2 and G2. You may need to repeat the array trick (CTRL-SHIFT-ENTER) for each of those again if things look wrong. So, your excel will look like this:
Now, drag the formulas down as far as you need. The iferror part of the formula will ensure that cells look clean if no more models are found.
---EDIT AFTER RECENT COMMENT---
I cannot determine how to automatically pick distinct values from column A and automatically convert them to a row. It's easy to keep it in a column, but the transpose to row is troubling.
At any rate, here's the ugly update. Cell D1 would simply state "Brands". In cell D2, make this an array formula (CTRL-SHIFT-ENTER).
=IFERROR(INDEX($A$2:$A$9, MATCH(0, COUNTIF($D$1:D1, $A$2:$A$9), 0)), "")
So, row 2 will be your brands. Drag the formula across, repeat the array trick.
Now, in cell E1, type formula =D2. Drag across.
Place the formula suggestion from the original answer, starting in row 3. End result looks like this below. It should be "automated" now, but it's not appealing. Minor edits will help (making row 1 nearly invisible, for example).
In large dataset - 250 rows and 1000 columns I need to compare each value in cell with each other in one column and iterate over all column. Heres simplified example of source data:
And this is what I need (formatting not necessary and 2 empty rows not necessary) - if match if found "1" is produced, if no match "2" is produced, if one or both were N/A - "3" is produced:
Comparison should only be "one sided" for example Terry and Joey is the same as Joey and Terry, thus further comparison of already compared pairs is not needed.
Is it possible to do this in Excel 2016 or are there better tools for this?
My thanks to all.
This alternative is a bit complex, but we all solve problems like this differently. If it helps you, please feel free to use it. If not, I can understand since some of these techniques are not particularly common and the resulting formula is a bit unreadable. I did it this way so that I would be able to organize the rows better and read the matching/unmatching indicators more easily. I started by creating a helper column rather than repeat the rows for each individual so that each row shows the two names being compared. This is the formula I used to compare using B8's information is:
=IF(OR(INDIRECT("R"&MATCH($I8,$A$1:$A$6,0)&"C"&COLUMN(),FALSE)="N/A",INDIRECT("R"&MATCH($A8,$A$1:$A$6,0)&"C"&COLUMN(),FALSE)="N/A"),3,IF(INDIRECT("R"&MATCH($I8,$A$1:$A$6,0)&"C"&COLUMN(),FALSE)<>INDIRECT("R"&MATCH($A8,$A$1:$A$6,0)&"C"&COLUMN(),FALSE),2,1))
I am going to try to explain the formula I used as follows:
Without using the helper column, the basic formula for cell B8 is this:
=IF(OR(B$2="N/A",B3="N/A"),3,IF(B$2<>B3,2,1))
and this would work for the range B8:H11. However, when I skip down to B13, the formula would need to change to:
=IF(OR(B$3="N/A",B4="N/A"),3,IF(B$3<>B4,2,1))
and this would work for the range B13:H15. Likewise B17, and B20 would be:
=IF(OR(B$4="N/A",B5="N/A"),3,IF(B$4<>B5,2,1))
=IF(OR(B$5="N/A",B6="N/A"),3,IF(B$5<>B6,2,1))
for their respective ranges. I shy away from formulas where I have to remember what I need to change for each section (heaven forbid I should write any notes or read them if I did).
In order to do this, I used the person column (A) and my helper column (I) to determine which rows to compare.
MATCH($I8,$A$1:$A$6,0)
gives the row of the person value in the Chart from A1:H6 in the comparison
MATCH($A8,$A$1:$A$6,0)
gives the row of the helper value in the Chart from A1:H6 in the comparison
Since the data being compared is always in the same column, I just use COLUMN() to determine which column to use.
In cell B8, MATCH($I8,$A$1:$A$6,0) will tell me it is row 2 and MATCH($A8,$A$1:$A$6,0) will tell me it is row 3. Thus, I want to use the values in Row 2, Column 2 compared against Row 3, Column 2.
To tell Excel to compare Row 2, Column 2 against Row 3, Column 2 is fairly simple, but creating a formula that you can copy from cell to cell without having to modify it each time is not as easy, since each section is a bit different and there could be blank rows in between sections. What I did was to use indirect cell notation using "R1C1" syntax rather than the more common "A1" cell referencing.
In other words in column B8 this:
INDIRECT("R"&MATCH($I8,$A$1:$A$6,0)&"C"&COLUMN(),FALSE)
gives the value in Row 2 (for Terry), Column 2 and
INDIRECT("R"&MATCH($A8,$A$1:$A$6,0)&"C"&COLUMN(),FALSE)
gives the value in Row 3 (for Joey), Column 2 and
In both of the above, I am concatenating and R and a C to the numbers returned by the MATCH() and COLUMN() functions and using the FALSE parameter to tell Excel to treat the concatenated result as "R1C1" notation. In other words, this:
OR(INDIRECT("R"&MATCH($I8,$A$1:$A$6,0)&"C"&COLUMN(),FALSE)="N/A",INDIRECT("R"&MATCH($A8,$A$1:$A$6,0)&"C"&COLUMN(),FALSE)="N/A")
translates to this:
OR(R2C2="N/A",R3C2="N/A")
I realize that the helper column is a burden you did not ask for and I realize that the formula is overly complicated, but I can freely copy this formula to any column that has the two names and it will do a comparison for that day of the week.
Here is a picture of what I am describing:
Added comments
Just to carry the above a bit further, suppose you had a Sheet1 which had the rows of data to be compared and suppose this were limited to 250 rows with the same 7 columns (rather than 1000). I could create another sheet similar to the above along with another helper cell (I put it in A1) to automatically populate the person column and the helper column like this:
New Helper Cell value: 1 (essentially saying to start at the top). This would populate Cell A2 with the following formula:
=IFERROR(IF(INDEX(Sheet1!$A$1:$A$250,NUMBERVALUE(RIGHT($A$1,3)+ROW()))=0,"",INDEX(Sheet1!$A$1:$A$250,NUMBERVALUE(RIGHT($A$1,3)+ROW()))),"")
Basically this is just this formula:
=INDEX(Sheet1!$A$1:$A$250,NUMBERVALUE(RIGHT($A$1,3)+ROW()))
but is checking first to see if it results in zero and then is replacing it with blanks if it is an error. Copying this cell down Column A will populate that column with the names starting at the first row after the data row specified by A. If you have more headings or other data you would need to add additional amountst to the +ROW() portion in both occurrences in the formula. Column I gets populated siimilarly with this:
=IF(A2="","",INDEX(Sheet1!$A$1:$A$250,NUMBERVALUE(LEFT($A$1,3)+1)))
However, this value does not vary from row to row.
Now that the helper columns are populated, you can populate the formula a bit differently from the above (which had used the same sheet) for example in B2:
=IF($A2="","",IF(OR(INDIRECT("Sheet1!R"&MATCH($I2,Sheet1!$A$1:$A$250,0)&"C"&COLUMN(),FALSE)="N/A",INDIRECT("Sheet1!R"&MATCH($A2,Sheet1!$A$1:$A$250,0)&"C"&COLUMN(),FALSE)="N/A"),3,IF(INDIRECT("Sheet1!R"&MATCH($I2,Sheet1!$A$1:$A$250,0)&"C"&COLUMN(),FALSE)<>INDIRECT("Sheet1!R"&MATCH($A2,Sheet1!$A$1:$A$250,0)&"C"&COLUMN(),FALSE),2,1)))
The main difference from the first formula is the off sheet references to "Sheet1" that were added and the extension of the formula to cover 250 rows.
Here is a picture with Cell A1 set to 1:
Here is a picture with Cell A1 set to 3:
Using this, your Sheet1 values remain where they are and you can create a generic comparison sheet to compare the values of various rows of Sheet1. These can be dynamically built by changing the value in A1 or you can create dozens of similar sheets, each differing by the value in A1.
Not sure if any of this makes sense.
Good Luck
Just use a function like this(exemple for cell B4):
=IF(B3=B2;1;IF(B3="N/A";3;2))
Print of it working
Do it for each line and just drag it from the begining to the end.
EDIT: You should do an or in the 2nd if to make surre neither is "N/A"
=IF(OR(B3="N/A";B2="N/A";3;IF(B3=B2);1;2))
I'm trying to create a formula in column K which sums all cells that apply , in column J, only when the following conditions are true:
dates are the same in column A
AND client name is the same in column B
For example, in cell K2, I want the sum of J2+J3+J4 because A2=A3=A4 and B2=B3=B4.
K5=J5 only, because there are no other dates with the same client name.
K6=J6+J7 because A6=A7 and B6=B7.
What kind of formula would I use for this? I can't figure out how to do it with a SUMIFS.
I would try using a pivot table with:
The names as row values
The dates as the column values
And funds received using SUM in the values column
Edit
Based on #pnuts comments here is how to get the values in column K. Put this in K2 and drag down.
=IF(OR(COUNTIFS($B$1:B3, B3) = 1, B3 = ""), SUMIFS($J$2:J2, $A$2:A2, A2, $B$2:B2, B2), "")
This formula will give blank values until the formula finds a new client on a new date. However, I still think using pivot table is a better solution.
However, I still find the pivot table
In cell K2 put following formula:
=IF(COUNTIFS($A$2:A2,A2,$B$2:B2,B2)=1,SUMIFS($J$2:$J$10,$A$2:$A$10,A2,$B$2:$B$10,B2),"")
Adjust row 10 value. It will be last row of your actual data.
Copy down as much you need.
EDIT
Uploaded file shows the cause behind formula not working correctly for you. It turned out to be whitespace characters in column B (names) data e.g.
Cell B3: "Moe John" has a trailing space.
Cell B10: Same case with "Doe Jane"
If you want to use above posted formula then all names shall be corrected. Or alternatively to deal with spaces you can adopt below approach.
=IF(COUNTIFS($A$2:A2,A2,$B$2:B2,"*"&TRIM(B2)&"*")=1,SUMIFS($J$2:$J$28,$A$2:$A$28,A2,$B$2:$B$28,B2),"")
Notice the change in COUNTIFS formula where B2 is now replaced with "*"&TRIM(B2)&"*".
Even such formula will take a beating if you have uneven whitespace characters in between your data. I'd suggest normalizing it as much as possible.
I am trying to add values in Column B based on data in Column A. Additionally I am looking to remove duplicates from Column A in a separate output on another sheet. Here is how the data looks:
Excel Screenshot
I've tried SUMIF and VLOOKUP based on some similar posts but neither have worked. I know I could use remove duplicates manually but would like to have a formula solution such that the data is automatically consolidated.
Thank you in advance.
You can do this using formula to avoid manual consolidation, try the below set of formulas
In the cell A2, enter the below formula
=IFERROR(INDEX($F$2:$F$7, MATCH(0, INDEX(COUNTIF($A$1:A1, $F$2:$F$7), 0, 0), 0)), "")
In the cell B2, enter the below formula
=if(A2="","",SUMIF($F$2:$F$7,A2,$G$2:$G$7))
The $F$2:$F$7 and $G$2:$G$7 references in the above formulas are the data. If it is from different sheet, then you may need to replace these accordingly.
Once you enter the same in A2 and B2, copy the same in rest of the rows, and you will get what you want.
How can I sort a table in sheet 1 like
A B C D E
3 7 3 6 5
into another table in sheet 2
A C E D B
3 3 5 6 7
by using function only?
One really easy way to do it would be to just have a rank index and then use HLOOKUP to find the corresponding values:
=RANK(A4,$A$4:$E$4,1)
=IF(COUNTIF($A$1:A$1,A1)>1,RANK(A4,$A$4:$E$4,1)+COUNTIF($A$1:A$1,A1)-1,RANK(A4,$A$4:$E$4,1))
=HLOOKUP(COLUMN(),$A$2:$E$4,2,FALSE)
=HLOOKUP(COLUMN(),$A$2:$E$4,3,FALSE)
Okay, here's the "one formula does it all" solution without additional temporary columns:
Formula in A6:
=INDEX($A$2:$E$2,MATCH(SMALL($A$3:$E$3+COLUMN($A$3:$E$3)/100000000,COLUMN()),$A$3:$E$3+COLUMN($A$3:$E$3)/100000000,0))
Enter it as an array formula, i.e. press Ctrl-Shift-Enter. Then copy it to the adjacent columns.
To get also the number, use this formula in A7 (again as array formula):
=ROUND(SMALL($A$3:$E$3+COLUMN($A$3:$E$3)/100000000,COLUMN()),6)
Both formulas are a bit bloated as they have to also handle the potential duplicates. The solution is to simply add a very tiny fraction of the column before applying the sorting (SMALL function) - and then to remove it again...
I think an easier solution is to use the "Large" function:
The Column functions are just an easy way to count from 5 down to 1, but a helper column may be even easier.
You can have a similar answer using the "Small" function as well.
Although I have used the "add a small number technique", I think this is the most elegant for a helper row/column:
=RANK(B4,$B$4:$F$4,0) + COUNTIF($B$4:$F$4,B4)-1
(copy across the row column) RANK gets you close and the COUNTIF portion handles duplicates by counting the number of duplicates of the cell to that point. Since there is always match (itself) you subtract 1 for the final rank. This "sorts" ties in the order that they appear. Note that an empty cell will generate #N/A and character data as #Values.
It's doable! :-)
Here is the sample file.
Explanation
I assume that your data is in row 1 of Sheet1 and that you want the data sorted starting in column 1 of another sheet - if not, adjust accordingly.
Place this formula in column 1 of the target sheet, say in row 2:
=ROUND(SMALL(Sheet1!$A$1:$E$1+COLUMN(Sheet1!$A$1:$E$1)/100000000,COLUMN()),6)
You need to enter the formula as an array formula, i.e. press Ctrl-Shift-Enter.
In case you place it in another column than column one, you need to replace COLUMN() with COLUMN()-COLUMN($A$2)+1 where $A$2must be a reference to the cell itself.
This formula will return you the lowest number in your range - if you copy it the next 4 columns, you'll get your order list of numbers.
To translate this back to the column number, we need to perform 2 steps:
Figure out the column number:This can be done with with this formula:
=MATCH(SMALL(Sheet1!$A$1:$E$1+COLUMN(Sheet1!$A$1:$E$1)/100000000,COLUMN()),Sheet1!$A$1:$E$1+COLUMN(Sheet1!$A$1:$E$1)/100000000,0)
- again, to be entered as array formula. If the source data does not start in column A, you need to add +COLUMN(Sheet1!$A$1)-1 where $A$1 needs to be replaced with the leftmost cell of the source data.
Convert the column number to a letter:Assuming your column number from step 1 is in cell A6, this formula will do the job:
=LEFT(ADDRESS(1,A6,2),SEARCH("$",ADDRESS(1,A6,2))-1)
Of course, you can also combine step 1&2, this will result in this megaformula:
=LEFT(
ADDRESS(
1,
MATCH(
SMALL(Sheet1!$A$1:$E$1+COLUMN(Sheet1!$A$1:$E$1)/100000000,COLUMN()),
Sheet1!$A$1:$E$1+COLUMN(Sheet1!$A$1:$E$1)/100000000,
0),
2),
SEARCH(
"$",
ADDRESS(
1,
MATCH(
SMALL(Sheet1!$A$1:$E$1+COLUMN(Sheet1!$A$1:$E$1)/100000000,COLUMN()),
Sheet1!$A$1:$E$1+COLUMN(Sheet1!$A$1:$E$1)/100000000,0),
2)
)-1
)
Again, to be entered as array formula.