Excel - Analyzing / Counting the comma separated values in cells - excel

Here's an Excel sheet, where we track Demand of Products across the countries [Sheet/Table name: Data]
Country
Products
India
A
Australia
A,B
Brazil
B, C
This Data will be used to understand the demand of the products across the countries, by simply counting products for each country. This is how the data will look like:
Products
Demand
A
2
B
2
C
1
[Sheet/Table name: Product-Demand]
One of the ways, I was able to do this was :
Split the comma separated values in the Products Column/cell, and then CountIFS
However, this approach involved
Every time the Data table was updated, manually copy-pasting this to another sheet.
The products may increase, ex: new product "Z" may be launched
We use Power BI to create a heat-map of Products in demand across the country. The Power BI Service pulls the data every Monday. Manual effort kind of destroys the automation.
Please advise/guide on
What's the best way to count the products (or comma separated values) in a cell with least amount of manual work.
Thanks!

Where the data is in columns A and B on both sheets, and there is a header row with the data starting in row 2, on the Product-Demand sheet, in cell B2, place this formula:
=COUNTIF(Data!$B$2:$B$4,"*" & A2 & "*")
then drag down

You need to transform the data into a more useful structure. One way to do that is to use Power Query.
Start with your source data as a table called Table1.
Then, paste the following code in the Advanced Editor in Power Query:
let
Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
#"Changed Type" = Table.TransformColumnTypes(Source,{{"Country", type text}, {"Products", type text}}),
#"Replaced Value" = Table.ReplaceValue(#"Changed Type"," ","",Replacer.ReplaceText,{"Products"}),
#"Split Column by Delimiter" = Table.SplitColumn(#"Replaced Value", "Products", Splitter.SplitTextByDelimiter(",", QuoteStyle.Csv), {"Products.1", "Products.2"}),
#"Changed Type1" = Table.TransformColumnTypes(#"Split Column by Delimiter",{{"Products.1", type text}, {"Products.2", type text}}),
#"Unpivoted Columns" = Table.UnpivotOtherColumns(#"Changed Type1", {"Country"}, "Attribute", "Value"),
#"Removed Columns" = Table.RemoveColumns(#"Unpivoted Columns",{"Attribute"})
in
#"Removed Columns"
This code will produce a table of usefully-structured data. The final table you want can be produced by a PivotTable using Power Query's output table as a source.

Related

Concatenate multiple values into one cell, based on a lookup ID

I'm trying to concatenate multiples values in one cell based on a lookup search (ID), the thing is this ID sometimes might be alone but other time might be between multiple IDs in the same cell (at the beginning, middle or end separated by commas). I've been using the below formula but only returns the first value when the ID is alone.
Current formula --> =TEXTJOIN(",",TRUE,IFERROR(XLOOKUP(A2,D:D,E:E),"ID not found"))
Hope you can help.
Thanks.
Rows highlighted in blue, yellow and green are the expected results (I did them manually).
Row 7 is the actual result (wrong/incomplete) for the current formula.
You can try below approach to get results:
=TEXTJOIN(",",TRUE,IF(ISNUMBER(SEARCH(A2,D:D,1)),E:E,""))
One suggestion would be to limit the entire column usage to improve formula speed.
This can also be done via power query. I used different ID values from your table on the right, but it should still work correctly.
Create a table that has ID's in Col1 and the Value to be Returned in Col2
Open the table in Power Query (Data tab > Get & Transform Data via From Table/Range.
If you don't have power query, reference this Complete Guide to Installing Power Query.
Power Query Steps
Change type of Col: Value to be Returned to text
Split Col: ID by Delimeter = ','
You know should have multiple ID columns (ID.X). Select all ID columns > Right click on header > select Unpivot Other Columns
Remove any unecessary columns
Select the column with all of your ID's > right click and select Group By
Under new column name, enter a new column header. Change the Operation to Sum. For Column, select your column that contains your Values to be Returned
Reference this guide for the next step. You need to manually configure the M code in the formula bar & change the formula from List.Sum([COL]).. to Text.Combine([COL], ",")..
The last step is to make sure that your new column is a text column, not a number.
I've attached a copy of my workbook, which should hopefully help. If not, I've pasted my code from the Advanced Editor below in case that is helpful. Be sure to update Table & Column names accordingly based on your workbook.
let
Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
#"Changed Type" = Table.TransformColumnTypes(Source,{{"ID", type text}, {"Value to be returned", type text}}),
#"Split Column by Delimiter" = Table.SplitColumn(#"Changed Type", "ID", Splitter.SplitTextByDelimiter(",", QuoteStyle.Csv), {"ID.1", "ID.2", "ID.3"}),
#"Changed Type1" = Table.TransformColumnTypes(#"Split Column by Delimiter",{{"ID.1", type text}, {"ID.2", type text}, {"ID.3", type text}}),
#"Unpivoted Columns" = Table.UnpivotOtherColumns(#"Changed Type1", {"Value to be returned"}, "Attribute", "Value"),
#"Removed Columns" = Table.RemoveColumns(#"Unpivoted Columns",{"Attribute"}),
#"Reordered Columns" = Table.ReorderColumns(#"Removed Columns",{"Value", "Value to be returned"}),
#"Grouped Rows" = Table.Group(#"Reordered Columns", {"Value"}, {{"Value.1", each Text.Combine([Value to be returned], ", "), type number}}),
#"Changed Type2" = Table.TransformColumnTypes(#"Grouped Rows",{{"Value.1", type text}})
IN
#"Changed Type 2"
Let me know if this works or if you have any follow up questions.

Creating a consolidated set of pairs on Excel

I am working with an Excel file having import and export data between different countries for various shipping products, which looks pretty much like this:
The goal is to create a consolidated state pair that have a trade relation between them. So the final list for the above example should look something like this:
What would be the best way to go about this?
Try below formula-
=COUNTIFS(A:A,E4,B:B,F4)+COUNTIFS(A:A,F4,B:B,E4)
So assume your data is in a&b in the first screenshot, put this formula in column c
=a1&b1 then hit enter, then drag the bottom right hand corner down so the formula works for all cells in that column. Then copy the column and paste it as values.
Then in column d, use the formula =countifs(c:c,c1) and drag it down in the same way. Now paste column d as values.
Finally, on the data tab, remove duplicates based on column c and then delete column c.
You can do this really easy with Pivot Tables. Just take Field Importing Country into rows section and also values section (make sure it's counting) and field Exporting Countryto rows section.
Choose Tabular design, deactivate subtotals and activate Repeat labels. This is what you get:
You can do this with Power Query, available in Windows Excel 2010+ and O365
Sort each row horizontally
Group by the two resultant country rows, aggregating by Count
M Code
let
Source = Excel.CurrentWorkbook(){[Name="Table3"]}[Content],
#"Changed Type" = Table.TransformColumnTypes(Source,{{"Importing Country", type text}, {"Exporting Country", type text}}),
#"Added Custom" = Table.AddColumn(#"Changed Type", "Country", each List.Sort({[Importing Country],[Exporting Country]})),
#"Removed Columns" = Table.RemoveColumns(#"Added Custom",{"Importing Country", "Exporting Country"}),
#"Extracted Values" = Table.TransformColumns(#"Removed Columns", {"Country", each Text.Combine(List.Transform(_, Text.From), ";"), type text}),
#"Split Column by Delimiter" = Table.SplitColumn(#"Extracted Values", "Country", Splitter.SplitTextByDelimiter(";", QuoteStyle.Csv), {"Country.1", "Country.2"}),
#"Changed Type1" = Table.TransformColumnTypes(#"Split Column by Delimiter",{{"Country.1", type text}, {"Country.2", type text}}),
#"Grouped Rows" = Table.Group(#"Changed Type1", {"Country.1", "Country.2"}, {{"Occurrences", each Table.RowCount(_), Int64.Type}})
in
#"Grouped Rows"

Multiple criteria MATCH/INDEX combination returns wrong row number

I've been struggling with this for a day and can't find where is the problem.
I am recreating a table for SQL import so from table 1 I need to create a list of unique rows to have row structure.
I can identify the unique row by two columns (ID_concept, ID_country) and then find the unique value by row of years (ID_year - top row 7,8,9,10...44).
The source table looks like this: Source table
To get the values in single rows I have created a second table to use multiple index/match combination that writes value per row. It looks like this: Desired table for SQL import
In the value column I use following INDEX/MATCH formula to look for the data:
{=INDEX(Sheet1!$C$2:$AN$2813;MATCH(Sheet2!A2&Sheet2!B2;Sheet1!$A$2:$A$2813&Sheet1!$B$2:$B$2813;0);MATCH(Sheet2!C2;Sheet1!$C$1:$AN$1;0))}
When I copy the formula across Sheet2, it populates all value fields in the value column but some of the values are copied wrong. The combination of ID_concept and ID_country in the MATCH function should always lead to a unique row. I have checked the MATCHES separately and the column match works always fine. Unfortunately the row match (that uses & statement) returns in few cases wrong row number (e.g. 32 instead of 395, input values 11 and 41 and returns row for 1 and 140).
Range of values:
ID_concept: 1-38, ID_country: 1-190, years: 7-44, Source table 2812x38, SQL table 106 856 rows
Any ideas why is the multiple criteria MATCH returning wrong row information?
Thanks
Instead of doing this using formulas, you can easily create your output table, in Excel, by using Power Query (available in Excel 2010 or later).
In 2016+, go to the data tab and select Get & Transform from Table/Range.
In earlier versions, there is a free, Microsoft-provided, add-in to install.
Then it is merely a matter of
selecting the first two columns
unpivot other columns
rename the resultant Attribute column --> ID_Period
change the Type of this column to Whole Number
Sort, if you want to, the results by selecting, in order, columns 3, then 2, then 1 as appropriate.
All of the above can be done from the UI, but here is the generated M-Code which you could paste into the advanced editor with minor changes:
let
Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
#"Changed Type" = Table.TransformColumnTypes(Source,{{"ID_concept", Int64.Type}, {"ID_country", Int64.Type}, {"7", type number}, {"8", type number}, {"9", type number}, {"10", type number}, {"11", type number}, {"12", type number}, {"13", type number}, {"14", type number}}),
#"Unpivoted Other Columns" = Table.UnpivotOtherColumns(#"Changed Type", {"ID_concept", "ID_country"}, "Attribute", "Value"),
#"Renamed Columns" = Table.RenameColumns(#"Unpivoted Other Columns",{{"Attribute", "ID_Period"}}),
#"Changed Type1" = Table.TransformColumnTypes(#"Renamed Columns",{{"ID_Period", Int64.Type}}),
#"Sorted Rows" = Table.Sort(#"Changed Type1",{{"ID_Period", Order.Ascending}, {"ID_country", Order.Ascending}})
in
#"Sorted Rows"

Trying to concatenate values in Column C when A1 & B1 match A2 & B2

I have three columns of data. Column A is a list of computers. Column B is the list of User ID's. Column C are the user permissions. What I want to do is concatenate the values in Column C when there is a match for A & B. Attached is a simple screenshot of what I am trying to do. Please advise the easiest way to achieve this. I am new to Excel formulas so any assistance is appreciated!
Your desired results don't make sense given your original data.
In particular, you only have two bbb123 in your data, and the aaa123 has two different matches.
If that is typo related, what you want can be done easily with Power Query aka Get&Transform which is a part of versions of Excel since 2010.
Except for the Custom Column, most of the code below can be generated automatically from the User Interface.
Algorithm:
Group the data by machine and account
-This forms a table of the grouped "permissions"
Convert the table into a list (this is what the Custom Column does)
Expand the list by extracting the values and using comma as the delimiter
Delete the column containing the tables
The formula for the custom column is: (Add Column/Custom Column from the UI)
=Table.Column([Grouped],"permissions")`
The M-Code:
let
Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
#"Changed Type" = Table.TransformColumnTypes(Source,{{"machine", type text}, {"account", type text}, {"permissions", type text}}),
#"Grouped Rows" = Table.Group(#"Changed Type", {"machine", "account"}, {{"Grouped", each _, type table}}),
#"Added Custom" = Table.AddColumn(#"Grouped Rows", "Custom", each Table.Column([Grouped],"permissions")),
#"Extracted Values" = Table.TransformColumns(#"Added Custom", {"Custom", each Text.Combine(List.Transform(_, Text.From), ","), type text}),
#"Removed Columns" = Table.RemoveColumns(#"Extracted Values",{"Grouped"})
in
#"Removed Columns"
Original Data
Grouped Data

Excel Separate Pipe Delimited String into separate columns - where value starts with A, B, C but values in string are not cronological

I have an excel sheet, which has values from a database. One cell has responses from a multiple choice question which is pipe delimited. eg a user could ask what colour cars have you had? With options such as:
A. Black
B. White
C. Red
D. Yellow
So a user can respond with A, C and D. these values are stored in one cell as "A. Black|C. Red|D. Yellow" I want to separate each of these values in a A column, B column, C column and D column.
I tried using the Text to Column feature but this does know that the A column should only contain As.
I thin I need to add a formula to each column which looks for the "A.", "B.", "C." or "D." and then finds the next available pipe character. I think I need a substring of some sort maybe. Something like this maybe:
=LEFT(C2,LEN(C2)-FIND("A.",C2))
But I don't know how to find the next occurrence of the pipe symbol - any ideas? Is there a nextIndexOf function in excel maybe?
Many thanks in advance
I think this would require either VBA or Power Query, because you are talking about having to analyze the data to determine what column it goes into. It's actually very easy to do in Power Query, but if you've never even heard of Power Query (it's built into Excel 2016+ and is a free add-in for 2013) then this solution is probably out of scope without an extensive explanation of what Power Query is.
That being said, for anyone interested, I took this dummy set of data, and converted it into an output table with Power Query which I believe is what was being asked in the question.
This is the code for the Query. A quick summary is we split it by the pipe delimiters and index it. Then the main trick is using the Group function combined with the Transpose function to get the split columns into an unpivoted data set. After expanding back out from the Group we can then split out the "ABCD" section from the answer, and pivot off that to get the ABCD columns aligned with the original entries.
let
Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
#"Split Column by Delimiter" = Table.SplitColumn(Source, "Column1", Splitter.SplitTextByDelimiter("|", QuoteStyle.Csv), {"Column1.1", "Column1.2", "Column1.3", "Column1.4"}),
#"Added Index" = Table.AddIndexColumn(#"Split Column by Delimiter", "Index", 1, 1),
#"Grouped Rows" = Table.Group(#"Added Index", {"Index"}, {{"Rows", each Table.Transpose(Table.RemoveColumns(_, {"Index"})), type table}}),
#"Expanded Rows" = Table.ExpandTableColumn(#"Grouped Rows", "Rows", {"Column1"}, {"Rows.Column1"}),
#"Filtered Rows" = Table.SelectRows(#"Expanded Rows", each ([Rows.Column1] <> null)),
#"Split Column by Delimiter1" = Table.SplitColumn(#"Filtered Rows", "Rows.Column1", Splitter.SplitTextByDelimiter(". ", QuoteStyle.Csv), {"Selection", "Answer"}),
#"Pivoted Column" = Table.Pivot(#"Split Column by Delimiter1", List.Distinct(#"Split Column by Delimiter1"[Selection]), "Selection", "Answer")
in
#"Pivoted Column"

Resources