Visual Basic テクニック
VB.NET2002対応 VB.NET2003対応 VB2005対応 VB2008対応

 

Visual Basic 中学校 > テクニック >

C#のサンプルコードをVBで活用する

 

インターネットで検索したらサンプルがC#でがっかりしたという経験はありませんか?今回はC#のサンプルコードをVBで活用する方法を説明します。具体的にはそのためにC#からVBの翻訳のポイントを説明し、最後は実際に翻訳を行ってみます。

概要

・C#とVBは兄弟言語なので、C#のサンプルをVBに翻訳するのは難しくない。

・機械的な作業でも8割くらいは翻訳ができる。あとの2割はピンポイントでつぶす。

・キーワードや構文の翻訳早見表

・具体的な翻訳例

1.なぜC#のサンプルが必要か?

 

VBとC#(読み方:C# = シーシャープ)は兄弟といっていい言語で、言語としての構造や考え方が似ているだけではなく、使用するクラスやフレームワークまで同じです。厳密には.NET Frameworkを使用しないC#というものもあり得るのかもしれませんが現実的にはこの可能性は無視できます。

こういう状況ですから、VBについてわからないことがあって調べ物をするときに、実はC#の情報がとても役に立ちます。

みなさんは経験がないでしょうか?クラスやメソッドの使い方がわからずインターネットで検索してみたらC#のサンプルが見つかったが、VBのサンプルが見つからないというようなことが?

そのときみなさんはどうしていましたか?VBではないのであきらめていたでしょうか?

今回はこのような状況でもC#のサンプルをVBのために役立てる方法を説明します。いくつか覚えることはありますが簡単なことです。

やろうとしているのはC#で書かれたプログラムを簡単にVBに翻訳することです。

 

2.VBプログラマからみたときのC#の特徴

 

VBとC#は基本が一緒ですので、VBである程度のプログラム経験があればC#をゼロから勉強する必要はありません。ここでは知っておくべきいくつかのC#の言語的な特徴をあげて、後で具体例を見ていくことにします。

なお、今回の説明ではC#のコードの9割程度をVBに翻訳できる情報量を目指しています。さすがに10割翻訳するためにはもっと修練を積む必要があります。

特徴1.行末に 「;」(セミコロン) がつく。「;」を付けなければ単語の区切りで自由に改行して良い。

VBでは1行1命令のような構造になっていて、どうしても改行を入れたければ「 _」を記述する必要がありますが、C#では逆で「;」をつけるまでが1命令で、改行は単語の区切りであれば自由です。

たとえば、次のbutton1のフォントと文字を変更するプログラムを見てください。

C#対応

button1.Font = new Font(this.Font.FontFamily, 12, FontStyle.Bold);
button1.Text =
"フォント変更!";

■リスト1:C#でのフォントの変更の例

途中に出てくるthisはVBで言うとMeです。

この例を改行して次のように書くこともできます。

C#対応

button1.Font = new Font(this.Font.FontFamily,
12,
FontStyle.Bold);
button1.Text =
"フォント変更!";

■リスト2:C#では複数行にわたって自由に書くことができる。

長いコードを改行したいときはよくありますが、このように自由に改行できるのはC#のいいところです。

 

特徴2.変数を宣言するとき型名を前に書く。

たとえば、VBでは変数を宣言したり使用するときは以下のような書き方をします。

VB.NET2003対応 VB2005対応 VB2008対応

Dim count As Integer
Dim message As String

For i As Integer = 0 To Me.Controls.Count - 1
   
'何かの処理
Next

■リスト3

これと同じ意味のC#のプログラムは次のようになります。

C#対応

int count;
string message;

for
(int i = 0; i <= this.Controls.Count - 1; i++)
{
    //何かの処理
}

■リスト4

forの書き方がVBと違いますが、これは後で説明します。変数の宣言部分に着目するとDimAsがとれて型名が前に来るという法則になっていることがわかります。

ただし、型名も微妙にことなっており、VBのIntegerはC#のintStringstringになっています。もっともstringに関しては.NET Frameworkのクラス名がStringなのでStringでも通用します。

この法則にしたがって関数の宣言も次のようになります。

C#対応

public int GetProductCount(string productCode)
{
    //何かの処理
}

■リスト5

これと等価なコードをVBで書くとすると次のようになります。

VB6対応 VB.NET2002対応 VB.NET2003対応 VB2005対応 VB2008対応

Public Function GetProductCount(ByVal productCode As String) As Integer
    '何かの処理
End Function

■リスト6

見事に型を指定する部分が前から後になっていることがわかります。

こういう事情なのでC#ではDimとかFunctionとかSubのようなキーワードはつけません。後で説明しますがSubのときは特殊な型であるvoidを使用します。

 

特徴3.ブロック構造は { } (中カッコ)で表現する。

VBではブロック構造を表現するのに、If End IfFunctionEnd FunctionClassEnd Classのように対応するEnd ○○を付けますが、C#ではそれも { と } で表現します。そのため、入れ子が深くなるとどの } が何の終わりなのかVB以上にわかりにくくなってしまいますが・・・。

 

特徴4.コメント行は // ではじめる。また、/* と */ で囲まれたブロックはまるごとコメントになる。

「//」についてはVBの「'」と同等です。「/* 〜 */」はVBにはない機能でブロックを丸ごとコメントにできます。

10年前にVBにも選択範囲をまるごとコメントにするツールバーのアイコンが追加されたので、ブロックコメントがなくても不便は感じなくなりましたが、それ以前はVBはブロックまるごとコメントにするためにはい行ずつ「'」をつけなくてはいけなかったのでかなり面倒でした。そのときはまだC#はありませんでしたが、前身となるCにも同じブロックコメント機能があったのでうらやましく感じたものです。

C#対応

public int GetProductCount(string productCode)
{
    /*
    こうやって書くとこの部分は
    何行でもコメントになるんですね!
    string message = "これはコメントです!";
    */
}

■リスト7:C#のブロックコメント

 

特徴5.メソッドの呼び出しには必ず ( ) をつける。引数がなくてもつける。

VBでは引数がないメソッドの呼び出しは( )をつけなくてもいいのですが、C#ではだめです。

たとえば、変数の型名を取得する以下のVBのプログラムは有効です。

VB.NET2002対応 VB.NET2003対応 VB2005対応 VB2008対応

Dim count As Integer = 3
Dim message As String

message = count.GetType.FullName

MessageBox.Show(message)

■リスト8

このプログラムではGetTypeメソッドをかっこなしで呼び出しています。かっこをつけても構いません。VBではどちらの書き方もできます。

しかし、C#では必ずかっこをつける必要があります。

C#対応

int count = 3;
string message;

message = count.GetType().FullName;

MessageBox.Show(message);

■リスト9

FullNameはプロパティなのでかっこをつけません。

 

ここでいうメソッドにはコンストラクタも含まれることに注意してください。VBのプログラマは引数なしでNewが使用できるとき ( ) をつけないことが多いですが、C#の世界では必ず ( ) をつけます。

 

特徴6.変数が等しいか調べる演算子は「=」ではなくて「==」

VBメインでためにC系の言語をいじるようなプログラマはわかっていてもついつい == を = を書いてしまいます。

よくよく考えるとVBの「=」には代入と比較の2つの意味があるのですが、C#の「=」には代入の意味しかなく、比較する場合は「==」を使います。これは主にif文の中で問題になります。

次のプログラムはフォームに配置されているコントロールの数を数えるVBのプログラムです。もし、コントロールの数が1個だけならばメッセージを表示します。

VB.NET2002対応 VB.NET2003対応 VB2005対応 VB2008対応

Dim count As Integer
count = Me.Controls.Count

If count = 1
Then
    MessageBox.Show("コントロールが1つしかありませんね!")
End
If

■リスト10

このプログラムでは = が2つ登場しますが、最初の = は代入、次の = は比較の意味で使用しています。

これと等価なプログラムをC#で書くと次のようになります。

C#対応

int count;
count =
this.Controls.Count;

if (count == 1)
{
    MessageBox.Show("コントロールが1つしかありませんね!");
}

■リスト11

 

特徴7.配列やコレクションの要素にアクセスするときは ( ) ではなく [ ] を使う。

C#ではメソッドの呼び出しはVBと同じで ( ) を使うのですが、配列やコレクションの要素にアクセスするときはVBでは ( ) を使うところが [ ] になります。

たとえば、以下のプログラムはVBで記述したものです。

VB2005対応 VB2008対応

Dim names As New List(Of String)

names.Add(
"アメンボ")
names.Add(
"イノシシ")
names.Add(
"ウマ")

Dim
secondName As
String
secondName = names(1)

MessageBox.Show(secondName)

■リスト12

これと等価なプログラムをC#で書くと次のようになります。

C#対応

List<string> names = new List<string>();

names.Add(
"アメンボ");
names.Add(
"イノシシ");
names.Add(
"ウマ");

string secondName;
secondName = names[1];

MessageBox.Show(secondName);

■リスト13

 

特徴8.大文字と小文字を区別する。

これまでの例ですでに気がつかれたと思いますが、C#では大文字と小文字を厳密に区別します。たとえば、C#ではCountcountは違う変数です。

また、構文でも if と書くところを If と書くことはできません。

単純なことですが重要な違いなので注意です。

特に昔堅気のプログラマは型名を小文字にした変数名を使ったりします。VBに翻訳するときはなんか工夫する必要があるかもしれません。

 

特徴9.コンストラクタを作るのはSub Newではなくクラス名を同じ名前のメソッド

VBでは自作のクラスのコンストラクタを作るにはNewという名前のSubプロシージャを定義しますが、C#ではクラスメイト同じ名前で戻り値の指定がないプロシージャがコンストラクタになります。

たとえば、VBで以下のようなコンストラクタを書いたとします。

VB.NET2002対応 VB.NET2003対応 VB2005対応 VB2008対応

Public Class TestClass

    Dim
X As
Integer

   
Public Sub New()
        X = 100
    End
Sub

End
Class

■リスト14

これと等価なプログラムはC#では以下のとおりです。

C#対応

public class TestClass
{
   
int X;

   
public TestClass()
    {
        X = 100;
    }

}

■リスト15

 

3.キーワード・記号翻訳早見表

 

C#のキーワードや記号のVBでの翻訳例を表にまとめておきます。必要に応じて参照してください。

  C# C#対応 VB VB.NET2002対応 VB.NET2003対応 VB2005対応 VB2008対応
コメント // '
ブロックコメント /* */ (該当なし)
範囲内のすべての行頭に ' を付ける。
XMLコメント /// '''
継承 public class MyCollection : System.Collections.ArrayList Public Class MyCollection
   
Inherits System.Collections.ArrayList
コレクションの要素へのアクセス [ ] ( )
三項演算子 s = x==0 ? "OK" : "NG"; s = IIf(x = 0, "OK", "NG")
比較演算子 == =
否定 ! Not
非等値演算子 != <>
加算演算子 ++ += 1

※ただし、使用できる場所が違うのでそのまま置き換えられない。C#の「i++」と「++i」は加算するタイミングが違うので要注意。

減算演算子 -- -= 1

(上の項目の説明を参照)
反照代名詞 this Me
条件分岐 switch Select Case
ジェネリック < >
例:
List<string> names = new List<string>();
(Of )
例:
Dim names As New List(Of String)
名前空間 using Imports
Null参照 null Nothing
戻り値なし void (該当なし)
基本的にすべてのvoidを削除する。
共有メンバ static Shared
参照渡し ref ByRef

 

 

4.構文翻訳早見表

 

C#とVBは構文も似ています。C#にもif文やdoループなどがありますが、書き方が少し違うので、代表的なものだけまとめておきます。こういった点は必要に応じて見ればよいので、神経質にならなくてもよいでしょう。MSDNライブラリのC#リファレンスも参考になります。

ここではC#のコードを等価なVBのコードに置き換える例を示すだけでC#のコードやキーワードの意味・使用方法までは踏み込まないことにします。

  C# C#対応 VB VB.NET2002対応 VB.NET2003対応 VB2005対応 VB2008対応
if if (X == 1)
    Y = 0;
else if (X == 2)
    Y = 1;
else
   
Y = 3;
If X = 1 Then
   
Y = 0
ElseIf X = 2
Then
   
Y = 1
Else
   
Y = 3
End
If
if
(複数行の場合)
if (X == 1)
{
    Y = 0;
    Z = 0;
}
else
{
    Y = 3;
    Z = 1;
}
If X = 1 Then
   
Y = 0
    Z = 0
Else
   
Y = 3
    Z = 1
End
If
switch switch (X)
{
    case 0:
        MessageBox.Show("0です。");
       
break;
   
case 1:
        MessageBox.Show("1です。");
       
break;
   
default:
        MessageBox.Show("その他です。");
       
break;
}
Select Case X
    Case 0
        MessageBox.Show(
"0です。")
   
Case 1
        MessageBox.Show(
"1です。")
    Case
Else
       
MessageBox.Show("その他です。")
End
Select

 

for for (int i = 0; i < 3; i++)
   
MessageBox.Show(i.ToString());
For i As Integer = 0 To 2 '注意:「2」になる
    MessageBox.Show(i.ToString)
Next
for
(複数行の場合)
for (int i = 0; i < 3; i++)
{
    string message = "現在値は" + i.ToString();
   
MessageBox.Show(message);
}
For i As Integer = 0 To 2 '注意:「2」になる
    Dim message As String = "現在値は" & i.ToString
    MessageBox.Show(message)
Next
for
(--の場合)
for (int i = 2; i >= 0; i--)
   
MessageBox.Show(i.ToString());
For i As Integer = 2 To 0 Step -1
    MessageBox.Show(i.ToString)
Next
foreach foreach (Control item in this.Controls)
{
   
MessageBox.Show(item.Name);
}
For Each item As Control In Me.Controls
    MessageBox.Show(item.Name)
Next
try try
{
   
decimal d = 0;
    d = 1 / d;
}
catch (Exception ex)
{
    MessageBox.Show(ex.ToString(), "例外発生");
}
finally
{
    MessageBox.Show("こんにちは。");
}
Try
    Dim d As Decimal = 0
    d = 1 / d
Catch ex As Exception
    MessageBox.Show(ex.ToString(),
"例外発生")
Finally
   
MessageBox.Show("こんにちは。")
End
Try

 

void private void ProcessSomething(int X)
{

}
Private Sub ProcessSomething(ByVal X As Integer)
End
Sub

 

 

5.それで…?

 

文章で表現すると長くなってしまいましたので、C#からVBに翻訳するときの方針を簡単にまとめておきます。

手順1.まずはコメントを翻訳します。つまり、 // や /* */ を ' に置き換えます。

手順2.; セミコロンをとります。このとき、C#で改行されている個所をVB流に「 _」を付けるか1行にまとめるかします。

手順3.宣言をなおします。つまり、int X見たいになっている部分を Dim X As Integerのように書き換えます。

このとき、宣言の中にあるvoidは削除します。関数の場合はvoidの部分にsubを入れます。

手順4.ジェネリックを翻訳します。つまり、<型名>が使われている個所を(Of 型名)にします。

手順5.ブロック構造を翻訳します。つまり、if { } for { }などを IfEnd IfForNextなどに書き換えます。

手順6.構文を翻訳します。ifforforeachなどの構文をVBに翻訳します。

手順7.細かいところを直します。つまり、thisMeにしたり、[ ] を ( ) にしたりします。

この段階で翻訳作業の8割は完了です。ほとんど機械的にできます。

あとは、残っている部分を個別につぶしていきます。MSDNやインターネットで調べる必要があるかもしれません。

 

6.具体例:VBでIEからイベントを受け取る

 

それでは、最後に具体例としてIEからイベントの通知を受け取るプログラムをVBで作成してみます。

すでにC#のサンプルコードを入手しているという仮定で、VBに翻訳してみましょう。

このC#のクラスは、RunメソッドでIEを開いてホームページを表示します。そして、ユーザーがリンクをクリックするなどして別のページに移るとNavigateCompletedイベントを発生させます。本当はもっといろいろなイベントや情報が取得できるのですが、翻訳の練習ということで簡単な機能だけに絞りました。

このプログラムを実行するにはC#でもVBでもCOMオブジェクトの「Microsoft Intenet Controls」への参照設定が必要になります。

それから、Vistaで使用する場合はIE7の保護モードをオフにする必要があります。[ツール]メニューの[インターネット オプション]でセキュリティ画面を表示させて、インターネットゾーンと、ローカルイントラネットゾーンの保護モードをオフにしてください。ただし、この設定をするとセキュリティ上問題があるかもしれないので気を付けてください。実験が終わったら元に戻してください。

さて、C#のコードは次のようなものです。このコードはMSDNライブラリに載っていたものを私が機能を削ってシンプルにしたものです。

C#対応

namespace IEOperation
{
    using System;
   
using System.Runtime.InteropServices;
   
using SHDocVw;

   
public class Explorer
   
{
        static private SHDocVw.InternetExplorer m_IExplorer = null;
        static private IWebBrowserApp m_WebBrowser = null;

        public
delegate void NavigateCompletedHandler(object sneder,EventArgs e);
        public event NavigateCompletedHandler NavigateCompleted;

        public
void Run()
        {
           
//■「Navigate Complete」を取得できるように構成
           
m_IExplorer = new SHDocVw.InternetExplorer();

            if
(m_IExplorer == null)
                return;

           
//1.Navigate Complete event
           
DWebBrowserEvents2_NavigateComplete2EventHandler ncd
                          = new DWebBrowserEvents2_NavigateComplete2EventHandler(OnNavigateComplete);
            m_IExplorer.NavigateComplete2 += ncd;

            //■IEを開いてホームページを表示

       
    try
       
    {
                m_WebBrowser = (IWebBrowserApp)m_IExplorer;
                m_WebBrowser.Visible = true;
                m_WebBrowser.GoHome();
            }
            catch (Exception sE)
            {
            }
        }

       
//ページが遷移したとき NavigateCompletedイベントを発生させる。
       
public void OnNavigateComplete(Object o1, ref Object o2)
        {
            NavigateCompleted(this,null);
        }

}
}

■リスト16:C#版の完全なコード

VBに移植するために、まずはVBのプロジェクトを作成しましょう。今回はWindowsアプリケーションを使用することにします。名前はC#のコードの名前空間が「IEOperation」になっているのでそれをそのまま使うことにします。別に違う名前を付けたければそれでも構いません。

それから、参照設定でさきほどの「Microsoft Internet Controls」への参照の追加も忘れないでください。これはCOMですので、.NETの一覧には表示されていません。ページをCOMに切り替えてから探してください。

プロジェクトにExplorerというクラスを追加しましょう。このクラスの名前はC#のサンプルコードの中のクラス名から採りました。これも好きな名前にしておいてもよいのですが、クラス名レベル以下は混乱を避けるために同じ名前に翻訳することをお勧めします。

ExplorerクラスにはVBが自動生成する何行かのコードは削除してC#のコードをそのまま貼り付けてしまってください。

いっぱいエラーがでますが当然ですね。

さぁ、いよいよ翻訳スタートです。まずはさきほどの手順1から片づけましょう。つまり、コメント行を ' に変えます。それから手順2のセミコロン除去作業と複数行まとめ作業もやってしまいましょう。

ここまでで次のようになります。

Namespace IEOperation
{
    using System
   
using System.Runtime.InteropServices
   
using SHDocVw

   
Public Class Explorer
    {
       
static private SHDocVw.InternetExplorer m_IExplorer = null
       
static private IWebBrowserApp m_WebBrowser = null

       
public delegate void NavigateCompletedHandler(object sneder,EventArgs e)
       
public event NavigateCompletedHandler NavigateCompleted

       
public void Run()
        {
           
'■「Navigate Complete」を取得できるように構成
           
m_IExplorer = new SHDocVw.InternetExplorer()

           
if (m_IExplorer == null)
               
return

           
'1.Navigate Complete event
           
DWebBrowserEvents2_NavigateComplete2EventHandler(ncd) = new DWebBrowserEvents2_NavigateComplete2EventHandler(OnNavigateComplete)

            m_IExplorer.NavigateComplete2 += ncd

            '■IEを開いてホームページを表示

           
try
           
{
                m_WebBrowser = (IWebBrowserApp)m_IExplorer
                m_WebBrowser.Visible =
true
               
m_WebBrowser.GoHome()
            }
           
catch (Exception sE)
            {
            }

        }

       
'ページが遷移したとき NavigateCompletedイベントを発生させる。
       
public void OnNavigateComplete(Object o1, ref Object o2)
        {
            NavigateCompleted(this,null)
        }
    }
}

■リスト17:手順1.コメント、手順2.セミコロン除去を実行した段階

インデントは私が少し整えましたが、本物はもっと乱れているはずです。

真ん中あたりにあるDWebBrowserEvemt2...という長い行はC#では2行になっていますが、VBではまとめて1行にしてしまいます。長いのが嫌いな人は「 _」を使用して2行にわけたままでもかまいません。

このくらいではまだVBのプログラムの感じがしませんね。

 

次は手順3に従って宣言を直します。ジェネリックはないので手順4は飛ばして、手順5のブロック構造のVB化もやってしまいましょう。

Namespace IEOperation

   
using System
   
using System.Runtime.InteropServices
   
using SHDocVw

   
Public Class Explorer
 
       
Private Static m_IExplorer As SHDocVw.InternetExplorer = null
       
Private Static m_WebBrowser As IWebBrowserApp = null

       
Public Delegate Sub NavigateCompletedHandler(ByVal sneder As Object, ByVal e As EventArgs)
       
Public Event NavigateCompleted As NavigateCompletedHandler

       
Public Sub Run()

           
'■「Navigate Complete」を取得できるように構成
           
m_IExplorer = New SHDocVw.InternetExplorer()
           
if (m_IExplorer == null)
               
Return
           
End If

           
'1.Navigate Complete event
           
Dim ncd As DWebBrowserEvents2_NavigateComplete2EventHandler = New DWebBrowserEvents2_NavigateComplete2EventHandler(OnNavigateComplete)

            m_IExplorer.NavigateComplete2 += ncd

           
'■IEを開いてホームページを表示

           
Try
               
m_WebBrowser = (IWebBrowserApp)m_IExplorer
                m_WebBrowser.Visible =
True
               
m_WebBrowser.GoHome()
           
catch ( sE as Exception)
           
End Try
       
End Sub

       
'ページが遷移したとき NavigateCompletedイベントを発生させる。
       
public sub OnNavigateComplete( o1 as Object, ref o2 as Object)
            NavigateCompleted(this, null)
       
End Sub

   
End Class

End
Namespace

■リスト18:手順3.宣言の修正、手順5.ブロック構造の修正を実行した段階

{ } がなくなってだいぶVBらしくなってきました。もう雰囲気はVBですね。良く見るとキーワードByValがついている個所がありますが、これはVBが自動的につけてくれるので自分でつける必要はありません。

それから、なれてないと戸惑うと思うので簡単に書いておきますが、C#の以下の記述はNavigateCompletedHander型のイベントNavigateCompletedを宣言している個所です。


public
event NavigateCompletedHandler NavigateCompleted;
 

■リスト19

変数の宣言と型名が前に来ているので、VB化すると次のようになります。

VB.NET2002対応 VB.NET2003対応 VB2005対応 VB2008対応


Public
Event NavigateCompleted As NavigateCompletedHandler
 

■リスト20

intとかstringだとすぐにわかると思いますが、このようなオブジェクト型の場合はぱっと見でわけがわからないような印象を持ってしまう方もいるかもしれませんね。でも、法則どおりAsを付けて型名を後ろに持って行くだけでいいのです。

それから、Dim ncd As ...の行ですが、翻訳前はかっこがついていてメソッド呼び出しのようになっていますが、実はこのかっこはVBが勝手につけたもので、一番最初の状態をみると単なる変数の宣言なんです。このように時折VBがかってにかっこをつけたりしますので惑わされないように注意が必要です。

 

次には手順6に従って構文を翻訳します。このサンプルではIfTryの2つがあります。それから、手順7にしたがって代表的なキーワードや記号も置き換えてしまいましょう。これには「3.キーワード・記号翻訳早見表」を使ってください。

Namespace IEOperation

   
imports System
   
imports System.Runtime.InteropServices
   
imports SHDocVw

   
Public Class Explorer

      
 Private Shared m_IExplorer As SHDocVw.InternetExplorer = Nothing
      
 Private Shared m_WebBrowser As IWebBrowserApp = Nothing

       
Public Delegate Sub NavigateCompletedHandler(ByVal sneder As Object, ByVal e As EventArgs)
       
Public Event NavigateCompleted As NavigateCompletedHandler

       
Public Sub Run()

           
'■「Navigate Complete」を取得できるように構成
           
m_IExplorer = New SHDocVw.InternetExplorer()
           
If m_IExplorer = Nothing Then
               
Return
           
End If

       
    '1.Navigate Complete event
           
Dim ncd As DWebBrowserEvents2_NavigateComplete2EventHandler = New DWebBrowserEvents2_NavigateComplete2EventHandler(OnNavigateComplete)
            m_IExplorer.NavigateComplete2 += ncd

           
'■IEを開いてホームページを表示

           
Try
           
    m_WebBrowser = (IWebBrowserApp)m_IExplorer
                m_WebBrowser.Visible =
True
               
m_WebBrowser.GoHome()
           
Catch sE As Exception
       
    End Try

   
    End Sub

       
'ページが遷移したとき NavigateCompletedイベントを発生させる。
   
    Public Sub OnNavigateComplete(ByVal o1 As Object, ByRef o2 As Object)
            NavigateCompleted(Me, Nothing)
       
End Sub

   
End Class

End
Namespace

■リスト21:手順7完了時点

これでほとんどVB化されました。このように定型的な処理だけでここまでの状態にできます。

でも、まだエラーがいっぱいでているのが気になりますか?

この例ではImportsの位置が悪いのでエラーがたくさんでてしまいます。

ここからの翻訳はケースバイケースになりますが、まずはNamespace End Namespaceを削除してみましょう。VBでは通常はNamespaceを自分で宣言することはしませんし、これのせいでImportsの位置が悪くなって こともあるのでだいぶ状況が改善されます。

あとは、1つずつつぶしていきます。

まず、ここでエラーが出ていますね?

If m_IExplorer = Nothing Then
   
Return
End If

■リスト22

VBでは変数の内容がNothingであるか確認するときにはIsNothing関数を使用するようにしましょう。

つまり、次のようになります。

VB.NET2002対応 VB.NET2003対応 VB2005対応 VB2008対応

If IsNothing(m_IExplorer) Then
   
Return
End If

■リスト23

 

それから、行が長くて気が付きにくいのですが、この行でエラーがでているはずです。

Dim ncd As DWebBrowserEvents2_NavigateComplete2EventHandler = New DWebBrowserEvents2_NavigateComplete2EventHandler(OnNavigateComplete)

■リスト24

何が悪いのか考えてみると、かっこのなかにメソッドを入れていますよね?VBではメソッドそれ自体を値のように引数にしたりするにはAddressOf演算子を使用して明示する必要があります。これはちゃんとVBのことを知っていないとちょっと厳しいかもしれませんね。

次のようになります。

VB.NET2002対応 VB.NET2003対応 VB2005対応 VB2008対応

Dim ncd As DWebBrowserEvents2_NavigateComplete2EventHandler = New DWebBrowserEvents2_NavigateComplete2EventHandler(AddressOf OnNavigateComplete)

■リスト25

 

次は少しC#の知識が必要です。


m_IExplorer.NavigateComplete2 += ncd
 

■リスト26

これはC#ではイベントハンドラの割り当てを意味しています。VBではイベントハンドラを動的に割り当てるにはAddHandlerを使用します。

この箇所は次のようになります。

VB.NET2002対応 VB.NET2003対応 VB2005対応 VB2008対応


AddHandler
m_IExplorer.NavigateComplete2, AddressOf OnNavigateComplete
 

■リスト27

 

次もC#の知識が必要になります。C#ではよくやることなのですが次のコードは型変換を意図しているのです。


m_WebBrowser = (IWebBrowserApp)m_IExplorer
 

■リスト28

つまり、変数m_IExplorerIWebBrowserApp型に変換してm_WebBrowserに代入するという処理です。VBでは型変換にはDirectCastCTypeを使用します。

VB.NET2002対応 VB.NET2003対応 VB2005対応 VB2008対応


m_WebBrowser =
DirectCast(m_IExplorer, IWebBrowserApp)
 

■リスト29

 

最後は次のコードです。


NavigateCompleted(Me, Nothing)
 

■リスト30

この行はNavigateCompletedイベントを発生させようとしていますから、VBではRaiseEventを使用する必要があります。

VB.NET2002対応 VB.NET2003対応 VB2005対応 VB2008対応


RaiseEvent
NavigateCompleted(Me, Nothing)
 

■リスト31

 

さて、これですべてのエラーがなくなりました。もちろん見かけ上のエラーがなくなっただけで完成というわけではありませんが、今回は特に問題なく使用できるようになります。

参考に完成版のコードを載せておきます。

VB.NET2002対応 VB.NET2003対応 VB2005対応 VB2008対応

Imports System
Imports System.Runtime.InteropServices
Imports SHDocVw

Public Class Explorer

    Private Shared m_IExplorer As SHDocVw.InternetExplorer = Nothing
   
Private Shared m_WebBrowser As IWebBrowserApp = Nothing  

   
Public Delegate Sub NavigateCompletedHandler(ByVal sneder As Object, ByVal e As EventArgs)
   
Public Event NavigateCompleted As NavigateCompletedHandler

   
Public Sub Run()

   
    '■「Navigate Complete」を取得できるように構成
       
m_IExplorer = New SHDocVw.InternetExplorer()
       
If IsNothing(m_IExplorer) Then
           
Return
       
End If

       
'1.Navigate Complete event
       
Dim ncd As DWebBrowserEvents2_NavigateComplete2EventHandler = New DWebBrowserEvents2_NavigateComplete2EventHandler(AddressOf OnNavigateComplete)
       
AddHandler m_IExplorer.NavigateComplete2, AddressOf OnNavigateComplete

       
'■IEを開いてホームページを表示

       
Try
           
m_WebBrowser = DirectCast(m_IExplorer, IWebBrowserApp)
            m_WebBrowser.Visible =
True
           
m_WebBrowser.GoHome()
       
Catch sE As Exception
       
End Try

   
End Sub

   
'ページが遷移したとき NavigateCompletedイベントを発生させる。
   
Public Sub OnNavigateComplete(ByVal o1 As Object, ByRef o2 As Object)
       
RaiseEvent NavigateCompleted(Me, Nothing)
   
End Sub

End
Class

■リスト32:VB版の完全なコード

 

フォームに次のようなプログラムを書いて動作を確認してみてください。Vistaの方はさきほど書いたように保護モードをオフにしてないとうまく動きません。

VB2005対応 VB2008対応

Public Class Form1

    Dim
WithEvents exp As New Explorer

    Private
Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        exp.Run()
    End
Sub
    Private Sub exp_NavigateCompleted(ByVal sneder As Object, ByVal e As System.EventArgs) Handles exp.NavigateCompleted
        MsgBox(
"ページ遷移しました!")
    End
Sub

End
Class

■リスト24:完成版をテストするためのフォーム側のコード

 

7.まとめ

 

今回私はC#のサンプルをVBで活用する方法を説明しました。そしてそのための翻訳作業はそれほど難しくないことを理解していただけたと思います。実際にやってみるとピンポイントで何箇所か難しい箇所がでてくることはありますが、9割程度の翻訳は今回の方法でうまくいきますし、私たちの目的は「C#をVBに翻訳すること」ではなく「C#のサンプルをVBで活用すること」なのですから大きな問題にはならないでしょう。それにC#の機能をそのまま使いたいのであれば、わざわざ翻訳する必要はなくC#のままでVBから呼び出せばいいわけです。

なれてくれば逐一翻訳しなくてもC#のサンプルを頭の中でVBに役立つ形に整理できるようになるでしょう。

これで、C#のサンプルが活用できるようになれば情報量は2倍になるかもしれません。大いに役立ててください。