読者です 読者をやめる 読者になる 読者になる

echo("備忘録");

IT技術やプログラミング関連など、技術系の事を備忘録的にまとめています。

VB6からVB.netに移植する際の注意点

.net Windows プログラミング 仕事 フリーエンジニア

なんか最近、急に感じるようになったんですが、1週間ってこんなにしんどかったっけ?
いや「精神的」になら、発病時&闘病中は死ぬほど感じてましたが、そうではなくて「肉体的」になんです。(むしろ精神的には、特に問題ないです。)

…単純に、年なんですかね。
あ~ヤダヤダ。(若いっていいなあ。)

とまあ、アラフォーおっさんの愚痴はこれぐらいにして、と。

今日「VB6のプログラムをVB.netに移植する」という業務があったんですが、そこでちょっとハマったので、備忘録的にメモ。

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 mojiretu_string As String = "あいうえお"
Dim mojiretu_byte As Byte()
mojiretu_byte  = System.Text.Encoding.GetEncoding("Shift_JIS").GetBytes(mojiretu)

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

Dim mojiretu_moto As String = ""
mojiretu_moto  = System.Text.Encoding.GetEncoding("Shift_JIS").GetString(mojiretu_byte)

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

Dim hairetsu(5) As string, max_index As integer
max_index = UBound(hairetsu)
Redim preserve hairetsu(10)

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

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

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

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

ですが、VB6では

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

んです。

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

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

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

max_index = hairetsu.length - 1

とすべきです。

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

VB.netの場合:要素は6つ → hairetsu.length - 1 = 5 ← OK!
他の言語の場合:要素は5つ → hairetsu.length - 1 = 4 ← OK!

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

前のXamarinの導入でも「VBは独自で、C#とかに慣れてると難しい」って書きましたが、まさにこういう所が難しいんですよねえ…
(この件について、Twitterなどで結構反響がありました。ありがとうございます。)