Пример простого приложения для Таблиц на Google Apps Script

Изменить сообщение
От слов к делу. Вот задача.
Друзья, добрый день!
Помогите, пожалуйста, со скриптом для таблиц Гугл.
Задача: Необходимо скопировать определенную строку/строки в таблице 1 и вставить ее/их, в конец таблицы 2, при нажатии кнопки.
Пример Таблицы 1 по ссылке: ...
Копировать необходимо строку 45, 46 и очистить от значений диапазон h2:h40 и o2:о40.
Заранее благодарю за помощь. 
План решения внятно описан в виде кода у +Alexey Isachenko в этой Таблице. Листинг

var dataSheetName = "Прием заказа";
var dbSheetName = "Таблица 2";
function myFunction() {
  var ss = SpreadsheetApp.getActive();
  var dataSheet = ss.getSheetByName(dataSheetName);
  if (!dataSheet) throw ("не могу найти лист " + dataSheetName);
  var data = dataSheet.getRange(45, 1, 2, dataSheet.getLastRow()).getValues();

  var dbSheet = ss.getSheetByName(dbSheetName);
  if (!dbSheet) throw ("Не могу найти лист " + dbSheetName);
  dbSheet.getRange(dbSheet.getLastRow()+1, 1, 2, data[0].length).setValues(data);

  ["h2:h40","o2:o40"].forEach(function(r){dataSheet.getRange(r).clearContent();});

  ss.toast("Готово");
}
function onOpen() {
  SpreadsheetApp.getUi().createMenu("Заказы").addItem("Обработать", "myFunction").addToUi();
}
Добавим немного полезного в непростой вызов и настройку скриптов. Создадим элементарный интерфейс и добавим возможность редактировать настройки. Код был написан параллельно, поэтому кроме общей логики с предыдущим ничего нет.
 #лайфхак Поставьте формулу =NOW() в ячейки A45 и A46, и вы будете иметь дату и время операции копирования.

Таблица со скриптом

Для "очумелых ручек" приведу код:
Code.gs
function clearRange(range) {
  if(!range) return;
  SpreadsheetApp.getActiveSheet().getRange(range).clear({ contentsOnly: true});
}
function copyRange(range, destinationSpreadsheetID, destinationSheetName){
  var s, sh, values;
  if(destinationSpreadsheetID){
    s = SpreadsheetApp.openById(destinationSpreadsheetID)
  }else{
    s = SpreadsheetApp.getActiveSpreadsheet();
  }
  if(destinationSheetName){
    sh = s.getSheetByName(destinationSheetName)
  }else{
    sh = s.getSheets()[0]
  }
  values = SpreadsheetApp.getActiveSheet().getRange(range).getValues();
  for(var i in values){
    sh.appendRow(values[i])
  }
}
function saveProperties(prop){
  PropertiesService.getDocumentProperties().setProperties(prop)
}
function onOpen() { //зарезервированная функция-триггер. Срабатывает при открытии документа
  var ui = SpreadsheetApp.getUi(); //создаем объект UiApp для Таблиц
  ui.createMenu('Меню действий') //создаем корень собственного меню
  .addItem('Копировать', 'copy') //создаем пункт меню "Запусти это", который будет вызывать функцию "zapustiEto" без параметров
  .addItem('Настройки', 'settings') //создаем пункт меню "Second item", который будет вызывать функцию "menuItem2" без параметров
  .addToUi(); //обновляем интерфейс
}
function copy() {
  try{
    var prop = PropertiesService.getDocumentProperties().getProperties();
    copyRange(prop['RANGE_FOR_COPY'], prop['DESTINATIN_ID_SHEET'], prop['DESTINATION_SHEET_NAME']);
    clearRange(prop['RANGE_FOR_CLEAR']);
    SpreadsheetApp.getUi().alert('OK');
  }catch(err){
    SpreadsheetApp.getUi().alert(JSON.stringify(err))
  }
}
function settings() {
  var ui = HtmlService.createHtmlOutputFromFile('settings')
  .setTitle('Бла-Бла-Бла сервис');
  SpreadsheetApp.getUi().showSidebar(ui);
}
function getPreferences(){
  return PropertiesService.getDocumentProperties().getProperties()
}
settings.html
<link rel="stylesheet" href="https://ssl.gstatic.com/docs/script/css/add-ons.css">
<div class="sidebar">
<span>Диапазон очистки</span><br/><input type="text" id="RANGE_FOR_CLEAR" name="RANGE_FOR_CLEAR" goal="settings"/><br/>
<span>Диапазон копирования<sup style="color:red">*</sup></span><br/><input type="text" id="RANGE_FOR_COPY" name="RANGE_FOR_COPY" goal="settings"/><br/>
<span>ID Таблицы назначения копирования</span><br/><input type="text" id="DESTINATIN_ID_SHEET" name="DESTINATIN_ID_SHEET" goal="settings"/><br/>
<span>Имя Листа назначения копирования</span><br/><input type="text" id="DESTINATION_SHEET_NAME" name="DESTINATION_SHEET_NAME" goal="settings"/><br/>
<input type="button" id="save" value="Сохранить"/>
</div>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js">
</script>
<script>
  $(function() {
    $('#save').click(saveProperties);
    google.script.run.withSuccessHandler(function(prop){
      for(var i in prop){
        $('[name="' + i +'"]').val(prop[i]);
      }
    })
    .withFailureHandler(function(err){alert(err)}).getPreferences();
  });
  function saveProperties(){
    var prop = {};
    $('[goal="settings"]').each(function(){
      prop[$(this).attr('name')] = $(this).val() || '';
    })
    google.script.run.withSuccessHandler(function(){alert('OK')})
    .withFailureHandler(function(err){alert(err)}).saveProperties(prop);
  };
</script>
Пока Google Apps Script распространять не очень удобно. Ждем новых решений.