There isn't a way to share only one sheet of one spreadsheet in Google Sheets. So, you have to share an entire spreadsheet. So, I was thinking in writing a script to synchronize two sheets (each one in a different spreadsheet). I thought using a function to get rows as array to do this. Is there a better strategy to do that?
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.
Two-way synchronization is a hard problem, but one that is solved quite effectively by Google Docs. Your concern about need-to-know, however, is a common one when sharing spreadsheets. Your best option in your example is probably to change which sheet is considered the 'master' of the shared data.
Everyone who needs to edit spreadsheet content should do that on the same 'master' sheet, taking advantage of the sharing and revision tracking provided by Google Docs. If you need or wish to combine all or part of that sheet with other sheets, for example to perform review alongside other data that is privileged and unavailable to all editors of the master sheet, then use the ImportRange()
spreadsheet function in the secondary sheet to pull from the master sheet, effectively a 1-way sync.
There is no built-in method to keep two sheets synchronized.
First, you can decide on the synchronization scope: whether to include only values or to incorporate other properties like cell and content formatting, rows and columns, tab color, protections, etc.
If you only want the values from one sheet on the second sheet, you might use the built-in function IMPORTRANGE.
Another option is to use Google Apps Script, which can help you sync the sheets automatically or on demand.
The most efficient way might be to use the Advanced Sheets Service, more specifically, using batchUpdate. The simplest two-way synchronization of values is to use the Spreadsheet Service (SpreadsheetApp) together with on edit and on change triggers.
If you want a value-only two-way sync, you might want to create a library to hold a single copy of the primary function and onEdit simple trigger on each spreadsheet.
Below is a sample script for syncing values, assuming that only one cell is edited, the edits are done slowly, and both spreadsheets are not used simultaneously.
Disclaimer: I have not tested this code yet.
/**
* Primary function to be included in a library to make it easier to maintain / extend.
*
* @param {EditEventObject} e Edit event object
* @param {string} targetId Id of the spreadsheet to which the values will be pushed.
*/
function sync(e, targetId){
if( // The edited range has only one cell
e.range.rowStart === e.range.rowEnd
&& e.range.columnStart === e.range.columnEnd
){
const target = SpreasheetApp.openById(targetId);
const name = e.range.getSheet().getName();
const sheet = target.getSheetByName(name);
const range = sheet.getRange(e.range.rowStart, e.range.columnStart);
if(e.value){
range.setValue(e.value);
} else {
range.clearContent();
}
} else {
// do nothing
}
}
Let's say that the library identifier is MyLibrary, the code to be included in the bounded Apps Script project to each spreadsheet is the following
const targetId = "FILE_ID_OF_THE_TARGET_SPREADSHEET";
function onEdit(e){
MyLibrary.sync(e, targetId);
}
To sync row and column insertion/deletion, an installable on-change trigger should be used in addition to the on-edit trigger.
© 2022 - 2024 — McMap. All rights reserved.