Я создал новый проект, который должен сравнить имя из Sheet1 со списком имен в Sheet2 и проверить, есть ли имя уже в этом списке. Для этого я выбрал цикл for, чтобы просмотреть список в Sheet2 и сравнить каждую запись в списке с именем из Sheet1. Только если имя уже существует в списке, это должно произойти.
function myFunction() {
var tabSheet1 = 'Sheet1';
var tabSheet2 = 'Sheet2';
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet1 = ss.getSheetByName(tabSheet1);
var sheet2 = ss.getSheetByName(tabSheet2);
var lastRow1 = sheet2.getLastRow() + 1;
var playerNameSheet1 = sheet1.getRange(1, 1).getValue();
for (var j = 1; j < lastRow1; j++) {
var playerNameSheet2 = sheet2.getRange(j, 1).getValue();
if (playerNameSheet2 == playerNameSheet1) {
...stuff...
}
}
}
Теперь моя проблема в том, что похоже, что сценарий не может определить, что имя уже существует в списке. Оба значения (playerNameSheet1 и playerNameSheet2) полностью идентичны (без пробелов или других скрытых препятствий), однако скрипт никогда не продолжит работу с материалом в операторе if. Моим примером имени для проверки моего сценария было «Оливер Бауманн».
Я немного смущен этим - даже больше, потому что другое сравнение, немного позднее в коде сценария, работает отлично.
Я уже пытался изменить оператор на ===, но это тоже не сработало.
if (playerNameSheet2 === playerNameSheet1) {
...stuff...
}
Я также заметил, что если я поставлю точку позади обеих переменных, я смогу выбирать дополнительные функции только с playerNameSheet2, но не с playerNameSheet1. Может, я опечатал опечатку и просто слишком слеп, чтобы ее заметить? Я не знаю. Кто-нибудь знает, как решить проблему?
Полный проект можно найти здесь. Однако много всего написано на немецком языке и очень элементарно. Я только что запустил и у меня нет времени убирать. Просто чтобы вам не удивляться.
Вы пробовали регистрировать playerNameSheet2
и playerNameSheet1
вне условия if, чтобы проверить, почему это условие не выполняется?
@Umair да, я это уже проверил. Однако я полностью повторил свой код с помощью tehhowch, и он работает.
Вы, вероятно, выиграете от изменения вашей процедуры проверки - в настоящее время то, что у вас есть, не масштабируется из-за вызовов медленно, повторяется к службе электронных таблиц. Используйте пакетный метод - getValues()
- для возврата Javascript Array
, который содержит весь контент, который вы можете захотеть, из вашего «основного списка» имен:
// Create an N x 1 array of arrays, e.g. [ [r1c1], [r2c1], [r3c1], ... [rNc1] ],
// of data in column A in sheet2. There will be blanks at the end if other columns have more data.
var allNames = sheet2.getRange(1, 1, sheet2.getLastRow(), 1).getValues();
Чтобы проверить, присутствует ли имя с первого листа, мы можем заменить этот код:
for (var j = 1; j < lastRow1; j++) {
var playerNameSheet2 = sheet2.getRange(j, 1).getValue();
if (playerNameSheet2 == playerNameSheet1) {
/* do stuff */
с этим кодом (обратите внимание, что j
теперь начинается с 0):
for (var j = 0; j < allNames.length; ++j) {
if (playerNameSheet1 === allNames[j][0]) {
/* do stuff */
Если вам нужно только do stuff
для имени однажды в вызове функции (например, вам не нужно выполнять тело цикла двадцать раз, когда имя листа 1 - «Боб», а на листе 2 двадцать экземпляров «Боб») , вы можете упростить проверку значения allNames
с помощью метода Array#indexOf
. Во-первых, нужно свернуть «2D» массив массивов значений в массив значений. Мы хотим применить функцию к каждому элементу внешнего массива и построить массив его выходных данных, поэтому мы решили вызвать на нем Array#map
:
var db = allNames.map(function (row) { return row[0]; });
Используемая нами функция просто возвращает первый элемент переданного элемента, то есть значение в первом столбце, что приводит к выводу, подобному [ r1c1, r2c1, r3c1, ... rNc1 ]
.
Тогда код замены:
if (db.indexOf(playerNameSheet1) === -1) {
console.info({
message: "Did not find '" + playerNameSheet1 + "' in database.",
database: db, original: allNames, searched: playerNameSheet1
});
return;
}
/* do stuff */
В нем говорится, что «если имя отсутствует на листе 2, зарегистрируйте неудачный поиск, а затем прекратите выполнение функции».. Чтобы способствовать фактическому ведению журнала, журнал отправляется в Stackdriver, который будет хранить его намного дольше, чем это сделал бы собственный класс Logger
.
Если ваши биты do stuff
используют индекс j
, вы все равно можете получить этот индекс и использовать связанную строку на листе 2:
var index = db.indexOf(playerNameSheet1);
if (index === -1) {
console.info({
message: "Did not find '" + playerNameSheet1 + "' in database.",
database: db, original: allNames, searched: playerNameSheet1
});
return;
}
/* do stuff with the user's existing row of data, e.g.
var userDataRow = sheet2.getRange(index + 1, 1, 1, sheet2.getLastColumn()).getValues();
var userData = userDataRow[0];
...
*/
Возможным улучшением модификации indexOf
, которое я оставляю вам для изучения и / или реализации, было бы использование Object
для хранения имен как «ключей» (свойств объекта) и индекса связанных данных листа (или даже data напрямую) как связанное значение пары ключ-значение.
вы можете попробовать преобразовать данные в массив и сравнить в цикле for:
var dataRangeSpieler = sheetSpieler.getDataRange().getValues();
var dataRangeDBSpiele = sheetDBSpieler.getDataRange().getValues();
for (i in dataRangeSpieler ) {
for (j in dataRangeDBSpiele) {
if (dataRangeSpieler[i][1] == dataRangeDBSpiele[j][0]) {
Logger.log(dataRangeSpieler[i][1]); //Oliver Baumann
}
}
}
в этом конкретном случае я не вижу ничего особенного в использовании for ... in, дополнительно for ... in используется как пример в официальной статье GAS: developers.google.com/apps-script/articles/removing_duplicat es
То, что они там его используют, не означает, что мы должны обучать этому новых программистов и задающих вопросы. Не все примеры документации написаны кодировщиками, которые раньше сталкивались с этим шаблоном :)
Я бы проверил, правильно ли установлен playerNameSheet1:
Logger.log(Utilities.formatString("[%s]", playerNameSheet1))
Кроме того, я бы зарегистрировал каждый playerNameSheet2, чтобы еще раз проверить, что делает сравнение