ABCDE12345 などの全角英数字記号を半角に変換するには、 VB の StrConv 関数を使用すれば簡単にできますが、 StrConv 関数では全角カタカナ文字および 「」、。ー・゛゜ の記号も、 文字化け発生率が非常に高い半角カタカナ・記号へと変換されてしまうという問題点があり非常に不便です。 拙作の ZenkakuToHankaku 関数は全角カタカナは変換されないようにしてあります。
Option Explicit '----- ZenkakuToHankaku 関数 Ver 1.00 ----- '2 バイト全角英数字("ABC123" など)および記号("&%#" など)を '1 バイト半角英数字・記号に変換します。 ' 'VB の StrConv でもできる処理なのですが、StrConv では '全角カタカナおよび日本語記号("「」ー" など)も文字化けしやすい '半角カタカナに変換されてしまうという問題点があるため作ってみました。 ' '引数 strSource ' 全角英数字・記号を含んだ文字列式を指定します ' '戻り値 ' 引数 strSource に渡された文字列に含まれる全角英数字・記号を ' 半角英数字・記号に変換した文字列を返します。 ' Public Function ZenkakuToHankaku(ByRef strSource As String) As String Dim lngSourceLength As Long '渡された文字列の長さ Dim strResult As String '変換後文字列を格納するバッファ Dim strSingle As String '抜き出された 1 文字分のバッファ Dim intCharCode As Integer '1 文字の文字コードを格納する Dim i As Long 'ループカウンタ lngSourceLength = Len(strSource) '文字列の長さを得る If lngSourceLength = 0 Then Exit Function '0 文字なら関数を抜ける strResult = Space$(lngSourceLength) '変換後文字列を格納するバッファサイズを確保 strSingle = Space$(1) '1 文字分のバッファを確保 For i = 1 To lngSourceLength Step 1 '文字列の最後までループ Mid(strSingle, 1, 1) = Mid$(strSource, i, 1) '1 文字だけ抜き出す intCharCode = Asc(strSingle) 'Asc 関数で文字コードを得る If ((intCharCode > &H8340) And (intCharCode < &H8394)) Or _ (intCharCode = &H8175) Or _ (intCharCode = &H8176) Or _ (intCharCode = &H8141) Or _ (intCharCode = &H8142) Or _ (intCharCode = &H8145) Or _ (intCharCode = &H815B) Or _ (intCharCode = &H814A) Or _ (intCharCode = &H814B) Then '全角カタカナなどであるか判別 Mid(strResult, i, 1) = strSingle '変換せずにそのままバッファに格納 Else 'StrConv 関数で半角英数字・記号に変換。手抜きです(^^; Mid(strResult, i, 1) = StrConv(strSingle, vbNarrow) End If Next i ZenkakuToHankaku = strResult '結果を返す End Function |
サンプル :
z2h.lzh(2.69KB)
その他にも、NKF32.DLL の ToHankaku() を使用する方法もあります。 海人さんのウェブサイトから NKF32.DLL を入手しシステムフォルダに置き、 NKF32.DLL で文字コード変換の NKF32.DLL Declaration Module for Visual Basic(32bit) Ver 1.xx をプロジェクトに組み込み、
'strHoge に全角英数字・記号文字列が含まれていると仮定 Call SetNkfOption("-s") Call ToHankaku(ByVal strHoge) 'ToHankaku() で半角英数字・記号に変換 strHoge = TrimNull(strHoge) 'NULL 文字以下をカットするとするだけです。
Win32 API 関数には、引数の値に符号なし(長)整数型(unsigned int, unsigned long, DWORD など)を渡す必要がある関数が星の数ほどあります。
32bit 符号なし整数型は 0(&H00000000) 〜 4,294,967,295(&HFFFFFFFF) の範囲の正の整数値を扱うことができます。
しかし VB には符号なし整数型はなく、符号付き長整数型(Long)しかありません。
ちなみに VB の Long 型の範囲は -2,147,483,648 〜 2,147,483,647 です。
そのため 2,147,483,648(&H80000000) 〜 4,294,967,295(&HFFFFFFFF) の範囲の整数値を VB の Long 型に格納しようとする場合、
&H80000000 のように 16 進数表記で指定しないとオーバーフローしてしまいます。
文字列を数値に変換する際は注意が必要です。
Dim lngNumber As Long lngNumber = CLng("&H80000000") '正常に処理される lngNumber = CLng("2147483648") 'オーバーフローエラー発生もし上記の範囲の整数値で、10 進数で記述された文字列、 または倍精度浮動小数点数型(Double)や通貨型(Currency)などの整数値を 4 バイトの符号なし整数型として扱いたい場合は、 4,294,967,296 をマイナスしてやればよいです。
Dim dblNumber As Double Dim lngNumber As Long dblNumber = CDbl("2147483648") '整数値文字列を Double 型に変換 If dblNumber > 2147483647 Then '2147483647 より大きい場合 lngNumber = CLng(dblNumber - 4294967296#) '4294967296 をマイナスし、Long 型に変換 Else lngNumber = CLng(dblNumber) End IflngNumber を VB で参照すると -2147483648 となっていますが、 lngNumber を Win32 API の unsigned な引数に指定すれば DLL 内でちゃんと符号なし整数型の 2147483648 として処理されますので心配はいりません。
Dim lngNumber As Long Dim intNumber As Integer lngNumber = CLng("32768") '整数値文字列を Long 型に変換 If lngNumber > 32767 Then '32767 より大きい場合 intNumber = CInt(lngNumber - 65536) '65536 をマイナスし、Integer 型に変換 Else intNumber = CInt(lngNumber) End If逆に Win32 API が符号なし整数型を返してくることもあります。 でもそんな場合でも、逆に 4,294,967,296 をプラスするだけで OK ですね。
Dim lngTime As Long Dim dblTime As Double Dim strTime As String lngTime = GetTickCount 'GetTickCount は DWORD 値を返す If lngTime < 0 Then '戻り値が負の値の場合 dblTime = CDbl(lngTime) 'Double 型に変換 dblTime = dblTime + 4294967296# '4294967296 を加算 strTime = CStr(dblTime) '文字列に変換 Else strTime = CStr(lngTime) End If Debug.Print ; "システムが起動してから " & strTime & "ms 経過しました。"Integer 型の場合も同様にして 65,536(&H10000) をプラスしてもよいですが、 65,635(&HFFFF&) との論理積(And)を求めてやった方がスマートです。
Dim intNumber As Integer Dim lngNumber As Long intNumber = ReturnUShort 'ReturnUShort 関数は符号なし 16bit の値を返す(架空の関数) lngNumber = CLng(intNumber) And &HFFFF& 'Long 型に変換し、&HFFFF& との論理積を求める
GetWindowsDirectory などの、文字列をバッファに格納して返す関数は、
文字列の末尾に NULL 文字(vbNullChar)を付加して返し、文字列の終端を表現します。
C/C++ ならそのまま扱えますが、VB の可変長文字列に格納するには、
NULL 文字を削除してやらないと都合が悪いですね。
こんなところで書くまでもないかもしれませんが、一応私の使っている関数を載せます。
昔読んだ某 16bit 版 VB の解説書に載ってたサンプルを、32bit 用に書き換えたものです。
'----- TrimNull ----- '文字列より NULL 文字を検索し、最初に見つかった NULL より前までの '文字列を返します。 ' '引数 strTemp ' NULL 文字を含む文字列を指定。 ' '戻り値 ' NULL が取り除かれた文字列。 ' 見つからなかった場合、引数として渡した文字列をそのまま返します。 ' Public Function TrimNull(ByRef strTemp As String) As String Dim lngRet As Long lngRet = InStr(strTemp, vbNullChar) If lngRet Then TrimNull = Left$(strTemp, lngRet - 1) Else TrimNull = strTemp End If End Function |
バイト型配列に格納されている文字列から NULL 以下を削りたい場合は、 TrimNullBytes 関数をどうぞ(^^;
'----- TrimNullBytes ----- 'バイト型配列から NULL を検索し、NULL 以降を削ります。 ' '引数 bytArray() ' NULL を検索するバイト型配列を指定。結果もここに返されます。 ' '戻り値 ' NULL を取り除いたByte型配列のサイズを返します。 ' 引数 bytArray() の最初の要素が NULL である場合は 0 を返します。 ' Public Function TrimNullBytes(ByRef bytArray() As Byte) As Long Dim lngSize As Long '配列 bytArray() の初期配列要素最大値 Dim i As Long 'ループカウンタ lngSize = UBound(bytArray) + 1 'bytArray()のサイズを取得 For i = 0 To (lngSize - 1) Step 1 '配列の最後の要素までループ If bytArray(i) = &H0 Then 'NULL が見つかった場合 If i Then 'カウンタ i が 0 以外の場合 '配列サイズを NULL を発見した位置 -1 に削る ReDim Preserve bytArray(i - 1) TrimNullBytes = i '配列要素最大値を返す Exit Function Else 'カウンタ i が 0 の場合(いきなり NULL 発見) Exit Function End If End If Next i 'NULL が見つからなかった場合、配列要素最大値のみ返す TrimNullBytes = lngSize End Function |
処理の進行状況をあらわすことができるプログレスバーコントロールというものがありますが、
VB の標準コントロールではなく、Windows コモンコントロールの一部となっています。
プログレスバーを使うだけのために必要ランタイムが増えてしまうのは嫌ですね(^^;
ピクチャーボックスコントロールに四角形を描画することによって、
プログレスバーコントロールのような進行状況表示をすることができます。
Picture1.Line (0, 0)-(sngWidth, sngHeight), RGB(0, 0, &H80), BF
sngHeight にはピクチャーボックスの Height(縦幅) を指定します。sngWidth の値を増やすことによって、
進行状況表示バーが伸びていきます。割合とかは自分で考えてね(^^;
詳しいことは、ヘルプの「Line メソッド」などをお読み下さい。
なお、ピクチャーボックスの AutoRedraw プロパティが True になっていないと描画されません。
VB5以降なら、フォームの StartUpPosition プロパティを vbStartUpCenterScreen にしておくだけですが、 VB4には StartUpPosition プロパティはありません。でもまあ、ごく簡単なことです(^^;
Private Sub Form_Load() Me.Left = Screen.Width \ 2 - Me.Width \ 2 Me.Top = Screen.Height \ 2 - Me.Height \ 2 End Sub