Using Cell Reference in Range_String in IMPORTRANGE in Google Sheets - google-sheets

tl;dr Need a way to substitute 'range_string' in IMPORTRANGE with cell referencing to an input field in the current sheet.
I started off with this query(working well):
=Query({IMPORTRANGE("URL_Y","25 July - 31 July!A16:E26")},"select Col5 where Col3 is not null order by Col5")
I want the formula to apply to new sheetnames in workbook Y. I tried to replace "25 July - 31 July" using cell reference by:
Having an input box(A1 in the current worksheet) for my friend to paste the new sheet name created in Y.
In cell M3, I used =CONCATENATE(A1,"!A16:E26") so that M3 could be referenced directly as range_string:
=Query({IMPORTRANGE("URL",=indirect(M3))},"select Col5 where Col3 is not null order by Col5")
but it returned:
function INDIRECT parameter value is '25 July - 31 July!A16:E26'. It is not a valid cell/range reference.
Is it because there are no " " double quotation marks around the string? I tried CHAR(34) but it gave '"25 July - 31 July!A16:E26"', with the same error above.
It's my first time working with these and I'm having trouble allowing Apps Script to run (autoflagged as unsafe) so I'm stuck with formulae, maybe macros. Tried googling for the whole day but I'm not getting anywhere.
Otherwise, I'm open to any suggestions. How can I achieve this?
(Removed the actual URL as there are personal identifiers are found in the sheets, sorry about that!)

Instead of the concatenate formula try (in M3)
="'"&A1&"'!A16:A89"
Then in the importrange try
=Query({IMPORTRANGE("URL", M3)},"select Col5 where Col3 is not null order by Col5")

Related

Formatting and organizing time entries in Google Sheets

I have tables with Start and End time data entered in either an AM/PM cell for each day in this spreadsheet. How do I organize and display the number of hours between the two times to end up with a graph that looks like the second image below?
Starting data
Desired data
Challenges/variables:
Data is provided in free text so it may not be in a time format. Usually it is 1, 2, 4 or 5 characters but it might be anywhere from 1 -5 characters with some variations depending on the use of a colon. For example, 1, 10, 130, 1:30, 1130, 12:30.
My approach
IF(RIGHT(B2,2)="AM",text(IF(AND(LEN(C2)>0,LEN(C2)<3),
C2&":00",IF(LEN(C2)>3, C2, "")), "HH:MM AM/PM"),
IF(RIGHT(B2,2)="PM",text(IF(AND(LEN(C2)>0,LEN(C2)<3), 12+C2&":00",IF(LEN(C2)>3,
12+split(C2,":")&":"&RIGHT(C2,2), "")), "HH:MM AM/PM"),""))
I used length to figure out if something was already in a time format, and convert those that weren't. I added 12 to any PM value. If it was blank, it would result in a blank space.
Limitations:
I couldnt get it to work as an array (not sure why)
I realized afterwards that this would not work for 3 or 4 characters where there was no colon Entries like 1120, 145 wont work, for example 7:00 - 1120 = 7:00.
Possible solutions?
1.I think probably a REGEX would work better to convert anything into a time format but other solutions would be possible such as seeing if the 3rd character from the Right was equal to :
2. As far as the reorganization, I think it will require some combination of filter, transpose, or query, but I think a prerequisite might be getting the conversion to work as an array of some sort.
Thanks in advance for your help. The shared spreadsheet is here.
You'll have to add in some more if new time formats are added, but give this a swing
=ARRAYFORMULA(
TRANSPOSE(
QUERY(
QUERY(
IF(ISBLANK(C2:C),,
{A2:A,REGEXEXTRACT(B2:B,"(.*) \|"),
IF(REGEXMATCH(TO_TEXT(C2:C),"AM|PM"),C2:C,
IF(REGEXMATCH(TO_TEXT(C2:C),":"),--(TEXT(C2:C,"HH:MM")&" "&RIGHT(B2:B,2)),
IF(LEN(C2:C)<3,--(C2:C&":00 "&RIGHT(B2:B,2)),
--(REGEXREPLACE(TO_TEXT(C2:C),TO_TEXT(RIGHT(C2:C,2)),"")&":"&RIGHT(C2:C,2)&" "&RIGHT(B2:B,2)))))}),
"select Col1, Max(Col3)
where
Col3 is not null and
Col1 is not null
group by Col1
pivot Col2
label Col1 'Day'
format Max(Col3) 'hh:mm am/pm'"),
"select Col1, Col3, Col2")))
I also added your duration difference to your sheet.
=ARRAYFORMULA(
IF(ISBLANK(H9:J9),,
IF(H11:J11<=H10:J10,
1+H11:J11-H10:J10,
H11:J11-H10:J10)))
The ranges will be different, depending on where you have it. It would be best to remove the TRANSPOSE from the first formula so the days run down the column. I included a demo of this in your sheet.
see:
=ARRAYFORMULA(IF(ISNUMBER(C2:C15)*(IFERROR(TIMEVALUE(C2:C15), 2)<=1), TIMEVALUE(C2:C15),
IF(ISNUMBER(C2:C15)*(IFERROR(TIMEVALUE(C2:C15), 2)=2),
IFERROR(TIMEVALUE(C2:C15&":00 "&REGEXEXTRACT(B2:B15, "AM|PM")),
TIMEVALUE(REGEXREPLACE(C2:C15&"", "(\d+)(\d{2})$", "$1:$2 ")&REGEXEXTRACT(B2:B15, "AM|PM"))),)))

Calculate sum and average treating blank values with specific values based on other column condition without adding helper column

I would like to calculate the sum and average in Google Spreadsheet of a range based on conditions from another column, but treat blanks with a specified value. It can be accomplished using a helper column, but I would like to do it without it. Here is the sample data:
I would like to sum values in column B based on value on Column A, but replacing blanks values with the value specified on E2 and E3 respectivelly.
Here is a sample in google sheet:
https://docs.google.com/spreadsheets/d/1Cv9YxFMHuGq2biNNCdGsjU8cAD_OwCPTR4YCPLc2r34/edit?usp=sharing
I was trying to use the following formulas for the sum of team A but I am not getting the expected result:
=sumif(A2:A,"A", if(B2:B<>"",B2:B,E2)) returns 6 instead of 19
=sum(if(A2:A="A",if(B2:B<>"", B2:B, E2),)) return 27 instead of 19
I cannot use a combintation of sumif and arrayformula like this because it expects a range in the third input argument:
=sumif(A2:A,"A", ARRAYFORMULA(if(B2:B<>"", B2:B,E2)))
I wasn't going to jump in on this one, since it's after midnight and I didn't feel I had the energy to both write and explain such a formula. But I see that you yourself have helped others on this forum. So I'll soldier through for you.
Delete everything from columns G:I (i.e., leave those columns entirely blank); and I suggest removing all of the formatting that you currently have in place in those columns, since it won't make sense after what I propose below.
Place the following formula in G1:
=ArrayFormula(QUERY(FILTER({A2:A,IF(B2:B="",IFERROR(VLOOKUP(A2:A&"*",D:E,2,FALSE),0),B2:B)},A2:A<>""),"Select Col1, SUM(Col2), AVG(Col2) GROUP BY Col1 LABEL Col1 'Team', SUM(Col2) 'Sum', AVG(Col2) 'Average'"))
This one formula will generate all headers, team names and results for all teams' sums and averages.
The virtual array between the curly brackets pairs every element of A2:A with the results of the IF function. That IF function checks to see if B2:B is blank. If so, a VLOOKUP with wildcard is performed to find the Col-A team name at the start of any value in Col D and, if found, returns the corresponding filler value from Col E. (If not found, IFERROR returns 0 as the filler value. It's important to have a numerical value because of the way QUERY works.)
FILTER filters in all of the above results only for those rows where A2:A contains a non-null value.
QUERY then pulls the team names, sums and averages; the LABEL portion of the QUERY assigns your desired column headers to the results.
This formula is not restricted to only two teams. You can add as many teams as you like in A:B and assign as many filler values as necessary in D:E.
It's important to note, however, that the formula relies on the FULL team name found in A:A being found at the beginning of the Col-D values. So if your team name is "Bears," just make sure the corresponding entry in Col-D starts with "Bears" as well (e.g., "Bears blanks" or even just "Bears").
You'll need to format the entire Col H as whole numbers and the entire Col I as 0.00 to match the results you shown in your sample.
ADDENDUM (after further comments from OP):
It seems that what you're saying is that the D:E values in your sample spreadsheet were something you wanted included within the formula itself and that you did not intend for them to be used as a reference list. I think your post's reference to "without a helper column" may have been your attempt to say this; but it was not clear, as with or without that D:E list as a live reference range, the main formula may have relied on its own helper column in addition to that list.
If you want a formula that contains the list:
=ArrayFormula(QUERY(FILTER({A2:A,IF(B2:B="",IFERROR(VLOOKUP(A2:A,{"A",2;"B",4},2,FALSE),0),B2:B)},A2:A<>""),"Select Col1, SUM(Col2), AVG(Col2) GROUP BY Col1 LABEL Col1 'Team', SUM(Col2) 'Sum', AVG(Col2) 'Average'"))
To add further blank-values, just keep adding to this section...
{"A",2;"B",4}
... being sure to follow the pattern of team-comma-value-semi for all but the last entry which will not need the closing semi.
You can use a combination of sumifs and countifs
to add up the non-blanks
=sumifs(B2:B10,A2:A10,"A")
to add up the blanks (and multiply by the default value)
=countifs(A2:A10,"A",B2:B10,"")*E2
all together
=sumifs(B2:B10,A2:A10,"A")+countifs(A2:A10,"A",B2:B10,"")*E2
Average (use countifs to work out how many items):
=(sumifs(B2:B10,A2:A10,"A")+countifs(A2:A10,"A",B2:B10,"")*E2)/countifs(A2:A10,"A")

Combing base data set for a formula from two *other* Google sheets

We have hit the dreaded 5 million rows limit which is so small for any semi-serious data.
We have an important ArrayFormula piece in one of our worksheets (tab) currently that summarizes the data from another worksheet in the same file where time series data is kept with dates. This is our current function:
=ArrayFormula(SUMIFS(DataSheet!$B:$B,
MONTH(DataSheet!$A:$A), 1,
YEAR(DataSheet!$A:$A), 2020)
)
Explanation: This basically summed all of column B in the DataSheet tab for the month of Jan 2020 based on date found in column A of that sheet.
However, this worksheet of data that is now running close to that row limit. We can move it to another Google Sheets file, and refer to the same data via IMPORTRANGE.
The question then is how to refer to that data instead of the DataSheet!$A:$A in the above old formula? Will this reference be replaced by the entire IMPORTRANGE function?
Old:
=ArrayFormula(SUMIFS(DataSheet!$B:$B,
MONTH(DataSheet!$A:$A), 1,
YEAR(DataSheet!$A:$A), 2020)
)
New:
=ArrayFormula(SUMIFS(IMPORTRANGE(filename, rows)!$B:$B,
MONTH(IMPORTRANGE(filename, rows)!$A:$A, 1,
YEAR(IMPORTRANGE(filename, rows)!$A:$A, 2020)
)
This does not work of course, because we cannot have the exclamation ! followed by the column in an importrange. Any other thoughts?
Try this in cell A1 on a fresh, brand new tab somewhere:
=ARRAYFORMULA(QUERY(1*TEXT(IMPORTRANGE("[spreadsheet key]","Sheet1!A:B"),{"mmmyyyy","0.00"}),"select Col1,SUM(Col2) where Col2<>0 group by Col1 order by Col1")
The "spreadsheet key" is the combination of letters and numbers after the "/d/" and before the "/edit..." in the URL of your source sheet.
Obviously, you'd also replace "Sheet1!A:B" with whatever the real tab/column reference is.
Then, select all of Column A and from the Menu choose Format>Number>More Formats>Custom Number Formatting, Then this in the dialog box:
mmmm yyyy
You want to IMPORTRANGE from two different sheets in a different spreadsheet.
While the following formula will import data from both sheets, it will also import the blank rows, so you might have to scroll down hundreds of rows in order to see the data from the second sheet (and this might give your the wrong impression that the second sheet is not getting imported):
{
IMPORTRANGE("SPREADSHEET_ID","CurrentMonth!$A:$J");
IMPORTRANGE("SPREADSHEET_ID","All2020!$A:$J")
}
You can use QUERY in order to filter out blank rows:
=QUERY(
{
IMPORTRANGE("SPREADSHEET_ID","CurrentMonth!$A:$J");
IMPORTRANGE("SPREADSHEET_ID","All2020!$A:$J")
},
"SELECT * WHERE Col1 IS NOT NULL ORDER BY Col1 DESC"
)
Note:
I thought you'd like to sort the data according to the date in column A, please remove ORDER BY Col1 DESC if that's not the case.

Google Sheets Query returning results that don't exist in the source list

I am creating a budget tracker within Google Sheets. I am having trouble with Google Query Language returning results that do not exist in the source data
I have a Google Form into which expenditure can be entered, which populates an associated Sheet in my Google Drive. My Master budget tracker also sits within my Google Drive. I use IMPORTRANGE to pull the data into the Master from the Responses spreadsheet, and then Query to separate this out into different 'expenditure' categories on sheets within the workbook (one for each month). February worked perfectly - all expenditure was found and summed correctly and then the February sheet was duplicated for each month of the year, the formulae or look up terms updated. But March is acting strangely - it is returning a value for March that doesn't exist - and not only does the summed value not exist but the word 'March' also does not exist either, so shouldn't be matching. I have tweaked the code, tried refreshing and rewriting the formula into the cell to force a refresh, re-imported the range from the external spreadsheet, I have tried various parentheses placements (I'm not a SQL or Google Query Language expert, so am feeling my way a bit) as I thought it was something to do with the AND/OR clauses not being 'collated', but none has produced even a different result, it's always the same false value being returned
The query code is as follows:
=query(spend, "select sum(B) where H = '"&$H$1&"' and E='Leisure' or E='Tickets' or E='Parking' or E='Other' label sum(B) ''", -1)
'spend' is the range containing the data imported from the Responses spreadsheet, which includes several post form completion formulae coding the row with a day and a month. Right now, there are only values coded as 'February' in H - nothing else. Cell H1 contains the month name (written in, not formula). This formula works perfectly within the 'February' sheet, and if I update cell H1 to read 'February' in the March sheet it shows the accurate values for February, however, if I enter 'March' in H1 I am getting the odd outcome
I am expecting a £0 result for March, but instead, I am getting a value of £19.46. As previously described - the source list 'spend' only contains values coded as February in H, and the value £19.46 does not appear singularly in the list (and doesn't appear to be made by any values when 'summed'). I am at a loss as to what is happening, and no answers seem to address the appearance of mystery values, so I hope I'm not repeating old ground - please do correct me if I am, and many thanks in advance for any guidance
you picked 19.46 because even if H1 wasn't found in Query, Query continued to evaluate for AND and OR statements and sum up a bunch of nonsense
=IFERROR(IF(QUERY(spend,
"select count(H)
where H='"&$H$1&"'
label count(H)''", 0)>0,
QUERY(spend, "select sum(B)
where (H='"&$H$1&"')
AND (E='Leisure')
OR (E='Tickets')
OR (E='Parking')
OR (E='Other')
label sum(B)''", -1), ), )
I think you might just want to try this:
=query(spend, "select sum(B) where H = '"&$H$1&"' AND (E='Leisure' OR E='Tickets' OR E='Parking' OR E='Other') label sum(B) ''", -1)
EDIT: This will cause an error since it will return an empty query, so try this instead.
=iferror(query(spend, "select sum(B) where H = '"&$H$1&"' AND (E='Leisure' OR E='Tickets' OR E='Parking' OR E='Other') label sum(B) ''", -1),0)

How do I do a date-based query in new Google Spreadsheets?

I am using the new Google Spreadsheets that was rolled out a couple of weeks back. I'm using a following query to pull data out of another spreadsheet:
=QUERY(IMPORTRANGE("https://docs.google.com/spreadsheet/ccc?key=blablathisisanexample", "samplesheet!A:D"), "select SUM(Col4) where ( Col1 >= date '2012-1-1' ) ")
The query works perfectly well if I remove the bit 'where ( Col1 >= date '2012-1-1' )'. It will pull data and sum it correctly.
But what's wrong with my where-col1-date filter thingy? It's written the way it was in previous version of Google Spreadsheet, and it gives no error messages. It just returns a header and no result, as if it didn't find a single date. The dates in the data file are in column 1, written in format 4/7/2014, for example. This used to work in the previous version and I'm at a loss now.
I have several suggestions here. But first: Let's copy the "2012-1-1" value to a particular cell, say F5, and write it with the exact same date format az in the original spreadsheet: 1/1/2012.
Use FILTER function:
=SUM(FILTER(IMPORTRANGE("https://docs.google.com/spreadsheet/ccc?key=blablathisisanexample", "samplesheet!D:D"), IMPORTRANGE("https://docs.google.com/spreadsheet/ccc?key=blablathisisanexample", "samplesheet!A:A")>=F5))
I admit that it's not that pretty because of the two ImportRange functions, but it works for sure, I tried it.
If you insist on using QUERY then try to replace the where condition as follows:
"select SUM(Col4) where ( Col1 >= " & F5 & ")"
I haven't tried this one, but the first one (with FILTER) should work.

Resources