web-dev-qa-db-ja.com

Googleスプレッドシートにタイムスタンプを自動的に追加する方法

Googleスプレッドシートに5つのセルを含むシートがあり、最初の3つには単語のみが含まれ、最後の2つには時間(具体的にはタイムスタンプ)が含まれています。

_cell 1 = data
cell 2 = data
cell 3 = data
cell 4 = time start
cell 5 = time ended
_

セル1にデータが提供されると、タイムスタンプがセル4に自動的に表示されます。セル2とセル3にデータが提供されると、タイムスタンプがセル5の新しい値になります。

私の友人は私にコードをくれました、それはスクリプトエディタに貼り付けられるべきです:

_function readRows() {
  var sheet = SpreadsheetApp.getActiveSheet();
  var rows = sheet.getDataRange();
  var numRows = rows.getNumRows();
  var values = rows.getValues();

for (var i = 0; i <= numRows - 1; i++) {
  var row = values[i];
  Logger.log(row);
 }
};
_

そして

_function onOpen() {
 var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
 var entries = [{
 name : "Read Data",
 functionName : "readRows"
}];
spreadsheet.addMenu("Script Center Menu", entries);
};
function timestamp() {
return new Date()
}
_

このコードは=IF(B6="","",timestamp(B6)) cell 4に貼り付けられ、このコードは=IF(D6="","",timestamp(C6&B6))がセル5にあります。彼の例のトラッカーではその動作を示しています。しかし、それを私のものにコピーしたとき、セル4とセル5の出力は今日の日付であり、時刻ではありません。

誰かが私を助けることができますか?なぜ時刻ではなく日付を出力するのですか?

5
Nixxhalle

これが役立つ場合は、これを参照できます チュートリアル 。スクリプトコードで、

var timestamp_format = "MM-dd-yyyy"; // Timestamp Format.

var timestamp_format = "MM-dd-yyyy hh:mm:ss"; // Timestamp Format.

これはおそらくあなたを助けるはずです。

7
Arpan

私はちょうどこの問題に遭遇し、 Internet Geeks によって提供されるコードを変更しました。

それらのコードは指定された列を更新することによって機能し、タイムスタンプは別の指定された列の同じ行に挿入されます。

変更したのは、タイムスタンプが日付形式ではなく文字列であるため、日付と時刻を分離したことです。私の方法はグラフの生成に役立ちます。

これは、変更を追跡する列を指定し、日付と時刻にそれぞれupDate列とupTime列を作成することで機能します。

function onEdit(event) {
  var timezone = "GMT+1";
  var date_format = "MM/dd/yyyy";
  var time_format = "hh:mm";

  var updateColName = "Резултат";

  var DateColName = "upDate";
  var TimeColName = "upTime";

  var sheet = event.source.getActiveSheet(); // All sheets
  // var sheet = event.source.getSheetByName('Test'); //Name of the sheet where you want to run this script. 

  var actRng = event.source.getActiveRange();
  var editColumn = actRng.getColumn();
  var index = actRng.getRowIndex();
  var headers = sheet.getRange(1, 1, 1, sheet.getLastColumn()).getValues();

  var dateCol = headers[0].indexOf(DateColName);
  var timeCol = headers[0].indexOf(TimeColName);

  var updateCol = headers[0].indexOf(updateColName);
  updateCol = updateCol + 1;

  if (dateCol > -1 && timeCol > -1 && index > 1 && editColumn == updateCol) {
    // only timestamp if 'Last Updated' header exists, but not in the header row itself! 

    var cellDate = sheet.getRange(index, dateCol + 1);
    var cellTime = sheet.getRange(index, timeCol + 1);

    var date = Utilities.formatDate(new Date(), timezone, date_format);
    var time = Utilities.formatDate(new Date(), timezone, time_format);

    cellDate.setValue(date);
    cellTime.setValue(time);
  }
}

これが人々に役立つことを願っています。

更新されたより単純なコード

function onEdit(e) {
  var sh = e.source.getActiveSheet();
  var sheets = ['Sheet1']; // Which sheets to run the code.

  // Columns with the data to be tracked. 1 = A, 2 = B...
  var ind = [1, 2, 3].indexOf(e.range.columnStart); 

  // Which columns to have the timestamp, related to the data cells.
  // Data in 1 (A) will have the timestamp in 4 (D)
  var stampCols = [4, 5, 6]

  if(sheets.indexOf(sh.getName()) == -1 || ind == -1) return;

  // Insert/Update the timestamp.
  var timestampCell = sh.getRange(e.range.rowStart, stampCols[ind]);
  timestampCell.setValue(typeof e.value == 'object' ? null : new Date());
}
6
Ivan

Internet Geeks のコードにも基づいて、少し異なるバージョンを作成しました。

複数の名前付きシートをサポートするために、またGoogle Sheets Scriptは現在Array.prototype.includes()をサポートしていないため、前述のポリフィルを含めました ここ

また、私のバージョンでは、タイムスタンプはその行のセルのcreationの日付を示しており、ここで提供されている他のスクリプトのように最後に更新された日付ではありません。 。

function onEdit(event) {
  var sheetNames = [
    'Pounds £', 
    'Euros €'
  ]
  var sheet = event.source.getActiveSheet();
  if (sheetNames.includes(sheet.getName())){
    var timezone = "GMT";
    var dateFormat = "MM/dd/yyyy";
    var updateColName = "Paid for ...";
    var dateColName = "Date";

    var actRng = sheet.getActiveRange();
    var editColumn = actRng.getColumn();
    var rowIndex = actRng.getRowIndex();
    var headers = sheet.getRange(1, 1, 1, sheet.getLastColumn()).getValues();
    var dateCol = headers[0].indexOf(dateColName) + 1;
    var updateCol = headers[0].indexOf(updateColName) + 1;
    var dateCell = sheet.getRange(rowIndex, dateCol);
    if (dateCol > 0 && rowIndex > 1 && editColumn == updateCol && dateCell.isBlank())
    {
      dateCell.setValue(Utilities.formatDate(new Date(), timezone, dateFormat));
    }
  }
}

// https://stackoverflow.com/a/51774307/349169
// https://tc39.github.io/ecma262/#sec-array.prototype.includes
if (!Array.prototype.includes) {
  Object.defineProperty(Array.prototype, 'includes', {
    value: function(searchElement, fromIndex) {

      if (this == null) {
        throw new TypeError('"this" is null or not defined');
      }

      // 1. Let O be ? ToObject(this value).
      var o = Object(this);

      // 2. Let len be ? ToLength(? Get(O, "length")).
      var len = o.length >>> 0;

      // 3. If len is 0, return false.
      if (len === 0) {
        return false;
      }

      // 4. Let n be ? ToInteger(fromIndex).
      //    (If fromIndex is undefined, this step produces the value 0.)
      var n = fromIndex | 0;

      // 5. If n ≥ 0, then
      //  a. Let k be n.
      // 6. Else n < 0,
      //  a. Let k be len + n.
      //  b. If k < 0, let k be 0.
      var k = Math.max(n >= 0 ? n : len - Math.abs(n), 0);

      function sameValueZero(x, y) {
        return x === y || (typeof x === 'number' && typeof y === 'number' && isNaN(x) && isNaN(y));
      }

      // 7. Repeat, while k < len
      while (k < len) {
        // a. Let elementK be the result of ? Get(O, ! ToString(k)).
        // b. If SameValueZero(searchElement, elementK) is true, return true.
        if (sameValueZero(o[k], searchElement)) {
          return true;
        }
        // c. Increase k by 1. 
        k++;
      }

      // 8. Return false
      return false;
    }
  });
}
1
Chris