札幌Ruby会議01に行ったらLinuxからExcelが使えるようになった話

札幌Ruby会議01行ってきました。最初から最後まで面白い話ばかりでしたが、感想を書くのが苦手なのでプログラム書きます。

まず興味深かったのが、artonさんの話。ActiveScriptRubyWindows向けに便利な機能がいろいろあるらしい。HTAの中身をRubyで書いたり、Windows固有のOLE操作とかできるって、なんかすげー。

それから関さんのdRubyの話。dRubyって名前から機能が想像できなくて全然中身を知らなかったんだけど、リモートでメソッドを呼べるってことだそうな。面白い。

ん?てことは、これらを組み合わせるとLinuxマシンからリモートでWindowsのOLEを操作したりってのがRubyでできたりするのかな。
やってみよう。

できた。


リモートでExcelを操作して計算結果を得るクライアントの例
excelcl.rb

#!/usr/bin/ruby
require 'drb/drb'
excel = DRbObject.new_with_uri('druby://localhost:12345')	# 接続先のURIを指定
excel.put("A1", "100")			# セルに値をセット
excel.put("A2", "120")
excel.put("A3", "150")
excel.put("A4", "=AVERAGE(A1:A3)")	# セルに数式をセット
average = excel.get("A4")		# 数式の計算結果を取得
puts "平均 = " + average.to_s

実行するとこんな感じこんな感じ。今回は1台のマシン上でやったけどURI変えればリモートでも動く。たぶん。


そのサーバはこんな感じ。MS Officeの入ってるWindowsマシンで動かすよ。
excelsv.hta

<html>
<head><title>Excel Server</title>
<script language="RubyScript">

require 'drb/drb'

class ExcelServer
	def initialize
		@excel = WIN32OLE.new("Excel.Application")
		@excel.Visible = true
		@excel.SheetsInNewWorkbook = 1
		@book = @excel.WorkBooks.Add()
		@book.Application.DisplayAlerts = nil
		@sheet = @excel.Worksheets(1)
	end

	def put(cell, str)
		@sheet.Range(cell).Value = str
	end

	def get(cell)
		@sheet.Range(cell).Value
	end

	def shutdown
		Thread.new do
			sleep 1
			@book.Close()
			@excel.Quit()
			Thread.main.run
		end
	end
end

def server_start()
	uri = "druby://localhost:12345"
	DRb.start_service(uri, ExcelServer.new)
	sleep
	@window.close
end

</script>
</head>
<body onload="server_start" language="RubyScript">
</body>
</html>

HTAなのでダブルクリックするだけでサーバ起動。楽チン。
あー、でもあれだ。sleepでdRubyの接続待ちするからブラウザに制御が戻らないや。せっかくのHTAだけど画面表示はあきらめよう。あとウィンドウが固まって[x]ボタンで終了できないからシャットダウンもdRuby経由だな。なんかかっこわりー。わざわざHTAにする意味なかったかも。

サーバをシャットダウンするプログラムはこんな感じ
shut.rb

#!/usr/bin/ruby
require 'drb/drb'
excel = DRbObject.new_with_uri('druby://localhost:12345')
excel.shutdown


そんなわけで、今回の札幌Ruby会議01はこれらに限らず中身の濃い話が多かったです。こんな話を生で聴けるとはちょっと前まで想像もできなかったことですが、最近のRubyコミュニティの力は本当にすごいですね。
ありがとうございました。