技術コラム

VB 6.0とVB.NETのちがい

VB 6.0とVB.NETを比較した場合の最大の違いは何か。冒頭でも触れたとおりそれは「構造化プログラミング」と「オブジェクト指向プログラミング」の違いとなる。

そもそもBASIC言語はFORTRANをベースに教育用に開発された手続き型(処理手順を基本としてアルゴリズムを記述するプログラミング言語。要するに問題解決をするために処理をシーケンシャルに継続的に記述する)の高級言語で、初心者でも容易にプログラミングを可能とすることを目的としていた。

1980年代に入りBASIC言語はパソコン用の主要言語となり、その後C言語などの構造化プログラミング(gotoレス、モジュール化、トップダウン設計などを基本概念とする)言語が台頭する中、同様の機能を実装しながら成長を遂げてきた。

Visual Basicはバージョン5.0の頃から「オブジェクト指向プログラミング」を(ある程度は)導入してきたが、VB.NETでは何が異なるのであろうか。それはクラスの導入による「カプセル化」および「継承」であり、クラス階層の「ポリモーフィズム」、さらにはこれらの機能により、より一層コードの再利用が可能となったことである。(というのは理論的なお話で...)プログラマ側から見た場合の違いとしては、VB.NETが自動生成するフォームを含め、すべてのコードがクラスに属することが上げられる。また、文法はVB6.0と変わりはないが、モジュールの論理構造およびコード再利用の概念は大幅に変更され、既存のVisual Basicプログラマ(C++、Javaなどのオブジェクト指向言語を知らない方)はかなり違和感を感じるであろう。見方を変えればVB.NETはMicrosoft社がVB6.0を派生させて開発した、新たな言語と捉えるべきであると筆者は考える。

データ型と値

整数型 (Integer) および長整数型 (Long)
VB6.0

長整数型(long)変数は32ビット符号付き数値、整数型(Integer)変数は16ビット符号付き数値として格納される。

VB.NET

長整数型(long)変数は64ビット符号付き数値、整数型(Integer)変数は32ビット符号付き数値、短整数型(short)変数は16ビット符号付き数値として格納される。32ビットシステムでは、16ビットまたは64ビットの整数演算より、32ビット整数演算の方が高速に処理される。

備考

変数の型が変更された。したがって、

Dim a As Integer
Dim b As Long

は、以下のようになる。

Dim a As Short
Dim b As Integer
文字列型(String)
VB6.0

可変型のテキスト文字列として動作する。そのため、追加、置換および削除などにより、その値を変更することができる。

VB.NET

不変型のテキスト文字列として動作する。Stringを変更すると、変更した値を保存するための新たなStringが生成され、元のStringは破棄される。なお、String型は参照型の変数であるため、実際はテキスト文字列が格納されているエリアのポインタが保存されている。

固定長文字列型
VB6.0

クラスモジュールのパブリック (Public) 変数以外の変数を固定長文字列として宣言できる。

VB.NET

現バージョンのCLRでは固定長文字列をサポートしていない。ただし将来のバージョンではサポートされる予定らしい。

通貨型 (Currency)
VB6.0

通貨型をサポートする。通貨型変数は64ビットの整数として格納される。数値は整数部15桁、小数部4桁で小数点が固定されており、10,000ずつ増減する。表示範囲は-922,337,203,685,477.5808 ~ 922,337,203,685,477.5807となる。

VB.NET

通貨型では切り上げに関するエラーを回避できる精度が提供されない。そのため固有のデータ型として10進型(Decimal)が追加された。

10進型変数は10のn乗に拡張された96ビット符号付き整数として格納される。10に累乗する値によって小数部の桁数を0 ~28の範囲で指定する。値が0の場合(小数点以下の桁数なし)、最大値は +/-79,228,162,514,264,337,593,543,950,335となる。小数点以下が28桁の場合、最大値は +/-7.9228162514264337593543950335、0でない最小値は +/-0.0000000000000000000000000001となる。

備考

通貨型は10進型に変更された。したがって、

Dim a As Currency

は、以下のようになる。

Dim a As Decimal
日付型 (Date)
VB6.0

日付型変数は倍精度浮動小数点数型 (Double) 形式で格納され、内部処理では倍精度浮動小数点数型として計算される。

日付型変数は、IEEE 64ビットの浮動小数点数として格納され、100 年 1 月 1 日から 9999 年 12 月 31 日 (日付)、および 0:00:00 ~ 23:59:59 (時刻) の範囲で表現される。

VB.NET

日付型変数は64 ビットの整数として格納されるため、倍精度浮動小数点数型変数として直接処理することはできない。.NETFrameworkでは、ToOADate関数およびFromOADate関数を使用して、倍精度浮動小数点数型と日付型の変換を行う。日付を整数で表すことで、日付処理の簡素化および高速化につながる

バリアント型
VB6.0

バリアント型は特殊な「共通」データ型で、固定長文字列を除くすべてのデータを含めることができる。

VB.NET

「共通」データ型としてオブジェクト型を使用する。バリアント型は柔軟ではあるが、暗黙の型変換時にバグを発生させる要因となるため廃止された。(異種言語による、開発時の混乱を避ける意味でもバリアント型は廃止となったらしい)。

備考

バリアント型はオブジェクト型に変更された。したがって、

Dim a As Variant

は、以下のようになる。

Dim a As Object
Type
VB6.0

Type ステートメントは、ユーザー定義型を作成する場合に使用する。

VB.NET

ユーザーはクラス、列挙、およびインターフェイスを定義することができる。また、CLRではあらゆるデータ型を対象に広い意味でタイプと呼ぶため、User-Defined Type(ユーザ定義型)は曖昧な位置づけとなってしまった。User-Defined Type はQuickBasicからの遺物でもあるため、VB.NETでは廃止され、TypeステートメントはStructureに変更された。

備考

Type ステートメントが構造体に変更されたため、

Type MyType
MyVariable As Integer
End Type

は、以下のようになる。

Structure MyType
    Dim MyVariable As Short
End Structure
Empty
VB6.0

バリアント型はEmpty値で初期化され、数式で使用される場合は0に、文字列式で使用される場合は空の文字列に自動変換される。

VB.NET

オブジェクト変数はNothingに初期化され、数式で使用される場合は0に、文字列式で使用される場合は空の文字列に自動変換される。空の代わりにNothingを使用することで、言語の複雑性が軽減され、相互運用性が向上する。

Null値
VB6.0

Null値はバリアント型のサブタイプで、有効なデータが含まれていない変数を示す。

VB.NET

ADO.NETを使用したプログラミングでは、値が抽出される前にNullのフィールドかをテストされる。Null値を含むバリアント型データは、オブジェクト タイプ DBNullとして CLR にマーシャリングされる。

変数宣言

宣言時の初期化
VB6.0

ローカル変数の宣言時に初期化はできない。

VB.NET

ローカル変数の宣言時に初期化ができる。

備考

ローカル変数の宣言時に初期化ができるように変更された。したがって、

Dim a As Integer
a = 1

は、以下のようになる。

Dim a As Integer = 1
変数の並列宣言
VB6.0

複数の変数を同時に宣言した場合、1番目の変数のみが指定した型となり、2番目以降はバリアント型となる。

VB.NET

複数の変数を同時に宣言した場合、すべての変数が指定した型となる。

備考

複数の変数を同時に宣言した場合、すべての変数が指定した型となるように変更された。したがって、

Dim a, b, c As Integer     ' aのみInteger 他はVariantとなる
' すべてをIntegerとするには以下のように記述する
Dim x As Integer, y As Integer, z As Integer

は、以下のようになる。

Dim a, b, c As Integer     ' すべてがIntegerとなる
宣言時のオブジェクト生成
VB6.0

Dim ... As New ...ステートメントにて、宣言時のオブジェクト生成は行われず、変数の使用時に生成が行われる。(使用箇所ごとにオブジェクトの存在確認が実行され、存在しない場合に生成する)

VB.NET

Dim ... As New ...ステートメントにて、宣言時にオブジェクトの生成が行われる。

ブロック内のローカル変数
VB6.0

ローカル変数の宣言が含まれている行からプロシージャ末尾まで、ローカル変数を参照することができる。

VB.NET

変数のブロック スコーピングがサポートされた。したがってローカル変数を参照できるのは、宣言が含まれる行から宣言が明示されるブロックの末尾までとなる。

Sub Test(a As Integer)
    If a < 0 Then
        Dim b As Integer = a
        ...
    Else
        ...
    End If
End Sub

上記の例の変数(b)は、宣言されているブロック内でのみ使用可能となる。(Elseステートメントの前まで)

配列

配列の定義
VB6.0

整数の上限または下限を指定して配列を定義することができる。範囲が宣言で指定されていない場合は、Option Baseステートメントを使用して下限が決定される。

VB.NET

他言語との相互運用性を有効にするために、すべての配列において下限を0に固定する。これによりOption Baseステートメントが不要となった。

備考

配列の下限が0固定になった。したがって、

Dim a(1 to 10) As String

は、以下のようになる。

Dim a(9) As String
ユーザ定義型
VB6.0

Typeキーワードを用いてユーザ定義型を作成する。

VB.NET

Typeキーワードは廃止され、ユーザ定義型として構造体を使用する。構造体には変数(データの保存)の定義とメソッド(コードの保存)の定義が可能となる。

備考
Private Type Mydata
    Name As String
    Age As Integer
End Type

は、以下のようになる。

Private Structure Mydata
    Public Name As String
    Public Age As Integer
    Public Sub setMydata(ByVal x As String, ByVal xx As Integer)
        Name = x
        Age = xx
    End Sub
End Structure

演算子

連結演算子

VB6.0にはなかった、連結演算子がVB.NETにサポートされた。これらの演算子はC++などにはすでにサポートされている。

VB 6.0     VB.NET

A = A + B   A += B

A = A - B   A -= B

A = A * B   A *= B

A = A / B   A /= B

A = A \ B   A \= B

A = A ^ B   A ^= B

A = A & B   A &= B

これらの演算子は変数に対して演算を実行後、その結果を元の変数に戻す。

論理演算子

VB6.0にはなかった、AndAlso演算子とOrElse演算子が追加された。これらの演算子はAndやOrを含む条件判断を効率よく行うことができる。

(1)AndAlso

VB6.0

If 条件式1 And 条件式2 Then

・・・・条件式1と条件式2を評価してからAnd演算をする

VB.NET

If 条件式1 AndAlso 条件式2 Then

・・・・条件式1の評価結果が偽の場合は条件式1は評価しない

(2)OrElse

VB6.0

If 条件式1 Or 条件式2 Then

    

・・・・条件式1と条件式2を評価してからOr演算をする

VB.NET

If 条件式1 OrElse 条件式2 Then

・・・・条件式1の評価結果が真の場合は条件式2は評価しない

プロシージャ

プロシージャの呼び出し
VB6.0

Callステートメントを使用する方法と、Callステートメントを使用しない方法の2種類の呼び出し形式がある。前者の場合は引数リストをカッコで囲む必要があり、後者の場合はカッコを省略する。

VB6.0では一般的に、Callステートメントを使用せずにプロシージャを呼び出す。この時、引数リストをカッコで囲んでいて、複数のパラメータが存在する場合はコンパイラが構文エラーを検出するが、パラメータが単一である場合はエラーとせず、そのパラメータをByRefではなくByValとして渡してしまう。これが原因で、トレースが難しいバグが発生することが多々ある。

VB.NET

どのような場合でも、引数リストをカッコで囲む必要がある。

Functionプロシージャの戻り値
VB6.0

呼び出し元に値を返すには関数名の代入で行う

VB.NET

関数名の代入の他にreturn文を使用する方法が追加されている。このため呼び出し元のプロシージャに返される値が、より直感的にわかるようになっている。

Private Function abc() As Integer
    Dim a As Integer
    ・・・・・・
    abc = a
End Function

は、以下のように記述することもできる。

Private Function abc() As Integer
    Dim a As Integer
    ・・・・・・
    return a
End Function
パラメータ渡し
VB6.0

ByValまたはByRefのどちらも指定しないパラメータは、デフォルトでByRef(参照渡し)に設定される

VB.NET

ByValまたはByRefのどちらも指定しないパラメータは、デフォルトでByVal(値渡し)に設定される。

ByRefではなくByValをデフォルトとすることにより、プロシージャにて呼び出し側より渡される変数を誤って変更してしまう問題を回避できる。

エラー処理
VB6.0

On Error ... ステートメントにてエラー動作の指示を行う。また、関数内にエラーハンドラを記述することもできる。

Sub Proc1
    On Error GoTo ErrProc
    ' エラーの起きそうな処理
    Exit Sub

    ErrProc:
        ' エラー処理コード
        Resume Next
End Sub
VB.NET

VB6.0と同様にVisual Basic固有の記述も可能であるが、「例外処理」を利用することもできる。

Sub Proc1
    Try
        ' エラーの起きそうな処理
    Catch
        ' エラー処理コード
    End Try
End Sub

△Vol.1 VB.NETについてへ戻る

2009年6月17日 17:24