Следующий ответ может показаться излишне длинным, но две ключевые строки:
var defectcodes = defectvalues.map(function (row) { return row[0]; });
var c = defectcodes.indexOf(respcode);
ФП получает форму, сообщающую о дефектах. Существует три формы, и каждый ответ может содержать информацию о 35 отдельных дефектах. Информация о дефектах состоит из шести полей, но для этого упражнения есть три ключевых поля: «отдел», «тип дефекта» и количество дефектов. Целью ФП является предоставление информации о дефектах на отдельном листе («Всего дефектов») с указанием общего количества дефектов для каждой комбинации отдел / дефект. Существует более 2100 комбинаций отделов / дефектов, расположенных в пяти наборах из трех столбцов (Отдел, Дефект и Кол-во).
Проблема ОП заключается в сопоставлении "отдела" и "дефекта" из листов ответов формы.
Для этого предлагаемого решения необходимо несколько элементов:
- Изменение макета листа «Всего дефектов».
Макет с пятью столбцами является ненужным усложнением. Макет должен быть упрощен до одного набора столбцов из 2100 строк.
- Упрощение поиска / совпадения.
Вместо сопоставления двух отдельных значений («Отдел» и «Дефект») создайте один уникальный код путем объединения этих значений и используйте его для поиска / сопоставления.
- Используйте методы Javascript 'map' и 'indexof' для упрощения обработки.
В следующем ответе я сосредоточился на основах решения. Я не добавил код для автоматического обхода трех листов с ответами на формы, а также для обновления количества; это красные сельди. Я оставил в коде несколько операторов Logger, чтобы помочь оператору (и другим) в устранении неполадок и / или понимании кода.
function so5652371304() {
// setup Defects spreadsheet
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheetname = "TotalDefects02";
var defectsheet = ss.getSheetByName(sheetname);
//Logger.log("DEBUG: Defect sheet name "+defectsheet.getName());//DEBUG
var defectlastrow = defectsheet.getLastRow();
//Logger.log("DEBUG: the last defect row = "+defectlastrow);//DEBUG
// Layout on Total Defects is:
// Row#1 = Header
// Column A = Department
// Column B = Defect
// Column C = Concatenate Column A and Column B
// Column D = Qty
var defectrange = defectsheet.getRange(2,3,defectlastrow-1);// column 3 (C)- dept+code
//Logger.log("DEBUG: the defect range is "+defectrange.getA1Notation());//DEBUG
var defectvalues = defectrange.getValues();
// apply the "map" method to assign the row number to every element
var defectcodes = defectvalues.map(function (row) { return row[0]; });
// set up the response sheets
var respsheetname = "1st AQL";// 1st AQL// 2nd AQL // 3rd AQL
var respsheet = ss.getSheetByName(respsheetname);
//Logger.log("DEBUG: Response sheet name "+respsheet.getName());//DEBUG
var resplastrow = respsheet.getLastRow();
var resplastcolumn = respsheet.getLastColumn();
//Logger.log("DEBUG: Response lastrow = "+resplastrow+", last column"+resplastcolumn); //DEBUG
// Layout on Total Defects is:
// Row#1 & 2 = Header
// Column A to Q (Inclusive) = Irrelevant information (Column 1 to 17 inclusive)
// Column R to W = Response dataset#1
// Column R (18) = Department#1
// Column S (19) = Defect#1
// Column T (20) = Quantity
// Column U (21) = Irrelevant
// Column V (22) = Irrelevant
// Column W (23) = Irreelvant
// Column X (24) to HR (226) consists of a further 34 possible defect notices, each of 6 columns
var resprange = respsheet.getRange(3,18,resplastrow-2,resplastcolumn-18+1);
//Logger.log("DEBUG: the resp range is "+resprange.getA1Notation());//DEBUG
var respvalues = resprange.getValues();
// set Response variables
var repliesperrow=35;
var columnsperreply = 6;
//Loop through replies to find matches in the database
for (var r = 0;r<resplastrow-2;r++){//loop rows
for (var i=0; i<repliesperrow;i++){//loop per reply
if (respvalues[r][(i*columnsperreply)].length>0){
//Logger.log("DEBUG: dept = "+respvalues[r][(i*columnsperreply)]+", defect = "+respvalues[r][((i*columnsperreply)+1)]+", qty = "+respvalues[r][(i*columnsperreply)+2]); //DEBUG
var respcode = respvalues[r][(i*columnsperreply)].concat('',respvalues[r][((i*columnsperreply)+1)]);
var c = defectcodes.indexOf(respcode);
// if c=-1 then the code is not in TotalDefects Table
// if c>-1 then the code IS in the TotalDefects Table, AND the relevant row number of the matching code = c+2
if (c > -1) {
Logger.log("DEBUG: r:"+r+", i:"+i+", c="+c+", Code:"+respcode+" found in the defects database on row:"+(c+2)); // DEBUG the details are on (c+2) rows
} else {
Logger.log("DEBUG: r:"+r+", i:"+i+", c="+c+", Code:"+respcode+" NOT found in the defects database"); //DEBUG
}
}
else{
continue;
}
}
}
}
Layout-TotalDefects лист
UPDATE:
Эта ревизия проходит по листам и обновляет общее количество дефектов. Вместо того, чтобы использовать (дорогое) setValue () для каждого нового количественного значения, код накапливает значение qty и затем записывает одно setValues в конце каждого листа ответов.
Обратите внимание, что существуют операторы Logger, которые могут отображаться для:
- Успешных ответов
- Неудачные ответы (когда каскадный код не может быть найден в Total Defects. Можно было бы предложить OP, чтобы они были записаны в лист ошибок, чтобы упростить поиск и устранение неисправностей.
function so5652371306() {
// setup Defects spreadsheet
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheetname = "TotalDefects06";
var defectsheet = ss.getSheetByName(sheetname);
//Logger.log("DEBUG: Defect sheet name "+defectsheet.getName());//DEBUG
var defectlastrow = defectsheet.getLastRow();
//Logger.log("DEBUG: the last defect row = "+defectlastrow);//DEBUG
// Layout on Total Defects is:
// Row#1 = Header
// Column A = Department
// Column B = Defect
// Column C = Concatenate Column A and Column B
// Column D = Qty
// get 2 x ranges and data
// defectrange = enables the code to access the existing value of the qty
var defectrange = defectsheet.getRange(2,3,defectlastrow-1,2);// column C - dept+code // column D = qty
//Logger.log("DEBUG: the defect range is "+defectrange.getA1Notation());//DEBUG
var defectvalues = defectrange.getValues();
// defectqtyrange = enables the code to increment the qty andf then, as the last command, paste the adjusted values back onto the spreadsheet
// this avoids setValue within the Response loops.
var defectqtyrange = defectsheet.getRange(2,4,defectlastrow-1,1);// column D - qty
var defectqtyvalues = defectqtyrange.getValues();
// apply the "map" method to assign the row number to every element
var defectcodes = defectvalues.map(function (row) { return row[0]; });
// set up an array of response sheets
var respsheetname = [
'1st AQL',
'2nd AQL',
'3rd AQL'
];
// Layout of Response Sheets is:
// Row#1 & 2 = Header
// Column A to Q (Inclusive) = Irrelevant information (Column 1 to 17 inclusive)
// Column R to W = Response dataset#1
// Column R (18) = Department#1
// Column S (19) = Defect#1
// Column T (20) = Quantity
// Column U (21) = Irrelevant
// Column V (22) = Irrelevant
// Column W (23) = Irreelvant
// Column X (24) to HR (226) consists of a further 34 possible defect notices, each of 6 columns
// set Response variables
var repliesperrow = 35;
var columnsperreply = 6;
// loop through the response sheets
for (var t = 0; t < respsheetname.length; t++) {
var respsheet=ss.getSheetByName(respsheetname[t]);
var thissheet = respsheet.getName();
// Logger.log("DEBUG: Response sheet name "+thissheet);//DEBUG
var resplastrow = respsheet.getLastRow();
var resplastcolumn = respsheet.getLastColumn();
//Logger.log("DEBUG: Response lastrow = "+resplastrow+", last column"+resplastcolumn); //DEBUG
// define the range
var resprange = respsheet.getRange(3,18,resplastrow-2,resplastcolumn-18+1);
//Logger.log("DEBUG: the resp range is "+resprange.getA1Notation());//DEBUG
// get the response data
var respvalues = resprange.getValues();
//Loop through replies to find matches in the database
for (var r = 0;r<resplastrow-2;r++){//loop rows
for (var i=0; i<repliesperrow;i++){//loop per reply
if (respvalues[r][(i*columnsperreply)].length>0){
var respcode = respvalues[r][(i*columnsperreply)].concat('',respvalues[r][((i*columnsperreply)+1)]);
var c = defectcodes.indexOf(respcode);
// if c=-1 then the code is not in TotalDefects Table
// if c>-1 then the code IS in the TotalDefects Table, AND the relevant row number of the matching code = c+2
if (c > -1) {
// display this for the successful matches
//Logger.log("DEBUG: RESPONSE FOUND IN THE DATABASE. \nSheet:"+thissheet+", response row:"+(+r+1)+", response#:"+(+i+1)+", indexOf:"+c+", Code:"+respcode+", Qty:"+respvalues[r][(i*columnsperreply)+2]); // DEBUG the details are on (c+2) rows
// display this for matching row in the Total Defects
//Logger.log("DEBUG: Corresponding Defect. Code:"+defectvalues[c][0]+", Qty:"+defectvalues[c][1]+", SpreadsheetRow:"+(+c+2));
// increment the adjusted Total Defect quantity
defectqtyvalues[c][0] = Number(defectqtyvalues[c][0])+Number(respvalues[r][(i*columnsperreply)+2]);
} else {
// display this for failed matches
// Logger.log("DEBUG: Response: Code not found in Total Defects. \nSheet:"+thissheet+", response row:"+(+r+1)+", response#:"+(+i+1)+", Code:"+respcode); //DEBUG
}
}
else{
continue;
}
}
}
// update the defect range with the adjusted qty
defectqtyrange.setValues(defectqtyvalues);
}
}