Jの中でエクセルをエクセルの中でJを使う

JAPLA 2000シンポジウム 2000年12月16日
J の中でエクセルをエクセルの中で J を使う
慶応義塾大学理工学部
竹内寿一郎
1.はじめに
この稿は 1999年 12月の APL/J 研究会で志村正人氏が講演した内容に基づいて作成したもので
ある。表現などは私が適当に変えて述べているが、著作権は志村氏にあることをお断りしておく。
2.J の中でエクセルを使う
(1)OLE の設定
まず、J を起動して次の2本のスクリプトをRun|Fileで読み込む。
/system/examples/ole/excel/xlutil.ijs
/user/getexcel.ijs
スクリプト getexcel.ijs
をあらかじめ/user/
に入れておかねばならない。
このスクリプトについてはは (6)もしくは (7)で内容を示す。
なお、最初のxlutil.ijs
は、getexcel.ijs
にスクリプトを書き込んで、自動的にロード出来る
ようにしてもよい。
(2)OLE の起動
getexcel ’’
と打てばOLEが働いて自動的にEXCELが立ち上がる。
J のインストール後、1 度だけjreg.exeを実行してレジストリーに登録が必要である。
このとき、以下のことをEXCELで事前に処理しておかねばならない。
(1)カンマを取る。
カンマがあると、スペースが入り、データの次数が変わってしまう。EXCELで標準スタ
イルに戻しておく。
(2)ブランクを埋めておく。
Jで読み込んだときに、ブランクには変なブランク記号が入り数値化できない。0や184
184などの数値を入れてブランクをなくしておく。
(3)名前に日本語は使えない。
ファイルをコピーした後、ファイル名、シート名を日本語名から英語名に変更しておく。
(3)EXCEL でファイルを読み込む
エクセルに移り(ALT + Tab が便利)目的ファイルを読み込む。
(4)J に EXCELL のデータをインポートする
] temp=.xlreadr (filename.xls Sheet1 2 3 10 3)
temp2=. .> temp
これで、EXCELの Sheet1
の2−Cから10行3列の取り込みと数値化が完了する。2次元の
マトリックスがきれいに出来ていればOK。3次元になって変な形をしていればEXCELにお
{1{
かしなデータが混入している。
(5)EXCEL への書き込み
Jの結果は、配列のままEXCELに書き込むことができる。J 側で次のようにすればよい。
temp=. i. 10 3
temp xlwriter ’kadai.xls sheet1 10 1’
これで、EXCELのA−10を先頭に、Jの配列を書き込む。xlwriter
の rはレンジの意味であ
る。
(6)スクリプトgetexcel.ijs
の内容−1
getexcel.ijs
の内容:このファイル名は任意に変えても良い。
NB. ===============================================
NB. get EXCEL se OLE (xl til.ijs)
getexcel=: 3 : 0
NB. J Client use ole to EXCEL Sever
NB.Name of Excel’s Book is TEST and Sheet is TRY
NB. Usage: getexcel ’’
load ’c:\j403\system\examples\ole\excel\xlutil.ijs’
xlopen ’’
xlshow ’’
xlcmd ’wb add’
xlcmd ’temp saveas TEST’
xlget ’temp worksheets’
xlid ’ws’
xlget ’ws item sheet1’
xlid ’sh1’
xlset ’sh1 name TRY’
xlcmd ’sh1 activate’
)
NB. adjust your directry
(7)スクリプトgetexcel.ijs
の内容−2
志村正人氏のスクリプトに読み書きを付加したスクリプトです。
NB. ===============================================
NB. get EXCEL se OLE (xl til.ijs)
getexcel=: 3 : 0
NB. J Client use ole to EXCEL Sever
NB.Filename of Book is TEST and name of Sheet is TRY
NB. Usage: getexcel ’’
load ’c:\j403\system\examples\ole\excel\xlsutil.ijs’
xlopen ’’
xlshow ’’
xlcmd ’wb add’
xlcmd ’temp saveas TEST’
xlget ’temp worksheets’
{2{
NB. adjust your directry
xlid ’ws’
xlget ’ws item sheet1’
xlid ’sh1’
xlset ’sh1 name TRY’
xlcmd ’sh1 activate’
)
datain=:3 : 0
NB. a=.datain 1 1 5 5 (1 1) denotes a location; (5 5) denotes a size
(_2{.y.)$, .>xlreadr ’TEST.xls TRY ’,":y.
)
dataout=:4 : 0
NB. c dataout 6 6 (6 6) denotes a location of Excell Files
x. xlwriter ’TEST.xls TRY ’":y.
)
0!:0<’d:\j403\system\main\files.ijs’
0!:0<’d:\j403\system\main\stdlib.ijs’
readtable=:[:>0: .&.>[:c topen([: 1!:1 ])-.(13{a.) _
writetable=:4 : ’(,( :x.), 1 CRLF)1!:2 y.’
NB. Examples; makes a matrix file after reading
NB. from Excell File "Sheet TRY" in "TEST.xls"
NB. a=.datain 3 2 32 13
NB. a writetable<’d:\j403\temp\test.dat’
3.エクセルの中で J を使う
(1)はじめに
Excell
の中でマクロとして J が動くかどうか確認したところ、J405d、J406aなどのフリーウェ
アでは、インストールしてからある期間が過ぎると、作動しないことが分かった。
以下の環境で動作確認した。
● J403a J402 J405d J406a
●EXCEL2000 EXCEL97
● Windows/98,2nd Edition
/95 WindowsNT 4.0
JをサーバーとしてEXCELから使う方法は、幾つかあるが、J のユーティリティーとして提供
されている jsutil.xls
を使って、マクロでJを動かす方法が確実なので、ここではそれについて紹
介しよう。
(2)EXCEL で J のサーバーを立ち上げる
先ず、OLEで EXCEL からJを動かす手順を診てみよう。
(準備)jsutil.xl
を壊さないため、EXCELの適当なディレクトリーにコピーしておく。
(例えば/j403/system/examples/ole/excel/jsutil.xls
を/j403/user/jsutil.xls
へコピーする。)
(1) EXCEL を立ち上げる。Jに渡すファイルは、この時点で読み込んでおく。
(2) EXCEL から VISUAL BASIC のマクロを立ち上げる。
{3{
ALT+ F11 (またはツール (T) |マクロ (M))| Visual Basic Editor(V))
側に移って新しいモジュールを立ち上げる
(3) Visual Basic
挿入 (I) |標準モジュール
(Book1-Module1
のウインドウが立ち上がる。)
(4)Jのサーバーを登録
ツール (T) | 参照設定 (R) ・参照設定のウインドウで、右側の参照(B)ボタンでファイ
ルの参照ダイアログを出して、先ほど準備でコピーした jsutil.xls
を読みこむ。(このとき、
ファイルの種類を全てのファイル (*.*
)に切り換えておく。)
参照可能なライブラリーファイルの一覧の一番下に、jsutil.xls
にチエックが入ったことを確
認して、OKのボタンを押す。
(JSUTIL.XLS ThisBook
のモジュールウインドウが自動的に開く)
(5)先のモジュールウインドウに戻り、次のマクロを書き込む。
Sub auto_open()
jxopen
jshow 1
jlog 1
End Sub
(6)マクロの run
マクロの runには、次の2通りの方法がある。
・EXCEL に戻って、ALT+ F8 ( 又は、ツール (T) | マクロ (M))
ダイアログボックスにマクロの一覧が表示されるので、今定義したauto_runを選択し、実
行をクリックする。
・ショートカットキーを、今のSub auto_run()
の上にカーソルを持ってきて、F5キィ
を押す。
以降のrun_xx()でも上の2通りの方法が使える。
auto_runを実行すると、J OLE Automation Server
が立ち上がる。これは、J EXEその
もの。
(7) JDLLのロード
JDLL はライセンスフリーなJのモジュールである。J本体の完全な機能を有しているが。
文楽の黒子のように、姿が見えないので、学習用に使うにはハードルが高い。使い込んだ関
数の組み込みなどに向いているように思われる。
Sub auto_run()
jdopen
End Sub
(2)EXCELのマクロウインドウでJを使う
・先のマクロウインドウの下にJの命令を含んだマクロを書きこむ。
Sub run_1()
jcmdc "? 3 4 $ 10", 2, 3, 3, 4
End Sub
{4{
・" "の中は、Jの関数。最初のカンマ以下の 2,3,3,4
は EXCEL の開始セル (2-C)から3行4列を
指定。
・run_1を実行
直接 EXCEL のセル (2−C)を先頭に3行4列で生成した乱数が書き込まれれば成功。
Sub run_2()
jsetr "temp", "D3:F4"
End Sub
run_2を実行すると、EXCEL の指定したシートの範囲が、Jに転送される。ここで、tempはJ
の名詞で、名前は任意である。J側で、tempと打てば、ボックスの状態で表示される。
いずれにしても、EXCEL のセルの位置と幅を意識しなければならないのは、スプレッドシートの
功罪である。
(1) EXCEL のデータの受け渡し
Jで受ける名詞は任意。tempにしておこう。最初は数値だけで試してみよう。EXCEL には
、後に出てくるデータが入っている。これをJのサーバーに落としてみよう。
標準マクロウインドウに次のマクロを書く。
Sub run_3()
jsetr "temp", "a1:c30"
End Sub
A1:C30は EXCEL のから取り込むデータの最初のセル(左上)と最終のセル(右下)を指
定する。J に移って、tempと打つとボックスに入った状態で表示される。
jsetr
、jgetr
は、レンジでのデータの受け渡しで、EXCEL のセルの表現がそのまま使えて便
利である。
(2) Jでデータを受ける
サーバーのJに移って、temp。一個ずつボックスに入ったデータが表示される。
この場合は、Jの名詞を tempと指定している。指定しない場合は、JXP がデフォルトでこ
れに固定される。
>はボックスのオープンである。この方法で取り込んだデータは、数値であり、オープンす
るだけで使える。(なぜか、L:0が効かない。)
data=. > temp
69.1303 81.2368
76.4408 89.2311
84.1501 99.5354
92.29 109.297
101.664 121.983
・ ・
・ ・
257.237 295.818
261.618 300.989
265.364 305.79
Sub run_4()
jdo "] sum=.+/ > temp"
End Sub
] sum=.+/ > temp
{5{
59385 5104.11 6080.73
次に最小2乗法で、係数を求め、結果を EXCEL のシートに書き戻そう。
jdoはJの名詞、動詞定義を使用する。jcmdはVBの変数を使用して、結果をVBに保存し
ている。
”をJのコマンドで使うとVBの ”とバッティングするようで、ランクや数値化に影響がで
ている。(ランクは、
|
:である程度回避できる。)
Sub run_4()
jdo "data=.|:@ > temp"
jdo " a=. (1{data)"
jdo "b=. 2{data"
jcmdr "b %. 1 .a", "b32:a32"
End Sub
(3) Jのスクリプトのロードと計算
JexeServer
はJそのものだが、プロファイルを読み込んでいないプレーンな状態なので、と
にかくファイルを読み込ませよう。
Sub run_5()
jdo "0!:111<’c:\j403\user\loan.ijs’"
End Sub
loan.ijsのスクリプト
NB. calc loan %
NB. x. =.r (rate) ex. 0.01 0.02 0.0285 0.03 can use list
NB. y. =. n ex. 10 20 years. can use list
NB. r
NB. ------NB. 1-(1+ r)^_n
NB. Usage: [ loan ]
loan=: [ % temp_loan=: 1&-@(1&
+@[ ^/ -@])
このVB側からの操作で、Jのサーバーがスクリプトを読み込む。サンプルは、元利均等方
式の金利計算プログラムで、ここでは、1% 2%で10年、20年の元金に対する返済率
を求めている。
(4) Jexe Server
側で計算
・JexeServer
で
] temp=. 0.1 0.2 loan 10 20
0.162745 0.11746
0.238523 0.205357
0!:111
や 1!:0
はJの外部接続詞、俗に言うシステム関数で、0!:
系はスクリプト、1!:
系はファ
イルを取り扱うものであるだ。(詳細は、Jのヘルプを参照。)
1!:0
はスクリプトウインドウ(JS)の状態のようで、0!.111
の方がここでは都合がいいよ
うだ。
{6{
(5) VBのマクロで計算
VB 側でも操作できる。
Sub run_6()
jdo " 0.022 0.03 loan 20 25"
End Sub
JExeServer
側の結果
0.022 0.03 loan 20 25
0.0623434 0.0524309
0.0672157 0.0574279
(6) EXCEL に結果を返す
これを一気に EXCEL に戻してみよう。
Sub run_7()
cmdr " 0.02 0.03 loan 20 25", "D6:E7"
End Sub
jcmdrはレンジを指定した jdoで、EXCEL と馴染みが良く、長いタシットや明示型定義も
受け付けてくれる。
(7)プロファイルのロード
プロファイルをロードする jloadpro がサポートされている。
le
Sub profile()
jloadprofile
End Sub
これで、プロファイルをロードする。JEXE Server
が完全なJに戻る。
lpad ’plot’
で plotも使える。
(バージョン402では pro le.ijs
をコピーして、pro le.js
にリネームしないとエラーになる)
(8)種々のテスト
EXCEL の数式バーやソルバーをマニュアルを見ながら使うよりは、手慣れたJの作り置き
の関数を使った方が便利な事が多い。
以前に作ったスクリプトをロードしてみよう。
Sub run_8()
jdo "0!:111<’c:\user\ijs\calc.ijs’"
End Sub
J のスクリプト(QR法で固有値を求める。)
NB. find eval tacit definition
NB. ussage: eval_t pwr data
NB. ussage(take diag ): t eval_t pwr data
fst=. >&(0&{) NB. take first
snd=. >&(1&{) NB. take second
t=.(< 0 1)&|:@]
{7{
tmp=.128 !:0
d=. snd+/ . * fst
pwr=. ^:100 NB. repeat 100 times
eval_t=. d&tmp
EXCEL で E9:G11にデータを入れて、
3 -0.7 0.4
-0.7 3.5 0.3
0.4 0.3 3.6
一気にJに送り込んで計算して、固有値を書き戻してみると。
Sub run_9()
jsetr "temp", "E9:G11"
jcmdr "eval_t pwr temp", "E13:G15"
End Sub
エラー。
・
・
・Jに送り込んだ、tempはボックスに入っており、開かないといけない。
Sub run_9()
jsetr "temp", "E9:G11"
jcmdr "eval_t pwr >temp", "E13:G15"
End Sub
3.994269429 -0.000689153 4.03002E-16
-0.000689153 3.793080752 4.6691E-16
3.67265E-24 1.23595E-21 2.312649818
(9) EXCEL のファイルに登録
使い込んだJサーバーに関する EXCEL のマクロは、セーブしてファイルにしておくと便利
である。
EXCEL のマクロ画面で、挿入ファイルで、マクロを記述したファイルを読み込めば良い。
Sub auto_open()
jxopen
jshow 1
jlog 1
End Sub
この後に、マクロを書き込んでいけばいいだろう。ファイル名は oletest.xls
としておこう。
使うときは、マクロ画面でF5を使っても、EXCEL 側で、ALT | F8 でマクロの一覧を呼
び出してでも良い。
(10)数式バー
EXCEL なら使いたい数字の列を反転しておいて、数式バーをささっと使うと、便利だと思わ
れるようだが、この場合、jcmdを数式バーからダイレクトに使って、反転している EXCEL
{8{
のセルに直接書き込むと・
・
・
・
・
jcmd("
+/ 3 4 5 7")
---> B2: 19
jcmd("
+: 16")
---> B3 32
jcmd(B2 &"+ " & B3) ---> B4 52
Jの関数は ”で囲むこととなるが、数式バーのレや=をクリックしていくと、未定義の警告
を出しながら、Jのサーバーで計算して EXCEL に書き戻している。i.3 が
4 I. 3 4
に化けて
、計算できなくなるところなどは、全くのご愛敬である。
4.jsutil.xls
で定義済みの EXCEL (VB)のJ関連の関数
jsutil.xls
で定義済みの EXCEL( VB)のJ関係のコマンドは次の通りである。
open
show
log
実行
EXCEL に計
算結果を書き込
む
EXCEL から
のファイルの
渡し
jget
jloadpro le
jxopen
jxopen
jdopen
jdoprn
jshow
jshow 1 (or 0)
jlog (or 0) jlog 1 (or 0)
jdo
jdo "mean=.
+/ % #"
JexeServer open
JdllServer open
のみ1
Jexe =yes 0=no
のみ jexe
1=yes 0=no
結果はJの変数で、JXP
など、VBには残らない。
jcmd
jcmd ""
結果は EXCEL (VB)の
変数に残る。
jcmdc
jcmdc "3 4 $i.12",2,5,3,4 EXCEL
のセル指定。
TopLeft(
行,列),行数、列
数。2E から3行4列
jcmdr
jcmdr "3
+ i.11","a10:a20" EXCEL
のレンジを指定
(左上:右下)
jsetc
2-E
から3行4列
Sub run()
jsetc"temp",2,5,3,4
End Sub
jsetr
EXCELのレンジを指定
Sub run()
(左上:右下)
jsetr "temp","a10:a20"
End Sub
jget
Sub run()
jget "temp"
End sub
jloadpro le
{9{