How to sync two sheets with =importrange() in two googlespreadsheet? - google-sheets

I'm using =importrange() function to sync (echo sync) two sheets in two different spreadsheets (as described here). But, the importrange() it is not syncing to the second sheet when I make a change in the first sheet. Once imported, the cells stay static and do not alter as more changes are made in the first worksheet. Is there a way to fix it?

I don't think you'll be able to use the =importrange() function on two sheets because as soon as you add the function to the second sheet it will be importing the function you added to the first sheet with it's own ID as an argument.
You could use Google Apps Script, I have just answered a very similar question here. But I'll repeat what I wrote below.
One way you could accomplish this is by adding a script to both spreadsheets that copies it's contents to the other spreadsheet on a change trigger. For example if you were to add something like the below to both spreadsheets, swapping the source and destination information around.
var sourceSpreadsheetID = "ID HERE";
var sourceWorksheetName = "SHEET NAME HERE";
var destinationSpreadsheetID = "ID HERE";
var destinationWorksheetName = "SHEET NAME HERE";
function importData() {
var thisSpreadsheet = SpreadsheetApp.openById(sourceSpreadsheetID);
var thisWorksheet = thisSpreadsheet.getSheetByName(sourceWorksheetName);
var thisData = thisWorksheet.getDataRange();
var toSpreadsheet = SpreadsheetApp.openById(destinationSpreadsheetID);
var toWorksheet = toSpreadsheet.getSheetByName(destinationWorksheetName);
var toRange = toWorksheet.getRange(1, 1, thisData.getNumRows(), thisData.getNumColumns())
toRange.setValues(thisData.getValues());
}
Just add a change trigger for the importData function and then when any changes are made to either document it will copy the contents to the other spreadsheet, thus keeping the both synced.
Obviously if both spreadsheets are being updated at the same time you will run into trouble.

That was pretty helpfull script . Have edited some changes , in your script so that even multiple sheets can be synchronized for a give column and row .the code is a bit slow but works good.
I am now thinking if there was a way to merge multiple sheets using the same method , if it does it should be awesome .
// sync multiple sheets to a source sheet ( “sheet 1”)
// change active sheet name to the designated sheet names.
function importData(){
var ss = SpreadsheetApp.getActiveSpreadsheet();
var activeSheet = ss.getActiveSheet();
var activeSheetName = ss.getActiveSheet().getSheetName();
// set the sheet to copy from sheet 1 to sheet 2. sheet 1 active sheet.
if( activeSheetName == "Daily report Counselling" )
{
var thisSpreadsheet = SpreadsheetApp.getActiveSpreadsheet();
var thisWorksheet = thisSpreadsheet.getSheetByName("Sheet1");
var thisData = thisWorksheet.getRange("A5:H");
var toSpreadsheet = SpreadsheetApp.getActiveSpreadsheet()
var toWorksheet = toSpreadsheet.getSheetByName("Sheet2");
var toRange = toWorksheet.getRange("A7:H");
toRange.setValues(thisData.getValues());
}
// if sheet 1 has not the active sheet choose from sheet 2.
if( activeSheetName == "Follow Up Needed Editable" )
{
var thisSpreadsheet = SpreadsheetApp.getActiveSpreadsheet();
var thisWorksheet = thisSpreadsheet.getSheetByName("Sheet2");
var thisData = thisWorksheet.getRange("A7:H");
var toSpreadsheet = SpreadsheetApp.getActiveSpreadsheet();
var toWorksheet = toSpreadsheet.getSheetByName("Sheet1");
var toRange = toWorksheet.getRange("A5:H");
toRange.setValues(thisData.getValues());
}
}
Please let me know if something interesting comes in the way .

Related

Google Sheets Error: The parameters (String) don't match the method signature for SpreadsheetApp.Sheet.getActiveCell

Trying to move data from one sheet to another if two sets of data in each sheet corresponds (the date in this case). I keep getting the following error:
Exception: The parameters (String) don't match the method signature for SpreadsheetApp.Sheet.getActiveRange
I've seen some things to suggest I might not be pulling through from the sheet I've named, or that it's pulling through the value wrong? Not sure, any advice would be great.
Code:
function pullData(){
var ss = SpreadsheetApp.getActiveSpreadsheet()
var inputSheet = ss.getSheetByName("Input");
var currentSheet = ss.getActiveSheet();
var dateCell = inputSheet.getActiveCell("C2").getValue();
var inputRange = inputSheet.getActiveRange("C6:Z999");
var currentRange = currentSheet.getActiveRange("C6:Z999");
if (dateCell == currentSheet.getActiveCell("B2").getValue()){
var inputRows = inputRange.getNumRows();
var inputCols = inputRange.getNumColumns();
for (var i = 1; i <= inputRows; i++) {
for (var j = 1; j <= inputCols; j++) {
var inputValue = inputRange.getCell(i,j).getValue();
var currentValue = currentRange.getCell(i,j).setValue(inputValue);
}
}
}
}
When the value of cell "C2" of the sheet Input is the same with the value of cell "B2 of the active sheet, you want to copy the values of cells "C6:Z999" of the sheet Input to the cells "C6:Z999" of the active sheet.
You want to know the reason of the following error message.
Exception: The parameters (String) don't match the method signature for SpreadsheetApp.Sheet.getActiveRange
Modification points:
getActiveRange() has no arguments. But you use the arguments. I think that the reason of your error message is this.
Also, getActiveCell() has no arguments. So in your script, I think that an error occurs at var dateCell = inputSheet.getActiveCell("C2").getValue();. From this situation, I thought that your tested script might be different from the script in your question.
When I saw the flow of your script, I thought that your goal might be as follows.
When the value of cell "C2" of the sheet Input is the same with the value of cell "B2 of the active sheet, you want to copy the values of cells "C6:Z999" of the sheet Input to the cells "C6:Z999" of the active sheet.
If my understanding is correct, getActiveCell("C2"), getActiveRange("C6:Z999") and getActiveCell("B2") might be getRange("C2"), getRange("C6:Z999") and getRange("B2"), respectively.
Pattern 1:
In this pattern, your script is modified for removing the error message.
Modified script:
Please modify your script as follows.
From:
var dateCell = inputSheet.getActiveCell("C2").getValue();
var inputRange = inputSheet.getActiveRange("C6:Z999");
var currentRange = currentSheet.getActiveRange("C6:Z999");
if (dateCell == currentSheet.getActiveCell("B2").getValue()){
To:
var dateCell = inputSheet.getRange("C2").getValue();
var inputRange = inputSheet.getRange("C6:Z9");
var currentRange = currentSheet.getRange("C6:Z9");
if (dateCell == currentSheet.getRange("B2").getValue()){
Pattern 2:
In this pattern, your script is modified by reducing the process cost. In your current script, getValue() and setValue() are used in the for loop. In this case, when inputRows and inputCols are large, the process cost will be high. So in this pattern, I would like to propose to reduce the cost.
Modified script:
Please modify your script as follows. In this modification, the values of cells "C6:Z999" of the sheet Input are copied to the cells "C6:Z999" of the active sheet using copyTo. By this, your goal can be achieved without using the for loop.
function pullData(){
var ss = SpreadsheetApp.getActiveSpreadsheet()
var inputSheet = ss.getSheetByName("Input");
var currentSheet = ss.getActiveSheet();
var dateCell = inputSheet.getRange("C2").getValue();
var inputRange = inputSheet.getRange("C6:Z9");
var currentRange = currentSheet.getRange("C6:Z9");
if (dateCell == currentSheet.getRange("B2").getValue()){
inputRange.copyTo(currentRange, {contentsOnly:true}); // Modified
}
}
References:
getActiveRange()
getActiveCell()
copyTo(destination, options)

How can I assign a Google Sheet script to only one sheet?

I have this script here, but I want it to only run on ONE specific sheet named "Nes Smart Data" (SheetNo5). Currently it runs on all sheets and puts the data on cells where I don't want them to be. Can you help me correct the code? Thanks a lot!
function onEdit(e){
var sheet = SpreadsheetApp.getActiveSheet();
var range = e.range;
var column = range.getColumn();
var row = range.getRow();
var text;
if (column==11) { //Replace 2 with the column number of your comments cell//
var newRange = sheet.getRange(row,column-5); //If the date is in the next column
var today = Utilities.formatDate(new Date(),Session.getScriptTimeZone(),'dd.MM.yyyy');
newRange.setValue(today);
}
if (column == 11){
text = sheet.getRange(row, 23).getValue();
sheet.getRange(row, 23).setValue(text + e.value+".");
}
}
Replace the following variable and things should work as desired -
Current:
var sheet = SpreadsheetApp.getActiveSheet();
Modification proposed:
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Nes Smart Data');
Let me know if it doesn't!

Series of Basic Google Sheet functions combined

So I am new to Google Sheets. I am making an inspection report for a small company using Sheets. I would like to add a button to the bottom of the sheet which does the following script:
Duplicate original sheet
Rename sheet to a cell value +today's date. i.e Fred01011980
Email the sheet as a PDF to a recipient.
Finally clear the inputted values in the original master template sheet.
I have looked up how to do each of these and a few of them are straightforward, but I don't know how to combine them. Can I just add all of the functions individually together without any additional syntax needed? Any help on this would be really appreciated. Thank you.
I believe you can just create another function that calls your functions, like this:
function doAllStuff() {
doStuff();
doMoreStuff();
}
Here's how I did it:
function AllinOne() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var name = "Inspection";
var sheet = ss.getSheetByName("Inspection").copyTo(ss);
var newname = ss.getSheetByName("Inspection").getRange(2, 2).getValue();
var newnamedate = ss.getSheetByName("Inspection").getRange(3, 2).getValue();
var sheetx = ss.getActiveSheet()
var thisSheet = sheetx.getName();
var actualSheetName = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet().getName()
var sheetfinal = ss.getSheetByName("Inspection")
var old = ss.getSheetByName(newname+newnamedate);
if (old) ss.deleteSheet(old);
sheet.setName(newname+newnamedate); //copies the sheet and renames it to "store+date"
ss.setActiveSheet(sheet)
// below is pdf conversion
var originalSpreadsheet = SpreadsheetApp.getActive();
var sourcesheet = originalSpreadsheet.getActiveSheet();
var sourcerange = sourcesheet.getRange('A1:B176'); // range to get - here I get all of columns which i want
var sourcevalues = sourcerange.getValues();
var data = sourcesheet.getDataRange().getValues();
var newSpreadsheet = SpreadsheetApp.create(thisSheet); // can give any name.
var sheetnow = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
var projectname = SpreadsheetApp.getActiveSpreadsheet();
var sheetz = sourcesheet.copyTo(newSpreadsheet);
var destrange = sheetz.getRange('A1:B176');
destrange.setValues(sourcevalues);
newSpreadsheet.getSheetByName('Sheet1').activate();
newSpreadsheet.deleteActiveSheet();
var pdf = DriveApp.getFileById(newSpreadsheet.getId());
var theBlob = pdf.getBlob().getAs('application/pdf').setName(newname+newnamedate);
var folderID = "File_ID"; // Folder id to save in a folder.
var folder = DriveApp.getFolderById(folderID);
var newFile = folder.createFile(theBlob);
DriveApp.getFileById(newSpreadsheet.getId()).setTrashed(true);
MailApp.sendEmail("Email","New Manager Inspection: "+newname+newnamedate, "A new Manager Inspection Report has been added to the Drive.");
ss.getSheetByName(name).getRangeList(["B176","B150:B164","B138:B146","B129:B134","B119:B125","B106:B115","B99:B102","B84:B95","B78:B80","B66:B74","B55:B62","B48:B51","B34:B44","B25:B30","B18:B21","B10:B14","B4:B7","B2","B16","B23","B32","B46","B53","B53","B64","B76","B82","B97","B104","B117","B127","B136","B148","B166"]).clearContent();
ss.setActiveSheet(sheetfinal);
SpreadsheetApp.getUi().alert("Report Submitted, Please do NOT Resubmit. Thank You");
}

Sharing Google sheets using addEditor

I am making a spreadsheet for people to submit information and when they submit the information on the entry sheet, the data is copied to a new sheet and then cleared from the entry sheet so that it is ready for another entry. When the new sheet is created, it is renamed and then shared with me so that I can view each sheet that people send in. Right now my script isn't working and I am not receiving the new sheets when they are made.
function Copy() {
var sss = SpreadsheetApp.getActiveSpreadsheet();
var ss = sss.getSheetByName('Sheet1');
var range = ss.getRange('A1:J30');
var strange = ss.getRange('A2:J30');
var data = range.getValues();
sss.appendRow(data[0]);
strange.clear();
var tss = SpreadsheetApp.create('New Entry');
var ts = tss.getSheetByName('Sheet1');
ts.getRange(1, 1, data.length, data[0].length).setValues(data);
var r = ts.getRange('A2:A3');
r.getA1Notation() == 'A2';
tss.setName(r.getValue());
tss.addEditor("john.doe#gmail.com");
}

Give the copy a specific name, sheets

How can I give a copy of one of my spreadsheets a specific name. Like giving them a week number.
This is what I have so far:
var sheet = SpreadsheetApp.getActiveSpreadsheet();
var destFolder = DriveApp.getFolderById("***********");
DriveApp.getFileById(sheet.getId()).makeCopy("Copy", destFolder);
So how can I add a number (from the sheet preferably) to the new file name "copy"?
I figured it out. Here it is:
var sheet = SpreadsheetApp.getActiveSpreadsheet();
var destFolder = DriveApp.getFolderById("*********");
var weekNumber = sheet.getRange("E1");
var week = [weekNummer1.getCell(1, 1).getValue()];
DriveApp.getFileById(sheet.getId()).makeCopy("Copy"+ (week), destFolder);

Resources