[リストへもどる]
一括表示

投稿時間:2002/12/02(Mon) 06:56
投稿者名:あずま
Eメール:
URL :
タイトル:
文字列を変数名として扱う事は出来ますか?
はじめまして。
VBで質問なのですが、プライベートな構造体で

Private Type STX
    ST_NUM As String
    ST_NAME As String
    ST_TEL  As String
end type

private ST_A as STX

の様に定義したものに対し、グローバルな関数、例えば
public function GetST("ST_NUM") の様に引数へ変数名を入れて、
何らかの形で各構造体のメンバ変数にアクセス(値の取得など)
したいのですが、このような事は可能でしょう?
私の場合、関数内で select case を使い、全てのパターンに対し

public function GetST(Para as string) as xxx
    DIM Ret
    select case Para
        case "ST_NUM":Ret=ST_A.ST_NUM
        case "ST_NAME":Ret=ST_A.ST_NAME
        case "ST_TEL":Ret=ST_A.ST_TEL
          :

のようにチェックしてるのですが、同じような処理を他の関数でも
使っているため、メンバが増えると2重3重の手間になってしまいます。

public function GetST(Para as string) as xxx
    DIM Ret
    Ret = XXX("ST_A." & Para)

のように変数名を文字列で指定し、実際の変数へアクセス出来る関数が
あれば、ソースコードも見やすく便利で良いのですが…
どなたか良い方法をご存知の方いらっしゃいましたら教えて頂けませんでしょうか?
よろしくお願い致します。

投稿時間:2002/12/02(Mon) 11:27
投稿者名:Lantern
Eメール:
URL :
タイトル:
Re: 文字列を変数名として扱う事は出来ますか?
私の勘違いでしたら申し訳ありません
以下の様なことでしょうか?

Private Type STX
    ST_NUM As String
    ST_NAME As String
    ST_TEL  As String
End Type

Private ST_A As STX

Public Function GetST(Para As String) As String
    GetST = SelectST(Para)
End Function

Private Function SelectST(Para As String) As String
    Dim Ret As String
    Select Case Para
        Case "ST_NUM": Ret = ST_A.ST_NUM
        Case "ST_NAME": Ret = ST_A.ST_NAME
        Case "ST_TEL": Ret = ST_A.ST_TEL
    End Select
    SelectST = Ret
End Function

投稿時間:2002/12/03(Tue) 04:11
投稿者名:あずま
Eメール:
URL :
タイトル:
Re^2: 文字列を変数名として扱う事は出来ますか?
> 私の勘違いでしたら申し訳ありません
> 以下の様なことでしょうか?
>
> Private Type STX
>     ST_NUM As String
>     ST_NAME As String
>     ST_TEL  As String
> End Type
>
> Private ST_A As STX
>
> Public Function GetST(Para As String) As String
>     GetST = SelectST(Para)
> End Function
>
> Private Function SelectST(Para As String) As String
>     Dim Ret As String
>     Select Case Para
>         Case "ST_NUM": Ret = ST_A.ST_NUM
>         Case "ST_NAME": Ret = ST_A.ST_NAME
>         Case "ST_TEL": Ret = ST_A.ST_TEL
>     End Select
>     SelectST = Ret
> End Function
回答ありがとう御座います。
でもって、説明不足ですみません。
えーとですね、上記のSelect Caseの部分をなくしたいんですよ。
この場合、変数名の”ST_A.”という部分が共通してますし、
続くメンバ名(ST_NUMなど)は引数から来てますよね?
これをうまく繋ぐことが出来ないかなぁと思いまして。
理想としてはこんな感じです。

'// 初期化
ST_A.ST_NUM = 10

'// 呼び出し
Dim Num as String
Num = SelectST("ST_NUM")

Private Function SelectST(Para As String) As String
    Dim Ret As String
    Ret = "ST_A." + Para … @
    SelectST = Ret
End Function

単にこれだけですと@の部分には"ST_A.ST_NUM"の様な文字列が
入ってしまいます。この文字列を変数名(ST_A.ST_NUM)と認識させ、
ST_A.ST_NUMの値("10")をRet⇒Numに返したいのです。

プログラム的に無理があるのでしょうか…

投稿時間:2002/12/03(Tue) 09:04
投稿者名:魔界の仮面弁士
Eメール:
URL :
タイトル:
Re: 文字列を変数名として扱う事は出来ますか?
> VBで質問なのですが、プライベートな構造体で
構造体ではなく、「ユーザー定義型」ですね。

> public function GetST("ST_NUM") の様に引数へ変数名を入れて、
> 何らかの形で各構造体のメンバ変数にアクセス(値の取得など)
> したいのですが、このような事は可能でしょう?
そういう用途であれば、通常、ユーザー定義型は用いません。
クラスにするか、コレクション系のオブジェクトを使うのが常套かと。

とりあえず、Dictionaryオブジェクトを使ったサンプルを掲載しておきます。

Option Explicit
Private GetST As Object
Private Sub Form_Load()
    Set GetST = CreateObject("Scripting.Dictionary")
    GetST("ST_NUM") = "ABC"
    GetST("ST_NAME") = "DEF"
    GetST("ST_TEL") = "GHI"
End Sub
Private Sub Command1_Click()
    MsgBox GetST("ST_NAME")
End Sub


Dictionaryオブジェクトの代わりに、PropertyBagオブジェクトやCollectionオブジェクトなどでも
同様の仕組みは作れますが、今回はDictionaryの方が使いやすいでしょう。

なお、上記のコードだと、想定外のメンバ名が利用できてしまいますし、
データ型も厳密に決定させる事ができません。そうした場合には、
クラスモジュールを使って、独自のコレクションを作ってしまえばOKです。

なお、独自のコレクションを作成する手順に付いては、MSDNライブラリを参照してください。
[Visual Studio 6.0 ドキュメント]
 └[Visual Basic ドキュメント]
  └[Visual Basic の使用方法]
   └[プログラミング ガイド]
    └[Visual Basic を使ってできること]
     └[オブジェクト]
      └[コレクションの作成方法]
       └[独自のコレクション クラスの作成]

投稿時間:2002/12/03(Tue) 09:14
投稿者名:魔界の仮面弁士
Eメール:
URL :
タイトル:
Re^2: 文字列を変数名として扱う事は出来ますか?
> そういう用途であれば、通常、ユーザー定義型は用いません。
> クラスにするか、コレクション系のオブジェクトを使うのが常套かと。

ちなみに、クラスモジュールとして定義しておいた場合は、
VB6のCallByName関数を使うことで、メンバ名を文字列で指定する事ができます。

投稿時間:2002/12/03(Tue) 11:33
投稿者名:Lantern
Eメール:
URL :
タイトル:
Re^2: 文字列を変数名として扱う事は出来ますか?
Dictionaryオブジェクトというのは知りませんでした^^;

Collectionのように、キー文字列での検索ができる
オブジェクトを使うことになるのですね。

投稿時間:2002/12/03(Tue) 12:57
投稿者名:魔界の仮面弁士
Eメール:
URL :
タイトル:
追記: Dictionaryオブジェクト
> Dictionaryオブジェクトというのは知りませんでした^^;

先のコードでは、As Objectで宣言して使っていましたが、参照設定して使う場合は、
SCRRUN.DLL (Microsoft Scripting Runtime)にチェックを入れておいてください。
そうすれば、
    Dim S As Dictionary
    Set S = New Dictionary
のように宣言して利用する事ができます。


> Collectionのように、キー文字列での検索ができる
> オブジェクトを使うことになるのですね。

ただ、Collectionとはキーの扱いが若干異なります。

・Collectionではキーを省略する事ができますが、Dictionaryではキーが必須です。
・Collectionではキーに文字列しか使えませんが、Dictionaryでは文字列以外も使えます。
・Collectionでは、キーの大文字/小文字/全角/半角は区別されませんが、
 Dictionaryでは、区別するかどうかを CompareMode プロパティで変更できます。
・Dictionary には、キーが存在しているかをチェックする Exists メソッドや、
  キーの一覧を返すKeysメソッドなどが追加されています。
・Collectionでは、値の取得を行うのは、「Itemメソッド」でしたが、Dictionaryでは、
 「Itemプロパティ」に変更されており、値の取得だけではなく、設定も可能となりました。
・Addメソッドでの登録はCollection/Dictionaryのいずれでも使えますが、
  引数の順番が異なります。Collectionでは「値, キー」の順ですが、
 Dictionaryでは逆の「キー, 値」になっています。

―――以上、蛇足までに。

投稿時間:2002/12/04(Wed) 07:16
投稿者名:あずま
Eメール:
URL :
タイトル:
Re: 追記: Dictionaryオブジェクト
Lanternさん、魔界の仮面弁士さん、
わかりやすいご説明ありがとう御座いました。

Dictionary、Collection、早速勉強してみたいと思います。
わからないことがありましたら、その時にはまたご助力を
頂けますと助かります。
本当にありがとう御座いました。