#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
и образцах выходных значений, которые вы ожидаете? Потому что в вашем скрипте atrow.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
}
}