1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

[VBScript]コード内でUNICODE文字を扱う場合及びCMDでユニコード文字の番号を知る方法

Last updated at Posted at 2020-09-13

VBScript自体はANSI(shift-jis)かUTF-16LE

スクリプト自体はANSI Or UTF-16LEでしか使えない。
UTF-8の.vbsは動かない。
このためNotepadでVBScriptを新規作成するときは
NotePad /a "C:\hogehoge\NewVbs.vbs
というように/aオプションででANSIにする。
しかしこの場合♥㈲èéêë.txtのようなファイル名があるとANSIで保存できない。
こういう場合にはChrW(&H2665) & ChrW(&H3232) & ChrW(&HE8) & ChrW(&HE9) & ChrW(&HEA) & ".txt"と表記する。
しかし、このような番号をどうやって取得すれば良いか。Excelを使う方法はすでに扱っているが、Excelがない場合どうするか。

ChrWとAscWの使い分け

ANSIでUnicode文字を扱うポイントは&Hの16進表示でChrWを使う ChrW(&H3232)
これによって、ANSIでは表記されない文字を表記できる。可読性はないが、VBSCRIPTやVBAでユニコード文字を扱うには、このような方法しかない。
ChrW(&H3232) & "架空のITサービス
とすると㈲架空のITサービスとなる

VBScript
' ChrWTest.vbs
Wscript.Echo ChrW(&H3232) '有限会社の(有)
Wscript.Echo AscW(ChrW(&H3232)) '12850 十進
Wscript.Echo Hex(Asc(ChrW(&H3232))) '3232 '16進
Wscript.Echo "&H" & Hex(Asc(ChrW(&H3232))) '&H3232 16進 はHexだけでなく "&H" & HEX() とすること
Wscript.Echo "&#" & Asc(ChrW(&H3232)) & ";" 'Webページでは &H#XXXXX;とすると、機種依存文字が表示される(例外あり)

CMD+CSCRIPTから文字コードを知る方法UTF-8出力

CMDを起動する
chcp 65001
と入力してUTF-8で出力されるようにする。

Cscript //Nologo UnicodeNumberCScipt.vbs "♥㈲">C:\hoge\rstUtf8.txt
Qiitaの表記上このようにコマンドラインで引数にする。(※Qiitaの現在のマークダウンは``で囲むと意図した文字♥ではなく♥十進ユニコード番号表記になるため、囲みを外しています

CMD+CSCRIPTから文字コードを知る方法UTF-16LE出力(ただし当方の環境ではエラー)

CMD /uとして起動する
Cscript //Nologo UnicodeNumberCScipt.vbs "♥㈲">C:\hoge\rstUtf16.txt
これでできたファイルはNOTEPADでは半角の英数字が全角になるなどの文字化けする。SAKURAエディタでは読める。

特殊文字の早見表

その他よく使うものがこちら
https://sakichin.com/other/html_words.html

CMDで出力される十進数とWebページは正の場合は一致している

しかし、この上記のページをみると、&#十進数字というコードだけで結構な記号を表すことができることがわかる。しかもその番号はこの方法によって得ることができる。

全部を表記することはできない。

以下のスクリプトは、単純に&#をつけている。しかし、半角スペース、円マーク、タブ記号などは&#表記ではないので、この方法ですべての特殊文字が表示できるわけではない。
♥㈲èéêëアイウエオქართული
の中身をスクリプトで取得すると、 
♥㈲èéêë&#-143;&#-142;&#-141;&#-140;&#-139;ქართული
と、いちおう取得できる。
こうなる。しかし、実際にマイナスになる番号をそのまま使うとうまくいかない。
このようになってしまう。
♥㈲èéêë&#-143;&#-142;&#-141;&#-140;&#-139;ართული
ქართული

どうしても出したいときはマイナスの場合は65536を加算する

半角カナの数値文字参照
♥㈲èéêëアイウエオქართული
マイナスの場合は65536[DEC]を加算する。
♥㈲èéêëアイウエオქართული

$-143+65536=65393$

CScriptで指定された文字のユニコードをダンプ出力するVBScript

VBScript
Dim var
Dim i
Dim str
Dim cnt
If Wscript.Arguments.count>0 then
Set var = Wscript.Arguments
'Wscript.Echo TypeName(var(0))
Wscript.Echo "番号" & vbTab &  "ユニコード文字" & vbTab & "ユニコード文字番号"
IF Typename(var(0)) = "String" Then
str = cStr(var(0))
for i = 1 to Len(str)
' どちらか一つを使用する
WScript.Echo i & vbTab & MID(str,i,1) & vbTab & "&H" & HEX(AscW(MID(str,i,1)))
' Webページ用
WScript.Echo i & vbTab & MID(str,i,1) & vbTab & "&#" & AscW(MID(str,i,1)) & ";" ' Webページ用
' Webページ用はマイナスになるとエラーになるため、マイナスの場合は65536を足す。半角カタカナで発生する。
'  IF AscW(MID(str,i,1)) <> -1 Then
'  .WriteText  i & vbTab & MID(str,i,1) & vbTab & "&H" & HEX(AscW(MID(str,i,1))) & vbTab & "&#" & AscW(MID(str,i,1)) & ";",1
'  Else
'  .WriteText  i & vbTab & MID(str,i,1) & vbTab & "&H" & HEX(AscW(MID(str,i,1))) & vbTab & "&#" & AscW(MID(str,i,1))+65536 & ";",1
'  End IF
WScript 
Next
End If
End If

しかし番号は取得できるが文字化けする時がある

このとき932にしたままだと出力したダンプファイルは
1 ? &#9829;
となる
chcp 65001に変更すると
1 ? &#9829;
やっぱりこうなる。

VBSCRIPTで文字コードをUTF-16LEで出力

Cmd /aで起動する。
CurrentをC:\hoge\
そこにあると仮定しているCscriptUnicodeNumberUTF16LE.vbsを使う
Cscript //Nologo CscriptUnicodeNumberUTF16LE.vbs "♥㈲"
のようにCscriptを用いて、引数に求めるユニコード文字列を書く。文字列はダブルクォーテーションで囲む。
UnicodeNumberUTF16LE.txtに出力する。既存のファイルは削除する。
(おそらく番号を知れば十分というのが一般的であろうと判断してこういう仕様にしています、これを回避したいときは確認メッセージをだすかユニークなファイル名にしてください)
CHCPを使わず、FSOでUTF-16LEに出力します。(改行はvbCrLf)

VBScript
Const ForReading = 1 'AS Long
Const ForWriting = 2 'AS Long
Const ForAppending = 8 'AS Long
Const WindowsFolder = 0 'AS Long
Const TemporaryFolder = 2 'AS Long
Const UTF16True = -1 'As Boolean vbTrue
Const vTristateFalse = 0
Const vTristateTrue =-1
Const vTristateMixed =-2
Const vTristateUseDefault =-2
Const adModeReadWrite = 3
Const adTypeBinary = 1
Const adTypeText = 2
Const adSaveCreateOverWrite = 2

Dim var
Dim i
Dim str
Dim cnt
Dim FSO : Set fso = createObject("Scripting.FileSystemObject")
Dim TS
Dim strListFileFullName
If Wscript.Arguments.count>0 then
Set var = Wscript.Arguments

'Wscript.Echo TypeName(var(0))
IF Typename(var(0)) = "String" Then
strListFileFullName = fso.getParentFolderName(WScript.ScriptFullName) & "\UnicodeNumberUTF16LE.txt"
IF fso.fileExists(strListFileFullName) Then fso.DeleteFile(strListFileFullName)
Set TS = Fso.OpenTextFile(fso.getParentFolderName(WScript.ScriptFullName) & "\UnicodeNumberUTF16LE.txt" , ForWriting, True, vTristateTrue) 'テキストストリーム作成(リストファイル生成,UTF-16LE BOMはUTF-16LEの定義上付与されない) 
Ts.WriteLine "番号" & vbTab &  "文字" & vbTab & "文字番号" & VbTab & "HTMLのコード"
str = cStr(var(0))
for i = 1 to Len(str)
Ts.WriteLine i & vbTab & MID(str,i,1) & vbTab & "&H" & HEX(AscW(MID(str,i,1))) & vbTab & "&#" & AscW(MID(str,i,1)) & ";"
Next
Ts.Close
End If
End If

UTF-16LEとUTF-8BOMとUTF-8Nで出力

このときはchcp 932で起動します。CMDでもいいし、CMD /aでも良いです。タスクバーにアドレス欄を儲けておきましょう。
起動後VBSCRIPTのあるフォルダにCD /D C:\hogeのように移動して
Cscript //Nologo CscriptOUtputUnicodeNumber168B8N.VBS "♥㈲èéêëアイウエオ;ართული"

VBScript
' File Name CscriptOUtputUnicodeNumber168B8N.VBS
' How To Use
' [Win]+R
' CMD /a
' CD /D 'parentfolder
' Cscript //Nologo CscriptOUtputUnicodeNumber168B8N.VBS "UNICODECHARACTER"
Const ForReading = 1 'AS Long
Const ForWriting = 2 'AS Long
Const ForAppending = 8 'AS Long
Const WindowsFolder = 0 'AS Long
Const TemporaryFolder = 2 'AS Long
Const UTF16True = -1 'As Boolean vbTrue
Const vTristateFalse = 0
Const vTristateTrue =-1
Const vTristateMixed =-2
Const vTristateUseDefault =-2
Const adModeReadWrite = 3
Const adTypeBinary = 1
Const adTypeText = 2
Const adSaveCreateOverWrite = 2

Dim var
Dim i
Dim str
Dim cnt
Dim FSO : Set fso = createObject("Scripting.FileSystemObject")
Dim TS
Dim strListFileFullName
If Wscript.Arguments.count>0 then
Set var = Wscript.Arguments

'Wscript.Echo TypeName(var(0))
IF Typename(var(0)) = "String" Then
strListFileFullName = fso.getParentFolderName(WScript.ScriptFullName) & "\UnicodeNumberUTF16LE.txt"
IF fso.fileExists(strListFileFullName) Then fso.DeleteFile(strListFileFullName)
Set TS = Fso.OpenTextFile(fso.getParentFolderName(WScript.ScriptFullName) & "\UnicodeNumberUTF16LE.txt" , ForWriting, True, vTristateTrue) 'テキストストリーム作成(リストファイル生成,UTF-16LE BOMはUTF-16LEの定義上付与されない) 
Ts.WriteLine "番号" & vbTab &  "ユニコード文字" & vbTab & "ユニコード文字番号"
str = cStr(var(0))
for i = 1 to Len(str)
Ts.WriteLine i & vbTab & MID(str,i,1) & vbTab & "&H" & HEX(AscW(MID(str,i,1)))
  IF  Sgn(AscW(MID(str,i,1)) ) <> -1 Then
  Ts.WriteLine i & vbTab & MID(str,i,1) & vbTab & "&#" & AscW(MID(str,i,1)) & ";" ' Webページ用
  Else
  Ts.WriteLine i & vbTab & MID(str,i,1) & vbTab & "&#" & AscW(MID(str,i,1))+65536 & ";" ' Webページ用
  End If
Next
Ts.Close
End If
End If

Dim sr, strTempFileName
Dim iStr
Dim oStr

IF Typename(var(0)) = "String" Then
Set sr = CreateObject("ADODB.Stream")
Set oSr = CreateObject("ADODB.Stream")
strListFileFullName =""
strListFileFullName = fso.getParentFolderName(WScript.ScriptFullName) & "\UnicodeNumberUTF8.txt"
strTempFileName =  fso.getParentFolderName(WScript.ScriptFullName) & "\UnicodeNumberUTF8N.txt"
IF fso.fileExists(strListFileFullName) Then fso.DeleteFile(strListFileFullName)
IF fso.fileExists(strTempFileName) Then fso.DeleteFile(strTempFileName)
With sr
.Mode = adModeReadWrite
.Charset = "UTF-8"
.Type = adTypeText
.Open
.WriteText  "番号" & vbTab &  "文字" & vbTab & "文字番号" & VbTab & "HTMLのコード",1
for i = 1 to Len(str)
' Web用はマイナスの場合65536を加算
  IF AscW(MID(str,i,1)) <> -1 Then
  .WriteText  i & vbTab & MID(str,i,1) & vbTab & "&H" & HEX(AscW(MID(str,i,1))) & vbTab & "&#" & AscW(MID(str,i,1)) & ";",1
  Else
  .WriteText  i & vbTab & MID(str,i,1) & vbTab & "&H" & HEX(AscW(MID(str,i,1))) & vbTab & "&#" & AscW(MID(str,i,1))+65536 & ";",1
  End IF
Next
.SaveToFile strListFileFullName, 2 'ここがポイント、保存してもCloseさせずそのままBOMを削除に移行
End With
' Binaryを開く
With oSr
  .Mode = adModeReadWrite
  .Type = adTypeBinary
  .Open

'ここでsrを開いたままでポジションを0にする。そのあと、バイナリモードにスィッチして、ポジションを3にする。これでBOMをスキップ
  With sr
   .Position = 0 
   .Type = adTypeBinary
   .Position = 3
  End With
  ' write remaining bytes to file and clean up
  .Write Sr.Read
  .SaveToFile strTempFileName, adSaveCreateOverWrite
  .Close
  Sr.Close
End With
End IF
Set sr = Nothing
Set oSr = Nothing

このような場合にVisualBasic、C#を使う例はあったが、VBSCriptで対応可能である。

Powershell、CMDの画面ではMSゴシックはグルジア文字やアラビア文字が表示されない

Powershell,CMDとも共通しているが、それぞれのコンソールでMSゴシックを設定するとUNicodeもかなり表示できる。しかしグルジア文字はアラビア文字は文字化けする。
しかし、メモ帳をMS UI ゴシックにして、上記のVBScriptで出力すると、表示される。
UTF-8だと半角カナも文字化けするか、とにかくすべての言語を表示させることは難しい。
またUTF-16LEもCMD /Uでやるとメモ帳ではうまく開けない。しかしVBSだとうまくいく。

このため、文字のユニコードを調べたいときは
cmdを起動してchcp 932(標準)の状態で、上記の手順でvbsを使う。という方法で文字に対応するユニコード番号を取得できる。
Webページは&#'をつける。このため、上記のスクリプトでは&#'つきで十進表示し、マイナスの場合は失敗するので65532を加算して表示している。
通常のVBSやVBAの場合はChrW(&H)を使う。このため上記のスクリプトはすでに&Hをつけて表示している。

1
2
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?