[ 初めての方へ | 一覧(最新更新順) | 全文検索 | 過去ログ ]
『【ユーザーフォーム】ラベルのクリックイベントのまとめ方』(おおとりさん)
いつも参考にさせていただいております。
ユーザーフォームのラベルのイベント処理について
ご教示いただけますでしょうか。
ユーザーフォーム上にラベルが20個ほどあり、
それぞれにクリックイベントを作成したいと考えております。
イベント処理の中身は同じで
ラベル1がクリックされたらテキストボックス1〜10を処理
ラベル2がクリックされたらテキストボックス11〜20を処理
・・・
といった流れです。
クリックイベントのまとめ方、クリックされたラベルの取得の仕方について
ご教示いただけますと幸いです。
以上、宜しくお願いいたします。
< 使用 Excel:Excel2016、使用 OS:Windows10 >
>ユーザーフォーム上にラベルが20個ほどあり、 >ラベル1がクリックされたらテキストボックス1〜10を処理 >ラベル2がクリックされたらテキストボックス11〜20を処理 でラベルが3〜20をクリックした時、テキストボックスとの関連はどうなるのですか。 ラベル1=テキストボックス1ではないのですか。 (・・・) 2022/08/09(火) 11:06
>クリックイベントのまとめ方、クリックされたラベルの取得の仕方 とりあえず↑だけ考えて...
'正攻法(共通サブに自身を渡す)
Option Explicit
Private WithEvents Lbl1 As MSForms.Label
Private WithEvents Lbl2 As MSForms.Label
Private WithEvents Lbl3 As MSForms.Label
Private WithEvents Lbl4 As MSForms.Label
Private WithEvents Lbl5 As MSForms.Label
Private WithEvents Lbl6 As MSForms.Label
Private Sub Lbl1_Click()
LblsClicked Lbl1
End Sub
Private Sub Lbl2_Click()
LblsClicked Lbl2
End Sub
Private Sub Lbl3_Click()
LblsClicked Lbl3
End Sub
Private Sub Lbl4_Click()
LblsClicked Lbl4
End Sub
Private Sub Lbl5_Click()
LblsClicked Lbl5
End Sub
Private Sub Lbl6_Click()
LblsClicked Lbl6
End Sub
Private Sub LblsClicked(l As MSForms.Label)
MsgBox l.Name
End Sub
Private Sub UserForm_Initialize()
Set Lbl1 = Me.Controls.Add("Forms.Label.1", "Lbl1")
Set Lbl2 = Me.Controls.Add("Forms.Label.1", "Lbl2")
Set Lbl3 = Me.Controls.Add("Forms.Label.1", "Lbl3")
Set Lbl4 = Me.Controls.Add("Forms.Label.1", "Lbl4")
Set Lbl5 = Me.Controls.Add("Forms.Label.1", "Lbl5")
Set Lbl6 = Me.Controls.Add("Forms.Label.1", "Lbl6")
Lbl1.Top = 3 + Lbl1.Height * 0
Lbl2.Top = 3 + Lbl1.Height * 1
Lbl3.Top = 3 + Lbl1.Height * 2
Lbl4.Top = 3 + Lbl1.Height * 3
Lbl5.Top = 3 + Lbl1.Height * 4
Lbl6.Top = 3 + Lbl1.Height * 5
Dim i As Long
For i = 1 To 6
With Me.Controls("Lbl" & i)
.Caption = i
.SpecialEffect = fmSpecialEffectRaised
End With
Next
End Sub
'お遊び(透明なラベルを上にかぶせてクリック位置から逆算する)
Option Explicit
Private Lbl1 As MSForms.Label
Private Lbl2 As MSForms.Label
Private Lbl3 As MSForms.Label
Private Lbl4 As MSForms.Label
Private Lbl5 As MSForms.Label
Private Lbl6 As MSForms.Label
Private WithEvents LblCv As MSForms.Label
Private Sub LblCv_MouseDown(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single)
If X < 0 Or Y < 0 Then Exit Sub
If X > LblCv.Width Or Y > LblCv.Height Then Exit Sub
If Button = 1 Then
Dim h As Single
h = Lbl1.Height
MsgBox Int(Y / h) + 1 & "番"
End If
End Sub
Private Sub UserForm_Initialize()
Set Lbl1 = Me.Controls.Add("Forms.Label.1", "Lbl1")
Set Lbl2 = Me.Controls.Add("Forms.Label.1", "Lbl2")
Set Lbl3 = Me.Controls.Add("Forms.Label.1", "Lbl3")
Set Lbl4 = Me.Controls.Add("Forms.Label.1", "Lbl4")
Set Lbl5 = Me.Controls.Add("Forms.Label.1", "Lbl5")
Set Lbl6 = Me.Controls.Add("Forms.Label.1", "Lbl6")
Lbl1.Top = 3 + Lbl1.Height * 0
Lbl2.Top = 3 + Lbl1.Height * 1
Lbl3.Top = 3 + Lbl1.Height * 2
Lbl4.Top = 3 + Lbl1.Height * 3
Lbl5.Top = 3 + Lbl1.Height * 4
Lbl6.Top = 3 + Lbl1.Height * 5
Dim i As Long
For i = 1 To 6
With Me.Controls("Lbl" & i)
.Caption = i
.SpecialEffect = fmSpecialEffectRaised
End With
Next
Set LblCv = Me.Controls.Add("Forms.Label.1", "LblCv")
LblCv.Top = 3
LblCv.Height = LblCv.Height * 6
LblCv.BackStyle = fmBackStyleTransparent
End Sub
あとクラスモジュール使ってイベントをまとめる手法もありますね。 (モジュール分かれるから個人的には好きではないですが ^^;)
(白茶) 2022/08/09(火) 11:20
>ユーザーフォーム上にラベルが20個ほどあり、 >ラベル1がクリックされたらテキストボックス1〜10を処理 >ラベル2がクリックされたらテキストボックス11〜20を処理 でラベルが3〜20をクリックした時、テキストボックスとの関連はどうなるのですか。 ラベル1=テキストボックス1ではないのですか。 (・・・)
返信ありがとうございます。
ラベル3以降もテキストボックス21〜30と10単位で増加していきます。
処理の中身はラベルをクリックしたら、クリックしたらラベルの文字色(forecolor)を赤、
ラベルと関係のないテキストボックスは入力不可 enabled = False、Locked = True と処理しています。
例)
ラベル1をクリック
ラベル1の文字色を赤
ラベル2〜20の文字色を黒
テキストボックス1〜10を Enabled = True Locked = False
テキストボックス11〜200を Enabled = False Locked = True
上記の処理をラベル分作成するのが大変なため、まとめたいと考えております。
(おおとりさん) 2022/08/09(火) 11:51
返信、コードの提案ありがとうございます。
正攻法のコードで処理が可能か試させていただきます。
(おおとりさん) 2022/08/09(火) 11:53
Public sumControls() As New UserForm1
Sub SummationControls()
'
Dim uf As UserForm
Dim ctrl As Control
Dim cnt As Long, idx As Long
Dim ctrlName As String
'
Set uf = UserForm1
With uf
cnt = .Controls.Count
For idx = 1 To cnt
Set ctrl = .Controls(idx - 1)
ctrlName = ctrl.Name
With Module1.sumControls(idx)
Select Case True
Case ctrlName Like "Label*"
Set .Lbl = ctrl
Case ctrlName Like "Text*"
Set .Txt = ctrl
Case Else
End Select
End With
Next idx
End With
End Sub
でユーザーフォームUserForm1に
Public WithEvents Lbl As MSForms.Label
Public WithEvents Txt As MSForms.TextBox
Private Sub Lbl_Click()
'ここに処理を記述
'Lbl.index でそれぞれのインデックスが取得できる
End Sub
Private Sub Txt_Click()
'ここに処理を記述
'Txt.index でそれぞれのインデックスが取得できる
End Sub
ではどうですか?
(ngk) 2022/08/09(火) 13:47
ユーザーフォーム上にフレーム「Frame1」を配置します。その中に、オプションボタンを20個配置します。(OptionButton1 〜 OptionButton20)
フレーム内にオプションボタンを配置することでグループ化されてその中の一つだけ選択できるようになります。
テキストボックス名は Textbox1 〜 Textbox200 とします。
Private Sub OptionButton1_Click()
optCheck
End Sub
Private Sub OptionButton2_Click()
optCheck
End Sub
'中略・・・・
Private Sub OptionButton20_Click()
optCheck
End Sub
Public Sub optCheck()
Dim opt As Control, i As Long, j As Long
For Each opt In Me.Frame1.Controls
If opt.Value = True Then
opt.ForeColor = vbRed
For i = 1 To 200
With Me.Controls("Textbox" & i)
.Enabled = False: .Locked = True
End With
Next
j = Mid(opt.Name, 13) * 10 - 10
For i = 1 To 10
With Me.Controls("Textbox" & i + j)
.Enabled = True: .Locked = False
End With
Next
Else
opt.ForeColor = vbBlack
End If
Next
End Sub
もし、フレーム内に配置したくないという場合、オプションボタンの GroupNameプロパティを同じに設定すればグループ化されます。
(hatena) 2022/08/09(火) 14:21
ついでに、ありきたりな手法をもうひとつ ^^;
各コントロールのTagプロパティに、あらかじめグループ名を入れておいて そのグループ名をキーにして巡回処理を共通化する。という...
Private CurrentTagStr As String
Private Property Get CurrentGroup() As String
CurrentGroup = CurrentTagStr
End Property
Private Property Let CurrentGroup(newGroup As String)
If newGroup = CurrentTagStr Then Exit Property
CurrentTagStr = newGroup
Dim c As Control
For Each c In Me.Controls
If TypeOf c Is MSForms.Label Then c.ForeColor = IIf(c.Tag = CurrentTagStr, vbRed, &H80000012)
If TypeOf c Is MSForms.TextBox Then
c.Enabled = CBool(c.Tag = CurrentTagStr)
c.Locked = Not c.Enabled
End If
Next
End Property
Private Sub Label1_Click()
CurrentGroup = "G1"
End Sub
Private Sub Label2_Click()
CurrentGroup = "G2"
End Sub
Private Sub Label3_Click()
CurrentGroup = "G3"
End Sub
(白茶) 2022/08/09(火) 14:24
皆様、コードをご提案いただきありがとうございます。
同じ結果でも多様な方法があると改めて勉強になっております。
私の知識不足で調べてみないとわからない部分もあるため、
ひとつひとつ理解しながら試して最良なコードを探してみます。
合わせてオプションボタンへの変更も検討してみたいと思います。
(おおとりさん) 2022/08/09(火) 14:48
With uf
cnt = .Controls.Count
Redim module1.sumControls(cnt) ←これ書き忘れてました
For idx = 1 To cnt
Set ctrl = .Controls(idx - 1)
(ngk) 2022/08/09(火) 16:12
こんにちは、質問ですが
テキストボックス200個は、UserForm1 に 全部...並んでるんですか?
(あみな) 2022/08/09(火) 16:31
ご丁寧にありがとうございます。
追記しコードを試させていただきます。
(あみな)さん
はい、10列20行の形で並んでいます。
業務の処理上、この形が一番見やすいので上記で配置しています。
テキストボックスの入力処理はfor文とcontrolsで処理が可能なので
今回のクリックイベントの共通化を理解することができればとても楽になります。
(おおとりさん) 2022/08/09(火) 16:56
テキストボックスの配置については10個 * 20 行分といった形なので
10個分を作成したらコピペで配置できたのでそこまで大変ではありませんでした。
購買業務で使用しています。
1品種につき20社分の見積情報から購入先を選定する際に一覧表示できるように作成しています。
伝わりづらければ申し訳ありません。。。
(おおとりさん) 2022/08/09(火) 17:05
AddinBox/擬似からの脱却
http://addinbox.sakura.ne.jp/Breakthrough_P-Ctrl_Arrays.htm
汎用モジュール/clsBPCA を使って
サンプルコード を参考にすれば
かなり楽になると思いますよ。
(clsBPCA 自体は一切編集する必要はありません)
(AddinBox_角田) 2022/08/10(水) 10:32
コメントありがとうございます。
テキストボックスの処理については 処理列とテキストボックスの番号を合わせることで
そこまでコードを書かなくても処理ができております。
(最適なコードであるかはわかりませんが。。。)
例)
UserForm.Controls("textbox" & j).Value = Worksheets.Cells(行, j)
UserForm.Controls("textbox" & j).ControlSource= Worksheets.Cells(行, j)Address(RowAbsolute:=False, ColumnAbsolute:=False)
汎用モジュール/clsBPCA の件、URLまでありがとうございます。
初めて聞く処理のため理解が必要ですが、今回のラベルのクリックイベントでも使用できるかもしれません。
テキストボックスの処理の改善も含め、早速読んでみたいと思います。
(おおとりさん) 2022/08/10(水) 12:28
こんばんは、 テキストボックス200個は、UserForm1 に全部並んでるんですね。
業務では、処理スピードと、見やすさも重要かと 思われるので...やりやすい方法が一番良いのですが
ユーザーフォームの画面が大きいので大迫力だな〜と 想像しております。
そちらの処理と、全画面がわからないので...良し悪しがわかりませんので 一案ではありますが…どうなのでしょうか?^^;
マルチページを使用して、テキストボックスを10個ずつ 処理と、表示をさせることを検討されてはと思ったので 参考程度ですが
私が、「 ファイルなう 」と言うサイトへ… アップロードしたファイルです。 Windowsフォトビューアーで画像だけが閲覧可能です。
クリックイベントでも、オプションボタンでもよいのですが ユーザーフォームの初期画面から、選択して Opt1 を選択
◇1 ダウンロードURL: 購買管理初期値.JPG(53 KB) https://d.kuku.lu/1c9587d49
Opt1 選択後、コマンドボタンクリックから 画面を表示切替して、テキストボックスへ処理反映させたのが
◇2 ダウンロードURL: Opt1.JPG(49 KB) https://d.kuku.lu/c90521478
切替は、購買管理画面に戻り… Opt3 を選択後に表示切替させたのが下記URL
◇3 ダウンロードURL: Opt3.JPG(48 KB) https://d.kuku.lu/fb374b516
◆「 ファイルなう 」運営者情報 くくさま @kukusama https://twitter.com/kukusama
(あみな) 2022/08/10(水) 22:02
200個のデータをすべて一覧表示させておく必要があるのならだめですが、シートには一覧表示されているのなら、なくてもよさそうに思いますがいかがでしょう。
ちなみに、下記のコードの1行目は不要では。ControlSourceでリンクさせれば、セルの値は自動で反映されますので。
UserForm.Controls("textbox" & j).Value = Worksheets.Cells(行, j)
UserForm.Controls("textbox" & j).ControlSource= Worksheets.Cells(行, j).Address(RowAbsolute:=False, ColumnAbsolute:=False)
(hatena) 2022/08/11(木) 12:28
オプションボタン20個、テキストボックス20個を配置しておいて、
上記の部分は下記に訂正です。
オプションボタン20個、テキストボックス10個を配置しておいて、
コードとしては下記になります。
Private Sub OptionButton1_Click()
optCheck
End Sub
Private Sub OptionButton2_Click()
optCheck
End Sub
'中略・・・・
Private Sub OptionButton20_Click()
optCheck
End Sub
Public Sub optCheck()
Dim opt As Control, i As Long, j As Long
For Each opt In Me.Frame1.Controls
If opt.Value = True Then
opt.ForeColor = vbRed
j = Mid(opt.Name, 13)
For i = 1 To 10
Me.Controls("Textbox" & i).ControlSource = Worksheets(1).Cells(i, j).Address(False, False)
Next
Else
opt.ForeColor = vbBlack
End If
Next
End Sub
(hatena) 2022/08/11(木) 12:46
サンプル画面の作成をしていただきありがとうございます。
業務用のエクセルなので直接画面を乗せることができませんが、
200個のテキストボックスがすべて並んだ状態が見やすい形となっています。
10個ずつとなると少し見やすさに欠けてしまう状態となってしまいます。。。
わざわざ作成していただいたのにすみません。。。
(hatena)さん
コメントありがとうございます。
すべてのテキストボックスが並んでいることが最良な形となっています。
シートにも一覧表示されていますがシート画面の状態ですと見づらいため
今回のユーザーフォーム画面を作成しています。
1行目のコード不要の件、ご指摘ありがとうございます。
動作可能か試させていただきます。
皆様に挙げて頂いたコードを読みながら自分が実装できる範囲で作成しております。
現在、以下の形でおおよそ理想な処理ができるようになりました。
Private Sub Label1_Click(): call 購入処理(1): End sub Private Sub Label2_Click(): call 購入処理(2): End sub Private Sub Label3_Click(): call 購入処理(3): End sub
〜 20まで
Private Sub 購入処理(ラベル番号)
select case ラベル番号
case 1
開始番号 = 1
終了番号 = 10
case 2
開始番号 = 11
終了番号 = 20
case 3
開始番号 = 21
終了番号 = 30
〜 20まで
for i = 1 to 200 'テキストボックス処理用
select case i
case 開始番号 to 終了番号
該当テキストボックス処理
Else case
非該当テキストボックス処理
end case
next
(おおとりさん) 2022/08/12(金) 10:38
[ 一覧(最新更新順) ]
YukiWiki 1.6.7 Copyright (C) 2000,2001 by Hiroshi Yuki.
Modified by kazu.