Я согласен с ОП.Построение массива И итерации - это насущные проблемы, и они являются камнем преткновения при разработке электронной таблицы
У ОП есть поднятый ряд вопросов, однако самая неотложная, и одна из них, которая должна быть решена в рамках этого ответа, - это копирование списка деталей с одного листа на другой.В коде ОП именованные диапазоны были извлечены и использованы в качестве основы для создания копии списка деталей.Однако это также создает дублированный набор именованных диапазонов на целевом листе.На мой взгляд, это неоправданно усложняет дублирование списка деталей, так как легко программно создать / обновить список именованных диапазонов.
Следующий код состоит из трех функций:
so_5466573501()
- копирует список деталей с одного листа на другой.
Именованные диапазоны игнорируются;камнем преткновения OP является итерация необработанных данных и управление массивами.Этот код имеет дело только с этим аспектом в качестве средства упрощения этой проблемы.
createnamedranges()
- программно создает / обновляет именованные диапазоны.
Этот код включен, чтобы гарантировать, что OPне важно, чтобы именованные диапазоны были в центре внимания дублирования, показывая, насколько просто программно превратить список частей в серию именованных диапазонов (для разработки я создал 60 частей, и весь код выполняется менее чем за 1 секунду).Код предполагает список из двух столбцов (столбец A = имя параметра, столбец B = значение параметра).Код перебирает список, создавая / обновляя набор именованных диапазонов - имя диапазона является именем параметра в столбце A, а сам диапазон является соответствующей строкой в столбце B. Имя листа задается в переменной,так что эта функция может быть легко адаптирована.
deletenamedranges()
- Программно удаляет именованные диапазоны.
Этот код удаляет все именованные диапазоны с данного листа.Эта функция включена, потому что существующий код OP создает дублированные именованные диапазоны, и может быть необходимо быстро удалить их с листа.Имя листа хранится в виде переменной, поэтому функция может быть легко адаптирована.
function so_5466573501() {
//set master spreadsheet
var ss = SpreadsheetApp.getActiveSpreadsheet();
//create variables for calc and save sheets
var calcSheet = ss.getSheetByName('Part Cost Calculator')
var saveSheet = ss.getSheetByName('Saved Parts');
//get the Parts Parameters from Part Cost Calculator
//var namedRanges = calcSheet.getNamedRanges();
//Logger.log("DEBUG: Number of named ranges on Parts Cost Calculator = "+namedRanges.length);
// get the number of parts in the list on Parts Cost Calculator
var Avals = calcSheet.getRange("A1:A").getValues();
var Alast = Avals.filter(String).length;
//Logger.log("DEBUG: Number of parts in the list: "+Alast); //DEBUG
// get the parts list
var partsRange = calcSheet.getRange(1, 1, Alast, 2);
var partsRangeValues = partsRange.getValues();
//Logger.log("DEBUG: The parts range is: "+partsRange.getA1Notation());//DEBUG
//Logger.log("DEBUG: Parts List Row #1: Name: "+partsRangeValues[0][0]+", Value: "+partsRangeValues[0][1]);//DEBUG
// create an array to use for saving results and updating new Saved Parts sheet
var savedValues = new Array();
// Loop through the Parts List, row by row
for (i = 0; i < Alast; i++) {
// push the part name and part value onto the array
savedValues.push([partsRangeValues[i][0], partsRangeValues[i][1]]);
//Logger.log("DEBUG: Parts List: i = "+i+", Name: "+partsRangeValues[i][0]+", Value: "+partsRangeValues[i][1]);//DEBUG
}
// identify the range on the Saved Parts sheet to copy the parts list array.
var saveRange = saveSheet.getRange(1, 1, Alast, 2);
saveRange.setValues(savedValues);
}
function createnamedranges() {
//set master spreadhseet
var ss = SpreadsheetApp.getActiveSpreadsheet();
//create variables for calc and save sheets
var calcSheetName = "Part Cost Calculator";
var calcSheet = ss.getSheetByName(calcSheetName);
// get the number of parts in the list on Parts Cost Calculator
var AVals = calcSheet.getRange("A1:A").getValues();
var ALast = AVals.filter(String).length;
// get the parts range and values
var partsRange = calcSheet.getRange(1, 1, ALast, 2);
//Logger.log("DEBUG: The Parts range is "+partsRange.getA1Notation());//DEBUG
var partsRangeValues = partsRange.getValues();
// Loop through the parts list row by row
for (var i = 0; i < ALast; i++) {
// get the Part name and assign as the range name
var nrpartname = partsRangeValues[i][0];
//Logger.log("DEBUG: PartName = "+nrpartname+", value: "+partsRangeValues[i][1]);//DEBUG
// get the range to be named -note (i+1) because the loop starts at 0 (zero) but `getrange` starts at 1 (one)
var rng_to_name = ss.getSheetByName(calcSheetName).getRange((i + 1), 2);
//Logger.log("DEBUG: rng_to_name: "+rng_to_name+", range details: "+rng_to_name.getA1Notation());
// set (and/or update) the named range
ss.setNamedRange(nrpartname, rng_to_name);
// DEBUG: check that the range was created //DEBUG
// var rangeCheck = ss.getRangeByName(nrpartname);//DEBUG
// var rangeCheckName = rangeCheck.getA1Notation(); //DEBUG
// Logger.log("DEBUG: Rangename: "+nrpartname+", Range: "+rangeCheckName);//DEBUG
// credit megabyte1024 https://stackoverflow.com/a/12325103/1330560 "setNamedRange() outside of the spreadsheet container?"
}
}
function deletenamedranges() {
//set master spreadhseet
var ss = SpreadsheetApp.getActiveSpreadsheet();
//create variables for calc and save sheets
var calcSheet = ss.getSheetByName('Part Cost Calculator');
// get the named ranges
var namedRanges = calcSheet.getNamedRanges();
// loop through the list of named ranges and delete them
for (var i = 0; i < namedRanges.length; i++) {
namedRanges[i].remove();
}
}
ADDENDUM: - Копирование на основе именованных диапазонов
В оригинальном so_5466573501
предполагается, что детали находятся в простом списке из 2 столбцов;в этом случае именованные диапазоны не имеют значения.
В следующем коде предполагается, что детали находятся не в списке, а разбросаны в произвольном порядке по всему листу «Калькулятор стоимости детали».Этот код основан на получении NamedRanges, определении соответствующей строки и столбца Named Range, сопоставлении указанной строки и столбца с ВСЕМ диапазоном данных, а затем копировании результатов на лист «Сохраненные части».На листе «Сохраненные детали» по умолчанию не создаются именованные диапазоны, но это легко сделать с помощью функции createnamedranges
(соответствующим образом отредактированной для правильного имени листа).
function so_5466573502() {
//set master spreadhseet
var ss = SpreadsheetApp.getActiveSpreadsheet();
//create variables for calc and save sheets
var calcSheet = ss.getSheetByName('Part Cost Calculator')
var saveSheet = ss.getSheetByName('Saved Parts');
//get the Parts Parameters from Part Cost Calculator
var namedRanges = calcSheet.getNamedRanges();
var numNR = namedRanges.length
//Logger.log("DEBUG: Number of named ranges on Parts Cost Calculator = "+numNR);
// get all the data
var dataRangeValues = calcSheet.getDataRange().getValues();
// create an array to temporarily store results
var resultsarray = [];
// Loop through the array of Named Ranges
for (var x = 0; x < numNR; x++) {
var nrName = namedRanges[x].getName();
var nrRange = namedRanges[x].getRange();
var nrRangerow = nrRange.getRow();
var nrRangecol = nrRange.getColumn();
var nrRangeValue = dataRangeValues[nrRangerow - 1][nrRangecol - 1];
//Logger.log("DEBUG: Named Range-Name: "+nrName+", Range: "+nrRange.getA1Notation()+", Row: "+nrRangerow+", Column: "+nrRangecol+", Value-"+nrRangeValue);//DEBUG
// populate the array with the part name and the part value
resultsarray.push([nrName, nrRangeValue]);
}
// identify the range on the Saved Parts sheet to copy the parts list array.
var saveRange = saveSheet.getRange(1, 1, numNR, 2);
saveRange.setValues(resultsarray);
// sort the results on "Saved Parts"
saveRange.activate().sort({
column: 1,
ascending: true
});
}