Редактировать: ответ внизу
У меня странное поведение, с которым я столкнулся при использовании скрипта Google.
У меня есть 2d массив, и я вставляю в него данные, используя цикл.
Я заметил, что если использовать
appendRow (SomeArray [I])
ВНУТРИ цикла for все работает как положено.
Но если попытаться получить доступ к данным или использовать appendRow вне цикла for, он всегда выдаст мне данные последней строки, выполненной в цикле for.
так:
appendRow(someArray[1])
дает тот же результат, что и
appendRow(someArray[2]),appendRow(someArray[3])
при использовании вне цикла for.
Может кто-нибудь сказать мне, что вызывает это?
Это также происходит, когда я использую setValue на 2d массиве, я могу использовать его вне цикла, или все строки идентичны.
Я потратил 2 часа на эту простую мелочь и, наконец, понял, что вызывает проблему, но я все еще не могу понять, как ее исправить.
Я прилагаю простой код, который объясняет, в чем проблема, пожалуйста, обратите внимание на второй цикл FOR.
function myFunctionAppendRowInside() {
var sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
var data = sheet.getDataRange().getValues();
var newRow = data[5];
var arr = new Array(100,100);
var currentId = 20000;
var productSku = data[5][2];
for (var i = 0; i < 99; i++){
arr[i] = newRow
}
for (var i = 0; i < 99; i++){
target.getRange(targetRow,1).setValue(evento[i]);
arr[i][0] = currentId + i;
arr[i][2] = productSku + i;
sheet.appendRow(arr[i]);
}
//All of them gives the same row, which is the one created in the last run of the FOR loop arr[98]
sheet.appendRow(arr[1]);
sheet.appendRow(arr[2]);
sheet.appendRow(arr[3]);
}
Пожалуйста, объясните мне, что вызывает это и как преодолеть это.
Редактировать: добавлен мой код, который использует "setValues", но все еще испытывает ту же проблему. Мой массив заполняется только последней строкой, созданной циклом for
function myFunction() {
var sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
var activeSpreadsheet = SpreadsheetApp.getActiveSpreadsheet();
var newSheet = activeSpreadsheet.insertSheet();
newSheet.setName("newSheet");
var data = sheet.getDataRange().getValues();
//Taking the 5th row, using it as a template for rest of rows
var newRow = data[5];
//2d Array
var arr = new Array(100,100);
//data for the only 2 columns who are going to change between rows
var currentId = 20000;
var productSku = data[5][2];
for (var i = 0; i < 99; i++){
newRow[0] = currentId + i;
newRow[2] = productSku + i;
arr[i] = newRow;
}
newSheet.getRange(2, 1, arr.length, arr[0].length).setValues(arr);
}
Второе редактирование:
Таким образом, проблема заключалась в том, что getValues () возвращает массив, с которым мне нужно было работать.
Но Array передаются по ссылке, а не по значению, поэтому любые изменения, которые я вносил в код, меняли исходный массив, полученный из getValues.
Решение:
переберите массив, полученный из "getValues", и скопируйте значения одно за другим (ячейка за ячейкой) в новый массив и только затем манипулируйте им.
Я также создал 2d массив, который также требует запуска цикла for
Я прилагаю рабочий код, который выполняет:
1. скопируйте строку 13, которая включает 51 столбец из моего оригинального листа.
2. создать пустой 2d массив (9999x51).
3. взять строку 13 и манипулировать ее столбцами на основе текущей итерации (т. Е. Строка «1» будет содержать исходные данные + «1»
код:
function myFunction() {
var sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
var activeSpreadsheet = SpreadsheetApp.getActiveSpreadsheet();
var data = sheet.getDataRange().getValues();
//create Array
var arr = [];
//turn it to a 2 dimension array
for (var i=0;i<10000;i++) {
arr[i] = [];
}
//starting point for our new id which will run from 30000-39999
var currentId = 30000;
//run on our 2 dimension array and manipulate data cell by cell
for (var i=0; i <= 9999; i++){
for (var j=0; j<= data[13].length - 1; j++){
if (j == 0){
var obj = currentId + i;
arr[i][j] = obj;
}else{
if (j == 2){
arr[i][j] = data[13][j] + i;
}else{
arr[i][j] = data[13][j];
}
}
}
}
//copy to new sheet
var newSheet = activeSpreadsheet.insertSheet();
newSheet.setName("newSheet466");
newSheet.getRange(1, 1,10000, 51).setValues(arr);
}