Visual Basic6.0(SP5)で伺いたいことがあります。

フォーム上の全てのオブジェクトを For Each文で取得しています。以下の様にです。

Dim Control As Object

For Each Control In Form1.Controls
If TypeOf Control Is Text Then
End If
Next Control

このとき個々のControlがコントロール配列かどうかを知りたいのですが、どうすればよろしいでしょうか?フォーム上にはコントロール配列のオブジェクトも、コントロール配列ではないオブジェクトもあります。

Control.Indexの値を参照しようとしても、コントロール配列でない場合は
「配列ではないオブジェクトです」とエラーになります。
IsArray関数でもFalseになってしまいます。

何を行いたいかというと、そのControlがコントロール配列(Text1(0)とかText1(1)とか)かどうかを調べて、そのIndexをある関数の引数にしたいのです。全てコントロール配列だったら、Control.Indexで値を取得できるのですが。

よろしくお願いします。

このQ&Aに関連する最新のQ&A

A 回答 (4件)

新しいアルゴリズムを思いつきました。


コントロール配列って、たしか、同じ名前を共有しますよね。

だから、For Each ・・の中で、Control.Name を参照して、同じ名前が 2>= 出てきたら・・・と言うのは、いかがですか?
    • good
    • 0
この回答へのお礼

Masato_aさん、再度のご回答どうもありがとうございます。
なるほど!全てのオブジェクトの数だけ配列を用意してカウントする方法ですね。For Each文でオブジェクトを取得した場合、コントロール配列は必ずしも連続して取得できないので単純なコントロールブレイクではだめそうですが、全てのオブジェクトに対してカウントすれば確かによさそうですね。早速試してみます。

処理スピードとメンテナンスの方法等から総合的に判断して、こちらの方法をとるか、On Errorでの処理を取るか、一つ一つ場合分けするかを検討します。

どうもご回答ありがとうございました。

お礼日時:2001/08/05 22:07

ANo.#1に


>そうですね。なるべくなら On Error文を使いたくないんですよ。・・・
とありましたので、難しいことは分かりませんが tag にコントロール配列だという印(しるし)をつけたらどうですかね。スマートかどうかは判断しかねますが簡明にはなります。

On Error GoTo 0 ですが、エラー判定するべき箇所が終わったのでエラー処理ルーチンを無効にする意味で書きました。この後、どのような処理を書くかわかりませんので。エラー判定をずっと引きずりたくない意味です。書き方としては個人的な癖かもしれません。現プロシージャは終わってしまうので不要?でしょうか。
    • good
    • 0
この回答へのお礼

nishi6さん、早々のレスポンスありがとうございます。

実は最初tagに目印をつけようかと思ったのですが、既にtagは他の目的に使っていまして、桁を増やしたりしたくはないなと考えておりました。ちょっと修正箇所が多くなりそうなので。

あの・・・、「スマート」とは言葉が悪く、良識を疑われても仕様がない表現でした。謹んでお詫び申し上げます。もちろんMasato_aさんやnishi6さんの方法を悪く言うつもりはありませんでした。どうぞお気を悪くなさらないでください。

On Error GoTo 0 の使い方は存じませんでした。ありがとうございます。

矢張り、Controlで取得した場合、IsArray関数で配列とみなされないのは仕様なんですかね。

再度のご回答どうもありがとうございました。

お礼日時:2001/08/04 23:09

普通に調べてエラーが起きたら何もしないのは?


下記ではコントロール配列だけ<Debug.Print myCtrl.Name>に入っています。

<Err.Clear: On Error GoTo 0>とかはこんな使い方でした?年かな?だいぶ忘れてきました。


Private Sub Form_Load()
  Dim myCtrl As Control
  Dim CtrlFlg As Boolean

  On Error GoTo ErrorHandler
  For Each myCtrl In Form1.Controls
    CtrlFlg = (myCtrl.Index >= 0)
    If CtrlFlg = True Then
      Debug.Print myCtrl.Name
    End If
  Next

  Err.Clear: On Error GoTo 0
  Exit Sub

ErrorHandler:
  CtrlFlg = False
  Resume Next
End Sub
    • good
    • 0
この回答へのお礼

nishi6さん、どうもご回答ありがとうございます。

Masato_aさんのお礼にもお答えいたしましたが、On Error文で処理するのは最終手段にしようと思います。

なぜコントロールを使用すると、コントロール配列はIsArray関数で識別できないのでしょうかね?もちろんVarType 関数でもvbArrayは返しませんでした。

それと質問なのですが、
>  Err.Clear: On Error GoTo 0
の後半部分の On Error GoTo 0 とはどのような処理なのでしょうか?
たった今確認しましたところ、うまく動きましたが、GoTo 0の行き先がわかりません。再びご回答を賜りたく存じます。

ご回答どうもありがとうございました。

お礼日時:2001/08/04 22:38

無理やりインデックスを参照して見て、Err.Numberを使って判定するのって、嫌いですか?

    • good
    • 0
この回答へのお礼

Masato_aさん、ご回答どうもありがとうございます。

そうですね。なるべくなら On Error文を使いたくないんですよ。On Errorで飛ばして、そこでErr.Numberで判断するのは、処理的には変わらないのですが、気の持ちようというか、他にスマートな方法がないかなーって思ってしまいます。

フォームにオブジェクトがたくさんあるので、場合分けするのも大変なんですが、どうしようもなくなったら、On Errorか、一つ一つ聞いていくかにすると思います。

ご回答どうもありがとうございました。

お礼日時:2001/08/04 22:26

このQ&Aに関連する人気のQ&A

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

QFOR文でtext1,text2,text3...などとどうやって処理させればいいのですか

超初心者な質問ですみません。
たとえばFOR文を使ってtext1~10まで連続に処理させるには
どういったコードを記述すればよいのでしょうか?
初心者用の本やHPを探しても見当たりませんでした。
お願いします。

Aベストアンサー

textエリアをインデックス配列にすればいいです。
Text1のエリアをファーム上でコピーし、貼り付けると
Text1(0)~ Text1(9) の配列になります。
それを
 
(例)

i =0
for i=0 to 9
text1(i) = x
next

のようにすればいいです。

Q構造体配列の特定のメンバーをFor~Eachで

みなさんこんにちは。昔Vb6を少々やっていましたが
ここ数年遠のいていました。
必要に迫られ最近Vb2010を勉強しはじめた50歳です。

サンプルの通り3つのメンバーを持つ構造体配列があり、
メンバーData3の合計を得るのに、ループで回して
計算してましたが、これを For~Next ではなくFor~Each で
やれないかと考えておりました。配列の要素の個数が不定
な場合に便利だと思ったからです。
サンプルの ???_1が「型」で ???_2が「コレクション」と
なるように記述するのだということまではわかりますが、
具体的な記述がわかりません。For~NetでもDo~Loopでも
他にも方法があるのは知っています。勉強の為に、For~Eachでの
やりかたを知りたいのです。また、構造体配列ではなく、多次元配列での
特定の次元要素を同様に処理する方法も知りたいです。
どなたかご教授お願いできれば幸いです。
ネット上でそれなりに調べましたが、目的に沿う情報は
みつけることができません。


Public Class Form1
Structure STR
Dim Data1 As Double
Dim Data2 As Double
Dim Data3 As Double
End Structure

Private Sub Button1_Click(sender As System.Object, _
e As System.EventArgs) Handles Button1.Click
Dim Str_1(10000) As StR
Dim Rn As New System.Random()
For i = 0 To 9999
Str_1(i).Data3 = Rn.Next(100)
Next
'以降いろんな処理をやる
'
'
'このあと For~Nex ではなくFor Each をつかってメンバーDat3の合計を得るには?
Dim sum As Double
For Each X As ???_1 in ???_2 '???_1 と ???_2 の記述がわからない
sum += X
Next
Label1.Text = sum.ToString
End Sub

End Class

みなさんこんにちは。昔Vb6を少々やっていましたが
ここ数年遠のいていました。
必要に迫られ最近Vb2010を勉強しはじめた50歳です。

サンプルの通り3つのメンバーを持つ構造体配列があり、
メンバーData3の合計を得るのに、ループで回して
計算してましたが、これを For~Next ではなくFor~Each で
やれないかと考えておりました。配列の要素の個数が不定
な場合に便利だと思ったからです。
サンプルの ???_1が「型」で ???_2が「コレクション」と
なるように記述するのだということまではわかり...続きを読む

Aベストアンサー

For eachで 構造体のメンバーを直接取得って出来ないと思います

やるならば 構造体を個別に抽出して そのメンバーをループ中で使う方法になると思います
???_1に『STR』???_2に『Str_1』を使って

for each X as STR in Str_1
  Sum += X.data3
Next

といった具合かと …

QFor ~ Next の中での Dim宣言について

四角形を下方向にずらしながら繰り返し描きたい場合、
以下のソースのようにFor ~ Next の中での Dim宣言を
行うのは一般的でしょうか。

他にスマートな記述があれば教えてください。
よろしくお願いします。

---------------------------------------
'四角形を下方向にずらしながら描画
For i = 0 To 10
  Dim rect As New Rectangle(x, y* i , w, h)
  g.DrawRectangle(Pen.Black, rect)
Next

Aベストアンサー

RectangleのOffsetメソッドを使うという方向なら Rectangleオブジェクトの生成は1回でいいことになります

dim rect as new Rectangle( x, y, w, h )
for i = 0 to 10
  g.DrawRectangle( Pens.Black. rect )
  rect.Offset( 0, 1 )
next
といった具合です …

QVBのコントロール配列を二次元配列にする方法

タイトル通りです。
テキストボックスなどをコントロール配列で持つときに二次元配列で持つ方法はないでしょうか?

ご回答の方、宜しくお願いします。

Aベストアンサー

コントロールのIndexプロパティを利用する方法では二次元配列はできません。
しかし、変数としての二次元配列ならできます。

Dim TextBoxes(3, 10) As TextBox

などとすると、テキストボックスの多次元配列ができます。
ただし、この変数にはインスタンスがないので、インスタンスは別に作成してやる必要があります。

以下に例を示します。

名前がTexts、Indexが0のTextBoxを配置します。
フォームモジュールに以下を貼り付けます。

Option Explicit

Private TextBoxes(3, 10) As TextBox

Private Sub Form_Load()

On Error Resume Next
Dim N As Long, M As Long, T As Long

For N = 0 To 2

For M = 0 To 9

T = N * 10 + M
Load Texts(T) 'Load Texts(0)はエラーだが無視される
Set TextBoxes(N, M) = Texts(T)
TextBoxes(N, M).Left = N * 1320
TextBoxes(N, M).Top = M * 300
TextBoxes(N, M).Visible = True

Next M

Next N

End Sub

Private Sub Texts_Click(Index As Integer)

MsgBox "これは(" & (Index \ 10) & ", " & (Index Mod 10) & ")です"

End Sub

この方法を使う場合、TextBoxes(N, M)のIndexプロパティはN * 10 + Mを示すので、注意が必要です。

コントロールのIndexプロパティを利用する方法では二次元配列はできません。
しかし、変数としての二次元配列ならできます。

Dim TextBoxes(3, 10) As TextBox

などとすると、テキストボックスの多次元配列ができます。
ただし、この変数にはインスタンスがないので、インスタンスは別に作成してやる必要があります。

以下に例を示します。

名前がTexts、Indexが0のTextBoxを配置します。
フォームモジュールに以下を貼り付けます。

Option Explicit

Private TextBoxes(3, 10) As TextBox

...続きを読む

QVB6.0でコントロール配列の配列順序を変更したい

掲題の件ですが、たとえばオプションボタンでコントロール配列にしたとき
option(0)、option(1)、…
と追加された順番に従って設定されますが、
option(0)→option(2)
などにコードや設定で後から変更することは可能なのでしょうか?

どのようにすれば変更できるでしょうか。
よろしくお願い致します。

Aベストアンサー

コントロールのプロパティのindexの数値を変えることで変更できます。
ただし、すでに使用済みの番号に変える時は、一度使用されていない番号に変更する必要があります。

下記は一例
option(0)→をoption(2)に変えたい場合、先にoption(2)を現在使用されていない番号に変更する。
option(2)のプロパティ→indexの数値を適当に使用されていない番号に変更する。
それから、option(0)のプロパティ→indexの数値を2に変更する。

これで変更することができると思いますが、どうでしょう?


このカテゴリの人気Q&Aランキング

おすすめ情報