質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

89.20%

Accessマクロで実行モードのフォームのイベントで、そのフォームの他コントロールを操作

解決済

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 1,201

JanTh1989

score 51

Accessマクロにて、複数テーブルで共通のレコード追加フォームの作成を試みています。
その動作の一環として、テーブル名を持つコンボボックスを用意し、選択テーブルの列情報に準拠して、入力欄(ラベル:テキストボックスの組合せ)をフォーム内に設けるようにしようと考えています。
※コンボボックスが空文字の場合は入力欄全削除。

例)
コンボボックス:"テーブルA"選択
テーブルAフィールド:ID、名前、性別、学校名
フォーム配置コントロール:
(Label)ID: textbox
(Label)名前: textbox
(Label)性別: textbox
(Label)学校名: textbox

コントロール配置に向けたコード

Private Sub AddTableNameChange_Change()
    Me.AddTableNameChange.SetFocus

    Dim control As control

    If "" = Me.AddTableNameChange.Text Then
        For Each control In Me.Controls
            If コンボボックス名 <> control.Name Then
                DeleteControl Me.Name, control.Name
            End If
        Next
        Exit Sub
    End If

    Dim dbs As Database
    Dim td As TableDef
    Dim myField As field
    Dim AddLBControl, AddTBControl As control
    Dim AddPosY As Integer

    Set dbs = CurrentDb
    Set td = dbs.TableDefs(Me.AddTableNameChange.Text)

    AddPosY = 100    
    For Each myField In td.Fields
        'コントロール名、ラベル値、各サイズ、位置については、配置できるようになってから調整予定。
        Set AddLBControl = CreateControl(Me.Name, acLabel, , , "", 30, AddPosY, 50, 50)
        Set addtbconstrol = CreateControl(Me.Name, acCommandButton, , , "", 30, AddPosY, 50, 50)
        AddPosY = AddPosY + 30
    Next

End Sub

上記のコードを実行すると、
Set AddLBControl = CreateControl(Me.Name, acLabel, , , "", 30, AddPosY, 50, 50)
で「コントロールの作成と削除は、デザインビューまたはレイアウトビューで行います。」のエラーになります。

別のビューに開きなおせばいい、と考え、
DoCmd.OpenForm Me.Name, acDesign
を足してみたところ、「別のビューに切り替えることはできません。」のエラーになります。

質問

やりたいこととしては、フォーム内のコントロールイベント内で、そのフォーム内のコントロール操作になりますが、これは可能なのでしょうか。
可能でしたら、方法をご教授頂ければと思います。

開発環境

Microsoft Access 2010

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

0

アクティブなフォームのデザインビューへの変更は、
DoCmd.RunCommand acCmdDesignView
デザインビューからフォームビューへの変更は、
DoCmd.RunCommand acCmdFormView
で可能です。

しかし、サンプルを作成して実験してみましたか、自身のフォーム上のコントロールのイベントからでは、実行時エラーになりました。
そもそも、ユーザーが使用中にデザインビューにするのは危険だと思います。

事前にデザインビューに予想される最大数のラベルとテキストボックスを配置しておいて、
「可視」を「いいえ」にして保存します。
必用に応じて、Visible = True で表示させるようにするのが、安全だし高速です。

ラベルとテキストボックスの名前を
Lbl1, Lbl2, ・・・・・・
Txt1, Txt2, ・・・・・・
というようにつけておけば、下記のようにループでまわせます。

Dim i As Long
For i = 1 to td.Fields.Count
    With Me("lbl" & i)
        .Visible = True
        .Caption = td.Fields(i).Name
        .Top = 30 * i + 70
    End With
    With Me("Txt" & i)
        .Visible = True
        .Top = 30 * i + 70
    End With
Next


Accessのフォームではこの方法が一般的です。Excelのユーザーフォームだと使用中にコントロールを追加するというのはよくあるようですが。

質問とは関係ないですか間違いの指摘

    Dim AddLBControl, AddTBControl As control
    '上記の AddLBControl は型指定してないことになり、Variant型になります。
    '面倒でも下記のように変数一つずつ型指定してください。
    Dim AddLBControl As control, AddTBControl As control

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/06/27 16:47

    上の3つのテーブルは、すべて ID フィールドでリンクしているということでしょうか。
    だとしたら、すべて一対一の関係のテーブルということになりますが、データベースでは一対一の関係のデータを一つのテーブルにまとめるというのが原則です。そうすれば、「複数テーブルで共通のレコード追加」という処理は不要になります。
    クエリまたはフォームで必要なフィールドのみ表示させる設計にすればいいでしょう。

    参考リンク
    一対一関係のテーブル設計 - hatena chips https://hatenachips.blog.fc2.com/blog-entry-29.html

    VBでの開発経験がありその経験からの発想のように思いますが、まずは、Accessの基本の機能を理解されてから設計に取り組んだ方が結局近道になると思います。
    それとテーブル設計の基本「正規化」についての理解も必須です。

    連結フォームで作成していけば、VBAなしで大抵のことはできます。それでは不足する部分をVBAで補完するという設計が一般的です。
    Accessの非連結フォームでVBAでゴリゴリ書いていくぐらいなら、VBでAccessテーブルにリンクする設計にした方が融通がきくと思います。

    キャンセル

  • 2019/06/28 10:40

    仰る通り、VB思考が強く、Accessの知識が乏しいため、考えがAccess向け、DB管理向けではないと思います。
    クエリやフォームの扱いもよく分かっていないところがあります。
    回答内容や参考リンクなどの情報を基に、進め方について再検討してみます。

    ありがとうございました。

    キャンセル

  • 2019/06/28 11:25

    Accessおよびデータベースについて基本から学習する場合のおすすめのリンクは下記です。
    もう一度学ぶMS-Access https://www.accessdbstudy.net/
    特に「正規化」「リレーションシップ」の項目の解説は秀逸です。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 89.20%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる
  • トップ
  • VBAに関する質問
  • Accessマクロで実行モードのフォームのイベントで、そのフォームの他コントロールを操作