0

列 A のタイムスタンプは昇順です。列 G には従業員名があります。列 L の各セルには、1、0、または空白のいずれかがあります。従業員ごとに、L 列の最新の連続 1 を計算しようとしています。私の現在の試みには、次のフィルターを使用した従業員名のリストが含まれていました。私が考えたのは、このフィルターをカスタム数式内にネストして、フィルター処理された結果を反復処理し、1 の連続をカウントして最初の 0 で停止し、1 のカウントを返すことでした。タイムスタンプは昇順であるため、最後の行から反復する必要があります (または、データのインポートを変更して、シートの下部ではなく上部に追加する方法を見つけます)。私はプログラミングの経験がほとんどありませんが、失敗した試みは次のとおりです。私は信じられないほど遠くにいますか?(ところで、ボトムアップから反復する必要があることに気付きました):

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>
4

1 に答える 1

0

あなたはちょっと近いですが、あなたがしたいことによっては、これは非常に複雑になる可能性があります. それにもかかわらず、あなたは正しい軌道に乗っています。

最初に行うことは、スプレッドシートでアクティブな範囲の値を取得することです。

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

これにより、2 次元配列が に割り当てられmyDataValsます。

ここから、外側の配列 (行ごと) をループしてから、それぞれの内側の配列 (列ごと) をループできます。この問題を解決するには多くの方法があり、実際に何をしようとしているのかによって異なります。基本的な JavaScript プログラミングについて詳しくは、https ://www.javascript.com/resources をご覧ください。

試してみることができるサンプル関数を書きました。私の解決策は、行 (外側の配列) を反復処理し、キーが従業員名であるオブジェクトにそれらを割り当てることでした。これにより、行が名前で効果的にソートされます。次に、各名前内の行をタイムスタンプ値で降順に並べ替えました。次に、最初の (最新の) タイムスタンプから始めて、列 L が 1 か 0 かを確認します。1 が見つかった場合は、streaks オブジェクト内の名前のキーにある数値を 1 増やします。 0 が見つかった場合、ストリークは壊れており、streakEnded ブール値を true に変更して while ループを終了します。セルが空白の場合、または値が 1 または 0 以外の場合、アクションは実行されず、停止するか行がなくなるまでループが続行されます。

最後に、streaks オブジェクトが返されます。そこから、シートに新しいページを作成したり、結果を電子メールで送信したり、その他の操作を行うことができます。とりあえず、オブジェクトをスクリプト ロガーに記録しただけです。スクリプト エディターで ([表示] > [ログ]) を選択すると、結果を確認できます。セルの範囲を強調表示したことを確認してください。

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;
  }

}
于 2016-01-14T21:36:11.747 に答える