Как заполнить столбец данными после запуска .map() в 2d-массиве

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

#javascript #массивы #google-apps-script #google-таблицы

Вопрос:

При попытке использовать execute this code я получаю следующую ошибку. Исключение: количество столбцов в данных не соответствует количеству столбцов в диапазоне. Данные имеют 0, но диапазон имеет 1. (строка 15, файл «Code»)

 function getName(){
  const srcSheetName = "result";
  const dstSheetName = "Allergy";
  const ss = SpreadsheetApp.getActiveSpreadsheet();
  const srcSheet = ss.getSheetByName(srcSheetName);
  const allergyRange = srcSheet.getRange('F1:BQ'   srcSheet.getLastRow()).getValues();
  const dstSheet = ss.getSheetByName(dstSheetName);
  const lr = dstSheet.getRange("A2:A").getLastRow();
  var names = allergyRange.map(row => row.slice(row.length-12)).forEach((row, i) => {
    if(!row.every(val => val == 0)) return allergyRange[i][0]
});
  const dstRange = dstSheet.getRange(2, 1, dstSheet.getLastRow(), 1);
  const dstValues = dstRange.getValues();
  const putValues = [names];
  dstRange.setValues(putValues);
}
 

Я предполагаю, что это связано с тем, что переменная names ‘names’ имеет слишком много столбцов или желаемый диапазон не имеет значений. Я попытался просто ввести «имена» непосредственно в функцию setValues, но это не работает, и я получаю другое сообщение об ошибке «Неверное значение».

ОБНОВЛЕНИЕ: это происходит потому, что [names] пуст.

 dstRange.setValues(names);
 

Я предполагаю, что основная проблема заключается в том, что я использовал метод .map() для управления исходным 2d-массивом вместо Object.assign() , но когда я проверяю литературу здесь, в ней говорится, что .map() создает новый массив, а JavaScript рассматривает массивы как объекты.

Пытаясь диагностировать проблему, я использую Logger.регистрируйте как внутри, так и вне цикла, чтобы получить представление о том, что происходило с набором данных.

Внутренний цикл:

 var names = allergyRange.map(row => row.slice(row.length-12)).forEach((row, i) => {
    if(!row.every(val => val == 0)) Logger.log(allergyRange[i][0])
});
 

Внешний цикл:

   var names = allergyRange.map(row => row.slice(row.length-12)).forEach((row, i) => {
    if(!row.every(val => val == 0)) return allergyRange[i][0]
});
  Logger.log(names)
 

При использовании внутри цикла я получаю желаемый список имен, но при использовании вне цикла я получаю «null» при проверке журналов.

Должен быть критический шаг, который я пропускаю. Как я могу взять выходные данные из ‘names’ и использовать setValues () или что-то еще, чтобы поместить каждый вывод в первый столбец листа в Google Sheets? Есть ли способ создать новый 2d-массив с выводом из цикла или я должен использовать полностью другой метод для управления набором данных? Я очень новичок в JavaScript, любые советы приветствуются.

Обновить:

Я попробовал .reduce() со следующим кодом:

 function newNames(){
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var data = ss.getSheetByName("result");
  var cdata = ss.getSheetByName("Allergy");
  var valuesOfFormData = data.getRange("F1:BQ"   data.getLastRow()).getValues();
  var valuesForOrderChanges = valuesOfFormData.reduce((ar, [c,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, ...d]) => {   
    if (d.toString() != 0) ar.push([c]);
    return ar;
  }, []);
  if (valuesForOrderChanges.length > 0) {
    cdata.getRange(1, 1, valuesForOrderChanges.length, valuesForOrderChanges[0].length).setValues(valuesForOrderChanges);
  }
}
 

Я могу заполнить первый столбец нужного листа, но в списке представлены все имена из массива, а не только имена со значениями в последних 12 столбцах, как в исходном коде. В настоящее время я могу либо получить список всех имен в правильный столбец, либо сгенерировать список правильных имен без возможности поместить их в нужное место без ошибок. Чего мне не хватает?

Когда я внес следующие изменения в исходный код, я получил ту же ошибку:

   if(!row.every(val => val == 0)) return allergyRange[i][0];
},[]);
 

Я чувствую, что я приближаюсь или полностью все портю. Как мне ссылаться на результат из цикла .map(), чтобы я мог опубликовать его в столбце таблицы Google.

Обновить:

Пример данных Пример данных

Пример вывода

Пример вывода

Цель: если строка в данных содержит какое-либо значение в BF1:BQ, поместите имя из столбца F в столбец A аллергии. Сделайте это для каждой строки в ‘data.

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

1. Могу ли я спросить вас о ваших образцах входных значений allergyRange и образцах выходных значений, которые вы ожидаете? Потому что в вашем скрипте at row.slice(row.length-12)) BF1:BQ извлекаются ячейки. В этом случае я подумал, что значения могут быть получены непосредственно из ячеек BF1:BQ . Но из вашего вопроса я не могу понять вашу цель. Итак, я хотел бы задать пример входных и выходных значений.

2. обновлено. Пожалуйста, дайте мне знать, если вам нужно, чтобы я добавил больше информации.

3. Спасибо за ответ и добавление дополнительной информации. Но я должен извиниться за свое плохое понимание. К сожалению, из вашего обновленного вопроса я не смог понять вашу цель. Из-за этого я не могу понять вашу текущую проблему с вашим скриптом. Я прошу прощения за это. Например, можете ли вы предоставить пример входных и выходных значений, которые вы ожидаете? Таким образом, я хотел бы попытаться понять это.

4. @Tanaike Я предоставил обновленные примеры и описание. Пожалуйста, дайте мне знать, если вам нужна дополнительная информация.

5. Спасибо за ответ и добавление дополнительной информации. Я хотел бы подтвердить свое понимание вашей цели. В вашей цели, когда в ячейках BF2:BQ на листе «данные» есть значения, вы хотите извлечь значения из столбца «F» той же строки и поместить значения в лист «аллергия». Вы хотите добиться этого с помощью скрипта Google Apps. Правильно ли я понимаю?

Ответ №1:

Я считаю, что ваша цель заключается в следующем.

  • Когда в ячейках BF2: BQ на листе «данные» есть значения, вы хотите извлечь значения из столбца «F» той же строки и поместить значения в лист «аллергия».
  • Вы хотите добиться этого с помощью скрипта Google Apps.

В этом случае я хотел бы предложить изменить ваш нижний скрипт в разделе «ОБНОВЛЕНИЕ:».

Модифицированный скрипт:

 function newNames(){
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var data = ss.getSheetByName("result");
  var cdata = ss.getSheetByName("result");
  var valuesOfFormData = data.getRange("F2:BQ"   data.getLastRow()).getValues();  // Modified
  var valuesForOrderChanges = valuesOfFormData.reduce((ar, [c,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, ...d]) =>{
    if (d.some(e => e.toString() != "")) ar.push([c]);  // Modified
    return ar;
  }, []);
  if (valuesForOrderChanges.length > 0) {
    cdata.getRange(2, 1, valuesForOrderChanges.length, valuesForOrderChanges[0].length).setValues(valuesForOrderChanges);  // Modified
  }
}
 

Ссылка: