Λάδι Βιώσας

http://profile.hatena.ne.jp/kenkitii/

VBA から ruby のコードを実行したい

色々と調べて、結局、実運用には難しそう・・・と思っているのだけど、却下したアイデアでも、思考の流れを残しておかないと、数年後には忘れて同じことをやりはじめそうな悪寒がするので、そうならないように日記に書いておきます。

やりたいこと

秒間で更新される Excel Worksheet 上の数値を使って ruby で計算したい。Win32ole は使わない方向で。あ、VBA から ruby スクリプトを呼ぶだけなら Shell 関数でできます。

方針

Worksheet が更新されるタイミングで、socket 通信をして ruby にデータを流し込む。VBA からの socket 通信は、winsock.dll を使いたくないので、ruby製 のクライアントを呼び出す。できるだけお手軽に。

準備

こちらから↓ ActiveRuby をダウンロード&インストールします。ActiveRuby にする理由は、ScriptControl を使いたいから。
http://www.artonx.org/data/asr/

Excel のオプション - 参照設定で、ScriptControl 1.0 にチェックを入れます。

スクリプト

require 'socket'
require 'thread'

svr = TCPServer.open(123456)
puts "server is running..."

while true
  Thread.start(svr.accept) do |s|
    puts s.gets
    s.close 
  end
end
  • tcpclient.rb
require 'socket'

def client(s)
  sock = TCPSocket.open('localhost', 123456)
  sock.puts(s)
  sock.close
end

とりあえずのテストとして、Excel の Worksheet にボタンを貼り付けて、こんな感じに↓。

Private Sub CommandButton1_Click()
    Dim script As New ScriptControl
    
    script.Language = "RubyScript"
       
    fn = FreeFile
    Open "(pathto)\tcpclient.rb" For Input Access Read As fn
    script.AddCode StrConv(InputB(LOF(fn), fn), vbUnicode)
   
    script.Run("client", "testdata")    
End Sub

問題点

遅いのひとこと。うーんどうしたものか。