Tcl/Tk 覚え書き: ddeでExcelと連携
Windows版Tcl/Tkに付属するddeパッケージを使用してExcelを操作する方法についてまとめておきます。なお、最初の取っかかりはAM02:50 Tcl/Tk Scripting Laboratoryを参考にさせて頂きました。
前提条件とか注意事項とか
以下の変数が設定されていることとする。
- filename
- ファイル名
- bookname
- ワークブック名
- sheetname
- ワークシート名
- col, col1, col2
- セルの列番号
- row, row1, row2
- セルの行番号
- data
- セルに読み書きするデータ
手元にExcel2000しかないので、より新しいバージョンでも通用するかは不明。
日本語には基本的に対応していない。(詳しくは後述)
FirefoxなどのGeckoを使ったブラウザでは、コード例の部分が右端で折り返されずにはみ出してるので注意。(ドラッグしてコピーはできるので、必要ならエディタ等にコピペして見てください)
Excelが起動しているか確認する
以下の結果が0でなければ起動している、0ならば起動していない。
llength [dde services Excel {}]
ファイルを開く
dde execute Excel System [format {[OPEN("%s")]} $filename]
新規作成
dde execute Excel System {[NEW(1)]}
ただし、NEWの引数が1でワークシート1枚、2でグラフシート1枚、3でマクロシート1枚、5でワークシート3枚(通常の新規作成で作成されるもの)、7でダイアログを持ったドキュメントが作成される。
ブックにシート追加
set ddestr [format {[ACTIVATE("%s")][WORKBOOK.INSERT(1)]} $bookname]
dde execute Excel System $ddestr
WORKBOOK.INSERTの引数はNEWと同じ。ただし5は無効。
ブックからシート削除
削除確認ダイアログを表示する場合。
set ddestr [format {[ACTIVATE("%s")][WORKBOOK.DELETE("%s")]} $bookname $sheetname]
dde execute Excel System $ddestr
削除確認せずに強制的に削除する場合。
set ddestr [format {[ACTIVATE("%s")][ERROR(False)][WORKBOOK.DELETE("%s")][ERROR(True)]} $bookname $sheetname]
dde execute Excel System $ddestr
現在アクティブなブック名とシート名を得る
set nowname [dde request Excel System Selection]
set selptn {\[(.*)\](.*)!.*}
regexp -- $selptn $nowname allname bookname sheetname
ブック名がbooknameに、シート名がsheetnameに入る。
アクティブなシートを切り替える
現在のブック内で切り替える場合。
set ddestr [format {[WORKBOOK.SELECT("%s")]} $sheetname]
dde execute Excel System $ddestr
ブック名だけ指定する場合。
set ddestr [format {[ACTIVATE("%s")]} $bookname]
dde execute Excel System $ddestr
ブック名とシート名を指定して切り替える場合。
set ddestr [format {[WORKBOOK.ACTIVATE("[%s]%s")]} $bookname $sheetname]
dde execute Excel System $ddestr
セルにデータを入力する
1つのセルに入力する場合。
set tpcstr [format {[%s]%s} $bookname $sheetname]
set itemstr [format {R%dC%d} $row $col]
dde poke Excel $tpcstr $itemstr $data
row1,col1~row2,col2の矩形領域に入力する場合。
データは行毎に改行で、行内の各セル毎にタブで区切る。データが足りないセルは空になり、指定領域をはみ出すデータは捨てられる。
set tpcstr [format {[%s]%s} $bookname $sheetname]
set itemstr [format {R%dC%d:R%dC%d} $row1 $col1 $row2 $col2]
dde poke Excel $tpcstr $itemstr $data
セルからデータを取得する
1セルの場合。
set tpcstr [format {[%s]%s} $bookname $sheetname]
set itemstr [format {R%dC%d} $row $col]
set data [dde request Excel $tpcstr $itemstr]
矩形領域の場合。
dataに代入される値は、行毎に改行で区切られ、行内のセル毎にタブで区切られている。ただし、Windowsのデータ形式であるので、改行が "\n" でなく "\x0d\x0a" なので注意。
set tpcstr [format {[%s]%s} $bookname $sheetname]
set itemstr [format {R%dC%d:R%dC%d} $row1 $col1 $row2 $col2]
set data [dde request Excel $tpcstr $itemstr]
名前を付けてファイルを保存
set xlsfname [file nativename $filename]
set ddestr [format {[ACTIVATE("%s")][SAVE.AS("%s")]} $bookname $xlsfname]
dde execute Excel System $ddestr
日本語の扱いについて
Tcl/Tkの内部文字列はUTF-8で扱われます。一方Windowsの日本語はShift_JISであり、dde通信も当然Shift_JISで行われます。
ddeパッケージではUTF-8 ~ Shift_JIS間の変換を行っていないので、日本語は基本的に使用出来ません。例外として、Tcl8.4系以降ではdde requestコマンドに-bynaryオプションが追加され、バイナリデータを受け取ることが出来るようになったので、これと文字コードの変換を組み合わせて、日本語のデータを読み取ることだけはできるかもしれません。(未検証ですが)
過去に8.3系の時代のddeパッケージに手を入れて日本語対応にしたことがありますが、その後いろいろ内容が増えたり変わったりしてるようなので、以降のバージョンを対応させるのはすぐにはできそうにありません。
でもとりあえず、8.3系で作ったモジュールが8.4系でも使えるっぽい。スタブ万歳。
ということで、ちょっとモノは古いですが、日本語対応ddeパッケージを置いておきます。名前はddeecdとしてありますので、標準のddeは残したまま使えます。
| 固定リンク
この記事へのコメントは終了しました。
コメント