とあるHTAプログラムを作成中、Windows XP以降のエクスプローラと同様のファイル名ソートをする事になった。そのためには、shlwapi.dllに含まれるStrCmpLogicalWという関数を使用する必要がある事が分かった。
ところが、ここで問題となるのがHTAから、このようなwin32apiを呼び出す方法。調べてみたところ、以下のサイトが参考になった。
コマンドラインからマウスを操作する方法 (rundll32.exeで動くDLLの作成法) – 主に言語とシステム開発に関して
コマンドプロンプトから,Win32 APIや任意のDLLを呼び出して実行しよう (コマンドプロンプトから画面キャプチャする方法の仕組みを理解) – 主に言語とシステム開発に関して
個人的に、外部ライブラリを新たに追加する方法は除外。管理が面倒だし、スクリプトファイル単体でお手軽に使いたいから。また、今回は戻り値の取得が必要なので、戻り値の取得できないrundll32.exeを使用する方法は使えない。そんなわけで、今回は上記サイトにある「(3)VBAのCALL関数を,WSHやコマンドプロンプトから呼び出す」を採用。いやまぁ、Excelが必要じゃないかというツッコミ所があるのだけど、今回使用する環境ではOfficeがインストールされている可能性が高いのでその辺は妥協。
で、VBAのCALL関数を使って以下のように変数AとBの文字列を比較してみた。
Excel.ExecuteExcel4Macro( "CALL(\"shlwapi\", \"StrCmpLogicalW\", \"JCC\", \"" + A + "\", \"" + B + "\")" );
ところがこれは上手くいかなかった。正確に言うと、マルチバイト文字で正しく動作していなかった。理由を色々調べてみると、どうもCALL変数に渡すデータ型の指定が良くないようだ。CALL 関数と REGISTER 関数の使い方 – Excel – Office.com
更に調べていくと、マルチバイト用のデータ型指定という物が存在する事が分かった。ただし、Excel 2007以降のみ。
Excel 2007 のアドイン (XLL) の開発
Excel XLL CALL REGISTER DataTypes | Smurf on Spreadsheets
それによると、マルチバイト文字はデータ型C, Fの後ろに「%」をつけてC%、F%となるそうな。そんなわけで、修正後は以下のようになる。
Excel.ExecuteExcel4Macro( "CALL(\"shlwapi\", \"StrCmpLogicalW\", \"JC%C%\", \"" + A + "\", \"" + B + "\")" );
これで日本語でも正しくエクスプローラ同様のソートが行えるようになった。多分。
ちなみに、JavaScriptでソートする場合は以下のような感じ。
[js]
items.sort( function(A, B) {
return Excel.ExecuteExcel4Macro( "CALL(\"shlwapi\", \"StrCmpLogicalW\", \"JC%C%\", \"" + A + "\", \"" + B + "\")" );
});
[/js]
コメントを残す