連載

改訂版 プロフェッショナルVB.NETプログラミング

Chapter 04 演算子と関数の変化

株式会社ピーデー 川俣 晶
2004/04/01
Page1 Page2


 本記事は、(株)技術評論社が発行する書籍『VB6プログラマーのための入門 Visual Basic .NET 独習講座』の一部分を許可を得て転載したものです。同書籍に関する詳しい情報については、本記事の最後に掲載しています。

 ここでは、主に演算子と関数に関係するVB 6とVB.NETの相違点についてまとめてある。VB 6では関数であったものが、VB.NETではクラス・ライブラリの機能に移行しているものもあるが、それらも取り上げている。また、追加された便利な演算子などについても説明を行っている。なお、Visual Basic .NET 2003で追加されたシフト演算子は、本章ではなく本連載のPartVで解説を行っている。

関数がクラス・ライブラリ利用に変わる

 VB 6にはいくつかの数値関数が存在する。リスト4-1は、そのうちの主要なものを利用してみたプログラムである。

 1: Private Sub Form_Load()
 2:   Debug.Print Abs(-1)
 3:   Debug.Print Sin(0)
 4:   Debug.Print Cos(0)
 5:   Debug.Print Atn(0)
 6:   Debug.Print Tan(0)
 7:   Debug.Print Exp(1)
 8:   Debug.Print Log(1)
 9:   Debug.Print Round(1.1)
10:   Debug.Print Sqr(2)
11:   Debug.Print Sgn(-123)
12: End Sub
リスト4-1 主要な数値関数を使用したプログラム

 これを実行すると次のようになる。

 1:  1
 2:  0
 3:  1
 4:  0
 5:  0
 6:  2.71828182845905
 7:  0
 8:  1
 9:  1.4142135623731
10: -1
リスト4-2 リスト4-1の実行結果

 さて、これらの関数に相当する関数を、VB.NET自身は持っていない。その代わり、ほぼ同等のメソッド群が、クラス・ライブラリに含まれている。以下はそれを用いた例である。

 1: Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
 2:   Trace.WriteLine(Math.Abs(-1))
 3:   Trace.WriteLine(Math.Sin(0))
 4:   Trace.WriteLine(Math.Cos(0))
 5:   Trace.WriteLine(Math.Atan(0))
 6:   Trace.WriteLine(Math.Tan(0))
 7:   Trace.WriteLine(Math.Exp(1))
 8:   Trace.WriteLine(Math.Log(1))
 9:   Trace.WriteLine(Math.Round(1.1))
10:   Trace.WriteLine(Math.Sqrt(2))
11:   Trace.WriteLine(Math.Sign(-123))
12: End Sub
リスト4-3 リスト4-1と同等な、クラス・ライブラリのメソッドを用いたVB.NETのプログラム

 これを実行すると以下のようになる。

 1: 1
 2: 0
 3: 1
 4: 0
 5: 0
 6: 2.71828182845905
 7: 0
 8: 1
 9: 1.4142135623731
10: -1
リスト4-4 リスト4-3の実行結果

 ここで注目していただきたいポイントは2つある。1つは、関数名の先頭に“Math.”という文字が増えたこと。もう1つは、名前が変化した関数があることである。

 Mathとは、クラス・ライブラリに含まれるSystem.Mathクラスのことを意味する。この中に含まれる共有メソッド(インスタンスを作成せずに呼び出せるメソッドを参照)が、ここで使われているメソッド達である。System名前空間のクラスは、標準状態ではいちいち“System.”と前置きしなくても使用できるので、Mathだけで十分である。しかし、Mathは独立したクラスなので、通常は最低限のクラス名(Math)を明示しなければ、これらのメソッドを呼び出すことはできない。

 名前の変更は少々悩ましいが、これは名前の違いを覚えるしかないだろう。「Sqr」が「Sqrt」、「Sgn」が「Sign」など、まったくかけ離れた名前に変わっているわけではないので、一度慣れてしまえば混乱することはないだろう。

 なお、Mathクラスのメンバは以下のとおりである。このほかに2つの定数、E(自然対数)、PI(π)も含まれる。

Abs Ceiling IEEERemainder Pow Tan
Acos Cos Log Round Tanh
Asin Cosh Log10 Sign Sqrt
Atan Exp Max Sin
Atan2 Floor Min Sinh
▼表4-5 Mathクラスのメンバ
 
B系とW系の文字列関数

 VB 6の文字列処理関数には、同じ機能を持つものに3種類のバリエーションが存在する。すべての文字列処理関数が3種類のバリエーションを持っているわけではないが、バリエーションごとに分けて理解するとわかりやすいだろう。

 例えば、Asc関数の場合、Asc、AscB、AscWというバリエーションが存在する。つまり、「何も付かない」「Bが付く」「Wが付く」という3つのバリエーションが存在する。何も付かないものは、文字を標準的な方法で扱う。Bが付くものは、文字をバイト単位で扱う。Wが付くものは、文字をUnicodeベースで扱う。

 以下はこれらの関数を使用した例である。

 1: Private Sub Form_Load()
 2:   Debug.Print Len("あ")
 3:   Debug.Print LenB("あ")
 4:
 5:   Debug.Print Asc("あ")
 6:   Debug.Print AscB("あ")
 7:   Debug.Print AscW("あ")
 8:
 9:   Debug.Print InStr("アイウエオ", "ウ")
10:   Debug.Print InStrB("アイウエオ", "ウ")
11:
12:   Debug.Print Mid("アイウエオ", 3, 2)
13:   Debug.Print MidB("アイウエオ", 3, 2)
14:
15:   Debug.Print Left("アイウエオ", 2)
16:   Debug.Print LeftB("アイウエオ", 2)
17:
18:   Debug.Print Right("アイウエオ", 2)
19:   Debug.Print RightB("アイウエオ", 2)
20:
21:   Debug.Print String(10, "A")
22:
23: End Sub
リスト4-6 複数のバリエーションを持つ文字列処理関数を使用したプログラム

 これを実行すると以下のようになる。

 1:  1
 2:  2
 3: -32096
 4:  66
 5:  12354
 6:  3
 7:  5
 8: ウエ
 9:
10: アイ
11:
12: エオ
13:
14: AAAAAAAAAA
リスト4-7 リスト4-6の実行結果

 リスト4-6の2〜3行目では、2行目のLen関数は素直に“あ”は1文字であると判定している。しかし、3行目のLenB関数は、文字列をシフトJISに変換した状態で“あ”の1文字は2Bytes占有すると判断して“2”という値を結果としている。

 5〜7行目のAsc、AscB、AscW関数は、それぞれ“あ”のシフトJISによるコード、“あ”のシフトJISによるコードの下位バイトのみ、“あ”のUnicodeの番号を返している。

 9行目は“アイウエオ”の中で“ウ”は3文字目であるから、素直に“3”という結果になっている。しかし、10行目では“ウ”の位置はシフトJISのバイト数換算で5Bytes目(1から数えているため。0から数えれば4Bytes目)であるとして、“5”を結果としている。

 12行目では“アイウエオ”の3文字目から2文字ということで、素直に“ウエ”が結果となる。しかし、13行目では3Bytes目から2Bytesということで、“イ”の1文字が結果となる。15〜19行目も同様である。

 21行目は、VB.NETに直接対応する関数が存在しないのでここに書いてみたもので、特に難しいことはない。

 なお、ここで念のために付記しておけば、VB 6の文字列は内部的にはUnicodeで管理されており、文字列の長さや位置は、Unicodeを基準に扱われている。しかし、Asc関数やChr関数は例外的にシフトJISを基準としており、Unicodeで処理するにはWの付いた関数を使わねばならない。つまり、文字列中に保持できる文字のバリエーションは、シフトJISで表現できる文字のバリエーションよりも多く、そのため、文字列変数に含まれているすべての文字が、Asc関数で文字コードに変換できるとは限らないということである。もちろん、AscW関数を使えば可能である。

 さて、これとできるだけ同等になるようにVB.NETで記述したプログラムがリスト4-8である。

 1: Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
 2:   Trace.WriteLine(Len("あ"))
 3:   'Trace.WriteLine(LenB("あ"))
 4:
 5:   Trace.WriteLine(Asc("あ"))
 6:   'Trace.WriteLine(AscB("あ"))
 7:   Trace.WriteLine(AscW("あ"))
 8:
 9:   Trace.WriteLine(InStr("アイウエオ", "ウ"))
10:   'Trace.WriteLine(InStrB("アイウエオ", "ウ"))
11:
12:   Trace.WriteLine(Mid("アイウエオ", 3, 2))
13:   'Trace.WriteLine(MidB("アイウエオ", 3, 2))
14:
15:   Trace.WriteLine(Microsoft.VisualBasic.Left("アイウエオ", 2))
16:   'Trace.WriteLine(LeftB("アイウエオ", 2))
17:
18:   Trace.WriteLine(Microsoft.VisualBasic.Right("アイウエオ", 2))
19:   'Trace.WriteLine(RightB("アイウエオ", 2))
20:
21:   Trace.WriteLine(New String("A", 10))
22:
23: End Sub
リスト4-8 リスト4-6と同等のVB.NETのプログラム

 これを実行すると次のようになる。

1: 1
2: -32096
3: 12354
4: 3
5: ウエ
6: アイ
7: エオ
8: AAAAAAAAAA
リスト4-9 リスト4-8の実行結果

 まず、Bが付く関数が消滅してしまったことが分かる。消滅してしまったものは、コメントアウトしてある。残っているのは「何も付かない」「Wが付く」という2つのバリエーションだけである。しかし、残された関数の動作は、VB 6と互換性を持っていることが分かると思う。もし、Bが付く関数を活用していた場合はVB.NETへの移行が面倒になるかもしれないが、そうでなければ、スムーズに移行できるだろう。

 ただし、VB 6と同じ動作をしているということから分かるように、Asc関数がシフトJISのコードを返すという点に注意が必要である。つまり、文字列に含まれる文字をAsc関数で数値化して、Chr関数で文字に戻した場合、シフトJISでは表現できない文字があるために、元の文字に戻らない可能性があるということである(シフトJISとUTF-8の相違を参照)。これを回避するには、AscWとChrWを使えば問題はない。

 さて、最後のソース21行目に注目していただきたい。VB 6のString関数は、VB.NETには存在しない。その代わり、Stringクラスのコンストラクタを用いることができる。Stringクラスのコンストラクタには多数のバリエーションがあり、さまざまな初期条件を持った文字列を生成することができる。そのバリエーションの中に、ある文字を指定文字数だけ繰り返した文字列を生成する機能がある。コンストラクタの第1引数に文字を、第2引数に繰り返す数値を指定すれば、数値の数だけ文字が並んだ文字列が生成される。


 INDEX
  [連載] 改訂版 プロフェッショナルVB.NETプログラミング
  Chapter 04 演算子と関数の変化
  1.関数がクラス・ライブラリ利用に変わる/B系とW系の文字列関数
    2.Eqv演算子とImp演算子/AndAlso演算子とOrElse演算子/名前に$が付く文字列関連関数と付かない関数
 
「改訂版 プロフェッショナルVB.NETプログラミング 」


Insider.NET フォーラム 新着記事
  • 第2回 簡潔なコーディングのために (2017/7/26)
     ラムダ式で記述できるメンバの増加、throw式、out変数、タプルなど、C# 7には以前よりもコードを簡潔に記述できるような機能が導入されている
  • 第1回 Visual Studio Codeデバッグの基礎知識 (2017/7/21)
     Node.jsプログラムをデバッグしながら、Visual Studio Codeに統合されているデバッグ機能の基本の「キ」をマスターしよう
  • 第1回 明瞭なコーディングのために (2017/7/19)
     C# 7で追加された新機能の中から、「数値リテラル構文の改善」と「ローカル関数」を紹介する。これらは分かりやすいコードを記述するのに使える
  • Presentation Translator (2017/7/18)
     Presentation TranslatorはPowerPoint用のアドイン。プレゼンテーション時の字幕の付加や、多言語での質疑応答、スライドの翻訳を行える
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)
- PR -

注目のテーマ

業務アプリInsider 記事ランキング

本日 月間
ソリューションFLASH