技術ブログ

【VB6マイグレーション】LenB, StrConv, vbFromUnicode

以下のように直しましょう。

intRet = LenB(StrConv(objVal, vbFromUnicode)
↓
intRet = VBStrings.LenB(StrConv(objVal, VbStrConv.None)
Option Strict On

''' <summary>
''' Microsoft.VisualBasic.Strings をカバーした静的クラスです。
''' </summary>
Public Class VBStrings

#Region "文字列のバイト数を取得する"
    ''' <summary>
    ''' 半角 1 バイト、全角 2 バイトとして、指定された文字列のバイト数を返します。
    ''' </summary>
    ''' <param name="stTarget">バイト数取得の対象となる文字列。</param>
    ''' <returns>半角 1 バイト、全角 2 バイトでカウントされたバイト数。</returns>
    Public Shared Function LenB(stTarget As String) As Integer
        Return Text.Encoding.GetEncoding("Shift_JIS").GetByteCount(stTarget)
    End Function
#End Region

End Class

1.StrConv()関数
VB6の「StrConv()」関数の第2引数には色々引数を指定できますが、VB6の「vbFromUnicode」はVB.NETでは使えなくなっています。
https://msdn.microsoft.com/ja-jp/library/cc437757(v=vs.71).aspx

じゃあどうやるのかと言えば、System.Text名前空間の「Encoding」クラスを使って、まずByte型の配列にして、(日本語を扱いたい場合、先にGetEncoding()メソッドでシフトJIS対応のEncodingオブジェクトを取得する必要がある。)

Dim strVal As String = "あいうえお"
Dim strBytes As Byte()
strBytes = System.Text.Encoding.GetEncoding("Shift_JIS").GetBytes(strVal)

それからGetString()関数を使って、文字列に戻してあげればOK。

Dim strSource As String = ""
strSource = System.Text.Encoding.GetEncoding("Shift_JIS").GetString(strBytes)

2.配列の扱い
移植対象のソースの中に、こんな処理があって、

Dim strArray(5) As String, intMax As Integer
intMax = UBound(strArray)
ReDim Preserve strArray(10)

「VB.NETは配列のインデックスは0始まり固定って事は、他の言語(C#とかJavaとか)と共通になったんだから、intMaxは4だな。」って感じでソースを修正してたんですが…
いざデバッグすると、何度やっても、何をやっても期待した動きをしない。

最初、何が原因か分からず、結構ハマってたんですが…
まあ、原因は言うまでもなく「UBound(strArray)」の値です。

他のほとんどの言語(C#とかJavaとか)だと、例えば「strArray(5)」って定義したら、

strArray(0)~strArray(4)の5個の要素が作成される。

ですが、VB6では

strArray(0)~strArray(5)の6個の要素が作成される。

んです。

で、VB.NETはというと、VB6の仕様を継承しています。(多分、互換性の関係なんでしょうね。)
だから、intMaxは「4」ではなく「5」なんです。

…という「VBとC#は似てるっていうけど、過信すると痛い目にあうよ」というお話でした。

※ちなみに、VB独自の仕様に関係ないソースにするならば、配列の「Length」プロパティを使い、

intMax = strArray.Length - 1

とすべきです。

これなら、strArray(5)の場合

VB.NETの場合:要素は6つ → strArray.Length – 1 = 5 ← OK!
他の言語の場合:要素は5つ → strArray.Length – 1 = 4 ← OK!

となり、どちらの場合も正常に動作します。
(極力.NETや他の言語と共通のコードにしたほうが無難、ってことでしょうね。)


参照:

コメント