VBAでUTF8を直接吐くようなプロセスの標準出力をうまく使う方法(cmd /c を有効利用しましょう)
という意味のわからないタイトルですが、まあ、いろいろと困るのはこういうのです。
VBAとWScript.ShellオブジェクトとMSXMLとSubversionを知らない人にはなんのこっちゃって感じですが:
Set shellObj = CreateObject("WScript.Shell") Set msxml = CreateObject("MSXMLのProgId忘れた") With shellObj.Run("svn history --limit 1 --xml svn://example.org") msxml.LoadXml .StdOut.ReadAll ~~ 適当な処理 End With
この処理は一見問題がないように見えますが、非ASCII文字(日本語とか日本語とか)が混入したときに問題が出てきます。(svn --xml
はUTF-8のXMLを吐きます)
.StdOutがShift_JIS前提で標準出力ストリームを読み込んでしまうせいで、非ASCIIコードポイントで文字化けがおこり、msxml.LoadXmlでロードする内容としては壊れた内容になってしまいます。
これは困った。
まともに直接.StdOutから読むのは無理そうなので、一度どこかのファイルに吐き出してから、それを直接MSXMLにパースしてもらいましょう。
Set shellObj= CreateObject("WScript.Shell") Set msxml = CreateObject("忘れた") shellObj.Exec "cmd /c svn history --limit 1 --xml svn://example.org > どこかのファイル" msxml.Load どこかのファイル ~~ 適当な処理 + どこかのファイルを削除する処理
これでOK。標準出力にどんなバイナリを流されても平気です。重いけど。
ポイントは cmd/c 〜〜 > リダイレクト先
。ファイルに標準出力をリダイレクトさせるためにcmd /cを使ってます。
ほか、exeとしての実体がないdirの出力を出すときにもcmd /cは使えます。
まあ、もっと正攻法的なものがあるんだろうけど…