I need to pull a complete row from one excel sheet to another escel sheet, based on a cell value - excel

I have 2 Excel worksheets. In the first I have a table that has a column named "Sales Order" and "SO Item" of each row (product) plus some other columns. In this table I concatenate "Sales Order" and "SO Item" so that I have Sales Order parent (xxxxxxx00) and also Sales Order childs (xxxxxxx01, xxxxxxx02,...,xxxxxxx09). However, in the second worksheet I also have the "concatenation" column but only contains Sales Order parents. How can I pull the whole rows containing the childs of each parent from worksheet 1 to worksheet 2?
I've tried to do it using VLOOKUP but this only returns a single child value (xxxxxxx001) and also its not returning the whole row where this code is located
Table 1 is:
Sales Order
SO Item
Concatenation
Material Description
Feas Plan Date
2503319449
100
2503319449100
SYS-7210 SAS-Mxp
Bundle Header
2503319449
101
2503319449101
PS-7210 SAS-T/Mxp
1/31/2023
2503319449
102
2503319449102
SYS-7210 SAS-Mxp2VDC
Global Allocation
2503319449
200
2503319449200
OS-7210 SAS-Mxp
1/31/2023
Table 2 is:
Sales Order
SO Item
Concatenation
Material Description
Feas Plan Date
2503319449
100
2503319449100
SYS-7210 SAS-Mxp
Bundle Header
2503319449
200
2503319449200
OS-7210 SAS-Mxp
1/31/2023
I want Table 2 to extract the missing "Concatenation" items from Table 1.

It is not clear from the question, how to present the output. I assume Table2 is your lookup table. Based on the input data, you need to return the entire Table1, I assume your Table1 has more data in your real case, and you want to extract just the information based on the lookup table. In the way you construct the concatenation, for the lookup it is only necessary the SO Item column values. Put on G2 the following formula:
=LET(tbA, A3:E4, tbB, A9:E12, soA, 1*INDEX(tbA,,2), soB, 1*INDEX(tbB,,2),
DROP(REDUCE("", soA, LAMBDA(ac,x, LET(f,
FILTER(tbB, (soB >= x) * (soB < x+100),""), IF(#f="", ac, VSTACK(ac,f))))),1))
Here is the output:
The condition:
IF(#f="", ac, VSTACK(ac,f))
It is just to prevent empty result from the FILTER output (f), it is not really necessary if you want to include the parent (condition: soB >= x as it is in the formula), but if you want to exclude it (soB > x) then you need it. Check my answer to the question: how to transform a table in Excel from vertical to horizontal but with different length on how to use DROP/REDUCE/VSTACK pattern. I convert to numeric values (multiplying INDEX by 1) the value of SO Item column, in case the input data is in text format, otherwise it is not necesary.

Related

Comparing two columns and their values and outputting the greater value

I'm trying to compare two columns ("Shows") from different tables and showing which one has the greater number ("Rating") associated with it in another table.
Ignore the operation column above as part of the solution that I'm trying to get, it's just to illustrate for you what I'm trying to compare.
Important note: If the names are duplicated. Compare the matching pair in their corresponding order. (1st with 1st, 2nd with 2nd, 3rd with 3rd etc..) illustrated in the table below:
Thanks
You can try the following in cell F3 for an array solution that spills the entire result at once:
=LET(sA, A3:A6, rA, B3:B6, sB, C3:C6, rB, D3:D6, CNTS, LAMBDA(x,
LET(seq, SEQUENCE(ROWS(x)), MAP(seq, LAMBDA(s,ROWS(FILTER(x,(x=INDEX(x,s))
*(seq<=s))))))), cntsA, CNTS(sA), cntsB, CNTS(sB), eval, MAP(sA, rA, cntsA,
LAMBDA(s,r,c,IF(r > FILTER(rB, (sB=s) * (cntsB=c)), "Table 1", "Table 2"))),
HSTACK(sA, eval))
Here is the output:
Explanation
The main idea is to count repeated show values. We use a user LAMBDA function CNTS, to avoid repetition of the same formula twice. Once we have the counts (cntsA, contsB), we use MAP to iterate over Table 1 elements with the counts and look for specific show and counts to compare with Table 2 columns. The FILTER function will return always a single value (based on sample data). Finally, we prepare the output as expected using HSTACK.
Try-
=IF(INDEX(FILTER($B$3:$B$6,$A$3:$A$6=G3),COUNTIFS($G$3:$G3,G3))>INDEX(FILTER($E$3:$E$6,$D$3:$D$6=G3),COUNTIFS($G$3:$G3,G3)),"Table-1","Table-2")

Sort data contained in blocks in excel

I have a large amount of reference data in excel, which I am trying to manipulate in a variety of ways. I'm having some problems with the way it is structured and sorting into a more manageable format.
Problem number 1:
I have three columns. Column A contains first a date, and then a designator of high or low. Column B contains times, Column C contains heights.
I would like to sort the data by column B (easy enough) EXCEPT I would like the date headings in Column A preserved. It's almost as though I have 365 tables, each with between 3 and 5 pieces of data - I'm looking to sort the 3 - 5 pieces of data within each date only.
This is what I have currently:
There's no issue with me taking the data and manipulating it some other way first - this is ultimately around me being able to take a batch of data (5x different reference points, each for 365 days) and develop a process to sanitise it and get it displayed in time order, as well as being able to get it into a usable format for problem 2 (I need to adjust some other data points by the sorted data once I have it).
This is what I would like it to look like (I manually went through each of these blocks and sorted them):
It is possible to do it in Excel as follows in cell E2:
=LET(rng, A1:C11, set, FILTER(rng, (INDEX(rng,,1) <>"")),
dates, SCAN("", INDEX(set,,1), LAMBDA(acc, item, IF(ISNUMBER(item), item, acc))),
in, FILTER(HSTACK(dates, set), INDEX(set,,2)<>""), inDates, INDEX(in,,1),
out, REDUCE("", UNIQUE(inDates), LAMBDA(acc, date,
LET(sorted, VSTACK(date, DROP(SORT(FILTER(in, inDates = date),3),,1), {"","",""}),
VSTACK(acc, sorted)
))), IFERROR(DROP(DROP(out,1),-1),"")
)
Here is the output:
You can avoid the clean-up process except for removing the last row as follow:
=LET(rng, A1:C11, set, FILTER(rng, (INDEX(rng,,1) <>"")),
dates, SCAN("", INDEX(set,,1), LAMBDA(acc, item, IF(ISNUMBER(item), item, acc))),
in, FILTER(HSTACK(dates, set), INDEX(set,,2)<>""), inDates, INDEX(in,,1),
out, REDUCE("", UNIQUE(inDates), LAMBDA(acc, date,
LET(sorted, VSTACK(HSTACK(date,"",""), DROP(SORT(FILTER(in, inDates = date),3),,1),
{"","",""}), IF(MAX(LEN(acc))=0, sorted, VSTACK(acc, sorted))
))), DROP(out, -1)
)
Explanation
Basically is to carry out the manual steps but using excel functions. The name set, is the same as the input data (rng) but we removed the empty rows. The name dates, is a column with the same size as rng, repeating all the dates. The condition in the SCAN function to identify a new date is ISNUMBER because dates are stored in Excel as whole numbers. The name in has the data in the format we want for doing the sorting and filter by date removing the date header and adding as the first column the dates.
Now we use DROP/REDUCE/VSTACK pattern (check the answer to the question: how to transform a table in Excel from vertical to horizontal but with different length provided by David Leal) to append each sorted data for a given unique date. We add the date as the first row, then sorted data, and finally an empty row to separate each group of data. Finally, we do a clean-up via IFERROR/DROP to remove the #N/A values and the first and the last empty row.

Random of Table Header Name of another table via INDEX MATCH

I have these 2 tables:
On column B i'm trying to get one of the Header Names of a feature that is not empty on Table B. I want it to be selected randomly. The order of the items in Table A can be different than the order of the items in Table B, I'll need some sort of INDEX MATCH here too.
Excel Version: Office 365
Attempted Formula: I tried to base my formula on this:
=INDEX(datarange,RANDBETWEEN(1,COLUMNS(datarange)),1)
but there are more things to consider, like header name if the index match of the same fruit isn't empty, so I know it is more complex.
Any help will be greatly appreciated.
Assuming you have Excel 365 and a volatile result is acceptable:
=LET(
Fruits, Table_B[Fruit],
Properties, Table_B[[Red]:[Green]],
PropertiesHeaders, Table_B[[#Headers],[Red]:[Green]],
ThisFruit, [#Fruits],
ThisProperties, FILTER(Properties, Fruits = ThisFruit),
ThisPropertiesFiltered, FILTER(PropertiesHeaders, ThisProperties <> 0),
ThisPropertiesCount, COUNTA(ThisPropertiesFiltered),
IndexRand, RANDBETWEEN(1,ThisPropertiesCount),
IFERROR(INDEX(ThisPropertiesFiltered,IndexRand),"-")
)
ThisProperties is the row in Table_B for your fruit. I left out the column for the fruit names.
ThisPropertiesFiltered is the names of the properties that the fruit has. I filtered the header names based on if the fruit row had a non-zero value or not.
IndexRand gets a random number between 1 and the number of available properties. Note, if there are zero available properties, ThisPropertiesFiltered returns #CALC! so ThisPropertiesCount will return 1. This is handled later on.
Last we use INDEX to get the random property name. IFERROR returns "-" if no properties were available.
Here are the tables:
Table_A:
Fruits
Result
Watermelon
Heavy
Melon
Green
Banana
Tropic
Peach
Red
Apple
Green
Table_B:
Fruit
Red
Yellow
Tropic
Heavy
Green
Apple
x
x
Banana
x
x
Peach
x
Melon
x
Watermelon
x
x
Since you have access to dynamic arrays you could try:
Formula in B2:
=LET(X,FILTER(E$1:I$1,INDEX(E$2:I$6,MATCH(A2,D$2:D$6,0),0)<>"","No Feature"),INDEX(X,RANDBETWEEN(1,COUNTA(X))))
Or without LET():
=#SORT(SORT(CHOOSE({1;2;3},E$1:I$1,FILTER(E$2:I$6,D$2:D$6=A2),RANDARRAY(1,5)),3,1,1),2,-1,1)
If you are working through actual tables this should spill down results under Random Feature automatically. However, if one does not use tables, you could nest the above in BYROW() if you are an 365-insider:
=BYROW(A2:A6,LAMBDA(r,LET(X,FILTER(E$1:I$1,INDEX(E$2:I$6,MATCH(r,D$2:D$6,0),0)<>"","No Feature"),INDEX(X,RANDBETWEEN(1,COUNTA(X))))))
This would not work with the 2nd option where we used '#' to parse only the topleft value of our array (implicit intersection).
The idea is that:
A combination of INDEX() & MATCH() will 'slice' the row of interest out of the lookup-table based on our input.
In the 2nd step we'd use FILTER() to only leave those headers where the elements from the herefor returned array are not empty. In the case all elements are empty, this function will return the value "No Feature" as a headsup for the users.
In our final step we combine INDEX() with RANDBETWEEN(). The latter will return a random integer between a LBound (1 in our case) and an Ubound which we based on the amount of returned elements.
I tried to visualize this below.

Compare multiple columns in 2 sheets and return another column

I have some data of countries, states and cities. There are total of around 3 million rows.
`Country` `City` `AccentCity` `Region` `Population` `Latitude` `Longitude`
af amir kalay Amir Kalay 16 0 34.6333 70.3333
ad aixas Aixas 06 0 42.4833 1.4667
and lot more records
I divided it into 7 files to save it in csv. As you can see, it is showing region numbers and not region names. However, I found another file, which gives, as you can see below, 2-digit country code, region number and region name.
country,Region,State
AD,02,"Canillo"
AD,03,"Encamp"
AD,04,"La Massana"
AD,05,"Ordino"
AD,06,"Sant Julia de Loria"
AD,07,"Andorra la Vella"
AD,08,"Escaldes-Engordany"
AE,01,"Abu Dhabi"
How can I match these region numbers and region names so that every city shows the region name in front of it? Currently it shows the region number. Is there any query or formula which can match the country code and region number in both sheets and put the region name in front of the city name?
I'm making the assumption you want to show the column headed 'State' as a new column in the first table with Latitude/Longitude.
You can put the Country/Region/State in a new tab (Sheet4 in this example), add a column in front and concatenate columns B&C (=b2&c2) the country/region in column A.
In a new column use VLOOKUP concatinating country/Region of the first table finding the key in Sheet4, and returning the fourth column - "State".
=IFERROR(VLOOKUP(UPPER(A1)&D1,Sheet4!A:D,4,FALSE),"Unknown")
Please be sure to keep the leading zeros of region when placing in Excel.

Using tbl.Lookup to match just part of a column value

This question relates to the Schematiq add-in for Microsoft Excel.
Using =tbl.Lookup(table, columnsToSearch, valuesToFind, resultColumn, [defaultValue]) the values in the valuesToFind column have a consistent 3 characters to the left and then varying characters after (e.g. 908-123456 or 908-321654 - i.e. 908 is always consistent)
How can I tell the function to lookup the value based on the first 3 characters only? The expected answer should be the sum of the results of the above, i.e. 500 + 300 = 800
tbl.Lookup() works by looking for an exact match - this helps ensure it's fast but in this case it means you need an extra step to calculate a column of lookup values, something like this:
A2: =tbl.CalculateColumn(A1, "code", "x => LEFT(x, 3)", "startOfCode")
This will give you a new column that you can use for the columnsToSearch argument, however tbl.Lookup() also looks for just one match - it doesn't know how to combine values together if there is more than one matching row in the table, so I think you also need one more step to group your table by the first 3 chars of the code, like this:
A3: =tbl.Group(A2, "startOfCode", "amount")
Because tbl.Group() adds values together by default, this will give you a table with a row for each distinct value of startOfCode and the subtotal of amount for each of those values. Finally, you can do the lookup exactly as you requested, which for your input table will return 800:
A4: =tbl.Lookup(A3, "startOfCode", "908", "amount")

Resources