BETA

【GAS】社内文書を自動で作成するミッションが完了した

投稿日:2020-07-31
最終更新:2020-07-31

もうExcelなんか要らなくね?

薄々そんな予感はあったのだが、GASでExcelのワークシートは弄れないようだ。仕方がないので、気持ちを入れ替えてすべてスプレッドシートで行くことにする。

なのでドライブ上に準備するファイルは、若干変更になる。

  1. フォームの入力内容が記載されたスプレッドシート
  2. 報告書の元になるマクロが実装されたエクセルシートスプレッドシート

スプレッドシートに値を設定する

準備したスプレッドシートは、原本として残したまま使用するためにファイルIDを取得しておく。原本をコピーする先のフォルダも年度を通じて同じ場所になるので、これも頻度の関係からあらかじめフォルダIDを固定で持ってしまう。

報告書テンプレートに記載する内容だが、次の5パターンとした。

  1. 報告書No(数値、カンマ小数点なし)
  2. 日付(日付)
  3. 件名(書式なしテキスト)
  4. 電話番号(自動)
  5. 合計(通貨、端数気り捨て)

それぞれ、カッコ内の書式指定が行われているセルにコピーするイメージだ。

function myFunction() {  

    var reportNumber = '123456';  
    var reportDate = '2020/05/08';  
    var reportTitle = '0706';  
    var telephone = '09012345678';  
    var reportAmount = '15260';  


    const originalFileID = '*****';  
    const destinationFolderID = '#####';  

    var originalFile = DriveApp.getFileById(originalFileID);  
    var destinationFolder = DriveApp.getFolderById(destinationFolderID);  

    var destinationFile = originalFile.makeCopy('duplicate', destinationFolder);  
    console.log(destinationFile.getName());  

    var sheet = SpreadsheetApp.openById(destinationFile.getId()).getActiveSheet();  
    console.log(sheet.getName());  

    sheet.getRange(2, 2).setValue(reportNumber);  
    sheet.getRange(3, 2).setValue(reportDate);  
    sheet.getRange(4, 3).setValue(reportTitle);  
    sheet.getRange(7, 2).setValue(telephone);  
    sheet.getRange(17, 3).setValue(reportAmount);  
}  

エクセルのマクロをいじったことがある人であれば、うっすらと見覚えのある内容ではないかと思う。

タイトルの文字列は電話番号と比較してみたいがために、あえて0始まりの数値にしてみた。さて気になる実行結果がこれだ。

見事に電話番号の値が変質している。頭にゼロが付くデータを扱い際には注意しないといけない。

次はメール本文から文字列を抜き出す

調べた限りでは、「メールを受信したタイミングで実行」というトリガーはないようなので、このスクリプトは特定の時間経過で起動させることを考えている。

そして、起動されたタイミングでの処理対象となるべきメールは、その段階で未読のものとなる。幸いフォームから送られるメールは定型の複写メールなので、未読状態を既読に変更しても何ら問題はない。

なぜなら、このメール自体には読む価値はないからだ

予めこの定型メールは、Gmailの設定で特定のタグをつけてしまうなどして目につかないフォルダに入れてしまってもよい。(むしろ、再作成のことなどを考慮するとこのメールが何度もやってくる可能性があるわけで、それらは目に見えないところに集約しておくほうが都合がいい)

function myFunction() {  

    const tag = '【××××】実施報告';  

    var searchCondition = 'is:unread';  
    var threads = GmailApp.search(searchCondition, 0, 10);  

    for (var i = 0 ; i < threads.length; i++) {  
        var msgs = GmailApp.getMessagesForThread(threads[i]);  
        if (msgs[0].getSubject().toString().startsWith(tag)) {  
            Logger.log(msgs[0].getSubject());  
            var body = msgs[0].getPlainBody();  

            var name = body.match(/氏名: (.*)/);  
            Logger.log(name[1]);  

            msgs[0].markRead();  
        } else {  
            Logger.log('not match');  
        }  
    }  
}  

メールを検索する際には、未読メールであることを条件にしている。この実装例では10スレッド分検索するようにしているが、スクリプトの起動間隔を考慮したスレッド数を指定する。

取得した未読メールのうち、タイトルがtagで始まるメールのみを対象にする。定型メールゆえに固定で書けるが、業務などで人が付けるようなケースだと稀に間に半角スペースが混入したり、RE:だのFW:だのが付くことがしょっちゅうなので注意すること。

この実装では氏名のみ取得しているが、メール本文から正規表現で指定のワードで始まる値を取得している。取得した値を使用する際には要素数の指定を忘れないようにすること。

そして最後に、既読にすることを忘れない。

完了メールを送信する

複写メール本文から報告書の作成に必要な文字列を取得して、報告書ファイルを作成することは実現できた。次は報告書の作成が完了したことを知らせるメールを作成すればミッションは終了する。

  1. 申請者が入力フォームに入力した際に添付した画像ファイルを添付ファイルとすること
  2. 作成した報告書をテンプレートとすること

この完了メールには、上記の2点が満たされなくてはならない。複写メールを読まずに捨てるまで言い切った理由だ。

function MyFunction() {  
    var picture = DriveApp.getFileById('*****');  
    var report = DriveApp.getFileById('*****');  

    const recipient = '######';  
    const subject = '完了報告';  
    const option = {noReply: true, attachments: [picture, report]};  
    var body = '';  

    body = '報告書が作成されました。\n';  
    body += '内容を確認してください。';  

    GmailApp.sendEmail(recipient, subject, body, option);  
}  

オプションでnoReplyを指定すると、送信者のメールアドレスが自動で[email protected]~になる。
添付ファイルは、これまで同様に名前かIDで特定したオブジェクトを指定すればよい。が、問題はこのままではスプレッドシートがなぜかPDFに変換されてしまうということ。

スマホのGmailでメールを見ると、領域は小さいながらも添付ファイルはサムネ表示されている。サムネをタップすれば、全域を見ることも可能だ。

遂にミッションコンプリート

これまでのスクリプトを現実の業務に沿うように詳細化し、時間起動のトリガーを仕込めば晴れてミッションコンプリートだ。

これまで様々な現場でエクセルのスクリプトと格闘した人であれば、大抵のコードには既視感を覚えるだろう。意外と簡単にいろいろなことができそうなので、もう少しGASをいじってみてもいいかもしれない。

技術ブログをはじめよう Qrunch(クランチ)は、プログラマの技術アプトプットに特化したブログサービスです
駆け出しエンジニアからエキスパートまで全ての方々のアウトプットを歓迎しております!
or 外部アカウントで 登録 / ログイン する
クランチについてもっと詳しく

この記事が掲載されているブログ

そろそろ業界からオプトアウトされそうな枯れ老人の足掻きブログ

よく一緒に読まれる記事

0件のコメント

ブログ開設 or ログイン してコメントを送ってみよう