現役情シスが送る実践的Tips集

ラベル Google Apps Script の投稿を表示しています。 すべての投稿を表示
ラベル Google Apps Script の投稿を表示しています。 すべての投稿を表示

2021/09/07

【GoogleWorkspace】.newのショートカットURLで新規作成あれこれ



久々にGoogleのTipsを少々。

概要

突然ですが、考え事をしていてとりあえずExcelっぽいものに文字を打ち込みたくなりませんか?
あるいは、最速でMeetを立ち上げて会議をしたくなりませんか?

そんな要望を叶えてくれる素敵な仕組みを、Googleさんは用意してくれています。
その名も「.new ショートカット」
いわゆる.newドメインを使った
URLに対応する「アプリ名.new」と打ち込むことでそのアプリの新規作成画面を開いてくれるんです。

今回はせっかくなので色んな.newを試してみました。

色んな.new


sheet.new

新規スプレッドシートを起動してくれます

doc.new

新規ドキュメントを起動してくれます

slide.new

新規スライドを起動してくれます(オススメ)

form.new

新規フォームを起動してくれます

site.new

新規サイトを起動してくれます

script.new

新規スクリプトエディタを起動してくれます(オススメ)

keep.new

新規Keepメモを起動してくれます(オススメ)

cal.new

新規予定を起動してくれます

meet.new

新規Meetを起動してくれます(オススメ)

jam.new

新規Jamboardを起動してくれます


補足

アプリ名の表現は実はひとつではなく例えばスプレッドシートなら「sheet.new」の他に
「sheets.new」「spreadsheet.new」なんかもOKです。
が、複数覚えても意味ないので今回書いた一番短いので良いと思います。

ちなみに.newドメインはGoogle以外も対応しています。
excel.newならMicrosoft365の新規Excelが開いたりって感じです。
クリエイティブ系のSaaSを使ってる人は試しに.newを打ち込んでみると素敵なことが起きるかも。


なお、Google公式は以下を参照ください。

2020/09/23

【GAS】QRコードで簡単登録できる座席表を作ってみた

こんにちは。

今日はGASとQRコードを組み合わせてフリーアドレスな職場で使えそうな座席登録システムを作ってみました。


概要

最初に考えたのはどんなタイプの社員でも簡単に利用できるシステムであること。

在宅勤務によって社員が新たに入手したものと言えば、

在宅勤務に向いたPC・Web会議を実現する機器、そしてスマートフォンが挙げられます。

次に考えたのが開発が簡単であること。

このブログで「開発が簡単」というとそれはもうGoogleアカウントがあって「コピペ」でできることに尽きます。

GoogleAppsScriptとスプレッドシートの組み合わせが最もハードルが低い、というか最も向いていると考えました。


スマートフォンをキーとして、GASで開発できる仕組みと言えばQRコードの出番でしょう!

着席時に各座席のQRコードをスマホでピッとスキャンするだけで座席表に自分の名前が入っちゃう。

今回はそんなシステムを作ります。


作り方

スプレッドシートの準備

まずは座席表となるスプシを作ります。
下図のように「QR」「座席表」「LOG」シートを作ってください。


シートの準備ができたらスクリプトエディタを呼び出しましょう。

プログラミング

スクリプトエディタを起動したら適当に名前を付けて「コード.gs」に以下をコピペしてください。
  function doGet(e)
    var no = e.parameter.no;
    var datetime = new Date();
    var UserInfo = Session.getActiveUser().getEmail();
    var ss = SpreadsheetApp.getActive().getSheetByName('QR');
    var LogSheet = SpreadsheetApp.getActive().getSheetByName('LOG');
    var lastRow = ss.getLastRow();
    // 読み取ったQRコードから対応する座席に自分の名前を登録する
    for (var i=2; i<=lastRow; i++) {
       if (ss.getRange(i, 1).getValue() == no) {
         ss.getRange(i, 4).setValue(UserInfo);
         break;
       }
    }
    // 実行日時&メールアドレスセット
    LogSheet.appendRow(['登録完了', datetime, no, UserInfo]);
    return ContentService.createTextOutput("メールアドレス:"+UserInfo+"");
  }
こんな感じですね。

アプリを社内限定で公開

作ったプログラムをQRコードを通して実行できるように社内限定で公開します。
公開 > アプリケーションとして導入を実行してください。


下図のように選択して公開してください。
「自分のドメインなら誰でも自分のアカウントとして実行できる」みたいな意味合いです。(雑)

操作が成功したら公開URLが表示されるためコピーしてください。これを使ってQRコードを作ります。

QRコード生成

スプレッドシートに戻り「QR」シートにて1列目にヘッダを作成します。
下図はサンプルです。プログラムのコードに対応しているため各ヘッダの名前を変えるのは問題ありませんが、
座席NoをAではなくB列に変更するなんてことはやめてください。

続いてサンプルとして1つだけ座席用QRコードを生成してみます。
B2とC2にはそれぞれ以下の関数を入力してください。
  • B2:="公開URL/exec?no=" & A2
  • C2:=image("https://chart.apis.google.com/chart?chs=200x200&cht=qr&chl=" &B2)
そしてA2に適当に座席Noを割り当ててください。
下図は座席No「1001」としたサンプルです。
C2にQRコードができましたね!
Aに座席No、Bに座席Noに応じたURL、CにURLから生成したQRコードといった並びです。

ちなみにQRコードの生成はGoogle Chart APIを利用しています。
QRコードの生成は非推奨となっていますがまだまだ現役です。

スマホでスキャン

さっそく生成したQRコードをスマホでスキャンしてみましょう。
上部に出てきたリンクをタップすると・・・
実行許可確認の画面が出てきます、このあともアプリの確認が数回行われすべて許可で進むと・・・
超簡素&マスクしてるのでわかりにくいですが自分のメールアドレスが返ってきます。
そしてスプシを見てみると・・・
座席No「1001」の「座った人」にメールアドレスが入りました!

更に「LOG」シートにはしっかりと登録ログが残されています。

さてここまで来たらもうおわかりですよね?
残る「座席表」シートにフロアマップを書き込んで座席Noに対応するセルに
「QR」シートの「座った人」を表示させるようにしたら・・・
このとおりQRコードで登録できる座席表の完成です!

なお、他の人に使ってもらう場合はこのスプシの「編集権限」を与えて共有してください。
GAS経由で本人がスプシに直接書き込むことになるため編集権限が必要になります。
勝手に編集されて困るようなところは保護をかけましょう。(保護が強すぎると登録できないので注意)

補足

GAS部分をもう少し作りこめば、登録解除や座席変更、夜間に全リセットなんかも可能です。
ただし表示名をメールアドレス以外のものに変えたい場合、
現時点でGASが対応してないため別途手動でマスターデータを持つしかありません。
これは入社や異動時にメンテ工数が発生するのであまりおススメしません。。

できればもう少し権限周りを細かく制御したかったのですが、
まずは短期間で動くものを作ることを目標に取り掛かったので突っ込みはご容赦願いたい。


2020/08/31

【Gmail】共有テンプレートでメール業務はもっと楽になる

こんにちは。

今回は以前投稿したテンプレートアドオンのおまけで、テンプレートを共有化してみました。

元の記事はこちら。

【Gmail】テンプレートアドオンをインストールしよう

 

概要

以下のような観点からGmailのテンプレートを共有したいと考えたことはないでしょうか。

・カスタマーサポートをチームで行っているが担当者によって文言が微妙に違う
・新人や中途社員でもすぐメール業務を開始できるようにしたい
・メールテンプレートの更新を一括で行いたい

 アドオンのカスタマイズで共有化が実現できたのでご紹介します。

  

前提条件

・Gmailを利用している
・共有テンプレートの管理者を決めておく (テンプレートの更新は管理者のみとしておくことを推奨する)

 

導入手順

1. 共有テンプレート用スプレッドシートを準備する  (全文解説)
2. プログラミングする (差分解説)
3. Gmailに組み込む (省略)
4. 試してみる (差分解説)

流れは元のアドオンとほぼ同じため差分だけの解説とさせていただきます。

  

共有テンプレート用スプレッドシートを準備する (全文解説)

①テンプレート管理者は任意の場所に以下のスプレッドシートを作成する

※ 元のアドオンを実装済みの方は「gmail_template_list」を複製するだけで良い

・ファイル名:任意
・保存場所:任意
・シート名:list
・内容:
・A1:No
・B1:Title
・C1:Message

以下はスプレッドシートのサンプルです。

spleadsheet1

 

 

②作成したスプレッドシートを共有設定する

ユーザーの権限設定は以下が望ましい

・スプレッドシートを更新する人:「編集者」
・それ以外のテンプレート利用者:「閲覧者」

 

③スプレッドシートのURLから以下赤字部分を控える

例. https://docs.google.com/spreadsheets/d/13D_mdsvjyVd5Qxg_JS4CKb544dVdZrNyZCzY-IL7Po/

 

プログラミングする (差分解説)

~中略~

③以下のプログラムコードをコピーして…

// main
function buildTemplateComposeCard() {
  // settings template SpleadSheetID and SheetName (SpleadSheet must be shared)
  var ssID  = "スプレッドシートのID";
  var ssSName = "list";
  var ssUrl = DriveApp.getFileById(ssID).getUrl();

  // ①. Define Button "Show SpleadSheet"
  var showSSButton = CardService.newTextButton()
    .setText('Show Template')
    .setTextButtonStyle(CardService.TextButtonStyle.FILLED)
    .setBackgroundColor('#696969')
    .setOpenLink(CardService.newOpenLink()
      .setUrl(ssUrl)
      .setOnClose(CardService.OnClose.RELOAD_ADD_ON));

  // ②. exists template data. Display tempate list.
  var ss = SpreadsheetApp.openByUrl(ssUrl);
  var startRow = 1;
  var startCol = 1;
  var lastRow = ss.getLastRow();
  var lastCol = ss.getLastColumn();
  var ssData= ss.getSheetByName(ssSName).getRange(startRow,startCol,lastRow,lastCol).getValues();
  var buttons = CardService.newCardSection()

  for( var i=1; i<ssData.length; i++ ) {
    buttons.addWidget(CardService.newTextButton()
      .setText(ssData[i][1])
      .setOnClickAction(CardService.newAction()
        .setFunctionName('applyInsertTemplateAction')
        .setParameters({'message': ssData[i][2]})))
  }

  // Define UI
  var card = CardService.newCardBuilder()
    .addSection(CardService.newCardSection()
      .addWidget(showSSButton))
    .addSection(buttons)
    .build();
  return [card];
}


// functions
// Define template Buttons
function applyInsertTemplateAction(e) {
  var messages = e.parameters['message'];
  var sp_messages = messages.split(String.fromCharCode(10)).join(''); // ”\n” convert HTML format.
  var response = CardService.newUpdateDraftActionResponseBuilder()
    .setUpdateDraftBodyAction(CardService.newUpdateDraftBodyAction()
      .addUpdateContent(
        sp_messages,
        CardService.ContentType.MUTABLE_HTML)
      .setUpdateType(CardService.UpdateDraftBodyType.IN_PLACE_INSERT))
    .build();
  return response;
}

「コード.gs」タブに上書き貼り付けし、4行目の以下 スプレッドシートのID を1-③で控えた文字に置換する

  var ssID  = "スプレッドシートのID";

 

~中略~

⑦以下のプログラムコードをコピーして…


{
"timeZone": "Asia/Tokyo",
"dependencies": {
},
"exceptionLogging": "STACKDRIVER",
"oauthScopes": [
"https://www.googleapis.com/auth/gmail.addons.execute",
"https://www.googleapis.com/auth/gmail.addons.current.action.compose",
"https://www.googleapis.com/auth/gmail.addons.current.message.metadata",
"https://www.googleapis.com/auth/spreadsheets",
"https://www.googleapis.com/auth/drive"
],
"gmail": {
"name": "gmail_share_template",
"logoUrl":
"https://www.gstatic.com/images/icons/material/system/1x/label_googblue_24dp.png",
"primaryColor": "#45c4bf",
"secondaryColor": "#0000FF",
"composeTrigger": {
"selectActions": [
{
"text": "Build Mail Share Template",
"runFunction": "buildTemplateComposeCard"
}
]
}
}
}

「appsscript.json」タブに上書き貼り付けする

~中略~

⑪「Deployment ID」 の値をコピーし、共有テンプレートを利用するメンバーに共有する

 

Gmailに組み込む (省略)

※ 本手順は共有テンプレートの管理者・利用者共に実施すること

 

~中略~

⑥「インストール済みのデベロッパーアドオン」に「gmail_share_template」が表示されたら組み込み完了

  

試してみる

※ 本手順は共有テンプレートの管理者・利用者共に実施すること

 

~中略~

④警告画面が表示されるが「詳細」をクリックし…

下に展開された「gmail_share_template」をクリックする

※ 画像省略

 

~中略~

⑥「アクセス承認」が完了するとテンプレート機能が利用可能になる

 テンプレートの内容を確認したい場合は「SHOW TEMPLATE」をクリックする

 ※ スプレッドシートの「編集者」権限のみテンプレートの更新が可能

gmail addon1

 

以上。

 

補足

・件名、宛先の追加機能はまだない (アドオン側が未実装)
・スプレッドシートのTitleに数字のみはNG
・スプレッドシートの各列はすべて入力必須項目
・スプレッドシートの入力ミスなどでテンプレート機能が正常に動作しなくなった場合はGoogleドライブからスプレッドシートを直接開いて修正する
・コードはグローバル対応のため英語表記ですが (自己責任で) ソースを修正して日本語表記にすることも可能です
・くどいようですが、本機能はあくまで自分(あなた)が自作したものであり例えるならExcelの自作マクロと同等であるため、企業にありがちなセキュリティ要件はクリアできます
・AndroidのGmailアプリでも同じテンプレートが利用できます (iPhone未対応)
・機能を呼び出すアイコンが元のテンプレートアドオンと同じ青いラベルになっています。両方使う方はご注意ください。 (良いものがあれば追記予定)

 

最後に

2重更新の手間を省くために元のテンプレートアドオン記事からの差分のみの解説となっており、読みにくくて大変申し訳ないです。

わかりにくいという声が多い場合は再投稿も検討するため遠慮なくコメントしてください。

本投稿時点では類似機能はリリースされていないようなので興味がある方は検討の余地ありだと思います。

また、アドオン側の機能強化により宛先追加などが可能になった際は改修版を公開したいと思います。

 

2020/08/29

【Gmail】テンプレートアドオンをAndroidで使ってみた

こんにちは。

引き続きテンプレート機能の話です。

今回はAndroidでの使用感をレポートします。

 

初めて訪問された方は以下もどうぞ。

【Gmail】テンプレートアドオンを開発してみた

【Gmail】テンプレートアドオンをインストールしよう

 

概要

同じGoogleアカウントであればPC・Android(スマホ・タブレット)問わず共通のテンプレートが利用できます。

PCを利用しない方々にとっても導入する価値は大いにあると思います。

 

それでは利用イメージの紹介です。

今回はすごく短いので読みやすいと思います。

 

利用イメージ

①Gmailアプリにてメール新規作成画面を開き、右上のメニューから「挿入元 gmail_template」をタップする

gmail1

 

②共通のテンプレート一覧が表示するため前回同様「TEST TEMPLATE B」をタップする

gmail2

 

③対応したテンプレート内容がメール本文に反映された 

gmail3

 

以下は②で「EDIT TEMPLATE」をタップした場合

スプレッドシートアプリにてテンプレートを更新することができる

spleadsheet1

 

 

以上です。

 

 

スマホ・タブレットは文字入力に慣れが必要なため長文入力に苦労する人が多いと思います。

この機能を使えば定型文をボタン操作で本文に挿入できるため手間が軽減できるようになります。

テンプレートの更新はPCから行えばメンテナンスも簡単にできるはずです。

何よりPCで使っているテンプレートがスマホ・タブレットでも使えるのはGmailユーザーにとって感動ものだと思います。

 

2020/08/25

【Gmail】テンプレートアドオンをインストールしよう

こんにちは。

今回は前回の続きでテンプレートアドオンの設定手順を説明します。

 

非エンジニアの方でも利用できるよう詳細に記述するので有識者はご容赦ください。

前回の投稿はこちらからどうぞ。

https://blog.fkmint.com/2020/08/gmail20200802.html

 

では早速、解説に移ります。 

 

アドオンの利用要件

  • Gmailを利用している (フリーでも利用可)   …だけ

 

設定手順

GoogleAppsScriptでコードを書く

①コード管理画面にアクセスして「新規スクリプト」ボタンをクリックする

gas1

 

②新しいタブにスクリプトエディタが開く

gas2

 

③以下のプログラムコードをコピーして… 

// main
function buildTemplateComposeCard() {
  // settings template SpleadSheetName and SheetName (save in MyDrive)
  var ssName  = "gmail_template_list";
  var ssSName = "list";

  // exits SpleadSheat
  var ssExists = DriveApp.getFilesByName(ssName);
  if ( !ssExists.hasNext() ){
    createSS(ssName, ssSName);
  }
  // get SpleadSheetURL
  var ssUrl = DriveApp.getFilesByName(ssName).next().getUrl();
  // ①. Define Button "Edit SpleadSheet"
  var editSSButton = CardService.newTextButton()
    .setText('Edit Template')
    .setTextButtonStyle(CardService.TextButtonStyle.FILLED)
    .setBackgroundColor('#696969')
    .setOpenLink(CardService.newOpenLink()
      .setUrl(ssUrl)
      .setOnClose(CardService.OnClose.RELOAD_ADD_ON));
  // ②-A. for example first run, there is no template data. Display messages.
  var noDataMessage = CardService.newTextButton()
    .setText('Please, Click [Edit Template] and define template.')
    .setDisabled(true)
    .setOpenLink(CardService.newOpenLink() // dummy
      .setUrl(ssUrl)); // dummy
  // ②-B. exists template data. Display tempate list.
  var ss = SpreadsheetApp.openByUrl(ssUrl);
  var startRow = 1;
  var startCol = 1;
  var lastRow = ss.getLastRow();
  var lastCol = ss.getLastColumn();
  var ssData= ss.getSheetByName(ssSName).getRange(startRow,startCol,lastRow,lastCol).getValues();
  var buttons = CardService.newCardSection()
  // switch ②-A/B
  if ( lastRow == 1 ) {
    buttons.addWidget(noDataMessage)
  } else {
    for( var i=1; i<ssData.length; i++ ) {
      buttons.addWidget(CardService.newTextButton()
        .setText(ssData[i][1])
        .setOnClickAction(CardService.newAction()
          .setFunctionName('applyInsertTemplateAction')
          .setParameters({'message': ssData[i][2]})))
    }
  }
  // Define UI
  var card = CardService.newCardBuilder()
    .addSection(CardService.newCardSection()
      .addWidget(editSSButton))
    .addSection(buttons)
    .build();
  return [card];
}


// functions
// Create tempalte SpleadSheet
function createSS(ssName, ssSName) {
  var ssNew = SpreadsheetApp.create(ssName);
  ssNew.renameActiveSheet(ssSName);
  ssNew.getSheetByName(ssSName).getRange(1,1).setValue("No");
  ssNew.getSheetByName(ssSName).getRange(1,2).setValue("Title");
  ssNew.getSheetByName(ssSName).getRange(1,3).setValue("Message");
}
// Define template Buttons
function applyInsertTemplateAction(e) {
  var messages = e.parameters['message'];
  var sp_messages = messages.split(String.fromCharCode(10)).join('<br />'); // ”\n” convert HTML format.
  var response = CardService.newUpdateDraftActionResponseBuilder()
    .setUpdateDraftBodyAction(CardService.newUpdateDraftBodyAction()
      .addUpdateContent(
        sp_messages,
        CardService.ContentType.MUTABLE_HTML)
      .setUpdateType(CardService.UpdateDraftBodyType.IN_PLACE_INSERT))
    .build();
  return response;
}

「コード.gs」タブに上書き貼り付けする

gas3

 

④メニューの「表示」>「マニフェスト ファイルを表示」をクリックする

gas4

 

⑤作成中のプログラムに命名を求められるため「gmail_template」と入力して「OK」をクリックする

※ 個人で使う分には自由に名付けて問題ないが複数名で使用する場合は相談の上で命名すること

 

gas5

 

⑥「コード.gs」タブの隣に「appsscript.json」タブが表示される

gas6

 

⑦以下のプログラムコードをコピーして…

{
  "timeZone": "Asia/Tokyo",
  "oauthScopes":[
    "https://www.googleapis.com/auth/gmail.addons.execute",
    "https://www.googleapis.com/auth/gmail.addons.current.action.compose",
    "https://www.googleapis.com/auth/gmail.addons.current.message.metadata",
    "https://www.googleapis.com/auth/spreadsheets",
    "https://www.googleapis.com/auth/drive"
    ],
  "gmail":{
    "name": "gmail_template",
    "logoUrl": "https://www.gstatic.com/images/icons/material/system/1x/label_googblue_24dp.png",
    "primaryColor": "#4285F4",
    "secondaryColor": "#0000FF",
    "composeTrigger": {
      "selectActions": [
        {
          "text": "Build Mail Template",
          "runFunction": "buildTemplateComposeCard"
        }
      ]
    }
  },
  "exceptionLogging": "STACKDRIVER"
}

「appsscript.json」タブに上書き貼り付けする

gas7

 

⑧ 「コード.gs」と「appsscript.json」タブでそれぞれフロッピーアイコンをクリックして保存する

※下図のように最終的にタブ名の左隣 * が表示されなくなればOK

gas8

 

⑨メニューの「公開」>「マニフェストから配置」をクリックする

gas9

 

⑩「Get ID」をクリックする

gas10

 

 

⑪「Deployment ID」 の値をコピーする

gas11

 

Gmailにアドオンをインストールする

①Gmailを開き、歯車アイコン>「設定」をクリックする

gmail1

 

②「アドオン」タブで「ご利用のアカウントで、デベロッパーアドオンを有効にします」にチェックを入れる

gmail2

 

③「有効にする」をクリックする

gmail3

 

④「デベロッパー アドオン」項目が追加されるため空欄に1-⑪でコピーしたDeployment IDを貼り付けて「インストール」をクリックする

 

 

⑤「このアドオンのデベロッパーを信頼します」にチェックを入れて「インストール」をクリックする

gmail4

 

⑥「インストール済みのデベロッパーアドオン」に「gmail_template」が表示されたらインストール完了

gmail5

 

使用方法

初回のアクセス承認

①Gmailで新規作成画面を開き、青いラベルアイコンをクリックする

gmail6

 

②初回実行時のみ承認が必要となるため「アクセスを承認」をクリックする

gmail7

 

③使用するGoogleアカウントを尋ねられるため現在使用中のアカウントをクリックする

gmail8

 

④警告画面が表示されるが「詳細」をクリックし…

gmail9

下に展開された「gmail_template」をクリックする

gmail10

 

⑤テンプレート機能がアクセスする項目について確認が求められるため「許可」をクリックする

※ 第3者が作成したツールを利用する場合はアクセス項目が妥当であるか確認の上で使用してほしいが、今回は第3者(私)が考えたプログラムコードを使って自分(あなた)が作成したツールとなるため遠慮なく「許可」してほしい

gmail11

 

初期設定の例

①「アクセス承認」が完了するとテンプレート機能が利用可能になる

   初期状態ではテンプレートがないため以下のような画面となる

   早速テンプレートを作成するため「EDIT TEMPLATE」をクリックする

gmail12

 

②新しいタブにテンプレートを管理するスプレッドシートが開く

ss1

 

③例として以下のようなテンプレートを定義する

 なお、各列の説明は以下のとおり

・No:フィルタのソートで並び替えをするためのナンバリング
・Title:テンプレートの題名、テンプレート機能で一覧化される表示名
・Message:テンプレートの内容、Titleに紐づく

ss2

 

④スプレッドシートを閉じると以下のように反映される

gmail13

 

⑤「test template B」を選択した結果

対応するテンプレート内容がメール本文に反映された

gmail14

 

補足

・件名、宛先の追加機能はまだない (アドオン側が未実装)
・スプレッドシートのTitleに数字のみはNG
・スプレッドシートの各列はすべて入力必須項目
・スプレッドシートの入力ミスなどでテンプレート機能が正常に動作しなくなった場合はGoogleドライブからスプレッドシートを直接開いて修正する
・企業など複数名で使用したい場合は作成した「gmail_template」をメンバー間で共有設定した上で、2と3の作業を行ってもらう (2-④で入力するDeployment IDは共有メンバー間で同値となる)
・コードはグローバル対応のため英語表記ですが (自己責任で) ソースを修正して日本語表記にすることも可能です
・くどいようですが、本機能はあくまで自分(あなた)が自作したものであり例えるならExcelの自作マクロと同等であるため、企業にありがちなセキュリティ要件はクリアできます
・AndroidのGmailアプリでも同じテンプレートが利用できます (iPhone未対応)

 

最後に

本職がコーダーではないのでコードの完成度については目を瞑っていただきたいです。

 

基本的に最低限動けば良いレベルで作成していますので、コメントなどで修正の要望をいただいても対応できかねる場合があります。ご容赦ください。

また、本機能をご利用の際はあくまで自己責任でお願いします。