web-dev-qa-db-ja.com

Googleフォームに基づいてGoogleスプレッドシートに自動インクリメントフィールドを追加できますか?

Googleフォームでは、スプレッドシートに挿入する各行とタイムスタンプに一意の値を与えることは可能ですか?

20
Toby Allen

これを行うには、スクリプトトリガーを追加します。

現在のフォームに2つの列Timestampと1つの質問への回答があるとします。したがって、現在、列AとBにデータが入力されています。列Cに番号を自動インクリメントさせると仮定します。

最初にToolsに移動する必要があります()Script Editor

[スクリプトエディター]ウィンドウで、次のスクリプトを入力します。

function onFormSubmit(e) {

var sheet = SpreadsheetApp.getActiveSheet();
var row =  SpreadsheetApp.getActiveSheet().getLastRow();

sheet.getRange(row,3).setValue(row);


}

スクリプトを保存し、Triggersメニューに移動してCurrent script's triggersを選択します

次のようにドロップダウンに入力します。

Google Script Triggers

Saveをクリックします

次に、Google App Scriptウィンドウを保存して閉じます。

これで、フォームが送信されると、フォームを介して送信されたデータとともに列Cの行番号が入力されます。

行番号が保存される列を変更するには、スクリプトの次の行を変更する必要があります。

sheet.getRange(row,3).setValue(row);

値3を対応する列インデックス番号に変更します。

11
codingbadger

Barryの優れた答えに加えて、行を削除しても一意のIDを保持したい場合は、カウントを保持する静的セルを使用できます。その後、この番号を使用して、テーブルへの新しいエントリごとにインクリメントできます。

そのため、変更はスプレッドシートのどこかに番号を保持し(以下のコードの「M1」)、次のようにコードを変更します。

function onFormSubmit(e) 
{
   var sheet = SpreadsheetApp.getActiveSheet();
   var row =  SpreadsheetApp.getActiveSheet().getLastRow();

   var bugCount = sheet.getRange("M1").getValue();
   bugCount++;

   sheet.getRange(row,1).setValue(bugCount);
   sheet.getRange("M1").setValue(bugCount);
}

繰り返しになりますが、最後の2行目を変更して、IDの配置場所を変更します。

7
Danny Parker

(バリーとダニーからの)以前の両方の回答に基づいて:

ID列が列Aであると仮定します。「次のID」セルを選択し、次の式に設定します(「P1」にあると仮定)。

=MAX(A:A)+1

[ツール]メニューの下のスクリプトエディタを使用してスクリプトを作成し、次を貼り付けます。

function onFormSubmit(e) {
  // Get the active sheet
  var sheet = SpreadsheetApp.getActiveSheet();
  // Get the active row
  var row = sheet.getActiveCell().getRowIndex();
  // Get the next ID value.  NOTE: This cell should be set to: =MAX(A:A)+1
  var id = sheet.getRange("P1").getValue();
  // Check of ID column is empty
  if (sheet.getRange(row, 1).getValue() == "") {
    // Set new ID value
    sheet.getRange(row, 1).setValue(id);
  }
}

スクリプトエディターの[トリガー]メニューを使用してスクリプトトリガーを追加します。 enter image description here

7
oneself

上記の答えに加えて-このソリューションでは、スプレッドシートセルを追加する必要はありません。

フォームの送信に組み込みのイベントハンドラを使用して、一意のIDを取得できます。スプレッドシートはフォームの宛先であるため、行を削除しても実際には応答が削除されるわけではありません。それを念頭に置いて...

編集:IDの必要性を削除し、日付のフォーマットの問題に対処しました。

/**
* This function extracts the relevant properties from the event handler,
* then uses them to get the uniqueID and record the response
* @param {Object} e The event parameter for form submission to a spreadsheet;
*     e has the following properties values, range, namedValues
*/

function onFormSubmit(e) {
  var uniqueID = getUniqueID(e.values);
  recordResponseID(e.range, uniqueID);
}

/**
* Records the unique ID for this response to the correct cell.
* @param  {Object} eventRange Range in which the response is written
* @param  {Integer} uniqueID   Unique id for this range
*/

function recordResponseID(eventRange, uniqueID) {
  var row = eventRange.getRow();
  var column = eventRange.getLastColumn() + 1;
  var sheet = SpreadsheetApp.getActiveSheet();
  sheet.getRange(row, column).setValue(uniqueID);

}
/**
* A shortcut function to get the form that is connected to this spreadsheet
* @return {Form}          The form associated with this spreadsheet.
**/

function getConnectedForm() {
  var formUrl = SpreadsheetApp.getActiveSpreadsheet().getFormUrl();
  var form =  FormApp.openByUrl(formUrl);
  return form;
}

/**
* Returns a unique ID for the response, by finding the actual Response that
* has the same properties.
* @param  {Array} eventValues Array of: Timestamp_string, form_response_value...
* @return {Integer}             The unique id (by 1 based array position) of the Response
*/

function getUniqueID(eventValues) {
  var isMatch = false;
  var eventItems = eventValues.slice(1);

  var responses = getConnectedForm().getResponses();
  //loop backwards through responses (latest is most likely)
  for (var i = responses.length - 1; i > -1; i--) {
    var responseItems = responses[i].getItemResponses();
    //check each value matches

    for (var j = 0; j < responseItems.length; j++) {
      if (responseItems[j].getResponse() !== eventItems[j]) {
        break;
      }
      isMatch = true;
    }
    if (isMatch) {
      return i + 1;
    }
  }
}

function testOnSubmit() {
  var answers = [
    ["Sue", "39", "Okay I suppose"],
    ["John", "22", "Great"],
    ["Jane", "45", "yeah no"],
    ["Bob", "33", "Super"]
  ];

  var form = getConnectedForm();
  var items = form.getItems();
  for (var i = 0; i < answers.length; i++) {
    var formResponse = form.createResponse();
    for (var j = 0; j < items.length; j++) {
      var item = items[j];
      var itemResponse = item.asTextItem().createResponse(answers[i][j]);
      formResponse.withItemResponse(itemResponse);
    }
    formResponse.submit();
    Utilities.sleep(500);
  }

}
4
Tom Horwood

これは他の回答の派生物ですが、将来のユーザーにとっては役立つかもしれません。

function onEdit(e) 
{
   var sheet = SpreadsheetApp.getActiveSheet();
   var row =  SpreadsheetApp.getActiveSheet().getActiveCell().getRow();

   var bugCount = sheet.getRange("M2").getValue();
   bugCount++;

   if (sheet.getRange(row, 1).getValue() == "") {
      sheet.getRange(row,1).setValue(bugCount);
      sheet.getRange("M2").setValue(bugCount);    
   }

}

主な違いは、行が編集されたときにアクティブな行の列1が更新されることです。ただし、値がまだ指定されていない場合のみです。

編集時の他の回答に記載されているとおりにトリガーを設定する必要があります。

set trigger to on edit

2
nacross

「Googleフォームでは、スプレッドシートに挿入する各行とタイムスタンプに一意の値を指定することはできますか?」値を複製せずにさらにレスポンスを追加すると、これは機能するはずです:

=iferror(ArrayFormula(match(A1:A,A:A,0)),"")
0
pnuts