teratail header banner
teratail header banner
質問するログイン新規登録

回答編集履歴

3

補足追記

2018/03/30 08:46

投稿

hatena19
hatena19

スコア34367

answer CHANGED
@@ -92,4 +92,11 @@
92
92
  Private Sub UserForm_Initialize()
93
93
  Prc.Init Sheet1, Me.TextBox1, Me.ComboBox1
94
94
  End Sub
95
- ```
95
+ ```
96
+
97
+ 標準モジュールに、Public変数とプロシージャを記述することでコードの一元化は可能ですが、クラスにすることのメリットは、コードの一元化ができて、なおかつ、
98
+
99
+ > 一つの方法しては変数をpublicにするのも手だがグローバルにすると予想もつかない動きをする可能性がある
100
+
101
+ という危険性も回避できます。
102
+ 例えば、ユーザーフォームを同時に2つ開いて、それぞれで、MyProcクラスを生成して、対象シート、コントロールを設定しても、両者で競合することなく、正しく処理が実行されます。2つは別インスタンスになり、それぞれが独自に変数を所持できますので。

2

サンプルコードの追加2

2018/03/30 08:46

投稿

hatena19
hatena19

スコア34367

answer CHANGED
@@ -53,4 +53,43 @@
53
53
  Private Sub UserForm_Initialize()
54
54
  cTextbox.Bind Me.TextBox1
55
55
  End Sub
56
+ ```
57
+
58
+ 追記2
59
+ ---
60
+ 質問の、fmCustomerEntryName_Configプロシージャを見ると複数のコントロールとシートが必要のようなので、下記の方が希望に近いかな。
61
+
62
+ クラスモジュール MyProc
63
+ ```vba
64
+ Option Explicit
65
+
66
+ Private targetSh As Worksheet
67
+ Private mtxt1 As MSForms.TextBox
68
+ Private mcob1 As MSForms.ComboBox
69
+
70
+ Public Sub Init(ByRef ws As Worksheet, ByRef tb As MSForms.TextBox, ByRef cb As MSForms.ComboBox)
71
+ Set targetSh = ws
72
+ Set mtxt1 = tb
73
+ Set mcob1 = cb
74
+ End Sub
75
+
76
+ Public Sub Exec()
77
+ targetSh.Range("A1").Value = mtxt1.Value
78
+ targetSh.Range("A2").Value = mcob1.Value
79
+ End Sub
80
+ ```
81
+
82
+ ユーザーフォームのモジュール
83
+ ```vba
84
+ Option Explicit
85
+
86
+ Dim Prc As New MyProc
87
+
88
+ Private Sub CommandButton1_Click()
89
+ Prc.Exec
90
+ End Sub
91
+
92
+ Private Sub UserForm_Initialize()
93
+ Prc.Init Sheet1, Me.TextBox1, Me.ComboBox1
94
+ End Sub
56
95
  ```

1

サンプルコードの追記

2018/03/30 05:10

投稿

hatena19
hatena19

スコア34367

answer CHANGED
@@ -2,4 +2,55 @@
2
2
 
3
3
  下記のようなことでしょうか。
4
4
 
5
- [複数のコントロールのイベントを一つのプロシージャにまとめる(ExcelVBA) \- パソコンカレッジ スタッフのひとりごと](https://blog.goo.ne.jp/pc_college/e/9ca2b0c452e9e691cad1dbd2783868cf)
5
+ [複数のコントロールのイベントを一つのプロシージャにまとめる(ExcelVBA) \- パソコンカレッジ スタッフのひとりごと](https://blog.goo.ne.jp/pc_college/e/9ca2b0c452e9e691cad1dbd2783868cf)
6
+
7
+ 追記
8
+ ---
9
+
10
+ 他の人の回答へのコメントを見ました
11
+
12
+ > それぞれのユーザーフォームをみたとき、似たようなイベントするコントロールがあることに気付く。
13
+ > このばあいイベント内の共有部分を標準モジュールでサブルーチン化して呼び出すほうが、コード量が減るし、コードの改変が容易になる。
14
+ > だたし、各フォームによって、似たようなイベントをもつコントロールであってもコントロール名が異なる。
15
+ > 一つの方法しては変数をpublicにするのも手だがグローバルにすると予想もつかない動きをする可能性があるので変数はフォーム内で閉じておきたい。
16
+
17
+ やはり、クラスモジュールで対応するのがベストかと思います。
18
+ 具体的に何をしたいのか不明ですが、とりあえずシンプルなサンプルを。
19
+
20
+ クラスモジュール MyTextBox
21
+ ```vba
22
+ Private WithEvents txtb As MSForms.TextBox
23
+
24
+ 'クラスとテキストボックスを関連付け
25
+ Public Sub Bind(ByVal c As MSForms.TextBox)
26
+ Set txtb = c
27
+ End Sub
28
+
29
+ '共通処理
30
+ Public Sub ProcA()
31
+
32
+ MsgBox "テキストボックスの値は「" & txtb.Value & "」です。"
33
+
34
+ 'ここに共通処理を記述
35
+
36
+ End Sub
37
+
38
+ Private Sub txtb_Change()
39
+ Debug.Print "テキストが「" & txtb.Value & " 」に更新されました。"
40
+ End Sub
41
+ ```
42
+
43
+ ユーザーフォームのモジュール
44
+ ```vba
45
+ Option Explicit
46
+
47
+ Dim cTextbox As New MyTextbox
48
+
49
+ Private Sub CommandButton1_Click()
50
+ cTextbox.ProcA
51
+ End Sub
52
+
53
+ Private Sub UserForm_Initialize()
54
+ cTextbox.Bind Me.TextBox1
55
+ End Sub
56
+ ```