Сценарии приложений Google, счетчик

Столбец А имеет метку времени в порядке возрастания. Столбец G имеет имена сотрудников. Каждая ячейка в столбце L имеет либо 1, 0, либо пусто. Я пытаюсь рассчитать последнюю серию из 1 в столбце L на сотрудника. Мои текущие попытки включали список имен сотрудников со следующим фильтром: "фильтр L:L, где G:G = имя сотрудника, а L:L не пусто". Моя мысль заключалась в том, чтобы внедрить этот фильтр в пользовательскую формулу, которая перебирает отфильтрованные результаты, считая серию 1 с и останавливаясь на первых 0, возвращая количество единиц. Поскольку временные метки расположены в порядке возрастания, мне понадобится выполнить итерацию с последней строки вверх (или выяснить, как изменить импорт данных, добавив его в верхнюю часть листа, а не в нижнюю). У меня очень мало опыта программирования, но здесь была моя неудачная попытка. Как невероятно далеко я? (кстати, я только что понял, что это нужно для перебора снизу вверх):

function streak() { 
  var sheet = SpreadsheetApp.getActiveSheet() 
  var range = sheet.getActiveRange(); 
  var cell = sheet.getActiveCell(); 
  var value = cell.getValue();


  for (i in range) { 
    var count = 0 
    if (value = 1) { 
      count += 1; 
      } <br>
    return count; 
} <br>
} <br>

1 ответ

Вы вроде как близки, но в зависимости от того, что вы хотите сделать, это может оказаться довольно сложным. Тем не менее, вы на правильном пути.

Сначала вы должны получить значения для активного диапазона в вашей электронной таблице.

var myDataVals = SpreadsheetApp.getActiveSheet().getActiveRange().getValues();

Это назначит 2-мерный массив myDataVals,

Отсюда вы можете перебрать внешний массив (строка за строкой), а затем внутренний массив внутри каждого (столбец за столбцом). Есть много способов решить этот вопрос, и это действительно зависит от того, что именно вы пытаетесь сделать. Вы можете узнать больше о базовом программировании на JavaScript здесь: https://www.javascript.com/resources

Я написал пример функции, с которой вы можете поиграть. Мое решение состояло в том, чтобы перебрать строки (внешний массив), а затем назначить их объекту, ключами которого являются имена сотрудников; это эффективно сортирует строки по имени. Затем я отсортировал строки в каждом имени по значению отметки времени в порядке убывания. Затем, начиная с первой (самой последней) временной отметки, я проверяю, имеет ли столбец L 1 или 0. Если я найду 1, я увеличу число, расположенное в объекте штрихов на ключе, с именем на 1. Если я найду 0, полоса будет прервана, и я выйду из цикла while, изменив логическое значение streakEnded на true. Если ячейка пуста или значение не равно 1 или 0, никаких действий не предпринимается, и цикл продолжается до тех пор, пока он не остановится или не останется больше строк.

Наконец, объект штрихов возвращается. Оттуда вы можете создать новую страницу в листе, или отправить результаты по электронной почте, или что-нибудь еще, что вы можете сделать. Сейчас я только что зарегистрировал объект в логгере скриптов. Вы можете увидеть результаты, выбрав (View > Logs) в редакторе сценариев. Убедитесь, что вы выделили диапазон ячеек!

function streak() {
  var activeRangeVals, allStreaks, columns;

  // Get the active range as a 2-dimensional array of values
  activeRangeVals = SpreadsheetApp.getActiveSheet().getActiveRange().getValues();

  // Define which columns contain what data in the active Range
  // There are better ways to do this (named ranges)
  // but this was quickest for me.
  columns = {
    'name': 6,      // G
    'streak': 11,   // L
    'time': 0       // A
  };

  allStreaks = getStreaks(getEmployeeRowsObject(activeRangeVals));

  Logger.log(allStreaks);

  return allStreaks;

  function getEmployeeRowsObject(data) {
    // Create an empty object to hold employee data
    var activeName, activeRow, employees = {}, i = 0;

    // Iterate through the data by row and assign rows to employee object
    // using employee names as the key
    for(i = 0; i < data.length; i+= 1) {
      // Assign the active row by copying from the array
      activeRow = data[i].slice();

      // Assign the active name based on info provided in the columns object
      activeName = activeRow[columns['name']];

      // If the employee is already defined on the object
      if(employees[activeName] !== undefined) {
        // Add the row to the stack
        employees[activeName].push(activeRow);

      // If not:  
      } else {
        // Define a new array with the first row being the active row
        employees[activeName] = [activeRow];
      }
    }

    return employees;
  }

  function getStreaks(employees) {
    var activeRow, activeStreak, i = 0, streaks = {}, streakEnded;

    for(employee in employees) {
      activeRow = employees[employee];

      // Sort by timestamp in descending order (most recent first)
      activeRow = activeRow.sort(function(a, b) {
        return b[columns['time']].getTime() - a[columns['time']].getTime();
      });

      i = 0, streaks[employee] = 0, streakEnded = false;

      while(i < activeRow.length && streakEnded === false) {
        activeStreak = parseInt(activeRow[i][columns['streak']]);
        if(activeStreak === 1) {
          streaks[employee] += 1;
        } else if(activeStreak === 0) {
          streakEnded = true;
        }
        i += 1;
      }
    }

    return streaks;
  }

}
Другие вопросы по тегам