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

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

ただいまの
回答率

89.98%

AccessVBAの類似フォームのプロシージャコピー

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 959

MP430

score 38

前提・実現したいこと

Accessで類似フォームのプロシージャのコピーですが、効率のいい方法を教えて下さい。同じイベントを名前の違うフォームにコピーするのですが、同じコードの繰り返しになってしまします。1箇所にまとめる方法がありませんでしょうか?

該当のソースコード

'以下フォーム"AA注文在庫"
Private Sub メモ_GotFocus()

    Call MemoGotFocus(Me.Parent, Me.ActiveControl)

End Sub

Private Sub 工場用メモ_GotFocus()

    Call MemoGotFocus(Me.Parent, Me.ActiveControl)

End Sub


'以下Module1
Public Function MemoGotFocus(ParentFm As Form, txt As TextBox) As String

    ParentFm.LabelMemo.Caption = txt.Text

End Function

現状

Form(AA注文在庫)のメモ、工場用メモにフォーカスが移ったら親フォームのLabelMemoに拡大表示される仕様です。
Form(BB注文在庫)、Form(CC注文在庫)、など類似フォームが十数個あります。
1箇所でコーディングできないでしょうか?

補足情報(言語/FW/ツール等のバージョンなど)

windows10/Access2016

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

回答 2

checkベストアンサー

+1

上の回答の関数の改良版
テキストボックスのイベントプロパティに直接、関数を設定。
こちらの方が分かりやすいですね。

Public Function MemoGotFocus() As Long
    With CodeContextObject
        .Parent!LabelMemo.Caption = .ActiveControl.Text
    End With    
End Function


'このプロシージャは最初に一回実行すればOK
Public Sub SetFuncFormOnLoad2()
    Const FrmLst = "AA注文在庫,BB注文在庫,CC注文在庫" '対象フォームのリスト
    Const txtLst = "メモ,工場用メモ" '対象テキストボックスのリスト
    Dim Frm
    Dim txt

    For Each Frm In Split(FrmLst, ",")
        DoCmd.OpenForm Frm, acDesign, , , , acHidden   '対称フォームを非表示のデザインモードで開く
        For Each txt In Split(txtLst, ",")
            Forms(Frm).Controls(txt).OnGotFocus = "=MemoGotFocus()" 'イベントプロパティに関数を関連付け
        Next
        DoCmd.Close acForm, Frm, acSaveYes    '変更を保存して閉じる
    Next

End Sub

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2017/04/25 09:31

    本当に、本当にありがとうございました。
    やりたいことができました。
    このコードをベースに応用できそうです。

    キャンセル

0

1箇所でコーディングできないでしょうか?

下記のコードを標準モジュール(Module1)に記述後、
SetFuncFormOnLoad を一回だけ実行してください。

Option Compare Database
Option Explicit

Public Function MemoGotFocus() As Long

    With CodeContextObject
        .Parent!LabelMemo.Caption = .ActiveControl.Text
    End With

End Function

Public Function FormOnLoad() As Long
    Const txtLst = "メモ,工場用メモ" '対称テキストボックスのリスト

    Dim txt

    For Each txt In Solit(txtLst, ",")
        CodeContextObject(txt).OnGotFocus = "=MemoGotFocus()"
    Next

End Function


'このプロシージャは最初に一回実行すればOK
Public Sub SetFuncFormOnLoad()
    Const FrmLst = "AA注文在庫,BB注文在庫,CC注文在庫" '対称フォームのリスト

    Dim Frm


    For Each Frm In Split(FrmLst, ",")
        DoCmd.OpenForm Frm, acDesign, , , , acHidden '対称フォームを非表示のデザインモードで開く
        Forms(Frm).OnLoad = "=FormOnLoad()"
        DoCmd.Close acForm, Frm, acSaveYes '変更を保存して閉じる
    Next

End Sub

制限

フォームで、「読み込み時」にマクロかイベントプロシージャが設定してあると、上書きしてしまうので、
上記のコードの OnLoad を OnOpen に変更して「開く時」イベントと関連付けてください。
「開く時」イベントも使用している場合は、一箇所コーディングは諦めて、
各フォームの「読み込み時」時イベントで、SetFuncFormOnLoad を呼び出してください。

Private Sub Form_Load()

    '読み込み時のコード

    Call SetFuncFormOnLoad()

End Sub

イベントの引数を利用したり、もっと複雑なことをする場合は、クラスモジュールを使うことになります。その場合は、下記の私(hatena19)の回答を参考にしてください。

VBA - Access VBA クリックイベントをまとめたい(26259)|teratail

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2017/04/24 14:06

    SetFuncFormOnLoadを一回実行後、フォームをデザインビューで開いて、テキストボックスの「フォーカス取得後」プロパティを確認してみてください。
    =MemoGotFocus()
    と設定されているはずです。それではだめですか。

    キャンセル

  • 2017/04/24 15:48

    プログラムは動くんですがプロパティに表示がないです。なぜでしょう?

    キャンセル

  • 2017/04/24 17:28

    あっ、すみません。フォームの「読み込み時」プロパティの方を確認してください。
    そこに、
    =FormOnLoad()
    と設定されていると思います。
    そこで、テキストボックスの「フォーカス取得時」に、
    =MemoGotFocus()
    と設定するという2段階になっています。

    ちょっと分かりにくいかも。

    キャンセル

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

  • ただいまの回答率 89.98%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

同じタグがついた質問を見る