オフィス2007です。
Sub test()
Dim obj As AccessObject
For Each obj In CurrentProject.AllForms
Debug.Print obj.Name
Next
End Sub
---------------------------------
上記のコードでデータベースのすべてのフォーム名は取得できますが
フォーム1に乗っかっている複数のサブフォームを取得するにはどうすればいいのでしょうか?
サブフォームに独自の名前を付けて、IFステートメントを使うしかないですか?
No.4ベストアンサー
- 回答日時:
No.3です。
> Function SFEnumの方が使い方がよくわかりません。
SFEnum関数は、
・SFListup関数の「For Each ~ Next」のループ内
・SFEnum関数自身の中(→再帰呼出)
で使用するために定義した関数ですので、直接呼び出す必要は
ありません。
(2つセットになって、初めて目的の動作をする関数です)
「◆こちらの関数の再帰呼出により~」のコメントがわかりにくかった
ようで、すみません(汗)
以下、かなり大雑把に、前回のコードの説明をしてみます。
1)SFListup関数内のループで、当該データベース内のフォームを、
デザインビューで順次開いていく
2)当該フォームを「Frm」変数に記録した上で、指定したフォーム内
のサブフォームの情報を確認するSFEnum関数を呼び出す
3)SFEnum関数では、その直下にある全てのコントロールを確認
(→「For Each Cntl In Frm.Controls」以降)
4)コントロールがサブフォームだった場合は、更に詳細を確認
(→「If Cntl.ControlType = acSubform Then」以降)
5-a)サブフォームに「ソースオブジェクト」が設定されていない場合
(→「Case sSource = ""」):
イミディエイトウィンドウに、表示用フォームが指定されていないこと
を明示するため、sSourceに「(オブジェクト未設定)」と記録
5-b)サブフォームの「ソースオブジェクト」に、テーブルやクエリを直接
指定している場合(→「Case sSource Like "*.*"」):
※サブフォームには、「テーブル.(テーブル名)」の形を使用すると
テーブルやクエリを指定できるため、これを曖昧検索で確認
テーブル/クエリの中にサブフォームは設置できないので、その
サブフォームは確認終了
【訂正】
半角ピリオドはフォーム名に使用できないのですが、全角なら使用
可能なので、「sSource Like "*.*"」ではなくInStr関数を使用
して、「半角ピリオドを含むかどうか」を判定するべきでした(汗)
(→「Case InStr(1, sSource, ".", vbBinaryCompare) > 0」、と)
5-c)サブフォームの「ソースオブジェクト」にフォームを指定している
場合(→「Case Else」):
その下に、さらにサブフォームが存在する可能性があるため、
SFEnum関数で確認(→sFeNum関数の中で、同じSFEnum関数
を呼出:これを再帰呼出といいます)
6)それぞれの場合の確認が終わったら、引数iLvに記録されている
現在の階層数に合わせてスペースを追加して、変数sSourceに
記録した情報を、引数sEnumに追記
(→「sEnum = Space(iLv * 5) & Cntl.Name & "【" & sSource & "】"」)
・・・以上です。
この「再帰呼出」というのは、慣れないとちょっとわかりにくいと思います
ので(→少なくとも私自身はVBAを扱うようになってからも暫くは手が
出せていませんでした(汗))、気長に眺めてみることをお勧めします。
この再帰呼出の部分をさらに大雑把に説明すると、
1)デザインビューで開いたフォームにサブフォームがあるか確認
2)サブフォームがあったら、親フォームの情報をsEnumに記録する
前に、iLvに「1」を加算(→階層の記録)して、子フォームに移動
3)子フォームにもサブフォーム(孫)があったら、子フォームの情報を
sEnumに記録する前に、孫フォームに移動
4)サブフォームがなくなったところで、sEnumに自身の情報を記録
して、直接の呼出元(孫まであった場合は子の階層)に戻る
5)戻ってきたところでsEnumに自身の情報を追加して、同じく直接
の呼出元(子の場合は親の階層)に戻る
6)SFListup関数にまで戻ったら、イミディエイトウィンドウに表示
となります。
SFEnum関数内で定義したRslやCntlなどの変数は、再帰呼出を
しても上書されません。
(あたかも「Rsl’」や「Cntl’」という変数が別に用意されたかのように、
繰り返した階層ごとの値が、パソコンのメモリ内に保持されます)
・・・多分ここが、一番感覚がついてこないところではないかと・・・(汗)
・・・長くなりましたが(汗)、以上です。
No.3
- 回答日時:
遅れ馳せながら、再帰呼出により全てのサブフォームをデバッグ ウィンドウに
出力させる関数を作成してみました。
親子関係は、半角スペース5個のインデントで表す形としました。
また、サブフォームのコントロール名に加え、ソースオブジェクトも同時に
表示させています。
なお、サブフォームのソースオブジェクトが空白だったり、テーブル・クエリを
指定した場合にも念のため対応しました。
'◆イミディエイトウィンドウなどから呼び出すのはこちらの関数になります◆
Public Function SFListup() As Boolean
On Error GoTo エラー処理
Dim Rsl As Boolean, Obj As AccessObject, Frm As Form
Dim sName As String, sEnum As String
For Each Obj In CurrentProject.AllForms
sName = Obj.Name
DoCmd.OpenForm sName, acDesign
Set Frm = Forms(sName)
sEnum = "" '初期化
Rsl = SFEnum(Frm, sEnum, 0)
If Rsl = False Then
sEnum = Space(5) & "★エラーにより確認不可★" & vbCrLf
ElseIf sEnum = "" Then
sEnum = Space(5) & "(サブフォームなし)" & vbCrLf
End If
Debug.Print "~~~以下『" & sName & "』配下~~~"
Debug.Print sEnum
DoCmd.Close acForm, sName
Next
終了処理:
SFListup = Rsl
Set Obj = Nothing
Set Frm = Nothing
Exit Function
エラー処理:
MsgBox Err.Number & ":" & Err.Description
Resume 終了処理
End Function
'◆こちらの関数の再帰呼出により、全階層のサブフォームを取得します◆
Private Function SFEnum(Frm As Form, sEnum As String, ByVal iLv As Integer) As Boolean
On Error GoTo エラー処理
'[Frm=サブフォームを確認するフォーム, sEnum=デバッグウィンドウに表示する情報を記録, iLv=サブフォームの階層を記録]
Dim Rsl As Boolean, Cntl As Control, sSource As String
iLv = iLv + 1
For Each Cntl In Frm.Controls
If Cntl.ControlType = acSubform Then
sSource = Cntl.SourceObject
Select Case True
Case sSource = ""
Rsl = True
sSource = "(オブジェクト未設定)"
Case sSource Like "*.*"
Rsl = True
Case Else
Rsl = SFEnum(Cntl.Form, sEnum, iLv)
End Select
If Rsl = False Then GoTo 終了処理
sEnum = Space(iLv * 5) & Cntl.Name & "【" & sSource & "】" & vbCrLf & sEnum
End If
Next
Rsl = True
終了処理:
SFEnum = Rsl
Set Cntl = Nothing
Exit Function
エラー処理:
MsgBox Err.Number & ":" & Err.Description, vbCritical, "SFEnum"
Rsl = False
Resume 終了処理
End Function
・・・以上、参考まで。
ご回答がとても遅くなってしまい申し訳ございませんでした。
二つのプロシージャー
・Function SFListup
・Function SFEnum
を標準モジュールに張り付けて実行してみました。
Function SFListupはVBE画面でF5を押したら実行され、
イミティエイドウインドウに求める結果が表示されたのですが
Function SFEnumの方が使い方がよくわかりません。
F5を押しても何も起きないです・・・
せっかく教えていただいたのに
うまく使えてなくてごめんなさい。
もっと勉強してみます。
No.2
- 回答日時:
孫フォームまでですが、フォーム1が有った場合に
親子関係を分かりやすくしたつもり。
Sub b()
Dim ctl As Control
Dim ctl2 As Control
Dim frm As Object
Dim sMsg As String
For Each frm In CurrentProject.AllForms
If frm.Name = "フォーム1" Then
DoCmd.OpenForm frm.Name, view:=acDesign, windowmode:=acIcon
For Each ctl In Forms(frm.Name).Controls
If ctl.ControlType = acSubform Then
sMsg = "親=" & frm.Name & " 子=" & ctl.Name
For Each ctl2 In ctl.Form
If ctl2.ControlType = acSubform Then
sMsg = sMsg & " 孫=" & ctl2.Name
End If
Next
Debug.Print sMsg
End If
Next
DoCmd.Close acForm, frm.Name
End If
Next
End Sub
No.1
- 回答日時:
こんにちは。
すべてのフォームと、それに乗っているサブフォーム名をイミディエイトに出力します。
Sub test()
Dim obj As AccessObject
For Each obj In Application.CurrentProject.AllForms
Macro2 obj.Name
Next
End Sub
Sub Macro2(ByVal fName As String)
Dim ctrl As Control
Dim sbf As SubForm
Dim str As String
DoCmd.OpenForm fName
str = "**** " & fName & "のサブフォーム名 ****" & vbCrLf
For Each ctrl In Forms(fName).Controls
On Error GoTo 10
Set sbf = ctrl
str = str & vbTab & sbf.Name & vbCrLf
20:
Next
DoCmd.Close acForm, fName
Debug.Print str
Exit Sub
10:
Resume 20
End Sub
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
このQ&Aを見た人はこんなQ&Aも見ています
-
字面がカッコいい英単語
あなたが思う「字面がカッコいい英単語」を教えてください。
-
フォロワー20万人のアカウントであなたのあるあるを披露してみませんか?
あなたが普段思っている「これまだ誰も言ってなかったけど共感されるだろうな」というあるあるを教えてください
-
映画のエンドロール観る派?観ない派?
映画が終わった後、すぐに席を立って帰る方もちらほら見かけます。皆さんはエンドロールの最後まで観ていきますか?
-
海外旅行から帰ってきたら、まず何を食べる?
帰国して1番食べたくなるもの、食べたくなるだろうなと思うもの、皆さんはありますか?
-
天使と悪魔選手権
悪魔がこんなささやきをしていたら、天使のあなたはなんと言って止めますか?
-
Access サブフォームでの選択行の取得
その他(データベース)
-
サブフォームに対してGoToRecordするには?
その他(Microsoft Office)
-
Access2000 サブフォームのRecordSet取得法
Access(アクセス)
-
-
4
アクセスVBAのMe!と[ ]
Access(アクセス)
-
5
【ACCESS2003】サブフォーム名を変数に入れたい
Visual Basic(VBA)
-
6
ACCESS──メインフォームでサブフォームのレコード件数をカウントしたい
Access(アクセス)
-
7
VBとアクセスでSQL文に変数を使いたいのですが
Visual Basic(VBA)
-
8
サブフォームの新規レコードに移動したい アクセス
Access(アクセス)
-
9
親フォームからサブフォームのレコードソースを設定
Access(アクセス)
-
10
アクセスのフォームのビューが表示されないのですが、
その他(データベース)
-
11
Accessのレポート上のテキストボックス値を設定したい
その他(データベース)
-
12
access サブフォームにリストを表示させたいが一件しかレコードが表示されない
Access(アクセス)
-
13
サブフォームでのダブルクリックイベント
Access(アクセス)
-
14
フォーム上の全てのコントロールを取得したい
Access(アクセス)
-
15
どこにもフォーカスを当てたくない
Access(アクセス)
-
16
Access VBAでタブコントロールで選択するタブをしていするには。
Access(アクセス)
-
17
Accessで埋め込んだサブフォーム(データシート形式)でデータ追加ができない
Access(アクセス)
-
18
日付型のフィールドに空白を入れる方法を教えてください
その他(データベース)
-
19
[Access]帳票フォームにて連続する非連結コントロールに個々の値を入れるには
Access(アクセス)
-
20
Access ¥マークを表示しない
Excel(エクセル)
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・人生のプチ美学を教えてください!!
- ・10秒目をつむったら…
- ・あなたの習慣について教えてください!!
- ・牛、豚、鶏、どれか一つ食べられなくなるとしたら?
- ・【大喜利】【投稿~9/18】 おとぎ話『桃太郎』の知られざるエピソード
- ・街中で見かけて「グッときた人」の思い出
- ・「一気に最後まで読んだ」本、教えて下さい!
- ・幼稚園時代「何組」でしたか?
- ・激凹みから立ち直る方法
- ・1つだけ過去を変えられるとしたら?
- ・【あるあるbot連動企画】あるあるbotに投稿したけど採用されなかったあるある募集
- ・【あるあるbot連動企画】フォロワー20万人のアカウントであなたのあるあるを披露してみませんか?
- ・映画のエンドロール観る派?観ない派?
- ・海外旅行から帰ってきたら、まず何を食べる?
- ・誕生日にもらった意外なもの
- ・天使と悪魔選手権
- ・ちょっと先の未来クイズ第2問
- ・【大喜利】【投稿~9/7】 ロボットの住む世界で流行ってる罰ゲームとは?
- ・推しミネラルウォーターはありますか?
- ・都道府県穴埋めゲーム
- ・この人頭いいなと思ったエピソード
- ・準・究極の選択
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
サブフォームに対してGoToRecor...
-
クエリで出来た表にチェックボ...
-
ACCESSサブフォームにデータ反...
-
ACCESS──メインフォームでサブ...
-
Excel VBA 全部のUserForm名
-
Access2010 サブフォームの並び...
-
Accessでサブフォームのボタン...
-
サブフォームのあるフォームか...
-
Accessで埋め込んだサブフォー...
-
親・子リンクフィールドの設定...
-
Access SUMの結果が何もない時...
-
ACCESSでメインフォーム上のオ...
-
ACCESS2000で、エラーの理由が...
-
Accessでサブフォーム側の値の...
-
access フォーム上で複数行の...
-
アクセス2003のサブフォームの...
-
サブフォームに変数を代入し、R...
-
サブフォームのフォームフッタ...
-
Access2007が強制終了する事象...
-
ACCESSで条件によってサブフォ...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
サブフォームに対してGoToRecor...
-
クエリで出来た表にチェックボ...
-
ACCESS──メインフォームでサブ...
-
サブフォームを非表示させる方...
-
親・子リンクフィールドの設定...
-
親フォームからサブフォームの...
-
ACCESSサブフォームにデータ反...
-
Access VBA には Gridはないで...
-
ACCESSにて
-
アクセス2003のサブフォームの...
-
サブフォームのあるフォームか...
-
ACCESSのフォームで列固定?
-
Accessで埋め込んだサブフォー...
-
ACCESSで条件によってサブフォ...
-
ACCESS VBA メインフォーム及び...
-
サブフォームに変数を代入し、R...
-
ACCESS サブ・メインフォーム...
-
ACCESSのサブフォームコピーに...
-
Access 登録ボタンからサブフォ...
-
Access Dsum関数
おすすめ情報