• Как сделать автоматическое заполнение по множественному условию и сравнению из другой таблицы?

    @P1lK111p
    Псевдо-аналитик
    В твоей же таблице примерной прописал формулу:
    =ЕСЛИ(filter('Специалисты'!D:D;'Специалисты'!A:A=B2)<>0;
        filter('Специалисты'!B:B;
               'Специалисты'!A:A=B2;
               'Специалисты'!C:C<=A2;
               'Специалисты'!D:D>=A2);
        filter('Специалисты'!B:B;
               'Специалисты'!A:A=B2;
               'Специалисты'!C:C<=A2))


    Формула работает в том порядке что ты описал. Надеюсь ты знаком с функцией фильтр. Не особо использую функцию впр, но возможно она была бы удобнее в том плане, что не нужно было бы вставлять формулу в каждую ячейку.

    Опишу подробнее что делает формула:

    ЕСЛИ(filter('Специалисты'!D:D;'Специалисты'!A:A=B2)<>0; //эта часть проверяет заполнена ли дата увольнения в диапазоне 'Специалисты'!D:D сверяя имя в диапазоне 'Специалисты'!A:A и имени нашего спеца в ячейке B2.

    Если дата увольнения заполнена, значит сотрудник был уволен и нужно дополнительно сравнить дату сделки с датой увольнения, следующая часть сделает это:

    filter('Специалисты'!B:B; //ищем имя ропа в диапазоне ('Специалисты'!B:B) исходя из условий ниже

    'Специалисты'!A:A=B2; //находим строку в диапазоне фио ('Специалисты'!A:A) равную имени нашего спеца (B2)

    'Специалисты'!C:C<=A2; //находим строку в диапазоне даты приёма ('Специалисты'!C:C) которая меньше даты нашей сделки (A2), соответственно если дата сделки будет меньше даты приёма, фильтр не выведет имя ропа.

    'Специалисты'!D:D>=A2); //находим строку в диапазоне даты увольнения ('Специалисты'!d:d) которая больше даты нашей сделки (A2), соответственно если дата сделки будет больше даты увольнения, фильтр не выведет имя ропа.

    Последняя часть формулы будет выполняться если дата увольнения по сотруднику не заполнена, раз дата увольнения у сотрудника не заполнена, значит он не уволен, и смысла нет проверять-сверять дату сделки и дату увольнения, поэтому повторяем прошлую часть формулы без проверки на дату увольнения:

    filter('Специалисты'!B:B;
    'Специалисты'!A:A=B2;
    'Специалисты'!C:C<=A2))

    По логике зачем нам нужна последняя частя формулы, но там возникает проблема без неё. Если не проверять заполнена дата увольнения или нет, то фильтр не сможет искать и сверять по дате увольнения, ведь в случае незаполненной даты увольнения, дата увольнения будет нулевой и соответственно меньше даты сделки, что логически быть не может.
    Ответ написан
  • Как прописать условное форматирование для автоматического выделения ячеек в Google таблице в которых есть повторяющиеся элементы?

    @P1lK111p Автор вопроса
    Псевдо-аналитик
    Решил задачу с помощью скрипта предложенного Chat GPT. Есть данные в диапазоне d2:d, скрипт в начале выдёргивает 6-тизначные номера заказов из столбца D и переносит их в соответствующие строки столбца K, затем проверяет ячейки столбца K на дубликаты и подкрашивает красным цветом строки A:K последних найденных дубликатов. В ходе решения появлялись проблемы, что если данные в столбце D изменялись, старая раскраска не очищалась, переписал в скрипт очищение цвета перед новым раскрашиванием. Скрипт cрабатывает автоматически при ручном редактировании ячейки столбца D и проходится по всем ячейкам d2:d; k2:k.
    function onEdit(e) {
      var sheet = e.source.getActiveSheet();
      var range = e.range;
      var column = range.getColumn();
      
      // Убедимся, что изменение произошло в столбце D
      if (column == 4) {
        var lastRow = sheet.getLastRow();
        var dataRange = sheet.getRange(2, 4, lastRow - 1, 1); // Исключаем заголовок
        var dataValues = dataRange.getValues();
        
        var orderNumbers = [];
    
        for (var i = 0; i < dataValues.length; i++) {
          var sentence = dataValues[i][0];
          var orderNumber = extractOrderNumber(sentence);
          orderNumbers.push([orderNumber]);
        }
    
        var orderColumn = sheet.getRange(2, 11, lastRow - 1, 1);
        
        // Убираем только красный фон перед записью новых значений
        var backgrounds = orderColumn.getBackgrounds();
        for (var i = 0; i < backgrounds.length; i++) {
          backgrounds[i][0] = ""; // Очищаем фон
        }
        orderColumn.setBackgrounds(backgrounds);
        
        // Записываем номера заказов
        orderColumn.setValues(orderNumbers);
        
        // Убираем красный фон для столбцов A:K
        var rangeAtoK = sheet.getRange(2, 1, lastRow - 1, 11);
        var rangeBackgrounds = rangeAtoK.getBackgrounds();
        for (var i = 0; i < rangeBackgrounds.length; i++) {
          for (var j = 0; j < rangeBackgrounds[i].length; j++) {
            rangeBackgrounds[i][j] = ""; // Очищаем фон
          }
        }
        rangeAtoK.setBackgrounds(rangeBackgrounds);
        
        // Проверяем на дубликаты и подсвечиваем строки
        checkForDuplicates(sheet);
      }
    }
    
    function extractOrderNumber(sentence) {
      var match = sentence.match(/\b\d{6}\b/);
      return match ? match[0] : "";
    }
    
    function checkForDuplicates(sheet) {
      var dataRange = sheet.getDataRange();
      var data = dataRange.getValues();
      var duplicates = {};
    
      for (var i = 1; i < data.length; i++) {
        var orderNumber = data[i][10];
        
        if (orderNumber && orderNumber !== "") { // Проверяем, что значение не пустое
          var key = orderNumber;
    
          if (duplicates[key]) {
            sheet.getRange(i + 1, 1, 1, 11).setBackground("red"); // Подсветка строки красным
          } else {
            duplicates[key] = true;
          }
        }
      }
    }

    Минус кода в том что он пробегается и обновляет номера заказов по всем ячейкам в диапазонах d2:d; k2:k соответственно; Под себя подкорректировал, что бы перенос данных в столбец K происходил только по той строке в которой было изменение ячейки столбца D; А полное прохождение по всему диапазону d2:d; k2:k реализовал посредством отдельного вызова опции в меню; Это сделано что бы не нагружать табличку. Вот обновлённый код, если кому пригодится:
    function onOpen() {
      var ui = SpreadsheetApp.getUi();
      ui.createMenu('Custom Menu')
          .addItem('Run Script', 'runScript')
          .addToUi();
    }
    
    function runScript() {
      var sheet = SpreadsheetApp.getActiveSheet();
      var lastRow = sheet.getLastRow();
      var dataRange = sheet.getRange(2, 4, lastRow - 1, 1);
      var dataValues = dataRange.getValues();
      
      var orderNumbers = [];
    
      for (var i = 0; i < dataValues.length; i++) {
        var sentence = dataValues[i][0];
        var orderNumber = extractOrderNumber(sentence);
        orderNumbers.push([orderNumber]);
      }
    
      var orderColumn = sheet.getRange(2, 11, lastRow - 1, 1);
      
      var backgrounds = orderColumn.getBackgrounds();
      for (var i = 0; i < backgrounds.length; i++) {
        backgrounds[i][0] = "";
      }
      orderColumn.setBackgrounds(backgrounds);
      
      orderColumn.setValues(orderNumbers);
      
      var rangeAtoK = sheet.getRange(2, 1, lastRow - 1, 11);
      var rangeBackgrounds = rangeAtoK.getBackgrounds();
      for (var i = 0; i < rangeBackgrounds.length; i++) {
        for (var j = 0; j < rangeBackgrounds[i].length; j++) {
          rangeBackgrounds[i][j] = "";
        }
      }
      rangeAtoK.setBackgrounds(rangeBackgrounds);
      
      checkForDuplicates(sheet);
    }
    
    function extractOrderNumber(sentence) {
      var match = sentence.match(/\b\d{6}\b/);
      return match ? match[0] : "";
    }
    
    function checkForDuplicates(sheet) {
      var dataRange = sheet.getDataRange();
      var data = dataRange.getValues();
      var duplicates = {};
    
      for (var i = 1; i < data.length; i++) {
        var orderNumber = data[i][10];
        
        if (orderNumber && orderNumber !== "") {
          var key = orderNumber;
    
          if (duplicates[key]) {
            sheet.getRange(i + 1, 1, 1, 11).setBackground("red");
          } else {
            duplicates[key] = true;
          }
        }
      }
    }
    
    function onEdit(e) {
      var sheet = e.source.getActiveSheet();
      var sheetId = "Идентификатор вашей таблицы"; // Идентификатор вашей таблицы
      if (sheet.getParent().getId() !== sheetId) return; // Применяем скрипт только для указанной таблицы
    
      var range = e.range;
      var column = range.getColumn();
      var row = range.getRow();
      
      if (column == 4) {
        var dataRange = sheet.getRange(row, 4, 1, 1);
        var dataValue = dataRange.getValue();
        
        if (!dataValue || dataValue === "") {
          sheet.getRange(row, 11).setValue("");
          sheet.getRange(row, 1, 1, 11).setBackground("");
          checkForDuplicates(sheet);
        } else {
          var orderNumber = extractOrderNumber(dataValue);
          
          if (orderNumber && orderNumber !== "") {
            var orderColumn = sheet.getRange(row, 11);
            orderColumn.setValue(orderNumber);
            
            sheet.getRange(row, 1, 1, 11).setBackground("");
            checkForDuplicates(sheet);
          }
        }
      }
    }

    64e1316a64498616295039.png
    Ответ написан
  • Как сделать вывод текста по нескольким условиям из нескольких ячеек?

    @P1lK111p
    Псевдо-аналитик
    Решения задачи очень много, смотря для чего и как будет решаться проблема, поэтому просто приведу простой пример:
    64dfcee74fda4330447708.png
    Однако, можно реализовать и по другому, есть также функции "суммеслимн", "индекс", "поиск". У меня была такого типа задача, я использовал функцию поиск в сочетании с еслиошибка. В справочнике определил номер группы каждой площадки, а затем при выборе площадок, выводился соответствующий результат. Если поиск не находил значение "1" в диапазоне, то выдавал ошибку и результат выводился значением "2":
    64dfd1127d17d542134615.png
    Ответ написан