My IMPORTRANGE function is not refreshing with new data once the linked spreadsheet is added to. Instead, I am having to cut and paste all of the formulae again whenever I want to view the new information.
I'm using the new version of Google Sheets and I know there were some issues around the release of this with the IMPORTRANGE function.
I currently have 24 columns of data that I'm importing and the original spreadsheet will just keep growing as it is linked to a form. This is the main reason I'm using IMPORTRANGE, as it will help to keep the original spreadsheet working at maximum speed.
What I'd like to know is, has anyone else had a problem such as this, and if so is there any work around (in apps script/another function)? In worst case scenario, is there an apps script about which would clear the spreadsheet and re-enter all of the formulae on open/on a menu click as it really is a pain updating every column every time a new entry is made.
EDIT - Almost all of the cells I'm trying to import are formulated within the original spreadsheet if that changes anything - EDIT
In the spreadsheet settings under "File", go into the Calculations tab and change the Calculation Setting to "On Change and every minute". I had to do this on another importrange sheet and it did the trick for me.
What solves the problem? Setting the same owner for both spreadsheets: the one that you import data from and the one where you use importrange formula. I had the same problem. I updated the source and no response on final spreadsheet. After setting same owner for both spreadsheets refreshing takes few seconds
I've worked out an ultimate (and very simple) solution to any importrange problems. Let's say you have your data in Sheet1 and it's being collected from a google form. You'd like to importange it somewhere else but newly received rows don't trigger importrange refresh. The solution is to move the data using QUERY to Sheet2 (in the same file) and then importrange the data from Sheet2 to another file; it's easy to force refresh of the QUERY function using simple macro, below I pasted simplified version of my function:
function myFunction() {
var spreadsheet = SpreadsheetApp.getActive();
spreadsheet.setActiveSheet(spreadsheet.getSheetByName('Sheet2'), true);
spreadsheet.getRange('A1').activate();
spreadsheet.getActiveRangeList().clear({contentsOnly: true, skipFilteredRows: true});
spreadsheet.getCurrentCell().setFormula('=QUERY(\'Sheet2\'!A:Z;"SELECT *";1)');
};
So basically I clear the A1 cell that contains the QUERY formula and then I fill it with the same QUERY formula. I set this macro to trigger every 1 minute. Works like a charm.
A trick that seems to work
Instead of
=importrange("Relevant_Sheet_ID","Archive!a1:p259")
Use the below just adding => &"?"&now()
=importrange("Relevant_Sheet_ID"&"?"&now(),"Archive!a1:p259")
Basically, it fools GoogleSheets to think the data set referred is ever changing by adding a timestamp through a now() function.
Feedback welcomed, seems to work for me, but might not be consistent.
Click File > Spreadsheet Setting... and check both sheets are in the same Locale and if responces are comming from Jotforms, set the same Locale there too.
Make a copy of your master sheet and change url of your importrange function. it's work for me..
=importrange(new_master_sheet_copy_url,string_range)
Related
I have sheet named origin that displays set of data Col A:B via ImportRange
I have a sheet named destination
What I wanted to do:
When ImportData changes (a new item is added in the origin sheet) I wanted to copy that
item and paste it in the destination sheet.
What I dont want to happen:
Is copy data that are already existing in the destination sheet.
When ImportData Origin is sorted, the display in the origin sheet is
also changed. In this case I should still be able to copy data that
are not existing in the destination sheet even if both sheets are no
longer sorted the same.
Any idea on how I can achieve this?
Thank you so much
Explanation:
I would advice you to use a formula in the destination sheet, something like:
UNIQUE(IMPORTRANGE("url", "origin!A1:B"))
so you can have the unique items of the origin sheet in the destination sheet.
The reason that I am suggesting that is because you are looking for a trigger behaviour. Namely, when a new value is added in a cell, grab this value and send it to another spreadsheet. The problem with this approach is that Google-Apps-Script triggers are not triggered by scripts nor formulas, but only by user edits. In other words, if a cell is modified by your import range formula, there is not a direct GAS solution which can figure that out. Only workarounds exist which might have limitations and they are very specific to your exact use case.
Workarounds
See this thread for some info and references.
You can use the Properties Service which you can store some sort of data that is bound the script. In this way, you can create a Time-driven trigger which will run every 1 minute or so and check if there are changes to the original data. If a new value is added, update the property and send the data to the destination sheet. If no new data is added, do nothing.
I have a scheduled addon, which writes data periodically into a Google Sheet, without to open file. I have a formula, which should make some calculations on written data and write calculated values into the sheet, so then Data Studio with this sheet as data source updates the visualization.
What is the way to periodically run a formula calculation and write calculated values without manual steps like opening file?
I'm pretty new to this topic: my search approaches to find something like convert formula to app script or schedule formula execution brought me not to any fruitful idea.
PS_ the formula, which should do the calculation is:
=IFERROR(((VLOOKUP(A2,'[1]SV'!$A:$B,2.0))/B2)+(IF(B2=1,"33,9",IF(B2=2,"16,28",IF(B2=3,"10,36",IF(B2=4,"7",IF(B2=5,"5,64")))))+IF(B2=6,"4,13",IF(B2=7,"3,27",IF(B2=8,"2,61",IF(B2=9,"2,18",IF(B2=10,"1,82")))))+IF(B2=11,"1,77",IF(B2=12,"1,81",IF(B2=13,"1,85",IF(B2=14,"1,9",IF(B2=15,"2,04")))))+IF(B2=16,"1,68",IF(B2=17,"1,61",IF(B2=18,"1,65",IF(B2=19,"1,62",IF(B2=20,"1,59","0")))))),0)
If i would know, how to convert the formula to app script, i would manage the rest - i'm familiar with running scripts with time based trigger. Or, maybe, there is a method to run formula on the same scheduled way, like scripts...?
*Disclaimer: I have not tried this and it might not work, if it doesn't, comment and I will try to provide another solution
OK here's what i would try:
In google scripts there is a trigger function, manly used for testing. what it does is it runs your script and sends you an email if there is a error, and hypothetically, you could use this to run you script periodically.
A couple of other things I may try if this doesn't work, leave a comment if you would like me to go in depth about these:
depending on how you want this to work, you could set up a web app to do this, and instead of opining google sheets open the web app with a timer built into the script, that would trigger as long as you had the web page opened.
It might also be possible to run the script automatically with a JavaScript function, requires more research.
If Google Data Studio is not showing you the correct value then you could use a time-driven trigger to save the formula results in another cell. Example:
function respondToTimeDrivenTrigger(e){
var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
/** The range holding the formula */
var range = spreadsheet.getRange('Sheet1!A1');
/** The value returned by the formula */
var value = range.getValue();
/** Write the value to the cell to the right or the source cell */
range.offset(0,1).setValue(value);
}
Resources
https://developers.google.com/apps-script/guides/sheets
https://developers.google.com/apps-script/guides/triggers/installable
I'm using this code to use data in a Google Apps Script:
function getCurrentRow() {
var currentRow = SpreadsheetApp.getActiveSheet().getActiveSelection().getRowIndex();
return currentRow;
}
But when I use other sheet than the first one (number "gid=0"), my function remains getting data from that first sheet and not from my current active sheet. Since I'm using the method .getActiveSheet() how can I fix that?
PS - I'm not calling the code from a cell. I'm using this code:
http://opensourcehacker.com/2013/01/21/script-for-generating-google-documents-from-google-spreadsheet-data-source/
I created from scratch a brand new spreadsheet, within which, I created a few tabs/sheets with some data within each; and then in google apps script in that spreadsheet I installed the following code:
function getCurrentRow() {
var currentSelection = SpreadsheetApp.getActiveSheet().getActiveSelection()
var currentValue = currentSelection.getValue();
var currentRow = currentSelection.getRowIndex();
Logger.log(currentValue);
Logger.log(currentRow);
return currentRow;
}
I ran the script, and it gave me the correct results for the sheet that was open/which cell was selected. So I would say that this code pretty much works as you expect.
In your case, may I suggest that the quickest way to get more info about the error, or to see if the error persists, is for you start from scratch too, with a new spreadsheet, and paste in the code above, and then test to prove that at least that much works for you too. Then, only after this, paste in the greater code (that you have linked to), and see if it still/stops working.
I'm having the same problem while developing in the Script Editor -- the Script Editor instance/window becomes 'disconnected' from the Sheets instance/window and just has the first sheet / A1 etc as the 'actives'.
What worked for me:
Closing the Script Editor window and re-opening from Sheet > Tools > Script editor. Voila, .getActive...()s are working again.
Also:
As implied by some of the other answers, triggering the execution from the Sheets window/instance (probably always) also works. One of the answers calls a function from a cell, which means it's going to be triggered by the Sheet. Another option would be to add a .UI menu and menu-option and trigger it there.
Do you use your function as a formula?
Maybe I'm not understanding well the case, but using your code as a formula, it works as expected.
In Sheet1 (Active) apply the formula:
Then manually change the Sheet2 (Active) and apply the formula again:
Its because you are calling it from a custom function in a cell. You cant do that because custom functions must be deterministic. The answer from wchiquito works because he is using a different cell to try the 2nd case. If you use the same cell it will show the old cached result. Search s.o. for the issues about dedeterministic functions. Ive provided workarrounds in those (basically pass a second param =now()
create a spreadsheet in google drive and save it.
In the spreadsheet go to tools menu and script editor
and type the function.
I have created a form that pushes data to a Google Spreadsheet. The data is latitude, longitude, location, and other identifying data. The spreadsheet is then published as a .CSV file and imported into ARC GIS to be displayed on an interactive map. It works exactly as I wanted and I set it to republish after each change.
The problem is that when the spreadsheet has rows appended by the script, it is not seeing it as a change and republishing. In order to get the updated data imported to the map, I need to go in and manually republish. Is there anyway through the Google Apps Script that I could make a few lines of code to force a republish? I could then add that to the "on form submit" script I have or another time based one that already runs at 3 am everyday.
I have looked through the Google Apps Script documents and not found anything. When searching for help on the web, the overwhelming majority of responses are for how to publish your script as a template for other.
My testing sheet was republished after the following function was executed by either a menu entry or a time-based trigger.
function ChangeIt() {
var sheet = SpreadsheetApp.getActiveSpreadsheet()
var t = new Date()
var x = 'upd: ' + t
var range = sheet.getRange('a3')
range.setValue(x)
}
If I were in your shoes, I'd add an extra column to the end of the sheet with some benign constant data that a script can change without affecting the systems consuming the data. If an extra column isn't an option, try modifying my sample to read in a current value, change it, and immediately change it back.
Also, I'd see if the spreadsheet onEdit() trigger fires when the form submit adds a new row. If so, tie your GAS function to it to force the republish. If not, setup a timed trigger to execute the GAS function.
A quick workaround for this issue that doesn't require scripting is to simply make an array copy of the data.
For example, I made a new tab and in A1 put this: =ArrayFormula('Form Responses 1'!A1:Z1000)
While the main Form responses tab will insert rows and not play nice with formulas this new tab stay nice and constant and updates automatically when new data is added.
I have a spreadsheet which extracts and accumulates all the required data from other 6 spreadsheets using Vmerge and Query formulas and all the consolidated data will be converted to pdf and emaild to mail ids using trigger event.
Here begins the problem every time the attachment mail posted consist all the headers and other format, but the data which is extracted does not appear. It seems to appear like - to open the same spreadsheet, after a while all the - (hyphens) are replaced by the data / Hope all the data updates after a while of opening the spreadsheet.
link for sheet
Can anyone direct me to make this issue sorted out.
For this solution should be -> all the data should be updated and then the email script should work; or either it should update before emailing script starts.
Or any other better ideas are appreciated.
Some spreadsheet formulas, like ImportRange and ImportXml (and also Apps Script custom formulas) are only evaluated when there's someone logged in the spreadsheet. It's like these functions need an account to be evaluated from, for example, in importRange the account logged in must have access to the range being imported, if you share this spreadsheet with someone but not the importRange source, when this person is viewing this spreadsheet, the importRange function will not work (well, unless you're also in the spreadsheet and the formulas have already been evaluated).
Bottom line is, you can't have this formulas and use a script triggered on time-driven (or other trigger that does not require someone logged in) and expect the script to be able to read this data.
The workaround though is quite simple. Do what the importRange function does inside your script! e.g.
var source = SpreadsheetApp.openById('source-spreadsheet-key');
var data = source.getSheetByName('List').getRange('I6:AT500').getValues();
//then save it somewhere
var s = Spreadsheet.getActive().getSheetByName('hidden-import');
s.getRange('I6:AT500').setValues(data);
SpreadsheetApp.flush(); //force the data to be written
//so all the other formulas on your spreadsheet get updated with the new data
All your "logic" formulas, like query and vmerge, which are difficult for the script to mimic, can be left on the spreadsheet, but reference this "hidden-import" sheet I just invented instead of nesting importRange directly.
[edit]
To copy only non-empty rows do like this:
var data = SpreadsheetApp.openById('source-spreadsheet-key').
getSheetByName('List').getDataRange().getValues();
Spreadsheet.getActive().getSheetByName('hidden-import').
getRange(1,1,data.length,data[0].length).setValues(data);