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

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

新規登録して質問してみよう
ただいま回答率
85.50%
VBA

VBAはオブジェクト指向プログラミング言語のひとつで、マクロを作成によりExcelなどのOffice業務を自動化することができます。

Access

Accessはマイクロソフトによるリレーショナルデータベース管理システムです。オブジェクト指向のアプリケーション作成に対応しており、テーブルや編集をはじめ、クエリ生成、入力フォーム作成、レポート作成など一通りの機能を備えています。

Q&A

解決済

2回答

2419閲覧

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

MP430

総合スコア40

VBA

VBAはオブジェクト指向プログラミング言語のひとつで、マクロを作成によりExcelなどのOffice業務を自動化することができます。

Access

Accessはマイクロソフトによるリレーショナルデータベース管理システムです。オブジェクト指向のアプリケーション作成に対応しており、テーブルや編集をはじめ、クエリ生成、入力フォーム作成、レポート作成など一通りの機能を備えています。

0グッド

0クリップ

投稿2017/04/21 06:55

編集2017/04/21 07:30

###前提・実現したいこと
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

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

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

VB

1Public Function MemoGotFocus() As Long 2 With CodeContextObject 3 .Parent!LabelMemo.Caption = .ActiveControl.Text 4 End With 5End Function 6 7 8'このプロシージャは最初に一回実行すればOK 9Public Sub SetFuncFormOnLoad2() 10 Const FrmLst = "AA注文在庫,BB注文在庫,CC注文在庫" '対象フォームのリスト 11 Const txtLst = "メモ,工場用メモ" '対象テキストボックスのリスト 12 Dim Frm 13 Dim txt 14 15 For Each Frm In Split(FrmLst, ",") 16 DoCmd.OpenForm Frm, acDesign, , , , acHidden '対称フォームを非表示のデザインモードで開く 17 For Each txt In Split(txtLst, ",") 18 Forms(Frm).Controls(txt).OnGotFocus = "=MemoGotFocus()" 'イベントプロパティに関数を関連付け 19 Next 20 DoCmd.Close acForm, Frm, acSaveYes '変更を保存して閉じる 21 Next 22 23End Sub

投稿2017/04/24 08:28

編集2017/04/24 13:56
hatena19

総合スコア33620

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

MP430

2017/04/25 00:31

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

0

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

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

VB

1Option Compare Database 2Option Explicit 3 4Public Function MemoGotFocus() As Long 5 6 With CodeContextObject 7 .Parent!LabelMemo.Caption = .ActiveControl.Text 8 End With 9 10End Function 11 12Public Function FormOnLoad() As Long 13 Const txtLst = "メモ,工場用メモ" '対称テキストボックスのリスト 14 15 Dim txt 16 17 For Each txt In Solit(txtLst, ",") 18 CodeContextObject(txt).OnGotFocus = "=MemoGotFocus()" 19 Next 20 21End Function 22 23 24'このプロシージャは最初に一回実行すればOK 25Public Sub SetFuncFormOnLoad() 26 Const FrmLst = "AA注文在庫,BB注文在庫,CC注文在庫" '対称フォームのリスト 27 28 Dim Frm 29 30 31 For Each Frm In Split(FrmLst, ",") 32 DoCmd.OpenForm Frm, acDesign, , , , acHidden '対称フォームを非表示のデザインモードで開く 33 Forms(Frm).OnLoad = "=FormOnLoad()" 34 DoCmd.Close acForm, Frm, acSaveYes '変更を保存して閉じる 35 Next 36 37End Sub

制限

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

VB

1Private Sub Form_Load() 2 3 '読み込み時のコード 4 5 Call SetFuncFormOnLoad() 6 7End Sub

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

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

投稿2017/04/22 02:18

hatena19

総合スコア33620

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

MP430

2017/04/24 03:02

回答ありがとうございます。 コードを試させていただきました。 この方法だと、裏でロードしているフォームにコードが有効になっているという認識でよかったですか? 既にあるイベント群に追加して、プロシージャを最初に1回実行して次回からは何も実行しないような仕様にはできないでしょうか? 追加したイベントをデザインビューで確認できませんでした(コードは正しく動いています)
hatena19

2017/04/24 03:29

Accessの場合、イベントにVBAコードを関連付ける方法として、下記の2つがあります。 イベントプロパティに、[イベント プロシージャ]と設定して、コードはそのフォーム(またはレポート)のモジュールに プロシージャを記述する方法。 Functionプロシージャを標準モジュールに記述して、そのFunctionをイベントプロパティに直接設定する方法。 回答の方法は、後者の方法を使っています。 通常は、フォームをデザインビューで開いて、イベントプロパティに =呼び出す関数名() というように設定しますが、フォーム数が多いということなので、 標準モジュールに、フォームをデザインビューで開いてイベントプロパティに関数を設定して保存するというのを自動処理するプロシージャ(SetFuncFormOnLoad)を作成して、それを1回だけ実行します。 つまり「プロシージャを最初に1回実行して次回からは何も実行しないような仕様」になっています。
MP430

2017/04/24 04:04

早速の回答ありがとうございます。 今のAccess管理者は私なのですが、私以外が見たときにイベントプロパティに呼び出し関数が載っていないと理解できないか心配しています。デザインビューを保存してイベントプロパティに表示できないでしょうか?
hatena19

2017/04/24 05:06

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

2017/04/24 06:48

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

2017/04/24 08:28

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問