Цветовые ячейки на основе диаграммы «Дата начала» и «Дата окончания» с использованием Google Script в Google Sheets - PullRequest
0 голосов
/ 09 октября 2018

В настоящее время у меня есть рабочая версия этого с использованием условного форматирования в листах Google.К сожалению, производительность уменьшается, чем больше условий я добавляю.Я хотел бы преобразовать свое условное форматирование в скрипт Google, который запускается каждый час.Это в основном диаграмма Ганта, которая отлично подходит для моих нужд.

Формула условного форматирования:

=and(AF$2>=$L3,AF$2<=$M3)

, где столбец L - дата начала, а столбец M - дата окончания

enter image description here

Ячейка AF $ 2, AG $ 2, AH2 ... - даты, начинающиеся с сегодняшнего дня, завтра, послезавтра и т. Д. enter image description here

Какая альтернатива будет использовать скрипт Google вместо.Это то, что я до сих пор:

function columnToLetter(column)
{
  var temp, letter = '';
  while (column > 0)
  {
    temp = (column - 1) % 26;
    letter = String.fromCharCode(temp + 65) + letter;
    column = (column - temp - 1) / 26;
  }
  return letter;
}


function setCellBackgrounds() {
  // The name of the sheet to process.
  var sheetName = "MySheet";

  var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(sheetName);
  var range = sheet.getRange("AF3:BJ100");
  var values = range.getValues();
  var colors = [];
  for (var x = 0; x < values.length; x++) {
    colors[x] = [];
    for (var y = 0; y < values[x].length; y++) {

 //trying to apply the formula "=and(AF$2>=$L3,AF$2<=$M3)" here but I'm getting an error
       if (columnToLetter(32+y)+2 >= columnToLetter(12)+x && columnToLetter(32+y)+2 <= columnToLetter(13)+x ) {
        colors[x][y] = '#999999';
       } else {
         //colors[x][y] = '#ffffff';
       }
    }
  }
  range.setBackgrounds(colors);
}

1 Ответ

0 голосов
/ 09 октября 2018

Вы можете заменить формулу условного формата сравнением двух диапазонов L3:M и AF2:BJ2 и применением цветов к вашему выходному диапазону AF3:BJ.

const cols = sheet.getRange("AF2:BJ2").getValues()[0], // Extract the first (& only) row.
      rows = sheet.getRange("L3:M" + sheet.getLastRow()).getValues();

const inWindowColor = "#999999",
      otherColor = null; // null values -> reset color to default.
// Create a rectangular 2D array of color strings. Each row needs an array of colors
// with each inner element corresponding to the given column.
const output = rows.map(function (datePair) {
  var start = datePair[0],
      end = datePair[1];
  return cols.map(function (day) {
    var inWindow = day && start && end // guard against "" values
        && day.getTime() >= start.getTime() && day.getTime() <= end.getTime();
    return (inWindow ? inWindowColor : otherColor);
  });
});

sheet.getRange("AF3").offset(0, 0, output.length, output[0].length)
    .setBackgrounds(output);

.метод класса Array#map, который выполняет численное сравнение дат (как требуется при использовании проверок на равенство).Значение null дается для цветов ячеек вне окна для сброса фона к его цвету по умолчанию в соответствии с описанием метода .Можно было переписать последнюю строку, чтобы исключить вызов offset, но я подумал, что "AF3" легче поддерживать, чем (3, 32, output.length, output[0].length).

Другое чтение


Если цветиспользовать находится в той же строке, что и известный столбец, его можно прочитать без существенных изменений.Очевидно, что требуется, чтобы цветовой диапазон был того же размера, что и диапазон rows (поскольку каждая строка имеет соответствующий цвет).Затем вам просто нужно использовать 2-й автоматический параметр, заданный для Array#map - индекс текущего элемента.Здесь я показываю диапазон определения цвета с 2 столбцами («в окне» (V) и «закончен» (W))

const lastRow = sheet.getLastRow(),
      cols = ...,
      rows = sheet.getRange("L3:M" + lastRow).getValues(),
      colorDefs = sheet.getRange("V3:W" + lastRow).getValues();

const output = rows.map(function (datePair, row) {
  ...
    var color = null;
    if (day && start && end) {
      if (day > end) { // no equality, no `.getTime()` needed
        color = colorDefs[row][1]; // "ended" color is in 2nd index.
      } else if (day.getTime() >= start.getTime()) {
        color = colorDefs[row][0]; // "in window" color is in 1st index.
      } else { /* not started yet */ }
    } else { /* `day`, `start`, and/or `end` were "falsy" */ }
    return color;
 ... 
...