Quantcast
Channel: いつも隣にITのお仕事
Viewing all 2091 articles
Browse latest View live

Google Apps Scriptでチャットワークにタスクを追加する最も簡単なプログラム

$
0
0

task

みなさん、こんにちは!
タカハシ(@ntakahashi0505)です。

Google Apps Scriptからチャットワークを操作する様々なプログラムを作っています。

名言botを作ったり

Google Apps Scriptでチャットワークの名言botを作る方法
初心者向けGoogle Apps Scriptでチャットワークを操作するシリーズです。今回はスプレッドシートの操作、イベントトリガーなどの設定を利用してチャットワークのbotを作る方法についてです。

チャットワークでおみくじが引けるプログラムを作ってみたり。

Google Apps Scriptで乱数を使っておみくじプログラムを作る
今回はGoogle Apps Scriptで乱数を使用しておみくじを作る方法についてお伝えしていきます。乱数の発生、小数点の切り捨て、配列の要素数を求めるなど、あちこちで使えるテクニックが満載ですよ!

色々なツールが考えられるのですが、インターフェースがチャットなので誰もが扱いやすいものになりますよね。

さて、他のメッセージサービスにはないチャットワークの大きな特長としてタスク機能があります。

毎日や毎月など、定期的に発生するタスクも自動で追加できたら楽ちんできますよね。

ということで、今回から何回かにわたってチャットワークに自動でタスクを追加するプログラムの作成を目標に進めていきたいと思います。

初回の今回は、Google Apps Scriptでチャットワークにタスクを追加する最も簡単なプログラムを紹介します。

では、行ってみましょう!

チャットワークで特定のグループチャットにタスクを追加する

今回はタスク追加の最も簡単なパターンということで

  • マイチャットで
  • 自分自身に
  • 「牛乳を買う」というタスクを追加する

というプログラムを作っていきます。

チャットワークAPIのドキュメントによるとタスクの追加に関するリクエストについて

POST /rooms/{room_id}/tasks
チャットに新しいタスクを追加

body(必須):タスクの内容
limit:タスクの期限(※Unix timeで入力してください)
to_ids(必須):担当者のアカウントID(※担当者のアカウントIDをカンマ区切りで)

とあります。

パラメータが3つもあります。

HTTPメソッドが「post」の場合、payloadというパラメータで連想配列として渡してあげる必要がありました。

この辺は以下記事で紹介をしています。

Google Apps Scriptでチャットワーク上におみくじチャットを作る
Google Apps ScriptとチャットワークAPIを使ってチャットワークで「おみくじ」と送信すると、大吉から凶までのおみくじの結果を生成してチャットワークに返す「おみくじチャット」を作成します。

ひとまず今回は必須であるタスクの内容のbodyと担当者のアカウントIDのto_idsだけを考えます。limitについては別記事で紹介します。

リクエストURLは

https://api.chatwork.com/v1/rooms/{room_id}/tasks

です。

タスクを追加する場合に必要な要素は

  • room_id:タスクを追加するルームID
  • body:タスクの内容
  • to_ids:担当者のアカウントID

が必要となります。

アカウントIDの取得

アカウントIDは調べる必要がありますね。

最も簡単に調べる方法は、チャットワークでアカウントIDを調べたいユーザーに対してToをつけて送信したメッセージの「編集」をしてみることです。

例えば、私自身にあてたメッセージですが「編集」をクリックすると

チャットワークでメッセージを編集

メッセージ入力欄に

[To:XXXXXX]高橋 宣成さん[info]おみくじの結果:凶[/info]

と表示されます。

チャットワークのメッセージ編集でアカウントIDを取得

この「To:」の後に続く数字列がアカウントIDです。

タスクを追加するスクリプト

チャットワークにタスクを追加するスクリプトはこちらになります。

function addTestTask() {

  var token = 'APIトークン'; //チャットワークAPIトークン
  var room_id = XXXXXXXX; //ルームID

  var params = {
    headers : {"X-ChatWorkToken" : token}, //APIトークン
    method : "post",
    payload : {
      body : "ミルクを買う", //タスクの内容
      to_ids : XXXXXX //アカウントID
    }
  };
  var url = "https://api.chatwork.com/v1/rooms/" + room_id + "/tasks";
  UrlFetchApp.fetch(url, params); //チャットワークAPIにリクエスト

}

UrlFetchApp.fetchで渡すparamsの作りさえ押さえてしまえば、全く難しいところはありませんね。

実行結果

上記スクリプトを実行してみますと

GASでチャットワークにタスクを追加した

このようにタスクが追加されます。バッチリですね。

まとめ

Google Apps Scriptでチャットワークにタスクを追加する最も簡単なスクリプトについてお伝えしました。

今回はタスクの期限を設定するパラメータlimitに関して触れなかったので、その点に触れつつ、本シリーズの目標である定期的なタスクを自動追加する方法についてお伝えしていきたいと思います。

どうぞお楽しみに!


Google Apps Scriptのスプレッドシート読み書きを格段に高速化をする方法

$
0
0

speedup

みなさん、こんにちは!
タカハシ(@ntakahashi0505)です。

Google Apps Scriptでスプレッドシートの操作をしていて、こう感じたことはありませんか?

実行速度が遅い…遅いぞ!

スプレッドシートへの読み書きが多いと、どうやらすごく遅くなってしまいます。

エクセルVBAの場合は画面表示の更新を停止するなどをして高速化をすることができましたが

遅い…重い…そんなエクセルVBAプログラムの処理速度を劇的に改善する方法
エクセルVBAの実行速度が遅い・重いって時ありませんか?そんな時にエクセルVBAのプログラムの処理速度を速くするテクニックを紹介します。プログラムの実行時間を測定する方法も合わせてお伝えします。

Google Apps Scriptの場合はどうすれば良いでしょうか…?

今回はGoogle Apps Scriptでスプレッドシートを操作する場合に処理速度を格段に速くする方法をお伝えしていきます。

どれくらい遅いか?

例えば、以前紹介しましたこちらの記事のスクリプト。

【GAS】名刺管理アプリの出力データを活用してメルマガ配信リストを自動更新する
Google Apps Scriptでメルマガ配信システムを作りました。今回はスプレッドシートにインポートした名刺管理アプリのデータを使ってメルマガ配信リストを自動更新する方法を紹介いていきます。

名刺管理サービスCAMCARDから出力した連絡先リストを取り込んで、メルマガ配信リストを更新するものです。

このスプリプトに時間を測定する処理をちょちょっと追加します。

function inportContacts(){
  var start = new Date();
     // 処理
  var end = new Date();
  var span_sec = (end - start)/1000;
  Logger.log("処理時間は " + span_sec + " 秒でした" );
}

例えばCAMCARDのデータが50行あったとして、測定しながら実行してみますと

メルマガリスト更新のGoogle Apps Scriptの実行速度を測定

このように約42秒もかかります。

これが500件、5000件となったら…ちょっと実用に耐えないですよね。

今回はこの課題を解決していきます。

APIの呼び出し回数が多いと遅くなる

なぜこのスクリプトが遅いか?ということなのですが、ヒントはAPIの呼び出し回数にあります。

ここで言うAPIは他でもないSpreadsheetAppです。

つまり

  • getActiveSpreadsheet()
  • getSheetByName()
  • getDataRange()
  • getLastRow()
  • getRange()
  • getValue()
  • setValue()

などを使ってスプレッドシートにアクセスをするたびにAPIが呼び出されています。

ですから例えば

if(sheetAddress.getRange(ai,4).getValue() === sheetContacts.getRange(ci,9).getValue()){
     // 処理
}

このifの条件比較には一気に4つのAPI呼び出しがあります。これが入れ子状態のfor文の繰り返しの処理に含まれていていたら…Google Apps Script的にはたまったもんじゃないわけです。

お題:シート範囲を別シートにコピーする

今回はこのようなお題を使ってスプレッドシートを扱うGoogle Apps Scriptの高速化の方法をお伝えしていきます。

まずシート1にこのようなデータを用意します。

Google Apps Script高速化検証用シート

ランダムの数値が横3列×縦50行分並んでいまして、見出しを入れると全部で51行です。

これをシート2にコピーしたいと思います。

高速化を考えない場合はこのようなスクリプトになります。

function speedUp() {
  var mySS=SpreadsheetApp.getActiveSpreadsheet(); //スプレッドシートを取得

  /* シート1とシート2の準備 */
  var sheet1=mySS.getSheetByName("シート1");
  var row1=sheet1.getDataRange().getLastRow();

  var sheet2=mySS.getSheetByName("シート2");

  for(var i=1;i<=row1;i++){
    for(var j=1;j<=3;j++){
      sheet2.getRange(i,j).setValue(sheet1.getRange(i,j).getValue());
    }
  }
}

わかりやすさのために実行時間測定の部分は省いています。

さて、このスプリプトを実行してみますと

高速化対応前のGoogle Apps Script実行時間

21.8秒もかかっていますね。

API呼び出しが多いところを確認する

遅くなる原因でいうとスプレッドシートのAPI呼び出し回数ということになります。

前半の2~8行でシート1やシート2の準備で合計4回のAPI呼び出しがありますが、なんといっても12行目ですね。

入れ子になっている二つのfor文の中に、たったの一行で4つもAPIを呼び出すメソッドが含まれています。

行数が51、列数が3、読み書きのAPI呼び出しが1周あたり4回ですから、全部で612回のAPI呼び出しが発生していることになります。

セル一つ一つに対して読み書きをするメソッドであるgetValueやsetValueを何も考えずに使いまくると必然的に遅くなってしまうということになります。

APIリクエストを減らす方法

セル一つ一つに読み書きをすると遅くなるということですから、例えばデータのある範囲全体を一気に読み書きしたらよいのではないか?

ということになります。

では、その路線で検証してみましょう。

シート範囲を二次元配列にまとめて読み書きするgetValuesとsetValues

シートの範囲をまとめて読み書きをするgetValues、setValuesというメソッドがあります。

書き方はこちらです。

二次元配列 = Rangeオブジェクト.getValues();
Rangeオブジェクト.setValues(二次元配列);

これを使えばセル一つ一つではなくて、シート範囲のデータをまとめて読んてきたり、まとめて書き出したりすることができますね。

しかしgetValuesで取得した範囲のデータは二次元配列に入り、setValuesでシートに書き出す場合は二次元配列を指定しなければいけません。

getValuesで取得したデータの二次元配列について

二次元配列…ちょっと不慣れな場合もあるかも知れませんね。

今回のシート1を二次元配列var1に格納する場合

var var1=sheet1.getDataRange().getValues();

とします。

このとき、二次元配列はどんな様子になっているかというと

var1[0]=[数字1,数字2,数字3]
var1[1]=[83,47,75];
var1[2]=[43,99,27];
var1[3]=[50,56,41];
var1[4]=[0,64,79];
// 以下続く

とした場合と同じになります。

それぞれの行に対してまず一つ目の配列が用意されて、その中にそれぞれのセルの値が配列で格納されているというわけです。

ここで注意すべき点として、行も列も配列番号は「0」からスタートするということです。

1行目のデータはvar1[0]に格納され、1行目の1列目のセルはvar1[0][0]に格納されます。

getValues、setValuesを使ったスクリプトに修正

では、前述のスクリプトをgetValues、setValuesを使ったスクリプトに書き直してみましょう。

function speedUp() {
  var mySS=SpreadsheetApp.getActiveSpreadsheet(); //スプレッドシートを取得

  /* シート1とシート2の準備 */
  var sheet1=mySS.getSheetByName("シート1");
  var row1=sheet1.getDataRange().getLastRow();
  var var1=sheet1.getDataRange().getValues();

  var sheet2=mySS.getSheetByName("シート2");

  /* 二次元配列をコピー */
  var var2=var1;

  /* シート2に書き出す */
  sheet2.getRange(1,1,row1,3).setValues(var1);
}

…入れ子のfor文だったあたりが、12行目に集約されました。超シンプルなたったの一行になっちゃいましたね。

getRangeで範囲を指定する

15行目のgetRangeですが引数が4つあります。

一つのセルの場所を指定する場合は引数は2つでしたが、getRangeで範囲を表す方法としては、範囲の開始セルの行数、列数とともに、その範囲の行数、列数も指定をします。

getRange(開始セルの行数, 開始セルの列数, 範囲の行数, 範囲の列数)

今回の場合は、開始セルは(1,1)、範囲の行数はシート1の行数、範囲の列数は3になりますので

sheet2.getRange(1,1,row1,3).setValues(var1);

となったわけです。

Google Apps Scriptの高速化の結果

getValues、setValuesを使って高速化をしたスクリプトを実行してみますと

高速化を施したGoogle Apps Scriptの実行時間

0.57秒…!

実行速度はなんと38倍に。メチャメチャ速くなりましたね。

まとめ

Google Apps Scriptでスプレッドシートを操作する際に処理速度を格段に速くする方法についてお伝えしました。

二次元配列の取り扱いは慣れないと少しわかりづらいところもあるかも知れませんが、プログラムの処理速度を考えると絶対に使うべきですよね。

ぜひご活用下さい。

さて、次回ですが、今回の高速化のテクニックを活用してメルマガ配信リストの更新のスクリプトを修正していきたいと思います。

どうぞお楽しみに!

連載目次:Google Apps Scriptでメルマガシステムを作っちゃおう!

  1. 超初心者へGoogleAppsScriptを始めるメリットをこれでもかと説明します
  2. 初心者でも簡単!Google Apps ScriptでGmailを操作してメールを送る方法
  3. 初心者でも簡単!Google Apps Scriptでドキュメントを取得して表示する方法
  4. Google Apps Scriptでスプレッドシートのリストをもとに宛名を差し込んだメール本文を作る
  5. たったの38行!Google Apps Scriptで超簡易メルマガ配信システム
  6. 名刺管理アプリCAMCARDの連絡先リストをスプレッドシートに取り込む
  7. 【GAS】名刺管理アプリの出力データを活用してメルマガ配信リストを自動更新する
  8. Google Apps Scriptのスプレッドシート読み書きを格段に高速化をする方法

エクセルVBAでWordPress投稿用HTMLソースを自動で生成する

$
0
0

みなさん、こんにちは!
タカハシ(@ntakahashi0505)です。

ほら、企業向けサイトってブログサイトに比べて、デザインやレイアウトを色々したいことが多いじゃないですか。

ですから、企業向けサイトを作る場合Bootstrapを使うととっても便利です。

例えば、ちょちょっとクラスを追加するだけで

  • グリッドシステムで画面サイズに合わせたレスポンシブサイト&カラム分けが実現可能
  • デザインされたボタンの設置が簡単
  • スマートなテーブルの作成
  • メインイメージをかっこよく作れるジャンボトロン

などなどが実現可能です。

Boostrapの概要や使い方などは、くろゆきさん寄稿の以下の記事もご覧ください。

CSS初心者の強い味方!Bootstrapで簡単レスポンシブサイト制作
CSS初心者でもレスポンシブサイトが作れる!導入がややこしいBootstrapの設定を最小の記述で終わらせて実践方式で触ってみましょう!今回は導入前の予備知識の解説です。

ただし、Bootstrapでレイアウトを色々やるとWordPressで作る場合でもテキストエディタで結構なコーディングが必要になってきて、ちょっと面倒です。

ということで、今回から何回かにかけて、Bootstrapを使ったトップページのソースをエクセルVBAで自動生成する方法についてお伝えします。

エクセルに必要事項を入力すれば、それを元にコーディングしたソースを吐き出してくれる、といったものです。

初回の今回ですが、エクセルの入力情報をもとにシングルページの1つのセクションについて自動でコード生成をしてみたいと思います。

では、行ってみましょう!

BootstrapベースのHTMLコードはコーディングが面倒

弊社プランノーツのサイトもWordPressで作成しておりまして、テーマはBootstrapベースのHabakiriを使わせて頂いています。

トップページは、上部にメインイメージをスライドショーでドカン!と出しつつ、サービスやプラン、会社概要などを縦長の1ページで見せる、いわゆるシングルページの形式です。

でも、そんなに色々やると、たとえWordPressとはいえけっこうなコーディングが必要になります。

固定ページの編集画面を見てもらうと

企業サイトのトップページのWordPressソース

ほら、バリバリコーディングが必要ですよね?

WordPressのテキストエディタはインデントも利かないし、カラム組みするときはdivタグいっぱいになりますから、コーディング作業も大変ですし、わけがわからなくなります。

例えば、最初の「service」のセクションですが

プランノーツサイトのserviceセクション

画像とボタンは横に置いておくと、情報としてはこんなもんしかないんです。

プランノーツサイトのserviceセクションのテキスト情報

カラム数などが決まっていればコーディングは一意に決まります。

ということで、このエクセル表からソースコードを自動で作ってしまいたいと思います。

エクセルシートからトップページ用HTMLを生成するVBAプログラム

上記エクセルのシートからトップページ用のHTMLを生成するVBAプログラムはこちらです。

Sub createTopHTML()

Dim strHTML As String

Dim ws As Worksheet
For Each ws In ThisWorkbook.Worksheets

    Select Case ws.Name

        Case "service"

            strHTML = strHTML & createServiceSection(ws)

        Case "plan"

        Case "about"

    End Select

Next ws

Debug.Print strHTML

End Sub

こちらがメインのプロシージャです。今はシート名がserviceの場合の処理しかありませんが、おいおい他のセクション用のシートの処理も追加していきます。

最後に生成されたHTMLをイミディエイトウィンドウに出力します。

serviceセクションのHTMLを生成する関数

serviceセクションのHTMLを生成する処理は以下の関数にて実現しています。

Function createServiceSection(ByVal ws As Object) As String

Dim str As String

'section開始タグ
str = str & "<section id=""service"" class=""section"">" & vbCr

'***** セクションタイトルB1,セクション概要B2 *****
str = str & vbTab & _
        "<h1 class=""section-title"">" & ws.Range("B1").Value & _
        "<p class=""small"">" & ws.Range("B2").Value & "</p></h1>" & vbCr

'***** カラム *****
'class="row"の開始タグ

str = str & vbTab & "<div class=""row"">" & vbCr

Dim i As Long
For i = 5 To 8 '4カラム分繰り返し

    'class="col-sm-x"の開始タグ
    str = str & vbTab & vbTab & "<div class=""col-sm-3"">" & vbCr

    'タイトルB列
    str = str & vbTab & vbTab & vbTab & "<h2 class=""h4 text-center"">" & ws.Cells(i, 2).Value & "</h2>" & vbCr

    'サムネイル画像(枠のみ)
    str = str & vbTab & vbTab & vbTab & "<div class=""thum""><img src=""http://placehold.it/300x225"" /></div>" & vbCr

    'テキストC列
    str = str & vbTab & vbTab & vbTab & "" & ws.Cells(i, 3).Value & "</p>" & vbCr

    'class="col-sm-x"の閉じタグ
    str = str & vbTab & vbTab & "</div>" & vbCr

Next i

'class="row"の閉じタグ
str = str & vbTab & "</div>" & vbCr

'section閉じタグ
str = str & "</section><!-- service -->" & vbCr

createServiceSection = str

End Function

…なかなか大変ですね。ただFor~Nextが使えますしプログラムとして再利用可能ですから、ベタ打ちするよりはマシでしょう。

実際にはタブコードのvbTabや改行コードのvbCrはいらないのですが、インデントや改行がないと後でWordPressに貼り付けたときに可読性が低くなってしまうので、ここで頑張って入れておいたほうが良いです。

画像はWordPressで差し込んでいくことになりますので、今はPLACEHOLD.ITというサービスを利用して仮置きです。

imgタグのsrcを縦横サイズを指定して「http://placehold.it/300×225」などとすると、このサイズの仮の画像を差し込んでくれます。

実行してHTMLを生成して表示確認をする

Sub createTopHTML()を実行しますと以下のようにイミディエイトウィンドウにHTMLソースが出力されます。

エクセルVBAで生成したHTMLソース

このソースをコピーして、WordPressのテスト用固定ページをテンプレート「Blank Page」で用意してテキストエディタに貼り付けます。

自動生成したソースをWordPressに貼り付ける

プレビューで表示してみますと

自動生成したHTMLソースのプレビュー

バッチリ思った通りに表示されていますね。

まとめ

まず手始めではありますが、エクセル上のデータをもとにserviceセクションのHTMLソースを生成する方法についてお伝えしました。

弊社のサイトでは、他のセクションとして商品を紹介するplanセクションと、会社概要を記載するaboutセクションがありますので、次回以降これらのセクションに対応したVBAプログラムを作成したいと思います。

どうぞお楽しみに!

Google Apps Scriptでチャットワークに期限付きのタスクを追加する

$
0
0

みなさん、こんにちは!
タカハシ(@ntakahashi0505)です。

引き続きGoogle Apps Scriptでチャットワークに自動でタスクを追加するプログラムについて研究しております。

前回はこちらの記事。

Google Apps Scriptでチャットワークにタスクを追加する最も簡単なプログラム
チャットワークの大きな特徴であるタスク機能がもAPIを使って操作することができます。今回はGoogle Apps Scriptでチャットワークにタスクを追加する最も簡単なプログラムを紹介します。

チャットワークにタスクを追加する最も簡単なパターンについてお伝えしました。

ですが前回追加されたタスク…

GASでチャットワークにタスクを追加した

ちょっと寂しいですね。

そう、タスク期限がついていませんね。

期限がないといつまで経ってもやらなくなっちゃうこともありますから、ちゃんと期限を設定できるようにしておきたいものです。

ということで、今回はGoogle Apps Scriptでチャットワークに期限付きのタスクを追加する方法についてお伝えします。

前回のおさらい

前回は特定のアカウントIDに対して「ミルクを買う」というタスクを追加するスクリプトを作成しました。

作成したスクリプトはこちら。

function addTestTask() {

  var token = 'APIトークン'; //チャットワークAPIトークン
  var room_id = XXXXXXXX; //ルームID

  var params = {
    headers : {"X-ChatWorkToken" : token}, //APIトークン
    method : "post",
    payload : {
      body : "ミルクを買う", //タスクの内容
      to_ids : XXXXXX //アカウントID
    }
  };
  var url = "https://api.chatwork.com/v1/rooms/" + room_id + "/tasks";
  UrlFetchApp.fetch(url, params); //チャットワークAPIにリクエスト

}

HTTPメソッドは「post」で、パラメータpayload内の連想配列として、タスクの内容body、アカウントIDのto_idsを渡す形です。

リクエストURLは

https://api.chatwork.com/v1/rooms/{room_id}/tasks

でした。

チャットワークAPIに期限付きのタスクを追加するためのリクエスト

今回はタスクに期限をつけていきたいと思います。

タスク追加に関するリクエストについて、チャットワークAPIのドキュメントを再度確認してみましょう。

POST /rooms/{room_id}/tasks
チャットに新しいタスクを追加

body(必須):タスクの内容
limit:タスクの期限(※Unix timeで入力してください)
to_ids(必須):担当者のアカウントID(※担当者のアカウントIDをカンマ区切りで)

タスクの期限はlimitというキーでpayload内に渡せばよいですね。

なお、limitのパラメータの型はIntegerになります。

ただ“Unix timeで入力してください”とありますが、どういう意味でしょうか?

UNIX時間とは何か?

UNIX時間とは

UNIX時間(ユニックスじかん)またはUNIX時刻(ユニックスじこく、UNIX time(ユニックスタイム)、POSIX time(ポジックスタイム))とはコンピューターシステム上での時刻表現の一種。UNIXエポック、すなわち協定世界時 (UTC) での1970年1月1日真夜中(午前0時0分0秒)の時刻からの形式的な経過秒数(すなわち、実質的な経過秒数から、その間に挿入された閏秒を引き、削除された閏秒を加えたもの)として表される。
引用:Wikipedia

ということです。んー、わかるようなわからないような…。

つまり、日時の表記の仕方の一つで、1970年からの蓄積された秒数ですから、とっても大きい数字になりそうですね。

getTimeメソッドでUNIX時間を取得する

Google Apps Script(というかJava Script)では、getTimeメソッドで簡単にUNIX時間を取得することができます。

書き方は

Dateオブジェクト.getTime()

となります。

ただしgetTimeメソッドではミリ秒で取得するため、1000倍にして単位を秒に変換する必要があります。

以上を踏まえて作成したスクリプトがこちらです。

function addTestTask() {

  var token = 'APIトークン'; //チャットワークAPIトークン
  var room_id = XXXXXXXX; //ルームID

  var date = new Date(); //今日の日付
  var limit = date.getTime()/1000; //秒単位のUNIX時間を取得 

  var params = {
    headers : {"X-ChatWorkToken" : token}, //APIトークン
    method : "post",
    payload : {
      body : "ミルクを買う", //タスクの内容
      limit : limit, //タスクの期限
      to_ids : XXXXXX //アカウントID
    }
  };
  var url = "https://api.chatwork.com/v1/rooms/" + room_id + "/tasks";
  UrlFetchApp.fetch(url, params); //チャットワークAPIにリクエスト

}

しかしこれを実行すると

チャットワークAPIへのHTTPリクエスト時のエラーメッセージ

このようにエラーとなってしまいます。

どうやらlimtの値がintegerではないと言われているようですね…。

toFixedメソッドで指数表記を固定小数点表記に変換

前述のスクリプトでいうところの18行目、paramsへのパラメータ格納が終わったところにブレークポイントを設置してデバッグをしてみましょう。

ブレークポイントの設置は行数の箇所をクリックします。デバッグは虫マークのアイコンです。

Google Apps Scriptでブレークポイントを設置してデバッグ

するとpayload内のlimitの値が指数表記になっていますね。これが原因でエラーが出ていたというわけです。

数値を固定小数点表記に変換する場合はtoFixedメソッドを使います。

書き方はこちらです。

数値オブジェクト.toFixed(桁数)

桁数には小数点以下の桁数を指定します。0または省略で小数点以下0桁、つまり整数表記になります。

7行目の後に以下の一行を追加します。

limit = limit.toFixed();

実行結果

そのうえでスクリプトを実行しますと

チャットワークAPIで期限付きのタスクを追加した

無事に期限付きのタスクが追加されました。

これをイベントトリガーで毎朝8時などに追加すれば、「牛乳を買う」というタスクがその日の期限で毎日追加されることになります。

まとめ

Google Apps Scriptでチャットワークに期限付きのタスクを追加する方法についてお伝えしました。

  • UNIX時間の概要とgetTimeメソッドによる取得の方法
  • toFixedメソッドによる数値の固定小数点表記への変更

などのテクニックを使いました。

次回はスプレッドシートにタスク内容とタイミングを指定おくことで、それぞれのタイミングでタスク追加する方法についてお伝えしたいと思います。

どうぞお楽しみに!

連載目次:GASでチャットワークに自動でタスク追加をする

  1. Google Apps Scriptでチャットワークにタスクを追加する最も簡単なプログラム
  2. Google Apps Scriptでチャットワークに期限付きのタスクを追加する

エクセルVBAのボタン設置で引数を渡してマクロを呼び出す方法

$
0
0
buttons

photo credit: door bells via photopin (license)

みなさん、こんにちは!
タカハシ(@ntakahashi0505)です。

エクセルVBAでプログラムを動かす際にボタンを設置しますよね。

ボタンを設置しておけば、わざわざVBEを呼び出す必要もなくなりますし、開発タブを追加していない方でもプログラムを動作させることができるようになります。

しかし、そんなボタンですが、こうは思ったことはないですか?

ボタンに引数を渡せたらなぁ…と。

ほとんど同じような処理なのに、わざわざボタンごとにプロシージャをしたためるのもバカバカしいというとき、ありますよね。

今回はその悩みにお応えして、ボタンに登録したVBAマクロを引数を渡しながら実行する方法についてお伝えします。

では、よろしくお願いします。

一般的なボタン設置とマクロの登録方法

まずは引数を渡さない場合のボタン設置とマクロの登録方法をおさらいしておきます。

例えばこのような簡単なSubプロシージャを作ります。

Sub showMessage()

MsgBox "ボタンが押されました"

End Sub

これを新規で作成したボタンにマクロ登録していきます。

設置したいシートを開いてリボンから「開発」→「挿入」→「ボタン(フォームコントロール)」です。

エクセルVBAでフォームコントロールボタンを設置

トラップ的な感じですぐ下に「ActiveXコントロール」のボタンもあるのですが、VBAの神様いわく

一生触らなくて良い

とのことです。フォームコントロールだけ使いましょう。

設置するボタンの大きさをドラッグで決めると、マクロの登録ウィンドウが開きます。ここで登録したいマクロを選択してOKです。

エクセルVBAでボタンにマクロを登録

これでボタンへのマクロの登録は完了です。

ボタンを押せば

エクセルVBAでボタンを押してマクロを実行

ちゃんと実行がされます。

ボタンに応じた引数を渡してマクロを呼び出す

では、こちらの図のようにボタンを二つ設置して

エクセルVBAでボタンを2つ設置

それぞれ

「ボタンAが押されました」
「ボタンBが押されました」

とするにはどうすれば良いでしょうか?

わざわざそれぞれのボタン用のSubプロシージャを作ると処理が重複してしまいますので望ましくありませんね。

この場合は、それぞれのボタンに応じた引数を渡した上でマクロを呼び出せばOKですね。

引数を渡してマクロを登録する方法ですが、マクロの登録ウィンドウで

‘マクロ名 引数’

とします。記述のルールとしては

  • マクロ名の続きで半角スペースを空けて引数
  • 引数が文字列型、日付型の場合は引数をダブルクォーテーションで囲む
  • 引数を複数指定したいときはカンマで区切る
  • マクロ名と引数全体をシングルクォーテーションで囲む

となります。

今回のボタンAについては

エクセルVBAのボタンに引数を渡しつつマクロを登録

と設定すればOKですね。

ボタンA、ボタンBのマクロの登録は

button.xlsm!’showMessage “A”‘
button.xlsm!’showMessage “B”‘

となります。

一方でSubプロシージャのほうも引数の受け皿を用意する必要があります。

Sub showMessage(str As String)

MsgBox "ボタン" & str & "が押されました"

End Sub

ボタンに設定した引数はstrという文字列型の変数に格納されます。

そしてその変数を使ってMsgBoxの文字列を生成しています。

こちらを実行してみますと

エクセルVBAのボタンで引数を渡してマクロを実行

ボタンに応じたメッセージが表示されます。

引数があったりなかったりする場合

別の例を考えてみましょう。

例えばこちらの図のように二つのボタンを配置します。

エクセルVBAでボタンを2つ配置

ボタンには引数を渡さず、ボタン2にだけ整数2を引数を渡したいというときがあるとします。

その場合、それぞれのボタンに登録するマクロは

button.xlsm!’showMessage’
button.xlsm!’showMessage 2′

となります。

呼び出すSubプロシージャはこんなふうに用意してみました。

Sub showMessage(num As Integer)

MsgBox "ボタン" & num & "が押されました"

End Sub

しかし、ボタン2は無事に実行できるのですが、ボタンのほうを押すと

エクセルVBAの引数は省略できませんのエラー表示

「引数は省略できません」とエラーになってしまいます。

このように引数があったりなかったりする場合は、受け取る側でOptionalキーワードをつけて省略可能な引数であることを明示します。

Subプロシージャをこのように変更します。

Sub showMessage(Optional num As Integer = 1)

MsgBox "ボタン" & num & "が押されました"

End Sub

これによりnumという変数は省略可能で、省略した場合は1が代入されるという形になります。

こちらでボタンを押してみますと

エクセルVBAで省略可能な引数を渡してボタンによるマクロ実行

省略した場合の数値1が適用されて無事に実行されました。

まとめ

ボタンに登録したVBAマクロを引数を渡しながら実行する方法についてお伝えしました。

Optionalキーワードで引数を省略することもできます。

その他、引数の渡し方は色々とできますので、作成するプログラムに合わせて工夫をしてみてくださいね。

ブログを習慣化してコツコツ続けるためにオススメしたい5つのこと

$
0
0

cup-coffe-laptop

みなさん、こんにちは!
タカハシ(@ntakahashi0505)です。

当ブログも開始してから1年強、このたびめでたく月間15万PVを超えました!

15万PVって、なんとなく一つの大きな壁のような気がしていまして、嬉しいです。

こうなると商談の場でブログの活用について実績を持ってお話できる機会も増えてきますし、これから起業される方または起業仕立ての方には「絶対にやっておいたほうがいいよ」と堂々とオススメできるようになってきます。

ただ、そこでつまづきやすいのが「習慣化」です。

まずは「毎日やったほうがいい」とオススメすると、「そんな時間はとれないな…」と一歩踏み出すのを思いとどまってしまうパターン。

本業が忙しい方、家族(とくにお子様)がいる方には多いパターンかも知れませんね。

また、運よくスタート切れたとしても安心はできません。

最初のほうは熱も高いので、WordPressの記事や資料を一生懸命あさって毎日時間を割いてブログに向き合うのですが、しばらくすると

  • 次のネタが続かない
  • 本当にこれでいいのか気になって筆が進まない
  • 仕事の繁忙期を機にペースが乱れた
  • 家族とのイベントを機にペースが乱れた

などなど、色々なものが「習慣化」を邪魔します。

一度ペースを乱すと心の隅っこに小さく押し込めていた「明日でいいや」という名の悪魔が、ここぞとばかりに膨らみはじめ一気に毎日の習慣を支配しはじめます。

では、この最大かつ唯一と言ってもよい習慣化というハードルをどう乗り越えていけばよいでしょうか?

そのために支えとなるいくつかのテクニックがあります。

今回は私自身が実践しているブログを習慣化するための5つのテクニックについてお伝えします。

無理なペース設定をしない

ブログで成功している先人たちは「毎日記事を公開すべき」と声を揃えて言います。

実際、私もそう思います。ただ実行に移すのはすごく大変です。

私もブログをスタートした当初はサラリーマンでしたから、当時は大変でした。

通勤等も考えると平日の朝8:30くらいから早く帰宅できたとしても夜20:30くらい。晩御飯とお風呂を済ませた後22:00くらいから執筆作業に入ります。

今であれば2~3時間くらいあれば一つの記事をアップできますが、当時は慣れていませんしスキルも高くありません。

だいたい1つの記事に少なくとも5時間くらいかかっていました。8時間かかった記事もあります。

22時から5時間…午前3時。数時間だけ睡眠して翌朝会社へ。

…そんなことを続けたら間違いなく日々の生活に支障をきたします。体調を崩したり、睡眠不足で本業にも集中できなくなります。

実際、私も体調を壊してしまいました。

そこでオススメなのは、無理なペースを設定しないということです。

私の場合は、朝5:30に早起きをすることにして、そこから出社までの時間をブログの執筆に充て、更新頻度の目標は3日で1記事としました。

これで、無理なく続けられるようになり、今に至るというわけです。

家族と話をしてルールを取り決め、運用する

家族がいる場合は、ルールを話し合って決めておくというのは必須なのではないかと思います。

なんとなく家族に相談なしに自分だけでブログを始めちゃうこともあるかも知れないのですが、そうなると家族は心配をしたり不安になったりしてしまいます。

場合によっては、ブログに反対をし始めるケースもあるかも知れません。

ブログはそれっぽい結果が出るまでに最低でも半年、場合によっては1年以上かかります。

よく考えて下さい。

ブログの成果が出るまで、一番近くにいていつも一緒にいる家族が気持ちよく応援し続けてくれるのと、「もうやめたら?」と反対し続けるのとでは、天と地の差があります。

反対する家族が悪いわけではありませんよ。

自分が感じているブログの必要性や情熱を、何もせずとも家族が同じように思ってくれていると思ったら大間違いということです。

ですから、家族と話をしてルールを決めましょう。

どういうことを決めるかというと

  • 一日のうち、どの時間をブログの時間に充てるか。家族との時間はどう確保するか。
  • どこで書くか。一人で集中したい場合は部屋を確保。
  • どういう内容を書くか。本名は晒すのか晒さないのか。家族のことは書くのか、書かないのか。
  • 更新頻度はどのようなペースなのか。
  • ブログの目標をどこに設定をしていて、今はどの段階で、どういう成果が出ていて出ていないのか。

などです。

そして、最初に決めてそのまんまではなくて、定期的に家族と話をして必要に応じてルールを変更します。

決めたら決めっぱなしではなくて、ルールを運用することが大事です。

状況も変化しますからね。

生活の一部にするわけですから、家族の理解がなくては続けることはできません。

先にカレンダーに入れて時間を確保しておく

自分の時間とやるべきことを100%絶対に完璧にコントロールできる人なら、毎日何時から何時と決めておけばそれで良いかも知れません。

ただ多くの人の場合は、仕事の都合だったり、家族との約束だったり、友達付き合いだったり、優先順位の高いイベントが次から次へと生まれてくるわけです。

そこで優先順位によって予定を組み替える作業が発生するのですが、悲しいかなブログの執筆時間は優先順位として低い傾向にあります。

ブログなんて、やらなくても誰かが文句言うわけでもありませんし、お金が減るわけではありませんからね。

だから、何かイレギュラーなイベントが発生すると、真っ先にブログ執筆の予定は退かされてしまいます。

では、どうするかと言うと、カレンダーにブログ執筆の時間を確保しておくのがオススメです。

私の来週のカレンダーを晒すとこんな感じです。

ブログの予定をカレンダーに確保する

まず、定期の予定でブログ執筆の時間を19:00~22:00に確保しておきます。土日を含めて毎日確保しています。

例えばとある日の夜に別の優先的な予定が入った場合は、予定が被ってしまうブログの執筆時間を当日の別の時間に移動して、そこには他の予定を入れないようにします。

どうしてもその日の別の時間に入れられなくなった場合は、他の日に入れます。

つまり、一度定期で確保したブログ執筆時間は移動はしても良いが削除はしないようにするというわけです。

私の場合はブログ以外にも、食事の時間やジムに行く時間は先に確保するようにしています。

よろしければこちらの記事もご覧ください。

仕事の生産性を測定して振り返るためのGoogleカレンダーの使い方
過去に何の仕事にどれだけ時間をかけてきたか、振り返ったことはありますか?Googleカレンダーを上手に記録しておくことで、これまでの仕事の生産性を測定するための貴重なデータになります。

あちこちで公言する

ある程度ペースがつかめてきたら、ブログのプロフィールなどに「ほぼ毎日更新しています」などと記入して執筆ペースの目標について公言しましょう。

こうすることで、やらなきゃ格好がつかなくなる状況を作ります。

しかし、これはペースがつかめてからで良いと思いますし、後で変更をしても良いと思います。

というのも、ペースをつかめる前だと実現可能性が低い目標設定にしてしまっている場合もありますので、「できる」と思ってからで良いと思います。

公言内容が明らかにできるとわかっていることでも、ちゃんとやっていれば格好が良いです。

また、ブログに書くだけでなく、商談ではもちろんイベントやセミナーで「ほぼ毎日更新しています」と言うようにしています。

マーガレット・サッチャーさんも言っています。

考えは言葉となり、
言葉は行動となり、
行動は習慣となり、
習慣は人格となり、
人格は運命となる。

いい言葉ですね。

完璧を求めない

完璧を求めると動けなくなるときがあります。

  • 毎日更新すること
  • 1記事あたり2000文字以上にすること
  • 記事のクオリティ
  • ベストなキーワード対策
  • お気に入りのアイキャッチ画像

などなど当然高い目標を達成するに越したことはありません。

ただ、それら全ての要素について100点にもっていこうとすると、作業のキリがなくなってしまい、いつまで経っても公開できない気がしてきちゃいます。

当然ですが

  • 全く誰も必要としていない記事
  • 間違い情報
  • とっても読みづらい記事
  • 二次情報を集めただけの記事

とかはダメですし、伝えたいことが伝わらない記事を書いても意味がありません。

完璧を求めすぎて、何も言えなくなるよりは、つたなくても何かを伝えられたほうが良い結果が得られる場合が多いです。

止まりさえしなければ、どんなにゆっくりでも進めばよい。(孔子)

まとめ

ブログを上手に習慣化するための5つの方法についてお伝えしました。

私もこれまでITと仕事に関わる記事を本記事執筆時点で267記事書いてきました。

今でも、今日はモチベーション上がらないな…とか、5日分借金(記事数の)を抱えてしまったとか、そういうことはあります。

ですが、もうブログ辞めようという気持ちは一切なくなりました。

サッチャーさんの言葉で言うと、習慣が人格になりつつある、つまりアイデンティティというか自分の武器の一つになってきているというのを感じています。

ブログを続けることのメリットは最近感じることも多いので、ぜひまた別記事にてお話できればと思います。

地域の課題を解決するためにITが担う役割とその難しさについて

$
0
0

Agriculture

みなさん、こんにちは!
タカハシ(@ntakahashi0505)です。

先日、三鷹市市民協働センターで行われました「地域の課題を解決する「市民×IT」の出会い ~ともに考え、ともにつくる~」というイベントに参加しました。

ITを活用して地域の課題解決に取り組む組織「Code for Japan」の代表である関さんのお話と、チームに分かれてのグループセッションを通して学んできたことをお伝えできればと思います。

ITを活用する際の一番の課題は?

弊社では「仕事×IT」というテーマで活動をしています。

ですが、ビジネスの現場でも全ての業種、職種についてITが十分に活用されているかと言ったら、まだまだその浸透度は十分であるとは言えません。

そして、ITのほうは技術が日進月歩ですから、その利用者たちの間のIT格差が大きく広がりつつあると感じています。

市場の競争原理の中でそれぞれの企業が好きに使ったり使わなかったりすれば良いので、私としてはITに興味がある企業とお話をしていけば良いのです。

ですが、日本というくくりで考えると、世界に遅れを取らないようになんとかできることがないかなと思っています。

世界で拡がるデジタル格差に取り残されようとしている日本
IT活用によるお仕事効率化をテーマにビジネスをしていると、デジタル格差という課題が明らかにあることを感じています。今回は米国でのデジタル格差のレポートに触れつつ、日本が抱える課題について書いています。

ITを活用できない理由は企業それぞれなのですが感覚としては

  • 知らない
  • 苦手意識
  • リスクが怖い
  • 遠い存在に感じる

など、マインド的な抵抗感もけっこうあるのではないかと思います。

今回のイベントでは「市民×IT」ではあり、少し対象は違うのですが、ITをいかに受け入れてもらえば良いのか、といった部分に応えるヒントがあればと思い、参加させて頂きまいた。

Code for Japanとは?

Code for Japanという組織の存在を知ったことは、今回のイベントの大収穫でした。

Code for Japanとは

市民が主体となり、地域課題解決に取り組むコミュニティ作り支援や、テクノロジーを活用したアクションを創発する活動を支援していく非営利団体です。

Code for JapanにはBrigade(ブリゲード)という仕組みがありまして、例えば「Code for Hakodate」とか「Code for Kanazawa」など、地域ごとの各地のコミュニティが存在しています。

現在39の公認団体があり、準備中が23団体あります。

実際の地域への支援活動はそのブリゲードたちが各地域の市民や自治体と協力して行うという仕組みです。

三鷹を中心として武蔵野エリアではこれまでたくさんの地域活動のイベントに参加させて頂きました。

たくさんの市民の皆さんが様々な課題を解決すべく、熱心に活動をされているのに圧倒されるばかりですが、このたび「Code for Mitaka,Musashino」を準備中ということで、ITという切り口でそこを支援するチームが出来ることは、それらの活動にとって大きな推進力を得られるのではないかと期待しないわけにはいきません。

地域支援としてITを活用するメリットはたくさんあります。

関さんのお話では

  • 新しいコミュニケーションの提供
  • 課題の共有
  • システム思考のアプローチ
  • 解決策の再利用

が挙げられていました。

ITは企業活動と同様に、地域活動でも同様に様々な効果を生してくれます。

誰が頑張るべきなのか

後半のグループワークでは、防災、観光、農業、子育てといった4つのテーマについて実際に三鷹地域が抱えている課題を提示して、それをITで解決するためのアイデアを出すアイデアソンを実施しました。

私は農業のグループに入りました。

三鷹という都会でも、農業を営まれている方が実際にいらっしゃいまして、都市農業ならではの高付加価値な農産物の生産活動を行われています。

ただ、やはり農家の皆さんはPRが下手…ということで、そこをサポートするITを使った何かを作ろうというわけです。

私たちのチームでは、三鷹の地産地消を促進するという目的のもと

  • 直売所での農産物の販売情報
  • 農産物の生育情報や育てる際のコダワリなどのストーリー
  • 農産物のオススメレシピ
  • 体験農業などのイベント情報

などの情報を誰もが自由に取得できる場がWeb上にあれば良いのでは?というアイデアが出ました。

当然、お得な情報や農産物のストーリーなどがあれば地元の農産物を欲しくなるのではないかと思いますし、写真や記事などのコンテンツが充実してくれば検索やSNSからの流入なども期待できるかも知れません。

ただ、誰がそのコンテンツを投稿をするのか?

という点で、少し詰まってしまいました。

農家は忙しく、ITが苦手、これは皆さん声を揃えて言いますし、私もそう思います。

では、誰かボランティアのような人が農家や直売所を頻繁に取材してコンテンツの投稿をしますか?

これはなかなか大変…完全にボランティアでは長続きはしないでしょう。

結局、イベントでは小さくスタートしてみよう、という結論になりまして、その答えについてははっきり出ませんでした。

結局、今回私がこのイベントに参加して知りたかった疑問を再提示された形でした。

皆さんはどう思われますか?

まとめ

疑問投げっぱなしでまとめに入ってしまいましてすみません。

私は、農家さんの中から頑張る人が出てこないと、このプロジェクトはうまくいかないのではないかと感じています。

その活動をするためのハードルを低くしたり、効果を倍増させるのは我々ITに詳しい人たちの役割だと思います。

いずれにしても立ち向かう価値のある役割ですし、今回この場に50名以上の老若男女が集まったということは、色々な期待を感じさせるものとなりました。

Google Apps Scriptのメルマガ配信リスト自動更新スクリプトを高速化する

$
0
0

speeding-up

みなさん、こんにちは!
タカハシ(@ntakahashi0505)です。

Google Apps Scriptを使ってメルマガ配信システムを作成しています。

ここしばらくの連載では名刺管理サービスCAMCARDのデータをスプレッドシートに取り込んで、メルマガ配信システムの宛先リストを自動更新する処理を作る方法についてお伝えしています。

【GAS】名刺管理アプリの出力データを活用してメルマガ配信リストを自動更新する
Google Apps Scriptでメルマガ配信システムを作りました。今回はスプレッドシートにインポートした名刺管理アプリのデータを使ってメルマガ配信リストを自動更新する方法を紹介いていきます。

しかしながら、Google Apps Script…何も考えずにスプレッドシートの読み書きをガシガシ行うような組み方をすると、めっちゃ処理が遅くなるんです。

それを回避するために、前回はスプレッドシートを操作する際にAPIの呼び出し回数を抑えて、処理を格段に速くする方法についてお伝えしました。

Google Apps Scriptのスプレッドシート読み書きを格段に高速化をする方法
Google Apps Scriptでスプレッドシートの操作をしていて実行速度が遅い!と感じたことがあると思います。今回はスプレッドシートを操作する場合に処理速度を格段に速くする方法をお伝えします。

今回は上記処理速度を速くする方法を活用して、メルマガ配信リストの自動更新スクリプトの最適化を進めていきたいと思います。

おさらい:修正前のスクリプトとその実行速度

おさらいですが、以前作成したメルマガ配信リストの自動更新スクリプトはこちらです。

function inportContacts(){

  var mySS=SpreadsheetApp.getActiveSpreadsheet(); //スプレッドシートを取得

  // 配信先リストシートとその最終行の取得
  var sheetAddress=mySS.getSheetByName("配信先リスト"); //配信先リストシートを取得
  var rowAddress=sheetAddress.getDataRange().getLastRow(); //配信先リストシートの最終行

  // Contactsシートとその最終行の取得
  var sheetContacts=mySS.getSheetByName("Contacts"); //Contactsシートを取得
  var rowContacts=sheetContacts.getDataRange().getLastRow(); //Contactsシートの最終行

  /* Contactsのリストについて配信先リストに同じものがあるかを検索する */
  for(ci=2;ci<=rowContacts;ci++){

    var flugFind = false; //配信リストに該当のメールアドレスがある:true/ない:false

    for(ai=2;ai<=rowAddress;ai++){

      /* 既に配信先リストに同じデータがあればフラグを立てる */
      if(sheetAddress.getRange(ai,4).getValue() === sheetContacts.getRange(ci,9).getValue()){
        flugFind = true;
      }
    }

    /* flugFindがfalseのままなら配信リストに追加をする */
    if(!flugFind){

      sheetAddress.getRange(rowAddress+1,1).setValue(sheetContacts.getRange(ci,6).getValue()); //社名
      sheetAddress.getRange(rowAddress+1,2).setValue(sheetContacts.getRange(ci,2).getValue()); //苗字
      sheetAddress.getRange(rowAddress+1,3).setValue(sheetContacts.getRange(ci,3).getValue()); //名前
      sheetAddress.getRange(rowAddress+1,4).setValue(sheetContacts.getRange(ci,9).getValue()); //To

      rowAddress++;
    }
  }   
}

CAMCARDのデータが50行だった場合に実行してみますと、その実行速度は…

メルマガリスト更新のGoogle Apps Scriptの実行速度を測定

42秒…遅いっすね。

では、スクリプトを修正して解決していきましょう。

APIの呼び出し回数を減らして高速化する

上記のスクリプトですが、14行から始まるfor文内にそれはもうたくさんのAPI呼び出しがいますね…。

シートの読み書きはgetValuesやsetValuesを活用して範囲でまとめて配列に処理するようにして、セル単位での比較や計算は配列内のデータに対して行うようにします。

全体の流れとしては以下のようにしていきます。

  1. 配信リストシート・Contactsシートとその最終行の取得
  2. 配信リストシート・Contactsシートの全てのデータを配列に格納
  3. Cotntactsの配列データについて
    1. 配信リストにも同じメールアドレスが存在すればフラグを立てる
    2. フラグが立っていなければ配信リストの配列データに行を追加
    3. 追加した行に社名、苗字、名前、メールアドレスを追加
  4. 配信リストの配列データを配信リストシートにまとめて貼り付ける

という流れで組んでいきます。

処理速度を改善したメルマガ配信リスト更新スクリプト

スクリプトはこのようになりました。

function inportContacts2(){

  var start = new Date();

  var mySS=SpreadsheetApp.getActiveSpreadsheet(); //スプレッドシートを取得

  // 配信先リストシートとその最終行の取得
  var sheetAddress=mySS.getSheetByName("配信先リスト"); //配信先リストシートを取得
  var rowAddress=sheetAddress.getDataRange().getLastRow(); //配信先リストシートの最終行
  var varAddress=sheetAddress.getDataRange().getValues(); //配信先リストのデータ

  // Contactsシートとその最終行の取得 
  var sheetContacts=mySS.getSheetByName("Contacts"); //Contactsシートを取得
  var rowContacts=sheetContacts.getDataRange().getLastRow(); //Contactsシートの最終行
  var varContacts=sheetContacts.getDataRange().getValues(); //Contactsシートのデータ

  var row=rowAddress; //データ追加行

  /* Contactsのリストについて配信先リストに同じものがあるかを検索する */
  for(var ci=2;ci<=rowContacts;ci++){

    var flugFind = false;
    for(var ai=2;ai<=rowAddress;ai++){

      /* 既に配信先リストに同じデータがあればフラグを立てる */
      if(varAddress[ai-1][4-1] === varContacts[ci-1][9-1]){
        flugFind = true;
        break;

      }
    }

    /* flugFindがfalseのままなら配信リストに追加をする */
    if(!flugFind){

      varAddress[row]=[];
      varAddress[row][1-1] = varContacts[ci-1][6-1];
      varAddress[row][2-1] = varContacts[ci-1][2-1];
      varAddress[row][3-1] = varContacts[ci-1][3-1];
      varAddress[row][4-1] = varContacts[ci-1][9-1];

      row++;
    }
  }

  sheetAddress.getRange(1,1,row,4).setValues(varAddress);

}

追加すべきリストが見つかったら、配信リストのデータが格納された配列であるvarAddressに新たな行を追加します。

二次元配列のときは事前に”箱”の確保を

その際に注意点として36行の

varAddress[row]=[];

が必要になります。

例えば、スクリプトを動作させる前のvarAddressは行方向の配列の数が3行だったとします。

その場合、varAddressには

varAddress[0]=[社名,姓,名,メールアドレス];
varAddress[1]=[株式会社プランノーツ,高橋,宣成,~.co.jp];
varAddress[2]=株式会社HOGEHOGE,山田,太郎,~.com];

とした場合と同様になるのですが、ここに新しい行として

varAddress[3]=[株式会社サンプル,鈴木,花子,~.co.jp];

と追加しようとするとエラーになります。

varAddress[3]を格納するためのエリアの割り当てができていないからです。

その場合には、データを格納しようとする前に

varAddress[3]=[];

などとして、格納するための”箱”を事前に確保してあげればOKです。

実行結果

上記スクリプトを実行して、速度を測定してみましょう。

高速化したGoogle Apps Scriptの実行速度

0.267秒…!

その差158倍です。絶対にこちらの方法が良いですね。

まとめ

Google Apps Scriptのメルマガ配信リスト自動更新スクリプトの高速化をする方法についてお伝えしました。

APIの呼び出し回数を減らすことを考えるのは、もう必須と言っていいほど効果がありますね。

ぜひ、マスター頂ければと思います。

さて、しばらく何回かの記事に分けてお伝えしてきた、Google Apps Scriptによるメールマガジン配信システムですが、いったんこれにて完成とさせて頂ければと思います。

Google Apps Scriptでは様々なGoogleサービスを操作できますので、引き続き皆さんのお仕事に役立つツールについて紹介できればと思います。

どうぞお楽しみに!

連載目次:Google Apps Scriptでメルマガシステムを作っちゃおう!

  1. 超初心者へGoogleAppsScriptを始めるメリットをこれでもかと説明します
  2. 初心者でも簡単!Google Apps ScriptでGmailを操作してメールを送る方法
  3. 初心者でも簡単!Google Apps Scriptでドキュメントを取得して表示する方法
  4. Google Apps Scriptでスプレッドシートのリストをもとに宛名を差し込んだメール本文を作る
  5. たったの38行!Google Apps Scriptで超簡易メルマガ配信システム
  6. 名刺管理アプリCAMCARDの連絡先リストをスプレッドシートに取り込む
  7. 【GAS】名刺管理アプリの出力データを活用してメルマガ配信リストを自動更新する
  8. Google Apps Scriptのスプレッドシート読み書きを格段に高速化をする方法
  9. Google Apps Scriptのメルマガ配信リスト自動更新スクリプトを高速化する

エクセルで重複したデータを削除する方法とVBAプログラム

$
0
0

duplicate

みなさん、こんにちは!
タカハシ(@ntakahashi0505)です。

あってはならないのですが、エクセルの表で間違えて同じデータを入力してしまっている場合、皆さんはどのように対処をされますか?

例えばそのデータが請求書のデータだったら、本来は一通で良い請求書が先方に二通届いてしまうかも知れません。

また、そのデータがテストの点数だったら、とある人のテストの点数が異様に高くなってしまうかも知れません。

…といったように、誤入力によるデータの重複を見逃すと、ひどい目に合うことがあります。

このデータの重複を対処する方法なのですが、まさか目で追って重複を確認するなどはやっていませんよね…?

そんなことをしていたら日が暮れちゃいますし、見逃しが発生します。

こういった作業はコンピュータが得意ですので、任せてしまいましょう!

今回はエクセルの超便利機能である重複削除の方法と、それをVBAのプログラムで実行する方法についてお伝えします。

エクセルでデータの重複削除をする

まずこのようなエクセルの表があるとします。

エクセルのテスト点数結果表

よく見るとわかるのですが、重複データがいくつか紛れ込んでいます。

こんな少ししかデータがなくても見逃しちゃいそうですからね…人の目なんぞは全く信用できるものではありませんね。

さて、ではこの表に重複の削除の機能を使用してみましょう。

全ての列が重複しているデータの重複の削除

まずセルを対象となる表のどこかに置きます。その上で、リボンから「データ」→「重複の削除」です。

エクセルでデータ→重複の削除

するとエクセル、超頭が良いことに「たぶんここ」という範囲を勝手に選択してくれます。そして「重複の削除」ウィンドウが開きます。

エクセルの重複の削除ウィンドウ

このウィンドウでは

  • 先頭行をデータの見出しとして使用するかどうかのチェックボックス
  • 列をそれぞれ選択するチェックボックス

があります。

今回の場合は、先頭行は見出しなので「先頭行をデータの見出しとして使用する」にはチェックを入れたまま、また、全ての列が重複している場合に削除としたいので列の選択は全てチェックにしたままで「OK」とします。

すると

エクセルで重複の削除をした結果

「重複する3個の値が見つかり、削除されました。一意の値が8個残っています。」とのこと。うまくいきましたね。

特定の列のみが重複しているデータの重複の削除

では列それぞれの選択のチェックボックスを外してみるとどうなるでしょうか?

先ほどの表に対しての重複の削除をする際に、「科目」と「点数」のチェックを外して「OK」としてみます。

エクセルで特定の列だけをみて重複の削除をする

すると

エクセルで特定の列だけをみて重複の削除をした結果

「重複する8個の値が見つかり、削除されました。一意の値が3個残っています。」とのことです。

「名前」の列だけにチェックが入っていましたから、この列だけを見て「一意」になるようにデータが削除されたわけです。

どの行が削除されずに残るかというと

  • 最初に登場した「高橋」の行
  • 最初に登場した「鈴木」の行
  • 最初に登場した「山田」の行

が残ります。行数が最も少ない一意のデータが残るということですね。

エクセルVBAで重複の削除をする

では次にエクセルVBAで重複の削除をする方法をお伝えします。

エクセルVBAで重複の削除をする場合は、Rangeオブジェクトに対してのRemoveDuplicatesメソッドを使います。

Rangeオブジェクト.RemoveDuplicates Columns:=列番号の配列,
Header:=1行目を見出しとして使用するかの指定

列番号の配列ですが、どの列を見て重複の削除をするかを指定します。

Columns:=Array(列番号1,列番号2,…)

と、複数の列番号について指定します。

要は、ここで列番号を指定するということは、重複の削除のウィンドウでのそれぞれの列にチェックを入れたのと同じ意味になります。

また、Headerで指定する値ですが

  • xlNo:1行目を見出しとして指定しない(既定値)
  • xlYes:1行目を見出しとして指定する
  • xlGuess:エクセルに判断を任せる

となります。既定値はxlNoなので、Header:=…を省略すると、1行目は見出しとして取り扱われません。

ちょっと気になるところですが、xlGuessを使うケースってあるんですかね…。

全ての列が重複しているデータの重複の削除をするVBA

では、プログラムを作ってみましょう。

まず全ての列を選択するパターン、つまり全ての列が重複している場合のみ重複の削除をするVBAプログラムはこちらです。

Sub duplicateDelete()

Worksheets(1).Range("A:C").RemoveDuplicates Columns:=Array(1, 2, 3), Header:=xlYes

End Sub

ArrayにはA列からC列までの列番号1~3を全て列挙します。1行目は見出しですので、Headerの値はxlYesです。

簡単ですね。

ではこれを実行してみましょう。

エクセルVBAで重複の削除をした結果
瞬きをしている間に終わります。メッセージも何にも出ませんが、無事に完了しています。

ちなみにですがVBAで重複の削除をした場合は、アンドゥつまり Ctrl + Z などで一手前に戻すことができませんので、注意してくださいね。

特定の列のみが重複しているデータの重複の削除をするVBA

では、同様に「名前」の列だけを見て重複の削除をするVBAプログラムを作ってみましょう。

Sub duplicateDelete()

Worksheets(1).Range("A:C").RemoveDuplicates Columns:=Array(2), Header:=xlYes '重複削除

End Sub

列の指定だけ変更をすれば良いですね。

実行結果はこちらです。

エクセルVBAで特定の列を対象に重複の削除をした結果

バッチリです。

まとめ

エクセルで絶対に覚えたほうが良い便利機能である重複の削除の方法 と、VBAで重複の削除をする方法についてお伝えしました。

目で見たり、オートフィルタをかけたりして作業をしてはダメですよ。重複の削除の機能を使えば、2クリックで正確に完了します。

VBAのプログラム内でも少しメソッド名は長いですが、たったの1行で実現できますから、ぜひ覚えて頂ければと思います。

【GAS】スプレッドシートに記載したタスクを毎日チャットワークに自動で追加する

$
0
0

daily

みなさん、こんにちは!
タカハシ(@ntakahashi0505)です。

Google Apps Scriptでチャットワークに自動でタスクを追加するシステムを作成しています。

前回は、チャットワークに期限をつけてタスクを追加する方法についてお伝えしました。

Google Apps Scriptでチャットワークに期限付きのタスクを追加する
Google Apps ScriptでチャットワークAPIを操作してチャットワークに期限付きのタスクを追加する方法です。その際に使うUNIX時間の取得方法、数値の固定小数点表記の方法についても触れます。

これでタスク追加に関する基本的な使い方はバッチリ抑えられたかと思います。

さて、お仕事の中で毎日や毎週、毎月など定期的に発生するタスクがありますよね。

これらを自動的にチャットワークにタスク追加をしていきたいというとき、どのように実現したらよいでしょうか。

Google Apps Scriptでそれぞれのタスクについてスクリプトを組んでいっても良いですが、例えばスプレッドシートに自動追加するタスクを登録しておいて、その通りにタスクを追加してくれたら楽ちんですよね。

今回から何回かに分けて、Google Apps Scriptを使ってチャットワークに自動追加するタスクをスプレッドシートでコントロールするシステムを開発していきたいと思います。

初回はスプレッドシートにリストされているタスクについて毎日自動でチャットワークでもタスク追加する方法です。

では、行ってみましょう!

スプレッドシートで毎日のタスクリストを作成する

このようなスプレッドシートを作成しました。

スプレッドシートに記載した毎日のタスクリスト

毎日発生するタスクを記載しています。

今は二つしかありませんが…そのうち盛り上がりますので。

ルームIDはタスクを追加するグループチャットのルームID、アカウントIDはタスクを追加する担当者のアカウントID(複数いる場合はカンマ区切り)です。

このリストにあるタスクを毎朝(例えば7~8時など)に、指定のグループチャットにタスク追加するというスクリプトを考えていきます。

チャットワークにタスク追加をする関数

各行についてタスク追加をすることになりますので、チャットワークにタスク追加をするルーチンを関数化しておきたいと思います。

チャットワークAPIの仕様を確認すると

POST /rooms/{room_id}/tasks
チャットに新しいタスクを追加

body(必須):タスクの内容
limit:タスクの期限(※Unix timeで入力してください)
to_ids(必須):担当者のアカウントID(※担当者のアカウントIDをカンマ区切りで)

となっています。

HTTPメソッドはPOSTですね。この時点で関数として渡す引数はroom_id,body,limit,to_idsとなります。

リクエストURLは

https://api.chatwork.com/v1/rooms/{room_id}/tasks

です。

またチャットワークAPI共通でHTTPヘッダに “X-ChatWorkToken”というパラメータ名でAPIトークンを渡す必要がありました。

ちょっと引数が多いですが、関数addTaskを

addTask(APIトークン,ルームID,タスク内容,タスク期限,アカウントID)

といった感じで作ってみます。

addTask関数

関数addTaskのコードはこちらです。

function addTask(token,room_id,body,limit,to_ids){
  var params = {
    headers : {"X-ChatWorkToken" : token}, //APIトークン
    method : "post",
    payload : {
      body : body, //タスク内容
      limit : limit, //タスク期限
      to_ids : to_ids //アカウントID
    }
  };
  var url = "https://api.chatwork.com/v1/rooms/" + room_id + "/tasks";
  UrlFetchApp.fetch(url, params); //チャットワークAPIにリクエスト
}

詳細は前回のこの記事や

Google Apps Scriptでチャットワークに期限付きのタスクを追加する
Google Apps ScriptでチャットワークAPIを操作してチャットワークに期限付きのタスクを追加する方法です。その際に使うUNIX時間の取得方法、数値の固定小数点表記の方法についても触れます。

チャットワークにメッセージの送受信をする関数の作り方について解説したこちらの記事をご覧ください。

【GAS】チャットワークのメッセージを取り出す関数とメッセージを送る関数
Google Apps Scriptを活用してチャットワークにおみくじチャットを作成しています。今回はチャットワークからメッセージを取り出す、メッセージを送る処理を関数化して全体のコードをスッキリさせます。

スプレッドシートにリストした毎日のタスクをチャットワークに自動追加する

ではこの関数addTaskを使って、前述のスプレッドシートにリストされた毎日のタスクをチャットワーウに自動追加するスクリプトを作っていきます。

プログラムの流れとしては

  • シート自体と最終行数、データの取得をする
  • 本日の日付をUNIX時間で取得し、固定小数点表記に変更
  • 全てのタスクについて
    • D列の頻度が”毎日”であれば
      • タスク内容、ルームID、アカウントID、期限を本日としてタスク追加

という流れとなります。

スクリプトとしてはこちらになります。

function addRegularTasks() {

  var mySheet=SpreadsheetApp.getActiveSheet();
  var maxRow=mySheet.getDataRange().getLastRow();
  var myVars=mySheet.getDataRange().getValues();

  var token = 'APIトークン'; //チャットワークAPIトークン

  var date = new Date();
  var limit = date.getTime()/1000;
  limit = limit.toFixed();

  for(var i=2;i<=maxRow;i++){
    if(myVars[i-1][4-1]="毎日"){
      var body = myVars[i-1][1-1];  //タスク内容
      var room_id = myVars[i-1][2-1];  //ルームID
      var to_ids = myVars[i-1][3-1];  //アカウントID
      addTask(token,room_id,body,limit,to_ids);
    }
  }
}

getValuesを使ってデータ範囲をまとめて配列に格納

5行目ですがgetValuesでシート上のデータ範囲を二次元配列変数myVarsに格納しています。

このスクリプト自体はイベントトリガーを使って完全自動で動作するので、実行速度はあまり気にしなくても良いのかも知れませんが、二次元配列に慣れておいたほうが良いということで、このようにしています。

詳しくはこちらの記事もご覧下さい。

Google Apps Scriptのスプレッドシート読み書きを格段に高速化をする方法
Google Apps Scriptでスプレッドシートの操作をしていて実行速度が遅い!と感じたことがあると思います。今回はスプレッドシートを操作する場合に処理速度を格段に速くする方法をお伝えします。

本日の日付をUNIX時間で取得し固定小数点表記に

9行目~11行目はタスクの期限を求める箇所です。

今回は当日のタスクしかありませんので、本日の日付をそのまま指定しています。

UNIX時間や固定小数点表記についての詳細はこちらの記事をご覧ください。

Google Apps Scriptでチャットワークに期限付きのタスクを追加する
Google Apps ScriptでチャットワークAPIを操作してチャットワークに期限付きのタスクを追加する方法です。その際に使うUNIX時間の取得方法、数値の固定小数点表記の方法についても触れます。

二次元配列からaddTaskの引数を取り出す

15行目~17行目でそれぞれタスク内容、ルームID、アカウントIDを二次元配列から取り出しています。

配列番号は1からではなくて0から始まりますので、指定の際は実際の行番号や列番号をマイナス1した数字になりますので、注意してくださいね。

実行結果

このスクリプトを実行すると

GASによる毎日の自動タスク追加結果

このように無事にタスクが追加されます。

スクリプトエディタのメニューから「リソース」→「現在のプロジェクトのトリガー」から、イベントトリガーを「時間主導型」→「日タイマー」→「午前7時~8時」などとすれば、毎日自動でタスクが追加されます。

まとめ

スプレッドシートにリストされているタスクについて毎日自動でチャットワークでもタスク追加する方法をお伝えしました。

当然、定期のタスクは毎週だったり、毎月だったりに追加したかったりします。

次回以降、スプレッドシートに色々なパターンで自動登録用のタスクをリストできるように改良をしていきたいと思います。

どうぞお楽しみに!

エクセルVBAで印刷時のページ中央配置と余白を設定する

$
0
0
margin

photo credit: Magic Margin via photopin (license)

みなさん、こんにちは!
タカハシ(@ntakahashi0505)です。

前回、エクセルVBAでPDF出力する方法と出力の際に1ページに収めて出力する方法についてお伝えしました。

初心者でも簡単!エクセルVBAでPDFを出力する最もシンプルなプログラム
エクセルVBAではPDF形式での出力もできます。今回は、初心者向けエクセルVBAでPDFを出力する最も簡単なプログラムと、PDF出力の際にシート1ページに収めて出力する方法についてお伝えしていきます。

ただちょっと配置が左にちょっとずれていたんですよね…

エクセルVBAでは前回も登場したPageSetupオブジェクトを使うことでPDF出力や印刷の際の様々な設定を行うことができます。

今回は、エクセルVBAで印刷設定をページ中央配置にする方法、また上下左右のマージンを設定する方法についてお伝えしたいと思います。

また、プレビューの表示の仕方にも触れますよ。

どうぞよろしくお願いいたします!

前回のおさらい:シートを1ページに収めてPDF出力をする

前回のおさらいですが、シートを1ページに収めてPDF出力をするプログラムはこちらです。

Sub outputPDF()
Dim fileName As String '保存先フォルダパス&ファイル名
fileName = ThisWorkbook.Path & "\201603請求書_株式会社ホゲホゲ御中.pdf"

With ActiveSheet.PageSetup

    .Zoom = False
    .FitToPagesWide = 1
    .FitToPagesTall = 1

End With

ActiveSheet.ExportAsFixedFormat Type:=xlTypePDF, fileName:=fileName
End Sub

アクティブシートに対して、5行目~11行目で1ページ内に収める設定をしつつ、13行目で指定したファイル名でPDF出力をしています。

しかしお題のシートに対してプログラムを実行をすると

エクセルVBAで1ページに収めて出力したPDF

このようにちょっと左に寄った状態で出力されてしまいます。

今回はこれを解決していきたいと思います。

印刷プレビューを表示する

まずその前に、実行のたびに出力されたPDFを開いて結果を確認するのが、ほんの少し面倒なので、印刷プレビューを使いたいと思います。

エクセルVBAで特定のシートの印刷プレビューを表示したいとき

WorkSheetオブジェクト.PrintPreview

を使います。

お題のプログラムの13行目について

ActiveSheet.PrintPreview
'ActiveSheet.ExportAsFixedFormat Type:=xlTypePDF, fileName:=fileName '選択したシートをPDF出力

として実行をしますと

エクセルVBAで印刷プレビューを表示

このようにプレビュー画面が表示されます。

これでチェックが楽ちんになりますね。

印刷出力設定を中央配置にする

エクセルVBAで印刷の出力設定をする場合はシートのPageSetupオブジェクトを使います。

その中でも、印刷をページの水平方向または垂直方向で中央に設定する場合はそれぞれ

WorkSheetオブジェクト.PageSetup.CenterHorizontally = True または False
WorkSheetオブジェクト.PageSetup.CenterVertically = True または False

というプロパティを使います。

Trueにすればそれぞれの方向についての中央配置となります。

これはエクセルの「印刷」→「ページ設定」→「余白」タブからページ中央のチェックボックスにチェックを入れた状態と同じです。

エクセルで印刷のページ設定をする

例えば先ほどのプログラムのPageSetupの設定ですが、Withのブロック内に

.CenterHorizontally = True

を追加しますと

エクセルVBAで印刷時のページ中央配置
このようにバッチリ水平方向の中央配置となります。

印刷の上下左右とヘッダー・フッターの余白を設定する

先ほどのプレビューなのですが、上下のマージンをもう少し小さくしてもいいかも知れませんね。

その前にエクセルの余白について簡単に説明をしておきたいと思います。

エクセルの余白は上下左右以外にヘッダーとフッターがあり、全部で6箇所設定が可能です。

ヘッダー、フッターはどこを指しているかというと、以下の図のようにヘッター領域(またはフッター領域)までの距離を指定します。

エクセルのヘッダー余白と上余白

上、下はそれぞれ印刷用紙の上端、下端からシート内の印刷範囲で設定されているエリアまでの距離となります。

今回の場合、上下左右を今の半分くらいにしても良いかなという感じですね。

さて、エクセルVBAで印刷出力時の上下左右そしてヘッダーとフッターのマージン設定をする場合はそれぞれ

WorkSheetオブジェクト. TopMargin = 上余白(pt)
WorkSheetオブジェクト. BottomMargin = 下余白(pt)
WorkSheetオブジェクト. LeftMargin = 左余白(pt)
WorkSheetオブジェクト. RightMargin = 右余白(pt)
WorkSheetオブジェクト. HeaderMargin = ヘッダー余白(pt)
WorkSheetオブジェクト. FooterMargin = フッター余白(pt)

と設定します。

では試しに上下のマージンをそれぞれ1に設定してみましょう。

PageSetupの設定のWithのブロック内に

. TopMargin = 1
. BottomMargin = 1

を追加して実行してみましょう。

エクセルVBAで上下余白を1ポイントに設定

おや…?思ったよりも窮屈になってしまいましたね。

長さの単位をセンチメートルからポイントに変換

実は設定の単位が良くありません。

PageSetupオブジェクトへのマージン設定の単位はポイント(pt)ですが、エクセルの「印刷」→「ページ設定」で開くウィンドウで設定する単位はセンチメートル(cm)なのです。

こういう場合は、センチメートルからポイントに単位を変更するCentimetersToPointsメソッドを使います。

Application.CentimetersToPoints(センチメートル)

上下の余白を

. TopMargin = Application.CentimetersToPoints(1)
. BottomMargin = Application.CentimetersToPoints(1)

に変更をして実行してみます。

エクセルVBAで上下マージンを1cmに設定

ちょうど良いマージンになりました。

まとめ

エクセルVBAで印刷設定をページ中央配置にする方法上下左右のマージンを設定する方法についてお伝えしました。

全部PageSetupオブジェクトで設定できるのでわかりやすいですね。ちょっとプロパティの数は多いですが…

また、PrintPreviewメソッドによるプレビューの表示の仕方についてもお伝えしました。

本番のプログラムでは使わないと思いますが、デバッグなど開発途中では便利そうですよね。

次回は、シートが複数ある場合に一気にPDF出力する方法についてお伝えできればと思います。

どうぞお楽しみに!

連載目次:エクセルVBAでPDF出力と色々な印刷設定

  1. 初心者でも簡単!エクセルVBAでPDFを出力する最もシンプルなプログラム
  2. エクセルVBAで印刷時のページ中央配置と余白を設定する

企業がリモートワーカーを利用する理由、そしてリモートワーカーが優秀な理由

$
0
0

みなさん、こんにちは!
タカハシ(@ntakahashi0505)です。

先日「採用せずに、130%の業務拡大を実現した外部リモートワーカー活用勉強会」というイベントに参加してきました。

企業側の視点で人材確保の一つの選択肢として「リモートワーク」に着目した内容です。

株式会社エス・エム・エスファイナンシャルサービスの岩谷さん、我らがChatWork株式会社の働き方エバンジェリスト河野さん、そして本日主催の株式会社casterのCEO中川さん、石野さんのパネルディスカッション形式です。

その中で「リモートワーカーさんがとにかく優秀だ!」というお話がありました。

なぜリモートワーカーは優秀なのか、その点に焦点を置いてレポートをしていきたいと思います。

オンラインアシスタント・秘書サービスCasterBizについて

casterさんが提供するサービスCasterBizは、会社の事務業務や秘書業務をはじめとする業務をリモートワーカーに依頼をできるサービスです。

例えば毎月実働30時間であれば3カ月契約で10万円~依頼でき、今回登壇されているSMSさん、ChatWorkさんも利用されています。

弊社もそうですが人員の少ない企業だと、コアワークにかけられる時間が生命線なので、電話受付やら名刺発注やらのそれ以外の仕事をまるっと採用コストなしでお願いできる非常にありがたいサービスと言えます。

中川さんのお話ですと、CasterBizで登録されているリモートワーカーさんは比率として圧倒的に女性が多いそうです。時代ですね…。

ちなみに企業のうちリモートワークの利用実績は7%…まだまだ低い傾向とのことでした。

リモートワーカーを利用する理由は?

ChatWorkさんはもともと提供されるサービスからリモートワークはむしろ得意分野だというのはわかるのですが、SMSさんはグループとしては介護、医療系かつ従業員も連結で1000人近くもいらっしゃる大企業。

なぜ、リモートワーカーを利用する必要があるのでしょうか?

SMSの岩谷さんは何度も「リモートワーカーさんは優秀だ」とおっしゃられていました。

弊社もブログ執筆やその他お仕事について、リモートワーカーを募集しておりまして応募はボチボチ来ます。

確かに、お仕事をお願いしている方は超優秀な方ですが、本当に全部が全部優秀なのかな?と疑って聴いていました。

casterの中川さんにその理由を尋ねてみると

  • 年間300~500人の応募があり、その中から質重視で厳選
  • 実際にトライアルのお仕事を担当してもらって、評定をつけて高い人から採用
  • skypeなどの面談など定期的にしている

とのこと。

なるほど、厳選されてますね~。

リモートワーカーが優秀な理由を考える

casterさんが厳選されているというのも当然あるのですが、そもそもリモートワーカーさんが優秀になりやすい理由がいくつかあるのではないかと感じました。

その理由についてお伝えしていきたいと思います。

働く人それぞれがベストパフォーマンスを発揮できる環境がある

ChatWorkさんは、リモートもオフィス勤務も自由に選択できるスタイルなのですが、河野さんがお話されたエピソードを一つ紹介します。

とあるエンジニアさんが、もともと通える距離だったというのもあってオフィス勤務をしていたのですが、ある事情で一定期間リモート勤務になりました。

そしたら、そのエンジニアさんのパフォーマンスが劇的に上がったんですね。

周りから見て明らかだったので、リモート勤務に切り替わったそうです。

オフィス勤務は、経営者やマネージャーから見ると管理をしやすい環境かも知れませんが、個々のスタッフが最大限実力を発揮できる環境かというとそれは違うということですね。

さて、別の例として兵庫県西脇市でリモートワークをするプログラマーである伊藤さんの記事を紹介します。

その中で田舎暮らしを選択している理由を

僕が独身でひたすら最新の技術だけを追い求めたい、と考えているのであれば、東京に住むのがベストです。
しかし「家族と暮らす、子どもを育てる」という目的ができた現在では、東京よりも今住んでいる西脇の方が僕にとってはるかに素敵な町です。

とおっしゃっています。大事なものがそこにあるんですよね。

そして、まとめの一文がジーンとしつつ、深い意味が込められています。

田舎に住んでて良かった!リモートで働けて良かった!
しばらくこのスタイルを手放したくないので、突然仕事を失ったりしないよう、これからも精進していきます。

そうなんです。リモートワークは時間で測れない分、成果が求められます。

ですから、リモートワークでの仕事をし続けたい人は、もらった金額以上の価値提供をすることにこだわる、だから優秀になりやすいのではないかと思います。

集中しやすく、記録がしやすい

もう一つ別の方の記事を紹介したいと思います。

普段徳島県でリモートワークをされていたのですが、一定期間東京に勤務をされた「リモートのdanyさん」の例です。

箇条書きで東京勤務で感じられたことをわかりやすくまとめて頂いているのですが、特にコミュニケ―ション関連について抜粋します。

  • 口頭での情報共有がとても多い。人によるけど、あまり記録に残らなかったり。
  • 特に非開発系の人とのやり取りは東京に居てめちゃめちゃ捗った。
  • 初めて同じ場所で長時間作業できたことで、リモートに戻ってからもコミュニケーションしやすいなと感じる部分はあったり。
  • 「話しかける」というストレスコストは東京の方が圧倒的に少ない。
  • 「話しかけられる」というインタラプトコストは東京の方が圧倒的に多い。
  • 「集中するぞ」って切り替えやすいのは、確かにリモート。やっぱり人が周りにいると、声でかい人の声はイヤホン突き抜けるし、人の動きもなんだかんだで気になる。

オフィスでは必然的に口頭でのコミュニケーションが多くなります。それによって、非常に効率の良いかつ「雰囲気」なども含む密度の濃い情報交換が可能です。

しかし、その代償として集中を遮られるというのはあります。

これは私もサラリーマン時代と比較してとても強烈に感じていますが、リモートワークはインタラプトつまり仕事を遮られることが圧倒的に少ないです。

チャットワークは多少の時間であれば返事をしなくても何とも思われませんが、口頭で話しかけられて無視をしていたとすると多少の時間でもすごく印象悪いですもんね。

そしてもう一点の代償ですが、記録に残さないというのがあります。

サラリーマンのときは、同じことを何度も聞いてくる方がいました。

メモっといてくれ!と心底思いましたが、彼らからすると私がいることでメモる必要がないわけです。

一方で、リモートの場合は何せ成果主義ですから、何度も同じことを聞くのははばかられます。というか、チャットの履歴を見れば何度も聞く必要がありませんからね。

ということで、リモートワークに慣れている方は、集中しやすいそして記録する(というか記録されている)ということで優秀になりやすいのかと思います。

まとめ

リモートワーカーさんが優秀になりやすい理由について、イベントのレポートといくつかの記事から考察してみました。

決してオフィス勤務を否定するつもりはありませんし、全てのリモートワーカーが必ず優秀だというわけではないとは思います。

ですが、正社員や派遣社員の採用がなかなかうまくいかないと感じられるのであれば、選択肢の一つとして検討して全く損はないと思います。

大事なのは、切れるカードとして持っておくということです。

さて、今回のイベントでは、実際にリモートワークを導入する上での課題やその解決法などもお話がありましたので、機会をみてそのあたりも記事にしたいですね。

エクセルVBAでインデントや改行を入れながらHTML文を追加していく便利関数を作る

$
0
0

price

みなさん、こんにちは!
タカハシ(@ntakahashi0505)です。

エクセルVBAで自動でHTML生成をするといったことを進めています。

具体的には

  • Bootstrapを使ったWordPressによる企業向けサイト
  • service,plan,aboutの3つのセクションによるトップページ
  • エクセルの入力情報から自動生成する

といった方針です。

前回はこちらの記事で、serviceセクションを作りました。

エクセルVBAでWordPress投稿用HTMLソースを自動で生成する
WordPressサイトのソースをエクセルVBAで自動生成する方法についてのシリーズ。初回の今回ですが、エクセルの入力情報をもとにシングルページの1つのセクションについて自動でコード生成をする方法です。

ただちょっと、文字列連結のアンパサンド(&)がたくさんあって見づらいんですよね。

今回は、タブコードや改行コードを入れながらHTML文を追加していく処理を関数化してスッキリさせつつ、Planセクションを生成するプログラムも作っていきたいと思います。

では、よろしくお願いいたします!

前回のおさらい:ServiceセクションのHTMLを生成する

前回のプログラムのおさらいです。

メインのプロシージャがこちら。

Sub createTopHTML()

Dim strHTML As String

Dim ws As Worksheet
For Each ws In ThisWorkbook.Worksheets

    Select Case ws.Name

        Case "service"

            strHTML = strHTML & createServiceSection(ws)

        Case "plan"

        Case "about"

    End Select

Next ws

Debug.Print strHTML

End Sub

生成されたHTMLがイミディエイトウィンドウに出力されます。

serviceセクションを生成する関数createServiceSectionはこちらです。

Function createServiceSection(ByVal ws As Object) As String

Dim str As String

'section開始タグ
str = str & "<section id=""service"" class=""section"">" & vbCr

'***** セクションタイトルB1,セクション概要B2 *****
str = str & vbTab & _
        "<h1 class=""section-title"">" & ws.Range("B1").Value & _
        "<p class=""small"">" & ws.Range("B2").Value & "</p></h1>" & vbCr

'***** カラム *****
'class="row"の開始タグ

str = str & vbTab & "<div class=""row"">" & vbCr

Dim i As Long
For i = 5 To 8 '4カラム分繰り返し

    'class="col-sm-x"の開始タグ
    str = str & vbTab & vbTab & "<div class=""col-sm-3"">" & vbCr

    'タイトルB列
    str = str & vbTab & vbTab & vbTab & "<h2 class=""h4 text-center"">" & ws.Cells(i, 2).Value & "</h2>" & vbCr

    'サムネイル画像(枠のみ)
    str = str & vbTab & vbTab & vbTab & "<div class=""thum""><img src=""http://placehold.it/300x225"" /></div>" & vbCr

    'テキストC列
    str = str & vbTab & vbTab & vbTab & "" & ws.Cells(i, 3).Value & "</p>" & vbCr

    'class="col-sm-x"の閉じタグ
    str = str & vbTab & vbTab & "</div>" & vbCr

Next i

'class="row"の閉じタグ
str = str & vbTab & "</div>" & vbCr

'section閉じタグ
str = str & "</section><!-- service -->" & vbCr

createServiceSection = str

End Function

…やっていることは文字列の連結なので、さほど難しいことをしているわけではないのですが、タブコードvbTabや改行コードvbCrなども入れるとアンパサンド(&)が多くなり見づらいですね。

まずはこの文字列の連結を関数化することでスッキリしていきましょう。

HTML文への文字列連結をする関数addHTML

createServiceSectionの各行は元の文字列strに文字列を追加していくという処理ですが

  • 元の文字列の後ろに文字列を一行ずつ追加する
  • 各行の冒頭にタブコードvbTabが0~3つ入る
  • 各行の最後は改行コードvbCr

という法則性があります。

したがって、この処理を関数化することでコードをスッキリさせることができそうです。

この後に作るであろうplanセクションやaboutセクションのHTML生成にも便利ですし、後で読み返すときやメンテナンスするときに簡潔に書いておくほうが良いからです。

脱プログラミング初心者のためのバイブル「リーダブルコード」のススメ
とにかくプログラマーというプログラマーが皆さんオススメしまくっている本「リーダブルコード」。その名のとおり「読みやすいコード」を書くための実践的なテクニックを凝縮している本書について紹介します。

関数addHTMLのプログラム

その部分を関数化したaddHTMLはこちらです。

Function addHTML(ByVal strBase As String, ByVal cntIndent As Long, ByVal strAdd As String) As String

If cntIndent > 0 Then

    Dim i As Long
    For i = 1 To cntIndent

        strBase = strBase & vbTab

    Next i

End If

strBase = strBase & strAdd & vbCr

addHTML = strBase

End Function

各引数は

  • strBase:元のHTML文字列
  • cntIndent:タブコードの数
  • strAdd:追加する特定の文字列

として与えれます。

この関数では元の文字列に

  1. 必要な数のタブコードを追加
  2. 特定の文字列を追加
  3. 改行コードを追加

して文字列を返します。

addHTMLを使ってcreateServiceSectionを書き直す

関数addHTMLを使ってcreateServiceSectionを書き直すと、このようになります。

Function createServiceSection(ByVal ws As Object) As String

Dim str As String
str = ""

'section開始タグ
str = addHTML("", 0, "<section id=""service"" class=""section"">")

'***** セクションタイトルB1,セクション概要B2 *****
str = addHTML(str, 1, "<h1 class=""section-title"">" & ws.Range("B1").Value & "<p class=""small"">" & ws.Range("B2").Value & "</p></h1>")

'***** カラム *****
'class="row"の開始タグ
str = addHTML(str, 1, "<div class=""row"">")

Dim i As Long
For i = 5 To 8 '4カラム分繰り返し

    'class="col-sm-x"の開始タグ
    str = addHTML(str, 2, "<div class=""col-sm-3"">")

    'タイトルB列
    str = addHTML(str, 3, "<h2 class=""h4 text-center"">" & ws.Cells(i, 2).Value & "</h2>")

    'サムネイル画像(枠のみ)
    str = addHTML(str, 3, "<div class=""thum""><img src=""http://placehold.it/300x225"" /></div>")

    'テキストC列
    str = addHTML(str, 3, "" & ws.Cells(i, 3).Value & "</p>")

    'class="col-sm-x"の閉じタグ
    str = addHTML(str, 2, "</div>")

Next i

'class="row"の閉じタグ
str = addHTML(str, 1, "</div>")

'section閉じタグ
str = addHTML(str, 0, "</section><!-- service -->")

createServiceSection = str

End Function

少しわかりやすくなりましたね。

planセクションを生成するプログラム

では、続いてplanセクションを生成するプログラムを作っていきます。

エクセルシートはこのように準備しました。

planセクションのテキスト情報

planセクションはserviceセクションと同じく4カラムで、類似しています。

プランノーツサイトのplanセクション

異なる点としては、サムネイルとタイトルの順番が異なり、小さめの文字フォントで金額が記載されているという点です。

ですから、createServiceSectionをコピーして必要箇所の書き換えや行の入れ替えをすればできそうです。

planセクションを生成するcreatePlanSection

planセクションを生成するcreatePlanSectionはこちらです。

Function createPlanSection(ByVal ws As Object) As String

Dim str As String
str = ""

'section開始タグ
str = addHTML("", 0, "<section id=""plan"" class=""section"">")

'***** セクションタイトルB1,セクション概要B2 *****
str = addHTML(str, 1, "<h1 class=""section-title"">" & ws.Range("B1").Value & "<p class=""small"">" & ws.Range("B2").Value & "</p></h1>")

'***** カラム *****
'class="row"の開始タグ
str = addHTML(str, 1, "<div class=""row"">")

Dim i As Long
For i = 5 To 8 '4カラム分繰り返し

    'class="col-sm-x"の開始タグ
    str = addHTML(str, 2, "<div class=""col-sm-3"">")

    'サムネイル画像(枠のみ)
    str = addHTML(str, 3, "<div class=""thum""><img src=""http://placehold.it/300x225"" /></div>")

    'タイトルB列&価格C列
    str = addHTML(str, 3, "<h2 class=""h4 text-center"">" & ws.Cells(i, 2).Value & "<p class=""small"">" & ws.Cells(i, 3).Value & "</p></h2>")

    'テキストD列
    str = addHTML(str, 3, "" & ws.Cells(i, 4).Value & "</p>")

    'class="col-sm-x"の閉じタグ
    str = addHTML(str, 2, "</div>")

Next i

'class="row"の閉じタグ
str = addHTML(str, 1, "</div>")

'section閉じタグ
str = addHTML(str, 0, "</section><!-- plan -->") & vbCr

createPlanSection = str

End Function

実行により出力されたデータをWordPressでプレビューしてみます。

生成したplanセクションのHTMLソースのプレビュー
バッチリですね。

まとめ

エクセルVBAで自動でHTML生成をするプログラムですが、今回はserviceセクションの文字列連結部分を関数化してスッキリさせるとともに、それを活用してplanセクションを生成する関数を作成しました。

あとトップページに関してはaboutですね。

次回、お伝えしていきたいと思います。

お楽しみに!

連載目次:エクセルの入力情報からVBAでHTML文を自動生成

  1. エクセルVBAでWordPress投稿用HTMLソースを自動で生成する
  2. エクセルVBAでインデントや改行を入れながらHTML文を追加していく便利関数を作る

Google Apps Scriptで毎朝チャットワークに電車の遅延情報をプッシュ通知する

$
0
0

train

みなさん、こんにちは!
タカハシ(@ntakahashi0505)です。

以前、Google Apps Scriptでチャットワークに天気予報を送る方法についてお伝えしました。

【GAS】JSON形式のデータを取り出してチャットワークに天気予報を送る
Google Apps Scriptを使ってチャットワークに天気予報を送るシステムを作成中です。今回はJSON形式で受け取ったデータの中から必要な情報を取り出し、チャットワークに送る部分を組みます。

これで定期的にチャットワークのマイチャットに天気予報が送られてくるようになったのですが、お出かけをすると考えた場合に、もう一つ欲しい情報がありますよね。

そうです、電車の運行情報です。

毎朝、家を出る時間に通勤で使用する路線の運行情報がチャットワークに送られてきたら便利ですよね。

ということで、今回はGoogle Apps Scriptで電車の運行情報をチャットワークに送る方法についてお伝えします。

鉄道遅延情報のjson

まず、路線の運行情報を取得できるAPIが必要です。

今回は鉄道遅延情報のjsonを使わせてもらおうと思います。

少し手作り感はありますが、Tetsudo.comさんから許可を得て、そのRSSを取得してjsonを生成しているとのこと。更新は10分ごとです。

こちらのURL

https://rti-giken.jp/fhc/api/train_tetsudo/delay.json

にリクエストを送ることで、遅延が起こっている路線の情報をJSON形式で得ることができます。

ですから、逆に言うと遅延が起きていない路線の情報は含まれていないということですね。

JSONの構造は

[
     {"name":"武蔵野線","company":"JR東日本","lastupdate_gmt":1460881621,"source":"鉄道com RSS"},
     {"name":"中央・総武各駅停車","company":"JR東日本","lastupdate_gmt":1460881621,"source":"鉄道com RSS"},
     //以下同
     {"name":"予讃線","company":"JR四国","lastupdate_gmt":1460881502,"source":"鉄道com RSS"}]
]

となっていますね。要素は

  • name:路線名
  • company:運営会社名
  • lastupdate_gmt:更新時間(UNIX時間)
  • source:情報ソース

の4種類です。

遅延情報をチャットワークへ送るスクリプト

スクリプトの流れ

スクリプトの大まかな流れを考えてみましょう。

  1. 鉄道遅延情報のjsonにリクエストをし、レスポンスを取得
  2. json内の全てオブジェクトについて
    • 指定した路線と運営会社名とマッチしたデータがあれば
      • チャットワークへ送る文字列を「●●が遅延しています」
  3. チャットワークへ送る文字列が空ならば
    • チャットワークへ送る文字列を「本日の遅延はありません」
  4. チャットワークへ文字列を送る

という流れです。

1はさらに分解すると

  1. UrlFetchApp.fetchメソッドでURLリクエストを送る
  2. getContentTextで純粋なテキストデータのみ取り出す
  3. JSON.parseでJSONデータを解析し配列に格納する

という流れになります。

詳細はこちらの記事へどうぞ。

【Google Apps Script】天気予報をWeb APIで取得する方法
チャットワークに天気予報を通知するを目標に、今回はWeb APIとは何か、Google Apps Scriptでlivedoor天気情報のWeb APIからJSON形式のデータを取得してくる方法です。

4は以前作成したチャットワークへメッセージを送るsendMessage関数を使います。

【GAS】チャットワークのメッセージを取り出す関数とメッセージを送る関数
Google Apps Scriptを活用してチャットワークにおみくじチャットを作成しています。今回はチャットワークからメッセージを取り出す、メッセージを送る処理を関数化して全体のコードをスッキリさせます。

実際のコード

スクリプトを作ってみました。こちらです。

function fetchDelayInfo() {

  var token = 'APIトークン'; //チャットワークAPIトークン
  var room_id = XXXXXXXX; //ルームID

  //電車遅延情報をJSON形式で取得
  var json = JSON.parse(UrlFetchApp.fetch("https://rti-giken.jp/fhc/api/train_tetsudo/delay.json").getContentText());

  var name="日比谷線";
  var company="東京メトロ";
  var body="";

  for each(var obj in json){

    if(obj.name === name && obj.company === company){

      body = "[info][title]電車運行情報[/title]" + company + name + "が遅延しています(^^;)";
    }
  }

  if(!body){ 
    body = body + "[info][title]電車運行情報[/title]本日の遅延情報はありません(nod)";
  }

  body = body + "[/info]";
  sendMessage(token,room_id,body);
}

9,10行目で路線名と運営会社名を指定すれば、その路線について判別をしてチャットワークに送ります。

21行目のif文ですが、空の文字列はif文ではfalseの判定になります。その否定ですから、bodyが空の文字列であればtrueになり、if文内の処理を実行します。

実行結果

実行結果ですが、例えば遅延情報があった場合は

遅延があった場合のチャットワークへの通知

遅延情報がなかった場合は

遅延がなかった場合のチャットワークの通知
とそれぞれチャットワークにメッセージが送られます。

毎日の出勤であれば、例えばイベントトリガーで毎朝6時~7時などに設定をすれば、自動で送られるようになります。

まとめ

Google Apps Scriptで電車の運行情報をチャットワークに送る方法についてお伝えしました。

データを取得するためのリクエストURLやレスポンスで得られるjsonの構造は違いますが、それ以外は天気予報の取得とさほど変わりありませんね。

さて、今回は1つの路線のみしかチェックができませんでしたが、次回は複数の路線をチェックできるように改良をしていきたいと思います。

どうぞお楽しみに!

GoogleスプレッドシートとExcelで使える日付関連の関数まとめ

$
0
0
date-stamp

photo credit: datestamp via photopin (license)

みなさん、こんにちは!
タカハシ(@ntakahashi0505)です。

Googleスプレッドシートやエクセルで日付に関する処理をする場合も多いですよね。

ただ、けっこう日付の処理って、ややこしいしたくさん関数があって覚えきれなかったりしますよね。

今回は、スプレッドシートで使える日付関連の関数を一通り紹介したいと思います。

ちなみにですが、実は今回紹介する関数はExcelでも全く同じように使えますので、一石二鳥。

では、行ってみましょう。

スプレッドシートで使える日付関連の関数

今日の日付を求める

今日の日付を求める関数はTODAY関数です。

TODAY()

括弧内は何も書かないでOKです。

特定の日付から年、月、日を取り出す

ある日付から年、月、日を取り出したい場合はそれぞれYEAR,MONTH,DAY関数

YEAR(日付)
MONTH(日付)
DAY(日付)

とします。

例えば日付が「2016/4/18」であれば

  • YEAR(“2016/4/18”) → 2016
  • MONTH(“2016/4/18”) → 4
  • DAY(“2016/4/18”) → 18

となります。

年、月、日を指定して日付にする

逆に、年月日を指定して日付にしたい場合はDATE関数

DATE(年,月,日)

と書きます。

何カ月後の日付を求める

ある特定の日から指定の月数だけ加算した日の日付を求めたい場合はEDATE関数を使います。

書き方は

EDATE(開始日,月数)

です。

例えば以下の場合はそれぞれ

  • 来月の同じ日付:EDATE(TODAY(),1)
  • 前月の同じ日付:EDATE(TODAY(),-1)
  • 1年後の同じ日付:EDATE(TODAY(),12)

と書きます。

末日を求める

月末の日付を求める場合はEOMONTH関数を使います。

書き方はこうです。

EOMONTH(開始日,月数)

例えば

  • 今月末:EOMONTH(TODAY(),0)
  • 来月末:EOMONTH(TODAY(),1)
  • 前月末:EOMONTH(TODAY(),-1)

などと使います。覚えておくと便利です。

日付関連の関数を使った演習

さて、では演習です。

チャットワークに自動でタスクを追加するというシステム作りを進めているのですが、このようなスプレッドシートがあります。

スプレッドシートで次のタスク期限を求める

記事はこちらですので、ご興味があればどうぞ。

【GAS】スプレッドシートに記載したタスクを毎日チャットワークに自動で追加する
Google Apps Scriptを使ってスプレッドシートの定期タスクをチャットワークのタスクとして自動で追加するシステムを作ります。今回はスプレッドシートの毎日のタスクについてしぼって実現します。

さて、今まで紹介した関数を駆使ししてF4セルとF5セル、つまり「次のタスク期限」を求める適切な数式を入れたいと思います。

では、それぞれ求めていきましょう。

今日の日にちを条件に今月または来月の特定の日を求める

F4セルは

  • 今日の日にちがE4セルで指定した日以前の日にちであれば、今月のE4セルと同じ日にちの日
  • 今日の日にちがE4セルで指定した日より後の日にちであれば、来月のE4セルと同じ日にちの日

と設定をしたいです。

条件によって分岐があるのでまずIF関数を使います。

IF(論理式, TRUE値, FALSE値)

論理式の部分ですが、「今日の日にちがE4セルで指定した日より後の日にちであれば」という式については

  • 今日の日にち:DAY(TODAY())
  • E4セルで指定した日にち:E4

ですから

IF(DAY(TODAY())>E4, TRUE値, FALSE値)

と表現することができます。

次にFALSE値からいきますが、「今月のE4セルと同じ日にちの日」は

  • 年は今日の日付と同じ年
  • 月は今日の日付と同じ月
  • 日はE4セル

ですから

DATE(YEAR(TODAY()),MONTH(TODAY()),E4)

と表現できます。

TRUE値は「来月のE4セルと同じ日にちの日」ですからつまり「今月のE4セルと同じ日にちの日」のちょうど一月後です。

EDATE(DATE(YEAR(TODAY()),MONTH(TODAY()),E4),1)

です。ややこしいですけど、コピペすれば簡単。

もしくは

DATE(YEAR(TODAY()),MONTH(TODAY())+1,E4)

と書くことができます。

ですから、F4セルは

=IF(DAY(TODAY())>E4,DATE(YEAR(TODAY()),MONTH(TODAY())+1,E4),DATE(YEAR(TODAY()),MONTH(TODAY()),E4))

とすればよいということです。

条件に応じて月末日を求める

次にF5です。

E5セルを見て「末」と書いてあれば、その月の月末日を求めるということです。

こちらは簡単ですね。

=IF(E5="末",EOMONTH(TODAY(),0))

で、「末」と書いていない場合は先ほどのF4の場合を当てれば両方のパターンで使えますので

=IF(E5="末",EOMONTH(TODAY(),0),IF(DAY(TODAY())>E5,DATE(YEAR(TODAY()),MONTH(TODAY())+1,E5),DATE(YEAR(TODAY()),MONTH(TODAY()),E5)))

としておきます。

超長いですが、分解して段階を踏めば…なんとかなりますでしょ?

まとめ

スプレッドシートで使える日付関連の関数を多数お伝えしました。リファレンス的にご活用頂ければうれしいです。

  • 今日の日付を求める:TODAY()
  • 日付から年を取り出す:YEAR(日付)
  • 日付から月を取り出す:MONTH(日付)
  • 日付から日を取り出す:DAY(日付)
  • 年月日を指定して日付にする:DATE(年,月,日)
  • 特定の日から指定の月数だけ加算した日の日付を求める:EDATE(開始日,月数)
  • 特定の日の月末の日付を求める:EOMONTH(開始日,月数)

お伝えするのは2回目になりますが、これらの関数はExcelでも全く同じように使えます。

ぜひマスターしちゃいましょう。

次回、これを活用してチャットワークに自動でタスクを追加する記事の続きを書きますので、よろしければそちらもどうぞ。

連載目次:GASでチャットワークに自動でタスク追加をする

  1. Google Apps Scriptでチャットワークにタスクを追加する最も簡単なプログラム
  2. Google Apps Scriptでチャットワークに期限付きのタスクを追加する
  3. 【GAS】スプレッドシートに記載したタスクを毎日チャットワークに自動で追加する
  4. GoogleスプレッドシートとExcelで使える日付関連の関数まとめ

初心者でも簡単!Contact Form 7の表示をテーブル化してかっこよくするカスタマイズ

$
0
0
contact

photo credit: via photopin (license)

みなさん、こんにちは!
タカハシ(@ntakahashi0505)です。

WordPressのプラグイン「Contact Form 7」は利用されていますか?

いわゆる「問い合わせフォーム」を簡単に作ることができる超超超定番プラグインの一つです。

WordPressで企業サイトを作っている場合、ブログサイトでコンテンツマーケティングをする場合には、問い合わせフォームは必須ですから、Contact Form 7はたいへん重宝します。

ですがこのContact Form 7。ちょっと見た目が寂しい…。

ということで、今回はテーブル化とCSSでContact Form 7による問い合わせフォームの見栄えをよくする方法についてお伝えします。

ちょっとのカスタマイズでできますので、初心者でも簡単ですよ!

デフォルトのContact Form 7による問い合わせフォーム

最初にContact Form 7のデフォルトの問い合わせフォームはこんな感じ、というのを共有しておきましょう。

まず、WordPress管理画面の「お問い合わせ」から編集したいコンタクトフォームを選択すると

Contact Form 7のコンタクトフォーム編集画面

このような編集画面が開きます。

この中に表示する内容やフォーム部品を入力していって、問い合わせフォームを作るわけですね。

お名前 (必須)<br />
    [text* your-name placeholder akismet:author "山田 太郎"] 

メールアドレス (必須)<br />
    [email* your-email placeholder "sample@example.com"]

題名<br />
    [text* your-subject] 

メッセージ本文<br />
    [textarea* your-message]

[submit "送信"]

実際に表示する内容をpタグ内にベタベタと書いていき、テキストや入力部品を編集していきます。

ちなみに上記はほぼデフォルトで入力されているものを少し変えただけです。

実際の表示は

ほぼデフォルトのコンタクトフォームの表示

となります。

それにしてもちょっと寂しい…。

では、少しコーディングをしてテーブル表示にしていってみましょう。

Contact Form 7の表示をテーブル化する

コンタクトフォームの編集でContact Form 7の表示をテーブル化していきます。

なおプレビュー機能がないので、表示を確認するには保存して更新するしかありません。

念のため、以前のコンタクトフォームの内容は「」でコメントアウトにしておくか、新規のコンタクトフォームを作りましょうね。

もとに戻したいときに困ります。

では、単純に上記の内容(送信ボタン以外)をテーブルで構成してみましょう。

<table>
  <tr>
    <th>お名前 (必須)</th>
    <td>[text* your-name placeholder akismet:author "山田 太郎"]</td>
  </tr>
  <tr>
    <th>メールアドレス (必須)</th>
    <td>[email* your-email placeholder "sample@example.com"]</td>
  </tr>
  <tr>
    <th>題名(必須) </th>
    <td>[text* your-subject]</td>
  </tr>
  <tr>
    <th>メッセージ本文(必須) </th>
    <td>[textarea* your-message]</td>
  </tr>
</table>
[submit "送信"]

  • 全体をtableタグで囲む
    • 一行ずつをtrタグで囲む
      • 見出しはthタグで囲む
      • 入力フォーム部品はtd部品で囲む

という構成にします。

ちなみに、WordPressのエディタはインデントが使いづらいので、Atomなどのエディタで作って貼り付けるとコーディング楽ちんですよ。

では、表示を確認してみましょう。

テーブル化したコンタクトフォームの表示

…うーん、良くなったようななってないような…。

少しCSSをいじっていきましょう。

Contact Form 7の簡単CSSカスタマイズ

クラスの追加とCSSの修正をすることで、表示をかっこよくしていきたいと思います。

ちなみに、CSSの追加は子テーマに対して行うようにしましょうね。

子テーマはテーマ制作者が用意してくれている場合があります。詳しくは以下記事もご覧ください。

WordPressの面倒な子テーマ作成&有効化をコマンド一発で実行する方法
WP-CLIでWordPressをコマンドラインから操作するシリーズも終盤です。今回はwpコマンドを使ってコマンドラインからWordPressの空の子テーマを瞬時に作成する方法についてお伝えします。

テーブルの余白を調整し偶数行に色を付ける

まずテーブル全体として以下修正することで、かっこよくしていきます。

  • テーブルの各要素の余白を追加
  • 一行ごとに色を変える

これらは、たった1つのクラスを追加することで実現できます。

コンタクトフォームの編集でtableタグに「table-ctf7」というクラスを追加します。

<table class="table-ctf7">

次にCSSですが以下を追加します。

.table-ctf7 tr th,td {
    padding: 10px; /* 余白を10px持たせる */
    border-top: 1px #DDD solid; /* 上側にグレーの実線を引く */
}

.table-ctf7 tr:nth-child(even) {
    background-color: #F9F9F9; /* 偶数行をうっすらグレーに */
}

たったこれだけです。

それぞれの意味はコメントをご覧いただければわかると思いますが、偶数行にどうこうというCSSセレクタの使い方はクールですよね。

実際の問い合わせフォームの表示はこちら。

CSSでtableをカスタマイズしたコンタクトフォームの表示

いいですね~。

ちなみに、Bootstrapを導入していればCSSをいじらずともtableタグを

<table class="table table-striped">

などとするだけで同じようにできます。

「※必須」の文字だけCSSを当てる

もう一点、「(必須)」をスマートにしていきましょう。

  • 「(必須)」を「※必須」と表記を変更
  • フォントサイズを小さく
  • フォントの色を赤に

という修正をしていきます。

特定の文字だけCSSを当てていくにはspanタグが便利ですね。

コンタクトフォームの編集で「(必須)」は「※必須」に変更をしつつ「required」というクラスを追加して

<span class="requied">※必須</span>

に置換していきます。

CSSは以下を追加。

.table-ctf7 span.requied {
    font-size: 10px; /* フォントサイズを10pxに */
    color: red; /* フォントカラーを赤に */
    font-weight: normal; /* フォントの太さを通常に */
}

これでOKです。

では、問い合わせフォームの表示を見てみましょう。

CSSでテキストをカスタマイズしたコンタクトフォームの表示
良い感じですね。

まとめ

WordPressのプラグインContact Form 7の問い合わせフォームについてテーブル化およびCSSの調整で簡単にかっこよくする方法についてお伝えしました。

お問い合わせフォームはサイト内の他のコンテンツとくっきり分離されているので、CSSでのカスタマイズもしやすいですね。

WordPressでのCSSカスタマイズの練習に向いていると思いますよ!

また簡単めなWordPressのCSSカスタマイズについて見つけたら紹介したいと思います。

エクセルVBAで印刷範囲の設定をする方法とクリアをする方法

$
0
0

area

みなさん、こんにちは!
タカハシ(@ntakahashi0505)です。

エクセルVBAでPDF出力や印刷をする際の様々なテクニックをお伝えしています。

前回はこちらの記事。

エクセルVBAで印刷時のページ中央配置と余白を設定する
エクセルVBAでPageSetupオブジェクトを使って印刷設定をページ中央配置にする方法、また上下左右のマージンを設定する方法についてお伝えします。また印刷プレビューの表示方法も紹介します。

PageSetupオブジェクトの設定で印刷設定をページ中央配置にする方法と上下左右のマージンを設定する方法についてお伝えしました。

さて、以下記事でお伝えしたプログラムですが、縦横1ページに収めるという設定をしています。

初心者でも簡単!エクセルVBAでPDFを出力する最もシンプルなプログラム
エクセルVBAではPDF形式での出力もできます。今回は、初心者向けエクセルVBAでPDFを出力する最も簡単なプログラムと、PDF出力の際にシート1ページに収めて出力する方法についてお伝えしていきます。

この場合、本来印刷したくない領域も印刷範囲に含まれてしまい困ることがあります。

今回は、その点を解決すべく、エクセルVBAで印刷範囲の設定する方法についてお伝えしたいと思います。

また、印刷設定のクリアについてもお伝えします。

では、よろしくお願いいたします!

前回のおさらい:請求書の印刷プレビュー

まず前回のおさらいをしておきましょう。

プログラムはこちらです。

Sub outputPDF()
Dim fileName As String '保存先フォルダパス&ファイル名
fileName = ThisWorkbook.Path & "\201603請求書_株式会社ホゲホゲ御中.pdf"

With ActiveSheet.PageSetup

    .Zoom = False
    .FitToPagesWide = 1
    .FitToPagesTall = 1
    .CenterHorizontally = True
    .TopMargin = Application.CentimetersToPoints(1)
    .BottomMargin = Application.CentimetersToPoints(1)

End With

ActiveSheet.PrintPreview
'ActiveSheet.ExportAsFixedFormat Type:=xlTypePDF, fileName:=fileName '選択したシートをPDF出力

End Sub

「201603請求書_株式会社ホゲホゲ御中.pdf」という書類のPDFを出力するプログラムなのですが、検証中ということで実際のPDF出力はコメントアウトしていまして、代わりに16行の命令でプレビュー表示としています。

印刷の設定に関しては5行~14行のPageSetupオブジェクトの各プロパティで

  • シートを縦横1ページに収める
  • 水平方向にページを中央配置
  • 上下のマージンを1cmずつ

という設定を行っています。

今回のお題:社内向けのコメントを印刷範囲から外したい

今回のお題ですが、例えばこちらのようなシートがあるとします。

エクセルで印刷をしたい範囲

図の赤枠で囲ったエリアのみが本来印刷したいエリアで、「ここに品目、単価、数量を入力してください」という吹き出しによるコメントは印刷範囲として含みたくありません。

ですが、普通に印刷プレビューを見てみますと

エクセルでプレビュー

とこのように吹き出しまで全部印刷範囲に含まれてしまいます。

これ間違えて取引先に送ったら、こっぱずかしいですね~。

さて、エクセルで普通に印刷範囲の設定をする方法としては

  1. 印刷範囲を選択してアクティブにする
  2. リボンから「ページレイアウト」→「印刷範囲」→「印刷範囲の設定」

としますね。

エクセルで印刷範囲の設定をする

これをVBAでやりたい場合はどうしたらよいでしょうか?

印刷範囲の設定とクリア

エクセルVBAで印刷範囲を設定する場合はPageSetupオブジェクトのPrintAreaプロパティを使います。

書き方は

WorkSheetオブジェクト.PageSetup.PrintArea=範囲を表す文字列

です。

ここで、「範囲」ではなくて「範囲を表す文字列」であることに注意してください。

Rangeオブジェクトではなくて文字列で指定するということです。

例えば今回の場合はA1からD60までの範囲ですから、PageSetupのWithのブロック内に

.PrintArea = "A1:D60"

を追加してあげればOKです。

それで実行をしますと

エクセルで印刷範囲を設定してプレビュー

このように必要なところのみが印刷範囲となっていることがわかります。

Addressプロパティで範囲の文字列を求める

Rangeオブジェクトから範囲を表す文字列を求める方法がありますので、触れておきたいと思います。

Addressプロパティを使いまして

Rangeオブジェクト.Address

とすることで、範囲を表す文字列を取得できます。

例えば「Range(“A1:D60”).Address」であれば、「$A$1:$D$60」という文字列が得られます。

今回の例ではわざわざ使う必要はないのですが、あえてAddressプロパティを使うと

.PrintArea = ActiveSheet.Range("A1:D60").Address

となります。

範囲の文字列は列全体でもOK

PrintAreaで指定する範囲の文字列は列のみの指定でも動作します。

今回の例ではD列までを印刷範囲としたいので

.PrintArea = "A:D"

としてもOKです。

印刷範囲のクリアをする

印刷範囲のクリアをする場合は

WorkSheetオブジェクト.PageSetup.PrintArea=”” または false

と設定をします。

人為的に印刷範囲の設定が行われる可能性があるシートに対して、VBAで印刷やPDF出力をする際などには念のためで入れておくのが良いかも知れません。

まとめ

エクセルVBAで印刷範囲の設定をする方法とクリアをする方法についてお伝えしました。

引き続きPageSetupオブジェクトが大活躍でしたね。

設定する場合はRangeオブジェクトではなく範囲を表す文字列で設定をするということをお忘れなく。

次回は印刷のヘッダーやフッターを指定する方法についてお伝えしたいと思います。

どうぞお楽しみに!

連載目次:エクセルVBAでPDF出力と色々な印刷設定

  1. 初心者でも簡単!エクセルVBAでPDFを出力する最もシンプルなプログラム
  2. エクセルVBAで印刷時のページ中央配置と余白を設定する
  3. エクセルVBAで印刷範囲の設定をする方法とクリアをする方法

MFクラウドExpo2016で学んだ、超クラウド後進国である日本を変えるためにすべき事

$
0
0

みなさん、こんにちは!
タカハシ(@ntakahashi0505)です。

先日MFクラウドExpo2016に参加してきました。

いやー、超疲れますが、ほんとに行って良かったです。いつもそう思います。

さて、MFクラウドと言えば、皆さまご存知の日本の代表的なクラウド会計ソフトの一つです。

もう言うまでもありませんが、MFクラウドを使うことで経理作業や確定申告、経費精算などが超劇的に簡単になります。

フリーランス・副業の経理作業はMFクラウド確定申告を使うのが良いです
個人事業主にとって避けては通れない経理と確定申告…それを断然楽にするクラウド会計ソフト「MFクラウド確定申告」について、その素晴らしさとちょっとしたテクニックについて紹介したいと思います。
MFクラウド経費アプリで領収書と交通費の経費精算が超簡単!
MFクラウド会計・確定申告ですが、このたびMFクラウド経費アプリがリリースされました!レシートや領収書などの経費や交通費などの仕訳が超簡単になりましたので、その使い方をお伝えしていきます。

今回、朝10時から夜19時まで、ランチ食べながらもセッションもあり、毎回15分しかない休憩時間に展示も見て回り、PCの充電補給もしつつ、てな感じでまったく休む暇のない密度の濃い一日でした。

その中から、いくつかレポートをしたいと思うのですが、今回は中小企業のクラウド利用率についてです。

本イベントでもそれに関連して色々と調べてみても、本当にガッカリすることばかりなのですが…

現実を直視すべしということで、元気よく行ってみます!

日本は超クラウド後進国?

MFクラウドExpo2016、冒頭は株式会社マネーフォワード代表取締役CEOの辻庸介氏のお話。

「クラウド経営とフィンテックがもたらす世界」というタイトルでさらさらとFintechを取り巻く国内外の様々なプレーヤーとその動き、法整備との関係性、MFクラウドとしての動きなどお話下さいました。

昨年も参加しましたが、国内外のFintechを取り巻く状況は劇的に変化しているな…と。

しかしながら、私がどうしても気になったのはこちらのスライドでした。

中小企業のクラウドサービス利用率 日米の比較

日米の中小企業のクラウドサービス利用率の比較です。

ちょっと斜めになっていて恐縮なのですが、クラウドサービスの利用率は

日本の中小企業:23%
米国の中小企業:59%

圧倒的な差がついています。

まじ、焦りました。

未だに進まない中小起業のクラウドサービス利用

出展が平成25年の情報通信白書ということで3年前のデータだからだろ、と思いまして平成27年のデータを見てみました。

日本企業のクラウドサービス利用率

総務省「平成26年通信利用動向調査」

一部でもクラウドサービスを利用していると回答した企業の割合は38.7%

おお!増えてますね~…と思いきや、資本金規模別(下図右側) で見てみますと

日本企業の業種別・資本規模別クラウドサービス利用率

総務省「平成26年通信利用動向調査」

資本金規模が1,000万円未満の企業のクラウドサービス利用率は29.5%です。

資本金規模が小さい=中小企業ではありませんが、規模の小さい企業ほどクラウドサービスを利用していない傾向は依然見て取れます。

中国企業のクラウド利用率は

アメリカがすごすぎるのかも知れませんね。

では、他の国とも比べてみましょう。

中国に関するクラウド利用に関するレポートです。

IDCが出した中国企業のクラウドに関するレポート によると、2015年時点で68%(同じレポートで日本は22%)の企業がクラウドサービス(IaaS、PaaS、SaaSのいずれか)を利用している。

…ダメでした。

二つの大国としか比べていませんが、日本だけが遅れていると思っていたほうがよさそうな気がします。

なぜ日本企業はクラウドを利用しないのか?

クラウドを利用しないという選択が、どう考えても私には理解できないのです…。

特に、クラウドサービスはまさに中小企業のためにあると思うんです。

例えば

  • チャットワーク:無料から利用可能、ビジネスプランは月500円/1アカウント
  • MFクラウド会計:フルで利用できるベーシックプランでも月2,980円
  • Googleの各種サービス/Google Apps for Works:無料から利用可能、ビジネスプランは月500円/1アカウント
  • Evernote:無料から利用可能、最もオススメのプレミアムプランでも月450円
  • Dropbox:月1,200円で1TB(!)

などなど、無料から使えるサービスも多数ありますし、有料でも大概はアカウント単位の従量制なので初期コストが劇的に安いんです。

激安なんです。

無料または激安で利用可能!お仕事に便利なクラウドサービスまとめ12選
技術の進歩によりお仕事に限らず様々なクラウドサービスが利用できるようになりました。今回はお仕事効率化オタクの私が「便利さ」「手軽さ」「価格」を重点ポイントとして12のサービスを厳選しまして紹介をしていきます。

その一つすら利用したことがない企業がまだ70%以上もいる…理由が知りたい!

なぜ日本企業はクラウドサービスを利用しないのか

それで、また総務省のデータを見てみます。

クラウドサービスを利用しない理由です。

日本企業がクラウドサービスを利用しない理由

総務省「平成26年通信利用動向調査」

44.7%が「必要がない」、34.5%がセキュリティ面の不安を挙げている

…まじですか…。本当に必要ないんですか?!

にわかには信じがたい。

少しヒントになるデータで、今度は平成25年の総務省のデータなのですがクラウドサービスの利用内訳つまりクラウドサービスを何に使っているか?です。

クラウドサービス利用の内訳

総務省「クラウドコンピューティング等のICT利活用に関する諸外国の政策等に係る調査研究」(平成25年)

この図では「情報系システム」と「基幹系システム」と大きく分けていますが、コミュニケーションなど全社的にかかわる部分のほうが、開発・人事・経理・生産管理などの部門別にかかわる内訳よりも米国との差が小さい印象です。

端的に言うと、私は現場に近いところほどクラウドサービスの利用率が低いのではないかと推測しています。

クラウドサービスが浸透しない組織的構造による要因

さらにこれを読み解いていくヒントとして、先ほどのZDNet Japanの記事の中にこのような記述がありました。

日本では、経営層がITに関して米国と比較すると新規ソリューション知識が乏しく、また自社競争力向上ではなく、業務の効率化やコスト削減などの社内目的として活用するという認識が強い。
これを打開するためにはボトムアップ的に改革を進めて行く必要があるが、現場の人間としては、クラウドサービスなど新しい技術を導入することで、さらなる業務の効率化やコスト削減が可能であるとは考える一方でリスクが大きくなることも知っている。

この記事はこの前後もかなり興味深い内容なのでぜひ読んで頂きたいです。

さて整理しますと、日本の経営者の状況としては

  • ITが解決するものは業務効率化、コスト削減であると思っている
  • 業務効率化、コスト削減は経営として優先度が高いものではないと思っている
  • 業務効率化、コスト削減はボトムアップで提案がなされるものと思っている
  • しかしボトムアップで提案がなされても判断できる材料を持ち合わせない

といったところでしょうか。

そして現場としては

  • 業務効率化、コスト削減は達成しても評価されづらい
  • システムを変更することで生じ得るリスクを背負いきれない

ということで、積極的に提案をしづらい事情があるものと予想されます。

ちなみに、ITに期待する役割がそもそも日米で違っていまして、先ほどのZDNext Japanの記事では

ITに対する期待では、日本企業が「ITによる業務効率化/コスト削減」をトップに挙げているのに対し、米国は「製品やサービス開発強化」がトップ、これに「ビジネスモデル変革」が続いていた。

ともありました。

トップの役目は変えること、現場の役目ではない

ここでMFクラウドExpo2016に戻ります。

午前中の基調講演「自ら時代を創る「意思」を持つ~10年後に差がつく経営術~」では

  • 株式会社クラウドワークス代表取締役社長兼CEO:吉田浩一郎氏
  • 株式会社ブイキューブ代表取締役社長CEO:間下直晃氏
  • 株式会社メタップス代表取締役CEO:佐藤航陽氏

という錚々たるメンバーによるパネルディスカッションが行われました。

  • 企業が成長した理由とその痛み
  • いかに意思決定をするか
  • 連続性と非連続性
  • 海外マーケットの攻め方
  • 海外拠点のマネジメント
  • 情報の仕入

などなど、一流の上場企業のトップから珠玉の経営の考え方や捉え方の雨あられ…。

さて、クラウドサービスの利用率の重い悩みに関しては、ブイキューブの間下さんが最後にお話された内容がぐっと刺さりました。

  • トップの役目は変えていくこと
  • それを拒む会社は続いていかないと思う
  • 働き方を変えて、いい意味で楽をしていく
  • トップのコミットメントが必要
  • 現場に丸投げで放り込んでもダメ、現場は変えたくないと思っているから

これはきっと間下さんが、1998年に創業されてから20年近く、数々の企業の経営者にずっと言い続けてきたことなんだろうと思います。

まとめ

そういえば、去年の「cybozu.com カンファレンス 2015」でもそのテーマは「変える覚悟、変わる覚悟。」でした。

クラウドサービスを世に提供されている方々は皆さんは、そういうメッセージを世の経営者にずっと送り続けているんですね。

日本の仕事とITを取り囲む状況はあまり良くないかも知れません。

とはいえ、そこにずっと活力とメッセージを送り続けている、超優秀な方々がたくさんいると思うと、勇気が湧いてくるものです。

超ちっぽけな力しかありませんが、私もその一員として少しでもお役に立てればと思います。

チャットワークが劇的に伸びている理由そしてSlackとの戦いとこれから

$
0
0
chat

photo credit: tonight via photopin (license)

みなさん、こんにちは!
タカハシ(@ntakahashi0505)です。

先日参加しました「MFクラウドExpo2016」のレポート第2段です。

MFクラウドExpo2016ですが、クラウド会計ソフトのリーディングカンパニーである株式会社マネーフォワードさんが主催する、国内のクラウドサービスやFintechサービスを提供する各社が集結したイベントです。

第1段のレポートはこちらで、日本の中小企業のクラウド利用率の低さを嘆き、奮起しているという内容です(なんじゃそりゃですが)。

MFクラウドExpo2016で学んだ、クラウド超後進国である日本を変えるためにすべき事
先日MFクラウドExpo2016に参加してきました。その中からのレポートですが、中小企業のクラウドサービス利用率についてです。いかに日本が他国に比べてクラウド後進国であるか、またその理由についてです。

第2段の、今回は我らがChatWork社のセッションについてレポートをしたいと思います。

ChatWorkさんは昨年のMFクラウドExpo2015にも登壇されていて、その際にこちらの記事を書きました。

本当にストレスフリーに成果が上がる!チャットワークの一歩進んだ使い方
私の愛してやまないチャットワーク。メールや電話に代わってビジネスの現場に劇的な効率化をもたらしてくれるクラウドサービスです。今回はその魅力と一歩進んだ超便利な使い方をお伝えします。

チャットワークがなぜ良いのか、そしてその活用法について書いていますが、今でもかなり読まれている優秀な記事です。

今回はちょっと趣向を変えて、なぜチャットワークが伸びているのか、Slackとの戦いは実際どうなのか?そしてこれからについて書いていきたいと思います。

この1年で利用社数が1.5倍!

今回も前回と同様、ChatWork株式会社常務取締役COOの山口氏が登壇されました。

チャットワークの利用者数は、なんと全世界で97,000社に及んでいます。そして、日本のコミュニケーションツールではシェア70%だそうです。

去年2015/4/23時点の発表では66,000社でしたから、31,000社増えていて約1.5倍の伸び…改めてすごい勢いですね!

ChatWork社には営業マンがいませんが、どのようにしてシェアを拡げているのでしょうか??

顧問企業が絶賛オススメしている

特に弁護士や税理士などと言った「士業」の世界でのシェアが目立ちます。

当日登壇された弁護士藤井総さんのお話でも、「クライアントとのやり取りを全てチャットワークに」した結果、導入して3年間で顧問企業数が10倍の59社に増えたとのこと。

弁護士の世界では顧問企業0~1社の企業が半数を占め、10社以上の会社は1割にも満たないというお話だったのですが…すごいですね~!

ワンストップであらゆる専門家事務所が連携してサービスを提供するトリプルグッドさんの事例でも

お客様1,400社とのやりとりを全てチャットワークに切り替えている

とのこと。

顧問企業側からしてもチャットワークを導入することによるコミュニケ―ションコストの劇的な効率化を図ることができる一方で

我々は「お客様の経営」がクラウドツールを使うことで、もっと効率的になってほしいと考えています。 チャットワークを当社と一緒に使うことで「うちも、クラウドを導入できた!」という成功体験になるので、そういうお客様は他のツールの利用も一気に進みます。

とあるように、クラウド導入を促すことで先方への付加価値にもつながるということで、積極的に提案しているということなんですね。

チャットワークはこのように士業やコンサル業をはじめ現在利用している企業からの協力が得られるから、営業マンがいなくても勝手にガンガンシェアが伸びていく、というわけです。

弊社もクライアントには100%提案をしていまして、ほとんどの企業様に使って頂いています。

ビジネスチャットサービスの巨人「Slack」との戦い方

ITに少し詳しい皆さんはご存知だと思いますが、ビジネスチャットサービスでいうと「Slack」という米国産のジャイアントがいます。

先日の発表でも

評価額が38億ドル(約4200億円)に

そして

1日当たりのアクティブユーザーは270万人(2月の230万人から増加)で有料ユーザーは80万人

ということで、ものすごい勢いで成長しています。

私も長いことチャットワークの信者ですし、できることなら日本発のサービスが世界に広まっていってほしいと思っていましたから、かなりの脅威になるのではないかと心配していました。

少し前の記事ですが、ChatWorkのCEO山本敏行さんご本人によるブログ記事でそんなSlackとどう戦っていくか、というお話がありました。

私の心配をよそに

Slackのようなサービスが出てきて、ChatWorkを心配してくれる方も
いるのですが、実はいろんな追い風が吹いています。

  • 市場があることが証明された
  • 競合視していた会社が買収された
  • ChatWorkの味方が増えた

と、わりと飄々とした感じのようです。また、

Slack台頭の背景として、そこを見落としている方は多いのではないかと思います。一方でChatWorkが狙っている市場は非エンジニア層です。(中略)世の中の90%以上の人が非エンジニアです。

とあるように、Slackはエンジニア(かつ英語圏)に絶大な勢力を誇っていますが、一方で非エンジニアかつ日本(そしてアジア圏)でいうとチャンスは十分にあるということなんですね。

チャットワークの今後はAPIと機能追加に注目!

最近LINEやFacebook Messangerなどで立て続けにニュースがありましたが、チャットのプラットフォーム化という動きはIT界隈ではものすごく興味深いものとなっています。

というのも、例えば「WordやExcelは使えなくてもチャットならできる」というユーザー層がビジネスにおいてもたくさんいるのです。

チャットワークの利用事例でも、農業、建築、介護、漁業、美容・理容など様々な業種で「チャットならみんなできる」ということが証明されています。

ということはどういうことかと言いますと、チャットというインターフェースを通して時間、場所、スキルを選ばずにデータの入出力が可能になるということです。

例えば、現在提供されているAPIでも

  • 「出勤」「退勤」とチャットを送れば勤怠管理システムに打刻ができる
  • 請求先や金額を入力すると請求書が自動発行される
  • 移動先をチャットすれば交通費申請ができる
  • 購入品名と個数をチャットで送れば備品購入依頼ができる

などといったことが実現できます。

そしてチャットワークの機能追加としても

決裁や請求書の発行、ビジネスニュースの配信など、チャットワークを起点に様々な業務が実行できるような機能追加を検討中だという。

ということで、今後のバージョンアップも期待大です。

弊社でもAPIを使ったチャットワークのカスタマイズについてお受けできますので、ご興味あればぜひお問い合わせ下さいね。

チャットワークAPIについてはこちらの記事もご覧ください。

Google Apps ScriptでチャットワークAPIを活用するための最初の一歩
チャットワークAPIを駆使すると、様々な操作を行うことができるようになります。今回はチャットワークAPIの概要とGoogle Apps Scriptでの簡単な使い方についてお伝えします。

まとめ

山口さんのお話の締めとして、株式会社武蔵野代表取締役の小山昇さんのビデオメッセージが紹介されていました。

電子ツールは考えちゃダメ!

さて、山口さんのお話なんですが、実は昨年のとほとんど同じ内容だったんですねw

でもそれわかるんです。サービスがシンプルだから、変えようがないんです。

一方で、実際に触ってみるとその効果やメリットがわかります。特に、使いこなしている人と一緒に使うと、なおのこと理解が深まります。

ということで、そのような体験会を用意させて頂きました!

このような場もぜひご活用を頂ければと思います。

私は、チャットワークのような誰でも使えるサービスを皮切りに、他のITサービスも次々と活用して頂くことで、日本の中小企業の生産性を大きく改善できると考えています。

ですから…これからもチャットワークを絶賛応援しまくりますよ!

エクセル入力情報からWebサイトの会社概要のHTML文を生成するVBAプログラム

$
0
0

みなさん、こんにちは!
タカハシ(@ntakahashi0505)です。

エクセルの入力情報をもとに自動で企業サイト向けトップページのHTMLを生成していきます。

  • Bootstrapを使ったWordPressによる企業向けサイト
  • service,plan,aboutの3つのセクションによるトップページ

という方針で進めております。

前回はこちらの記事。

エクセルVBAでインデントや改行を入れながらHTML文を追加していく便利関数を作る
エクセルVBAで自動でHTML生成シリーズです。今回はインデントや改行コードを入れながらHTML文を追加していく処理を関数化させつつ、Planセクションを生成するプログラムを作っていきます。

HTML生成の際の便利関数を作りつつ、serveceとplanまでのセクションを生成できるようになりました。

今回は会社概要をテーブルで組んでいるaboutセクションのHTMLを生成するVBAプログラムを進めていきます。

では、行ってみましょう。

今回のお題:aboutセクションを作る

では今回のお題を確認していきます。

作成するセクションはこちらのaboutセクションです。

企業サイトによくある会社概要の部分ですね。

会社概要のaboutセクション

この部分に該当するHTML文を以下エクセルシートから生成するというものです。

aboutセクションの情報を記載したエクセルシート

エクセルシートを見る限り、簡単そうに見えますよね?

ですが、ここはテーブルで作られていますので、今までのserviceやplanセクションとは少し作り方が変わっちゃうんですよね。

aboutセクションのHTMLを生成する関数

Worksheetオブジェクトを受け取ってaboutセクションのHTMLを生成する関数はこちらです。

Function createAboutSection(ByVal ws As Object) As String

Dim str As String
str = ""

'section開始タグ
str = addHTML("", 0, "<section id=""about"" class=""section"">")

'***** セクションタイトルB1,セクション概要B2 *****
str = addHTML(str, 1, "<h1 class=""section-title"">" & ws.Range("B1").Value & "<p class=""small"">" & ws.Range("B2").Value & "</p></h1>")

'**** テーブル *****
'tableの開始タグ
str = addHTML(str, 1, "<table class=""table table-striped"">")

Dim i As Long, j As Long
For i = 5 To 9 '5~9行目まで繰り返し

    'trの開始タグ
    str = addHTML(str, 2, "<tr>")

    For j = 1 To 2 '1~2列目まで繰り返し

        'tdタグ
        str = addHTML(str, 3, "<td>" & ws.Cells(i, j).Value & "</td>")

    Next j

    'trの閉じタグ
    str = addHTML(str, 2, "</tr>")

Next i

'tableの閉じタグ
str = addHTML(str, 1, "</table>")

'section閉じタグ
str = addHTML(str, 0, "</section><!-- about -->") & vbCr

createAboutSection = str

End Function

意外とシンプルにできましたね。

テーブルにする範囲が行方向は5~9行目、列方向は1,2列目(A,B列)ですから、i,jと二つのイテレータを使った入れ子のFor~Next文を使うことでプログラムの行数を減らしています。

HTML形式のテーブルの構造とその作り方について詳しく知りたい方は、こちらの記事もご参考頂ければと思います。

エクセルの表をHTMLのtableタグに変換して出力するVBAマクロ
HTMLファイルを作るときにtrやtdタグでテーブルを構成するの…面倒ですよね?今回はエクセルVBAでエクセルシート上の表をHTML形式のテーブルに変換して出力する方法をお伝えしたいと思います。

addHTML関数(おさらい)

ちなみに、プログラム内で使っているaddHTML関数は、前回作ったHTML文を追加していくときに便利な関数です。

Function addHTML(ByVal strBase As String, ByVal cntIndent As Long, ByVal strAdd As String) As String

If cntIndent > 0 Then

  Dim i As Long
  For i = 1 To cntIndent

  strBase = strBase & vbTab

  Next i

End If

strBase = strBase & strAdd & vbCr

addHTML = strBase

End Function

渡された文字列に指定された数のタブと指定の文字列、改行コードを追加して文字列として返す関数です。

実行結果

プログラムを実行するとイミディエイトウィンドウに

aboutセクションのHTMLの出力結果
と出力されます。

この出力されたHTML文をWordPressのテキストエディタに貼り付けてプレビューしてみますと

aboutセクションをWordPressでプレビュー

と正しく表示されます。

セル内改行コードVbLfをbrタグに置換する

ただ、正しく表示されているとはいえ

<tr>
            <td>業務内容</td>
            <td>●業務効率化に関するコンサルティングおよびシステム提供
●研修/セミナーの開催・オンラインスクールの運営
●電子書籍事業に関するコンサルティングおよび各種業務
●WEBサイト企画・制作・運営・マーケティング</td>
        </tr>

この部分のHTML文がガタガタしていて気持ち悪いですよね。

WordPressのテキストエディタは頭が良いので、これでもちゃんと表示してくれるのですが、プレーンのHTMLファイルにてブラウザで見てみると

aboutセクションをブラウザでプレビュー

このように改行がうまく反映されません。

HTML文としては、この部分はちゃんとbrタグを挿入しないとですね。

ということで、25行目をこのように修正します。

str = addHTML(str, 3, "<td>" & Replace(ws.Cells(i, j).Value, vbLf, "<br>") & "</td>")

Replace文を使ってVbLfコードをbrタグに置換しています。

これで出力をしたHTML文をブラウザで見てみましょう。

brタグ入りのaboutセクションをブラウザでプレビュー

無事にbrタグが機能して改行がされていますね。

まとめ

エクセルVBAを使ってエクセルの入力データからHTMLを生成するプログラムですが、今回は会社概要部分のaboutセクションを作成しました。

テーブルのHTML文を自動生成する処理と、VbLfコードをbrタグに置換する部分がポイントでした。

これで一通り完成になりますが、作るWebサイトによっては、全てこの型にはまるとは限りませんよね。

次回以降は、このエクセルシートとVBAプログラムに汎用性を持たせられるようにバージョンアップしていきたいと思います。

どうぞお楽しみに!

連載目次:エクセルの入力情報からVBAでHTML文を自動生成

  1. エクセルVBAでWordPress投稿用HTMLソースを自動で生成する
  2. エクセルVBAでインデントや改行を入れながらHTML文を追加していく便利関数を作る
  3. エクセル入力情報からWebサイトの会社概要のHTML文を生成するVBAプログラム
Viewing all 2091 articles
Browse latest View live