Google Script работает как 2 отдельных скрипта, но не внутри одной функции - PullRequest
0 голосов
/ 31 января 2020

В основном у меня есть скрипт, который состоит из 4 блоков: 1. Копирует в пределах диапазона каждой строки при условии, что он соответствует критериям 2. Удаляет все пустые строки 3. Устанавливает все числа в процентах 4. Применяет условное форматирование ячейки к одному из колонки

Четвертая часть вызывает у меня проблемы. Сценарий запускается без каких-либо сообщений об ошибках, и блок 4 работает отлично, если он находится в другом сценарии с теми же определенными переменными, но как только он находится внутри той же функции, что и другие, он просто не запускается без каких-либо сообщений об ошибках. .

Попытка изменить имя переменных на одноразовые, чтобы убедиться, что это не потому, что один из «var» был изменен над ним, удалив «else if», чтобы оставить только «if» в l oop, перемещая его в другие части скрипта, но если блок 1 находится в скрипте, тогда блок 4 не будет применяться (будет применяться, если это только с 2 & 3.

2 & 3, которые следуют той же структуре, хорошо работают с 1.

Кто-нибудь знает, что не так с моим сценарием? :) Каждый блок комментируется тем, что он делает

function copy() {
//Set variables & criterion to choose which rows to copy
  var s = SpreadsheetApp.openByUrl('https://docs.google.com/spreadsheets/d/1bEiLWsbFszcsz0tlQudMBgTk5uviyv_wDx7fFa8txFM/edit');
  var ssSource = s.getSheetByName('Variations');
  var ssDest = s.getSheetByName('Email');
  var lastRowSource = ssSource.getLastRow();
  var lastRowDest = ssDest.getLastRow();
  var lastColSource = ssSource.getLastColumn()
  var criteria = 0;
  var titles = ssSource.getRange(1,1,1, lastColSource).getValues()


//Copies the range
  ssDest.getRange(1,1,1, lastColSource).setValues(titles)

  for (var i = 2; i < lastRowSource; i++ ) {
    var test = ssSource.getRange(i ,1);    
    Logger.log(test.getValue()+ ' <? ' + criteria);
    if (ssSource.getRange(i ,6).getValue() > criteria) { 

      ssSource.getRange(i ,1,1,ssSource.getLastColumn()).copyTo(ssDest.getRange(i ,1,1,ssSource.getLastColumn()), {contentsOnly:true}); // copy/paste content only
}  
    }

//Removes empty rows
  var data = ssDest.getDataRange().getValues();
  var targetData = new Array();
  for(n=0;n<data.length;++n){
    if(data[n].join().replace(/,/g,'')!=''){ targetData.push(data[n])};
    Logger.log(data[n].join().replace(/,/g,''))
  }
  ssDest.getDataRange().clear();
  ssDest.getRange(1,1,targetData.length,targetData[0].length).setValues(targetData);

//Formats numbers as percentages
  var rangePercent = ssDest.getRange(1,1,ssDest.getLastRow(),ssDest.getLastColumn());
  var rowsPercent = rangePercent.getNumRows();
  var colsPercent = rangePercent.getNumColumns();

  for(var rowPercent = 1; rowPercent <= rowsPercent; rowPercent++) {
    for(var colPercent = 1; colPercent <= colsPercent; colPercent++) {
      var cellPercent = rangePercent.getCell(rowPercent, colPercent);
      var valuePercent = cellPercent.getValue();
      if(typeof(valuePercent) == 'number') {
        cellPercent.setNumberFormat("##.#%");
      }
    }
  }

//Adds conditional background colours

  for (var z = 2; z < lastRowDest+1;z++) {
    var avgCpc = 4;
    var rangeColour = ssDest.getRange(z,avgCpc);
    var dataColour = rangeColour.getValue()
    if (dataColour < 0) {
      ssDest.getRange(z,avgCpc).setBackground('#d9ead3')
      }
            else if (dataColour > 0) {
        ssDest.getRange(z,avgCpc).setBackground('#f4cccc')
      }

  }

//Centers Values

}

1 Ответ

0 голосов
/ 04 февраля 2020

Проблема в том, что в вашем коде есть проблемы с производительностью, потому что вы слишком часто вызываете такие методы, как getRange() и getValue() внутри различных циклов, поэтому Apps Script не может идти в ногу со всеми этими вызовами. Пожалуйста, отметьте Best Practices .

Сказав это, я изменил ваш код, чтобы сделать его более эффективным. Помимо вашей функции copy, я добавил еще две функции, чтобы сделать код более читабельным.

функция copy

Как и раньше, эта функция устанавливает переменные, но теперь она вызывает две другие функции, которые setPositiveCostValues и formatCells

function copy() {
  //Set variables & criterion to choose which rows to copy
  var ss = SpreadsheetApp.openByUrl('your-url');
  var ssSource = ss.getSheetByName('Variations');
  var ssDest = ss.getSheetByName('Email');
  // set the title
  var titles = ssSource.getRange(1,1,1, ssSource.getLastColumn()).getValues();
  ssDest.getRange(1,1,1, ssSource.getLastColumn()).setValues(titles);
  // get the positive values you want from the cost col
  var positiveValues = setPositiveCostValues(ssSource, ssDest, ssSource.getLastRow());
  // fomrat the cells you want as percentage and set the color
  formatCells(ssDest, positiveValues);
}

функция setPositiveCostValues ​​

Это будет принимать значения, при которых стоимость является положительной, и будет извлекать ячейки с пустыми значениями и "n / a "values.

function setPositiveCostValues(ssSource,ssDest, lastRowSource){
  var postiveCost = ssSource.getRange(2, 1, lastRowSource, 6).getValues();
  // this loop will clean the empty elements and the ones that only have n/a
  for (var i = postiveCost.length - 1; i >= 0; i--) {
    if (postiveCost[i][0]) {
      postiveCost.splice(i + 1, postiveCost.length - (i + 1));
      postiveCost = postiveCost.filter(function(el){ return el != 'n/a'})
      break;
    }
  }
  return postiveCost;
}

функция formatCells

Это отформатирует ячейки в стоимости col в процентах и ​​установит правильный цвет в вашем avgCp c col.

function formatCells(ssDest, postiveCost){
  var avgCpc = 4, cost = 6, row = 2, criteria = 0;
  // iterate over the array and depending on the criteria format the cells 
  postiveCost.forEach(function(el){
    if(el[cost - 1] > criteria){
      var ssDestRange = ssDest.getRange(row, 1, 1, cost);
      ssDestRange.setValues([el]);
      ssDestRange.getCell(1, cost).setNumberFormat("##.#%");
      // set the color depending on the avgCpc value condition
      if(el[avgCpc - 1] < criteria) ssDest.getRange(row, avgCpc).setBackground('#d9ead3');
      else ssDest.getRange(row, avgCpc).setBackground('#f4cccc');
      row++;
    }
  });
}

Код

Весь ваш код теперь будет выглядеть так:

function copy() {
  //Set variables & criterion to choose which rows to copy
  var ss = SpreadsheetApp.openByUrl('your-url');
  var ssSource = ss.getSheetByName('Variations');
  var ssDest = ss.getSheetByName('Email');
  // set the title
  var titles = ssSource.getRange(1,1,1, ssSource.getLastColumn()).getValues();
  ssDest.getRange(1,1,1, ssSource.getLastColumn()).setValues(titles);
  // get the positive values you want from the cost col
  var positiveValues = setPositiveCostValues(ssSource, ssDest, ssSource.getLastRow());
  // fomrat the cells you want as percentage and set the color
  formatCells(ssDest, positiveValues);
}

function setPositiveCostValues(ssSource,ssDest, lastRowSource){
  var postiveCost = ssSource.getRange(2, 1, lastRowSource, 6).getValues();
  // this loop will clean the empty elements and the ones that only have n/a
  for (var i = postiveCost.length - 1; i >= 0; i--) {
    if (postiveCost[i][0]) {
      postiveCost.splice(i + 1, postiveCost.length - (i + 1));
      postiveCost = postiveCost.filter(function(el){ return el != 'n/a'})
      break;
    }
  }
  return postiveCost;
}

function formatCells(ssDest, postiveCost){
  var avgCpc = 4, cost = 6, row = 2, criteria = 0;
  // iterate over the array and depending on the criteria format the cells 
  postiveCost.forEach(function(el){
    if(el[cost - 1] > criteria){
      var ssDestRange = ssDest.getRange(row, 1, 1, cost);
      ssDestRange.setValues([el]);
      ssDestRange.getCell(1, cost).setNumberFormat("##.#%");
      // set the color depending on the avgCpc value condition
      if(el[avgCpc - 1] < criteria) ssDest.getRange(row, avgCpc).setBackground('#d9ead3');
      else ssDest.getRange(row, avgCpc).setBackground('#f4cccc');
      row++;
    }
  });
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...