1

私はまだここでロープを学んでいます。他の寄稿者が提案したコードに基づいて、Google フォームを使用して時間エントリを記録するコンサルタントにリマインダー メールを送信するスクリプトをまとめました。スプレッドシートは、最初に各コンサルタントのすべてのジョブ情報を含むカレンダー エントリをインポートします。カレンダー エントリがインポートされた後、コンサルタントがまだ時間エントリを記録していない場合は、次のスクリプトによって、そうするように促すメールが送信されます。

function sendReminder() {

  var rmndrFrom = "XYZ, Inc.";
  var myemail   = "support@xyz.com";

  var sheet     = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Pending");
  var numRows   = sheet.getLastRow();
  var lastCol   = sheet.getLastColumn();
  var dataRange = sheet.getRange(2, 1, numRows, lastCol); // row 1 is the header row
  var sheetData = dataRange.getValues();

  for (var i = 0; i < sheetData.length; ++i) {
    var row = sheetData[i];
    if (row[0]){
      var jobNumb = row[0]; // Job Number
      var conName = row[2]; // Consultant Name
      var conMail = row[3]; // Consultant Email
      var jobDate = row[4]; // Date

      // format email string
      var subject = "Time Entry Reminder: " + conName + " / Job " + jobNumb;

        try {
          var conMsgH = 'This is a reminder for you to record your time entry for Job #<strong>' + jobNum + '/' + jobDate + '</strong>';

          // strip HTML for plain text message
          var conMsgP = conMsgH.replace(/\<br\/\>/gi, '\n').replace(/(<([^>]+)>)/ig, "");

          // send reminder to consultants
          MailApp.sendEmail(conMail, subject, conMsgP, { htmlBody:conMsgH, name:rmndrFrom });

        } catch (e) { // error handler
          MailApp.sendEmail(myemail, "Error in sending reminder email.", e.message);
        }
      }
  }
}

基本的に、このスクリプトは Pending シートを解析し、列 A にジョブ番号がある場合、そのジョブ番号でコンサルタントにリマインダー メールを送信します。ただし、1 人のコンサルタントの名前に複数のジョブ番号が含まれている場合があります。各コンサルタントに、時間エントリを記録する必要があるジョブ番号のリストを記載した電子メールを 1 通送信するスクリプトが必要です。

よろしくお願いいたします。コードを最適化する方法についての提案も大歓迎です。

4

2 に答える 2

2

これにアプローチする方法はいくつかあります。1 つの方法は、コンサルタントの電子メール、名前、仕事番号のリストを記載したシートを保持することです。このデータ、すべてのジョブ ID とジョブ情報のリストをスクリプトにロードします。次に、コンサルタント リストに基づいてジョブ ID をフィルター処理し、メールを作成します。または、その番号のリストを非常に短いスクリプトで送信することもできます。

もう 1 つの方法は、コード内でコンサルタントごとにすべての並べ替えを行い、その方法でメールを送信することです。これは私が取ったアプローチであり、反復 JS 関数 map、filter、reduceも MDN で使用しています。

コードは以下に掲載されていますが、スプレッドシートに添付されてコメントが付けられているのを確認したい場合は (コンサルタント情報だけを含む追加のシートを作成する機能も)、ここを参照してください。

以下は、あなたの関数の私の反復です。あなたの状況に役立つことを願っています:

var rmndrFrom = "XYZ, Inc.";
var myemail   = "me@emailisawesome.com";
var subject   = "Time Entry Reminder";

function sendReminder() {
  var sheet       = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Pending");
  var numRows     = sheet.getLastRow();
  var lastCol     = sheet.getLastColumn();
  var sheetData   = sheet.getRange(2, 1, numRows-1, lastCol).getValues();
  var cons = sheet.getRange(2,3,numRows-1,1).getValues().reduce(flatten_).filter(getUniqueConsultants_);
  cons.forEach(sendEmail_, sheetData);
}

function sendEmail_(consultant) {
  var consultantsJobs = this.filter(getJobsForConsultant_, consultant);
  var jobList = consultantsJobs.map(buildJobLine_).join("<br>"); 
  try {
    var conMsgH = "Hi " + consultant + ",<br>";
    conMsgH    += "This is a reminder for you to record your time entry for the following jobs:<br><br>";
    conMsgH    += jobList;
    conMsgH    += "<br><br>Thank you for your cooperation.";
    var conMsgP = conMsgH.replace(/\<br\/\>/gi, '\n').replace(/(<([^>]+)>)/ig, "");
    MailApp.sendEmail(consultantsJobs[0][3], subject, conMsgP, {htmlBody:conMsgH, name:rmndrFrom});
  } catch (e) {
    MailApp.sendEmail(myemail, "Error in sending reminder email.", e.message);
  } 
}

function buildJobLine_(job) {
  return "Job #" + job[0] + " on " + Utilities.formatDate(job[4], Session.getTimeZone(), "MMM dd yyyy");
}

function getJobsForConsultant_(row) {
  return row[2] == this;
}

function getUniqueConsultants_(v,i,a) {
  return a.indexOf(v) == i;
}

function flatten_(a,b) {
  return a.concat(b);
}
于 2012-12-24T23:34:01.450 に答える
1

foob​​yの答えは私の JS スキルをはるかに超えていると言わざるを得ません。うまく機能すると確信していますが、楽しみのために、何か違う (そして私の pov とはより単純な) ものを提案したい気がします;-)

元のスクリプトとの主な違いは、重複した名前を検出し、それに応じて脅威を与えることができる配列の並べ替えです。HTML 構成は確かにはるかに優れている可能性がありますが、それはあなたの主な要求ではありませんでした。

ここにコードがあります

function sendReminder() {

  var rmndrFrom = "XYZ, Inc.";
  var myemail   = "support@xyz.com";
  var sheet     = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Pending");
  var initial = "Hi conName,<BR>This is a reminder for you to record your time entry for the following jobs : <BR><BR><table border = 1 cellpadding = 3 bgcolor='#FFFFBB'><TR><TD>";

  var sheetData = sheet.getDataRange().getValues();// simplified code to get the data array
  sheetData.shift();//skips the headers
  sheetData.sort(function(x,y){
  var xp = x[2];// sort on column 3 but you can change  here...
  var yp = y[2];// sort on column 3 but you can change  here...
  return xp == yp ? 0 : xp < yp ? -1 : 1;// sort ascending, eventually change here...
  });
//  Logger.log(sheetData);// sorted
  var last = sheetData.length
  var i = 1;//index 0 is handled outside the loop
  var row = sheetData[0];
  var subject = "Time Entry Reminder: " + row[2] + " / Job "
  var conMsgH = initial
  var msgComponent = makeline_(row)
  subject += msgComponent[0]
  conMsgH += msgComponent[1]

  while (i<last){
    if(sheetData[i][2]!=sheetData[i-1][2]||i==last-1){
      sendData_(sheetData[i-1][3],sheetData[i-1][2],subject,conMsgH)
      var subject = "Time Entry Reminder: " + sheetData[i][2] + " / Job "
  var conMsgH = initial;
      }
  msgComponent = makeline_(sheetData[i])
  subject += msgComponent[0]
  conMsgH += msgComponent[1]
  ++i
  }
}

function sendData_(conMail,conName,subject,conMsgH){
  conMsgH = conMsgH.substr(0,conMsgH.length-8)+'</TABLE>'
  conMsgH = conMsgH.replace('conName',conName)
  var conMsgP = conMsgH.replace(/<\/tr>/ig, '\n').replace(/<br>/ig, '\n').replace(/(<([^>]+)>)/ig, "")
  subject = subject.substr(0,subject.length-2);// remove the last '+ '
//  Logger.log(subject)
//  Logger.log(conMsgH)
  Logger.log(conMsgP)
//  Logger.log(conMail)
  try{
          // send reminder to consultants          
          MailApp.sendEmail(conMail, subject, conMsgP, { htmlBody:conMsgH, name:rmndrFrom });
        } catch (e) { // error handler
//          MailApp.sendEmail(myemail, "Error in sending reminder email.", e.message);
    }
}

function makeline_(row){
      var jobNumb = row[0]; // Job Number
      var conName = row[2]; // Consultant Name
      var conMail = row[3]; // Consultant Email
      var descr = row[1]; // description
      var FUS1=new Date(row[4]).toString().substr(25,6)+':00';// get timezone of this event, taking care of daylight savings
      var jobDate = Utilities.formatDate(row[4], FUS1, "MMM dd yyyy @ hh:mm aaa"); // Date
      var subject =  jobNumb+' + ';
      var conMsgH =  'Job #'+jobNumb + '</TD><TD>' + jobDate + '</TD><TD>' + descr + '</TD></TR><TR><TD>';
return [subject,conMsgH];
}

EDIT :メール形式を改善し、テーブルを使用してジョブと日付を表示し、いくつかのバグを削除しました ;-) (正直なところ、ほとんど同じユースケースを持っているので、これも個人的な使用のために作成しました)

于 2012-12-25T01:07:47.997 に答える