Я бы сделал так:
/**
* Копирует значения и форматирование из fromRange в toRange
*
* @param {"A1:B10"} fromRange Исходный массив
* @param {"D1:E10"} toRange Конечный массив
* @return 0 если выполнилось без ошибок, или описание ошибки
* @customfunction
*/
function copyRange(fromRange, toRange){
var ss = SpreadsheetApp.getActiveSpreadsheet();
try{
var source = ss.getRange(fromRange);
var dest = ss.getRange(toRange);
dest.setValues(source.getValues());
dest.setBackgrounds(source.getBackgrounds());
// и т.д. Есть много чего из форматирования, получается по get... ставится по set...
return 0;//Завершение без ошибок
}catch(err){
Logger.log(Utilities.formatString((arguments.callee.toString().match(/function ([^(]*)\(/)[1]) + "(%s) - %s", Array.from(arguments).join(", "), err.message)); //Ошибку в лог
return err.message;//Завершение с ошибкой
};
};
Использовать так:
function syncRanges(){
copyRange("b7:b11", "c7:c11"); // b7:b11 >> c7:c11
copyRange("f1:f20", "g1:g20"); // f1:f20 >> g1:g20
//и т.п. можно вызывать несколько раз для разных диапазонов
};
И настроить для функции
syncRanges() триггер "на изменение таблицы" или "по времени".