wolf47
@wolf47
Айтишник, немного програмирую на JS

Как сделать вложенный цикл в google spreadsheet?

У меня список покупателей и товаров.

Покупателей 30, а товаров 400.

Мне нужно чтобы у каждого покупателя были свои товары. То есть будет большое полотно, для 1 покупателя будет 400 товаров, для 2 покупателя также, и так далее для каждого покупателя. Это нужно для того чтобы я смог отдельно для каждого покупателя настроить товар.

Я имею 2 таблицы google spreadsheet. 1 - покупатели, 2 - товары. Каждая таблица может периодический обновляться.

Проблема в том что товары перезаписываются, вместо того чтобы на листе быть 12000 строк, я получаю всего 400.

Вот такой скрип я написал. Помогите с правильным скриптом. Тут я думаю нужны чисто знания JavaScript-а. Не могу выстроить правильную логику.

И еще я получаю ошибку на самом последней строке: TypeError: Cannot read property "0" from undefined.
Система указывает на эту строчку кода

sheet.getRange(i, 2).setValue(products[i][0]);

Мой код:

function writeData(){
  var sheet = SpreadsheetApp.getActiveSheet();
  var rows = sheet.getDataRange();
  var numRows = rows.getNumRows();   

  var buyers = getBuyers();
  var products= getProducts();
  
  sheet.getDataRange().clear();
  
  for (var j = 1; j <= buyers .length; j++)
  {
    var i = 0; 
    while (i <= products.length)
    {
      i++;
      sheet.getRange(i, 1).setValue(buyers [j]);
      sheet.getRange(i, 2).setValue(products[i][0]);
      sheet.getRange(i, 3).setValue(products[i][4]);
    }
  }
}
  • Вопрос задан
  • 2963 просмотра
Решения вопроса 1
wolf47
@wolf47 Автор вопроса
Айтишник, немного програмирую на JS
Решил вот таким вот способом:

function writeData(){
var ss = SpreadsheetApp.getActiveSpreadsheet();
var resultSheet = ss.getSheetByName("Result");
var agentsSheet = ss.getSheetByName("Buyers ");
var productsSheet = ss.getSheetByName("Products");

var buyersNumRows = buyersSheet.getDataRange().getNumRows();
var productsNumRows = productsSheet .getDataRange().getNumRows();
var productsNumColumns = productsSheet.getDataRange().getNumColumns();

var buyersData = agentsSheet.getDataRange().getValues();
var productsData = productsSheet .getDataRange().getValues();

resultSheet.getDataRange().clear();

for(var i=1; i< buyersNumRows ; i++)
{
var lastrow = resultSheet.getLastRow();
resultSheet.getRange(lastrow+1, 1).setValue(buyersData [i][0]);
resultSheet.getRange(lastrow+1, 2, productsNumRows , productsNumColumns).setValues(products);
}
}

в итоге получилось 24 000 строк. Задача выполнена, для всех покупателей сделали свои услуги.
Ответ написан
Пригласить эксперта
Ответы на вопрос 2
oshliaer
@oshliaer
Google Product Expert
Здравствуйте.

Ни при каких обстоятельствах не дразните систему setValue(), да еще и во вложенном цикле. Запись происходит не на ваш ПК, а на сервер. Кому понравится, когда его так дергают?

Чтобы работало даже с "черновиками", т.е. до 50 000 строк на лист, сначала берите ВСЕ данные, потом формируйте ГОТОВЫЙ массив, потом делайте setValue().

Примерно так:
function writeData(){
  //Не факт, что поможет, но вдруг
  SpreadsheetApp.flush();
  
  //Далее как у всех
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  
  var resultSheet = ss.getSheetByName("Result");
  var agentsSheet = ss.getSheetByName("Buyers");
  var productsSheet = ss.getSheetByName("Products");
  
  var aV = agentsSheet.getDataRange().getValues();
  var pV = productsSheet.getDataRange().getValues();
  
  //срезать шапку
  aV.shift();
  //  pV.shift();
  
  var res = [];
  
  for(var i = 0; i< aV.length; i++)
  {
    res.push([].concat([aV[i][0]], pV[0]));    
    for(var j = 1; j < pV.length; j++){      
      res.push([].concat([''], pV[j]));      
    }
  }
  
  res = res.slice(0, 50000);
  resultSheet.getDataRange().clear(); 
  resultSheet.getRange(1, 1, res.length, res[0].length).setValues(res);
}

С уважением.
Больше ответов на русском языке тут Bit.Ly/rudrive и тут Bit.Ly/rugoogleapps.
Ответ написан
sheet.getRange(i, 1) => sheet.getRange(i + (j * 400), 1)
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через TM ID
Похожие вопросы