GASで仕組みづくりを始めたばかりから ちょっとわかるようになった人🫣
こんにちは。@lattest です。
この記事は airCloset Advent Calendar 2022 の 09 日目です。
昨年、GASど素人だった人間がGAS素人になって帰ってまいりました🧎🧎♂️🧎
GAS(google Apps Script)と他媒体をつなぐ機能について、少し理解が広がってきたので
今回はスプレッドシート、GASとSlackを使った通知機能について...
と言っても、この3つに関してはAPIなどを駆使して色々な機能実装に関する記事を見かけるので,なにを書くか考えたのですが、素人が最近知って便利だなぁと思った機能について書くことにします。
スプレッドシートって並び順ソートかけたうえにPDF化してSlackに通知送れるんだよー!!!
という実装を書きます。
なぜ、この実装を作ったか?
各個人のptなど、日次での進捗具合をわかりやすく共有することができるためです。
前提条件として
通知用のボットの作成と権限の設定等は事前に行ってあるものとします。
例えば、スプレッドシートがこんな感じだったのを...
こんな風に自動で並び替えて
PDF化してSlackへ送信
それぞれどんなことをしているの?
- スプレッドシートから範囲選択をする
- ソートがかかってたらリセットする
- ソートをかける
- PDFに加工する
- Slackへ飛ばす
以上です!
ソートに関しては、手動でソートをかけるのと基本同じ手順を自動化しています。
1から順に見ていきます
- スプレッドシートから範囲選択をする
サクッと、シートの取得
//スプレッドシートのファイル自体をとる(パターン①)
const ss = SpreadsheetApp.getActiveSpreadsheet();
//スプレッドシートのファイル自体をとる(パターン②)
const ss = SpreadsheetApp.openById(sheetId)//sheetIdの例('DH3SuHCjXM0kTs-aaa_S8899')のようなスプレッドシートのURLに組み込まれた羅列;
//シート指定
const sheet = ss.getSheetByName('シート1名を入れる');
ここでRange
で範囲指定します。
引数に(始まりの行, 始まりの列, 行数, 列数)
let data = sheet.getRange(2, 1, 5, 5);
次に2を見ていきます
- ソートがかかってたらリセットする
※何度も自動ソートをかける際、正しくソートをかけるためにフィルターが存在する(ソートがかかってる)場合はフィルターを削除してまっさらな状態にしています。
-
リセットするにはフィルターを取得します
.getFilter()
を使う -
そして、そのフィルターを削除する
.remove()
これで削除する
実際の使い方
- スプレッドシートの範囲内のフィルターを取得→
data.getFilter()
- 範囲取得されたフィルターに削除をくっつける→
data.getFilter().remove()
//フィルターがnull以外(存在する)なら削除するロジック
if(sheet.getFilter() != null) {
sheet.getFilter().remove();
}
続いて、3を見ていきます
- ソートをかける
- ソートをかけるにはフィルターを作成し、ソートをかける必要があります
フィルターをかけるには→.createFilter()
ソートをかけるには→.sort(列の位置, Booleanで決まる昇降順)
//範囲内の列6番目(列は1から始まります)
//true→昇順
//false→降順
data.createFilter().sort(6, true);
ちゃんとソートされています
加工の最後、4を見ていきます
- PDFに加工する
PDF化する共通関数を作ってそこに投げてらく効率化します
//特定のスプレッドシートの指定範囲のPDFファイルを作成して、そのファイルインスタンスを返却する関数
//返却されたインスタンスを用いてSlackへの投稿ができる
function createPDFByRange(ss(スプレッドシート), sheetName(シートの名前), rangeStr(PDFしたい範囲)) {
const ssid = ss.getId(); //スプレッドシートのIDを取得
const sheet = ss.getSheetByName(sheetName);
const sheetid = sheet.getSheetId(); //シートIDを取得
const pdfRange = rangeStr; //PDF化範囲
//PDFをエクスポートするURL
const url = "https://docs.google.com/spreadsheets/d/SSID/export?".replace('SSID', ssid);
//PDF化オプションを設定
const opts = {
exportFormat: 'pdf',
format: 'pdf',
size: 'A4', //出力するサイズ
portrait: 'true', //PDFファイルの向き。true:縦向き、false:横向き
fitw: 'true', //ページのフィット。true:フィット、false:原寸大
sheetnames: 'false', //シート名。true:有り、false:無し
printtitle: 'true', //ドキュメントのタイトル。true:有り、false:無し
pagenumbers: 'false', //ページ番号。true:有り、false:無し
gridlines: 'false', //グリッドライン。true:有り、false:無し
fzr: 'false', //各ページの行見出し。true:含める、false:含めない
range: pdfRange,
gid: sheetid
};
//オプションを「&」で繋げる
let url_ext = [];
for (optName in opts) {
url_ext.push(optName + '=' + opts[optName]);
}
const options = url_ext.join('&');
//API使用のOAuth認証
const token = ScriptApp.getOAuthToken();
const fileName = dayjs.dayjs().format("YYYYMMDD_outputFile") + '.pdf';
//PDF作成
return pdf = UrlFetchApp.fetch(url + options, { headers: { 'Authorization': 'Bearer ' + token }, muteHttpExceptions: true }).getBlob().setName(fileName);
}
このfunctioncreatePDFByRange
に引数を渡すとPDFが作成されます
1~3で作ったデータを使ってPDF化してみます
const range = 'A1:F7';//PDF化したい範囲
const pdf = createPDFByRange(ss, 'シートの名前', range);
最後に投稿、5を見ていきます
- Slackへ飛ばす
これも、Slackへとばす共通関数を作ってそこに投げてらく効率化します
/**
* SlackにPDFファイルを投稿する
* @param {obj} パラメータobj
* @param {string} channelId:チャンネルID(例:'C0008J000MD')
* @param {obj} file:投稿する実ファイル
* @param {string} comment:投稿時のコメント
*/
function postFile({
channelId,
file,
comment
}) {
const payload = {
token: 'xox.......',//tokenはそれぞれSlackで設定したものを使ってください
channels: channelId,
file,
comment
};
const param = {
method: 'POST',
payload
};
if (typeof(file) === "Array") {
param.contentType = 'multipart/form-data';
}
// channelにピン留めする
const url = "https://slack.com/api/files.upload";
return UrlFetchApp.fetch(url, param);
}
いよいよ完了、Slackへ飛ばしてみる
postFile({
channelId: "C0000J0J00Z",//チャンネル右クリック→コピー→コピーリンクで出てきます
file: pdf,
comment: "学年末試験の総合得点をお知らせします"
});
振り返ってみて
一つ一つのロジックは徐々に実装を追加していたので気づかなかったのですが
一つにまとめるとたくさんの工程を経て今の形になっているのを感じました。
グループとして最高のUXを目指して、これからもコツコツと改善に努めていきたいと思います。
参照サイト
-
sort
AutoWorker〜Google Apps Script(GAS)とSikuliで始める業務改善入門
快 ブログ -
PDF
blob型について
レッツ効率の良い人生 -
SlackへPOST
contentType
YoheiM.NET
token
slack help center
Men of Letters(メン・オブ・レターズ) - 論理的思考/業務改善/プログラミング
Discussion