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

チームのみんなが使っている電車の遅延情報を毎朝チャットワークに通知する

$
0
0

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

前回、Google Apps Scriptで電車の運行情報をチャットワークに送る方法をお伝えしました。

Google Apps Scriptで毎朝チャットワークに電車の遅延情報をプッシュ通知する
毎朝、家を出る時間に通勤で使用する路線の運行情報がチャットワークに送られてきたら便利ですよね。今回は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);
}

7行目で鉄道遅延情報のjsonにHTTPリクエストを送りレスポンスをJSON形式で受け取っています。

鉄道遅延情報のjsonには遅延のあった路線情報のみ含まれていますので、その中で

  • name:日比谷線
  • company:東京メトロ

が含まれて入ればそれについて通知、そうでなければ遅延情報がないと送ります。

詳しい解説は前回の記事もご覧下さい。

Google Apps Scriptで毎朝チャットワークに電車の遅延情報をプッシュ通知する
毎朝、家を出る時間に通勤で使用する路線の運行情報がチャットワークに送られてきたら便利ですよね。今回はGoogle Apps Scriptで電車の運行情報をチャットワークに送る方法についてお伝えします。

スプレッドシート上の路線についての遅延情報をチャットワークへ通知

複数の路線について遅延情報を通知するために、リストをスプレッドシートにまとめたいと思います。

このようなリストです。

スプレッドシートの路線リスト

nameとcompanyは、鉄道遅延情報のjsonと同じ表記を選ぶ必要があるので注意下さい。

スクリプトの流れ

作るスクリプトの流れとしては

  1. 電車遅延情報をJSON形式で取得
  2. シートとその最終行またシートのデータを取得
  3. シートの全ての行について
    1. nameとcompanyを取得
    2. json内の全てのオブジェクトについて
      • nameとcompanyが一致していれば
        – チャットワークへ送る文字列を「●●が遅延しています」
    3. チャットワークへ送る文字列が初期のままであれば
      • チャットワークへ送る文字列を「本日の遅延はありません」
    4. チャットワークへ文字列を送る

という流れになりますかね。

ちょっと長い印象ですが、シートを使うのでその部分の処理が増えているというくらいです。

実際のスクリプト

スプレッドシートのリストの路線に対してチャットワークにそのすべての遅延情報を送るスクリプトはこちらです。

function fetchDelayInfo() {

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

  //電車遅延情報をJSON形式で取得
  var json = JSON.parse(UrlFetchApp.fetch("https://rti-giken.jp/fhc/api/train_tetsudo/delay.json").getContentText());

  //シートとその最終行数、シートのデータを取得
  var mySheet = SpreadsheetApp.getActiveSheet();
  var maxRow = mySheet.getDataRange().getLastRow();
  var myVars = mySheet.getDataRange().getValues();

  var body = "[info][title]電車運行情報[/title]";

  for(var i=2;i<=maxRow;i++){ 

    var name = myVars[i-1][1-1];
    var company = myVars[i-1][2-1];

    for each(var obj in json){
      if(obj.name === name && obj.company === company){
        body = body + company + name + "が遅延しています(^^;)\n";
      }
    }
  }

  if(body === "[info][title]電車運行情報[/title]"){
    body = body + "本日の遅延情報はありません(nod)";
  }

  body = body + "[/info]";
  sendMessage(token,room_id,body);
}

10~12行がスプレッドシートとその行数、そしてデータを取得する部分です。もうスプレッドシートを扱うときはお決まりのフレーズたちになりつつありますね。

18行と19行で各路線のnameとcompanyを取得して、それと一致するデータがjson内に含まれているかを判定していきます。

実行結果

これらを実行しますと、リスト内の路線に遅延があれば

遅延があった場合のチャットワークへの通知

と表示されますし、そうでなければ

遅延がなかった場合のチャットワークの通知

こちらの表示となります。

まとめ

以上、Google Apps Scriptで複数の路線についてその遅延情報を確認してチャットワークに通知を送る方法についてお伝えしました。

APIで取得できるものは何でもチャットワークに送れます…楽しいですね。

また面白いアイデアを見つけましたらお伝えしたいと思います。

お楽しみに!


【GAS】Gmailに送られた過去のメールから特定条件のメールを検索して取得する

$
0
0

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

みなさん、問い合わせの分析ってしていますか?

記録によると当サイトにContact Form 7によって問い合わせフォームを設置したのが、2015/6/9でした。

今は株式会社プランノーツのサイトの問い合わせフォームに集約していますが、ブログによるマーケティングをはじめてからもう10カ月。

ボチボチ問い合わせを頂いているのですが、これまでちゃんと集計をしていなかったんですよ…反省しているところです。

さて、とうことで今回から何回かに分けて

  1. 過去の問い合わせメールをスプレッドシートに取り込んで整理する
  2. Contact Form 7から送信されたメールをスプレッドシートに追加していく
  3. スプレッドシートを使って問い合わせの効果を分析する

など、問い合わせデータの蓄積と効果分析にまつわることを色々とやっていきたいと思います。

初回の今回は、Google Apps Scriptで過去の問い合わせメールを特定条件で検索して取り出す方法です。

では行ってみましょう。

Gmailで受信さえしていればGoogle App Scriptで色々できる

まずGmailを使っているというのが前提です。

Gmailであれば、Google Apps Scriptを使って様々な操作をすることができます。

以下の記事ではGoogle App ScriptでGmailを操作してメールを送る方法ですね。

初心者でも簡単!Google Apps ScriptでGmailを操作してメールを送る方法
Google Apps Scriptでメールマガジンを送るシステムを作りたいと思います。シリーズ初回の今回は、Google Apps ScriptでGmailを操作してメールを送る方法です。

逆にGmailに届いたメールであれば取得をしてくることができます。

会社のアドレスなどドメインがgmail.comでなくとも、Gmailをメーラーとして使うことができます。

1つのGmailアカウントで複数のメールアドレスをまとめて使えるようにする方法
会社、プライベートなどの複数のメールアドレス…実は1つのGmailアカウントでまとめて管理できます。別のメールアドレスをGmailで送受信する設定をする方法について、とってもわかりやすくお伝えします。

とにかくGmailで受信していればGoogle Apps Scriptでアレコレできるってわけです。

ぜひ、Gmailを使いましょう。

Gmailの問い合わせのメールのみを抽出する

さて、今回のお題ですが、Gmailに蓄積されている数々のメールの中から、サイトの問い合わせフォームから送られたもののみを選んで抽出します。

プラグインContact Form 7からの問い合わせについては、以下のような内容でWordPress管理者宛にメールが送られます。

Contact Form 7からの通知メール

どの部分を抽出条件として使うかなのですが

このメールは 株式会社プランノーツ (http://plannauts.co.jp) のお問い合わせフォームから送信されました

という部分ですかね。

ちなみにですが、ブログ開始当初はプランノーツ社のサイトがありませんでしたので

このメールは いつも隣にITのお仕事 (http://tonari-it.com) のお問い合わせフォームから送信されました

というメールも過去メールの中には存在しているようです。

ですから、この二つを条件に検索して引っ張ってくるのがよさそうですね。

例えばGmailの検索窓で以下のように入力して検索します。

(“このメールは 株式会社プランノーツ http://plannauts.co.jp のお問い合わせフォームから送信されました” OR “このメールは いつも隣にITのお仕事 http://tonari-it.com のお問い合わせフォームから送信されました”)

すると

Gmailで特定条件でメールを検索した結果

このように検索結果が表示されますね。

検索条件でOR条件にしたいときは「OR」で条件をつなげばOKです。また、スペースを含む文字列で検索したい場合はダブルクォーテーションで囲めばOKです。

これと同様の検索をGoogle Apps Scriptで実施出来れば良いということですね。

特定の文字列を含むメールを取り出すスクリプト

Google Apps Scriptで特定の文字列を含むメールを取り出すスクリプトを作ってみました。

function searchContactMail() {
  
  // Gmailの検索条件
  var strTerms = '("このメールは 株式会社プランノーツ http://plannauts.co.jp のお問い合わせフォームから送信されました" OR '
                  + '"このメールは いつも隣にITのお仕事 http://tonari-it.com のお問い合わせフォームから送信されました")';

  var myThreads = GmailApp.search(strTerms, 0, 500); //条件にマッチしたスレッドを検索して取得、最大500通と決まっている
  var myMessages = GmailApp.getMessagesForThreads(myThreads); //スレッドからメールを取得する →二次元配列で格納

  for(var i=0;i < myMessages.length;i++){
    Logger.log(myMessages[i][0].getSubject());  //各スレッドの1番目のメールの表題をログ出力
  }
}

ひとまずこれだけ…簡単そうですね。

以下解説をしていきますね。

Gmailから特定条件でスレッドを検索する

Gmailから特定条件のスレッドを検索するにはGmailApp.searchメソッドを使います。

GmailApp.search(検索条件, 開始スレッドのインデックス, 最大取得数)

と書きます。

開始スレッドのインデックスですが、今回はすべてのメールを検索してきたいので、0を指定しています。以前取得したスレッドは取得したくない、といったときはこの値をうまく設定するという使い方になると思います。

最大取得数ですが、仕様上500スレッドが最大になりますので、500と設定をしています。

おわかりだと思いますが、GmailApps.searchメソッドで取得できるものはスレッドの集まりになります。

スレッドから個別のメールを取得する

Gmailをスレッド表示にしている方はご存知だと思いますが、Gmailではメールの一連の流れを「スレッド」というかたまりで管理してくれています。

最初のメールに対する返信、またそれに対する返信…といったやり取りは基本的に全部同じスレッドに紐づくことになります。

ですから、スレッドはいくつかのメールの集まりになります。

スレッドの集まりからメールをまとめて取得するにはGmailApp.getMessagesForThreadsメソッドを使います。

書き方は

GmailApp.getMessagesForThreads(スレッドの集まり)

です。メソッド名の通り、スレッドの集まりから含まれるメールを全て取得できるのですが、メールは二次元配列に格納されます。

例えば今回のスクリプトの例では

  • myMessages[0][0] →1番目のスレッドの1番目のメール
  • myMessages[0][1] →1番目のスレッドの2番目のメール(たぶん1回目の返信?)
  • myMessages[1][0] →2番目のスレッドの1番目のメール

といった感じになります。

実行結果

getSubjectメソッドはその名のとおり、メールの件名を取得できます。メールから色々と取得するのは、次回以降詳しく解説をしたいと思います。

本スクリプトでは各スレッドの配列番号0、つまり1番目のメールの件名をログ出力するというものです。

実行してみますと

Gmailから抽出したメールの件名をログ出力

このように取得できました。

まとめ

Google Apps Scriptで過去のGmailに送られたメールの中から特定の条件のメールを検索して取得する方法についてお伝えしました。

スレッドの考え方さえ理解できちゃえば簡単かなと思います。

さて、次回はログ出力ではなくてスプレッドシートに出力をしていきたいと思います。

どうぞお楽しみに!

【GAS】定期的に発生するタスクをチャットワークに自動でタスク追加(完全版)

$
0
0

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

引き続きGoogle Apps Scriptでチャットワークに自動でタスクを追加する仕組みを作っています。

以前の記事で毎日のタスクについて自動でチャットワークにタスク追加する方法をお伝えしました。

【GAS】スプレッドシートに記載したタスクを毎日チャットワークに自動で追加する
Google Apps Scriptを使ってスプレッドシートの定期タスクをチャットワークのタスクとして自動で追加するシステムを作ります。今回はスプレッドシートの毎日のタスクについてしぼって実現します。

それで、毎日だけでなく毎月だったり毎週だったりのタスクも自動で追加していきたいので、その事前準備としてスプレッドシートに毎月のタスクについて、次のタスク期限を求めるように数式を仕込みました。

それがこちらの記事です。

GoogleスプレッドシートとExcelで使える日付関連の関数まとめ
Googleスプレッドシートやエクセルで日付に関する処理をする場合も多いですよね。今回は、今日の日付、何か月後の日付、月末日をはじめ両方で全く同じく使える日付関連の関数を一通り紹介したいと思います。

これで準備が整いましたので、今回はGoogle Apps Scriptで毎月、毎週も含む定期のタスクを自動でチャットワークにタスク追加するプログラムを作っていきたいと思います。

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

定期タスクのリストをスプレッドシートに準備

まず定期で追加するタスクについてまとめたスプレッドシートがこちらです。

スプレッドシートの定期的なタスクのリスト

A列からタスク内容、ルームID、アカウントID、頻度、設定日、次のタスク期限という構成です。

次のタスク期限はE列が日数であれば今日以降の最初にくるその日数の日付、「末」であれば今日以降の最初にくる末尾の日付が出力されます。

ここについては前回記事をご参考下さい。

GoogleスプレッドシートとExcelで使える日付関連の関数まとめ
Googleスプレッドシートやエクセルで日付に関する処理をする場合も多いですよね。今回は、今日の日付、何か月後の日付、月末日をはじめ両方で全く同じく使える日付関連の関数を一通り紹介したいと思います。

スクリプトの流れ

毎月のタスクについては、タスク期限当日のタスク追加だと、さすがにタスクの消化がしんどいので、期限の3日前に自動でタスクを追加するというルールににします。

スクリプトの流れとしては

  1. スプレッドシートとその最終行数、データの取得をする
  2. スプレッドシートの全ての行について繰り返し
    1. 頻度が「毎日」であれば
      • 期限を本日としてチャットワークにタスクを追加
    2. 頻度が「毎月」であれば
      • 今日の日付がタスク期限の3日前であれば
        • チャットワークにタスクを追加

という流れで進めたいと思います。

チャットワークに定期タスクを追加するスクリプト

スクリプトはこちらです。

function addRegularTasks() {
  
  /* スプレッドシートとその最終行数、データを取得 */
  var mySheet=SpreadsheetApp.getActiveSheet();
  var maxRow=mySheet.getDataRange().getLastRow();
  var myVars=mySheet.getDataRange().getValues();

  var token = 'APIトークン'; //チャットワークAPIトークン
  
  for(var i=2;i<=maxRow;i++){

    var date = new Date(); //今日の日付
    var limit = ""

    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   

    if(myVars[i-1][4-1] === "毎日"){

      limit = changeUnixTime(date);     
      addTask(token,room_id,body,limit,to_ids);

    } else if(myVars[i-1][4-1] === "毎月"  || myVars[i-1][4-1] === "毎週"){

      var date1 = new Date(myVars[i-1][6-1]); //タスク期限
      var date2 = new Date(date.setDate(date.getDate()+3)); //期限日の3日前に通知

      if(compareDate(date1,date2)){
        limit = changeUnixTime(date1);
        addTask(token,room_id,body,limit,to_ids);
      }
    }   
  }
}

24行目からのif文にて、D列の頻度が「毎日」か「毎月」(または「毎週」)かで分岐をしています。

「毎日」であれば、本日を期限としてチャットワークにタスクを追加します。

日付を固定小数点表記のUNIX時間に変換する関数

changeUnixTimeは日付を固定小数点表記のUNIX時間に変換する関数です。

/* dateを受け取って固定小数点表記のUNIX時間に変換 */
function changeUnixTime(date){

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

}

なんてことはありませんね。この処理が「毎日」と「毎月」の二か所で必要になったので関数化をしました。

getDateとsetDateで3日後の日付を求める

大元の関数addRegularTasksですが、24行目以降が「毎月」(または「毎週」)だった場合の処理になります。

26行目のdate1には、スプレッドシートのF列「次のタスク期限」に算出されている日付、27行目のdate2には今日の3日後の日付を格納します。

date2ですが二つのメソッドの組み合わせをしています。

まずDateオブジェクトから日数を取り出すgetDateメソッドで日数を取り出しsetDateでDateオブジェクトの日数を設定するときにプラス3をすることで「3日後」の日付を求めています。

setDateは

Dateオブジェクト.setDate(日数)

とすることで、そのDateオブジェクトの日数を設定します。

同じようにget~とset~で何かを書き換えるみたいなことがGASでは結構ありますので、慣れておくと良いと思います。

二つの日付が等しいかを判定する関数

29行目のif文ですが、compareDateというのは二つの日付が等しいかどうかを判定する関数です。

/* 2つの日付が等しいかを比較する */
function compareDate(date1,date2){

  if(date1.getFullYear() === date2.getFullYear() && date1.getMonth() === date2.getMonth() && date1.getDate() === date2.getDate()){
    return true;
  }else{
    return false;
  }

}

if(date1 === date2)などという条件文でできそうですが、そうはいきません。

dateオブジェクトには年月日だけでなく、時分秒も含まれているので、1秒でもずれていれば等しいという判定になりません。

ということで、年月日だけを比較する関数を作りました(他にスマートな方法があれば教えて欲しい…)。

ちなみに、その際に使っているgetFullYear、getMonthなどのメソッドについては、以下の記事で詳しく説明しているので、ご参考ください。

Google Apps Scriptで特定月のカレンダーのイベント情報を取得する
Googleカレンダーの記録を活用して過去の仕事の生産性を測定するしていきます。今回はGoogle Apps Scriptで特定の月のカレンダーのイベント情報を取得する方法についてお伝えします。

実行結果

では、このスクリプトを実行してみましょう。

チャットワークに自動で定期タスクを追加

このように、当日のタスクが二つ、毎月のタスクが一つ追加されました。

イベントトリガーで毎日に設定をしておけば、毎日のタスクも毎月のタスクもそれぞれがきちんと自動でタスク追加されるようになります。

毎週のタスクにも対応

実はこのスクリプトですが毎週のタスクもそのまま対応しています。

例えばスプレッドシートとして

毎週のタスクもスプレッドシートの定期タスクリストに追加

このようにH列、I列に曜日と値の表を準備します。

F6セルには

=IF(VLOOKUP(E6,$H:$I,2,false)>WEEKDAY(TODAY()),TODAY()+(VLOOKUP(E6,$H:$I,2,false)-WEEKDAY(TODAY())),TODAY()+(VLOOKUP(E6,$H:$I,2,false)-WEEKDAY(TODAY())+7))

などとしています。

もう少しスッキリかけそうな気もしますが、各自研究してみてください。

まとめ

Google Apps Scriptで毎月、毎週、毎日の定期のタスクをチャットワークに自動でタスク追加するプログラムについてお伝えしました。

日付の扱い…スプレッドシートでもGoogle Apps Scriptでもなかなかやっかいかもですね。

ですが、スプレッドシート、Gmail、カレンダーなどといったGASの得意分野を扱う上では避けては通れないと思いますので、ぜひ慣れてしまってほしいと思います。

本連載はこれでひとまず終了となります。

また面白いアイデアを見つけたら紹介していきますので、どうぞお楽しみにしてくださいね。

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

  1. Google Apps Scriptでチャットワークにタスクを追加する最も簡単なプログラム
  2. Google Apps Scriptでチャットワークに期限付きのタスクを追加する
  3. 【GAS】スプレッドシートに記載したタスクを毎日チャットワークに自動で追加する
  4. GoogleスプレッドシートとExcelで使える日付関連の関数まとめ
  5. 【GAS】定期的に発生するタスクをチャットワークに自動でタスク追加(完全版)

WordPress用レンタルサーバー選びで失敗しないための4つのポイント

$
0
0

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

WordPressでブログをやろうと思ったとき、起業してWebサイトを作る必要が出てきたとき、必ずぶつかる壁として「サーバー選び」というのがあります。

ロリポップ、エックスサーバー、さくらインターネット、お名前.com…他にも有象無象たくさんあります。

レンタルサーバーは”紹介フィーがナイスな商品”なので、それをネタにした紹介サイトや記事も超大量にあります。

本当にどれがいいかわかりませんよね。

今日は、自社のWebサイトとブログを運営しつつ、さらに法人個人問わずWebサイトの立ち上げやリニューアルをお手伝いしてきた私からの視点で、WordPressを使う場合のレンタルサーバーはこう選んで欲しいというのをお伝えしたいと思います。

サーバー選び…インターネットは信用ならない?

サーバー…インターネットやITに詳しくない方にとっては、完全に未知の領域だと思います。

おそらくだいたいの方々はインターネットでレンタルサーバー会社のホームページや、比較サイトなどを見て

  • WordPressが使えるか
  • 価格

である程度しぼって、追加でそれについていくつかの記事を見て追加情報を得て決めていると思います。

ですが、だいたいの記事はアフィリエイトが利いているので、悪いことは書いていないのが辛いところです。

そんなレンタルサーバーですが、私から4点ほど選ぶポイントをお伝えしていきます。

電話の問い合わせがある

ITが苦手な方にオススメなのは、電話の問い合わせがあるレンタルサーバー会社です。

全くITに自信がないのにも関わらず、電話の問い合わせがないというのはやめたほうが良いです。

ブログサイトを一個立ち上げるだけでも

  1. ドメインを取得
  2. レンタルサーバーのいずれかのプランに新規契約
  3. レンタルサーバーにドメインを登録
  4. レンタルサーバーにWordPressをインストール
  5. ドメインにネームサーバーを設定

といった手順が必要になります。

サーバーに関してどうしてもわからないことが出てきたら、問い合わせをしなくてはいけなくなります。

ですが、電話がなくて問い合わせフォームでのやり取りになってしまうと、一つ解決するのに数日かかっちゃったりします。

電話であれば、一連の流れのところまで話をしながらなんとか進められます。

この差は大きいです。

同じ運営会社でも、プランによって電話の問い合わせがあったりなかったりする場合もありますので、よく確認を頂ければと思います。

一旦サイトを作ったら、レンタルサーバーに問い合わせをするということもあまり多くないのでは?

と思うかも知れません。

転ばぬ先の杖です。例えば、ブログがうまく行って毎月30万PVくらいの人気サイトになったとして、何かの理由でサイトがダウンしたとします。

問い合わせフォームに連絡して、数日のんびり待てますか?

解約の仕方を見ておく

おそらく一度契約をしたら解約をするということはあまりありません。

ですが、ここはあえて契約前に解約方法を見ておく、ということをオススメしておきます。

実は、解約するときの手順を確認しておくという目的もあるのですが、別の理由もあります。

解約の仕方を見ておくことで

  • そのサービスの説明がわかりやすいか
  • その説明で自分が作業ができそうか
  • ユーザーに対する姿勢や態度

などを確認できます。

解約の仕方を見に行って「なんだこれ?さっぱり意味わからん」と思ったら、そのサービスの契約やドメインの追加などで「なんだこれ?さっぱり意味わからん」となる可能性が高いということです。

コントロールパネルと呼ばれる様々な機能を提供する管理画面があるのですが、まあ各社のクセがありますよ。

私は自社で使っているエックスサーバーや、さくらインターネットは使いやすいと思っていますが、人によっては違うかも知れませんからね。

MySQLの数を確認

MySQLの数は確認しておきましょう。

MySQLというのは、データベースとイコールと思って頂いてOKです。

WordPressサイト一つに対してデータベースが一つ必要になります。そのデータベースに、投稿した記事やその他色々な情報が格納されます。

各社のWordPressが使える中で一番安いプランだと「MySQLが1つだけ」というのがけっこうあります。

例えばロリポップのライトプランだと「独自ドメイン50個までOK!」と書いてあっても、結局MySQLが1つだけなので、結局WordPressサイトは1つしか作れません。

(一応、データベース1つでも複数のサイトを作る方法はあるのですが、少しテクニックが必要です。)

「一生、絶対に一つしかサイトを作りません!」

というのであれば、それでもいいのですが、複数のサイトを運営したくなったり、練習用のWordPressをインストールしたくなったりすると、そのプランでは対応ができなくなります。

まあ、その時はプランをアップグレードすればいいんですけどね。

WordMoveが使いやすいのが良い

ここからは、急に技術的な内容になっちゃうので、本気でスキルアップしていきたい人以外は無視してもらって良いです。

WordMoveというのは、簡単に言うとローカルのPC内で作ったWordPressサイトを簡単にインターネット上に公開するための超便利ツールです。

超簡単に本番と同期できるWordPressおすすめローカル環境構築までの道のり
このたび、WordPressローカル環境を作り直しました。今回はその導入編、超簡単に本番環境と同期できるWordPressローカル環境構築までの全体の工程について整理をしてお伝えしておきますね。

WordPressは本来インターネット上にあるものを直接管理画面でいじくるのですが、ちょっと本番のサイトをいじくるのが怖いときは、手元にあるローカルPC内で作りこんだり、十分な動作確認をした上で、本番に反映するんですね。

しかもローカルPCで構築できればWP-CLIなどで、色々な作業を自動化したりもできます。

WordPressをコマンドラインで操作するWP-CLIをインストールする方法
WordPressサイトを10分で立ち上げるべく、効率化の最大のポイントとなるツールWP-CLIをインストールしていきます。これでコマンドラインでWordPressのあらゆる操作ができるようになります。

で、そのWordMoveが使える、そして使いやすいレンタルサーバーがいいということになります。

それでいうと、私の経験上

  • エックスサーバー→◎
  • さくらインターネット→◎
  • お名前.com→今のところ×
  • ロリポップ→?

となります。

お名前.comは「mysqldumpが見つからない問題」がどうしても解決できずにいます(どなたか知っていたら教えて欲しいです)。

ロリポップはSSH接続ができるのがスタンダードプラン以上になりますが、そもそもロリポップ使っている人はライトの人が多くて、スタンダード以上の人にまだお目にかかってないです。

まとめ

以上、レンタルサーバーを選ぶポイントを4つほどお伝えしました。

特に、電話問い合わせ解約の仕方については、悪くない選び方だと思うので、ぜひご活用を頂ければと思います。

あと本気でやられたい方は、MySQLやSSH接続を中心にほかの項目もご覧くださいね。

では、良いサーバーに出会えることをお祈りしています!

オススメサーバー

当サイトはエックスサーバーで運営しています。


エクセルVBAで印刷時のヘッダー・フッターの設定をする方法と書式コード・VBAコード一覧

$
0
0

heading

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

引き続き、エクセルVBAでPDF出力や印刷をする際のテクニックについてお伝えしています。

前回の記事はこちら。

エクセルVBAで印刷範囲の設定をする方法とクリアをする方法
エクセルVBAでPDF出力や印刷をする際の様々なテクニックをお伝えしています。今回はPageSetupオブジェクトで印刷範囲の設定する方法と印刷範囲のクリアをする方法です。範囲は文字列で指定しますよ。

印刷範囲の設定とクリアをする方法についてお伝えしました。

これまで印刷またはPDF出力に関しては

  • ページ中央配置にする
  • 上下左右のマージンをとる
  • 縦横1ページに収める
  • 倍率を決める
  • 印刷範囲を決める

などなど、様々な設定をシートに対するPageSetupオブジェクトで設定してきました。

今回はそれに加えてエクセルVBAで印刷時のヘッダー・フッターの設定の方法についてお伝えしたいと思います。

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

前回までのおさらい

前回終了時点のプログラムはこちらです。

Sub outputPDF()

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

With ActiveSheet.PageSetup

    .PrintArea = "A:D"  '印刷範囲の設定
    .Zoom = False       '倍率をクリア
    .FitToPagesWide = 1 '横方向に1ページに収める
    .FitToPagesTall = 1 '縦方向に1ページに収める
    .CenterHorizontally = True                          '水平方向に中央配置
    .TopMargin = Application.CentimetersToPoints(1)     '上マージンを1cm
    .BottomMargin = Application.CentimetersToPoints(1)  '下マージンを1cm

End With

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

End Sub

PageSetupオブジェクトの各プロパティの設定についてはコメントでおわかりだと思いますが、結構いろいろ設定できますよね。

それでとある請求書を印刷した結果がこちらです。

エクセルで印刷範囲を設定してプレビュー

だいぶ出来上がっていますが、今回はこれにヘッダー・フッターを追加していきましょう。

エクセルVBAでヘッダー・フッターの設定をする

ちなみにヘッダー・フッターは皆さん使われていますか?

エクセルはセルの行列の幅を自在に変更できるので、ページの見出しやページ番号などをシートに直接書き込んでいる場合も多いかもしれませんが、使いこなすと便利です。

特に以下二つのメリットは作業効率という意味ではかなり大きいです。

  • ヘッダー・フッターの領域にはセルの幅に依存せずに配置できる
  • テーブルに無駄な行列を入れる必要がなく数式やマクロに強いシートが作れる

ヘッダー・フッターを活用しましょう!

ヘッダー・フッターを設定するPageSetupオブジェクトのプロパティ

ということで、エクセルVBAでヘッダー・フッターを設定する方法です。

これもおなじみのPageSetupオブジェクトのプロパティで以下をそれぞれ使います。

WorkSheetオブジェクト.PageSetup.LeftHeader = 設定内容
WorkSheetオブジェクト.PageSetup.CenterHeader = 設定内容
WorkSheetオブジェクト.PageSetup.RightHeader = 設定内容
WorkSheetオブジェクト.PageSetup.LeftFooter = 設定内容
WorkSheetオブジェクト.PageSetup.CenterFooter = 設定内容
WorkSheetオブジェクト.PageSetup.RightFooter = 設定内容

設定内容は基本的に文字列を指定していくのですが、書式コードまたはVBAコードを利用することでヘッダー・フッター特有の設定をすることができます。

書式コード・VBAコードを使った設定内容の表記の仕方

ヘッダー・フッターの設定で利用可能な書式コード・VBAコードは以下のようなものがあります。

コード 説明
&L 左詰めに配置
&C 中央揃えに配置
&R 右詰めに配置
&E 二重下線付き
&X 上付き文字
&Y 下付き文字
&B 太字
&I 斜体
&U 下線付き
&”フォント名” フォント指定(※ダブルクォーテーションで囲む)
&nn フォントサイズ指定(※nnには2桁の数値を指定)
&D 現在の日付
&T 現在の時刻
&F ファイル名
&A シート名
&P ページ番号
&P+<数値> ページ番号に<数値>を加えた値
&P-<数値> ページ番号から<数値>を引いた値
&& アンパサンド (&)
&N 総ページ数
&Z ファイルパス

書式コード・VBAコードを使う際のルールはこちらです。

  • 文字列に装飾をするものは、装飾したい文字列の前に上記コードを付加します。
  • 装飾を打ち消したいときは、打ち消したい文字列の前に再度同じコードを付加します。
  • フォントの指定はフォントの名称をダブルクォーテーションで囲います。
  • フォントサイズの指定は二ケタの数字で指定をします。

ヘッダー・フッターを指定する例

では一つ試してみましょう。

出力するシートはこちらです。

印刷するエクセルシート

前回まで上部に「請求書」とシート内に記載していたのですが、中央ヘッダーで配置をしたいので削除しました。

例としてのプログラムはこちらです。

Sub outputPDF()

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

With ActiveSheet.PageSetup

    .PrintArea = "A:D"  '印刷範囲の設定
    .Zoom = False       '倍率をクリア
    .FitToPagesWide = 1 '横方向に1ページに収める
    .FitToPagesTall = 1 '縦方向に1ページに収める
    .CenterHorizontally = True                          '水平方向に中央配置
    .TopMargin = Application.CentimetersToPoints(1)     '上マージンを1cm
    .BottomMargin = Application.CentimetersToPoints(1)  '下マージンを1cm
    .LeftHeader = "" '左側ヘッダー:なし
    .CenterHeader = "&""メイリオ""&28請求書"  '中央ヘッダー:なし
    .RightHeader = "&D &T"  '右側ヘッダー:日付 時刻
    .LeftFooter = "" '左側フッター:なし
    .CenterFooter = "&""Verdana""&08" & "Confidencial"   '中央ヘッダー:Verdanaフォント、サイズ8で「Confidencial」
    .RightFooter = "&P/&N"  '右側フッター:ページ数/総ページ数

End With

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

End Sub

ヘッダー・フッターの指定をしている箇所は以下の通りです。

  • 15行目:左側ヘッダー→なし
  • 16行目:中央ヘッダー→フォントをサイズ28のメイリオにして「請求書」と出力
  • 17行目:右側ヘッダー→今日の日付に半角スペース空けて今の時間
  • 18行目:左側フッター→なし
  • 19行目:中央フッター→フォントをサイズ8のVerdanaにして「Confidencial」と出力
  • 20行目:右側フッター→現在のページ数/総ページ数

フォントの指定はダブルクォーテーションで囲むのですが、VBAで記述する場合はエスケープのため2つ連続で書く必要があります。

ちなみに、左側のヘッダー・フッターはあえて「””」で指定していますが、シートに前の設定が保存されている可能性があるので、空欄にするときも念のため設定をしておいたほうが良いと思います。

出力結果

実行してプレビューを見ますと、ヘッダーは

プレビュー出力のヘッダー

フッターは

プレビュー出力のフッター

と出力されます。

まとめ

エクセルVBAでPDF出力または印刷時のヘッダー・フッターの指定をする方法についてお伝えしました。

使える書式コード・VBAコードがたくさんありましたね…覚えなくても良いので、本ページをブックマークして都度参照頂ければと思います。

次回は複数のシートをまとめてPDF出力する方法についてお伝えしたいと思います。

どうぞお楽しみに!

ITをなりわいにしているフリーランスの1時間あたりの最低目標売上

$
0
0

watch

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

ゴールデンウィークですね。

私は誕生日が5月5日。いつもゴールデンウィークの華々しさに自分の誕生日がかき消されてしまうのを、少し寂しい気分で迎えていました。

いやー、しかし今年も交通渋滞の予想が…半端ないですね。

なぜ混むのがわかっていて突っ込むのでしょう?

あの渋滞の中、パパたち、ママたち、子供たちが渋滞にはまっている時間を全部かき集めたら、どれほど素晴らしい仕事を成し遂げることができ、どれだけ多くの学びを得ることができるでしょうか。

やっぱり、「そこしか休みがとれないから、しょうがない。」となっちゃうんですかね…

日本は環境はまあまあエコですが、時間については全然エコじゃないです。

…さて、私はひとり社長になってからもうすぐ一年です。

お金がたくさんあるわけではないですし、設備もPCくらいなので、弊社のリソースは「私自身の時間」とイコールと言っても良くて、その使い方が生死を分けます。

今回はその時間の使い方として「1時間あたりの最低目標売上を決めておいたら良かった」ということについてお話したいと思います。

1時間あたりの売上目標を計算する

ITをなりわいにしているフリーランスの1時間あたりに稼がなくてはいけない売上の計算をします。

本当にシンプルで

1時間あたりの売上目標=(生活費+経費)÷営業日数÷営業時間

です。

生活費は保険とか税金とかそういう支払も全部込みです。

例えば

  • 生活費で30万円
  • 経費で5万円
  • 1カ月20日働いて
  • 1日8時間働く

なら、1時間あたり2,187.5円を稼がないと、まあまあ早い段階で立ち行かなくなります。

この1時間あたりの売上目標はあくまで「下限」つまり最低限の目標で、上振れする分には全然良いですし、仕事の質がよければ当然それ以上の価値にも成り得ます。

当然利益を出したいですから、もっと設定を高くして活動をしたくなります。

この”クセ”がついたことは独立したことによる大いなるメリットだと思っています。

以下で具体例をいくつか挙げさせてもらっています。

予算が低すぎる場合は仕事を受けられない

仕事を受けるときの判断材料として強力な武器になります。

以前、こちらの記事で書いた通り

独立してから出てきた課題について納品のない受託開発にヒントを得た
独立してから5か月。業務支援ツールの開発が主なお仕事なのですが、いくつかの課題が出てきました。それを解決する方法として「納品のない受託開発」という書籍にヒントを得ましたのでそれについて書いています。

見積ってすごく難しいです。

ですが一つでも指標があるとないとでは大違いです。

だいたいの工数が想定できて、予算感もヒアリングできているのであれば、あとはシンプルに計算するだけ。

どう考えても成立しない案件をハッキリとお断りできます。

また、とりあえず値切ってくる場合とかにも対応しやすいです。

交渉が苦手なフリーランスだとずるずる交渉負けしちゃったりする場合もありますが、「生命線」がハッキリすることで、わりとスッと要望を伝えられるようになると思います。

タダで簡単に得たものは大事にしない説

ITをなりわいにしていると「ちょっと教えて」ということがよくあります。

ブログへのコメント欄や問い合わせフォームから技術的な質問が来る場合もあるのですが、やり取りのどこかのタイミングで「コンサルは基本有料ですので、他のお客様の手前云々」とお伝えするようにしています。

知り合いだとズバっと断りづらくて困るのですが、あまり度が過ぎないように気をつけています。

当然、私の立場からすると、本来コンサル的に報酬を頂いている部分なので、みんながみんなに親切にタダで提供すると立ち行かなくなる、というのもあります。

それとは別にもう一つ、タダで簡単に得たものって大事にしないんじゃないかなーという気がします。

やっぱりお金を払ってまで必要!と思っている人とそうではない人と、どちらに時間をかけたほうが良い価値を提供できるか、と考えると明らかです。

お金がなければ、ご自身の時間を使うのがオススメです。あーでもない、こーでもないと一生懸命調べたり考えたりがあるほうが、結果的に身に付きが良かったりします。

「とりあえずのアポ」を避ける

先日も某大手SaaSの営業マンから電話がかかってきて「情報交換のためにアポイントの時間が欲しい」と連絡がありました。

弊社のような零細企業では、そのSaaSのサービスはちょっと敷居が高いのは明らかでしたから、先方のサービスに変化がない限りはどう考えても導入できません。

便利なのはわかっていても、固定費をむやみに増やすとすぐに赤字になっちゃいます。

例えば、弊社にお越し頂く場合でも、自宅は打ち合わせスペースがありませんので、近くの喫茶店に行きます。

  • 喫茶店までの往復で30分
  • 打ち合わせで1時間
  • コーヒー代300円
  • 1時間あたり3,000円を稼がなくてはいけない

のであれば、その打ち合わせで4,800円分の価値を生み出さないといけなくなります。

要件もなくとりあえず会って話をして、その商談の場で一気に価値のある動きにつながるようにはどうしても思えません。

クラウド関係のお仕事をされているのであれば、時間の貴重さみたいなところを行動の基本に置いて欲しいんですが…残念な気持ちになりました。

自宅で仕事をする

当然、もともと最初からオフィスを借りるということは資金的に検討できなかったわけですが、例えば仲の良い経営者が「うちの部屋の一角を使っていいよ」なんて言ってくれたらどうしますか?

インターネット代や電気代なども持ってくれるとしたら…ありがたいと思っちゃいますよね。

ですが、今だったら、その話には乗らないかも知れません。せっかく借りてもあまり行かなくなっちゃうかなと。

なぜなら移動時間がかかるからです。

  • 1時間あたり3,000円を稼がなくてはいけない
  • オフィスまで往復2時間かかる

と考えると、そのオフィスを使うことによって1回あたり6,000円+往復交通費を余計に稼がなくてはいけません。Wifiや電気代程度では全く足りませんね。

働いている時間が8時間だとすると、生産性としては25%倍の生産性を上げなくてはいけません。

だから移動を伴う打ち合わせの場合は、直接会わないといけない要件なのかどうかを見極めたいところです。

特に通勤だと、毎日だと積み重ねで、たいへんな価値になります。

もっとシンプルにリモートワークがガンガン増えてもいいのではないかと思います。

まとめ

1時間あたりの価値を計算するこについて、そしていくつかの具体例についてお伝えしてきました。

予定を組むとき、仕事を受けるときなどにご参考頂ければと思います。

実際、「価値」というのは、それにかけた時間だけで測れるものではありませんので、あくまで下限を決めるための一つの指標として取り扱うのが良いかと思います。

上限も時間だけで決めてキャップをしてしまうと、速くやればやるだけ価値が下がってしまうということが起きてしまいます。

世の中のビジネスシーンでは、よく起きていますけどね…

【セミナーレポート】チャットワークを丸々2時間体験するセミナーを開催しました

$
0
0

お仕事のためのIT活用セミナー~チャットワーク+なんでも相談会~

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

先日、「お仕事のためのIT活用セミナー~チャットワーク+なんでも相談会~」と題してセミナーを開催させて頂きました。

2015年12月から毎月1,2講座のペースで自主開催しているセミナーですが、今回は

  1. チャットワークだけをテーマ
  2. 地元板橋区での開催

という二点で初の試みでした。

実際にどうだったか…レポートをさせて頂ければと思います。

チャットワークだけで2時間持つのか…?

いつものセミナーでは、ExcelやVBA、WordPressをテーマに、初心者がある程度できるまでをみっちり3時間かけてやる、という内容で行っています。

今回は2時間ではありましたが、チャットワークはいわばビジネス版のLINEみたいなもの…チャットツール一つだけで2時間のセミナーが持つのか…?

なかなかのチャレンジでした。

(実は足りなかったときのためにGoogle Apps関連のコンテンツもいくつか用意していたのです…期待されていた方がいらしたらごめんなさい)

さて、やってみた結果としては

全然いける!

というのが結論です。

むしろ、用意してきたコンテンツを全て伝えきれなくて、30分以上延長をしました。3時間にすればよかったくらいです。

セミナーのアジェンダ

アジェンダとしては以下の通りでした。

  1. チャットワークについて
    • コミュニケーションの実態
    • チャットワークとは
    • チャットワークの特徴
    • 新しいコミュニケーション手段
    • 減らすことができる時間
  2. チャットワークの使い方
    • チャットワークの画面構成
    • ①メッセージ
    • ②プロフィール
    • ③コンタクト
    • ④グループチャット
    • ⑤マイチャット・ダイレクトチャット
    • ⑥チャット概要の使い方
    • ⑦タスク
  3. チャットワーク事例
    • 3つの事例
    • チャットワークAPI
    • 期待できる効果
  4. チャットワーク導入の課題
    • 取引先に導入してもらうのが気が引ける
    • 社内でちゃんと使ってくれるか不安
    • セキュリティが心配
    • 「既読」がないと読んでもらえたかわからない
    • Facebook・Skype・LINEではダメなの?

最後のほうは駆け足になってしまって…、申し訳ありませんでした。

ですが現場でも和気あいあいとしていましたし、アンケートでも

  • 大変有意義でした。
  • 使い方のイメージが湧いた。
  • 登録から実際に使用しながら学ぶ所まで教われ、便利だと実感しました。

と回答を頂きました。ありがたいです。

実際に触ってみると楽しい

中でも「2.チャットワークの使い方」の箇所がとても効果が高かったように思います。

実際に参加者の皆さんにPCやiPadでグループチャットに参加して頂いて、メッセージを送り合ったり、グループを作ってみたり、かなりアグレッシブに触れられていました。

少し慣れてくると

  • 音声ファイルを送ってみるとどうなるか?
  • グループから参加者を外してみる
  • コンタクトを削除しても再度コンタクトができるのか?

とか、実際の運用ではなかなか試せないことを試すこともでき、かなり面白い体験になったのではないかと思います。

まず、触ってみることが大事。

そして、そもそも根本的に

チャットって楽しい!

ということなんですね。

ぜひ、参加者の皆様には引き続き楽しみながらご活用頂ければ幸いです。

運動できる健康食堂さんぽプラス

普段は縁あって、三鷹市を中心とした武蔵野地域でセミナーを開催させて頂くことが多かったのですが、今回は念願の板橋区で開催をすることができました。

実は弊社のセミナーでは開催場所にもこだわっています。

貸会議室ですと比較的コストは安く使わせて頂けるのではあるのですが、「ザ・会議室」みたいな会場で「IT活用セミナー」…となると、いかにも堅苦しい印象がどうしてもしてしまうので、気軽に参加できるイメージを演出したいんです。

ほら、ITって印象として融通がきかないとか、そもそも難しそうとかいうイメージあるじゃないですか?

それを少しでも緩和して、一歩足を踏み出して頂ければと思ってセミナーを開催しています。

今回のセミナーを開催させて頂いたさんぽプラスさんですが…そういう点ではバッチリです。

店内に入ってみますと…

運動できる健康食堂さんぽプラス店内

なんとジムスペースがあります。月額制でジム利用が使い放題ですし、パーソナルトレーニングもお願いできますので、お近くの方はご利用してみてはいかがでしょうか?

お食事や飲み物も健康重視のメニューがたくさんあります。運動直後に食事をとると効果的なんですって。

こちらが、その中でもオススメ食事メニュー「30品目とれる定食」です。

運動できる健康食堂さんぽプラス  30品目とれる定食

ああ…お腹が減ってきた。

しかしITと健康…このミスマッチが良いでしょ?

私はセミナー後にビールをいただきました。さんぽプラスさん、アルコールとおつまみもありますよ(結果的にあまり健康じゃない私)。

次回、さんぽプラスさんでのセミナー開催も期待してくださいね。

まとめ

以上、「お仕事のためのIT活用セミナー~チャットワーク+なんでも相談会~」のセミナーレポートでした。

チャットワークだけをメインにしたセミナーはもちろん、一つのツールに特化していろはを体験し尽くすタイプのセミナーは非常に効果的だということがわかりました。

今後のセミナー企画の参考にしていきたいと思います。

さて、次回セミナーは5/7に三鷹で、ExcelVBAのセミナーと

WordPressのセミナーの

ダブル開催です1

ぜひこちらもご参加頂ければと思います。

コンテンツマーケティングには覚悟が必要、しかし決して辛いものではない

$
0
0

prepare

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

ブログによるコンテンツマーケティング、大きなコストをかけることができない中小企業や個人事業主でも成功する可能性がある有力なマーケティング手法です。

弊社も2015年2月頃から、当ブログを運営しはじめて1年と少し。ブログによる成果は…出てきていますよ!

ブログをやらずして、今も立っていられたかと思うと…少しゾッとします。

そんなコンテンツマーケティングですが、成果を上げるために間違いなく必要なもの、かつ忘れがちなものがあります。

それは「覚悟」です。

「覚悟」というと、根性とか、耐えるとかそういう辛い感じのニュアンスがありますが、決してそんなことはありません。

今回の記事では、ブログによるコンテンツマーケティングに必要な覚悟についてお伝えできればと思います。

コンテンツマーケティングとは

そもそもコンテンツマーケティングとは何か、ということですが簡単に言うと

  • ターゲットに価値のあるコンテンツを提供して
  • 顧客の獲得や良い関係づくりをする

方法です。

コンテンツマーケティングは別にWebとかブログに限った話でもないのですが、ブログを活用する方法が採用されることが多くなっています。

というのも、ブログつまり記事コンテンツによるコンテンツマーケティングは

  • コスト面や技術面での参入障壁が低く
  • 業種問わずに活用できる

という特徴があるからです。

自社のビジョン、テーマ、サービス、ニュース、活動、顧客の反応、事例などそういったものを、将来顧客になり得るターゲットや既存顧客に有益な形にして提供をしていけばよいわけです。

最初必要なのは

  • ドメインとサーバーの契約(月々数百円~)
  • ブログを書く技術と知識(WordPressなどのソフトウェアの使い方、文章の書き方、ネットの知識)

くらいです。ブログを書く技術や知識も必要ですが、たいして難しいものではなく、ExcelやWordが使える人ならすぐにできるようになると思います。

最大そして唯一の敵は「続かなくなること」

はじめるのは簡単なブログですが、最大の敵は「続かなくなること」です。

なにせ一つの記事を作るのに数時間かかります。毎日やろうとしたら…起きている時間の1/5はブログに時間を割かなくてはいけません。

そして成果が出るのに半年や1年といった期間が必要です。

ブログを始めて1年、フリーランスとして毎日3時間をかけた価値はあったのか?
独立してから仕事を獲得する戦略として、ブログの更新を1年間、ほぼ毎日3時間をかけてコツコツと続けてきました。1年続けてきて実際にその価値はあったのか、実際のアクセス推移も含めてお伝えします。

では、週1回だったらできるかも…ということで、やってみるとそれはそれで続かない場合が多いです。結局、締め切りの当日に頑張り始めて、当日に書き切れなかったとすると、「今週はいいや、来週から頑張ろう」となります。

そして毎週が2週間に1回になり、1月に1回になり、そうなると簡単に立ち消えます。

これは企業でも同じで

  • 現場や外部に丸投げをする
  • 本業のおまけ程度の認識ではじめる
  • 責任者を他の業務の責任者と兼務にする
  • コンテンツマーケティングのためのリソースを十分に想定、確保しない
  • コンテンツマーケティングの活動を評価を適当にする

などの項目が一つでも当てはまると、あっという間に立ち消えます。

ですから、ドメインやサーバーとブログの技術や知識に加えて、もう一つ覚悟が必要になります。

覚悟という言葉のイメージ

辞書で覚悟という言葉を調べてみると

かくご【覚悟】

1. 危険なこと、不利なこと、困難なことを予想して、それを受けとめる心構えをすること。「苦労は―のうえだ」「断られるのは―している」
2. 迷いを脱し、真理を悟ること。
3. きたるべきつらい事態を避けられないものとして、あきらめること。観念すること。「もうこれまでだ、と―する」
4. 覚えること。記憶すること。
5. 知ること。存知。
引用:goo辞書

あら…、パッと見は意外とネガティブな感じですね。

耐えるとか、我慢とか、根性とか、自分を捨てるとか、そういう印象があります。

武士の時代、戦時中などに「覚悟」などという言葉を使うと、「命を失うことを選択肢に入れる」というニュアンスが当然のようにあります。

現代の企業の中でも「覚悟を決める」などというと、失敗したときには自らが責任をとって今のポジションを失うことも想定する、というニュアンスがあったりします。

つまり

失敗したら自分の命やポジションが危ういという可能性を生じさせることにより、現時点からのパフォーマンスを最大限に上げよう

ということなんだと思いますが、私はその「覚悟」の使い方は全く間違っていると思います。

「覚悟」を表す英単語はいくつかある中で「preparedness」という単語があります。この単語には「準備」という意味も含まれています。

大事なのは、玉砕する可能性がある中に身を投じるということではなく、玉砕しないように準備をしておくということです。

ジョジョの奇妙な冒険に出てくるジョルノ・ジョバーナ(イタリア人)も

覚悟とは犠牲を払うことではない!
覚悟とは暗闇のなかに進むべき道を切り開くことだ

と言っています。

「覚悟」について色々な名言を探しましたが、この言葉が一番好きでした。荒木先生、さすがです。

前もって続けられる状態にする

毎日フルマックスでもりもり仕事をしているのであれば、その上にブログをやる時間を数時間を乗っけるのは、どだい無理な話です。

しんどいに決まっています。

それがわかっている上で何の備えもせずに突っ込むのは覚悟ではありません。

というのも、再度「preparedness」ですが、この単語は

  • pre:前もって
  • par:~という状態にする

という意味が含められています。

毎日数時間必要ならば、その時間を事前に確保すれば良いだけです。

毎週1回というルーチンにするのであれば、それがきちんと運用されるような仕組み(時間の確保、役割、報酬、罰など)を整えておけば良いです。

生活や習慣や仕組みを変えて整えておく、それが覚悟というものです。

まとめ

ブログによるコンテンツマーケティングで必要なものは

  • ドメインとサーバーの契約(月々数百円~)
  • ブログを書く技術(WordPressなどのソフトウェアの使い方、文章の書き方、ネットの知識)
  • 覚悟(=運用できるような仕組みを事前に整えておくこと)

です。

ここで言う「覚悟」は生活や習慣や仕組みを変えて運用できる体制を整えておくことです。

それさえできれば、ブログによるコンテンツマーケティングは簡単です。

気合も根性も無理をすることも必要なく、整えた通りに遂行していくだけですからね。


40歳はまだまだひよっこ。むしろこれからが市場価値を上げる勝負の時

$
0
0

chick

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

この5月5日に、晴れて40歳になりました。

大人になっても子供の日が誕生日というのは、なかなか話のきっかけとしては使いやすいです。

だいたいGW中だと忘れ去られるものなのですが、たくさんの方にお祝いのメッセージを頂きまして、大変うれしく思っています。

さて、40歳。

  • 「もう、完全にオッサンだ」
  • 「これからは衰えていく一方」
  • 「もう転職は厳しい」

働く現場ではこのような暗いイメージがつきまとっているように思えます。

読者のみなさんはどうですか?

ですが、私は全くそんなふうには思っていません。むしろ

  • 「まだまだ全然フレッシュ!」
  • 「これから成長していく一方!」
  • 「転職だけではなくて選択肢はたくさんある」

と思っています。

今日は、40歳なんでまだまだひよっこで、これからがむしろ勝負だ、ということを書きたいと思います。

40歳以上の従業員の雇用は守らない

シャープ訪問時の、ホンハイ会長のコメントです。

「40歳未満の従業員の雇用は守るから安心してほしい」

逆の意味で読んでください。

「40際以上の従業員の雇用は守らないから安心してほしい」

という意味です。日本の40歳以上も見下されたもんです。

しかし、日本国内の転職市場でも40歳以上、場合によっては35歳以上は年齢だけで足キリをされちゃったりしますよね。

一方で、今では大手企業も業績悪化を理由に平気で行う「早期退職募集」。

これも、年齢が高い人たちが対象になります。

…なんか、年を重ねれば重ねるほど「無能」扱いされる…悲しい現実です。

普通に考えれば、年数があるほど学ぶ時間が多くなるわけですから、能力は上がっていくはずなんですけどね…おかしいですね?

長く居続けると会社への依存度が増す?

先日こんな記事を読みました。

この記事の中で、大手の飲料メーカーに勤める40前後の知人との会話が掲載されていました。

「40くらいになると、もう他社に転職するのは不可能なんだよね。多分、このままずっと行くと思う。」

「なぜ?」

「一度、転職しようかとおもってエージェントに会ってみたけど、年収下がるって。150万くらい。」

「150万か……。でも、新しい環境でチャレンジするなら、それくらいは許容範囲じゃない?」

「いやいや、多分家族が許してくれない。」

「そうか。」

「それと、新しい職場で成功するって言う保証はないじゃない。」

「まあね。」

「今の職場は、面白く無い訳じゃない。多少ガマンすれば、安定して良い職場だし。」

「じゃ、なんで不安なの?」

「最近、50くらいの人がリストラされてさ。まあ、かなりできない人たちが対象だったから、問題ないとは思うけど。」

「ふーん。」

「でも、うちの会社も大きいとはいえ、業績もほとんど伸びてないし……このまま定年まで逃げ切れればいいけど。」

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

イラっとしますよね??

40前後の大手飲料メーカーに勤めるサラリーマンの彼は、そのまま定年まで逃げ切りたいと言っています。

彼が就職したのが22歳とすると、まだ20年も働いていません。

定年が65歳とすると、残りはあと25年もあります。

まだ半分も走っていないのに…逃げ切れるのでしょうか?

ていうか、逃げ切れなかったときはどうなりますか?

50歳あたりでいきなりリストラされて転職市場に放り出されたら、どうやって彼と家族は生きていくのでしょうか?

ちょうど、アラフォー手前でぶら下がり状態から放り出された奴の記事がありますので、良かったら見て下さい。

私が仕事を辞めて独立して起業をすることになった理由
来る2015年6月をもちまして現在の会社を辞めることになりました。ほどなくして法人を設立しましてひとり社長として活動を開始します。今回はそのご報告とともに、それに至る経緯についてお話できればと思います。

有事の時のために常に準備をしておくことは簡単ではありませんができますし、アラフォーだから覚えが悪いとかそんなことは全くありません。

40歳だとしてもメキメキ能力を上げ、スキルを身に着け、市場価値を上げていくことができます。

アラフォーでも成長し市場価値を上げられる

私の場合は、独立する前のサラリーマン時代に1年弱ですが準備期間を持つことができました。38歳のときです。

プラス独立をして1年なので、約2年間。そこで様々なスキルを身に着けることができました。

この2年間で身に着けたスキル

ざっと上げてみますと

  • VBA
  • ブログとそれによるマーケティング
  • WordPress
  • Google App Script・JavaScript
  • セミナー
  • 経理
  • 統計・データ分析

などがあります。

経理以外は全て収益に直接結びついています。

これらは全て、38歳より前には触れたこともありません。偉そうにブログで書きまくっていますが、VBAですらここ最近で身に着けたものです。

つい最近までこんな記事を書いていましたが…

アラフォーの私が今さらながらプログラマーを目指している理由
お仕事効率化をテーマに起業をしてからしばらく経ちました。そこで確信したことがあります。私はプログラマーになるしかない!と。なぜそう確信するに至ったか、その理由を3つほど挙げようと思います。

独立当初の私はプログラムなしで何をもって収益を得るつもりだったんですかね?

…まあいいや。

少し話を戻しますね。

独立してからはそんなに気にしなくていいのですが、会社員時代でスキルを上げるためには一つ重要なポイントがあるんです。

会社への依存を捨てて自立する

それは、会社への依存を捨てて自立するということです。

なぜなら会社に所属している状態では、多くの場合は

  • 平日昼間は学習に充てられない
  • 行きたいセミナーやイベントに行けない
  • 今の仕事と直接関係ないことをやるのは気が引ける
  • 会社のPCや設備が整っていない
  • スキルを上げてもそれを活かす場がない
  • スキルを上げても評価されない

など、様々な事象が従業員の市場価値を上げることを阻害し、会社に依存し続けるような引力が働きます。

一方で会社が個々人のスキルを上げるための環境や機会を十分に用意しているかというと、多くの会社では不十分です。

ですから、働きながらも自らのスキルを磨き、市場価値を上げるためには、就業規則に反しない範囲で本業の合間を縫って行動をする必要があります。

しかし、そのためには自立が必要です。

それは

  • 何か見つかってアレコレ言われてもちゃんと対等に会話をして解決をする
  • 残業をせずにさっさと帰ることに後ろめたさを感じない

などといった覚悟とも言い換えることができます。

逆に、その覚悟を持って動き出しはじめると、市場での価値やポジションが少しずつ正確に見えてくるようになります。

副業が一番の近道

許されるのであれば副業をするのが近道です。

資金面でも余裕を持たせつつ、お金を稼ぐ感覚や市場のニーズをリアルに味わえるからです。

副業禁止!?いやむしろ解禁することで企業にもたらされる4つのメリット
多くの企業では副業禁止としていますが、しかしその中でコッソリと副業をしている従業員がいるのも事実。今回の記事では、むしろ副業を容認することで企業にもメリットがあるということについてお伝えします。

私はブログとコンサル(オンライン中心)からスタートをしました。

ブログはパソコン一台あればできますし、WordPressとWebマーケティングのスキルを身に着けつつ、お小遣い程度の広告収入も得られます。

コンサルはチャットワークなどのツールを使えば、休み時間や、帰宅後の時間で対応ができます。

どうしても打ち合わせがしたい、というときには就業時間後にお願いするか、有休を使うようにしました。

まとめ

私は40歳になりましたが、経営者としてはまだ1歳のヨチヨチ歩きです。

準備期間を含めて2年ほどで、そこそこ商売ができるほどのスキルを身に着けていますから、まだまだ伸び盛り。

今のペースで5年、10年と学びを続けていけば…かなり自分の市場価値は上げられるのではないかと思っています。

目標は80歳まで現役!

…まだ40年もあります。長いっす。

さて、日本の40代(もちろん他の世代も歓迎!)が、そのように市場価値を上げていったらどうなりますか?

1億総活躍もいいですが、今働いているオッサンたちがもっとキラキラ活躍できたら、間違いなく日本は復活するはずです。

40歳なんて、まだまだひよっこ。勝負はこれからですよ!

複数のチャットサービスをまとめて管理できる無料のアプリケーションFranzとその使い方

$
0
0

Franzサイトトップ

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

チャットワークやSlackなどビジネス向けのものから、Facebook Messenger、Skypeなどプライベートでも使えるものに至るまで、お仕事の現場ではたくさんのチャットサービスが使われるようになってきました。

一つにまとめたいなーなどと思っていても

  • 自社ではSlack
  • 取引先とはチャットワーク
  • 仕事友達とはFacebook

…といったように、どうしても複数のチャットサービスを並行して使いこなさざるを得ない場合も出てきているのではないでしょうか?

そして、切り替え…面倒ですよね?!

そんなときに便利なアプリケーションが今回紹介するFranzです。

Franzは数あるチャットサービスをまとめて管理できる無料のアプリケーションです。

今回はFranzの概要とその使い方についてお伝えします。

Franzとは

Franzでは以下に挙げるチャットサービスをまとめて一つのアプリケーションで管理できます。

  • Slack
  • Messenger
  • WhatApp
  • Telegram
  • Skype
  • WeChat
  • HipChat
  • ChatWork
  • Hangouts
  • GroupMe
  • Grape
  • Gitter
  • Steam Chat
  • Discord

…たくさんありますね!

ですが、なんと無料です。

OSはWindows、Mac、Linuxに対応をしています。

マルチアカウント、つまり同じチャットサービスで複数のアカウントを使い分けている場合も、それぞれのアカウントについて追加してまとめて管理できます。

私がFranzを使う理由

私は主にチャットワークをメインで使っています。

たまにMessengerを使います。このMessengerが…ちょっとクセものなんですよね。

  • ブラウザでMessengerを開いたままにするほど使用頻度は高くない
  • ブラウザでFacebookを開いたまんまだと、いいねを押したの押してないの…結構色々な通知が気になっちゃって仕事にならない
  • しかもFacebookのチャット窓は使い勝手が悪い

など…全体的に使いづらいと感じていました。ですが、時々以上しばしば未満くらいの頻度でFacebookメッセージで連絡が来ます。

そこでFranz登場です。

では、実際にダウンロードして使ってみましょう。

Franzのダウンロードと起動

まずFranzサイトにアクセスします。

これがトップページです。

Franzサイトトップ

ページをスクロールすると、ダウンロードするとDownloadボタンがすぐに見つかると思いますのでクリック。

Franzをダウンロード

zip形式のファイルがダウンロード保存されます。ちなみに、今回はWindows版です。

zipを解凍すると、フォルダの中に「FranzSetup.exe」というファイルがポツンとありますので、これをダブルクリックして起動。

起動した画面がこちらです。

Franzを起動

簡単ですよね?

一回起動するとFranzのショートカットがデスクトップに生成されますので

Franzのショートカット

これをスタートアップフォルダにコピーしてもらえれば、次回からはPC起動時に自動でFranzが立ち上がるようになりますので便利です。

Windows10のスタートアップフォルダについてはこちらをご覧ください。

Windows10にアップデートして見つけられなくなったスタートアップフォルダの場所
Windows10にアップデートして少し困ったこととして「スタートアップフォルダが見つからない件」があります。今回はWindows10のスタートアップの設定の仕方とその内容についても紹介をしています。

各チャットサービスのタブを追加

各チャットサービスの「タブ」をFranzに追加することで、タブ切り替えで各チャットサービスを切り替えて使えるようになります。

では、例としてチャットワークとMessengerのタブを追加していきますね。

チャットワークのタブを追加

Franzの画面からチャットワークを選択します。

Franzでチャットワークを選択

「Add ChatWork」というウィンドウが開きます。ラジオボタンの設定は

  • 通知をする
  • 音をミュートする

です。

マルチアカウントの場合はNameをそれぞれのアカウント名などに変更しておくとわかりやすいと思います。

「Add ChatWork」ボタンをクリックします。

Franzでチャットワークを追加

すると、Franzの上部に「ChatWork」のタブが追加されます。

Franzでチャットワークタブが追加

タブをクリックすると、チャットワークのログイン画面が開いていますので、ブラウザで開いているときと同じように、メールアドレスとパスワードを入力してログインしてください。

Franzでチャットワークにログイン

これでチャットワークにログインでき、Franz上でふつうにチャットができるようになります。

Franzでチャットワークを使用

Facebook Messengerのタブを追加

続いてFacebook Messengerを追加していきましょう。

Franzアイコンのタブをクリックします。

Franzのホームアイコンをクリック

今度はMessengerを選択します。

FranzでMessnagerを選択

あとはチャットワークのときと同様に操作を進めていけばMessengerのタブがFranzに追加されます。

Messengerのタブを選択してメールアドレスとパスワードを入力。「次へ」をクリックすれば…

FranzでFacebook Messangerにログイン

Messengerにログインしてチャットをすることができるようになります。

FranzでMessnagerを使用

タブの切り替えはショートカットキー

タブの切り替えはChromeブラウザと同じショートカットキーが使えます。

Ctrl + 0:Franzホームタブに移動
Ctrl + 1Ctrl + 9:各番号のタブに移動
Ctrl + Tab:次のタブに移動
Ctrl + Shift + Tab:前のタブに移動

使いこなすととても便利ですよ。

まとめ

複数のチャットサービスをマルチアカウントでまとめて管理できるアプリケーションFranzとその使い方についてお伝えしました。

二つ以上使う場合はもうFranz使ってもいいかもしれませんね。

ぜひご活用下さい。

Google Apps Scriptでチャットワーク上に翻訳チャットを作る

$
0
0

robots

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

以前、Google Apps Scriptを使って「おみくじチャット」を作りました。

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

「わーい、今日は大吉だ!」

…なんて、まあまあ楽しいのですが、残念ながら仕事にはあんまり役に立たないです。

ですが、Google Apps ScriptチャットワークAPIを使って

  • チャットワークからメッセージを受け取り
  • 何かしらの処理をして
  • チャットワークにメッセージを返す

というベースの仕組みは非常に応用性の高いものです。

そこで、この仕組みを応用して「翻訳チャット」を作っていきたいと思います。

ちょっと調べものをしているとき、チャットで翻訳ができたら…けっこう便利そうですよね!?

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

おみくじチャットのおさらい

最初にベースとなるおみくじチャットプログラムをおさらいしておきたいと思います。

function getOmikuji(){

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

  var json = fetchMessage(token,room_id);

  /* json内に「おみくじ」メッセージがあればチャットワークに送信 */
  for each(var obj in json){
    if(obj.body === "おみくじ"){

      var body = "[rp aid=" + obj.account.account_id
        + " to=" + room_id
        + "-" + obj.message_id
        + "] " + obj.account.name
        + "さん[info]おみくじの結果:" + generateOmikuji() + "[/info]"; //チャットワークに送るテキスト

      sendMessage(token,room_id,body);
    }
  }
}

いくつか独自の関数がありますが

fetchMessageはチャットワークの特定のルームから未取得のメッセージをjson形式で取得してくる関数

fetchMessage(APIトークン, ルームID)
– 引数 token:APIトークン, room_id:ルームID
– 返り値 json:レスポンスをJSON解析した配列

sendMessageはチャットワークの特定のルームにメッセージを送る関数

sendMessage(APIトークン, ルームID, メッセージ本文)
– 引数 token:APIトークン, room_id:ルームID, body:メッセージ本文
– 返り値 なし

generateOmikujiは”大吉”,”中吉”,”小吉”,”吉”,”半吉”,”末吉”,”凶”の中からランダムにいずれかを返す関数です(この関数については今回は関係ないですね)。

9行目から始まるfor each文で取得した全てのメッセージについての繰り返しとしています。

取得したメッセージが「おみくじ」とイコールであれば、12~16行でメッセージを成形しつつ、チャットワークにメッセージを送ります。

詳しくはこちらの記事をご覧くださいね。

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

翻訳をするtranslateメソッド

さて、翻訳チャットシステムのキモとなる翻訳処理をいかにするか考えます。

Google翻訳のサービスは今や世界中のたくさんの方が利用してるかと思いますが、Google Apps ScriptからGoogle翻訳の機能を利用するためにLanguageApp.translateメソッドが用意されています。

LanguageApp.translate(元のテキスト,元の言語,翻訳する言語)

と書きます。

言語のところは日本語なら「ja」、英語なら「en」など、2文字であらわされる言語ごとのコードを入力します。

これはISO 639-1に登録されているもので、ウィキペディアにコード一覧がありますので、どうぞご活用下さい。

ウィキペディア:ISO 639-1コード一覧

例えば、resultという変数に日本語から英語への翻訳結果を格納したい場合は

var result = LanguageApp.translate("日本語から英語へ翻訳します", "ja", "en");

とします。簡単でしょ?

さらに、ここがすごいのですが、第二引数の「元の言語」に空の文字列を設定した場合は元のテキストから言語が自動検出されます。

var result = LanguageApp.translate("日本語から英語へ翻訳します", "", "en");

でも良いということです。

便利ですね~。

ですから翻訳システムとしては、翻訳する本文と翻訳後の言語だけユーザーに指定をさせれば動かすことができる、ということですね。

翻訳チャットシステムの概要

さて、今回作る翻訳チャットのシステムですが、翻訳に必要な情報は

  • テキスト本文
  • 翻訳する言語

となりますので、動作としては

  1. チャットワークに「言語コード;本文」とメッセージを送信
  2. その返信の形で翻訳結果を返す

という動作にしたいと思います。セミコロンの前に翻訳をする言語コードを指定して、セミコロンの後に本文を書くという形です。

システムの流れとしては、おみくじチャットを応用して

  1. チャットワークから未取得のメッセージをjson形式で取得
  2. 取得したすべてのメッセージについて
    1. セミコロンで言語コードと本文を分ける
    2. 翻訳
    3. チャットワークに送るテキストを成形
    4. チャットワークにメッセージを送信

という流れです。

2-1,2-2を作って、2-3をちょっと変更すればOKです。

翻訳チャットの最も簡単なスクリプト

実際のスクリプトはこちらです。

function translateChat() {

  var token = 'APIトークン'; //チャットワークAPIトークン
  var room_id = XXXXXX; //翻訳さんのルームID

  var json = fetchMessage(token,room_id); //翻訳さんグループチャットのメッセージを取得

  /* 各メッセージについて 繰り返す */
  for each(var obj in json){

      var arr = obj.body.split(';'); //セミコロンでsplitして配列に格納
      var result = LanguageApp.translate(arr[1], "", arr[0]); //翻訳

      var body = "[rp aid=" + obj.account.account_id
        + " to=" + room_id
        + "-" + obj.message_id
        + "] " + obj.account.name
        + "さん[info]翻訳結果:" + result + "[/info]"; //チャットワークに送るテキスト

      sendMessage(token,room_id,body); //チャットワークにメッセージを送る
    }
}

特定の文字で文字列を分割して配列に格納する

11行目で取得したメッセージをセミコロンで分割をしています。

文字列を特定の文字で分割する場合はsplitメソッドを使い

文字列.split(特定の文字);

とします。結果は配列として格納されます。

今回はarrという配列を指定していますので、メッセージがルールに則ったものであれば

  • arr[0]:言語コード
  • arr[1]:本文

と格納されるはずです。

実行結果

チャットワークにルール通りにメッセージを送った上でスクリプトを実行しますと

チャットワークの翻訳チャット結果

このような形で翻訳結果が返ってきます。

シンハラ語のほうは…合ってるかわかりませんが…汗

まとめ

Google Apps Scriptとチャットワークで翻訳チャットを作成しました。

…すごいですね。便利ですね。

さて、今回のプログラムではルールに則っていないメッセージをチャットワークから送るとGoogle Apps Scriptではエラーとなり、正しく動作しません。

ということで、次回ルールに則っていないメッセージが送られてきたときの処理を追加したいと思います。

どうぞお楽しみに!

【エクセルVBA】シートの開始行や行数の変更があってもちゃんと動く繰り返し文の書き方

$
0
0

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

エクセルにおいて「全ての行について何かしらの処理をしたい」というニーズがあったとき、エクセルVBAでFor~Next文を使うのが基本中の基本です。

ですが、ワークシートの運用上、行の挿入や行の追加が発生する

  • 開始行が変わってしまったり
  • 行数(最終行)が変わってしまったり

して、うまくFor~Next文を使ったプログラムが動かなくなることがあります。

今回は、その回避方法をいくつかお伝えしたいと思います。

エクセルVBAでワークシートの開始行や行数の変更があっても繰り返し処理がちゃんと動くプログラムの作り方です。

特にセルに名前をつける方法は、なぜかあまり知られていないような気がしますがオススメです。

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

お題:For~Nextの開始と終了の変更を不要にしたい

今回はお題としてこちらのシートを使いたいと思います。

エクセルに入力した会社概要のデータ

ホームページに記載する会社概要についてまとめた表です。

こちらの記事で、このシートの情報をもとにHTML文を作成する方法をお伝えしています。

エクセル入力情報からWebサイトの会社概要のHTML文を生成するVBAプログラム
エクセルの入力情報をもとに自動で企業サイト向けトップページのHTMLを生成していきます。今回は会社概要をテーブルで組んでいる箇所のHTMLを生成するVBAプログラムの作成を進めていきます。

少し省略していますが以下のようなプログラムです。

Function createAboutSection(ByVal ws As Object) As String

'初期処理

Dim i As Long, j As Long
For i = 5 To 9 '5~9行目まで繰り返し

     '5~9行目までのそれぞれの行に行う処理

Next i

'後処理

End Function

ですが、例えばこのようにシートに変更があったとすると

エクセルシートに行を追加した

処理をする対象が6~11行目になりますから、For~Next文の開始と終了の値を変更しなくてはならなくなります。

いちいちVBEを開いて修正するのは面倒ですし、現実的ではありませんので、その修正をしなくても済むように元のプログラムを直していきたいと思います。

セルに名前をつけて開始行を都度求める

ではまず開始行に変更があっても対応できるようにしていきます。

セルに名前をつけるという方法を使います。

「項目名」と入力されているA4セルに「目印」としての名前をつけたいと思います。

以下画像で示した入力欄に「A4」と入力されていますが「項目名」と上書き入力して Enter をします。

エクセルの名前ボックスでセルに名前をつける

この入力欄は名前ボックスと言いまして、ここに任意の文字を入力して Enter をするとセルに名前をつけることができます。

このセルが他の行列の挿入や削除により移動することがあったとしても、つけた名前も引き連られます。

そしてエクセルVBAでは、以下のように名前を指定してセルを取得することができます。

Worksheetオブジェクト.Range(セルの名前)

ですから、今回の場合は

Function createAboutSection(ByVal ws As Object) As String

'初期処理

Dim startRow as Long
startRow = ws.Range("項目名").Row + 1

Dim i As Long, j As Long
For i = startRow To 9 '「項目名」の次の行~9行目まで繰り返し

     'それぞれの行に行う処理

Next i

'後処理

End Function

などとすることで、セルの名前からセルの行数を求め、それにより最終行を特定することができます。

最終行の位置を都度求める

では次に行数に変化があった場合でも対応できるようにしていきたいと思います。

この方法として、二つほど方法があります。

まず一つ目は、都度最終行の行数を取得する方法です。

こちらの記事でも紹介していますが

【初心者向けエクセルVBA】行の数をカウントする&不要な行を隠す
今回は行数をカウントする、行を隠す、などの「行を取り扱うテクニック」を紹介しています。いずれもデータや帳票を扱ったエクセルVBAではかなり重宝するテクニックですので、知っておいて損はありませんよ。

Worksheetオブジェクト.Cells(Rows.Count, 列数).End(xlUp).Row

という書き方です。

今回の場合は

Function createAboutSection(ByVal ws As Object) As String

'初期処理

Dim startRow as Long
startRow = ws.Range("項目名").Row + 1

Dim endRow as Long
endRow = ws.Cells(Rows.Count, 1).End(xlUp).Row

Dim i As Long, j As Long
For i = startRow To endRow '「項目名」の次の行~最終行目まで繰り返し

     'それぞれの行に行う処理

Next i

'後処理

End Function

などとすればOKです。

Do While文で行数に関わらず繰り返すようにする

もう一つの方法は、For~Next文ではなくて、Do While~Loopを使う方法です。

書き方はこちらです。

Do While 条件文
(繰り返したい処理)
Loop

今回の場合、条件として「1列目のセルに値が入力されている間」とすることで、最終行まで処理を繰り返して、最終行を超えたら繰り返しを抜けてくれるようになります。

Function createAboutSection(ByVal ws As Object) As String

'初期処理

Dim startRow as Long
startRow = ws.Range("項目名").Row + 1

Dim i As Long, j As Long
i = startRow
Do While ws.Cells(i, 1).Value <> "" '「項目名」の次の行~最終行目まで繰り返し

     'それぞれの行に行う処理
     i=i+1
Loop

'後処理

End Function

Do Whileを使う場合は二つほど重要な注意点があります。

一つ目は、繰り返しの判定で使う列のセルに空欄を入れないということです。空欄があるとその時点で繰り返しから抜けて二度と戻って来ません。

二つ目は、13行目のi=i+1を必ず入れるということです。While Doはイテレータ(今回でいうと変数i)を使わない繰り返しですので、イテレータの増加は別途命令しないといけません。これを忘れると永久に繰り返しから抜け出さなくなります。

以上、二点に気を付けて頂ければと思います。

詳細はこちらの記事もご覧ください。

【エクセルVBA入門】Do While~Loopで条件を満たす間繰り返し
エクセルVBAを使ってバラバラの経費精算書のデータを集約するシリーズの第2回です。今回はDo While~Loopを使って条件を満たす間、任意の処理を繰り返すプログラムの書き方をマスターしていきます。

個人的にはDo While~Loopのほうが変数も少なくて済みますので好きです。

まとめ

以上、エクセルVBAでワークシートの開始行や行数の変更があっても繰り返し処理がちゃんと動くプログラムの作り方についてお伝えしました。

エクセルVBAは多くの場合、業務の変更に合わせてプログラムを修正をする必要がありますね。

逆に言えば、業務フローの設計や最適化といった面も学べるという側面もあります。そのような部分も気にしながら学習されると、より一層の広さ・深さでのスキルアップが図れると思いますよ。

次回は、今回お題にしたHTML作成のVBAを進めていきたいと思います。

どうぞお楽しみに!

連載目次:エクセルの入力情報からVBAでHTML文を自動生成

  1. エクセルVBAでWordPress投稿用HTMLソースを自動で生成する
  2. エクセルVBAでインデントや改行を入れながらHTML文を追加していく便利関数を作る
  3. エクセル入力情報からWebサイトの会社概要のHTML文を生成するVBAプログラム
  4. 【エクセルVBA】シートの開始行や行数の変更があってもちゃんと動く繰り返し文の書き方

【GAS】Gmailからメールを検索してスプレッドシートに書き出す

$
0
0

write-mail

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

Gmailに届いたWordPressサイトからの問い合わせメールの分析を進めています。

前回こちらの記事で

【GAS】Gmailに送られた過去のメールから特定条件のメールを検索して取得する
問い合わせメールのデータの蓄積と効果分析にまつわることを色々とやっていきたいということで、今回はGoogle Apps Scriptで過去の問い合わせメールを特定条件で検索して取り出す方法です。

Google Apps Scriptで過去の問い合わせメールを特定条件で検索して取り出す方法についてお伝えしました。

今回はGoogle Apps Scriptにスクリプトを追記して、取り出したメールたちをスプレッドシートに書き出してみたいと思います。

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

前回のおさらいと今回のお題

前回作成したスクリプトはこちらです。

function searchContactMail() {

  var strTerms = '("このメールは 株式会社プランノーツ http://plannauts.co.jp のお問い合わせフォームから送信されました" OR '
                  + '"このメールは いつも隣にITのお仕事 http://tonari-it.com のお問い合わせフォームから送信されました")';
  var myThreads = GmailApp.search(strTerms, 0, 500); //条件にマッチしたスレッドを取得、最大500通と決まっる
  var myMsgs = GmailApp.getMessagesForThreads(myThreads); //スレッドからメールを取得する →二次元配列で格納

  for(var i=0;i < myMsgs.length;i++){
    Logger.log(myMsgs[i][0].getSubject()); 
  }
}

検索条件がちょっと強引な感はありますが…

  1. 特定のメッセージが含まれるスレッドを抽出
  2. スレッドからメッセージを取得し二次元配列に格納
  3. 各スレッドの1番目のメールの件名をログ出力

という流れになりますね。

各スレッドの1番目のメールがほぼ間違いなく問い合わせメールになります。ちなみに、各スレッドの2番目以降のメールは、問い合わせに対する私の返信などを含む、一連のメールのやり取りということにほぼ間違いありません。

詳細は前回記事をご覧ください。

【GAS】Gmailに送られた過去のメールから特定条件のメールを検索して取得する
問い合わせメールのデータの蓄積と効果分析にまつわることを色々とやっていきたいということで、今回はGoogle Apps Scriptで過去の問い合わせメールを特定条件で検索して取り出す方法です。

今回は上記流れの3のところを修正して、各スレッドの1番目のメールについて

  • 日時
  • 送信元
  • 件名
  • 本文

をスプレッドシートに書き出していきたいと思います。

シートはこのように準備しました。

メールを出力するスプレッドシート

メールの日時、送信元、件名、本文を取り出す

各メールについてのに日時、送信元、件名、本文を取り出すには、それぞれ以下のメソッドを使います。

日時:メール.getDate()
送信元:メール.getFrom()
件名:メール.getSubject()
本文:メール.getPlanBody()

ではこれらを用いてスクリプトを修正してみましょう。こちらです。

function searchContactMail() {

  /* Gmailから特定条件のスレッドを検索しメールを取り出す */
  var strTerms = '("このメールは 株式会社プランノーツ http://plannauts.co.jp のお問い合わせフォームから送信されました" OR '
                  + '"このメールは いつも隣にITのお仕事 http://tonari-it.com のお問い合わせフォームから送信されました")';
  var myThreads = GmailApp.search(strTerms, 0, 500); //条件にマッチしたスレッドを取得、最大500通と決まっている
  var myMsgs = GmailApp.getMessagesForThreads(myThreads); //スレッドからメールを取得する →二次元配列で格納

  var valMsgs = [];

  /* 各メールから日時、送信元、件名、内容を取り出す*/
  for(var i = 0;i < myMsgs.length;i++){

    valMsgs[i] = [];
    valMsgs[i][0] = myMsgs[i][0].getDate();
    valMsgs[i][1] = myMsgs[i][0].getFrom();
    valMsgs[i][2] = myMsgs[i][0].getSubject();
    valMsgs[i][3] = myMsgs[i][0].getPlainBody();

  }

  /* スプレッドシートに出力 */
  SpreadsheetApp.getActiveSheet().getRange(2, 1, i, 4).setValues(valMsgs); //シートを取得

}

メールから各情報を取り出していったんvalMsgsという二次元配列に格納をして、最後にsetValuesメソッドで一気にスプレッドシートに張り付けるという方法をとっています。

このあたり、詳しくはこちらの記事をご覧ください。

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

実行結果

このスクリプトを実行してみると

Gmailからのメールをスプレッドシートに出力した結果

こうなります。

一応ちゃんとシートに出力できているのですが

  • 本文が長すぎて見づらい
  • 送信元が自分のアドレスになっている

という問題点があります。この点を修正していきたいと思います。

文字列から指定の範囲だけ取り出す

まず本文が長すぎるので文字数でぶった切ってシートへ入力してしまいましょう。

文字列の部分文字列を取り出す場合はsliceメソッドを使いまして

文字列.slice(開始位置, 終了位置)

とします。

例えば50文字だけ取り出すのであれば

valMsgs[i][3] = myMsgs[i][0].getPlainBody().slice(0,50);

とします。

スレッドのパーマリンクを取得する

この場合、本文を全部読みたくなるときに困ります。

その時には、そのメールへのリンクを踏んでその先で全文を読めるようにしましょう。

パーマリンクはスレッド単位での取得になりますが、特定のスレッドのパーマリンクを取得する場合はgetPermalinkメソッド

スレッド.getPermalink()

と書きます。

メールの返信先を取得する

次に送信元が自分のアドレスになってしまっている件を解決していきます。

問い合わせフォームを作成しているWordPressプラグインContact Form 7のメールの設定を確認すると

Contact Form 7のメール設定

確かに、送信元が自分のアドレスになってしまっています。

過去のものは直しようがありませんので、今回は代替案として、「追加ヘッダー」に設定されている返信先つまり「Reply-To」の値をもって、送信元としたいと思います。

メールの返信先を取得する際はgetReplyToメソッド

メール.getReplyTo()

とすればOKです。

Gmailからメールを取得してスプレッドシートに書き出すスクリプト

以上をまとめると、こちらのスクリプトになります。

function searchContactMail() {

  /* Gmailから特定条件のスレッドを検索しメールを取り出す */
  var strTerms = '("このメールは 株式会社プランノーツ http://plannauts.co.jp のお問い合わせフォームから送信されました" OR '
                  + '"このメールは いつも隣にITのお仕事 http://tonari-it.com のお問い合わせフォームから送信されました")';
  var myThreads = GmailApp.search(strTerms, 0, 500); //条件にマッチしたスレッドを取得、最大500通と決まっている
  var myMsgs = GmailApp.getMessagesForThreads(myThreads); //スレッドからメールを取得する →二次元配列で格納

  var valMsgs = [];

  /* 各メールから日時、送信元、件名、内容を取り出す*/
  for(var i = 0;i < myMsgs.length;i++){

    valMsgs[i] = [];
    valMsgs[i][0] = myMsgs[i][0].getDate();
    valMsgs[i][1] = myMsgs[i][0].getReplyTo();
    valMsgs[i][2] = myMsgs[i][0].getSubject();
    valMsgs[i][3] = myMsgs[i][0].getPlainBody().slice(0,200);
    valMsgs[i][4] = myThreads[i].getPermalink();

  }

  /* スプレッドシートに出力 */
  SpreadsheetApp.getActiveSheet().getRange(2, 1, i, 5).setValues(valMsgs); //シートを取得

}

18行目ですが本文を取り出す文字列は200文字にしました。

また19行目のパーマリンクの出力先をE列にしましたので、それに伴って24行目のgetRangeの列幅を5に変更しています。

実行結果

実行結果はこちらです。

Gmailからのメールをスプレッドシートに出力した結果

前に比べるとだいぶ見やすくなりましたね。

またパーマリンクをクリックすると

スレッドのパーマリンクをリンク

このように各メールの全文を確認できるページが開きます。

まとめ

以上、Google Apps ScriptでGmailから特定条件で検索したメールをスプレッドシートに出力をする方法をお伝えしました。

各メールについて日時、送信元、件名、本文、返信先を、そして各スレッドについてパーマリンクを取得するメソッドを紹介しましたが、他にもありますので、用途に応じて調べてみて下さいね。

Class GmailApp | Apps Script | Google Developers

これで過去の問い合わせについて分析する地盤が整いましたので、分析を進めていきたいと思います。

どうぞお楽しみに!

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

  1. 【GAS】Gmailに送られた過去のメールから特定条件のメールを検索して取得する
  2. 【GAS】Gmailからメールを検索してスプレッドシートに書き出す

フリーランスの仕事はどこから来たか、独立して1年間の受注件数を全て晒す

$
0
0

work

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

独立してからもうすぐ1年となります。なんとか生き永らえています。

さて、前回のコチラの記事で

【GAS】Gmailからメールを検索してスプレッドシートに書き出す
Gmailに届いたWordPressサイトからの問い合わせメールの分析を進めています。 今回はGoogle Apps ScriptでGmailから検索して取り出したメールたちをスプレッドシートに出力します。

当ブログと会社のWebサイトからの問い合わせメールについての集計ができました。

今回、その集計データに加えて

  • どのような問い合わせが何件来たか
  • 問い合わせからの受注件数はいくらか

という情報を追加し、加えて問い合わせメール以外の受注経路についても集計をしました。

ちなみにですが、今から8カ月前、昨年の9月にこちらの記事を書いていました。

フリーランスの最初の仕事はどこから来るのか?
「月60万稼ぐフリーライターになるには」というトークイベントに参加してきました。イベントで語られた話題の中で、フリーランスが最初の仕事はどこから来るのか?に絞って聴いたこと考えたことを書いています。

その中で

独立している私がどのように仕事をゲットしているかと言いますと、100%が知り合いからのお声掛けでした。

と書いていました。

その後、8カ月が経った今、「仕事がどこから来るのか」には変化はあったのでしょうか?

毎日アホみたいに書きまくっているブログ…いわゆるコンテンツマーケティングの効果は本当にあるのでしょうか?

今回の記事では、実際の件数を全て晒してフリーランスのリアルをお伝えします。

Webサイトからの問い合わせ集計結果

当ブログと企業サイト経由の問い合わせフォームから送られたメールをGmailから検索してスプレッドシートに出力する方法について、冒頭に紹介した前回記事でお伝えしています。

それがこちらです。

Gmailからのメールをスプレッドシートに出力した結果

日付、送信元(正確には返信先)、件名、内容(冒頭200字抜粋)、パーマリンクを取得することができました。

それに加えて、今回作業として

  • 問い合わせのカテゴリは何だったか?
    • 依頼:仕事の依頼
    • 応募:パートナー募集(ブログ執筆や業務委託先としての)に対する応募
    • 営業:何かしらかの売り込み
    • 質問:ブログの内容についての質問(技術的なものが多い)
    • Bizer:Bizerの招待コードが欲しい!という内容
  • 「依頼」と「応募」に関してはその結果
    • 依頼→受注または失注
    • 応募→発注または失注

を情報として追加しました。

また、2016年2月からはチャットワークで直接問い合わせをすることもできるようにしましたので

チャットワーク経由の問い合わせについても同様に集計を行いました。

問い合わせの件数と成果

スプレッドシートに集計結果をまとめたのがこちらです。

Web問い合わせ件数と成果について集計

カテゴリ別の問い合わせ件数とその比率では

  • 依頼:14件(22.58%)うち受注9件(受注率64.29%)
  • 応募:17件(27.42%)うち発注2件(発注率11.76%)
  • 営業:25件(40.32%)
  • 質問:4件(6.45%)
  • Bizer:2件(3.23%)

となりました。

ちなみに、受注件数は新規顧客数です。リピートについては件数としてカウントをしていません。

仕事の依頼獲得の成果

まず一番気になる新規受注件数です。

ブログによるコンテンツマーケティングの結果として仕事の依頼に関して14件の問い合わせがあり、9件の受注をしました!

直叩きでWebサイトに来ている可能性もありますが、厳密には全てとは言えないかも知れませんが、企業サイトへのトラフィックの9割がブログまたは自然検索になります。

さて、驚くべきはその受注率。

現在検討を頂いている最中の案件が2件ありますので、それを除くと受注率は75%です。

というのも「この記事に書いてあることをお願い」という依頼がとても多いですし、私のやり方とか人柄もなんとなくわかった上でオファーを頂けます。

結果的に、Web経由のご依頼は提案・説明・交渉・クロージングが圧倒的にスムーズで確度も高くなります。

正直、対面営業よりも確率は高いと思います。

外部パートナー獲得の成果

外部パートナーを探すという目的でもコンテンツマーケティングが活躍をしています。

こちらに書いてある通り、ブログ執筆に加えてVBA、GAS、WordPressなどのお仕事をお願いできる方を絶賛募集しています。

今のところ、累計で17件の応募があり、2名の方にブログ執筆をお願いしています。

繰り返しになりますが、今でも絶賛募集中ですので、ぜひご連絡を!

Bizerの招待コードの問い合わせ

おまけでBizerの招待コードに関する問い合わせも2件頂きました。

月額2,980円で、人事、労務、経理などのバックオフィス業務をダンドリしてサポートしてくれるサービスなのですが、招待コードを使って登録すると招待した側とされた側の両方が1カ月無料になるのです。

こちらの記事で書いています。

無料または激安で利用可能!お仕事に便利なクラウドサービスまとめ12選
技術の進歩によりお仕事に限らず様々なクラウドサービスが利用できるようになりました。今回はお仕事効率化オタクの私が「便利さ」「手軽さ」「価格」を重点ポイントとして12のサービスを厳選しまして紹介をしていきます。

ということですので、Bizerを活用されたい方がいらっしゃいましたら、バンバンお問い合わせ頂ければと思いますよ!

経路別の仕事の受注件数

これまでWebサイト経由の問い合わせ件数について見てきましたが、それ以外の経路からは受注はできているのでしょうか?

経路別の受注件数についても集計してみました。

分類は以下の通りです。

  • Webサイト:ブログまたは企業サイト問い合わせから
  • 知人:独立前のつながりがあった知人から
  • イベント:独立以降に参加または登壇したイベントで知り合った方から
  • セミナー:自主開催セミナーで参加いただいた方から

そして、それぞれの経路からの件数(新規獲得顧客数)はこちらです!

  • Webサイト:9件(47.37%)
  • 知人:4件(21.05%)
  • イベント:2件(10.53%)
  • セミナー:4件(21.05%)

そして、それぞれの受注件数を月別に積み上げたグラフがこちらです。

経路別受注件数の月別推移

…どうなんでしょう。まだ危なっかしいですが、少しずつ増えていると言えますかね。

Webサイト経由の仕事獲得が約半数

前述のとおり、Webサイト経由は9件で比率としては47%つまり約半数がWeb経由での獲得となっています。

Webサイト…今となっては超重要になりました。

月によって増減があり、まだアグラをかけるほどの余裕は全くないのですが、毎日頑張って更新することでトラフィックは確実に伸びてきていますし、それに伴って問い合わせの件数も増えてくる期待はできると思います。

ブログを始めて1年、フリーランスとして毎日3時間をかけた価値はあったのか?
独立してから仕事を獲得する戦略として、ブログの更新を1年間、ほぼ毎日3時間をかけてコツコツと続けてきました。1年続けてきて実際にその価値はあったのか、実際のアクセス推移も含めてお伝えします。

12月、3月の受注が多かったというのは、季節的な要因もあるのかもしれませんが…ちょっと不明です。

イベント・セミナーでの獲得もある

IT関連や地域活性のイベントになどに参加して、たまに登壇もさせて頂いておりますが、そこでのつながりからで累計で2件ですがお仕事を頂けました。

意外だったのがセミナーの参加者からのお仕事です。

昨年の12月から毎月1~2講座ほどのペースでExcel、VBA、IT活用、WordPress、チャットワークなど様々なテーマで自主開催をしています。

毎回の参加者はだいたいの場合は数人、多くて8人。決して母数は多くないですから、比率としてはけっこう驚異的です。

2~3時間プレゼンができているという見方もできますが、セミナーの内容がご納得いただけているものと、嬉しい気持ちでお受けしております。

大きな案件から小さくて継続的な案件に

先ほどのグラフを見て頂くとわかるのですが、昨年の7月から11月にかけて、ほとんど新たな仕事を獲得することができていませんでした。

というのも、7月から9月くらいまでは大きな案件を中心にお受けしていて、そのお仕事にかかりっきりの傾向がありました。

案件が大きいのはありがたいのですが、10月くらいから大き目の案件が一つ一つ終わり、その穴が大き過ぎて全く埋められない…という現象が起きていたのです。

正直、あと一カ月そのモードが続いていたら、ちょっと危なかったかも知れません。

それで慌てて、秋ごろから

  • 小さい仕事を
  • たくさん
  • かつ継続的に

といった仕事の獲得するようにシフトしました。

イメージとしてはひと月で何十万の仕事を獲得するというよりは、毎月数万円の仕事を半年分獲得するという方向性です。

これであれば、一つの仕事が終わってもさほど大きなインパクトはありませんし、その穴も埋めやすいです。

また、継続的なお話が積み重なってくれば先々まで予定が組めるので、収益も必要なリソースも今後が予測しやすいというメリットがあります。

Webサイトに掲載するプランも変更して提案もなるべくその方向にもっていくようにしています。

今もあまり変わっていませんが、プランはこちらです。

それが功を奏したのか、年末くらいから件数が増えていって、この4月くらいでようやく様になってきたかなと。

4月は具体的には9社のお客様のお仕事に関わらせて頂きました。

たいへんありがたいことです。

まとめ

以上、リアルに弊社のお仕事の獲得状況についてお伝えしてきました。

まず間違いなく言えることは

ブログによるコンテンツマーケティングは大いに成果を期待できる

ということです。

これから独立される方、既に起業されてまだWebを活用されていない方は、ぜひ検討をしてみてください。もし、お困りであればWebサイトの制作から運用までお手伝いができますので、ぜひご連絡下さい。

セミナーやイベントに積極的に参加・活用する

というのもオススメです。イベント参加自体はコストかかりますし、自主開催セミナーは赤字覚悟になる場合もありますが、先につながる可能性も十分にあります。

また業種にもよりますが

たくさんの小さな仕事を継続的に受ける

のは、特に起業仕立てのリソースが限られている時期では非常に効果的だと思います。

どうぞご参考頂ければ幸いです。

まだ、のんびりできる状況ではありませんし、状況に変化がくる可能性があるので、このまま順調に…とはいかないかも知れませんが、また折を見てご報告できればと思います。

連載目次:GASでGmailに届いた問い合わせメールを分析する

  1. 【GAS】Gmailに送られた過去のメールから特定条件のメールを検索して取得する
  2. 【GAS】Gmailからメールを検索してスプレッドシートに書き出す
  3. フリーランスの仕事はどこから来たか、独立して1年間の受注件数を全て晒す

エクセルVBAでセルが結合されているかどうか、またそのセルの数を判定する方法

$
0
0

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

エクセルの表をHTML形式のテーブルしてHTMLファイルに出力する方法というのを前回こちらの記事でお伝えしました。

エクセルの表をHTMLのtableタグに変換して出力するVBAマクロ
HTMLファイルを作るときにtrやtdタグでテーブルを構成するの…面倒ですよね?今回はエクセルVBAでエクセルシート上の表をHTML形式のテーブルに変換して出力する方法をお伝えしたいと思います。

エクセルの表が行と列で理路整然とおとなしく作られていればいいんですが…

セルの結合がされているときはどうすれば良いでしょうか??

今回はエクセルVBAでセルが結合されているかどうか、またその結合されているセルの数を判定する方法を使って、結合セルがある場合でもHTML形式に出力できるように修正していきたいと思います。

セルの結合を判定するプログラムの概要

エクセルで例えばこんな表を作ってみました。

セル結合を含むエクセル表

この表の各セルについて結合されているかどうか、またその結合されている数を判定するVBAプログラムを作ってみたいと思います。

どのように作れば良いですかね…?

流れとしては

  • 1行目から5行目まで繰り返し
    • A1セルから列方向にE1セルまで繰り返し
      • 今いるセルが結合されているセルであれば
        • その結合数を調べて出力
      • 結合セル分列移動(結合なしであれば1)

という流れでいければと思います。

MergeCellsでセルが結合されているか判定する

特定のセルが結合されているかを判定する場合はMergeCellsプロパティを使います。

Rangeオブジェクト.MergeCells

とします。

Rangeオブジェクトが結合セルに含まれている場合にTrue、そうでない場合はFalseが返ります。

使うときの対象は範囲ではなくて単一セルの場合が多いと思いますけどね。

ワークシートwsの行数i、列数jのセルが結合セルに含まれるかどうかを判定するのであれば

If ws.Cells(i, j).mergeCells Then

    (処理)

End If

とすればセルが結合されているかどうかで処理を分けることができますね。

MergeAreaプロパティで結合セルの範囲を取得

いくつのセルが結合をされているかを調べたいと思います。

その場合は、結合セルの範囲を取得するMergeAreaプロパティを使います。

Rangeオブジェクト.MergeArea

とすれば、Rangeオブジェクトが含まれているセル結合の範囲を取得することができます。

Rangeオブジェクトが単体セルで、かつセル結合もされていない場合は、そのセル自体が返ります。

取得した範囲について、Rows.Countプロパティで列数を取得すれば、いくつのセルが結合されているかを知ることができますね。

例えばワークシートwsの行数i、列数jが含まれる結合セルの列数を取得するのであれば

colSpan = ws.Cells(i, j).MergeArea.Columns.Count

とすればOKです。

この場合、Cells(i,j)が結合されていない単体セルであれば、colSpanには1が返ります。

MergeAreaプロパティを使うと列数以外にも

  • Countプロパティ:セル数
  • Rows.Countプロパティ:行数
  • Addressプロパティ:範囲のアドレス

などが取得できます。

セルの結合を判定するVBAプログラム

以上を使って、与えられたシートの表について結合セルの判定をするプログラムを作ってみました。

'結合セルの調査
Sub mergeCells()

Dim ws As Worksheet
Set ws = ThisWorkbook.Worksheets(1)
Dim colSpan As Long

Dim i, j As Long
i = 1
Do While ws.Cells(i, 1).Value <> ""

    j = 1
    Do While ws.Cells(i, j).Value <> ""

        Debug.Print "行:" & i, "列:" & j
        colSpan = 1

        If ws.Cells(i, j).mergeCells Then

            colSpan = ws.Cells(i, j).MergeArea.Columns.Count
            Debug.Print "結合セル数:" & colSpan & vbLf

        End If

        j = j + colSpan

    Loop

    i = i + 1

Loop
End Sub

表のサイズが可変でも動作するように行方向、列方向の繰り返しにはDo While文を使っています。

実行結果

このプログラムの実行結果は

エクセル表のセル結合状態について出力

となります。

セル結合があるセルの位置とその結合数をイミディエイトウィンドウの出力によって知ることができますね。

結合セルを含むエクセル表をHTMLで出力するVBAプログラム

さらにこのプログラムを活用して、結合セルを含むエクセル表をHTMLに変換するVBAプログラムを作ります。

列数が複数の場合のHTML文はtdタグを

<td colspan=列数>~</td>

とすれば良いですね。

作ったプログラムはこちらです。

Sub convertHTML()

Dim ws As Worksheet
Set ws = ThisWorkbook.Worksheets(1)

Dim htmlFile As String
htmlFile = ActiveWorkbook.Path & "\table.html"

Open htmlFile For Output As #1

Dim colSpan As Long
Dim i, j As Long
i = 1

Print #1, "<table border=""1"">"

Do While ws.Cells(i, 1).Value <> ""

    Print #1, vbTab & "<tr>";

    j = 1
    Do While ws.Cells(i, j).Value <> ""

        colSpan = 1

        If ws.Cells(i, j).mergeCells Then

            colSpan = ws.Cells(i, j).MergeArea.Columns.Count
            Print #1, "<td colspan=""" & colSpan & """>" & ws.Cells(i, j).Value & "</td>";

        Else

            Print #1, "<td>" & ws.Cells(i, j).Value & "</td>";

        End If

        j = j + colSpan

    Loop

    Print #1, "</tr>" & vbCr;
    i = i + 1

Loop

Print #1, "</table>"

Close #1

MsgBox htmlFile & "に書き出しました"

End Sub

先のセルの結合を判定するVBAプログラムmergeCellsとほとんど流れとしては変わりませんね。

ちなみに、本プログラムは行方向のセル結合には対応をしていません。

行方向も対応をしようと思うと、プログラムとしてはなかなかに複雑になりそうですよね…機会をみてチャレンジしてみてください。

実行結果

このプログラムを先ほどのエクセル表について実行します。

出力されたHTMLファイルはこちら。

セル結合があるエクセル表を変換したHTML文

このファイルをブラウザーにドラッグすると

セル結合があるエクセル表をHTMLで出力したものをブラウザで表示

このように表示されます。

問題なさそうですね!

まとめ

以上、エクセルVBAでセルが結合されているかどうか、またその数について知る方法について、MergeCellsプロパティとMergeAreaプロパティを使って実現しました。

また、セル結合がエクセル表に含まれている場合にHTMLに変換してファイルに吐き出すプログラムも紹介をしました。

次回ですが、テキストファイル出力の場合に文字コードをUTF-8で出力する方法についてお伝えしたいと思います。

どうぞお楽しみに。

連載目次:エクセルVBAでCSVや様々なテキストファイルを出力する

  1. エクセルVBAでテキストファイルに書き出す最も簡単なプログラム
  2. エクセルVBAでエクセルシート上のデータをCSVファイルに書き出す
  3. エクセルの表をHTMLのtableタグに変換して出力するVBAマクロ
  4. エクセルVBAでセルが結合されているかどうか、またそのセルの数を判定する方法

Google Apps Scriptでエラーが発生したときに処理を分ける方法

$
0
0
error

photo credit: Error via photopin (license)

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

Google Apps Scriptはイベントトリガーを設定してタイマーやフォーム送信などをトリガーに自動でスクリプトを動作させることができます。

しかしそのようにイベントトリガーを設定しているスクリプトでエラーが起きたらどうなりますか?

その場合は、スクリプトは中断してしまいますよね。

今回は、以前作成したチャットワークの翻訳チャットを例にエラーが発生したかどうかを判定して、エラーによって処理を分ける方法についてお伝えします。

ちなみに、前回は記事はこちら。

Google Apps Scriptでチャットワーク上に翻訳チャットを作る
Google Apps ScriptとチャットワークAPIを使って翻訳チャットを作る方法です。Google翻訳の機能をGASで扱うtranslateメソッドを使って、まずは最低限のシステムを目指します。

翻訳したい言語のコードと文章をセミコロンでつないだメッセージを「翻訳さん」というグループチャットで送信すると、翻訳語の文章で返信が来るというシステムです。

基本的な機能はもう出来上がっているのですが、セミコロンを忘れたり、言語コードを間違えたりなど、うっかりルール外のメッセージを送ってしまうと翻訳の処理でエラーが発生して止まってしまいます。

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

翻訳の結果が一生待っても返って来ない問題

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

function translateChat() {

  var token = 'APIトークン'; //チャットワークAPIトークン
  var room_id = XXXXXX; //翻訳さんのルームID

  var json = fetchMessage(token,room_id); //翻訳さんグループチャットのメッセージを取得

  /* 各メッセージについて 繰り返す */
  for each(var obj in json){

      var arr = obj.body.split(';'); //セミコロンでsplitして配列に格納
      var result = LanguageApp.translate(arr[1], "", arr[0]); //翻訳

      var body = "[rp aid=" + obj.account.account_id
        + " to=" + room_id
        + "-" + obj.message_id
        + "] " + obj.account.name
        + "さん[info]翻訳結果:" + result + "[/info]"; //チャットワークに送るテキスト

      sendMessage(token,room_id,body); //チャットワークにメッセージを送る
    }
}

「翻訳さん」のルールではISO639-1で登録されている言語コード(アルファベット2文字)を指定して

言語コード;本文

という形でチャットワークでメッセージを送るというのがルールです。

11行目でその本文をセミコロンで分割して

  • arr[0]:言語コード
  • arr[1]:本文

と格納します。

12行目でそれをもとに翻訳をするのですが、この時点でエラーが発生するとスクリプトはそこでストップをして処理が先に進まないまま終了してしまいます。

チャットワークの向こうでワクワクして待っていても、一生返事は返ってこない…ということになります。

今回はその問題を解消すべく、色々と模索をしていきたいと思います。

翻訳テスト用スクリプト

検証のために、以下のようなテスト用のスクリプトを作成してみました。

function translateTest(){

  var strTest = "ja;翻訳してください"; //テスト用文字列
  var arr = strTest.split(';'); //セミコロンでsplitして配列に格納   
  var result = LanguageApp.translate(arr[1], "", arr[0]); //翻訳
  Logger.log(result);
}

3行目の文字列を色々なパターンに書き換えて実行をすることで、5行目のLanguageApp.translateメソッドの挙動を確認していくためのスクリプトです。

strTestで正しい入力が与えられれば、ログ出力に翻訳結果が返ります。

例えば上記プログラムの通りstrTestが「ja;翻訳してください」であれば

Google Apps Scriptの翻訳テスト正しい場合

このようにログ出力されます。

これを使って色々な文字列を入力してみましょう。

セミコロンがない場合

strTestにただ「翻訳してください」と入力してみます。

Google Apps Scriptの翻訳テストセミコロンがない場合

この場合は、「無効な引数」でエラーとなりそこで中断します。

セミコロンがないので

  • arr[0]:”翻訳してください”
  • arr[1]:null

となり、言語コードが不明でエラーとなります。

無効な言語コードを使った場合

strTestに存在しない言語コードzzを使って「zz:翻訳してください」としてみます。

Google Apps Scriptの翻訳テスト言語コードが正しくない場合

こちらも同様に「無効な引数」エラーです。

  • arr[0]:”zz”
  • arr[1]:”翻訳してください”

となっていると思われますが、LanguageApp.translateメソッドではちゃんと言語コードが判定されているわけですね。

セミコロンが二つ以上ある場合

「en;翻訳してください;翻訳してください」とセミコロンを複数使った場合はどうなるでしょうか。

Google Apps Scriptの翻訳テストセミコロンが二つ以上の場合

splitメソッドで

  • arr[0]:”en”
  • arr[1]:”翻訳してください”
  • arr[2]:”翻訳してください”

と分割されます。arr[2]は使われることがなく、普通にLanguageApp.translateメソッドは成功するわけですね。

このパターンは特に問題ないとして良いと思います。

本文が空の場合

「en;」と本文を何も入力しない場合は

Google Apps Scriptの翻訳テスト本文が空の場合

とこのように空の文字が返ってきます。

  • arr[0]:”en”
  • arr[1]:null

は、エラーとならないようですね。

エラーを判定して処理を分ける

LanguageApp.translateメソッドでエラーが発生するかどうかの判定はどのようにすれば良いでしょうか?

言語コードのリストをスプレッドシートに置いておいて、arr[0]の値がそこに含まれているかどうかを判定するという方法もあります。

ただし言語コードは184ありますし、他の翻訳を使うスクリプトを使う場合に毎回スプレッドシートを用意するのも…ちょっとだるいですね。

今回はLanguageApp.translateメソッドでエラーが発生するかどうかを直接キャッチしてしまう、という方法を使いたいと思います。

try~catch文を使ってエラーの発生を検知する

JavaScriptではエラーの発生をキャッチするtry~catch文というものが用意されています。

書き方はこちら。

try{
// 処理1
}catch(e){
// 処理2
}

処理の流れを説明しますね。

まず、エラーをキャッチしたい処理をtry{ ~ }内に記載します。上記でいうと処理1の部分ですね。

処理1でエラーが起きなければ、catch(e){ ~ }内の処理2は実行されずにスルーされます。

処理1でエラーが発生した場合は、その時点で処理1を中断してcatch(e){ ~ }内の処理2が実行をされます。

ちなみに、引数eですがErrorオブジェクトつまりエラーの内容が渡されます。エラーの内容から処理を分けていきたい場合などに使えばOKです。

try~catch文を使った翻訳テスト用スクリプト

ではこのtry~catch文を使って翻訳テスト用のスクリプトを組んでみましょう。

こちらです。

function translateTest(){

  var strTest = "翻訳をして下さい"; //テスト用文字列
  var arr = strTest.split(';'); //セミコロンでsplitして配列に格納

  try{
    var result = LanguageApp.translate(arr[1], "", arr[0]); //翻訳
  }catch(e){
    result = "エラーの内容:" + e;
  }
    Logger.log(result);
}

LanguageApp.translateメソッドが検証の対象になっていて、エラーが発生すればログにエラーの内容が出力されます。

Google Apps Scriptの翻訳テストtry~catch文でエラー処理を分ける

エラーがなければ、catchの中は実行されませんので翻訳結果が出力されます。

まとめ

今回はGoogle Apps Scriptでエラーが発生したときに、try~catch文で処理を分ける方法についてお伝えしました。

次回はこの方法を用いて、チャットワークの翻訳チャットにルール外のメッセージが来たときの処理を作成していきたいと思います。

どうぞお楽しみに!

連載目次:GASとチャットワークAPIで翻訳チャットを作る

  1. Google Apps Scriptでチャットワーク上に翻訳チャットを作る
  2. Google Apps Scriptでエラーが発生したときに処理を分ける方法

エクセルVBAで全てのシートを一つのPDFにまとめて出力する方法

$
0
0


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

エクセルVBAでPDF出力や印刷をする際のテクニックについて引き続きお伝えしていきます。

前回はこちらの記事。

エクセルVBAで印刷時のヘッダー・フッターの設定をする方法と書式コード・VBAコード一覧
エクセルVBAでPDF出力や印刷をする際のテクニックについてお伝えしています。 今回はエクセルVBAで印刷時のヘッダー、フッターの設定の方法と設定できる書式コード・VBAコードの一覧についてです。

エクセルVBAで印刷時のヘッダー・フッターの設定をする方法についてお伝えしてきました。

さて、今回は少し視点を変えまして、エクセルVBAで全てのシートをまとめてプレビューまたはPDF出力をする方法についてお伝えします。

今までは一つのシートしか対象にしていませんでしたからね…全部まとめてやっちゃいますよ。

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

アクティブシートを印刷プレビューするVBAプログラム

アクティブシートのみを対象に印刷プレビューをするVBAプログラムはこちらです。

Sub outputPDF()

Dim fileName As String '保存先フォルダパス&ファイル名
fileName = ThisWorkbook.Path & "\201604請求書_株式会社ホゲホゲ御中.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

アクティブシートについて、PageSetupオブジェクトを使って出力設定を行いプレビューをするというプログラムですね(PDF出力はコメントアウトになっています)。

詳細についてはこちらの記事をご覧ください。

エクセルVBAで印刷時のページ中央配置と余白を設定する
エクセルVBAでPageSetupオブジェクトを使って印刷設定をページ中央配置にする方法、また上下左右のマージンを設定する方法についてお伝えします。また印刷プレビューの表示方法も紹介します。

当然ながら、例えばこちらのようにシートが複数ある場合でも

エクセルに複数のシートがある

実行すると当然ながらアクティブシートしかプレビューされません。

プレビューでアクティブシートしか表示されない

全てのシートを全部まとめてPDFにしたいのです。以降でその方法について解説をしていきます。

全てのシートをまとめてプレビューまたはPDF出力

皆さんが普通にエクセルで作業をされていて、全てのシートをまとめて印刷またはPDF出力するときはどうしていますか?

まずシート全てを選択してアクティブにしますよね?

VBAで動作させるときも同様で、印刷またはPDF出力をしたいシートを全て選択すればOKなのです。

では、それも踏まえてVBAプログラムを組んでみましょう。こちらです。

Sub outputPDF()

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

Dim ws As Worksheet
For Each ws In Worksheets

    With ws.PageSetup

        .Zoom = False
        .FitToPagesWide = 1
        .FitToPagesTall = 1
        .CenterHorizontally = True
        .TopMargin = Application.CentimetersToPoints(1)
        .BottomMargin = Application.CentimetersToPoints(1)

    End With

Next ws

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

End Sub

以下ポイントを解説していきますね。

全てのワークシートについて繰り返す

7行目~20行目のFor Each~Next文ですが

For Each 変数 In Worksheets
‘処理
Next 変数

とすることで、ブックに存在するすべてのワークシートについて繰り返し処理ができます。

WorksheetsはWorksheetsコレクションといいまして、作業中のワークブックにあるすべてのWorksheetオブジェクトの集まりを表しています。

ですから、その中の全てのワークシートについて処理をすることができるというわけですね。

これで同一の出力設定を施すということを実現しています。

全てのワークシートを選択してアクティブにする

同様にWorksheetsコレクションを使うことで、全てのシートをアクティブにすることができます。

22行目の

Worksheets.Select

の部分です。

選択したシートをプレビューまたはPDF出力する

複数のシートをプレビューまたはPDF出力する場合は、対象となるシートを全て選択した上でワークブックに対してPrintPreviewまたはExportAsFixedFormatメソッドを実行します。

Workbookに対して、というのがポイントです。

つまり対象のシートが選択されている状態であれば、PDF出力する場合は

Workbookオブジェクト.PrintPreview

PDF出力する場合は

Workbookオブジェクト.ExportAsFixedFormat Type:=xlTypePDF, fileName:=ファイル名

とします。

上記プログラムでいうと23,24行目ですね。

実行結果

このプログラムを実行すると

全てのシートをプレビュー

とプレビュー表示されます。画像だとわかりづらいですが、「請求書②」のシートも2ページ目としてきっちりプレビューされています。

また、このプログラムが実行された後のワークブックの状態として

全てのシートが選択された

このように全てのシートが選択されている状態になっていますね。

まとめ

以上、エクセルVBAで全てのシートをまとめてプレビューまたはPDF出力をする方法についてお伝えしました。

まず、作業中のワークブックの全てのシートを表すWorksheetsコレクションですね。

これに対してFor~Each文による繰り返しをすることや、Selectメソッドを実行することをお伝えしました。

また最終的にプレビューをするまたはPDF出力する際には、全てのシートを選択した状態でワークブックに対してメソッドを実行することがポイントでした。

次回は、全てのワークシートではなくて、一部のワークシートを対象にした場合はどうするか、についてお伝えできればと思います。

どうぞお楽しみに!

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

  1. 初心者でも簡単!エクセルVBAでPDFを出力する最もシンプルなプログラム
  2. エクセルVBAで印刷時のページ中央配置と余白を設定する
  3. エクセルVBAで印刷範囲の設定をする方法とクリアをする方法
  4. エクセルVBAで印刷時のヘッダー・フッターの設定をする方法と書式コード・VBAコード一覧
  5. エクセルVBAで全てのシートを一つのPDFにまとめて出力する方法

【GAS】新たな問い合わせメールをGmailで取得しスプレッドシートに随時追加する

$
0
0
contact

photo credit: Pen Friends via photopin (license)

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

こちらの記事でGmailから特定条件で検索したメールをスプレッドシートに書き出す方法についてお伝えしました。

【GAS】Gmailからメールを検索してスプレッドシートに書き出す
Gmailに届いたWordPressサイトからの問い合わせメールの分析を進めています。 今回はGoogle Apps ScriptでGmailから検索して取り出したメールたちをスプレッドシートに出力します。

具体的にはWordPressサイトの問い合わせフォームからのメールを検索してスプレッドシートに取り出しました。

過去の問い合わせメールを集計分析してみたりして、なかなか便利です。

フリーランスの仕事はどこから来たか、独立して1年間の受注件数を全て晒す
独立してからもうすぐ1年となります。その間、いかにして仕事を獲得したのか、毎日書いているブログによるコンテンツマーケティングの効果はあったのか、実際の件数を全て晒してフリーランスのリアルをお伝えします。

ただ、過去のメールは良いのですが、これから来る問い合わせメールについてはどうしましょう?

来たメールを順次このスプレッドシートに追加してくれると便利なんですけどね…

ということで、今回はGoogle Apps Scriptで問い合わせメールを都度スプレッドシートに追加していく方法についてお伝えします。

新たな問い合わせメールをスプレッドシートに追加するシステム

追加先のスプレッドシート

問い合わせを追加するのは、こちらのスプレッドシートです。

問い合わせメールをスプレッドシートに出力

過去の問い合わせメールについて

  1. 日付
  2. 送信元(返信先)
  3. 件名
  4. メッセージ(冒頭200文字)
  5. パーマリンク
  6. カテゴリ(手動入力)
  7. 結果(手動入力)

が記録されています。

6,7は後ほど手動で入力するものですので、1~5についてGoogle Apps Scriptで自動入力をしていきたいと思います。

システム動作の流れ

システムの動作としては

  • イベントトリガーで15分ごとなど動作
  • Contact Form 7から送られたメールで未読のものがあれば
    • スプレッドシートの最終行に追加をする
    • そのメールを既読にする

という流れで考えます。

メールを既読にする理由は同じメールを何度もシートに取得しないようにするためですね。

既読にしてしまうと、うっかり見逃す可能性もありますが、これについては追々チャットワークにメッセージ送信&タスク追加などで対応をしたいと思います。

前回のスクリプトを確認

さて、スクリプトですが前回紹介したこちらのスクリプトを大活用したいと思います。

function searchContactMail() {

  /* Gmailから特定条件のスレッドを検索しメールを取り出す */
  var strTerms = '("このメールは 株式会社プランノーツ http://plannauts.co.jp のお問い合わせフォームから送信されました" OR '
                  + '"このメールは いつも隣にITのお仕事 http://tonari-it.com のお問い合わせフォームから送信されました")';
  var myThreads = GmailApp.search(strTerms, 0, 500); //条件にマッチしたスレッドを取得、最大500通と決まっている
  var myMsgs = GmailApp.getMessagesForThreads(myThreads); //スレッドからメールを取得する →二次元配列で格納

  var valMsgs = [];

  /* 各メールから日時、送信元、件名、内容を取り出す*/
  for(var i = 0;i < myMsgs.length;i++){

    valMsgs[i] = [];
    valMsgs[i][0] = myMsgs[i][0].getDate();
    valMsgs[i][1] = myMsgs[i][0].getReplyTo();
    valMsgs[i][2] = myMsgs[i][0].getSubject();
    valMsgs[i][3] = myMsgs[i][0].getPlainBody().slice(0,200);
    valMsgs[i][4] = myThreads[i].getPermalink();

  }

  /* スプレッドシートに出力 */
  SpreadsheetApp.getActiveSheet().getRange(2, 1, i, 5).setValues(valMsgs); //シートを取得

}

このスクリプトからの変更点としては

  • 検索条件として「未読」であることを追加
  • スプレッドシートへの出力先を最終行の次の行に
  • スプレッドシートに追加したメッセージを既読にする

といった点になります。

では、具体的にスクリプトを作成していきましょう。

新たな問い合わせメールをスプレッドシートに追加するスクリプト

新たな問い合わせメールを都度スプレッドシートに追加するスクリプトを作りました。

せっかくなので名前もfetchContactMailと変更してみました。

function fetchContactMail() {

  /* Gmailから特定条件のスレッドを検索しメールを取り出す */
  var strTerms = '(is:unread "このメールは いつも隣にITのお仕事 http://tonari-it.com のお問い合わせフォームから送信されました")';
  var myThreads = GmailApp.search(strTerms, 0, 500); //条件にマッチしたスレッドを取得、最大500通と決まっている
  var myMsgs = GmailApp.getMessagesForThreads(myThreads); //スレッドからメールを取得する →二次元配列で格納

  var valMsgs = [];

  /* 各メールから日時、送信元、件名、内容を取り出す*/
  for(var i = 0;i < myMsgs.length;i++){

    valMsgs[i] = [];
    valMsgs[i][0] = myMsgs[i][0].getDate();
    valMsgs[i][1] = myMsgs[i][0].getReplyTo();
    valMsgs[i][2] = myMsgs[i][0].getSubject();
    valMsgs[i][3] = myMsgs[i][0].getPlainBody().slice(0,200);
    valMsgs[i][4] = myThreads[i].getPermalink();

    myMsgs[i][0].markRead(); //メッセージを既読にする

  }

  /* スプレッドシートに出力 */
  var mySheet=SpreadsheetApp.getActiveSheet(); //シートを取得
  var maxRow=mySheet.getDataRange().getLastRow(); //シートの使用範囲のうち最終行を取得
  mySheet.getRange(maxRow+1, 1, i, 5).setValues(valMsgs); //シートに取得したメッセージのデータを追加
}

冒頭で紹介したsearchContactMailをほんの少~し変更しただけですのでポイントを解説していきますね。

Gmailで未読のメールのみ検索する

4行目の検索条件ですが

(is:unread “このメールは いつも隣にITのお仕事 http://tonari-it.com のお問い合わせフォームから送信されました”)

と変更をしました。

Gmailの検索条件として「is:unread」未読のメールという条件になります。逆に「is:read」は既読ですね。

半角スペースはAND条件になりますので、未読のメールで「このメールは いつも隣にITのお仕事 http://tonari-it.com のお問い合わせフォームから送信されました」という文字列を含むスレッドを検索するということになります。

試しにGmailで検索してみますと

Gmailで未読のメールを検索

と未読のメールでかつ指定した文字列のもののみ抽出できました。

メールを既読にする

メールを既読にする場合はmarkReadメソッドを使って

メール.markRead()

と書きます。

スクリプトでいうと20行目の部分ですね。

スプレッドシートの最終行の下に追加する

25行目~27行目ですが、スプレッドシートの最終行の行数を取得して、その次の行にsetValuesをすることで、スプレッドシートに”追加”となります。

よく使うテクニックですのでぜひマスターしてくださいね。

実行結果

では、まず指定の文字列を含むメールのうち2つのメールを未読にしました。

Gmailで条件に合う未読のメールは2つ

この状態で上記スクリプトを実行してみますと

スプレッドシートに新たな問い合わせを追加した

このようにシートの76,77行目に対象の2つのメールが追加されました。

Gmailを更新してみますと

Gmailでメールが既読になった

先ほどの2つのメールが既読になっていますね。

これで、同じメールを何度も取得することを防ぐことができるというわけです。

まとめ

Google Apps Scriptで問い合わせメールを都度スプレッドシートに追加していく方法についてお伝えしました。

未読のメールだけを取得してきて既読にしちゃうというのがポイントですね。

少し変えるだけで良いというのが気持ちいですね。

次回は、問い合わせメールが来たらチャットワークに通知する方法についてお伝えしたいと思います。

どうぞお楽しみに!

連載目次:GASでGmailに届いた問い合わせメールを分析する

  1. 【GAS】Gmailに送られた過去のメールから特定条件のメールを検索して取得する
  2. 【GAS】Gmailからメールを検索してスプレッドシートに書き出す
  3. フリーランスの仕事はどこから来たか、独立して1年間の受注件数を全て晒す
  4. 【GAS】新たな問い合わせメールをGmailで取得しスプレッドシートに随時追加する

さらば紙の契約書!クラウドサインによるペーパーレス契約による3つのメリット

$
0
0

cloudsign

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

皆さん、契約書で消耗していませんか?

先日「クラウドサインとチャットワークでペーパーレス」セミナーに参加してきました。

私はチャットワークの大ファンなのですが、今回はまずはクラウドサインについて書きたいと思います。

クラウドサインは契約をクラウド上で行えるサービスです。

えー、それって法的に大丈夫なの?と思われるかも知れませんが、運営は「弁護士ドットコム」ですから。

では、セミナー当日に学んだクラウドサインのメリットと使い方、そしてその信頼性についてレポートをしたいと思います。

クラウドサインとは?

契約業務は一般的に

  1. 契約内容の作成
  2. 交渉・すり合わせ
  3. 締結
  4. 管理

といった四段階に分けることができますが、クラウドサインはその3,4、つまりその契約締結から契約書管理を担うクラウドサービスです。

例えば締結業務と言っても、実際に紙で行おうとすると

  • 自社の作業
    1. 契約書を二部印刷する
    2. 製本する
    3. 自社の分を捺印する
    4. 送付状を準備する
    5. 場合によっては返信用封筒を準備する
    6. 封筒に一式を入れる
    7. 宛先を書く
    8. 切手を貼る
    9. ポストに投函する
  • 先方の作業
    1. 受領して中身を確認する
    2. 先方が捺印する
    3. 送付状を準備する
    4. 封筒に一式入れる
    5. 宛先を書く
    6. 切手を貼る
    7. ポストに投函する
    8. 先方の分を保管する
  • 自社の作業
    1. 受領して中身を確認する
    2. 自社の分を保管する

などという作業が発生してしまいます。

まー…うざいですね。

さらに先方に送った時点で、うっかり修正が入った場合は…もううんざりです。

これをクラウドサインで行う場合を簡単に説明をしていきますね。

書類をアップロードする

クラウドサインでは契約書、申込書、発注書などの契約書類をPDFで取り扱います。

ドラッグアンドドロップでアップロードをします。

クラウドサインに契約書類をPDFでアップロード

複数書類があってもOKです。

送り先メールアドレスを追加

続いて、契約書を送る先方のメールアドレスを追加します。

クラウドサインで宛先を追加する

一旦、クラウドサインに登録したことのある宛先であれば、「連絡先から追加」から選択することができます。複数名を選択することもできます。

押印、フリーテキストの割り当てと自社の押印

次に「押印」欄をドラッグして自分もしくは先方に割り当て、自社の分を押印します。

クラウドサインで押印を割り当てる

この「押印」は実は法的には不要のようですが、押した感を出すために…というお話でした。あとは先方に入力頂く必要がある箇所があれば「フリーテキスト」欄も追加できます。

契約書の送信

これで送信。

クラウドサインで契約書を送信する

先方にメールが届く

先方にはこのようなメールが届きますので、URLをクリックしてもらいます。

クラウドサインから送られたメール

先方の押印と同意

開いて押印をしてもらい、「書類の内容に同意」をしてもらいます。これで締結が完了です。

クラウドサインで契約締結が完了

いかがでしょうか?簡単でしょ?

実は先方は”クラウドサインへの登録が不要”なことに注目してください。URLでクリックするだけです。

クラウドサインを使う3つのメリット

クラウドサインを使うメリットはとても明確で3つあります。

契約締結のスピードアップ

紙の契約書で締結する場合は、自社から先方、また先方から自社という郵送が必要なので、どうしてもそれだけで1週間くらいの時間がかかってしまいます。

その他に製本や捺印や郵送…複数人で役割分担をしている会社であれば、待ち行列で少しずつ時間がとられていきます。

一方で、クラウドサインの場合はどうでしょうか?

先ほどの説明では、自社側の作業が終わったら、先方の作業は

  1. 受け取ったメールでURLをたたく
  2. 押印して同意

これだけです。

先方がメールを開くタイミングが良ければ数分で完了します。

コスト削減

一般的に発注書1件を送付するのに

  • 人件費:200円(印刷、郵送、回収、保管を6分で行った場合)
  • 郵送費:82円(定形郵便かつ25g以内、製本されている契約書であれば140円)
  • その他:20円(封筒、用紙、印刷等にかかるコスト)

ということで、300円程度かかるとされています。

また、それよりもインパクトがあるものですと、印紙税があります。

業務委託契約書は一般的に一通あたり4,000円です。

しかもそれが両社でかかるということを注目してください。クラウドサインにすれば両社合わせて9,000円くらいコストダウンとなります。

コンプライアンス強化

え?紙のほうがコンプライアンスでいうと強力なのでは?

…と思いますか?

実はそんなことはありません。

まず、前提として一部の業法で指定されている契約(労働条件通知書など)は紙での締結が定められているようですが、その他のいわゆる一般的な契約については契約方式は自由です。口頭でもFaxでももちろんクラウドでもOKです。

その上で、クラウドのほうが利点といえるポイントがいくつかあります。

受信者が特定される

紙の契約書の場合は、誰がその封書を開封したのか、契約書を受け取ったのか、捺印をしたのかが実は明確ではありません。

クラウドサインの場合は、送る先はメールアドレスで特定され、一意に決められたURLでのみアクセス可能なので、そのアドレスの持ち主がURLを配布しない限りはアクセスすることができません。

改竄防止

クラウドサインで締結されたPDF書類は誰も改竄することはできません。

セミナーの配布資料から言葉を借りますと

クラウドサインで合意締結されたすべての書類には、クラウドサインのみが発行可能な電子署名が付与されますので、それにより真正あ素類を判別することができます。電子署名の仕組みには、強固な暗号化方式によって守られている公開鍵暗号方式に基づくデジタル署名を採用しています。

とのことです。

紙の書類であれば、書き足しや、印字ができてしまいますからね。

一元管理による漏れ防止

大きな契約書に関してはそんなことはないかもしれませんが、小さな案件の申込書…うっかり回収忘れをしている場合ありませんか?

クラウドサインでは、送った契約書はその大小に限らずステータスが一目瞭然です。

クラウドサインの契約ステータス管理

ここから「リマインド」メールも送ることができます。

また、締結業務が楽ですので、双方ともに「後回し」にするリスクも減りますよね。

メールよりも楽、お互いが楽

私もITオタク、クラウドオタクを自負していたのですが、今までは

  • 基本契約書はクラウドサイン、または印刷(先方が望んだ場合)
  • 個別契約はメールで。保管はEvernote

というやり方をしていました。

なんとなく「個別契約はメールでOK」→「メールが一番楽ちん」と思い込みをしていたんですね。

今回のセミナーを聞いて、個別契約もクラウドサインにすれば契約がいっさいがっさいクラウドサインで管理できると気付きました。

というのも、小さい契約ほどステータス管理が雑になりがちなのですが、そこまで含めて任せられるようになるのは大きなメリットですね。ひとり社長にはありがたいです。

一方で、先方の立場としても、メールだと受け取って文字を打って返信をしないといけないのですが、クラウドサインならばクリックだけで締結いただくことが可能です。

メールよりもお互いが圧倒的に楽になります。

まとめ

以上、クラウドサインとは何か、またそのメリットについてお伝えしました。

今後、弊社からは案件の大小に限らずクラウドサインでお願いしていきます。

ちなみに、ユーザー数一人で毎月30通までは無料で利用可能です(私も無料で利用させて頂いています…汗)。

それ以上であれば月額10,000円+1通50円のスタンダードプランになります。ここまで来ると、受注件数をたくさん増やしたい感じになりますね。頑張ります。

さて、本セミナーについては実はもう1ネタありますので、後日お伝えできればと思います。

どうぞお楽しみに!

【保存版】初心者向け実務で使えるGoogle Apps Script完全マニュアル

$
0
0
stairs

photo credit: via photopin (license)

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

Gmail、Googleカレンダー、スプレッドシート、ドキュメント、フォーム、翻訳、などなど…Googleは仕事に役立つ数多くのサービスを提供してくれています。

もちろんGoogle検索もありますね。

Google Apps ScriptはGoogleが提供しているJavaScriptベースの開発環境

冒頭に紹介したサービスをはじめ数多くのGoogleサービスをプログラミングにて操作をすることができる魔法のようなシロモノです。

当ブログではあれやこれやのGoogle Apps Scriptのテクニックについてお伝えしていますが、全くの初心者ではどこからどのように習得していいのか迷ってしまうかも知れません。

このページでは【初心者がGoogle Apps Scriptを使って何かしらかの便利ツールやシステムを作れるようになる】ための助けとなるまとめ記事です。

ぜひ当ページをブックマークしつつ、少しずつしかし確実にGoogle Apps Scriptを習得していくための道しるべとしてご活用頂ければと思います。

連載目次:初めてのGoogle Apps Scriptで自動でチャットワークに色々と送る

最初のお題にも限らずチャットワークを中心に操作していきます。スプレッドシートやカレンダーをはじめとするGoogleサービスはもちろん、Twitterなどの外部のサービスともAPIで連携させて色々なものをチャットワークに通知してみますよ。
  1. 超初心者へGoogleAppsScriptを始めるメリットをこれでもかと説明します
  2. Google Apps Scriptの第一歩、初心者でもチャットワークにメッセージを送れる
  3. Google Apps Scriptでチャットワークの名言botを作る方法
  4. Google Apps ScriptでTwitterの検索結果を自動でチャットワークに通知
  5. 【幹事必見!】スプレッドシートの入力が完了したらチャットワークに自動で通知する方法
  6. スプレッドシートのリストアップ件数をGASでチャットワークに通知する
  7. GASでチャットワークにGoogleアナリティクスの前日レポートを自動送信
  8. GASでGoogleアナリティクスの記事ランキングをチャットワークに送る
  9. Google Apps ScriptでWordPressの更新情報をチャットワークに送る
  10. 毎朝、当日の予定をGoogleカレンダーから取得してチャットワークに送る
  11. 【Google Apps Script】天気予報をWeb APIで取得する方法
  12. 【GAS】JSON形式のデータを取り出してチャットワークに天気予報を送る

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

Google Apps ScriptでGmail、スプレッドシート、ドキュメントを連携させて操作することでメルマガシステムが簡単に実現できます。思ったより2割くらい簡単にできますよ。ちなみに無料です…さすがGoogle。
  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のメルマガ配信リスト自動更新スクリプトを高速化する

連載目次:Googleカレンダーの記録を活用して過去の仕事を振り返る

企業ではスプレッドシートを勤怠管理やプロジェクト進捗管理などに使っている場合も多いと思います。このシリーズでは、カレンダーとスプレッドシートを連携をさせて仕事の生産性を簡単に測定する方法についてお伝えしています。
  1. 仕事の生産性を測定して振り返るためのGoogleカレンダーの使い方
  2. Google Apps Scriptで特定月のカレンダーのイベント情報を取得する
  3. Google Apps ScriptでGoogleカレンダーの記録をスプレッドシートに出力する
  4. Googleカレンダーの記録を活用してスプレッドシートに業務別のコスト計算

連載目次:GASでGmailに届いた問い合わせメールを分析する

お仕事の現場では日々様々なメールが届きます。その中で重要なのが「問い合わせメール」ですね。このシリーズでは、Webサイトからの問い合わせメールを自動でスプレッドシートに取り込んだり、チャットワークに送る方法についてお伝えしていきます。
  1. 【GAS】Gmailに送られた過去のメールから特定条件のメールを検索して取得する
  2. 【GAS】Gmailからメールを検索してスプレッドシートに書き出す
  3. フリーランスの仕事はどこから来たか、独立して1年間の受注件数を全て晒す
  4. 【GAS】新たな問い合わせメールをGmailで取得しスプレッドシートに随時追加する
⇒以下連載中!

連載目次:チャットワークAPI初級編:おみくじチャットを作る

本シリーズはGoogle Apps ScriptでチャットワークAPIの様々な機能を呼び出す練習となります。メッセージの取得をして、処理をして、メッセージを返すという一連の流れの基礎を学ぶことができますよ。
  1. Google Apps ScriptでチャットワークAPIを活用するための最初の一歩
  2. Google Apps Scriptでチャットワークからのメッセージを取得する方法
  3. Google Apps Scriptで乱数を使っておみくじプログラムを作る
  4. Google Apps Scriptでチャットワーク上におみくじチャットを作る
  5. Google Apps ScriptでチャットワークにToや返信でメッセージを送る
  6. 【GAS】チャットワークのメッセージを取り出す関数とメッセージを送る関数

連載目次:GASとチャットワークAPIで翻訳チャットを作る

おみくじチャットの仕組みを利用して翻訳チャットを作ります。Google Apps ScirptでGoogle翻訳を操作する方法、チャットからの入力がルール外だった場合のエラー処理など少し発展的な内容を学ぶことができますよ。
  1. Google Apps Scriptでチャットワーク上に翻訳チャットを作る
  2. Google Apps Scriptでエラーが発生したときに処理を分ける方法
⇒以下連載中!

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

タスク管理は重要なのですが、タスクを立てること自体を忘れてしまったりませんか?このシリーズではスプレッドシートとチャットワークを使って定期的なタスクを自動で追加する方法についてお伝えしています。
  1. Google Apps Scriptでチャットワークにタスクを追加する最も簡単なプログラム
  2. Google Apps Scriptでチャットワークに期限付きのタスクを追加する
  3. 【GAS】スプレッドシートに記載したタスクを毎日チャットワークに自動で追加する
  4. GoogleスプレッドシートとExcelで使える日付関連の関数まとめ
  5. 【GAS】定期的に発生するタスクをチャットワークに自動でタスク追加(完全版)

その他のGoogle Apps Scriptに関する様々なテクニック

  1. Google Apps Scriptのスプレッドシート読み書きを格段に高速化をする方法
  2. Google Apps Scriptで毎朝チャットワークに電車の遅延情報をプッシュ通知する
  3. チームのみんなが使っている電車の遅延情報を毎朝チャットワークに通知する
Viewing all 2093 articles
Browse latest View live


<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>