• ベストアンサー

VB6-オブジェクトを配列にセット

質問用に、本来作りたいものではなく、機能に絞った質問をします。 ちなみにNo.2567628とは違います。 テキストボックスが10個あり、Text1、Text2、…Text10というオブジェクト名となります(説明の便宜上以上の名前になっているが実際はtxt○○で、○○の規則は無い)。仕様の都合上、text(1)、text(2)…の配列は使用できません。(配列のタイプはNo.2567628) 上記の仕様で、全てのテキストボックスをvbnullstringに割り当てたいのですが、 Private Sub Form_Load() Dim i As Integer Dim obj(9) As Object Set obj(0) = Text1 Set obj(1) = Text2 Set obj(2) = Text3 Set obj(3) = Text4     … Set obj(9) = Text10 For i = 0 To 10 obj(i).text = vbnullstring Doevents Next i End Sub で、本来出来るのですが、 Set obj(0) = Text1 の右辺がStringで定義したい場合ができません。 つまり Set obj(0) = "Text1" という感じです。 (本来のシステムなら"Text1"にあたる所が"strData"とかになる) Private Sub Form_Load() Dim i As Integer Dim obj(9) As Object Set obj(0) = "Text1"  'ここでエラー Set obj(1) = "Text2" Set obj(2) = "Text3" Set obj(3) = "Text4" Set obj(4) = "Text5" Set obj(5) = "Text6" Set obj(6) = "Text7" Set obj(7) = "Text8" Set obj(8) = "Text9" Set obj(9) = "Text10" For i = 0 To 9 obj(i).Text = vbNullString DoEvents Next i End Sub ちなみにエラーは「型が一致しません」です。 どこを直したらいいか教えてください。

質問者が選んだベストアンサー

  • ベストアンサー
noname#140971
noname#140971
回答No.6

Private Sub Command1_Click()   Dim I   As Integer   Dim ctl  As Control   Dim obj(2) As String      obj(0) = "Text1"   obj(1) = "Check1"   obj(2) = "Command1"   For Each ctl In Me.Controls     For I = 0 To 2       If ctl.Name = obj(I) Then         ctl.BackColor = vbYellow         Exit For       End If     Next I   Next ctl End Sub Exit For があった方がいいです。

tocci_pc
質問者

お礼

ありがとうございます。 僕の思っていた仕様が上記となります。 上記の考えをヒントにして、 本ツールを作ってみたいと思います。 それで、ちょっと踏み込みたいのですが、 チェックボックスcheck1のみ check1(0)~check1(3)の4つがある場合、 dim J as integer (中略)       If ctl.Name = obj(I) Then         if オブジェクトが配列の場合 = true ther          for J = 0 to UBOUND(ctl.Name)          ctl(J).BackColor = vbYellow          next Exit For         Else ctl.BackColor = vbYellow end if       End If  ・・・ の用にしたらだめですが、For Each ~ Inにした方がいいですか?

その他の回答 (7)

noname#140971
noname#140971
回答No.8

ちょっと、踏み込んでいいですか? Const conCTLNAME = "Text1/Check1/Command1" Private Sub Command1_Click()   Dim ctl As Control      For Each ctl In Me.Controls     If InStr(1, conCTLNAME, ctl.Name, vbTextCompare) Then       ctl.BackColor = vbYellow     End If   Next ctl End Sub 先の回答は、このようにも書けますよね。 違いは、プログラムコード自体から"Text1/Check1/Command1"を追放していることです。 コード内に埋め込まれた特定の数字や文字列は’マジックナンバー’と呼ばれています。 このマジックナンバーのあるコードはメンテナンスが非常に困難とされています。 ですから、[記号定数]を利用して特定のデータはコード内から追放することが推奨されています。 さて、「それじゃ、ctl がText1かCheck1なのかが判らない」という不具合も発生します。 これも、記号定数に規則性を持たせることで解決します。 Instr で検索して10番目からが Text1である、20番目はCheck1であるとすれば良い訳です。 '               ----+----1----+----2----+----3----+----4 Const conCTLNAME = "---------Text1/----Check1/---Command1" Private Sub Command1_Click()   Dim P  As Integer   Dim ctl As Control     For Each ctl In Me.Controls     P = InStr(1, conCTLNAME, ctl.Name, vbTextCompare)     If P > 0 Then       Select Case P         Case 10 ' Text1           ctl.BackColor = vbYellow         Case 20 ' Check1           ctl.BackColor = &H8000000F         Case 30 ' Command1           If ctl.Style = 1 Then             ctl.BackColor = vbYellow           End If         Case Else       End Select     End If   Next ctl End Sub まあ、定年間際のおじさんのおせっかいです。 お礼など必要ありません。 ちょっと、先の回答を参考にされるとすれば問題の多い書き方でしたので補足した次第です。

tocci_pc
質問者

お礼

非常にユニークな考え方ですね。 長年の経験がひしひしと伝わってきます。 今回は流用はできませんが、次回以降の開発の参考にしてみます。 あと、ここに書く形になって申し訳ないですが、 今までご回答していただいたかた、誠にありがとうございました。 最初の解答からだいぶ目的が変わってきましたので、 一旦ここで閉め、改めて質問します。

noname#140971
noname#140971
回答No.7

ANo3の補足+ANo6の補足だけですと、一切、コードを変更する必要はないです。 配列の形でCheck1が増えようとも、それは For Each のループ回数が3つ増えるだけですよ。 そして、その都度にそれぞれの増えたチェックボックスのプロパティが設定されます。 コード変更は無用という理由です。

tocci_pc
質問者

お礼

あ、そうですねぇ。 ちょっと別プログラムで合成してたらとばしたのでその部分を取り払って動きを見てみます。 ありがとうございました。

noname#140971
noname#140971
回答No.5

ズブの素人ですが、横から失礼! Private Sub Command1_Click()   Dim I   As Integer   Dim ctl  As Control   Dim obj(2) As String      obj(0) = "Text1"   obj(1) = "Check1"   obj(2) = "Command1"   For Each ctl In Me.Controls     For I = 0 To 2       If ctl.Name = obj(I) Then         ctl.BackColor = vbYellow       End If     Next I   Next ctl End Sub obj() は、オブジェクトでも何でもないですよね。 単に ctl を比較テストするための文字列データ。 ctl.BackColor を設定しなきゃ。 なお、コマンドボタンはグラフィックスにしておかないと背景色の指定は無視されます。

  • redfox63
  • ベストアンサー率71% (1325/1856)
回答No.4

For Eachの場合 Nextは単独にしないといけません Next ctlのctlを削除しましょう

tocci_pc
質問者

お礼

削除しました。

  • redfox63
  • ベストアンサー率71% (1325/1856)
回答No.3

プロパティの種類が統一されていないので難しいように思いますよ たとえば LabelはCaptionが表示文字列TextBoxはTextといった具合に でご希望の処理をしようとするなら obj配列は String型で フォームのContolsコレクションを舐めてNameプロパティと比較 個別の処理 といった具合かと for each ctl in Me.controls   for n=0 to 9     if ctl.Name = obj(n) then       ' 何かの処理     end if   next Next

tocci_pc
質問者

お礼

テキストボックス・チェックボタン・コマンドボタンが一個ずつあります。 Dim n As Integer Dim ctl Dim obj(2) As String obj(0) = "Text1" obj(1) = "Check1" obj(2) = "Command1" For Each ctl In Me.Controls If ctl.Name = obj(n) Then obj(n).BackColor = vbYellow End If Next ctl を実行してみましたが、うまくいきませんでした (修飾子が不正です)。

noname#245936
noname#245936
回答No.2

No.1です。 お礼欄のQに関しては。 その場合は一括でオブジェクト型で受けるもよし。 または別途それぞれに配列型各オブジェクト変数を用意し、画面上の 位置情報のみ別の構造体配列かクラスで持てばいいかと思います。 オブジェクト変数は何にでもなれ「すぎる」ので、なれ「すぎない」 ほうがオブジェクト指向には合った考え方だと思います。 また複数コントロールが介在する場合は、「お前はテキスト ボックス?」とカレントオブジェクト自身を判定させれば いいはずです。 各コントロールは、自分が「何」かプロパティをもっていたかと。 ちなみに。 複数コントロールが動的に画面に現れるクラスってのがイマイチ イメージつかないのですが? ソフトウェアの機能概要はなんでしょうか? 通常はフォーム概念で「業務クラス」になるような気がしますが。 (一部は郵便番号コントロールとか、独立オブジェクトになる  はずですけどね)

noname#245936
noname#245936
回答No.1

んー。 ちょっとタッチが違うように思いますね。 VB6はなんだかんだ言われても一応オブジェクト指向できますので。 まず、 1.Dim obj(9) As Object ではなく、Dim oText(9) AS TextBox   ではないかと。   テキストクラスの入れ子ですよね? 2.変数領域が確保できたら、newでインスタンスを作成する   必要がありますよね? 3.変数代入は今まで通り、oText(index).Text = "あいうえ"と   なるのでは?と思います。 ADODB.commandとか、Recordsetを利用するのと同じ形にすれば いいんじゃないでしょうか? これでいいんじゃないでしょうか?

tocci_pc
質問者

お礼

質問のところにしっかり書いてなかったのですが、 実はDim obj(9) As Object には、テキストボックス以外に、コンボボックス、ラジオボタン、チェックボックスなども入ってくる可能性があります。 その場合はどうなるのでしょうかね。