Merge Columns without deleting or affecting the rows - google-sheets

Im seeking some experienced advice, as I have been working on a little project to automate how we gather data in my office using Google Sheets(Please note that I can't use add-ons).
I'm encountering difficulties in finding a way to merge columns that have the same name, but without deleting/merging the row(because im pulling stats for the different tasks employees handle).
In the example you can see that column A has names that repeat because each individual completes one or more tasks, so my goal would be to find a way to automatically merge the repeating names in column A without affecting the rest of the columns.
I believe it is important to know that the table auto-populates as im currently using a filter function, because I paste all my data in the excel and it filters only my agents names.
Here is the formula that im using in c26:
=FILTER(A3:G22,ARRAYFORMULA(ISNUMBER(MATCH(A3:A22,{"Mary";"Jason";"Ana";"Jen";"Ben";"Helen";"Dan";"Richard";"Breg"},0))))
Please tell me that there is a way to do this!
Here is a link to the example Doc That I made
https://docs.google.com/spreadsheets/d/1RsCeHfzzbRsUDnj6UmmCdfzjryp-2xW09UTCx_qfIpA/edit?usp=sharing

Here you can do it, but can't merge by formula:
= ARRAYFORMULA (
ifna (
vlookup (
ifna (
sort (
{ row(A4:A22) *
len ( vlookup ( A4:A22,
{"Ana";"Jen";"Ben";"Helen";"Dan";"Richard";"Breg"},1,0)
)^0}
,1,true
),""
)
, { row(A4:A22),
left(A4:A22, 1000 *
transpose (
split (join("","1," & rept("0,",countif(A4:A22,unique(A4:A22))-1)),",",true,true))
),
B4:G22
},{2,3,4,5,6,7,8},false
),""
)
)
Another formula with the same result:
= ARRAYFORMULA (
ifna(vlookup (
sort (
{ row(A4:A22) *
len ( vlookup ( A4:A22,
{"Ana";"Jen";"Ben";"Helen";"Dan";"Richard";"Breg"},1,0)
)^0}
,1,true
),
{ row(A4:A22),
if(transpose(split(join(
"","1," & rept("0,",COUNTIF(A4:A22,unique(A4:A22))-1)),",",true,true))=1,
A4:A22,""
),B4:G22
},{2,3,4,5,6,7,8},false),""
)
)

After a little bit of discussion on the sheet, this query() will display only one name per agent, but still list all the rows for that agent.
=ARRAYFORMULA(ARRAY_CONSTRAIN(QUERY({Sheet1!A1:G22,IF(COUNTIFS(Sheet1!A1:A22,Sheet1!A1:A22,ROW(Sheet1!A1:A22),"<="&ROW(Sheet1!A1:A22))>1,"",Sheet1!A1:A22)},"select Col8,Col2,Col3,Col4,Col5,Col6,Col7,Col1 where Col1 matches '"&TEXTJOIN("|",TRUE,A2:A)&"' order by Col1 label Col8'Name'",3),9^99,7))

Related

Selecting few columns in Google Sheet's QUERY function

I am trying to select few columns in Google Sheet's QUERY function but get errors when I combine with other formula in the function.
Here is my formula. What I am trying to do? my goal is combine data (column) from different sheets that will ultimately feed into a pivot table
=QUERY({TeamData!C:C,TeamBonusData!F:F;IndividualData!M:O,IndividualBonusData!P:R},) - this does not work
=QUERY({TeamData!C:C,TeamData!F:F},) - this works.
Follow the advice Tedinoz gave and ensure that those references have a matching number of rows and columns. It may help if you visually group ranges so that they stack side-by-side or on top of each other, like this:
=lambda(
teams, teamsBonus, individuals, individualsBonus,
lambda(
numTeams, numIndividuals,
{
array_constrain(teams, numTeams, 2), array_constrain(teamsBonus, numTeams, 2);
array_constrain(individuals, numIndividuals, 2), array_constrain(individualsBonus, numIndividuals, 2)
}
)(
min(rows(teams), rows(teamsBonus)),
min(rows(individuals), rows(individualsBonus))
)
)(
TeamData!C2:D, TeamBonusData!F2:G, IndividualData!M2:O, IndividualBonusData!P2:R
)

Google Sheets - combine data from multiple rows to single row or cell with arrayformula

I have an export from our student information system that has multiple rows for each student, depending on how many contact email addresses the parent entered.
Sample data from the export
I would like to combine all the contact addresses either into multiple columns on the same row or even all to the same cell would be fine. After many attempts through a lot of searching, I can get it to work with =join(char(10), filter(extract.csv!G:G,extract.csv!A:A=J2)) and manually filling the formula down. (Although I'd rather not have the return first but rather just between the results, but I can live with it if it's not possible.)
What'd I'd love is to have that in an arrayformula so that I don't have to copy it down but I can't figure out how to adjust the last reference to the J row. If I leave it as is, it puts the same values in every cell to match the J2 data.
with arrayformula
Or is there another way to get what I'm trying for? Thanks for any help... I'm just a teacher who loves to code and automate things muddling through and learning bits and pieces as I go!
It's probably worth posting this, because it's how far I got just creating some representative data of my own before I realised that you'd posted a sheet for us (thank you).
=ArrayFormula(if(mod(sequence(countunique(A2:A),D2,0),D2)<countif(A2:A,unique(filter(A2:A,A2:A<>""))),
vlookup(vlookup(unique(filter(A2:A,A2:A<>"")),{A2:A,row(A2:A)},2,false)+MOD(sequence(COUNTUNIQUE(A2:A),D2,0),D2),{row(A2:A),B2:B},2,false),))
D2 is a helper cell which contains the maximum number of contacts per student - either from formula or entered manually.
I will have a go with your data, but I wasn't quite clear whether the student's own email should come first, followed by the parent contacts? I'm kind of hoping that the secondary email isn't populated because it would complicate things further.
Here's how it looks with your data - same formula with slightly different columns:
=ArrayFormula(if(mod(sequence(countunique(A2:A),I2,0),I2)<countif(A2:A,unique(filter(A2:A,A2:A<>""))), vlookup(vlookup(unique(filter(A2:A,A2:A<>"")),{A2:A,row(A2:A)},2,false)+MOD(sequence(COUNTUNIQUE(A2:A),I2,0),I2),{row(A2:A),G2:G},2,false),))
where I2 is currently set to 5 - it can be worked out from
=max(countif(A2:A,unique(filter(A2:A,A2:A<>""))))
if you want to make it more dynamic.
The issue being that I can't think of an easy way to remove the blank email address for the first student at the moment (I'm a bit surprised that the download contains blank addresses - data quality?).
I have added a new sheet ("Erik Help"), which is a duplicate of your "AutoFillData" sheet. In my sheet, I cleared Column AD and then placed the following formula in AD1:
`=ArrayFormula({"Contact Emails";IF(J2:J="",,IFERROR(VLOOKUP(J2:J,{UNIQUE(FILTER(extract.csv!A2:A,extract.csv!A2:A<>"")),SUBSTITUTE(TRIM(TRANSPOSE(QUERY(TRANSPOSE(IF(ISERROR(VLOOKUP(UNIQUE(FILTER(extract.csv!A2:A,extract.csv!A2:A<>""))&""&TRANSPOSE(UNIQUE(FILTER("|"&{extract.csv!E2:E;extract.csv!F2:F;extract.csv!G2:G},{extract.csv!E2:E;extract.csv!F2:F;extract.csv!G2:G}<>"")))&"",extract.csv!A2:A&"|"&extract.csv!E2:E&"|"&extract.csv!F2:F&"|"&extract.csv!G2:G,1,FALSE)),,TRANSPOSE(UNIQUE(FILTER({extract.csv!E2:E;extract.csv!F2:F;extract.csv!G2:G},{extract.csv!E2:E;extract.csv!F2:F;extract.csv!G2:G}<>"")))))," ",COUNTA(UNIQUE(FILTER({extract.csv!E2:E;extract.csv!F2:F;extract.csv!G2:G},{extract.csv!E2:E;extract.csv!F2:F;extract.csv!G2:G}<>""))))))," ",CHAR(10))},2,FALSE)))})'
Explaining this formula fully would take quite a long time.
In general, what it does is form a virtual 2D grid (never seen by the user) with the unique list of student IDs running vertically at left and the unique list of all email addresses (with an appended delineator) running horizontally across the top. If the combination of student ID and that email address is found in any string formed by the mash-up of studentID|email1|email2|email3, then that email address fills the virtual grid; if not, then that cross-section of the grid is left null.
This leaves a grid where all possible emails are filled in horizontally somewhere across from each unique ID, rather than being on separate lines.
Finally, a quirk in the QUERY function is used to combine all non-null entries per row. That is, the QUERY function can have any number of headers, not just 0 or 1. By having QUERY request every email section of the grid as headers and then TRIMing out spaces, we wind up with all the emails for each student ID together.
Then it's just a matter of replacing the remaining spaces with a line return character, i.e., CHAR(10).
Here are a few solutions (in sheets kishkin 1 in kishkin 2 respectively).
Emails in one row in separate columns:
=ARRAYFORMULA(
IF(
J2:J = "",,
TRIM(
SPLIT(
VLOOKUP(
J2:J,
SPLIT(
TRANSPOSE(QUERY(
QUERY(
FILTER({extract.csv!A:A & "♥", extract.csv!G:G & "♦"}, extract.csv!A:A <> ""),
"SELECT MAX(Col2)
GROUP BY Col2
PIVOT Col1",
1
),, COUNTA(extract.csv!A:A)
)),
"♥"
),
2,
),
"♦"
)
)
)
)
Emails in a single cell:
={
"CONTACT EMAILS";
ARRAYFORMULA(
IF(
J2:J = "",,
REGEXREPLACE(
VLOOKUP(
J2:J,
SPLIT(
TRANSPOSE(QUERY(
QUERY(
FILTER({extract.csv!A:A & "♥", extract.csv!G:G & CHAR(10)}, extract.csv!A:A <> ""),
"SELECT MAX(Col2)
GROUP BY Col2
PIVOT Col1",
1
),, COUNTA(extract.csv!A:A)
)),
"♥"
),
2,
),
"(?m)^\s+|\s+$",
)
)
)
}

Is there a way to create a dynamic Query on Google Sheets?

I'm creating a database on Google Sheets for work and while I'm aware it's not the best solution, due to a number of restraints, that's what I've got to work with atm.
The thing is, I'm creating this for people who don't really know how to work with formulas on Google Sheets so I'm trying to be as user friendly as I can.
I'll use this sample sheet to try and demonstrate what I'm trying to do:
https://docs.google.com/spreadsheets/d/1tXM0IlswQVdwFum9a0pR5NsbtL5Uq_AH1tPbytXGvVg/edit#gid=0
One of the sheets is the Database, which will countain multiple columns of data (there's 10 on the sample, but the actual database is much larger).
There is another sheet called Column Index where I have a list of all columns, what kind of data they represent and a checkbox for people to select what data they want.
Finally, theres a third sheet called Data Extraction and I want to get the checked columns from the Database and send them to this sheet so people can download or copy this data to other worksheet.
It looks like a QUERY situation to me, but I'm not sure if it's possible to do it dynamically
This should do it:
=ArrayFormula(QUERY(
Database!A:K,
"select A,"&
TEXTJOIN(
",",
1,
IFNA(
REGEXEXTRACT(
ADDRESS(
1,
MATCH(
IF(
'Column Index'!C2:C,
'Column Index'!B2:B,
""
),
Database!1:1,
0
)
),
"[A-Z]+"
)
)
)
))
I built the query string, selecting the column indices that we wanted. No need for the "Col Index" Column.
Using Address, we can generate the appropriate column letter using a column address, then we just extract the letters part with a regex.
What I got was not that different as I also tried to construct the query string. The downside is it may be a bit buggy (but it works)
Here it is:
=query(Database!A1:K15,"select A,"&join(",",ArrayFormula(SUBSTITUTE(ADDRESS(1,filter(row('Column Index'!C2:C11),'Column Index'!C2:C11),4), "1", ""))))

Google Sheet one column "fixed, rest tranpose

I am trying to make the following without using google-script.
I have this sheet (A):
And I want to get Sheet (B) "auto-updated", every time the sheet (A) changes.
What I am trying to get on sheet (B):
Thank you very much in advance.
Thanks for sharing a sheet. This formula is in A2 on a new tab called MK.Help.
=ARRAYFORMULA(VLOOKUP(SEQUENCE(COUNTA('sheet 1'!A2:A)*4;1;0)/4+2;{ROW('sheet 1'!A2:A)\'sheet 1'!A2:A\'sheet 1'!B2:E\IF(ROW('sheet 1'!A2:A);'sheet 1'!B1:E1)};MOD(SEQUENCE(COUNTA('sheet 1'!A2:A)*4;1;0);4)*{0\1\1}+{2\3+4\3}))
This solution is designed for 4 columns. In your case, there are no empty cells, but if there were, you would use a query around the solution like this:
=ARRAYFORMULA(QUERY(VLOOKUP(SEQUENCE(COUNTA('sheet 1'!A2:A)*4;1;0)/4+2;{ROW('sheet 1'!A2:A)\'sheet 1'!A2:A\'sheet 1'!B2:E\IF(ROW('sheet 1'!A2:A);'sheet 1'!B1:E1)};MOD(SEQUENCE(COUNTA('sheet 1'!A2:A)*4;1;0);4)*{0\1\1}+{2\3+4\3});"where Col2 is not null"))
It can also be built for an unknown number of columns. If that's something you need, let me know.
I call this a "retabulation" problem and it comes up often enough that i tried to create a lesson for my method. Here's a link to that lesson. It's a bit of a work in progress, but maybe it will help.
https://docs.google.com/spreadsheets/d/1EV_iziWtrTrkPdwY0FI2l0lzTFt-IRQHCOg1punnN5c/edit#gid=0
here the formula:
= arrayformula(
{
"Date","Country","Value";
split
(
transpose
(
split
(
textjoin
(
":",false,filter(A2:A&","&B1:D1&"," & B2:D,A2:A<>"")
)
,":",true,false
)
)
,",",true,false
)
}
)

Google sheet query / filter with columns not Blank

I'am working on some document which get data from Non Google form, and the output is 36 column but there will be always filled up 8 max 9 columns with empty columns in between, with our Form we CANT change way how data are outputed. Empty column are here cuz Client fill up specific type of order so data are put in specific column.
i need query for pulling data from the main sheet and output just specific 5 specific column ( those will be always in same place ), and 2 columns that can be anywhere in between.
writing down every single column is not perfect as i need to pull data row by row not all at once ( i will be adding data in between final query output) and with that it would drasticly slow down file with few hundreds inputs added per week.
I didnt found working way to combine filter and query together to do this job ( removing empty columns [ <>'' and is not null].
Could someone help me with this ?
providing link for file : https://docs.google.com/spreadsheets/d/1SDR939yUSq9trLcxBid9AQeZUn-lNNiRr7O7pDiu888/edit?usp=sharing
In cell M1 of your sheet 'Desired output' try entering this little monster
=Arrayformula(query({'Raw data'!A:Z\
{"Configurable list"; 'Raw data'!D2:D&'Raw data'!F2:F&'Raw data'!H2:H&'Raw data'!J2:J&'Raw data'!L2:L&'Raw data'!P2:P&'Raw data'!R2:R&'Raw data'!T2:T&'Raw data'!V2:V}\
{"Date"; ('Raw data'!E2:E&'Raw data'!G2:G&'Raw data'!I2:I&'Raw data'!M2:M&'Raw data'!O2:O&'Raw data'!Q2:Q&'Raw data'!S2:S&'Raw data'!U2:U&'Raw data'!W2:W)+0}};
"Select Col1, Col2, Col3, Col26, Col28, Col24, Col27 Where Col1 is not null format (Col28) 'dd.mm.yyyy'"))
See if that works for you?
Your answer is really in the heading. You can use =filter([Range], [Range]<>"") for each row to get to this in the desired output. The filter function is perfect for this application.
UPDATE:
Looked at your sheet to get a better view of the problem. You'll need some wildcard workaround as shown here as a second criteria to identify the Date & Configurable cells: =filter([Range], [Range]<>"", search("Date", [Top row]))

Resources