简体   繁体   English

使用 Google 表格的 Google Script 班次调度程序

[英]Google Script shift scheduler using Google sheet

I am still learning Google Script, Now I am working in a project to automate the shift schedule creation using Google sheet我仍在学习 Google Script,现在我正在从事一个使用 Google 工作表自动创建轮班计划的项目

I managed to find some scripts in how to get a certain range and fill it in a specific cell with certain values with some simple conditions and loops我设法找到了一些关于如何获得特定范围的脚本,并使用一些简单的条件和循环将其填充到具有特定值的特定单元格中

var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getActiveSheet();
var rangeData = sheet.getDataRange();
var lastColumn = rangeData.getLastColumn();
var lastRow = rangeData.getLastRow();
var searchRange = sheet.getRange(2,2, lastRow-1, lastColumn-1);

function onOpen() {
  ui.createMenu('Checker')
  .addItem('Bad Way', 'badWay')
  .addItem('Good Way', 'goodWay')
  .addToUi();
};

/* 
BAD - Go to each cell and see if it contains a value
and then fill in the background if it contains a dash or 
zero 
*/
function badWay() {
  //Loop through each column and each row in the sheet.
  for(i = 1; i < lastColumn; i++){
    for (j = 1; j < lastRow ; j++){
      var cell = searchRange.getCell(j,i).getValue();
      if (cell === "-"){
        sheet.getRange(j+1,i+1).setBackground("#cc4125");
      }else if (cell === 0){
        sheet.getRange(j+1,i+1).setBackground("#e69138");
      };
    };
  };

};

/*
GOOD - Create a client-side array of the relevant data
search through the array and if there is a dash or zero,
then add the relevant background color. 
*/
function goodWay() {
  // Get array of values in the search Range
  var rangeValues = searchRange.getValues();
  // Loop through array and if condition met, add relevant
  // background color.
  for ( i = 0; i < lastColumn - 1; i++){
    for ( j = 0 ; j < lastRow - 1; j++){
      if(rangeValues[j][i] === "-"){
        sheet.getRange(j+2,i+2).setBackground("#cc4125");
      }else if (rangeValues[j][i] === 0){
        sheet.getRange(j+2,i+2).setBackground("#e69138");
      }; 
    };
  };

};

But the problem is more complicated, I need to ensure a few conditions before allowing the script to fill the schedule like:但问题更复杂,在允许脚本填写时间表之前,我需要确保一些条件,例如:

  • Every day there must be a minimum No. of employees in each shift.每天每个班次必须有最少数量的员工。
  • Each employee can't work more than 5 days a week, (2 days off but not necessarily sequenced)每个员工每周工作时间不能超过 5 天,(2 天休息但不一定按顺序)

Shifts would look like this:班次看起来像这样:

在此处输入图片说明 Any idea how to implement this in google script and without using other external software?知道如何在谷歌脚本中实现这一点而不使用其他外部软件吗?

Thanks in advance提前致谢

This code will help you with what you want (Days off are empty cells):此代码将帮助您完成所需的操作(休息日为空单元格):

var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getActiveSheet();
var rangeData = sheet.getDataRange();
var lastColumn = rangeData.getLastColumn();
var lastRow = rangeData.getLastRow();
var searchRange = sheet.getRange(2, 2, lastRow-1, lastColumn-1);
var daysNotWorkedCounter = 0;
var numberEmpls = 0;
var emplWorkingDay = 0;
var emplWorkingNight = 0;

function onOpen() {
  var entries = [{
    name : "Good Way",
    functionName : "goodWay"
  }]
  ss.addMenu('Checker', entries);
};


/*
GOOD - Create a client-side array of the relevant data
search through the array and if there is a dash or zero,
then add the relevant background color. 
*/
function goodWay() {
  var rangeValues = searchRange.getValues();
  daysWorkedByWeek(rangeValues);
  numbDailyEmp(rangeValues);
}

/*
  It checks for every user if he/she has worked more than two days
  It also sets to red the cells where are days off
*/
function daysWorkedByWeek(rangeValues){
  // It checks all cols in a row
  for(row = 0 ; row < lastRow - 1; row++){
    daysNotWorkedCounter = 0;
    for (col = 0; col < lastColumn - 1; col++){
      // If there is a day off (empty cell), then set a color to that cell
      // and count the day the empl is not working
      if(!rangeValues[row][col] && col !== 0){
        sheet.getRange(row+2,col+2).setBackground("#ff0000");
        daysNotWorkedCounter++;
        // If there are more than two that week, Log a message 
        if(daysNotWorkedCounter > 2){
          Logger.log("This employee has worked more than two days in a week: " + sheet.getRange(row+2,1).getValues());
        }
      }
      // If 7 days passed (one week), restart the counter
      if(col % 7 === 0) daysNotWorkedCounter = 0;  
    }
  }
}

/*
  For every day it checks how many employees are working in each shift 
*/
function numbDailyEmp(rangeValues){
  // It checks all rows in a col
  for (col = 0; col < lastColumn - 1; col++){
    emplWorkingDay = 0;
    emplWorkingNight = 0;
    for(row = 0 ; row < lastRow - 1; row++){
      // Checks empls working that day
      if(rangeValues[row][col] && col !== 0){
        // Count the numbers of empls depending in the shift
        if(rangeValues[row][0] === "Morning") emplWorkingDay++;
        else if (rangeValues[row][0] === "Night") emplWorkingNight++; 
      }
    }
    // Log a message with the number of empls working in a shift that day
    if(col !== 0){
      Logger.log("Number of employees working at day " +  emplWorkingDay);
      Logger.log("Number of employees working at night " + emplWorkingNight);
      // if there are less than a min, then Log a message
      if(emplWorkingDay < 6 || emplWorkingNight < 6){
        Logger.log("Not enough working that day")
      }
    }
  }
}

Notice how I added two functions ( daysWorkedByWeek and numbDailyEmp ) to separate the two tasks you were requiring请注意我如何添加两个函数( daysWorkedByWeeknumbDailyEmp )来分隔您需要的两个任务

daysWorkedByWeek checks for every employee the number of days he/she has had off by a week. daysWorkedByWeek为每位员工检查他/她每周休假的天数。

/*
  It checks for every user if he/she has worked more than two days
  It also sets to red the cells where are days off
*/
function daysWorkedByWeek(rangeValues){
  // It checks all cols in a row
  for(row = 0 ; row < lastRow - 1; row++){
    daysNotWorkedCounter = 0;
    for (col = 0; col < lastColumn - 1; col++){
      // If there is a day off (empty cell), then set a color to that cell
      // and count the day the empl is not working
      if(!rangeValues[row][col] && col !== 0){
        sheet.getRange(row+2,col+2).setBackground("#ff0000");
        daysNotWorkedCounter++;
        // If there are more than two that week, Log a message 
        if(daysNotWorkedCounter > 2){
          Logger.log("This employee has worked more than two days in a week: " + sheet.getRange(row+2,1).getValues());
        }
      }
      // If 7 days passed (one week), restart the counter
      if(col % 7 === 0) daysNotWorkedCounter = 0;  
    }
  }
}

numbDailyEmp checks for every day if the minimum amount of employees are working that day depending in their shifts. numbDailyEmp每天检查是否有最低数量的员工在当天工作,具体取决于他们的班次。

/*
  For every day it checks how many employees are working in each shift 
*/
function numbDailyEmp(rangeValues){
  // It checks all rows in a col
  for (col = 0; col < lastColumn - 1; col++){
    emplWorkingDay = 0;
    emplWorkingNight = 0;
    for(row = 0 ; row < lastRow - 1; row++){
      // Checks empls working that day
      if(rangeValues[row][col] && col !== 0){
        // Count the numbers of empls depending in the shift
        if(rangeValues[row][0] === "Morning") emplWorkingDay++;
        else if (rangeValues[row][0] === "Night") emplWorkingNight++; 
      }
    }
    // Log a message with the number of empls working in a shift that day
    if(col !== 0){
      Logger.log("Number of employees working at day " +  emplWorkingDay);
      Logger.log("Number of employees working at night " + emplWorkingNight);
      // if there are less than a min, then Log a message
      if(emplWorkingDay < 6 || emplWorkingNight < 6){
        Logger.log("Not enough working that day")
      }
    }
  }
}

Docs文档

For best practices I recommend you check:对于最佳实践,我建议您检查:

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM