Как обновить строку на другом листе на основе идентификатора без перезаписи пустыми ячейками?

#javascript #google-apps-script #google-sheets

#javascript #google-приложения-скрипт #google-sheets

Вопрос:

Я пытаюсь скопировать строки с одного листа на другой с помощью Google Apps Script на основе соответствующего идентификатора в столбце 4 каждого, но, похоже, я не могу найти, как вставить его в соответствующую строку и сделать это, не перезаписывая существующие данные пустыми ячейками.

В Google Sheets Лист1 содержит строки новых данных, определенных идентификатором. Лист2 должен собирать каждую отдельную строку, обновляя строки новыми данными, если идентификатор новой строки на листе 1 совпадает с существующей строкой на листе 2. В конце дня Лист1 очищается, и все, что остается, — это самая актуальная информация о каждом элементе ID на Листе2. Иногда строки на листе 1 заполняются не полностью, и в этом случае только ячейки с данными (из листа 1) должны быть перезаписаны на листе 2.

Будут добавлены новые идентификаторы, но я уже более или менее разобрался, как это сделать, и это не входит в вопрос 🙂

 function myFunction() {
    // Path to Correct Spreadsheet
  var ss = SpreadsheetApp.getActive();
  var sheet1 = ss.getSheetByName("Sheet1");
  var sheet2 = ss.getSheetByName("Sheet2");
  var sheet3 = ss.getSheetByName("Sheet3"); //temporary, while I work out how to copy it to the right row in Sheet2

  // Get size of ranges
  var header = 1;  // Number of rows of header info (to skip)
  var range1 = sheet1.getDataRange();
  var data1 = range1.getValues();
  var range2 = sheet2.getDataRange();
  var data2 = data2 = range2.getValues();

      Logger.log('data1 = '   data1);

  var resultArray = [];
  for(var n=header; n < data1.length ; n  ){
    var keep = false;
    for(var p=header; p < data2.length ; p  ){
      Logger.log(data1[n][0] ' =? ' data2[p][0]);
      if( data1[n][3] == data2[p][3]){
        resultArray.push(data1[n]);
        Logger.log('true');
        break ;
      }
    }
  }  
  sheet3.getRange( 1,1,resultArray.length,resultArray[0].length).setValues(resultArray);
}
  

Мне удалось собрать код, который находит соответствующие идентификаторы и отправляет всю строку на Лист3 (на данный момент, прежде чем решить, как отправить ее в нужную строку на листе 2). Но при этом любые существующие данные перезаписываются пустыми ячейками (если таковые имеются), и я, похоже, не могу заставить {contentsOnly: true} работать (правильный ли это вообще подход?)

Я делал это всего неделю, стараясь изо всех сил, но не в своей тарелке. Была бы весьма признательна любая помощь, даже просто указания в правильном направлении тем для изучения. Последние 48 часов я использую stackoverflow, пытаясь найти что-то похожее на это, но я ничего не смог найти (возможно, я даже ищу не то, что нужно!). Очень унизительно.

Комментарии:

1. Это сравнение столбца 4, а не столбца 3 if( data1[n][3] == data2[p][3]) массивы начинают индексы с нуля, а столбцы в электронной таблице начинаются с единицы.

2. Почему вы используете sheet3? Разве вы не хотите, чтобы все было на листе 2?

3. Да, вы правы. Это столбец 4 в таблице Google. Как я уже упоминал, я использую Sheet3, потому что таким образом я, по крайней мере, получаю функцию для копирования выбранной строки куда-нибудь, но в идеале она найдет совпадение в Sheet2 и скопирует его в соответствующую строку. Это моя конечная игра, хотя я еще не дошел до конца.

Ответ №1:

попробуйте это:

 function myFunction() {
  var ss = SpreadsheetApp.getActive();
  var sheet1 = ss.getSheetByName("Sheet1");
  var sheet2 = ss.getSheetByName("Sheet2");
  var sheet3 = ss.getSheetByName("Sheet3");
  var header = 1;  // Number of rows of header info (to skip)
  var range1 = sheet1.getDataRange();
  var data1 = range1.getValues();
  var range2 = sheet2.getDataRange();
  var data2 = data2 = range2.getValues();
  var resultArray = [];
  for(var n=header; n < data1.length ; n  ){
    var keep = false;
    for(var p=header; p < data2.length ; p  ){
      if( data1[n][3] == data2[p][3]){
        var tA=[];
        var rg=sheet2.getRange(p 1,1,1,sheet2.getLastColumn());
        for(var i=0;i<data1[0].length;i  ) {
          tA.push((data1[n][i])?data1[n][i]:data2[p][i]);
        }
        rg.setValues([tA]);
        break ;
      }
    }
  }  
}
  

Комментарии:

1. Спасибо за попытку. Пытаюсь расшифровать это сейчас. Однако, похоже, это не работает, выдавая мне Cannot convert Array to Object[][]. для этой строки rg.setValues(tA); (я изменил 2s на 3s, чтобы соответствовать тому факту, что она находится в четвертом столбце, согласно вашему предыдущему комментарию.)

2. Поделитесь некоторыми данными, чтобы я мог их отладить.

3. Это тестовый лист, на котором я запускаю эту функцию. Довольно разреженный, но цель состоит в том, чтобы использовать его как часть персонального диспетчера задач. Лист2 будет собирать все задачи за все время, а Лист1 — это дневной лист с новыми задачами. Это одна небольшая часть целого (уже работают календарь, задачи, формы; еще нужно отшлифовать несколько подобных деталей). docs.google.com/spreadsheets/d /…

4. Я просто изменил код. Скопируйте это снова. Теперь это работает. Несколько опечаток и одна команда в неправильном месте. Вы также должны убедиться, что оба листа 1 и Лист2 имеют шесть заголовков. Я использовал их, чтобы получить правильное количество столбцов