Сценарий условного форматирования - установить итерацию - PullRequest
0 голосов
/ 07 ноября 2018

У меня есть пользовательская формула для правил условного форматирования. Я пытаюсь написать скрипт, который проверяет количество значений (около 50) в столбце (столбец B на листе «Мой»), и если ячейка равна определенной строке (M1, M2 или M3), то указанная формула для условного форматирования применяется лист «Представление календаря». Код, который у меня сейчас есть:

function myFunction() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName("Calendar View");
sheet.getRange("C4:NC50").clearFormat();
var range = sheet.getRange("C4:NC4");
var rule = SpreadsheetApp.newConditionalFormatRule()
    .whenFormulaSatisfied('=AND(indirect("Mine!$B5")="M1", C$2>=indirect("Mine!$C5"), C$2<indirect("Mine!$D5"))')
    .setBackground("#FF0000")
    .setRanges([range])
    .build();
var rules = sheet.getConditionalFormatRules();
rules.push(rule);
sheet.setConditionalFormatRules(rules);
}

Как я могу ввести метод итерации для .whenFormulaSatisfied, например:

.whenFormulaSatisfied('=AND(indirect("Mine!$B6")="M1", C$2>=indirect("Mine!$C6"), C$2<indirect("Mine!$D6"))')
.whenFormulaSatisfied('=AND(indirect("Mine!$B7")="M1", C$2>=indirect("Mine!$C7"), C$2<indirect("Mine!$D7"))')
.whenFormulaSatisfied('=AND(indirect("Mine!$B8")="M1", C$2>=indirect("Mine!$C8"), C$2<indirect("Mine!$D8"))')
............

Это лист, над которым я работаю: https://docs.google.com/spreadsheets/d/1Af84aHaG0VjXmtaWc0-uAdGFrX1LozRNLQLMatSOqgU/edit?usp=sharing

1 Ответ

0 голосов
/ 24 ноября 2018

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

Я предлагаю немного другой подход.
1) Возьмите данные о шахте и постройте календарь.
2) Поместите значения в поля забронированных дат.
3) Примените правило single условного форматирования для календаря.

Методология определения того, какие даты забронированы, заключается в том, чтобы вставить номинальное значение в соответствующие ячейки. Затем применяется правило .whenCellNotEmpty() вместо указания конкретного значения. Кроме того, код форматирует как фон, так и цвет шрифта, чтобы любые данные были скрыты.

Также обратите внимание: в начале скрипта код удаляет как содержимое, так и форматирование.

function so_53185335() {
    // build the spreadsheet app and set source and target sheets
    var ss = SpreadsheetApp.getActiveSpreadsheet();
    var calSheet = ss.getSheetByName("Calendar View");
    var dataSheet = ss.getSheetByName("Mine");

    // get the last rows and start rows for both sheets 
    var lrMine = dataSheet.getLastRow();
    var lrCal = calSheet.getLastRow();
    var dataRowStart = 5;
    var calRowStart = 4;

    // clear formats and data from Calendar  
    calSheet.getRange(calRowStart, 2, lrCal, 366).clear({
        contentsOnly: true,
        formatOnly: true
    });

    // get Mine rows with data, define the range and  get data
    var dataRows = lrMine - dataRowStart + 1;
    //Logger.log("Mine: number of data rows "+dataRows);// DEBUG  
    var dataRange = dataSheet.getRange(dataRowStart, 2, dataRows, 3);
    //Logger.log("data range is "+dataRange.getA1Notation());// DEBUG
    var dataValues = dataRange.getValues();

    //set some variables for use in loop  
    var i = 0; // counter
    var z = 0; // counter
    var calstartCol = 3; // equals first day of the year
    var calrow = 0; // counter row for Calendar sheet
    var calArray = [];
    var masterArray = [];

    // loop through the rows in Mine

    for (i = 0; i < dataRows; i++) {
        // test for value 
        if (dataValues[i][0] === "M1" || dataValues[i][0] === "M2" || dataValues[i][0] === "M3") {
            //Logger.log("Match: i="+i+", value = "+dataValues[i][0]);//DEBUG
            calArray = [];
            masterArray = [];
            calrow = calrow + 1;

            // calculate the start day (as a day in the year)
            var now = new Date(dataValues[i][1]);
            var start = new Date(now.getFullYear(), 0, 0);
            var diff = (now - start) + ((start.getTimezoneOffset() - now.getTimezoneOffset()) * 60 * 1000);
            var oneDay = 1000 * 60 * 60 * 24;
            var startday = Math.floor(diff / oneDay);

            // calculate the end day (as a day in the year)
            var fnow = new Date(dataValues[i][2]);
            var fstart = new Date(fnow.getFullYear(), 0, 0);
            var fdiff = (fnow - fstart) + ((fstart.getTimezoneOffset() - fnow.getTimezoneOffset()) * 60 * 1000);
            var foneDay = 1000 * 60 * 60 * 24;
            var endday = Math.floor(fdiff / foneDay);
            var nod = endday - startday + 1;

            // assign the value for the Property
            var cell = calSheet.getRange(calstartCol + calrow, 2);
            cell.setValue(dataValues[i][0]);

            // create an array of values for booked dates; just insert the number "1"
            for (z = 1; z < nod + 1; z++) {
                calArray.push(1);
            }
            masterArray.push(calArray);

            // Assign the values for booked dates
            var cell = calSheet.getRange(calstartCol + calrow, startday + 2, 1, nod);
            cell.setValue(masterArray);
        }

    }

    // create and apply a single Conditional forma rule for the data range on Calendar
    var range = calSheet.getRange(calRowStart, calstartCol, calstartCol + calrow, 366);
    var rule = SpreadsheetApp.newConditionalFormatRule()
        .whenCellNotEmpty()
        .setFontColor("#FF0000")
        .setBackground("#FF0000")
        .setRanges([range])
        .build();
    var rules = calSheet.getConditionalFormatRules();
    rules.push(rule);
    calSheet.setConditionalFormatRules(rules);

}

Календарь выглядит следующим образом.


enter image description here

...