I have a targeted table that uses ImportRange to retrieve some data from another Source spreadsheet, as in
A6 = query(ImportRange("mykey", "Weekly!B:BI"), CONCATENATE("select * WHERE Col1='",B3,"'"), 0)
The select clause is to select the data that matches the value in B3 - if this cell value is changed, then the import is updated "immediately".
I want to be able to force update if someone changes something in the source spreadsheet so that we see that this is reflected in Target “immediately”. Currently, this happens only after some indefinite time, which is a minute or so, and too slow for my purposes.
Update:
In accordance with the answer and comments below, I added the UpdateTarget function in the source, which is called from the edit * trigger:
function UpdateTarget() { try { var ss = SpreadsheetApp.openById("targetID"); } catch(err) { Browser.msgBox(err); } var sheet = ss.getSheetByName("Weekly"); sheet.getRange("A4").setValue("=query(ImportRange("sourceID", "Weekly!B:BI"), CONCATENATE("select * WHERE Col1='",B3,"'"), 0) "); SpreadsheetApp.flush(); }
This works more efficiently, but I can also have a script to write updated values directly to the target if I go along this route.
I really wanted Target to be a template that other users could duplicate, and that would extract certain "live" data from the main source, I do not want to implement scripts in the source that need support when adding new targets.
I think that I really need to reformulate the formula so that it depends on the cell, which can be edited and cause a recount, but does not affect the result?
(* Aside: I found that the openByID function returns an “Action is not allowed” exception if it is called through an explicit trigger - onEdit is prohibited for editing other spreadsheets - see https://developers.google.com/apps-script / understanding_triggers ).