Using IMPORTRANGE, INDIRECT, and CONCATENATE together - google-sheets

I have a sheet that pulls numbers from several different sheets to amalgamate numbers. Each week, a new sheet is added to the source files, all with the same name. I'd like to update the amalgamated sheet by changing one cell instead of many.
When the tab is located in the same Google sheet, this is easily done with INDIRECT.
Right now, the formula in the amalgamated sheet is:
=IMPORTRANGE(M4, "Aug29!$F$2")
That formula is on each line to pull from several different sheets:
=IMPORTRANGE(M5, "Aug29!$F$2")
=IMPORTRANGE(M6, "Aug29!$F$2")
and so on.
Each week, the "Aug29" changes to the new date - "Sep5", "Sep12", etc.
What I'd like to do is use INDIRECT to pull that part of the equation in (from cell Z1) so that I don't have to update each formula.
I was thinking I could use CONCATENATE to create the "Aug29!$F$2" portion of the formula with INDIRECT:
=IMPORTRANGE(M4, CONCATENATE(INDIRECT(Z1), "!$F$2"))
The problem is, the IMPORTRANGE formula requires quotations around the range string, and I can't figure out how to add them.
Weird problem, I'm sure, but wondering if there's anyone with a solution?

Short answer
Use =IMPORTRANGE(M4, CONCATENATE(Z1, "!$F$2")) or =IMPORTRANGE(M4, Z1&"!$F$2")
Explanation
INDIRECT requires a string that represents a cell or range references, like "Z1" but it will increase unnecessarily the complexity of your formula.
If Z1 has the name of the sheet, then just concatenate it by using CONCATENATE, CONCAT or &

UNTESTED. Please try something like:
=IMPORTRANGE(M4,Z$2)
with in Z2 something like:
=Z1&"!$F$2"
In other words, I think your IMPORTRANGE does not like INDIRECT.

Related

how can I write a formula that uses a cell's contents when building a range reference to the name of another sheet?

I have a large Google Sheets spreadsheet that has individual sheets for financial statements of activity for multiple years. I want to reference particular columns of those in other sheets, and I've successfully figured out how to do that with an HLOOKUP function. However, because I want to do this for multiple years, I'd like that HLOOKUP function to pick up the name of the sheet to reference from its column header. Right now, I'm hard-coding it like this—you can see the HLOOKUP range refers to cells in the "2021 Overall" sheet. The hard-coded approach works but makes adding a new year tedious. Ideally, the HLOOKUP formula would read the contents of its column header cell to determine which year it is.
As best I can tell, the solution is to use INDIRECT, but I can't figure out any way to build the formulate with INDIRECT and not get an error. For instance, this seemed like it should work. As you can see, I have 2021 in cell D4, and my INDIRECT statement is referencing that and building the rest of the range.
I've also tried using INDIRECT with an explicit CONCATENATE, with no more success.
Any ideas for how to look up that D4 cell and slide it into the HLOOKUP range?
Thank you!
Try to remove the "'"& before D4 and the ' after the Overall.
Your formula should look like this:
=IFERROR(HLOOKUP($A$2,INDIRECT(F4 &" Overall!$A$5:$X$150", Utility!$A10, FALSE)))
With Nikko's nudges in the right direction, I eventually figured out the right format. This allows the formula to work in multiple sheets and to be filled right (for more years) and down (for more classes).
=IFERROR(HLOOKUP($A$2,INDIRECT("'"D$4&" Overall'!$A$5:$X$150"), Utility!$A3, FALSE))
Note that if you try to replicate this, you may need to type the formula out from scratch—I had a problem where pasting it in didn't work. Once I'd retyped it and Google Sheets acknowledged it, it worked from then on in the spreadsheet, even when pasted from sheet to sheet.

Is there a way to copy certain parts of a formula down a column in Google Sheets?

I'm creating a Google Sheet documenting how many times a certain item appears in a video game with the formula in the D column (formatted to a percent):
=IFERROR(C2/SUM(C2:C51))
I want the "C2" cell to apply down the column (C3, then C4, you get the idea), but I want the "C2:C51" array to stay constant while the C2 part gets applied down the down the column. How could I modify the formula to do this? (I could manually edit the formulas all the way down, I only have 50 rows, but I think it would be helpful to learn for the future)
Try this:
=iferror(C2 / sum(C$2:C$51))
See absolute and relative references.
Alternatively, try this array formula that fills a whole column in one go:
=arrayformula(iferror(C2:C51 / sum(C2:C51)))

Google sheets, two-sheet dependent conditional formatting

My problem is probably trivial ... However, I was looking for similar problems and their solutions either do not work for me or I can not apply them.
I have 2 sheets - SheetA and SheetB. They are identical. I want to select every cell in SheetA that is no longer identical to Sheet B.
I was able to use (found here on Stack Overflow) such a function in conditional formatting:
= A1 <> INDIRECT ("SheetB! A" & ROW ())
It works if the range is column A. I know that I can apply this function to each column separately, but there is certainly a way that I can apply the same formula to the whole worksheet.
Will there be anyone who can show me the correct formula?
Edit: I tried to use above formula to every column... And my file become to work very slow... So whoever wants to do the same... think again.
After some tries I decided to move everything from SheetB to SheetA. I paste it a 1000 rows under data of Sheet A. Works fine without "indirect" function. No slow downs. It is not a perfect solution but it works.
But even after my problem is solved different way, I would like to know what is the correct formula for my problem... it might be useful for the future with smaller amount of data.
Solved ;)
You should be able to use the Address function to get the address of the current cell from its row and column:
=A1<>indirect("sheetB!"&address(row(),column()))
or for case-sensitive match:
=not(exact(A1,indirect("sheetB!"&address(row(),column()))))

Google Sheets, Is it possible to use Arrayformula to expand formulas downward when the formula uses arrays

I've been using Arrayformula to auto-expand formulas (such as "=Left(A2:A,B2:B-1") downward, but I need some help understanding this formula. I've read up on the function itself and browsed many forums about this but I can only find articles explaining how to use this with simple formulas, so I'm going to try to as this as simply as possible here: Is it possible to use Arrayformula to expand formulas downward when the formula uses arrays?
The summary for Arrayformula reads "Enables the display of values returned from an array formula into multiple rows and/or columns and the use of non-array functions with arrays." This was my understanding of how Arrayformula populated a formula into rows automatically. Using this I thought of it as writing a formula that generated an array of formulas, and then splitting them up with Arrayformula. This seems to not work with some formulas such as concatenate, which I will focus my question on. This example is far from my real life problem, but if someone could show me a solution I can apply it elsewhere.
Arrayformula spreadsheet example
Usually when I use Arrayformula with A1:A it would expand the formula through the column, referencing the corresponding rows as it went. With this example I want to have Column C be the concatenated result of columns A and B. Is this possible with Arrayformula? This question is not specific to concatenate, that is just the simplest one that came to mind. Another example would be Countif. Lets say I want to see how many values in the first 5 columns are over 20, and I want that formula to auto populate down, is that possible and if so how would it be done?
Arrayformula second example
P.S. Please don't say copy the formula using the drag handle in the lower right.

ARRAYFORMULA with IMPORTRANGE

In column B are listed IDs of Google Sheets. In column C are listed cells, from which I want to import data.
Screenshot of the table
In column D is shown the result of using IMPORTRANGE() by simply dragging it. e.g. for D1 it looks like:
=IMPORTRANGE(B1;C1)
for D2:
=IMPORTRANGE(B2;C2)
and so on.
In column E I want to display the same result but using ARRAYFORMULA that looks like:
=ARRAYFORMULA(IMPORTRANGE(B2:B4,C2:C4))
but the function displays only the data from the first spreadsheet.
People complain about this permissions issue a lot, but it's not hard to solve. What I do is have a sheet which I name "Splash sheet" into which I paste the URLs of the documents I wish to link. To its right is a column headed "permit to connect" which contains IMPORTRANGE formulas importing a single cell from each sheet -- usually a cell containing a confirmation code, number or document name -- on a sheet also named "Splash Sheet." For example,
=IF(B3="enter URL",,CONCATENATE(IMPORTRANGE(B3,"Splash sheet!A1")," ",IMPORTRANGE(B3,"Splash sheet!B1")))
So, when you first connect a spreadsheet via its URL, you get those messages telling you you need to connect, you click the Permit Access, the confirmation code/number/document name appears in the second column, and voilá, your sheets are connected forevermore! Now all your other IMPORTRANGEs referencing that URL will work, and you can use IMPORTRANGE formulas that reference the URL-containing cells on the "splash sheet."
As for the OP's original question, I came here seeking an answer to the same problem, and after more research have realized that we are attempting the impossible here. No way to do this an ARRAYFORMULA. No way around writing formulas that reference every single cell a document's URL may go into.
Problem is you can't make arrays of arrays in spreadsheets; that would involve multiple dimensions, and the medium is inherently two-dimensional. This is what people use databases for.
ARRAYFORMULA doesn't work when importing data (I think it relates to permissions). You could use something like this, =IFERROR(IMPORTRANGE(B5:B7;C5:C7)) and pre-fill the column first, but still there would be the permissions issue. Each new imported sheet needs it's permissions granted by a user.
TLDR: If I understand your intention correctly when you say you would like to see
=ARRAYFORMULA(IMPORTRANGE(B2:B4,C2:C4)), I believe you can make that
happen using the following.
=ARRAYFORMULA(IMPORTRANGE(
INDIRECT(ADDRESS(ROW(B2:B4), COLUMN(B2:B4)),
INDIRECT(ADDRESS(ROW(C2:C4), COLUMN(C2:C4))
)
Breakdown
Use IMPORTRANGE with INDIRECT to create ranges inside ARRAYFORMULA
Call INDIRECT with the ADDRESS function
Call ADDRESS with the ROW and COLUMN functions since they take ranges via ARRAYFORMULA
using IMPORTRANGE with INDIRECT
IMPORTRANGE's two parameters are the spreadsheet url stored in B2:B4 for this example and the range (e.g. sheet!A1:B2) stored in C2:C4.
Since IMPORTRANGE doesn't take a range reference directly as you mentioned, you'll need to build it for each row with ARRAYFORMULA using the INDIRECT function.
INDIRECT can be used to compose a cell reference using A1 notation, for instance
=IMPORTRANGE(INDIRECT("B" & 2), INDIRECT("C" & 2))
will produce the same result as
=IMPORTRANGE(B2, C2)
Since this produces the same result, we now just have to find a way to make INDIRECT work with ARRAYFORMULA
Use ADDRESS to build the parameters for INDIRECT
Next you want to use ADDRESS to build the A1 reference for INDIRECT. For the current purposes, ADDRESS takes a numerical value for row and column as parameters
=INDIRECT(ADDRESS(2,2))
will produce the same result as
=INDIRECT("B" & 2)
Since these two are interchangeable, now we just need to find a way to get the numerical row and column values out of ARRAYFORMULA.
Call ADDRESS using the ROW and COLUMN functions
From there, you can get the row and column indexes from standard A1 notation using the ROW and COLUMN functions. While this may seem like we're pointlessly going in circles, the difference now is that ROW and COLUMN perform as expected with the ranges provided by ARRAYFORMULA. So given that ADDRESS will return $B$2 using using either method below
=ADDRESS(2,2)
or
=ADDRESS(ROW(B2),COLUMN(B2))
we now know that
=ARRAYFORMULA(ADDRESS(ROW(B2:B4),COLUMN(B2:B4)))
will produce the following array of addresses
{ $B$2; $B$3; $B$4 }
Final Assembly
So when we put this all together, we get
=ARRAYFORMULA(IMPORTRANGE(
INDIRECT(ADDRESS(ROW(B2:B4), COLUMN(B2:B4)),
INDIRECT(ADDRESS(ROW(C2:C4), COLUMN(C2:C4))
)
where INDIRECT(ADDRESS(ROW(B2:B4), COLUMN(B2:B4)) is more or less interchangeable with what you might expect from B2:B4 inside ARRAYFORMULA and represents the url parameter
and INDIRECT(ADDRESS(ROW(C2:C4), COLUMN(C2:C4)) is roughly interchangeable with what you might expect from C2:C4 inside ARRAYFORMULA and represents the range parameter.
Suggestions on organization
I recommend using the indentation (Alt +Enter to create a new line ) above along with your indentation of choice to keep it easier to read. In the end it's just a bit more syntactic sugar and if spaces are used well it shouldn't be much harder to understand and make changes to 6 months later.
RE: Permissions - as mentioned by Atiq Zabinski, just placing a simple
IMPORTRANGE("http:/xxxx", "A1") somewhere on the sheet will provide a
means to know if the sheet is connected or not and the error message
should give you a context menu for connecting the sheet. You'll might
want to stay away from error handling in these scenarios as it will
slow down the process of connecting the sheets.

Resources