🙆

Google Apps Scriptで繰り返し作業を自動化した話1 -Google Docsのコピペ

5 min read

今回使うテンプレート

デフォルトで設定されているものを多少変更しています。
独自のものを作成する場合には多少の調整が必要です。

1 ドキュメント内の要素を取り出す

文書の体裁を維持したままコピーします。
Google Docsには以下のエレメントタイプが存在しています。
エレメントタイプ一覧

https://developers.google.com/apps-script/reference/document/element-type

それぞれコピーの仕方が違うのがちょっと厄介です…
早速エレメントタイプを調べてみましょう!!

1.1 ドキュメント内の行数を取得

ドキュメント内の行数を取得するためにはgetNumChildren()を使います。早速試してみましょう。

function myFunction() {
  var body = DocumentApp.getActiveDocument().getBody();
  var lastChildNum = body.getNumChildren();
  Logger.log(lastChildNum);
}

Execution logに21.0と出力されていれば成功です。

1.2 ElementTypeの取得

ドキュメントを一行一行見ていきましょう。ここではgetChild()を使っていきます。

function myFunction() {
  var body = DocumentApp.getActiveDocument().getBody();
  var lastChildNum = body.getNumChildren();
  for (i = 0; i < lastChildNum; i++) {
    var child = body.getChild(i);
    Logger.log(child.getType());
  }
}

出力結果をみてみるとPARAGRAPHLIST_ITEMしかないのがわかります。
簡単にコピペできそうです。

1.3 コピーしたい箇所を決める

今回は日付から最後までがコピーしたい範囲です。ただ2回目以降のコピペではpage breakを入れておく事とします。

function getStartIndex(body) {
  var lastChildNum = body.getNumChildren();
  for (i = lastChildNum - 1; 3 <= i; i--) {
    var child = body.getChild(i);
    if ( child.getType() == DocumentApp.ElementType.PAGE_BREAK) break;
  }
  return i + 1;
}

function getTemplate(body) {
  var lastChildNum = body.getNumChildren();
  var startIndex = getStartIndex(body);
  var template = [];
  for ( i = startIndex; i < lastChildNum; i++) {
    template.push(body.getChild(i))
  }
  return template;
}

1.4 コピペしていく

コピペしていく内容が決まったら一気にコピペしてしまいましょう!!

function myFunction() {
  var body = DocumentApp.getActiveDocument().getBody();
  var lastChildNum = body.getNumChildren();
  var startIndex = getStartIndex(body);

  var template = getTemplate(body);

  var startOffset = 3;
  for (i = 0; i < lastChildNum - startIndex; i++)
  {
    var el = template[i];
    if(el.getType() ==DocumentApp.ElementType.PARAGRAPH) {
      body.insertParagraph(i + startOffset, el.copy().asParagraph());
    } else if (el.getType() ==DocumentApp.ElementType.LIST_ITEM) {
      body.insertListItem(i + startOffset, el.copy().asListItem());
    }
  }
  body.insertPageBreak(i + startOffset);
}

2 日付の変更

日付の変更は非常に多い簡単に行うことができる。
まずは基準となる日付を設定する。
スクリプトを実行する日付を取得する場合はnew Date()だけで良い。

2.1 会議の日付に変更

例えば明後日の会議とする場合、2日進める必要がある。その際はgetDate(), setDate()を使って日付の変更を行う。

function getDate() {
  var date = new Date();
  date.setDate(date.getDate() + 2);
  Logger.log(date);
}

2.1 議事録の日付部分を置き換える

まずは、置き換える日付の文字列を作成する。今回は日付で英語が使用されているため、英語表記に対応できるようvar month = date.toLocaleString('default', {month: 'long'});を追加した。日本語での日付の場合はこのような操作は必要ない。また、09月のような表記をしたい場合には('0' + (date.getMonth() + 1)).slice(-2)としてあげると簡単に取得することができる。getMonth()は実際の月よりかひとつ小さい数となっているので注意が必要である。

function getDate() {
  var date = new Date();
  date.setDate(date.getDate() + 2);
  Logger.log(date);

  var month = date.toLocaleString('default', {month: 'long'});
  var dateString = date.getDay() + " " + month + " " + date.getFullYear() + " ";
  return dateString;
}

ここまで来たら置き換えることが可能となる。

	var tempDateString = newParagraph.getText().split('/')[0];
        newParagraph.replaceText(tempDateString, getDate())

これで置き換えが完了する。

3 まとめ

今回作成した議事録のコピーは50行程度のコードで実現できてしまうので、比較的簡単に取り組めるのではと思っている。

function myFunction() {
  var body = DocumentApp.getActiveDocument().getBody();
  var lastChildNum = body.getNumChildren();
  var startIndex = getStartIndex(body);

  var template = getTemplate(body);

  var startOffset = 3;
  for (i = 0; i < lastChildNum - startIndex; i++)
  {
    var el = template[i];
    if(el.getType() ==DocumentApp.ElementType.PARAGRAPH) {
      var newParagraph =  body.insertParagraph(i + startOffset, el.copy().asParagraph());
      if (i == 0) {
        var tempDateString = newParagraph.getText().split('/')[0];
        newParagraph.replaceText(tempDateString, getDate())
      }
    } else if (el.getType() ==DocumentApp.ElementType.LIST_ITEM) {
      body.insertListItem(i + startOffset, el.copy().asListItem());
    }
  }
  body.insertPageBreak(i + startOffset);
}

function getStartIndex(body) {
  var lastChildNum = body.getNumChildren();
  for (i = lastChildNum - 1; 3 <= i; i--) {
    var child = body.getChild(i);
    if ( child.getType() == DocumentApp.ElementType.PAGE_BREAK) break;
  }
  return i + 1;
}

function getTemplate(body) {
  var lastChildNum = body.getNumChildren();
  var startIndex = getStartIndex(body);
  var template = [];
  for ( i = startIndex; i < lastChildNum; i++) {
    template.push(body.getChild(i))
  }
  return template;
}

function getDate() {
  var date = new Date();
  date.setDate(date.getDate() + 2);
  var month = date.toLocaleString('default', {month: 'long'});
  var dateString = date.getDay() + " " + month + " " + date.getFullYear() + " ";
  return dateString;
}

Discussion

ログインするとコメントできます