none
VB6.0からVB.NET2005への移行

    質問

  • いつもお世話になっております。
    VB6.0からVB.NET2005への移行に関しての質問です。


    VB2005のアップグレード・ウィザードを使用して、
    VB6のソースをコンバートしましたところ、下記箇所でコンパイルエラーが
    発生してしまいました。(ソース1)


    ・画面1、画面2から共通モジュールを呼んで、エクセルファイルに出力する処理です。

    ・コンバートされたVB2005もほぼ同じソースとなりました。

    ・ソース2に修正すればコンパイルは通りましたが、frm12.frmからcmnFuncを呼べません。
    (当たり前ですが・・・)

    ・ucComboBoxはユーザコントロールです。



    VBとオブジェクト指向に関して、知識が足りないためなのか、
    何故VB6ではコンパイルが通り、VB2005ではコンパイルエラーになるのか?
    これをVB2005用に修正するにはどのへんの知識が必要なのかがわかりません。

    お手数お掛けしますが、ご教授下さい。



    *** VB 6.0 ソース1 ***************************************************************

    ---- frm11.frm (画面1) -------------------------

    Private Sub cmd_Click(Index As Integer)

            :
            :

        cmnFunc(me)

            :
            :

    End Sub

    ---- frm12.frm (画面2) -------------------------

    Private Sub cmd_Click(Index As Integer)

            :
            :

        cmnFunc(me)   

            :
            :

    End Sub

    ---- Common.bas (共通モジュール) ----------------

    Public Function cmnFunc(frm As Form) As Boolen

        Dim xlSheet As Excel.Worksheet

            :
            :

        xlSheet.Cells(2, 2).Value = frm.ucComboBox.Text

            :
            :

    End Function


    *** VB 6.0 ソース2 ***************************************************************

    Public Function cmnFunc(frm As frm11) As Boolen

        Dim xlSheet As Excel.Worksheet

            :
            :

        xlSheet.Cells(2, 2).Value = frm.ucComboBox.Text

            :
            :

    End Function
    2008年10月28日 7:33

回答

  • VB6のソースでは実行時にインスタンスにメンバが存在するかチェックされるのに対して、

    VS側ではコンパイル時にチェックされているという違いです。(これもオプションにより違いますが。Option Strict)

     

    提示されたVB6ソースでは、As Formの場合は実行時にfrm11ではないインスタンスが渡された場合エラーになります。

    そういう意味では危険なコードです。

    型を明示的に意識して記述するプログラミングをお勧めします。

     

    あと、貼り付いているコントロールは、その型(フォーム)に強く依存しますので、外からコントロールを参照するのはよくありません。

    独自にプロパティ等を実装して抽象的なインターフェースにしたほうがよいでしょう。

    2008年10月28日 8:53
  • こんな感じでいかがでしょうか。

    Code Snippet


    Public Class FormComBoxInside
     Inherits System.Windows.Forms.Form

     

    Public Function GetComboBoxText() As System.String

    Return ucComboBox.Text

    End Sub

     

    End Class

     

    Public Class frm11
     Inherits FormComBoxInside

    End Class

     

    Public Class frm12
     Inherits FormComBoxInside

    End Class

     

     

     

     

    Public Function cmnFunc(frm As FormComBoxInside) As Boolen

        Dim xlSheet As Excel.Worksheet

            :
            :

        xlSheet.Cells(2, 2).Value = frm.GetComboBoxText()

            :
            :

    End Function

     

     

    FormComBoxInsideをクラスではなくインターフェイスにしてもよいです。

    または、標準モジュールなんてものはなくしてしまってFormComBoxInsideをエクセルアクセス付の画面の基本クラスとしてしまう。

    2008年10月28日 15:13
  • # 細かい話で恐縮です。

     

     Myon さんからの引用

    Code Snippet

    Public Function GetComboBoxText() As System.String

        Return ucComboBox.Text

    End Sub

     

    GetComboBoxText という名前だと抽象化の方向性が違うんじゃないかと。 ※そういう場合も無いことは無いですが。

    要は何のテキストかがわからないですよね。

    それが社員コードならば、GetWorkerCodeとかかなと。ComboBoxはそのクラス内の実装ですから。

     

    細かい話をすると、ガイドライン的には、Get~, Set~はオブジェクトを主語としないメソッドというのがあります。

    いい例だと、String.GetHashCodeとか。無から有を作るというかそんな感じですかね。

    単純に前例だとWokerCode プロパティでいいんではないでしょうか。

    #個人的に意識してることなので書いてみました。

     

     Myon さんからの引用

    Code Snippet

    Public Function cmnFunc(frm As FormComBoxInside) As Boolen

     

    これもフォームを受け取るのではなく、共通概念としての項目(いわゆる業務項目)を引数としたほうがよいでしょう。

    Public Function xxx(ByVal workerCode As String, ByVal workerName As String) As Boolean

     

    いわゆる業務の世界にコントロールを持ち込むと身動きが取れなくなりますからね。

    2008年10月29日 3:23

すべての返信

  • VB6のソースでは実行時にインスタンスにメンバが存在するかチェックされるのに対して、

    VS側ではコンパイル時にチェックされているという違いです。(これもオプションにより違いますが。Option Strict)

     

    提示されたVB6ソースでは、As Formの場合は実行時にfrm11ではないインスタンスが渡された場合エラーになります。

    そういう意味では危険なコードです。

    型を明示的に意識して記述するプログラミングをお勧めします。

     

    あと、貼り付いているコントロールは、その型(フォーム)に強く依存しますので、外からコントロールを参照するのはよくありません。

    独自にプロパティ等を実装して抽象的なインターフェースにしたほうがよいでしょう。

    2008年10月28日 8:53
  • こんな感じでいかがでしょうか。

    Code Snippet


    Public Class FormComBoxInside
     Inherits System.Windows.Forms.Form

     

    Public Function GetComboBoxText() As System.String

    Return ucComboBox.Text

    End Sub

     

    End Class

     

    Public Class frm11
     Inherits FormComBoxInside

    End Class

     

    Public Class frm12
     Inherits FormComBoxInside

    End Class

     

     

     

     

    Public Function cmnFunc(frm As FormComBoxInside) As Boolen

        Dim xlSheet As Excel.Worksheet

            :
            :

        xlSheet.Cells(2, 2).Value = frm.GetComboBoxText()

            :
            :

    End Function

     

     

    FormComBoxInsideをクラスではなくインターフェイスにしてもよいです。

    または、標準モジュールなんてものはなくしてしまってFormComBoxInsideをエクセルアクセス付の画面の基本クラスとしてしまう。

    2008年10月28日 15:13
  • # 細かい話で恐縮です。

     

     Myon さんからの引用

    Code Snippet

    Public Function GetComboBoxText() As System.String

        Return ucComboBox.Text

    End Sub

     

    GetComboBoxText という名前だと抽象化の方向性が違うんじゃないかと。 ※そういう場合も無いことは無いですが。

    要は何のテキストかがわからないですよね。

    それが社員コードならば、GetWorkerCodeとかかなと。ComboBoxはそのクラス内の実装ですから。

     

    細かい話をすると、ガイドライン的には、Get~, Set~はオブジェクトを主語としないメソッドというのがあります。

    いい例だと、String.GetHashCodeとか。無から有を作るというかそんな感じですかね。

    単純に前例だとWokerCode プロパティでいいんではないでしょうか。

    #個人的に意識してることなので書いてみました。

     

     Myon さんからの引用

    Code Snippet

    Public Function cmnFunc(frm As FormComBoxInside) As Boolen

     

    これもフォームを受け取るのではなく、共通概念としての項目(いわゆる業務項目)を引数としたほうがよいでしょう。

    Public Function xxx(ByVal workerCode As String, ByVal workerName As String) As Boolean

     

    いわゆる業務の世界にコントロールを持ち込むと身動きが取れなくなりますからね。

    2008年10月29日 3:23
  • >まどかさん

    ありがとうございます。
    コンパイル時にチェックしているかどうかの違いなのですね。
    VB6.0をやったことがなかったので、こういうものかと思っていたのですが、
    やはり危険なコードだったのですね。
    根本的に作り直したいと思います。


    >Myonさん

    わざわざソースまで提示して頂いてありがとうございます。
    インターフェイスの作りかたがまだよくわかってないので、
    この機会に勉強したいと思います。
    2008年10月29日 8:34
  • まどか様

     

    ご指摘ありがとうございます。

    おっしゃる通りかと思います。

     

    単にcmnFuncメソッドに両方のFormを適用するにはどうしたらよいかを示したのみで、

    最適な実装にするにはまだまだ工夫がありますね。

     

     

     

    2008年10月29日 11:36