I am not sure the best way to ask this so I will give an example of what I am trying to do.
I have one tab in google sheets with several rows like so:
option 1
option 2
option 3
In a second sheet I want to create a formula that I can copy down that will produce something like this
prefix1_option1
prefix2_option1
prefix3_option1
prefix1_option2
prefix2_option2
prefix3_option2
prefix1_option3
prefix2_option3
prefix3_option3
Using formula like
"prefix1_"&'Sheet'!A1
"prefix2_"&'Sheet'!A1
"prefix3_"&'Sheet'!A1
works for the first one but does not copy properly.
Try:
=ArrayFormula(transpose(split(rept(concatenate({"prefix1_";"prefix2_";"prefix3_"}&char(9)),3),char(9)))&transpose(split(concatenate(rept(Sheet1!A:A&char(9),3)),char(9))) )
or alternatively, write in B1:B3 of sheet 1: "prefix1", "prefix2", "prefix3" (without the quotes) and then do:
=ArrayFormula(transpose(split(rept(concatenate(Sheet1!B:B&char(9)),3),char(9)))&transpose(split(concatenate(rept(Sheet1!A:A&char(9),3)),char(9))) )
Related
=ARRAYFORMULA("https://www.amazon.com/product-reviews/B08C1W5N87/ref=cm_cr_arp_d_viewopt_rvwer?ie=UTF8&reviewerType=avp_only_reviews&sortBy=recent&pageNumber="&SEQUENCE(5,1,1,1))
I use the code above to have the links that I would like to scrap the data. There are 5 links.
=IMPORTXML(A6,"/html/body/div[1]/div[3]/div/div[1]/div/div[1]/div[5]/div[3]/div/div[*]/div/div/div[2]/a[1]/i")
I also use the formula above to scrap the data I want from the link. A6 refers to the first link the first formula creates.
What I would like to do is, if possible, I want to scrap the data from the 5 links and list them in a column.
=IMPORTXML(ARRAYFORMULA("https://www.amazon.com/product-reviews/B08C1W5N87/ref=cm_cr_arp_d_viewopt_rvwer?ie=UTF8&reviewerType=avp_only_reviews&sortBy=recent&pageNumber="&SEQUENCE(5,1,1,1)),"/html/body/div[1]/div[3]/div/div[1]/div/div[1]/div[5]/div[3]/div/div[*]/div/div/div[2]/a[1]/i")
The formula above did not work.
=ARRAYFORMULA(IMPORTXML("https://www.amazon.com/product-reviews/B08C1W5N87/ref=cm_cr_arp_d_viewopt_rvwer?ie=UTF8&reviewerType=avp_only_reviews&sortBy=recent&pageNumber="&SEQUENCE(5,1,1,1),"/html/body/div[1]/div[3]/div/div[1]/div/div[1]/div[5]/div[3]/div/div[*]/div/div/div[2]/a[1]/i"))
The formula above did not work as well. It always scraps the first link's data only.
Thank you for your help in advance.
keep in mind that IMPORTXML itself is a "type of arrayformula" so it is not supported under ARRAYFORMULA
in your case try to hardcode 5 IMPORTRANGE formulae into array {} like:
={IMPORTRANGE();
IMPORTRANGE();
IMPORTRANGE();
etc}
update
with new LAMBDA function its possible to do it in one go:
=INDEX(TRIM(FLATTEN(SPLIT(FLATTEN(BYCOL(
"https://www.amazon.com/product-reviews/B08C1W5N87/ref=cm_cr_arp_d_viewopt_rvwer?ie=UTF8&reviewerType=avp_only_reviews&sortBy=recent&pageNumber="&
SEQUENCE(1,5,1,1), LAMBDA(x, QUERY(IMPORTXML(x,
"/html/body/div[1]/div[3]/div/div[1]/div/div[1]/div[5]/div[3]/div/div[*]/div/div/div[2]/a[1]/i")&"×",,9^9)))), "×"))))
In a Google spreadsheet, I want to sync A2:G500 in sheet1 to sheet2, I've been aware of the following two methods:
use IMPORTRANGE: put the following formula in A1 of sheet2:
=IMPORTRANGE("spreadsheet_url",sheet1!A2:G500)
It works but it feels like I am overdoing it, besides there seem to be a performance issue
In A2 of sheet2, put formula =sheet1!A2, then drag the formula to G500 in sheet2. This one is intuitive and simple to do. However, it doesn't work if sheet1 is a form response sheet - when new response is added, sheet2 won't automatically get it.
For learning purpose, I'm wondering if there is a way to do this using Arrayformula. Besides, I want to find a way to make this sync more care-free, meaning if there are indefinite rows of data I won't have to go back to this sheet every now and then and change the formula or manually drag the formula. Is this possible? And is Arrayformula the right way to go for this purpose?
I would recommend an { array expression }, like this:
={ Sheet1!A2:G }
This is more or less the same as
=arrayformula(Sheet1!A2:G)
...but I prefer the {} syntax because it allows you to specify non-adjacent columns. For example, you can skip columns D and F like this:
={ Sheet1!A2:C, Sheet1!E2:E, Sheet1!G2:G }
In spreadsheets where the locale uses the comma as decimal mark instead of the period, use a backslash \ instead of comma as horizontal separator.
To skip rows, use the semicolon ; as vertical separator. For example, you can skip rows 2:9 like this:
={ Sheet1!A1:G1; Sheet1!A10:G }
The open-ended range reference A10:G means "columns A to G starting in row 2 and extending all the way to the bottom of the sheet."
You can also leave out the row number to get an open-ended range reference like A:G which means "columns A to G from the very top to the bottom of the sheet." This reference will behave the same as A1:G in almost all situations. I have made it a habit to always include the start row in the reference because that way the formula will automatically adjust in the event a row is inserted above row 1.
When the source sheet is a form responses sheet, another tactic is needed. Form responses are always inserted in newly created rows that cannot be referenced directly in advance.
To avoid the range reference from adjusting when you dynamically copy form responses to another sheet, start the copy from row 1, like this:
={ 'Form Responses 1'!A1:A }
Alternatively, use an array formula, like this:
=arrayformula(
if(
row('Form Responses 1'!A1:A) = 1,
"Enter column header here",
'Form Responses 1'!A1:A
)
)
An even better way to deal with form responses is to aggregate the data directly to whatever reports you need with the query() function.
It's either:
ArrayFormula(Sheet1!A2:G500) for the 499 lines, or
ArrayFormula(Sheet!A2:G) if you wanto sync everything from line 2 down
=ARRAYFORMULA(Sheet1!A:G)
Does this not work?
try in row 1:
={""; INDEX(sheet1!A2:A)}
this will solve your form issues when you use it in 1st row. if you already have something in your row 1 you can add it into double quotes like this:
={"header"; INDEX(sheet1!A2:A)}
in case of multiple columns its like this:
={"","","","","","",""; INDEX(sheet1!A2:G)}
I have a formula that works as long as all the data it is trying to match from is in Column A. I need this to also look at the data in column B to see if it matches. I also have another formula that matches two different columns and I also need it to look in both A and B for the data. Both of these are used for conditional formatting. Can anyone help me set these up so it is looking on the Received tab in both columns A and B?
Current formulas that work:
=match($C:$C, indirect("Received!A2:A"),0)
=and(match($I:$I, indirect("Received!A2:A"),0), (match($O:$O, indirect("Received!A2:A"),0)))
What I am trying to do but is not working:
=match($C:$C, indirect("Received!A2:B"),0)
=and(match($I:$I, indirect("Received!A2:B"),0), (match($O:$O, indirect("Received!A2:B"),0)))
Test Doc: https://docs.google.com/spreadsheets/d/1dDrmASkiy4KY8ywVuBLdZzAZtvyTohJBFFWtSte5g8A/edit?usp=sharing
try:
=OR(MATCH($C:$C,INDIRECT("Received!A2:A"),0),MATCH($C:$C,INDIRECT("Received!B2:B"),0))
and:
=OR(AND(MATCH($I:$I,INDIRECT("Received!A2:A"),0),(MATCH($O:$O,INDIRECT("Received!A2:A"),0))),
AND(MATCH($I:$I,INDIRECT("Received!B2:B"),0),(MATCH($O:$O,INDIRECT("Received!B2:B"),0))))
I'm looking for a way to add together a dynamically generated list of ranges using (I'm guessing) an ARRAYFORMULA.
The normal way of attacking this is fine if there is a known list of ranges, the example of the results I want would work using this:
=ARRAYFORMULA( A1:A10 + B1:B10 )
In the case I'm after I want to add together ranges in multiple sheets. I don't want the users to have to manually adjust the array formula every time they add a new sheet to be calculated, and I also want to be able to add some logic to include or remove the particular sheet from the calculation, but for now I'm happy to ignore that and just focus on adding cells together.
My approach to this was to create a column with a list of names, each one matching a sheet in the document, and then using that list to dynamically build the list of ranges to add together, using INDIRECT.
.------------.
| sheet1 | <---- SheetListNamedRange
|------------|
| sheet2 |
`------------'
Here's a quick example
=ARRAYFORMULA( INDIRECT("'" & SheetListNamedRange & "'!D4:75") )
There are lots of failure modes depending on how it's done, but this particular formula only puts in the values of the first sheet and ignores any others, which I guess makes sense.
What I'm after is kind of the equivalent of i++ in a loop found in a normal coding language. Is there some way of making this work?
If I understand you correctly, you'd like to get a list generated based on different ranges across different sheets. If your case is as simple as the one you mention in the beginning of your post, the following would do the job.
={Sheet1!A1:A2; Sheet2!B1:B2}
If you want the sum of all these values, you can use SUM.
=SUM({Sheet1!A1:A2; Sheet2!B1:B2})
Please let me know if this isn't what you were looking for, so I can change the answer accordingly.
you can't refer to array of arrays in INDIRECT. you will need to INDIRECT each sheet which contains array.
=SUMPRODUCT(ARRAYFORMULA(INDIRECT(A1&"!"&"D:D")+
INDIRECT(A2&"!"&"D:D")+
INDIRECT(A3&"!"&"D:D")+
INDIRECT(A4&"!"&"D:D")))
note1: in this case result is 25 as sum of 10 + 15.
10 is sum of sheet1!D:D
and 15 is sum of sheet2!D:D
note2: there is no sheet3 and sheet4 which is equal to 0 in INDIRECT
note3: D:D of the sheet where you have the list of sheets needs to be empty
I am looking to take several columns in Google Sheets and combine them into one with the column header in an adjacent cell.
I would like to go from something like this:
to something like this:
I am currently achieving this by arraying the first column over and over for the number of columns. I am then arraying each column on on top of another so something like this:
Column 1 Column 2
={A1:A4;A1:A4;A1:A4} ={B1:B4;C1:C4;D1:D4}
In a third column I am using an if-then statements to get the Column name wherever the name column = "Name"
My issue is when I am trying to do this with several columns is becomes very tedious to build out these arrays. I am looking for help with a single formula to achieve this by just referencing the range for all columns.
It's a little tricky, but possible. For explanatory reason I am not putting everything into one, convoluted formula, but present step by step solution. DISCLAIMER: It's fast one, so it in not perfect.
Assumptions:
"Start" data are in Sheet named "Data"
Result is in Sheet named "Result"
Procedure
Add one column (A) to "start" data with this code in A1 (it will be our index):
=ArrayFormula(if(B1:B<>"";row(A1:A)-1;""))
In "Result" sheet put in A1 this code:
=ArrayFormula(INT((ROW(B1:INDIRECT("C"&(COUNTA(Data!$B1:B)-1)*4))-1)/4)+1)
In B1 this code:
=ArrayFormula(if(A1:A<>"";VLOOKUP(A1:A;Data!A1:E;2;0);"" ))
In C1 this:
=transpose(SPLIT(REPT(TEXTJOIN("*";1;Data!C1:1)&"*";COUNTUNIQUE(B1:B));"*";0;0))
In D1 this:
=ArrayFormula(IFERROR( VLOOKUP(B1:B;Data!B1:F;MATCH(C1:C;Data!B1:F1;0));""))
Finally in F1 - to clean the result put this:
={{"Name"\"Column"\"Number"};{B1:D20}}
Link to working copy
Link to spreadsheet
Final thoughts
You can pack everything into one formula
Its very hasty solution, so it will not expand to more than 4 columns by itself (One, Two, etc). This is hard-coded now. If you can't figure it out, just give me a comment - I will show this places / fix them to make it dynamic