Как сохранить данные в массиве, используя цикл For в скрипте Google Apps - передать массив по значению - PullRequest
0 голосов
/ 04 июня 2019

Редактировать: ответ внизу

У меня странное поведение, с которым я столкнулся при использовании скрипта 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);


}

1 Ответ

1 голос
/ 04 июня 2019

Я не уверен, что вызывает твою проблему.Но вместо добавления каждой строки (которая может быть очень медленной) быстрее получить диапазон и установить его значение.Например:

sheet.getRange(1, 1, arr.length, arr[0].length).setValues(arr);

Где две единицы - это начальная позиция, которую вы хотите использовать.Для получения дополнительной информации ознакомьтесь с документацией по getRange .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...