• ベストアンサー

コントロールが配列かどうかを知るには?

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で値を取得できるのですが。 よろしくお願いします。

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

  • ベストアンサー
  • Masato_a
  • ベストアンサー率21% (13/60)
回答No.4

新しいアルゴリズムを思いつきました。 コントロール配列って、たしか、同じ名前を共有しますよね。 だから、For Each ・・の中で、Control.Name を参照して、同じ名前が 2>= 出てきたら・・・と言うのは、いかがですか?

Magoichi
質問者

お礼

Masato_aさん、再度のご回答どうもありがとうございます。 なるほど!全てのオブジェクトの数だけ配列を用意してカウントする方法ですね。For Each文でオブジェクトを取得した場合、コントロール配列は必ずしも連続して取得できないので単純なコントロールブレイクではだめそうですが、全てのオブジェクトに対してカウントすれば確かによさそうですね。早速試してみます。 処理スピードとメンテナンスの方法等から総合的に判断して、こちらの方法をとるか、On Errorでの処理を取るか、一つ一つ場合分けするかを検討します。 どうもご回答ありがとうございました。

その他の回答 (3)

  • nishi6
  • ベストアンサー率67% (869/1280)
回答No.3

ANo.#1に >そうですね。なるべくなら On Error文を使いたくないんですよ。・・・ とありましたので、難しいことは分かりませんが tag にコントロール配列だという印(しるし)をつけたらどうですかね。スマートかどうかは判断しかねますが簡明にはなります。 On Error GoTo 0 ですが、エラー判定するべき箇所が終わったのでエラー処理ルーチンを無効にする意味で書きました。この後、どのような処理を書くかわかりませんので。エラー判定をずっと引きずりたくない意味です。書き方としては個人的な癖かもしれません。現プロシージャは終わってしまうので不要?でしょうか。

Magoichi
質問者

お礼

nishi6さん、早々のレスポンスありがとうございます。 実は最初tagに目印をつけようかと思ったのですが、既にtagは他の目的に使っていまして、桁を増やしたりしたくはないなと考えておりました。ちょっと修正箇所が多くなりそうなので。 あの・・・、「スマート」とは言葉が悪く、良識を疑われても仕様がない表現でした。謹んでお詫び申し上げます。もちろんMasato_aさんやnishi6さんの方法を悪く言うつもりはありませんでした。どうぞお気を悪くなさらないでください。 On Error GoTo 0 の使い方は存じませんでした。ありがとうございます。 矢張り、Controlで取得した場合、IsArray関数で配列とみなされないのは仕様なんですかね。 再度のご回答どうもありがとうございました。

  • nishi6
  • ベストアンサー率67% (869/1280)
回答No.2

普通に調べてエラーが起きたら何もしないのは? 下記ではコントロール配列だけ<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

Magoichi
質問者

お礼

nishi6さん、どうもご回答ありがとうございます。 Masato_aさんのお礼にもお答えいたしましたが、On Error文で処理するのは最終手段にしようと思います。 なぜコントロールを使用すると、コントロール配列はIsArray関数で識別できないのでしょうかね?もちろんVarType 関数でもvbArrayは返しませんでした。 それと質問なのですが、 >  Err.Clear: On Error GoTo 0 の後半部分の On Error GoTo 0 とはどのような処理なのでしょうか? たった今確認しましたところ、うまく動きましたが、GoTo 0の行き先がわかりません。再びご回答を賜りたく存じます。 ご回答どうもありがとうございました。

  • Masato_a
  • ベストアンサー率21% (13/60)
回答No.1

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

Magoichi
質問者

お礼

Masato_aさん、ご回答どうもありがとうございます。 そうですね。なるべくなら On Error文を使いたくないんですよ。On Errorで飛ばして、そこでErr.Numberで判断するのは、処理的には変わらないのですが、気の持ちようというか、他にスマートな方法がないかなーって思ってしまいます。 フォームにオブジェクトがたくさんあるので、場合分けするのも大変なんですが、どうしようもなくなったら、On Errorか、一つ一つ聞いていくかにすると思います。 ご回答どうもありがとうございました。

関連するQ&A

  • VBAでコントロール配列を持つことは可能ですか?

    Excel2002、OSはXPです。 VBではコントロールに配列を持つことが出来ましたが、 VBAでコントロール配列を持つことは可能でしょうか? やりたいことはユーザーフォームにラベルを100個ぐらい貼り付けて、 テキストボックス入力した値がCell(i,1)と等しければ、 i番目のラベルのCaptionに文字を入力したい。という感じです。 もしVBのようにコントロール配列を持てれば、 If TextBox1.text=Cells(i,1) Then Label(i).Caption="~~" という風に出来るのですが、どうも配列の設定がVBのようにできません。 プロパティにINDEXが無いですし、オブジェクト名を同じにしたら エラーとなってしまいますし。。 もし出来ないのであれば、何か回避策のようなものはないでしょうか? 力技で100個IFを書けば出来ることは出来るのですが・・ If TextBox1.text=Cells(i,1) Then If i = 1 Then Label1.Caption="~~" ElseIf i=2 then Label2.Caption="~~" ・・・・

  • フォーム上の全てのコントロールを取得したい

    フォーム上の全てのコントロールを取得したいです。 (サブフォームも含め) 自分なりにVBAで考えてみたのがこれです。 Sub test() Dim 数 As Long For Each 数 In Form_フォーム1.Controls.Count ’Debug.Print ? End If Next End Sub でもこれだけでもデバックしてみると 「コンハ゜イルエラー for Eachは、コレクション オブジェクトまたは配列でのみ繰り返しを実行します。」 となります。 答えを教えてください! よろしくお願いします。 (アクセス2003です)

  • VB.Net Tabコントロール中のすべてのタブで

    お世話になります。 Visual Studio 2012 を Windows 7 64Bit  にて使用しております。 Tabコントロールの全てのタブのタグ(Tag) に値を設定しており、変数と各タブページに格納してあるTag の値が一致したら、そのタブページのインデックスを取得できればと思っておりますが、 For Each Next 文にてそれをどう実現すればいいか困っております。 以下の文は プロパティ的にはめちゃくちゃですが、ニュアンスとして、こんな感じで実現できればと思っております。 指定タブコントロールの全てのタブの中でTagの値が 123 のタブがあったら、そのタブインデックスを取得する     Dim Flg As Integer = 0     For Each TabPage In Me.TabControl1.TabPages         If TabPage.Tag = 123 Then             Flg = TabPage.Index()             Exit For         End If     Next 何卒よろしくお願いいたします。

  • VB2005 コントロール配列について教えていただけませんか?

    現在VB2005を用いてプログラムを行なっている初心者です。 ここのサイトでVB2005ではコントロール配列は使用できないことを知りました。そこで、例えばフォーム上にTextBoxを5個配置して、各TextBoxに入力された値を配列に格納するのにはどのようにすれば良いでしょうか? data(0) = textbox1.text data(1) = textbox2.textと一つずつやるしかないでしょうか・・・ For文などを用いて簡単にできる方法を教えてください。 よろしくお願い致します。

  • jqueryのajax()内からグローバル配列に

    jqueryのajax(){success: function()内からグローバル連想配列に値を格納したい。 jqueryのajax()でhtmlファイルを読み込み配列に格納。 その後他の関数で使いたいと考えていますが グローバル連想配列に格納できません。 success: function()内でさらに関数を定義もして見ましたが反応せず。。。 (プルダウンメニューを変更したら実行する関数) 以下ソースになります。 ----------------------------------------------------------- $(function() { objectarray = new Object(); $.ajax({ type: 'GET', url: 'hoge.html', dataType: 'html', success: function(data) { var text = [];   $(data).each(function(i){ text = $(this).text().split("\n"); }); var alldata = $.grep(text, function(e){return e;});//空白やデータなしを削除 for(i=0; i<alldata.length; i++){ objectarray[i] = (alldata[i]); alert("forの中" + objectarray[i]);//取得できた } alert("forの外" + objectarray);//取得できた return objectarray;//あってもなくても変わらない。。。 }, error:function() { alert('問題がありました。htmlデータがありませんでした。'); }             //return objectarray;←有効にするとjsが認識されなくなります。 }); alert("ajaxの外" + objectarray[0]);//何も表示されない、firebugでみるとobjectarrayには値が入っている。 }); ----------------------------------------------------------- 上記はnew Object()でやっておりますがnew Array()でも同じ結果でした。 回避策をご教授いただけましたら幸いです。 どうぞよろしくお願いいたします。

  • VB.Netのコントロール名の操作について

    VB.Netのコントロール名の操作について教えて下さい。 変数Aに代入されている値(コントロール名)から、そのコントロールがフォーム上に存在するかどうか判断し、存在すればそのコントロールに入力されている値を取得したいのですが、ロジックがよくわかりません。 下記のように作りましたがエラーがでます。 どなたか教えて下さいm(_ _)m Dim CntWk As Control Dim objwk As Object Dim 変数A As String For Each CntWk In objwk If cntKoumoku.Name = 変数A Then    MsgBox(cntKoumoku.Visible)  End If Next ちなみにエラーは、  「オフジェクト参照がオフジェクトインスタンスに設定されていません」と出ます。 これはロジックの問題外かと思いますが、.Netに不慣れなためよくわかりません。

  • コントロールをロックしたい

    現在、VB.NETのWINDOWSアプリケーションで開発しており、DBはSqlserver2005を使用しています。 フォームLoad時に、指定したテキストボックスやボタンをロックする(readonly)共通関数を作成しようと考えています。 そこで、どのように記述すればいいか教えて下さい。 (1)フォームロード時 共通関数LookControlを実行する際、引数にコントロール名を渡したいのですが、  どのようにすればいいでしょうか?   Private Sub フォーム_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load 'テキストボックスの場合 Call LookControl(???, True) ←コントロール名の渡し方 'コンボボックスの場合 Call LookControl(???, True) 'ボタンの場合 Call LookControl(???, True) End Sub (2)共通関数LookControl  どのコントロールが引数で渡されてもロックができる関数を作りたい。  Module mod共通関数_表示 Public Sub LookControl(ByVal pControl As Control, ByVal pReadFlg As Boolean) Dim Textbox As TextBoxBase 'Dim Combbox As ComboBox 'Dim Bottan As Button Try For Each cldControl As Control In pControl.Controls If pControl.HasChildren = True Then LookControl(cldControl, pReadFlg) End If ' Select Case True Case TypeOf cldControl Is TextBoxBase TextBox = DirectCast(cldControl, TextBoxBase) TextBox.ReadOnly = pReadFlg Case TypeOf cldControl Is ComboBox             ??? Case TypeOf cldControl Is Button             ??? End Select Next Catch oExcept As Exception '例外が発生した時の処理 MessageBox.Show(oExcept.ToString, "例外発生") End Try End Sub End Module

  • コントロールを削除すると、一つ飛ぶ アクセス

    こんばんは。よろしくお願いします。 フォーム上のイメージを削除してるのですが Sub test() Dim ctl As Control Dim FormName As String FormName = "フォーム2" DoCmd.OpenForm FormName, acDesign For Each ctl In Forms(FormName).Controls If ctl.Name Like "イメージ*" Then Debug.Print ctl.Name DeleteControl FormName, ctl.Name End If Next ctl End Sub これをすると、コントロールが一つ飛ばされます。 イミディエイトウインドウで値を確認すると イメージ0 イメージ2 イメージ4 になりました。 1、3、5が飛ばされました。 実行結果は画像のような感じです。 なぜ飛ばされちゃうのでしょうか? 普段、For Each ctl In Forms(FormName).Controlsを使う分には値が飛ばされる事はないので DeleteControl FormName, ctl.Nameが原因だと思うのですが、 全ての「イメージ」で始まるコントロールを削除したい場合、どうすえばいいですか?

  • コントロール配列と同じような扱い方

    TextBox1、TextBox2、TextBox3・・・・TextBox10 と10個のテキストボックスにVB6で使っていたコントロール配列と同じような処理の仕方をコードで教えていただけませんか。 for i=0 to 9 TextBox(i).Text=i next i 上記のコードをVB.NETで書くとすれば、どのように書けばいいかということさえわかれば、なんとか頑張れる気がします。

  • C#でのコントロール配列について

    C#でのコントロール配列について ピクチャーボックスを配列にして動的生成しています (日本語おかしい…?) そこで質問です。 あるピクチャーボックスをクリックすると クリックされたピクチャーボックスの値(?)とかを取得 (たとえば、Nameとか) 1つだけの場合なら、イベントのClickでできたんですが 配列にすると、どうすればいいのかわからなくなりました わかりやすいサイトとかあったら教えてください!