Hatena::ブログ(Diary)

名もないテクノ手 このページをアンテナに追加 RSSフィード Twitter

EPUB版『InDesign者のための正規表現入門』

InDesignのTips一覧

2009-12-21

[][]特定のカレンダーのイベントを月別集計してみる

(*
get_events_TSV.app
iCalで特定のカレンダーの月別のイベントの集計を出します。
集計フォーマットは
開始時間\t終了時間\t摘要(イベント名)\t処理時間
開始時間順にソートします。
集計結果はクリップボードにコピーされます。
Mac OS 10.6.2
iCal 4.0.1 (1374)

2009-12-18	ver.0.1	とりあえず。
2010-02-18	ver.0.2	時間の単位を分にした
2010-02-18	ver0.3	作業時間(分)を切り上げで整数とし、再終行に合計をつけた
*)


tell application "iCal"
	activate
	set calName to name of every calendar
	set calName to choose from list calName with prompt "集計したいカレンダー名を選択してください" default items {"仕事"}
	if calName is false then
		error number -128
	else
		set calName to calName as Unicode text
	end if
	
	set my_year to year of (current date)
	set my_month to (month of (current date)) as number
	set my_date to text returned of (display dialog "計算したい年/月を入力してください(YYYY/MM)" default answer ("" & my_year & "/" & my_month))
	set my_date to my as_split("/", my_date)
	set my_year to item 1 of my_date
	set my_month to item 2 of my_date
end tell


--該当月の初日と最終日。ここをiCal直下でやるとdateがおかしくなる
set dStart to date (my_year & "/" & my_month & "/1")
set dEnd to (date (my_year & "/" & my_month & "/" & my getMlen(my_year, my_month))) + 86399

set copyText to "000000000\t開始時間\t終了時間\t摘要\t処理時間(min)" & (ASCII character 10) -- 結果を格納する変数(最初はヘッダ)

tell application "iCal"
	--set epoc to (current date) - (date "1970年1月1日木曜日 0:00:00") - 32400
	with timeout of 3600 seconds
		set theList to every event of calendar calName whose (start date ≥ dStart) and (end date ≤ dEnd)
		
		set total_time to 0
		repeat with i in theList
			set start_date to (start date of i)
			set end_date to (end date of i)
			set epoc_sec to start_date - (date "2001年1月1日月曜日 0:00:00") --擬似的なエポック秒(指数になるのが避けた)
			--set work_min to "" & (end_date - start_date) / 3600 & "時間"
			set work_min to (end_date - start_date) div 60
			set total_time to total_time + work_min
			set copyText to copyText & "" & epoc_sec & tab & (start_date as text) & tab & (end_date as text) & tab & summary of i & tab & work_min & (ASCII character 10)
		end repeat
		--最終行に合計時間を付加する
		set copyText to copyText & "536870910\t\t\t" & "合計\t" & my min2hour(total_time) & "(" & total_time & "分)" & (ASCII character 10)
	end timeout
	
	-- 結果をクリップボードにコピー
	--set copyText2 to do shell script "echo " & quoted form of copyText & " | sort -nu | sed -E -e 's/^\\n//;s/^[0-9]{8,}.//;s/([0-9])\\.0時間/\\1時間/;'"
	set copyText2 to do shell script "echo " & quoted form of copyText & " | sort -nu | sed -E -e 's/^\\n//;s/^[0-9]{8,}.//;'"
	set the clipboard to copyText2
	activate
	display dialog my_year & "/" & my_month & "の集計をクリップボードにコピーしました。"
end tell




to as_split(thedelimit, theText)
	set oldDelim to AppleScript's text item delimiters
	set AppleScript's text item delimiters to thedelimit
	set tmpList to every text item of theText
	set AppleScript's text item delimiters to oldDelim
	return tmpList
end as_split

--指定月の日数を返す
to getMlen(aYear, aMonth)
	set aYear to aYear as number
	set aMonth to aMonth as number
	
	set aDat to (aYear as text) & "/" & (aMonth as text) & "/1"
	if aMonth is 12 then
		set eDat to ((aYear + 1) as text) & "/" & (1 as text) & "/1"
	else
		set eDat to ((aYear as text) & "/" & (aMonth + 1) as text) & "/1"
	end if
	
	set eDat to date eDat
	set eDat to eDat - 1
	
	set mLen to day of eDat
	return mLen
end getMlen

--分を時間に変換
to min2hour(min)
	set h to min div 60
	set m to min mod 60
	return "" & h & "時間" & m & "分"
end min2hour

(追記:2010-02-18T16:00:09+0900)ver.0.3に変更しました。


アプリケーション形式のものはこちらからダウンロード:

get_events_TSV.app.zip 直

udagawaudagawa 2010/09/08 10:58 こういったものを探していました!感激です。本当にありがとうございます!

seuzoseuzo 2010/09/08 11:57 ありがとうございます。
不具合などがありましたら、お知らせください。

Genie08Genie08 2011/03/01 15:48 毎月便利に使わせて頂いています。
本当に感謝です!

seuzoseuzo 2011/03/01 18:51 Genie08さん

ブログでご紹介いただき、ありがとうございました。感謝!

kanakokanako 2011/10/19 20:53 合計時間を出ししたいと思っていたので助かりました!!
ありがとうございます。
ちなみに月ではなく1日の集計というのも、上の記述の数値等を変えたら可能だったりしますか?
現在受験生で、icalを実績表として使っています。
科目ごとにそれぞれのカレンダーを作って、勉強した時間に色を付けていってます。
なので、1日分の科目ごとの集計ができたらいいなと思ったんですが…。
教えて頂けたら嬉しいです><

SSDDSSDD 2011/12/19 16:07 すみません、AppleScriptを全く触った事がないのでよく分かりません…
上記のどこからどこまでをコピーして使えばよいのですか?

seuzoseuzo 2011/12/19 16:54 一番最後にアプリケーションがダウンロードできるようにしてあります。

SSDDSSDD 2011/12/20 10:09 seuzoさん、お返事ありがとうございます
当方PowerPC環境なのでどうやら使えないようなのです…

seuzoseuzo 2011/12/20 10:20 このスクリプトはiCal 4.0.1を使って書いたので、バージョンが古いともしかしたらうまく動作しないかもしれません。

アプリケーションを再構成するには
グレーで囲まれたコード部分、すなわち最初の「(*」で始まる行から、最後の「end min2hour」で終わる行までをコピーし、スクリプトエディタにペーストします。
そしてアプリケーション形式で保存してください。

SSDDSSDD 2011/12/20 14:03 seuzoさん、ご丁寧にどうもありがとうございました

言われた通りにやってみたのですが
保存できませんでした や、
構文エラー expressionがあるべきところですが"#"が見つかりました。
と出てうまくいきませんでした

seuzoseuzo 2011/12/20 14:29 45行目の
set theList to every event of calendar calName whose (start date ≥ dStart) and (end date ≤ dEnd)
の部分がブログに貼付けた時に、文字参照形式に変わってしまったたようです。
「≥」を「>=」、
「≤」を「>=」
にしてコンパイルしてください。それぞれ1文字に自動変換されます。

SSDDSSDD 2011/12/21 10:17 seuzoさん、何度も説明ありがとうございました
おかげさまでアプリケーションとして動くようにはなりました!

ですがスケジュールが入っている月を指定しても0時間になったり
違う月を参照してりしてしまいます…

seuzoseuzo 2011/12/21 10:51 0時間になってしまうのは、iClud上のイベントではないでしょうか?
同期させたら正しく計算しませんか?
最初に書きましたように、このプログラムはiCal 4.0.1を対象にしています。
ですからiCludの対応はしていません。

現在、ぼくの方はこのスクリプトを修正している時間がないため
この点については、お約束できない状態とお考えください。

SSDDSSDD 2011/12/21 11:10 いえ、ちゃんとiCal上のイベントなのですが…
当方のiCalは3.0.8なのでやはり無理なのかもしれませんね、残念ですが諦める事にします
最後までどうもありがとうございました!