tagCANDY CGI VBレスキュー(花ちゃん)の Visual Basic 6.0用 掲示板
VBレスキュー(花ちゃん)の Visual Basic 6.0用 掲示板
[ツリー表示へ]  [ワード検索]  [Home]

タイトル Re: Enumの項目名を変数で指定できないか。
投稿日: 2018/10/04(Thu) 16:03
投稿者魔界の仮面弁士
> 表題にもあるように、Enumの項目名を変数で指定できないか

VB6 の列挙型には、文字列でアクセスするための機構がありません。

VB6 の型システムにおいて、たとえば VbMsgBoxResult.vbAbort と VbMsgBoxStyle.vbYesNoCancel が
異なる列挙型の値であることを検知できず、ともに「Long 型の 3 の別名」として扱われてしまい、
同一視されるというのも、理由の一つです。

列挙型の型名を調べるために
 TypeName(vbYesNoCancel)
を実行した場合、VB.NET は "MsgBoxStyle" という型名を返すのですが、
VB6 や VBA は "Long" という文字列になってしまいます。


これが VB.NET であれば、MsgBoxResult.Abort と MsgBoxStyle.YesNoCancel を区別できますし、
 x = System.Enum.Parse(GetType(MsgBoxStyle), "YesNoCancel")
のようにして、文字列でアクセスすることも可能なのですけれども。



ですから VB6 の場合は、VBA.Collection か Scripting.Dictionary に
詰め替えておくことで妥協するぐらいしか手が無いと思います。

Private dictTEISU As VBA.Collection

Private Sub Form_Load()
    Set dictTEISU = New VBA.Collection
    dictTEISU.Add TEISU.AA, "AA"
    dictTEISU.Add TEISU.BB, "BB"
    dictTEISU.Add TEISU.CC, "CC"
End Sub

Private Sub Command1_Click()
    Dim KOUMOKUMEI As String
    KOUMOKUMEI = "BB"

    MsgBox dictTEISU(KOUMOKUMEI)
End Sub



ただしその列挙型が、ActiveX DLL (というかタイプライブラリ)にてレジストリ登録された、
公開された列挙型であるのなら、TypeLib Information 経由でメンバー名を抜き出す事が可能です。

具体的には、TypeLibInfoFromRegistry メソッドあるいは TypeLibInfoFromFile メソッドで
タイプライブラリの型情報を読み取り、Constants プロパティから
ConstantInfo オブジェクトのコレクションを得て、対象となる列挙型の
メンバーにアクセスするといった具合です。※要TLBINF32.DLL

列挙型以外の型にもアクセスしたいなら、Constants の代わりに TypeInfos プロパティを
用いることもできます。とりあえずこんな感じ。

Private Sub Form_Load()
    Dim filePath As String
    filePath = "C:\Program Files (x86)\Common Files\Microsoft Shared\DAO\dao360.dll"

    Dim tlbInfo As Object, typeInfo As Object, memberInfo As Object
    Set tlbInfo = CreateObject("TLI.TLIApplication").TypeLibInfoFromFile(filePath)

    For Each typeInfo In tlbInfo.TypeInfos
        If typeInfo.TypeKind = 0 Then
            Debug.Print typeInfo.Name
            For Each memberInfo In typeInfo.Members
                Debug.Print , memberInfo.Name; " ="; memberInfo.Value
            Next
        End If
    Next
End Sub


※ 相手が Enum ではなくオブジェクトであった場合は、TypeLib Information は不要です。
 オブジェクトならこんな回りくどいことをせずとも、CallByName 関数を使えば済む話なので。

- 関連一覧ツリー をクリックするとツリー全体を一括表示します)

古いスレッドにレスはつけられません。