自習用」カテゴリーアーカイブ

SharePointのリストに予め登録した時間帯と本文に応じてTeamsにボットからメッセージを送る

まとめ

SharePointのリストに投稿時間帯、投稿する本文を登録しておきます。PowerAutomateで1時間ごとに動作するクラウドフローを使い、リストの内容に応じたメッセージをTeamsに投稿します。

本記事の後半では、発展編として動作条件を複数にする場合や宛先を複数人にする場合を紹介します。

Google環境で同様の仕組みを作成する方法はリンク先をご覧ください。

前提とするリストの構造

以下のようなリストをSharePointに作成しておきます。投稿時間帯はhour列で指定します。

時間帯の判別をODataクエリで行う場合

時間帯の判別をSharePointのリストからアイテムを取得する段階で行います。この方法の利点は、リストから取得するアイテムの上限数制限に触れにくいこと、動作が高速であることです。

まず、現在時刻を取得し、時間の部分だけを抜き出します。

現在時刻の取得は、「組み込み」>「日時」にある「現在の時刻」と「タイムゾーンの変換」アクションを用います。現在時刻を協定世界時(UTC)で取得し、東京のタイムゾーンに変更します。「Recurrence」アクションの次に「現在の時刻」アクションを追加し、その次に「タイムゾーンの変換」アクションを追加してください。

次に、東京の現在時刻から、時間の部分だけ取り出します。「タイムゾーンの変換」アクションの後ろに、「組み込み」>「データ操作」にある「作成」アクションを追加してください。入力には式の入力画面に入ったあと次の式を入力してください。formatDataTime関数は、第1引数に現在時刻、第2引数に出力文字列の書式を設定します。次の式でbody(‘タイム_ゾーンの変換’)は東京の現在時刻、%Hは24時間表記での時間部分を示します。カスタム日時書式設定で時間はHで指定できますが、一文字だけで使う場合は%を頭に付ける必要があります。%がないとエラーを吐きます。

formatDateTime(body(‘タイム_ゾーンの変換’),’%H’)

この式の出力結果は0詰めなしの時間です。9時なら9、16時なら16が文字列として出力されます。

として入力できている場合、PowerAutomateのフロー上はfxと書かれたアイコンが表示されます。黒い文字だけなら単なる文字列として入力されていますので、式の入力画面から入力しなおしてください。

このあと複数の「作成」を用いる場合は、「作成」の名前を変更しておくと分かりやすいでしょう。アクションの名前を変更したい場合は、三点ボタンをクリックすると表示されるメニューから「名前の変更」を選択します。

時間の判定に使う文字列が用意できたので、次はSharePointのリストからデータを取得します。「標準」>「SharePoint」にある「複数の項目の取得」アクションを追加してください。

「サイトのアドレス」と「リスト名」は、ご自身で用意したリストを選択してください。次に、「詳細オプションを追加する」をクリックして詳細オプションを表示させます。詳細オプションの「フィルター クエリ」には「hour eq 出力」と入力します。ここで出力は前段のアクション「作成」の結果です。

ここまでの操作で、hour列の値が現在時刻の時間(hour)と一致するデータを取り出しました。この後は取り出して複数の項目に対して、それぞれTeamsにメッセージを送る処理を行います。

「アクションを追加」で「コントロール」>「Apply To Each」を挿入します。「以前の手順から出力を選択」にはvalueを選択します。

「Apply To Each」で実行するアクションを追加します。「標準」>「Microsoft Teams」>「チャットまたはチャンネルでメッセージを投稿する」を選択してください。どこにメッセージを投稿するのかを設定する画面が表示されます。ここでは仮にボットとのチャットに投稿する場合の設定例を示します。

*投稿者 フロー ボット
*投稿先 Chat with Flow bot
*Recipient ここに受信者のメールアドレスを設定します。読み込むリストに受信者を設定する列を用意しておけば、ここを動的な値にすることができます。
*Message
「動的なコンテンツを追加」からSharePoint複数の項目を取得の下にあるMessageを選択します。Messageの前後に文字列を追加しても結構です。

以上で設定は完了です。フローを保存して、テストしてみましょう。

時間帯の判別をPowerAutomateの条件判定で行う場合

SharePointのリストからすべてのデータを取得した上で、PowerAutomateの「コントロール」>「条件」で処理すべき項目か否かを判定します。

「Apply To Each」のループの中に、「作成」で条件判定に使う文字列を作ってみましょう。ここで注意が必要なのは、型を文字列に揃える必要がある点です。hour列の値は数値型、日時を変換して出てくる出力は文字列型です。hour列の値をstring()関数に入れて文字列に変換するなどの方法があります。

ここでは、hour列に合わせて時の文字列だけを取り出す方法と、年月日に合わせて文字列を成形する方法を示します。

時の文字列のみを作る場合

string(items(‘Apply_to_each’)?[‘hour’])

次の値に等しい

formatDateTime(body(‘タイム_ゾーンの変換’),’%H’)

年月日時という文字列を作る場合

concat(formatDateTime(body(‘現在の時刻’),’yyyy-mm-dd-‘),items(‘Apply_to_each’)?[‘hour’])

次の値に等しい

formatDateTime(body(‘タイム_ゾーンの変換’),’yyyy-mm-dd-H’)


発展編

ここからは、少々複雑な処理を行って機能を追加していきます。

発展編1 TeamsのチャットではなくOutlookでメールを送る

Teamsのチャットではなく、Outlookのメールでメッセージを送ることを考えます。方法は簡単です。コネクタをTeamsではなくOutlookにするだけです。

もちろん宛先に動的なコンテンツを入力することもできます。

発展編2 時間と曜日、日付に応じて動作するようにする

SharePointのリストから複数の項目を取得する際のクエリを変更して、曜日と日付も条件と合うようにします。

リスト側の操作で、列を追加します。

曜日(内部名Day)は漢字一文字(月,火,水,木,金,土,日)で表現することにします。選択肢でも一行テキストでも結構です。選択肢にする場合は、平日を意味する「月火水木金」だとかすべての曜日を意味する「月火水木金土日」といった選択肢を用意しておくとユーザーに便利です。

日付(内部名Date)は単純に数値型でよいのですが、日付は1~31までしかないので小数点以下0桁の最小値1、最大値31などと制限をかけておくと入力ミスを減らせます。工夫として、日付に関係なく動作させたい場合に備えて、日付が0のときにも動作させることを考えます。このため、最小値を1でなく0としておきましょう。

ここまでの操作で次のようなリストが得られました。

「組み込み」>「データ操作」にある「作成」アクションを使って、クエリに使う曜日と日付を作成しましょう。なお、以下では東京のタイムゾーンに変換した後の時刻をbody(‘タイム_ゾーンの変換’)と書きますが、式で書かずにタイムゾーンの変換結果を置いても結構です。

曜日は漢字一文字(月,火,水,木,金,土,日)で表現することにします。現在時刻を入力すると、対応する曜日の漢字一文字が出力される式はリンク先を参照しました。次の式の結果を後で曜日と書きます。

createArray(‘日’,’月’,’火’,’水’,’木’,’金’,’土’)[dayOfWeek(body(‘タイム_ゾーンの変換’))]

日付は時間hourと同じようにカスタム日時書式設定を使います。月の日にちはdの一文字ですから、Hと同様に%を入れて次のように書けます。次の式の結果を後で日付と書きます。

formatDateTime(body(‘タイム_ゾーンの変換’),’%d’)

本ページの前半で説明したの詳細は省きますが、時間帯hourを同様に時間帯と書くことにします。

リストに記録されたアイテムのうち、動作条件として入力した時間帯曜日日付の3つが現在時刻と一致するものだけを取り出すクエリは次のように書けます。

(hour eq 時間帯) and substringof(‘曜日‘, Day) and (Date eq 日付)

ここで曜日の判定だけはsubstringof(‘検査値’, 列名)関数を使用しました。検査値は曜日漢字一文字なので、リストの値が’月’のときも’月火水木金’のときも条件を満たす(Trueが返る)ようになります。また、曜日を一行テキストでなく選択肢にした場合もsubstringof()を使用してください。選択肢の場合、リストには単純な文字列ではなくJSONの形式で値が記録されています。したがって、曜日の漢字一文字と同値判定されません。ちなみに、選択肢としてDay列を作ると動的なコンテンツにはDayとDay Valueという2つのアイコンが表示されます。Dayは選択肢オブジェクト、Day Valueは選択肢の値を返します。検査値は文字列として扱うため、シングルクォーテーション”で囲むことを忘れないでください。

ここでさらに一工夫です。リストにDate列を追加する際に、日付に関係なく動作させたい場合はDateを0にするように考えました。SharePointのリストから複数の項目を取得する際のクエリとしては、「Dateの値が現在の日付と等しい、またはDateの値が0」と各必要があります。またはを表すのはorですので、クエリを以下のように書きなおします。

(hour eq 時間帯) and substringof(‘曜日‘, Day) and (Date eq 日付 or Date eq 0)

なお、時間帯がどの値でも実行するようにしたい場合は、時間帯に-1を入れるといった運用が考えられます。日付と同じ考え方であって、わかりやすい値で存在しない値を用いるという意味です。

これでフローの修正は完了です。Apply To Eachの中の処理は本ページの前半で解説した内容と変わりません。

発展編3 宛先を複数人にする

宛先を複数人にするのは少々手間がかかります。

まず、TeamsまたはOutlookコネクタに対して、どのような形式で宛先を入力すべきか考えましょう。

Teamsのボットチャットの場合はボット対1人の関係です。したがって、複数人に同じメッセージを送るには、人数分だけ繰り返し処理を宛先だけ変えて実行します。ApplyToEachで繰り返し処理するには、Arrayの中に宛先のメールアドレスが入っている形が良いでしょう。

Outlookのメールの宛先を複数人にするには、メールアドレスをセミコロン;で区切った文字列を宛先に入力することになります。そのものズバリの記事を他サイトで見つけたので、こちらを参照してください。技術的なポイントとしては、文字列変数にApplyToEachのループ処理でメールアドレスを追記していく形です。

コネクタに入力すべき値が見えてきたので、欲しい値を出力するにはどうするか考えます。リストにメールアドレスが文字列をとして入っている場合は、そのまま値を使えばいいので詳細は省きます。ここでは、リストに「個人」型かつ複数人を設定する場合を紹介します。内部名MessageToの列を以下の設定で作成します。

この列の値は、組織のユーザーデータベースから個人を指定できます。たとえば、会社のアカウントであれば同じ会社の個人のアカウントを入力できます。このアカウントはオブジェクト型なので、扱いには一工夫が必要です。

列の設定で複数の選択が許可されている場合、値は配列[]型です。配列の要素として、各個人の情報を示すオブジェクト{user#}が入っています。
[{user1}, {user2}, … , {userN}]
各人のアカウントを指すオブジェクトの中には、DisplayNameやEmailといったプロパティがあります。いま欲しいのはこのEmailだけです。Emailの取り出し方を考えてみましょう。

まず宛先の情報が含まれているMassageToの中身を確認します。仮の操作として、ApplyToEachのループの中に「組み込み」>「データ操作」>「作成」アクションを追加します。入力にはMassageToを置きます。

これで実行結果を確認してみると次の図のようになります。

このような複雑な値をPowerAutomateは自動で処理できません。そこで、「組み込み」>「データ操作」>「JSONの解析」アクションを使用します。上図の「未加工出力の表示」を開き、結果をコピーしておいてください。「JSONの解析」アクションを追加し、コンテンツにMessageToを選びます。次に、「サンプルから生成」を開き、先ほどコピーした「未加工出力の表示」の中身をすべてコピペします。こうすることで、PowerAutomateがJSONの構造を解析してくれます。「JSONの解析」アクションのスキーマを設定できたら、先ほどMessageToの中身を確認するために追加した「作成」アクションは削除してかまいません。

JSONの解析を行うと、MessageToの内部の情報、たとえばEmailを取り出せるようになります。JSONの解析のあとにアクションを追加すると、動的なコンテンツの中に次のような選択肢が出現することに気づきます。この中のEmailをTeamコネクタに入力すればよいわけです。

JSONの解析について詳しく学びたい方はリンク先の記事をご覧ください。

先述のように、複数の選択が許可された列の値は配列です。配列に対してはApplyToEachで配列内の各要素に対して処理を行います。「チャットまたはチャンネルでメッセージを投稿する」アクションのRecipient (宛先)にEmailを設定した場合、Emailは配列内の要素ですから、自動的にApplyToEachが追加されループの中にTeamsコネクタが移動します。ちなみに、ここで表示されているvalueはSharePointのリストから取得した各アイテムが要素である配列、本文はMessageToをJSONの解析した結果の配列です。

Teamsコネクタの場合は以上でフローが完成です。Outlookの場合は、最後に出てきた動的なコンテンツEmailを使って宛先文字列(メールアドレスが;で区切られている)を作成してください。

[PowerApps] スマホでPowerAppsを使う

PowerAppsで作成したアプリをスマートフォンで使用する場合の注意点をまとめます。

Power Apps Mobile の概要
iPhoneやiPadといったiOS端末であれ、Android端末であれ、モバイル環境でもPowerAppsで作成したアプリを動作させることはできます。ただし、一部の機能が制限される場合があります。
Power Apps Mobileアプリをスマホにインストールして、Power Apps Mobileアプリ上で各自作アプリを動作させる場合は支障がないかもしれません。一方で、Power Apps Mobileアプリをインストールせず、ブラウザアプリ上でPowerAppsのアプリを動作させる場合は、いくつかの制限が生じます。

アプリを Web ブラウザーで実行する
Edgeなどのブラウザアプリ上でPowerAppsを実行する場合は、次のような制約があります。

  • 一部のコントロールを使用できない。Barcode scannerなど。
  • プッシュ通知を使用できない。
  • モデル駆動型アプリが使用できない。キャンバスアプリのみ実行可能。
  • アプリを開く前に、Power Apps Mobileアプリをインストールするように勧めるページにリダイレクトされる。
    このリダイレクトを実行させないためには、作成したアプリを配布する際に、アプリのWEBリンク(後述)末尾に次の文字列を追加します。
    &skipMobileRedirect=1
    ただし、この文字列があるとPowerAppsモバイルアプリで開こうとする際にエラーが発生することがあります。
リンク先の「スマートフォン上の Web ブラウザーを利用してモバイル駆動型アプリを実行することはできません。Power Apps Mobile アプリを使用する必要があります。」は誤訳です。「モバイル駆動アプリ」と表記されている部分は「モデル駆動型アプリ」が正しい訳です。意味不明な表現がある場合は英語版を参照しましょう。ほかにも「Windows」が「窓」と表記されているのに気づくでしょう。

作成したアプリを配布する際には、PowerAppsでアプリの「共有」メニューから共有する相手を指定して共有するか、「詳細」画面に記載されているWEBリンクを共有します。もし実行権限を付与していないユーザーからWEBリンクのURLにアクセスがあった場合は、アプリの作成者に対して権限をリクエストする画面になります。

PowerAppsのメニュー
WebリンクのURL表示例

さいきょうの装置予約表

Microsoft365環境を前提として、共同利用する装置の予約システムの在り方を考える。

大学や研究所には、多種多様な共用装置がある。これらは予約表のような形で誰がいつ使用するのかを管理している。予約表は、装置の脇置かれたノートであったり、ホワイドボードに書かれた表であったり、あるいは共有ファイルサーバー上に置かれたExcelファイルであったりする。

装置管理の技術職員がいるような恵まれた環境でもない限り、予約表の管理は装置管理も含めた雑用のひとつとして装置利用者にのしかかる。たいていの場合、更新が必要な要素(毎年カレンダーを更新するだとか)は面倒なので誰もやらずに放置されて、我慢できなくなった誰かが更新するか、機能を喪失するかを待つ。デジタルだなんだという時代にあさましいこことだ。最新のデジタル技術を使って、いい感じの装置予約表を作れないものか。

どうせ作るなら、装置管理に必要な機能をひとまとめにしたものを作りたい。装置管理に必要な機能とは何だろうか?私の考える必要な要素は以下の通りである。各項目をMicrosoft365環境で実現できるサービスを併記する。

  • 装置の使用予定を確認、追加、編集、削除できる。
    Exchange Onlineで装置のメールアドレスを作ることで、会議室と同様に設備の予約ができる。
    参考 第30回 会議室や備品予約を簡単にする
  • 装置利用者向けの資料を閲覧できる。
    SharePointのニュースやページ、あるいはドキュメントを共有する形で資料を提示できる。
  • 装置利用者間の情報伝達手段が備わっている。
    Teamsのチャンネル機能またはグループチャットを使えば、装置利用者全員での情報共有が可能である。異常を装置管理者に報告するだけであればFormsでも良い。

ここからは各機能の果たす役割と実現にあたっての注意したい点を述べる。

装置の使用予定を確認、追加、編集、削除できる。

装置予約表としての基本機能。この機能が使いにくかったら利用してもらえない。
PCとスマートフォンの両方からアクセスできることが望ましい。通常の業務の中では常務用PCから装置予約表にアクセスできればいいが、装置の目の前にいるときにはその場でより簡便な手段を取りたい。装置の制御PCはインターネットに接続していないケースも少なくないので、スマートフォンから予約表にアクセスしたい。装置を使っていて使用を延長したり中止したりすので、予約を閲覧できるだけなく、編集機能も使えてほしい。

装置の予約状況は一目でわかるようにしたい。カレンダーアプリのような視覚的効果を使う。

これらの希望を満たすようなアプリをPowerAppsで開発すればよい。PC向けとスマホ向けで画面の広さが異なるので、それぞれアプリを作って動作とデータベースを共通化しておくとよいだろう。

装置予約表アプリは、各装置ごとに作るのではなく、装置ごとにIDを振ってどの装置にも簡便に装置予約表を追加できるようにする。アプリを作るような面倒なことはなるべく一回にして、利用者の為は極力なくす。ばらばらに低レベルのものを作るより、ひとつの一般化された高レベルのアプリを作る方がいい。

装置予約表を起点として、後述する資料提供機能と連絡手段にもアクセスできるようにする。

装置利用者向けの資料を閲覧できる。

利用者と管理者に必要な情報をそれぞれ蓄積し、必要な場面ですぐに閲覧できるようにする。

利用者向けの情報として、装置の使い方や注意点、ノウハウなどの情報を一元的に提供する。SharePointのページでもいいし、Wordファイルを共有してもいい。マニュアルのような資料が紙に印刷されて装置横に置かれている場合がよくある。紙だと修正や追加の度に印刷しなおすのが手間なので、いっそのこと電子的に共有して必要があればすぐに修正できる方が良い。装置管理者以外の利用者が多い場合には、管理者も知らないところでうまいやり方が編み出されていたり、熟練ユーザーには当たり前の注意点を初心者ユーザーがすっ飛ばして問題を起こしたりする。伝えるべきことを口頭ですべて伝えるのは無理があるので、これだけ見ればいい、ここを探せばいいという資料を用意して、それを利用者全員で優れたものにしていく取り組みが効果的である。

また、取扱説明書に書かれているような細かいスペック、パラメータの意味なども、業務に必要な情報を抜粋しておくと良い。その装置で実行できる限界の仕事を見積もったり、報告書をまとめたりする際に役に立つ。

管理者向けに必要な情報としては、メンテナンスや将来の装置更新に必要な情報を蓄積する機能を提供する。消耗品の交換や小規模な修繕は毎年のように発生するため、都度価格を調べて購買の稟議を通すのは面倒かつ時間がかかる。過去の支出情報を蓄積していけば、予算立案時にも適切な提案が可能になる。

将来の装置更新に必要な情報として忘れがちなのが、利用実績の把握である。どこの誰がどのような目的で装置を使用したのかを数年分蓄積するだけで装置更新時の費用対効果の見積もりが簡単になる。どこの誰がどれだけ装置を使ったのかは予約表または使用記録からわかるので、どのような目的で使用したかを予約表ないし使用記録に書き込ませると良い。

装置利用者間の情報伝達手段が備わっている。

利用者の多い装置では、利用者全員に対して簡便に連絡できる手段が求められる。Teamsのグループチャットやチャンネル(あるいはタグ)機能を使うと良い。

企業であれば部課単位、大学であれば研究室単位で縦割りの壁がある。同じ装置を使っている者同士であっても、不具合の報告ですら縦割りの壁に阻まれる。ちょっとおかしいかもしれないという利用者の声を吸い上げることが装置を健全に保つのに有効なのは言うまでもない。逆に、使い方の工夫をしたという有益な情報も同じように流通しにくい。これらは技術というよりコミュニケーションの課題であるから、コミュニケーションを促進するツールがあれば解決できる。コミュニケーションが促進された結果として、大きな技術的問題を回避できる。

なんでも報告できるようにするには、コミュニケーションツールそのものだけでなく運用も大事だ。ごくまれにしか使われないチャットに投稿するのは勇気がいるし、返信がもらえるか不安になる。装置管理者が積極的にツールを使うことで、過疎らせない、質問してよい不具合報告しても怒られない雰囲気を作るのもツールと同様に重視すべきである。

装置管理者の立場では、この装置予約表システムの導入時だとか、一斉に複数人が利用を開始するときに、一人一人のユーザーを利用者登録するのは面倒である。そこで、Excelなどで作成したリストを基に、PowerAutomateでグループチャットなりチームにユーザーを追加する機能が欲しいところだ。反対に、ユーザーの削除は複数人を一気に操作するケースは少ないだろうから、ユーザーの自動削除機能は優先度が低い。

むすび

すべてが紙の時代においては、装置脇に置かれた紙のノートが前述の3つの機能を網羅することができた。デジタル技術では、すべての自分で作るあげるのではなく、既存のサービスを組み合わせてやりたことを実現する場合が多い。私たちが「装置予約表」と呼んでいたものは単なる予約表ではなく、利用者間のコミュニケーションツールとしての側面を持っていたことに自覚的になることで、予約表以外の適切なサービスを組み合わせて、デジタル時代における「さいきょうの装置予約表」を構築できるだろう。

便利なキーボードショートカット

  • Win + P
    サブディスプレイ、プロジェクタの投影オプションを切り替え
    PCのみ・複製・拡張・セカンドスクリーンのみ
  • Win + Shift + S
    画面の一部を指定してキャプチャ
  • Win + 矢印
    左右:ウィンドウを左右の画面半分に割り付け
    上:最大化、下:最大化解除、最小化
  • Win + X
    シャットダウンや設定、PowerShellへのショートカットを表示
  • Win + R
    ファイル名を指定して実行
  • WIn + W
    Windows Ink Workspace 付箋はる、画面に書き込みなど
  • Win + L
    ロック画面を表示 (離席する際にはWin + L!)
  • Win + D
    ウィンドウをすべて隠してデスクトップを表示
  • Win + E
    ファイルエクスプローラを起動
  • Win + +  拡大鏡を起動 拡大
  • Win + - 拡大鏡 縮小
  • WIn + Esc 拡大鏡 終了
  • Ctrl + S ファイルの保存 上書き
  • Ctrl + X 切り取り
  • Ctrl + C コピー
  • Ctrl + V 貼り付け
  • Ctrl + Z 操作のやり直し
  • Ctrl + Y 操作の繰り返し
  • Ctrl + F 検索ダイアログの表示
  • Ctrl + Shift + Esc タスクマネージャー起動(プロセスタブから強制終了)
  • Alt + F4 ウィンドウを閉じる。ウィンドウが開いていないときはシャットダウンメニューの表示。
  • Alt + Tab 開いているウィンドウを順繰りに表示する

[Microsoft365] PublisherでQRコード画像を含んだ差し込み文書を作成する

Microsoft Officeの中でも影が薄いPublisherは、紙に印刷する用途でPowerPointのように自由なレイアウトを作るのに適してます。無理やりPowerPointやExcelで掲示物を作ると印刷するときに意図しないズレが生じたり、紙の大きさに合っていなかったり、決まった寸法で大量に掲示物を作ろうとしたときにうまくいかないといった不便さがあります。Microsoft 365 (旧Office 365)を導入していればほぼ使えるだろうPublisherを使って、このようなケースに対応してみましょう。

このページでは、レイアウトを揃えて、内容が異なる印刷物を作る例を紹介します。QRコードのような画像も入れ替えながら印刷できます。

Publisherの基本的な使い方

Publisherは印刷に適したソフトである一方でWordやExcel、PowerPointのように詳細な解説本がないというデメリットがあります。とはいっても、WordやPowerPointを使ったことがあれば直感的に操作できるようなソフトなので、ヘルプを読みながら、いろいろと自分で試してみるといいでしょう。ここでは、基本的な使い方を紹介します。

テンプレートから用紙サイズを選んでみましょう。Publisherを起動した画面で、新規>その他の白紙のページサイズを選びます。

次に、「宛名ラベル」から「30枚/ページ」を選んでみましょう。このとき、幅6.668 cm高さ2.54 cmの用紙サイズが設定されます。もちろん、目的にあったほかの用紙サイズを設定していただいて結構です。

用紙サイズを選択すると、いよいよ編集の開始です。指定した用紙サイズの白紙が表示されます。よく見ると、縦軸と横軸にcmの寸法が表示されていることに気づくでしょう。このように、PC上で作成したレイアウトが印刷したときにどのような大きさになるかを確認しながらレイアウト作成をできるのがPublisherの強みです。

Publisherで白紙が表示されたところ

このあとの操作はWordとPowerPointを合わせたようなものです。画面上部のメニューで「挿入」を選ぶと、PowerPointと同じように「テキストボックス」や「図形」といった選択肢があります。ほとんど同じように使えます。

Publisherの挿入メニュー

まずは共通する部分のレイアウトを作成してみましょう。PowerPointと同じと思って操作すれば大丈夫です。たとえば、下図のように共通部分を作ってみました。

Publihserの「差し込み印刷」機能を使おう

印刷レイアウトとは別に、予めExcelで差し込み印刷に使うデータを用意しておきます。データはExcelファイルで作成するのが便利です。1行目に何のデータを入れるのか書き、2行目以降に差し込み印刷に使いたいデータを入れていきます。このとき、実際にはあとで使用しないデータ列が入っていても問題ありません。

例として、次の図のようなExcelファイルを作りました。A列にはページタイトル、C列にはページのURLを書き込んでいます。D列には、C列のURLをQRコードにした画像のファイル名を書いています。同じ行に書き込まれたデータをセットとして、対応する項目を書き換えた印刷物が出力されるわけです。

差込データの身中身

画像ファイルは、上図のExcelファイルと同じフォルダに格納しておきます。フォルダの中は下図のようになります。

差込データと画像の入ったフォルダ

差し込みデータの準備ができたら、Publihserの方でデータを読み込みます。「差し込み文書」タブを開いて、「宛先の選択」をクリックします。すると下図のようなメニューが出てきますので、「既存のリストを使用」をクリックします。

「データファイルの選択」を求められますので、先ほど作成したExcelファイル (差し込みデータと画像.xlsx)を選択します。Excelファイルを選択すると、Excelファイルの中のどのシートを使うか問われます。ここではSheet1しかないので、これを使います。ここで「先頭行をタイトル行として使用する」にチェックが入っていると、データを選ぶ際に便利です。

差し込みデータの読み込み画面その11

PublisherがExcelファイルを読み込んで、読み込んだデータセットの対応が正しいかを確認する画面が出ます。ここで「アドレス帳」という言葉が使われるのは、もともと差し込み印刷の機能が手紙の宛名を印刷するのによく使われていたことの名残です。まったく意味はないので気になさらずに。

差し込みデータの読み込み画面その2

データの読み込みが終わると、レイアウトに差し込みデータを挿入できるようになります。「差し込みフィールドの挿入」を押すと、差込データのタイトル行に書かれた文言が表示されます。ここで「ページタイトル」を選択すれば、印刷時に「ページタイトル」の中身が表示される場所(フィールド)をレイアウトに挿入できます。

差し込みフィールドの挿入

画像を挿入する場合は、「画像」から差し込みデータで画像のファイル名をタイトル行に書いた「QRコード画像」を選択します。

差込画像の挿入

実際に差込フィールドを入れたの次の図です。「<<ページタイトル>>」と書かれた部分に、差込データの「ページタイトル」列のデータが入ります。差し込み文書は、通常のテキストボックスと同じように、それぞれ文字の大きさやフォントなどを設定することができます。画像の差し込みでは、画像アイコンが表示されていることを確認してください。画像アイコンになっていない場合、文字として挿入されている可能性があります。

sささsさし差込データ差込データ差し込みフィールドを含んだレイアウト

これで準備完了です。「完了と差し込み」をクリックして、「プリンターに差し込み」を選択してください。

完了と差し込み

印刷画面が表示されます。「用紙1枚に複数ページ」の設定で印刷プレビューをした場合には、次のように表示されます。差込データに対応して、文書と画像が書き換わっていることがわかるでしょう。この画面から印刷するなり、PDFに保存するなりすれば、レイアウトの揃った状態で内容を変えた印刷物を出力することができます。

差し込み印刷のプレビュー

QRコードの画像を用意する

QRコードの作成はフリーソフトなりWEBサービスなりで前もってやっておきます。あまり凝ったレイアウトを必要としない場合はWordの差し込み印刷機能にあるバーコード機能を使う手もあります。Wordのバーコード機能を使えばQRコードの画像を別に用意しなくていいので楽です。WordではQRコードの大きさ指定やレイアウトが若干使いづらい点は注意が必要です。フリーソフトではQRコードジェネレータ – QRコード一括作成ソフトが使えそう。ExcelシートからQRコードを大量生成するではExcelファイルをアップロードするとQRコードを作ってくれます。Pythonを使える方は、このページのコードをローカルで実行するのが便利でしょう。

現場でデジタルトランスフォーメーションを進めるための資料

以前から効率化が叫ばれて久しいところコロナ禍の到来によって業務のデジタル化が待ったなしの状況です。しかし、どのような考え方で、どんな手法を使って、身の回りの環境を変えていけばいいのか、そこにはどんな困難が生じやすいのか、知識がないところから気合だけ振り絞っても空回りしてしまいます。本稿では、現場からデジタルトランスフォーメーションの機運を上げるために役に立ちそうな資料をまとめます。

書籍

書籍は情報が整理された宝箱です。出版されているだけで権威付けもされて、まじめに読んでみようという気にさせてくれます。

組織を動かす

使いやすい仕組みをつくる

  • UI/UXデザインの原則
    デジタル化はそれ自体が目的ではなく、コンピュータの力を借りて、簡単に、速く、確実に業務を遂行できるようにすることが目的です。ヒトとコンピュータが向き合うUser Interface、ヒトが感じるUser Experienceをいかに優れたものにするかを学べます。デザインの考え方は紙の資料でも役に立ちます。

WEB

WEBはリンクから手軽に情報にアクセスできるのが魅力です。無料のサイトなら、必要なのものは時間と前向きな時間だけ。他人に新しいアイデアを紹介するとき、入口として最適です。

まとまりの良いもの

単発記事

[GAS] WEBアプリはフォームの多重送信に注意。特にスマホを使う場合。

Google Apps Script (GAS) はWEBアプリケーションを簡単に作成できるため、改善活動レベルで業務アプリをサクサク構築できます。JavaScript (JS)とHTMLを多少勉強する必要がありますが、業務の自動化を推進する上で強力なツールです。

GASではGET、POSTに対応する処理を行って、対応するHTMLを返すことができます。これをWEBアプリケーションと呼びます。WEBアプリの活用方法として、自作のフォームを使って依頼や連絡、申請の手続きを自動化したいと考える場面もあるでしょう。ここで気を付けたいのが、多重送信の防止です。

WEBアプリを操作する場合、ブラウザの戻る・進むの動作によって、GASに届けたい情報(パラメータ)を送るページを意図せず複数回開いてしまう可能性があります。注文のような1回だけ送りたい情報が何度も送られるようでは混乱を招くので、情報の多重送信を防ぐ仕組みの導入が必要です。
スマホを使う場合は、より多重送信への注意が必要です。PCから操作する場合、余計なタブを閉じたりPCをシャットダウンする際にブラウザも終了されるため、ブラウザの戻る・進むくらいしか意図せずページを開く可能性はありません。ところが、スマホの場合はアプリを終了しない、スマホの電源も切らないで運用されることが多く、多重送信の問題が生じやすい状況です。たとえば、ブラウザのアプリで複数のタブを開いた状態でスマホのホームボタンを押してもアプリが終了されるわけではありません。再度アプリを開いた時点でタブに残っていたページにブラウザがアクセスしようとして、前回アクセスしたときと同じリクエストを出してしまいます。

GETリクエストではURLにパラメータを含むので、同じURLにアクセスすれば同じパラメータが送信されます。別のURLに遷移させない限り、同じURLにアクセスするのを防がないと多重送信が生じます。

POSTリクエストでは、送信されるパラメータがURLに含まれないので、最後に表示されているのがPOSTリクエストへ応答してGASが生成したHTMLだということを忘れてしまうかもしれません。ブラウザ側はPOSTリクエストを覚えていて、再度その画面を開いたときにPOSTリクエストを再送してしまいます。PCでChromeなどブラウザを使っていると戻る・進むによってPOSTリクエストを送る場合に警告が出る場合がありますが、前述したスマホのタブでは警告もなくPOSTリクエストが再送されてしまいます。

多重送信の対策方法は、さいきょうの二重サブミット対策など様々な場所でまとめられています。
まず検討したいのが、GASが受け取るリクエストが過去のリクエストと同一でないか確認できる機構(トークンチェック)を組み込むことです。簡単には、フォームを含むページにアクセスしたときにトークンを発行し、formのhiddenにした要素を使ってほかの回答と一緒にトークンが送信されるようにします。送信されたトークンを過去のトークン(どこかに貯めておく)と比較して、過去に同じトークンを持った回答が送信されていない場合に次の処理に進むようにすれば、多重送信を弾けます。
トークンチェックで多重送信を検知したときに、安易にエラーページを表示するのはかえって危険です。ユーザーが送信に失敗したと思って、最初からフォームの送信作業をやり直すかもしれません。これは正規な手続きなので内容が同じであっても多重送信ではないためシステム側で検出することはできません。トークンチェックで多重送信を検出した場合は、あたかも送信に成功したかのように見せておくとユーザーの勘違いを防げます。

このほかに、フォームの送信ボタンを画面が更新される何度も押すという形の多重送信もあります。この場合はJavaScriptでフォームのボタンを無効にすることで、ボタンを複数回押せなくする方法で対策できます。formタグにonSubmitで回答送信ボタンがdisableになるJavaScriptを仕込むことで実現できます。

[GAS]WEBアプリケーションの見た目を整える

GASでWEBアプリケーションを作れるようになると、さまざまなシーンで電子化・自動化を進められます。よりたくさんの人に使いやすいと感じてもらうためには、多少の工夫が必要です。HTMLの知識があれば、見た目のよい、ぱっと見てわかりやすいWEBアプリケーションを作成することができるでしょう。

WEBページの見た目を改善するのには、HTMLと組み合わせて使われるCSSの作例を調べるのが簡単です。以下にすぐ使えるページを紹介します。

[GAS] Googleドキュメントの途中にパラグラフを挿入する

基準点となる文字列を含んだパラグラフの次に新しいパラグラフを挿入する方法を考えます。新しいパラグラフの中身はダイアログボックスで入力した文字列とします。

function myFunction() {
  var body = DocumentApp.getActiveDocument().getBody();
  
  var paragraphs = body.getParagraphs();
  
  for (var i = 0; i < paragraphs.length; i++) {
    var paragraph = paragraphs[i];
    var index = i;
    var text = paragraph.getText();
    if(text === 'key paragraph'){
      Logger.log('index %s text %s', index, text);
      var child = paragraph;
    }
  }
  
  var childIndex = body.getChildIndex(child);
  Logger.log('childIndex %s', childIndex);
  
  //input text to insert
  var ui = DocumentApp.getUi();
  var response = ui.prompt( '挿入する文字列を記入する。', ui.ButtonSet.OK_CANCEL);
  
  // Process the user's response.
  var button = response.getSelectedButton();
  var textToInsert = response.getResponseText();
  //キャンセルならスクリプト終了
  if (button !== ui.Button.OK) {
    return;
  }
  
  //insertParagraph
  body.insertParagraph(childIndex + 1, textToInsert);
}

//メニューを追加
function onOpen(e) {
  DocumentApp.getUi()
      .createMenu('GAS')
      .addItem('insert paragraph', 'myFunction')
      .addToUi();
}


まず、DocumentAppでBodyとその下のparagraphsを取ってきます。各paragraphの中の文字列はgetText()で取れるので、基準点となる文字列が含まれるparagraphを探します。上の例では、paragraphの文字列が「key paragraph」であるという条件で該当するparagraphを指定しました。

基準点となるparagraphオブジェクトが見つかったら、body.getChildIndex(paragraph)のように引数として渡してやると、bodyに対するchildIndexが返ってきます。

基準となるparagraphの childIndexが求まったら、そのparagraphの前に挿入する場合は childIndex を、そのparagraphの後ろに挿入する場合はchildIndex+1を、insertParagraphの引数に渡します。

挿入する文字列を入力するのに使ったダイアログボックスですが、V8エンジンではBrowser.inputbox()が動かないのか、UI.prompt()を使うと動きました。UI.prompt()は返ってきたresponseにさらにgetResponseText()しないとテキストが取れません。

ドキュメントのメニューからスクリプトを動作せさせる工程はGoogle Apps Scriptを使った独自メニューの作り方を参照しました。

テンプレートを別ファイルで用意する場合はGoogle Apps Scriptで議事録テンプレ作成を楽にしたが参考になります。

真の働き方改革 楽をしよう!

私は戦前から続く古びた会社で研究開発の業務に携わりながら、身の回りの業務効率向上―いわゆる働き方改革に取り組んでいます。同僚の多くは真面目で根気よく働くのですが、それゆえに抜本的に働き方、仕事のやり方を変えるという思考には至らないように見えます。たとえば、生産性を上げるためにどのような取り組みをするのかを議論すると、「よく考える」「がんばる」といった精神論レベルのアイデアしか出てこないのが現実です。本稿では、そのような勤勉な方々に向けて、大幅に生産性を向上させるための考え方を提示することを目指しています。

まず、楽をしよう。そして、浮いた時間で新しいことをしよう。

生産性を上げるとは、ある一定の時間に出せる成果の量を増やすことと言い換えられます。つまり、同じ仕事を短時間で処理できれば、生産性が上がったといえます。そこで、頑張って、あるいは気合を入れて、集中して仕事に取り組くことで、ひとつの仕事をいつもより短時間で終わらせることができたとします。ちょっと疲れていませんか?そのペースで一日中働けますか?時間やお金が有限なように、人間の体力や集中力も有限です。気合いを入れて、多くの体力や集中力をひとつの仕事に費やしてしまえば、あとの仕事に支障がでます。一日あるいは一週間というまとまった時間を振り返ってたときに、本当に成果の量は増えるでしょうか。

たとえ話として、走って移動する状況をイメージしてください。普段より気合いを入れて仕事にあたるのは、ジョギングのペースはなくダッシュのペースで走るようなものです。短距離走のペースで長距離走の距離を走ることはできません。長距離を走ろうと思えば、平均的な速度は遅くなります。そこで、別の方法を考える必要が出てきます。別の方法があるのかを考えるときに重要なのが、本来の目的です。もし走ることが目的ではなくて、何かを届けるのが目的なのであれば、駅伝にしてしまえばいい。一人当たりの走る距離を短くすれば速度は上がり、より早く遠くまでタスキを届けられるでしょう。ところで、どうして自分の足で走っているのでしょうか。自転車、自動車、電車、飛行機。 何かを届けるのが目的なら、 自力で走るという条件を外せば、桁違いに速く遠くまで行ける方法があります。冒頭、私が走って移動する状況をイメージしてくださいと書きました。親切なのか無知なのか、仕事の目的ではなく手段を具体的に説明するだけの人はけっこういます。あなたの上司もそんな指示の仕方をしていませんか。

いま取り組んでいる仕事の目的は何でしょうか。おそらく、やり慣れた仕事であれば、どのような成果物が必要なのかを把握されていることでしょう。そこで考えてください。今までのやり方をどのように変えれば、同じ成果物を楽に生み出せるかを。楽にできるということは、より短時間で、体力も集中力も消費せず、ひょっとするとお金もかけずに成果を上げるということです。そのためには、前の段落でたとえ話をしたように、本来の目的以外の前提条件を外して考えることをお勧めします。

楽に成果を上げられるようになったら、時間も体力も余裕ができますね。その浮いた時間で、新しいことをするのが生産性向上です。体力を削って時間を生んでも、あとで帳尻合わせが来ます。時間も体力も消費せずに、同じ成果を上げましょう。

人が手を動かさなくても成果が得られる仕組みをつくろう。

楽に成果を上げるなんて言うは易く行うは難しでは?はい、その通り。簡単ではありません。だから私はこの文章を書いているのです。簡単だったら、みなさんすでにやっておられるでしょう。

楽に成果を上げるのには、3つの方針があります。消す、方法を変える、道具を使うの3つです。

まず、仕事を「消す」ことを考えましょう。昔から続けているというだけで、何の役にも立たない仕事は消す価値があります。やめたら誰かに迷惑がかかるかもしれない?では、その迷惑がかかるかもしれない相手に聞いてみましょう。もし必要ないと言われれば、正々堂々と止めることができます。もし完全に止めることができなくても、ほかの仕事と共通化できれば、2あった仕事を1に減らせます。仕事を消すには関係者との交渉や確認が面倒くさいのですが、その苦労してでもやる価値があります。なんといっても、その仕事、消してしまえば金輪際やらなくていいんですよ。

次に考えるのは、仕事の「方法を変える」ことです。流れを変えるともいえるでしょう。たとえば、予め準備をしておくことを考えます。準備のない状態で問い合わせや指示が来て業務がスタートすると、その場で内容を確認し、適切な対処方法を調べたり考えたり、関連するルールとの整合性を検討したりといった多数の作業に取り掛かります。類似事例の経験があっても、昔のことで詳細は記憶に残っていないかもしれませんし、当時と現在ではルール変更など状況変化があるかもしれません。そのうえ納期はなるべく早くと言われたら、時間のない中でストレスを感じつつ、どうにかそれらしい答えを紡ぎだす羽目になります。そうならないための準備をしましょう。ある程度の経験があれば、業務のパターンが見えてきます。パターンごとに先方に確認すべき事項のリストを作ったり、過去事例をまとめた資料をつくったり、関連する規制情報をすぐに参照できるよう確認手段を明確にしておくといった準備ができるはずです。今の時代、たいていの情報はWEBや共有ネットワーク上に電子データで存在しますから、Wordで資料をつくって外部リソースへリンクを張っておけば、数クリックで必要な情報が集まるようにできます。さらに、電子データで準備をしておけば、容易に使いまわしができます。問い合わせてを受けて、調べて回答するまで数分から数時間かかっていたような業務が、準備資料を検索してコピーするだけのわずか数秒で解決できるようにできます。成果を使いまわせる点は重要です。むしろ、使いまわす前提で資料をまとめましょう。個別の案件にその都度対応していては、結局人間の手間がかかります。そこで、別件のための生み出した成果を使いまわすことを考えましょう。うまくいけば、インプットなしで成果を出せます。

最後に、仕事に「道具を使う」ことを考えましょう。人力で走るより車に乗った方が楽なのは言うまでもありません。車がコスト的に難しいなら、自転車でも人力よりずっとマシでしょう。今日の仕事の大部分である事務仕事にとって、Microsoft OfficeのWordやExcelあるいはG Suite (Google) のドキュメントやスプレッドシートは自転車と同じくらい当たり前の存在です。特に、事務仕事でExcelやスプレッドシートを開かない日はないほどです。これらのソフトウェアは、自転車以上に使うものの技量が問われます。SUM関数やグラフの挿入、罫線の修飾は誰でも使えるかもしれませんが、VLOOKUP関数やデータの並べ替え、データ分析に至っては10人に1人も使えるか怪しいところです。単純な道具の代表であるハサミでも使いようによっては繊細な紙細工を生み出せます。現代のコンピュータ技術の粋を集めて作られたExcelのようなソフトウェアを使いこなせたなら、どれほどのことができるか言うまでもないでしょう。多くの職場には、そんな便利な道具がすでに導入されているのですから、うまく使えるようになれば劇的に事務作業が楽になります。
もっと楽をしたいなら、プログラミングに挑戦しましょう。Officeソフトの使いこなしが自転車レベルとしたら、プログラミングは自動車レベルです。段違いの楽ができます。MS OfficeならVBA、G SuiteならGASというプログラムを自分で作ることで、ほとんどの作業は自動化できます。巷には何冊も書籍が出ていますし、ネット上を検索すれば参考になる情報がいくらでも出てきます。

最後に、他人を動かすのは北風ではなく太陽であることを忘れないで。

ここまで頑張ってきたあなたは、効率化の施策もろもろを組織全体に広げたいと考えることでしょう。ひたすらに前例踏襲に励み、ちっとも業務を効率化しようとしない同僚に苛立ちすら覚えているかもしれません。そこで、思い出していただきたいのが、北風と太陽の寓話です。人は激しい重圧に曝されると身を守る行動にでます。叱責や非難は、行動を変容させるための良い手段ではありません。他人の行動を変えるには、太陽のように温かい心で優しく手を差し伸べることが近道です。

自分ひとりで効率化を進めてきたあなたにとっては納得しがたいことかもしれません。大して努力しようとしない他人のために、なぜ自分が苦労しなければならないのかと。ここで思い出していただきたいのが、あなた自身がここまで来るのに積み重ねた努力と苦労の大きさです。それを他人にも強いるのですか?全ての人類が自分自身の成長を常に望んでいるわけではありませんよね。

自分の業務を効率化して多少の余裕がある。同僚にも役立つ効率化の具体的な手法と効果を知っている。そんな立場だからこそ、最小の労力で同僚の業務を効率化する提案ができるはずです。人間なんて現金なものですから、自分が労せずして楽をできると知れば、こちらの話に乗ってくれる可能性が高くなります。少し頑張るだけで楽をできるなら、自分も工夫してみようと考える仲間が現れるかもしれません。

まず、楽をしよう。次に、他人を楽させよう。そして、働きやすい環境を実現しよう。