#javascript #google-apps-script #google-sheets
#язык JavaScript #google-приложения-скрипт #google-листы
Вопрос:
У меня есть скрипт, который запускается при отправке триггера, и ему необходимо отсортировать полученные данные, чтобы определить, на какой лист записывать данные.
Раньше я жестко кодировал его с точными названиями, и он работал нормально, но теперь я пытаюсь упростить его масштабирование. Переменной value
в переключателе должно быть число.
Ниже приведен фрагмент кода.
var myIds = [111, 222, 333, 444]; var myUsers = ['aaa', 'bbb', 'ccc', 'ddd']; ... switch (param) { case 1: break; case 2: for (let i = 0; i lt; myIds.length; i ) { if (value == myIds[i]) { userName = myUsers[i]; break; } } userName = 'ETC'; break; } if (userName != 'ETC') { let inSheet = 'In ' userName; let outSheet= 'Out ' userName; if (checkIn == true) sheet = SpreadsheetApp.setActiveSheet(spreadsheet.getSheetByName(inSheet)); else sheet = SpreadsheetApp.setActiveSheet(spreadsheet.getSheetByName(outSheet)); } else sheet = SpreadsheetApp.setActiveSheet(spreadsheet.getSheetByName('ETC'));
Вместо того, чтобы переходить на соответствующие листы ввода / вывода, все вместо этого переходит на лист ETC. В другое время на простынях вообще не было бы никаких изменений. Было бы весьма признателен, если бы кто-нибудь мог объяснить, почему это происходит, в дополнение к вопросу.
Заранее спасибо.
Ответ №1:
break;
Внутренняя часть вашего for
цикла только вырывается из for
цикла, а не сама case
. Таким образом , вы выходите из for
и в конечном итоге включаетесь userName = "ETC";
, что перезаписывает любое значение, которое может быть установлено циклом.
Вместо этого вы можете использовать indexOf
или findIndex
:
case 2: const index = myIds.indexOf(value); // Or `.findIndex(id =gt; id == value)` if you need `==` not `===` userName = index === -1 ? "ETC" : myUsers[index]; break;
Если вам действительно нужен for
цикл, вы можете назначить userName
его перед циклом, чтобы цикл перезаписывался "ETC"
:
case 2: userName = "ETC"; for (let i = 0; i lt; myIds.length; i ) { if (value == myIds[i]) { userName = myUsers[i]; break; } } break;
Примечание: Я рекомендую избегать параллельных массивов, таких как myIds
и myUsers
. Очень легко в конечном итоге обновить одно, а не другое. Вместо этого рассмотрим массив объектов:
const users = [ {id: 111, name: "aaa"}, {id: 222, name: "bbb"}, {id: 333, name: "ccc"}, {id: 444, name: "ddd"}, ];
Тогда в первом приведенном выше примере будет использоваться find
:
case 2: const user = users.find(({id}) =gt; id == value); userName = user ? user.name : "ETC"; break;
В действительно современной среде с необязательной цепочкой и нулевым объединением вы могли бы перейти userName = user ? user.name : "ETC";
на userName = user?.name ?? "ETC";
, но в условной версии нет ничего плохого.
Примечание 2: Вы использовали let
в своем for
цикле, поэтому, похоже, используете более современный ГАЗ, поддерживающий функции ES2015 . Я предлагаю не использовать var
в новом коде, всегда используйте let
или const
.
Комментарии:
1. спасибо за отличный ответ! Я хотел бы подробнее остановиться на исходном вопросе, однако, где теперь , после размещения всего в массиве объектов, когда я пытаюсь использовать
getSheetByName("In " users[i].name)
, он возвращает ошибку, в которой говорится, что он не может прочитать свойство » имя » неопределенного. У меня естьusers
массив в качестве глобальной переменной, так что это не должно быть проблемой.2. @Shironats — Проблема не
users
в том , что этоusers[i]
… или, более конкретно, этоi
недопустимый индекс вusers
массиве. Я не могу сказать вам, почему нет, потому что я понятия не имею, в чемi
там ценность. Но этой строки кода не существует ни в вопросе, ни в ответе. Вы все равно будете использоватьuserName
его там, нетusers[i].name
; простоuserName
меняется то, как вы его устанавливаете.3. Спасибо за разъяснение, я прояснил эту проблему. Однако теперь, когда я использую этот
find(({id}) =gt; ...
метод, я не получаю никаких новых входных данных, хотя по логике вещей все должно быть указано на листе «ETC». Все еще пытаюсь понять, что пошло не так.
Ответ №2:
Очевидно, проблема заключалась в другой части кода, которую я не включил в вопрос, где я повторно инициализировал переменную имени пользователя в каждом цикле. Это привело к тому, что переменная имени пользователя в некоторых циклах не была определена, что, в свою очередь, привело к getSheetByName
возвращению функции ошибки.