Original image by martarey84 from Pixabay and modified by author

最小限の知識で入門する Google Apps Script〜Google ドキュメント編-2〜

今回も、最小限の知識で入門する Google Apps Script〜自動化の構想編〜 から続いている通院を記録するシステムを作る話です。

前回の記事では、Google Apps Scriptで Google ドキュメントを操作する準備として、Google ドキュメントに用意されているオブジェクトとそのメソッド、また、JavaScript の文法に関して今回必要となる基礎知識について説明しました。

今回の記事では、Google スプレッドシートのデータを Google Apps Script で取得し二次元配列に格納したものから、Google ドキュメントを作成したいと思います。

目次

スプレッドシートに保存されているデータと二次元配列の関係

通院記録フォームから送信されてきた情報はスプレッドシートに保存されました。そして、Google Apps Script のコードを書いて、スプレッドシートに保存されている情報を二次元配列に格納する関数 getAllData を作成しました。以下がそのコードです。コメント行をたどってみてどんな処理を行っているのか思い出してみてください。ここではスプレッドシートの ID を 1aDeGesrSue5 としています。

function getAllData(){
  // SpreadsheetApp オブジェクトの openById メソッドを使い
  // id が 1aDeGesrSue5 の Spreadsheet オブジェクトを取得し、
  // 変数 ss に代入
  const ss = SpreadsheetApp.openById('1aDeGesrSue5');

  // Spreadsheet オブジェクトの getSheetByName メソッドを使い
  // シート名 が 'フォームの回答 1'の Sheetオブジェクトを取得し、
  // 変数 sheet に代入
  const sheet = ss.getSheetByName('フォームの回答 1');

  // Sheetオブジェクトの getLastRow メソッドを使い
  // シートに存在するデータの最終行番号を取得し、
  // 変数 last_row_num に代入
  const last_row = sheet.getLastRow();

  // Sheetオブジェクトの getRange メソッドを使い
  // シートの 2行2列を左上のセルとし、
  // それを含めて行数が last_row-1、列数が7の領域を
  // Rangeオブジェクトとして取得し、変数 data_range に代入
  const data_range = sheet.getRange(2,2,last_row -1, 7);

  // Rangeオブジェクトの getValues メソッドを使い、
  // data_ranage に含まれているデータを二次元配列として取得し、
  // 変数 all_data に代入
  const all_data = data_range.getValues();
  console.log(all_data);

  //戻り値として all_data を呼び出し元へ返す
  return all_data;
}

前々回の記事で説明したように、この関数の戻り値として返される二次元配列は次の図のスプレッドシートで赤く囲まれた部分に対応するものですす。

getAllData関数が取得するスプレッドシートの領域

つまり、

const all_data = getAllData();

として、関数 getAllData によって取得される二次元配列を変数 all_data に格納すると、配列の値とシートのセルの値は次のように対応しています。

getAllData関数の戻り値となる二次元配列とスプレッドシートのセルの関係

つまり、

all_data[0] にはスプレッドシートの2行目のデータ、
all_data[1] にはスプレッドシートの3行目のデータ、
all_data[2] にはスプレッドシートの4行目のデータ、


のように一次元配列として格納されます。

またさらに例えば、

all_data[1][3] にはスプレッドシートの3行、2列の位置にあるデータ

が格納されています。

ですから、i = 0, 1, 2, 3,… に対して、

all_data[i][0] は通院日
all_data[i][1] は医療機関
all_data[i][2] は診察内容
all_data[i][3] は付添者
all_data[i][4] は備考
all_data[i][5] は次回予定日
all_data[i][6] は次回付添予定者

というようにデータが格納されています。

二次元配列のデータを書き込んでドキュメントを作成

次の図は、スプレッドシートに格納されていた一番上の行のデータから Google ドキュメントを作ったものです。

スプレッドシートの一番上の行のデータから作られたドキュメント

つまり、これは all_data[0] から作られるものです。このようなドキュメントをどのようなプログラムで自動的に作成すればよいのか考えてみることにします。

とにかくまず Google ドキュメントファイルが必要になりますから、初めに「通院記録」というファイル名のドキュメントをプログラムで新規作成するコードを書いても良いのですが、一度ファイルを作成するとそのためのコードはその後使われることがありません。ですから、ここではプログラムを簡単なものにするために、Google ドライブのどこかのフォルダに、「通院記録」というファイル名で中身が空のドキュメントファイルを自分で手動で最初に作成しておくことにします。そして、このファイルにフォームから送信されてくる内容を(スプレッドシートを経由し、二次元配列を取得して)書き込むことにより、通院情報を文書化して行くことにします。空のドキュメントファイルを作ったら、ドキュメント ID が必要になるので控えておいくようにしてください。

Google ドキュメントファイルの本文をあらわす Body オブジェクトを取得し、さらに本文を一度すべて消去

スプレッドシートから取得される二次元配列は、それまでに報告された通院情報をすべて含んでいます。そこで、少し乱暴ですが、フォームから情報が送信されるたびにドキュメントファイル「通院記録」の中身を一旦すべて消去し、改めて二次元配列に格納されている情報を使ってすべての情報を文書化するという仕方でプログラムを作っていこうと思います。つまり、過去に作られた文書の内容は一旦すべて消去されますが、最新の情報を含めてすべて作り直されるということです。

上記のようにすることでプログラムが簡単なものになる、過去に送信された内容に変更があった場合に対応しやすいなどのメリットがあります。一方で、新規に情報が送信されるたびにすべてを作り直しているので無駄があるとも言えます。

次のコードは、先に用意したドキュメントファイル「通院記録」を操作し、本文をすべて一度消去するプログラムです。

ここでは、ドキュメントの ID は 1yNcSBYaP 、そのドキュメントの最初のタブの ID は t.0 としています。

// ドキュメントファイルの ID を変数 doc_id に代入
const doc_id = '1yNcSBYaP';

// ドキュメントファイルの最初のタブの ID を変数 tab_id に代入
const tab_id = 't.0';

// DocumentApp オブジェクトの openByID メソッドで ドキュメントファイルを
// Documentオブジェクトとして取得し、変数 doc に代入
const doc = DocumentApp.openById(doc_id);

// Document オブジェクト doc の getTab メソッドで最初のタブを Tab オブジェクト
// として取得し、変数 tab に代入
const tab = doc.getTab(tab_id);

// Tab オブジェクト tab の asDocumentTab メソッドで tab を編集可能な DocumentTab オブジェクトとして
取得し、変数 documentTab に代入
const documentTab = tab.asDocumentTab();

// DocumentTab オブジェクト である documentTab の getBody メソッドで、本文をあらわす Body オブジェクトを
// 取得し、変数 body に代入
const body = documentTab.getBody();

// 本文である Body オブジェクト body の clear メソッドで、本文をすべて消去
body.clear();

Google スプレッドシートから全部のデータを取得し二次元配列に格納

次は、スプレッドシートからすべての情報を取り出し二次元配列に格納しますが、そのためにはすでに作ってある関数 getAllData を使って、

const all_data = getAllData();

とし、変数 all_data に格納します。

取得した二次元配列の各行で各列の値をわかりやすい名前の変数に代入

i = 0, 1, 2,… に対して all_data[i] の情報は、上から i 番目の行に対応する通院情報を含んだ一次元配列となっています。

ここでは例として、i = 1 に対応する情報のことを考えてみることにし、all_data[1] の情報からドキュメントを作ることを想定してみましょう。

例えば、all_data[1][3] は 「付添者」の列に入っていたデータです。

ここでは、わかりやすくするために、

let companion = all_data[1][3];

のように、companion という名前の変数を用意し、all_data[1][3] に格納されている値を変数 conpanion に代入することにします。

この他の列に対しても次のように、わかりやすい名前の変数をそれぞれ用意して代入することにします。

// 通院日
let date = Utilities.formatDate(all_data[1][0], 'JST', 'yyyy年MM月dd日');

// 医療機関
let med_inst_name = all_data[1][1];

// 診察内容
let detail = all_data[1][2];

// 付添者
let companion = all_data[1][3];

// 備考
let note;
if(!all_data[1][4]){
  note = 'なし';
}else{
  note = all_data[1][4];
}

// 次回予定日
let scheduled_date;
if(! all_data[1][5]){
  scheduled_date = '未定';
}else{
  scheduled_date = Utilities.formatDate(all_data[i][5], 'JST', 'yyyy年MM月dd日');
}

// 次回付添予定者
let scheduled_companion = all_data[1][6];

上記のように改めて変数を用意するという作業は、all_data のインデックスでそれが何を表しているのかすぐわかる人にとっては無駄な作業ですが、ここではわかりやすさを優先して変数を用意して代入しています。

フォームでは備考欄は入力必須とはなっていません。ですからなにも入力されず送信されることがあります。そこで、上のコードでは、備考欄が空白の場合には変数 scheduled_date には ‘未定’ という文字列が代入されるように、if 文を使って条件分岐させています。

Utilities というオブジェクトが上記のコードでは使われています。これは、日付を扱うために Google App Script で用意されているオブジェクトで、formatDate というメソッドを持っています。

Utilities.formatDate(日付型の値, 'JST', 'yyyy年MM月dd日');

とすることによって、〇〇〇〇年〇〇月〇〇日 という形であらわした日付を文字列として取得できます。

タイトルをドキュメントに書き込む

ドキュメントファイルのファイル名を取得し、ファイル名を文書のタイトルとして文書の一行目に挿入するコードを作ります。

// Google ドキュメントファイルのファイル名を取得し変数 title に代入
const title = doc.getName();

// Body オブジェクト body に変数 title に格納されている文字列を段落として段落番号 0 の位置に挿入させ、挿入した段落をあらわすオブジェクトを変数 paragrah に代入
let paragrah = body.insertParagraph(0, title);

// Paragraph オブジェクト paragrah に段落レベルを「タイトル」とするよう設定させる
paragrah.setHeading(DocumentApp.ParagraphHeading.TITLE);

ファイル名を「通院記録」としてあるので、このコード実行すると文書の一行目に 通院記録 と記入されます。また、DocumentApp.ParagraphHeading.TITLE という値を使って、見出しとしてのレベルを「タイトル」に設定しています。

送信されてきた報告1つをドキュメントに書き込む

ここではとりあえず、例として、スプレッドシートに記録されている報告で上から2つ目の行にあるものを文書に追加することを想定してみましょう。

このデータは all_data[1] に格納されています。先に説明したようにして、次のように、わかりやすい名前の変数に代入します。

// 通院日
let date = Utilities.formatDate(all_data[1][0], 'JST', 'yyyy年MM月dd日');

// 医療機関
let med_inst_name = all_data[1][1];

// 診察内容
let detail = all_data[1][2];

// 付添者
let companion = all_data[1][3];

// 備考
let note;
if(!all_data[1][4]){
  note = 'なし';
}else{
  note = all_data[1][4];
}

// 次回予定日
let scheduled_date;
if(! all_data[1][5]){
  scheduled_date = '未定';
}else{
  scheduled_date = Utilities.formatDate(all_data[1][5], 'JST', 'yyyy年MM月dd日');
}

// 次回付添予定者
let scheduled_companion = all_data[1][6];

上記のようにしてわかりやすい名前の変数に代入されたそれぞれの値を使い、段落を追加することにします。

ではまず、変数 date に代入された値を使って「通院日」の情報を文書に追加することにしましょう。本文に対応するBody オブジェクトとして取得した body の appendparagraph メソッドを使って、まずはじめに ‘–通院日–‘ という文字列と改行、さらに 変数 date に入っている文字列と改行を挿入します。

// Body オブジェクト body に「--通院日--」という文字列の段落を追加させ変数 paragrah に代入
let paragrah = body.appendParagraph('--通院日--\n');
let text = paragrah.editAsText();
text.setFontSize('14');

// Body オブジェクト body に変数 date に格納されている文字列を段落として追加させる
body.appendParagraph(date + '\n');

また、フォントサイズを 14 ポイントに設定しています。

改行を文字列の中で扱うときは、\n というあらわし方をします。

これで、変数 date に格納されている値、つまり all_data[1][0] の値を使って、ドキュメントに次のように書き込んだことになります。

all_data[0][1]から作られるドキュメントの段落

「通院日」以外の情報も同じようにして書き込むことができます。

次に書き込むのは「医療機関」の情報ですから、変数 med_inst_name に格納されている値 、つまり all_data[1][1] を使って「診察日」のときと同じようにしてコードを書けばよいわけです。すると次のようになります。

// Body オブジェクト body に「--医療機関--」という文字列の段落を追加させ変数 paragrah に代入
let paragrah = body.appendParagraph('--医療機関--\n');
let text = paragrah.editAsText();
text.setFontSize('14');

// Body オブジェクト body に変数 med_inst_name に格納されている文字列を段落として追加させる
body.appendParagraph(med_inst_name + '\n');

さらに同様にして、「診察内容」、「付添者」、「備考」、「次回予定日」、「次回付き添い予定者」についても書き込むことができます。

同じような処理を繰り返すことになるので、先のことを見込んで例えば次のような関数をつくっておくと便利です。

function appendNormalTextBlock(body, contents, fontsize){
  const paragraph = body.appendParagraph(contents);
  paragraph.setLineSpacing('1.7');
  const text = paragraph.editAsText();
  text.setFontSize(fontsize);
}

この関数 appendNormalTextBlock は、3つの引数 body、contents と fontsize があります。

この関数を呼ぶとき、引数 body には本文をあらわす Body オブジェクト、contents には本文に段落として付け加えるテキスト(文字列)を渡し、引数 fontsize にはフォントサイズをポイント単位であらわした数を渡します。そのようにしてこの関数を呼ぶと、すでに書き込まれている本文の最後に引数 contents を内容とし、引数 fontsize の値をフォントサイズとした段落が新しく付け加えられます。(この関数では、setLineSpacing メソッドを使って行間も指定しています。)

例えば、すでに Body オブジェクト body が取得されているときに、

appendNormalTextBlock(body, '--診察内容--\n', 14);

とすると、本文の最後に「–診察内容–」という段落が最後に改行を伴って、14 ポイントのフォントサイズで付け加えられます。

さて改めて、この関数を使って「通院日」、「医療機関」、「診察内容」、「付添者」、「備考」、「次回予定日」、「次回付き添い予定者」の情報を見出しともに本文に付け加えていくコードを書いてみると次のようになります。

// 通院日の情報を段落として追加
appendNormalTextBlock(body, '--通院日--', 14 );
appendNormalTextBlock(body, date + '\n', 11);

// 医療機関の情報を段落として追加
appendNormalTextBlock(body, '--医療機関--', 14 );
appendNormalTextBlock(body, med_inst_name + '\n', 11);
  
// 診察内容の情報を段落として追加
appendNormalTextBlock(body, '--診察内容--', 14 );
appendNormalTextBlock(body, detail + '\n', 11);
   
// 付添者の情報を段落として追加
appendNormalTextBlock(body, '--付き添い者--', 14 );
appendNormalTextBlock(body, companion + '\n', 11);
  
// 備考の情報を段落として追加
appendNormalTextBlock(body, '--備考--', 14 );
appendNormalTextBlock(body, note + '\n', 11);
    
// 次回予定日の情報を段落として追加
appendNormalTextBlock(body, '--次回予定日--', 14 );
appendNormalTextBlock(body, scheduled_date + '\n', 11);

// 次回付添予定者の情報を段落として追加
appendNormalTextBlock(body, '--次回付き添い予定者--', 14 );
appendNormalTextBlock(body, scheduled_companion + '\n', 11);
  
// 改ページを追加
body.appendPageBreak();

フォームから送信されプレッドシートに記録された1行分の情報が、上記のコードによりドキュメントへ書き込まれることになります。そのため、最後に改ページを追加しています。

送信されてきた報告すべてをドキュメントに書き込む

前節の最後のコードは、スプレッドシートに記録された1行分の情報をドキュメントに書き込むものですから、スプレッドシートに記録されているすべての情報を書き込むには繰り返し処理を行います。そのためにここでは for 文を使うことにします。これまでを踏まえて、次のようなコードを書けば良いことになります。

// i=0, 1, 2, ..., all_data.length-1 に対して 
// for文で all_data[i] に対する繰り返し処理を行う

for (let i=0; i<all_data.length; i++){
  // ---- わかりやすい名前の変数を用意して all_data の各値を代入 ----

  // 通院日
  let date = Utilities.formatDate(all_data[i][0], 'JST', 'yyyy年MM月dd日');
  
  // 医療機関
  let med_inst_name = all_data[i][1];

  // 診察内容
  let detail = all_data[i][2];

  // 付添者
  let companion = all_data[i][3];
  
  // 備考
  let note;
  if(!all_data[i][4]){
    note = 'なし';
  }else{
    note = all_data[i][4];
  }

  // 次回予定日
  let scheduled_date;
  if(! all_data[i][5]){
    scheduled_date = '未定';
  }else{
    scheduled_date = Utilities.formatDate(all_data[i][5], 'JST', 'yyyy年MM月dd日');
  }

  // 次回付添予定者
  let scheduled_companion = all_data[i][6];
  
  // ----ドキュメントに段落として追加 ----

  // 通院日の情報を段落として追加
  appendNormalTextBlock(body, '--通院日--', 14 );
  appendNormalTextBlock(body, date + '\n', 11);

  // 医療機関の情報を段落として追加
  appendNormalTextBlock(body, '--医療機関--', 14 );
  appendNormalTextBlock(body, med_inst_name + '\n', 11);
  
  // 診察内容の情報を段落として追加
  appendNormalTextBlock(body, '--診察内容--', 14 );
  appendNormalTextBlock(body, detail + '\n', 11);
   
  // 付添者の情報を段落として追加
  appendNormalTextBlock(body, '--付き添い者--', 14 );
  appendNormalTextBlock(body, companion + '\n', 11);
  
  // 備考の情報を段落として追加
  appendNormalTextBlock(body, '--備考--', 14 );
  appendNormalTextBlock(body, note + '\n', 11);
    
  // 次回予定日の情報を段落として追加
  appendNormalTextBlock(body, '--次回予定日--', 14 );
  appendNormalTextBlock(body, scheduled_date + '\n', 11);

  // 次回付添予定者の情報を段落として追加
  appendNormalTextBlock(body, '--次回付き添い予定者--', 14 );
  appendNormalTextBlock(body, scheduled_companion + '\n', 11);
  
  // 改ページを追加
  body.appendPageBreak();
}

日付に関して降順で報告をドキュメントに書き込む

さて、フォームから送信されてくる報告ですが、スプレッドシートでは新しく送信されてくるものが一番下に付け加えられるようになっています。

ですから、

all_data = getAllData()

として得られる二次元配列 all_data でも、all_data[0], all_data[1], all_data[2],…の順で、後ろの方ほど(つまり二次元配列の1番目のインデックスの値が大きいほど)日付の新しいデータが格納されていることになります。

そして、前節の for 文を使ったコードでも、i=0, i=1, i=2,… の順でドキュメントに書き込んでいましたから、日付の新しい報告ほどドキュメントの後ろの方に書き込まれることになります。

これでも構わないのですが、でも、新しい報告ほどドキュメントの最初の方にあったほうが良いということもありますね。(恐らく、そのほうが良いと思う人のほうが多い気がします。)

そこで、Google Apps Script でスプレッドシートを操作するコードを作り、スプレッドシートの通院日の列に関して降順(この場合は日付が古いほど下になる順)に並べ替えることをしたいと思います。

そのためには Google Apps Script で用意されている sort メソッドを使います。

sort メソッドはスプレッドシートの Range オブジェクトが持つメソッドです。スプレッドシートのシートから必要な範囲を Range オブジェクトとして取得して sort メソッドを使います。

次のコードを例として使い方を説明してみます。(これは Google Apps Script の公式リファレンス Class Range からの引用です。)

// スクリプトのコンテナとなっているスプレッドシートを取得し変数 ss に代入
const ss = SpreadsheetApp.getActiveSpreadsheet();

// スプレッドシート ss の最初のシートを取得し変数 sheet に代入
const sheet = ss.getSheets()[0];

// シート ss で左上がセルA1、 右下がセルc7となる矩形領域を取得し変数 range に代入
const range = sheet.getRange('A1:C7');

// 矩形領域 range に含まれるデータを第1列(つまり A 列)が昇順になるように並べ替え
range.sort(1);

// 矩形領域 range に含まれるデータを第2列(つまり B 列)が昇順になるように並べ替え
range.sort(2);

// 矩形領域 range に含まれるデータを第2列(つまり B 列)が降順になるように並べ替え
range.sort({column: 2, ascending: false});

sort メソッドの引数の与え方にはいくつかの流儀があるのですが、ここでは当面必要になる引数の与え方について説明します。

まず何列目を基準に並べ替えるのかということをあらわす数が必要です。

スプレッドシートでは、A列、B列、C列、…のように列の名前がつけられていますが、sort メソッドの引数では左から順に1列目、2列目、3列目、…のように数で指定します。

また、昇順で並べ替えるのか降順で並べ替えるのかを指定するものも必要です。sort メソッドは、昇順または降順の指定をしないと自動的に昇順で並べ変えてしまいますが、明示的に指定するためには、昇順で並べ変えたいときには true、降順で並べ替えたいときには false を指定します。

これらの2つを指定するためには、次のように、例えば、{ column: 2, ascending: false } のような連想配列を渡します。

range.sort({column: 2, ascending: false});

このコードでは、並べ替えの基準に使う列(column)は 左から2列目(つまり B 列)、また昇順(ascending)は偽(false)としているので、B列に関して降順で並べ替えが行われます。

さて、話を本題に戻しましょう。

フォームから送信されてきた報告を格納するためのスプレッドシート「通院記録(回答)」で回答の記録に使われるシート「フォームの回答 1」で並べ替えを行いたいのでしたね。そこで、このシートに記録されたすべての情報を含むセル範囲を range オブジェクトとして取得し、診察日の列(つまりB列)を基準に降順に並べ替える関数を sort メソッドを使って作ってみたいと思います。ここではスプレッドシート「通院記録(回答)」の ID を1aDeGes********rSue5 としています。

function sortTheSheetByDate(){
  // SpreadsheetApp オブジェクトの openById メソッドを使い
  // id が 1aDeGes********rSue5 の Spreadsheet オブジェクトを取得し、
  // 変数 ss に代入
  const ss = SpreadsheetApp.openById('1aDeGes********rSue5');
 
  // Spreadsheet オブジェクトの getSheetByName メソッドを使い
  // シート名 が 'フォームの回答 1'の Sheetオブジェクトを取得し、
  // 変数 sheet に代入
  const sheet = ss.getSheetByName('フォームの回答 1');
 
  // Sheetオブジェクトの getLastRow メソッドを使い
  // シートに存在するデータの最終行番号を取得し、
  // 変数 last_row に代入
  const last_row = sheet.getLastRow();
 
  // Sheetオブジェクトの getLastRow メソッドを使い
  // シートに存在するデータの最終列番号を取得し、
  // 変数 last_column に代入
  const last_column = sheet.getLastRow();

  // Sheetオブジェクトの getRange メソッドを使い
  // シートの 2行1列を左上のセルとし、
  // それを含めて行数が last_row-1、列数がlast_column の領域を
  // Rangeオブジェクトとして取得し、変数 range に代入 
  const range = sheet.getRange(2,1,last_row -1, last_column);
 
 // B列で降順に並べ替え
  range.sort({column: 2, ascending: false}: false});
}

ここでは 通院日に関して降順に並べ替える関数の名前を sortTheSheetByDate としました。

フォームと連携しているスプレッドシートで sort メソッドを使うときは、フォームと連携しているセル範囲をすべて含むように Range オブジェクトを取得する必要があります。

以上の準備のもとに二次元配列の情報をドキュメントに書き込む関数を作る

さて、以上で二次元配列に格納されているすべての情報を使って、これまでに送信されてきた通院情報をすべてドキュメントに書き込むために必要なコードが出揃いました。

ここでは、そのことを実行する関数の名前を writeToDoc とすることにします。そして次のようなコードを書けば良いということになります。

function writeToDoc(){
  //スプレッドシートを通院日に関して降順に並べ替え
  sortTheSheetByDate();

  // スプレッドシートから全部のデータを取得し二次元配列 all_data に格納
  const all_data = getAllData();

  // 操作対象の Google ドキュメントファイルの本文をあらわす Body オブジェクトを取得
  // さらに本文を一度すべて消去
  const doc_id = '1yNcSBYaP';
  const tab_id = 't.0';
  const doc = DocumentApp.openById(doc_id);
  const tab = doc.getTab(tab_id);
  const documentTab = tab.asDocumentTab();
  const body = documentTab.getBody();
  body.clear();

  // 本文をあらわす Body オブジェクトの最初段落番号(インデックスは 0 )の位置に
  // 操作対象の Google ドキュメントファイルの名前を段落として挿入
  // 挿入した段落のレベルを「タイトル」に設定
  const title = doc.getName();
  let para_title = body.insertParagraph(0, title);
  para_title.setHeading(DocumentApp.ParagraphHeading.TITLE);
  let text_title = para_title.editAsText();
  text_title.setForegroundColor("#007bff");  

  // スプレッドシートから取得した二次元配列 all_data に格納されている情報を
  // すべてドキュメントへ書き込む
  for (let i=0; i<all_data.length; i++){
    // ---- わかりやすい名前の変数を用意して all_data の各値を代入 ----

    // 通院日
    let date = Utilities.formatDate(all_data[i][0], 'JST', 'yyyy年MM月dd日');
  
    // 医療機関
    let med_inst_name = all_data[i][1];

    // 診察内容
    let detail = all_data[i][2];

    // 付添者
    let companion = all_data[i][3];
  
    // 備考
    let note;
    if(!all_data[i][4]){
      note = 'なし';
    }else{
      note = all_data[i][4];
    }

    // 次回予定日
    let scheduled_date;
    if(! all_data[i][5]){
      scheduled_date = '未定';
    }else{
      scheduled_date = Utilities.formatDate(all_data[0][5], 'JST', 'yyyy年MM月dd日');
    }

    // 次回付添予定者
    let scheduled_companion = all_data[i][6];
  
    // ----ドキュメントに段落として追加 ----

    // 通院日の情報を段落として追加
    appendNormalTextBlock(body, '--通院日--', 14 );
    appendNormalTextBlock(body, date + '\n', 11);

    // 医療機関の情報を段落として追加
    appendNormalTextBlock(body, '--医療機関--', 14 );
    appendNormalTextBlock(body, med_inst_name + '\n', 11);
  
    // 診察内容の情報を段落として追加
    appendNormalTextBlock(body, '--診察内容--', 14 );
    appendNormalTextBlock(body, detail + '\n', 11);
   
    // 付添者の情報を段落として追加
    appendNormalTextBlock(body, '--付き添い者--', 14 );
    appendNormalTextBlock(body, companion + '\n', 11);
  
    // 備考の情報を段落として追加
    appendNormalTextBlock(body, '--備考--', 14 );
    appendNormalTextBlock(body, note + '\n', 11);
    
    // 次回予定日の情報を段落として追加
    appendNormalTextBlock(body, '--次回予定日--', 14 );
    appendNormalTextBlock(body, scheduled_date + '\n', 11);

    // 次回付添予定者の情報を段落として追加
    appendNormalTextBlock(body, '--次回付き添い予定者--', 14 );
    appendNormalTextBlock(body, scheduled_companion + '\n', 11);
  
    // 改ページを追加
    body.appendPageBreak();
  }
 }

さて、ここまでで、フォームから送られてきた情報を Google ドキュメントに書き込むためのいくつかの関数を作ることができました。

次回は、作成したドキュメントにアクセスするための URL を関係者に Gmail で送信するコードを考えたいと思います。

上部へスクロール