Tbpgr Blog

Employee Experience Engineer tbpgr(てぃーびー) のブログ

Ruby-秀丸マクロ連携 日付減算

  • 概要

以下URLの記事で、作成したRubyの日付減算処理を利用して秀丸で入力中の
日付文字列FROM-日付文字列TOから時間差を出力する処理を実装します。

※作成済み日付減算処理(Ruby
http://d.hatena.ne.jp/tbpg/20120120/1327082337

  • 前提

TODOを表す文字列の日次の差分を算出して、作業実績を出力する。
TODO文字列は「/」区切りの3件の列をもつレコードからなる。
3項目目には作業を開始時間と終了時間が
yyyy/mm/dd hh:mm:ss-yyyy/mm/dd hh:mm:ss
で出力される。

★TODOデータ例
列1/列2/yyyy/mm/dd hh:mm:ss-yyyy/mm/dd hh:mm:ss

  • 設計

秀丸からの呼び出しは以前以下の記事で作成したEncloseString.macを流用。
http://d.hatena.ne.jp/tbpg/20120115/1326633970

    • 行読込処理の実装

秀丸で選択中の文字列を受け取り、それぞれに対して1行ごと処理を呼び出す。

    • 1行ごと処理の実装

秀丸の1行データを受け取り、全角スラッシュで分割する。
分割したデータの3項目目(リストの最後の要素)が時間のFROM-TOを表す。
FROMは1文字目から半角ハイフンの直前まで。
TOは半角ハイフンの次の目前のハイフンから最後の文字まで。
抽出した日付を、日付減算処理に渡して結果を秀丸に表示します。

  • 実装
// Rubyのパスを通しておくこと
$RUBY_HOME = "ruby";
// 日本語Shift-JIS指定
$RUBY_SHIFTJIS = "-Ks";
// 実行するrubyのファイル名を指定
$RUBY_SCRIPT = "C:\\Program Files\\Hidemaru\\mac\\Ruby\\OutputDateDiff.rb";

runex $RUBY_HOME + " " + $RUBY_SHIFTJIS +" '" + $RUBY_SCRIPT + "'"
    , 1             //sync    0:async 1:sync
    , 5, ""         //stdin   0:none 1:auto 2:file 3:(reserve) 4:all 5:select
    , 6, ""         //stdout  0:none 1:auto 2:file 3:add file  4:new 5:insert 6:replace
    , 6, ""         //stderr  0:none 1:=out 2:file 3:add file  4:new 5:insert 6:replace
    , 0, ""         //folder  0:none 1:current 2:specify 3:(reserve) 4:exe's folder
    , 1             //show    0:auto 1:show 2:hide
    , 1             //nodraw  0:draw 1:no draw
    , 0             //unicode 0:ansi 2:unicode
    ;

endmacro;
    • Rubyの実装(OutputDateDiff.rb)
require_relative 'DateUtil'

=begin
日付減算処理

スラッシュ区切りの文字列の最後の要素に開始日時-終了日時
というフォーマットの文字列があった場合、
時差を計算してその差を以下のフォーマットで行末に追加する
/HH時間MM分SS秒

不正な行データが入力された場合は、入力データをそのまま返却する
=end
def getDateDiff(line)
	#文字列を全角スラッシュで分割
	todo = line.split('')
	#分割後の最終要素が日時要素
	fromTo = todo[todo.size - 1]
	times = fromTo.split('-')
	from = times[0]
	to = times[1]

	#開始時間
	timeFrom = Time.mktime(DateUtil.getYear(from),DateUtil.getMonth(from),DateUtil.getDay(from),DateUtil.getHour(from),DateUtil.getMinutes(from),DateUtil.getSeconds(from))
	#終了時間
	timeTo = Time.mktime(DateUtil.getYear(to),DateUtil.getMonth(to),DateUtil.getDay(to),DateUtil.getHour(to),DateUtil.getMinutes(to),DateUtil.getSeconds(to))

	#日付の減算
	DateUtil.calcDateDiff(timeFrom, timeTo)
	
	rescue
		"測定不能"
end

while line = STDIN.gets
    if (/exit/ =~ line)
        break;
    end
    
=begin
chompで改行文字を削除
行末に/+日時減算結果を挿入
=end
    puts(line.chomp + '' + getDateDiff(line))
end
    • 日付ユーティリティに年月日時分秒取得メソッドを追加
class DateUtil
	def self.calcDateDiff(timeFrom, timeTo)
  #:
  #説明済みのため省略
  #:
	end
	
	def self.getYear(yyyymmddhhssmm)
		yyyymmddhhssmm.slice(0,4)
	end
	
	def self.getMonth(yyyymmddhhssmm)
		yyyymmddhhssmm.slice(5,2)
	end
	
	def self.getDay(yyyymmddhhssmm)
		yyyymmddhhssmm.slice(8,2)
	end
	
	def self.getHour(yyyymmddhhssmm)
		yyyymmddhhssmm.slice(11,2)
	end
	
	def self.getMinutes(yyyymmddhhssmm)
		yyyymmddhhssmm.slice(14,2)
	end
	
	def self.getSeconds(yyyymmddhhssmm)
		yyyymmddhhssmm.slice(17,2)
	end

end
  • 実行結果
    • 入力
task/正常系1/2012/01/24 9:41:47-2012/01/24 11:41:49
task/正常系2/2012/01/24 11:41:47-2012/01/24 23:41:49
task/不正日付/2012/01/24 11:41:47-不正日付
task/ハイフンなし/2012/01/24 11:41:472012/01/24 11:41:49
taskスラッシュなし2012/01/24 9:41:47-2012/01/24 11:41:49
    • 出力
task/正常系1/2012/01/24 9:41:47-2012/01/24 11:41:49/2時間40分42秒
task/正常系2/2012/01/24 11:41:47-2012/01/24 23:41:49/12時間0分2秒
task/不正日付/2012/01/24 11:41:47-不正日付/時刻が不正です
task/ハイフンなし/2012/01/24 11:41:472012/01/24 11:41:49/測定不能
taskスラッシュなし2012/01/24 9:41:47-2012/01/24 11:41:49/測定不能



以下、等記事の補足

  • 例外
    • raise = 例外を発生させる(Javaのthrow)
    • rescue = 例外発生時の処理(Javaのcatch)
    • ensure = 例外発生時の処理(Javaのfinally)
  • 別ファイルの読込
    • require "ファイル名" #.rbは省略可能
  • String.split('区切り文字') = Javaのsplitと同様。区切り文字で配列に分割
  • String.slice(startIndex, 文字数) = Javaのsubstringと同様。ただし第二引

数がindexではなく文字数であることに注意