前提・実現したいこと
別のサイトでご教示いただいた記述を参考に、自分のやりたいことを盛り込んでみたのですが
思うようにいかず、また動作も遅いように感じるのでご指摘をいただけたら幸いです。
前提
3行目から各行にそれぞれフォームコントロールボタンが挿入されており、
同じマクロが登録されています。
(下表E3のボタンをコピーして各行に貼り付け)
【入力用シート】
A | B | C | D | E | |
---|---|---|---|---|---|
2 | 日付 | 概要 | 対象製品 | ||
3 | 1月1日 | 特価セール開始 | (りんご)(いちご)(みかん) | 【ボタン】 | |
4 | 1月2日 | 追加発注 | (りんご)(いちご) | 【ボタン】 | |
5 | 【ボタン】 |
各ボタンに登録されているマクロ(標準モジュール)
Sub 呼び出し() ActiveSheet.Shapes(Application.Caller).TopLeftCell.Offset(, -1).Value _ = UserForm1.GetData End Sub
ボタンからユーザーフォームを呼び出し、C列に入力された概要の対称となる製品を
ユーザーフォームにあるチェックボタン(170個)でチェックしD列に()付きで入力するという
動きをさせています。
この時判定用シートへチェック内容を落とし込み、2回目のボタン押下時もそれを読み取ることで
チェックが残っている状態になる(同じ内容でチェックし直されている)ようにしています。
.
ユーザーフォームの記述(フォームモジュール)
Option Explicit Private data As String Private Sub UserForm_Initialize() Dim i As Integer For i = 1 To 170 'checkbox総数170 Controls("CheckBox" & i).Value = (Worksheets("判定用シート").Cells(3, i + 3).Value) Controls("CheckBox" & i).Caption = Worksheets("製品管理シート").Cells(i + 2, 520).Value '520はcheckboxのCaptionに設定したい名前(りんご、いちご等)を並べた列SZの列番号 Next i End Sub Private Sub CommandButton1_Click() Dim ctl As MSForms.Control Dim buf As String For Each ctl In Me.Controls If ctl.Name Like "CheckBox*" And ctl.Value = True Then buf = buf & "(" & ctl.Caption & ")" End If Next data = buf Me.Hide End Sub Public Function GetData() As String Me.Show vbModal GetData = data Unload Me End Function Private Sub UserForm_Terminate() Dim i As Integer For i = 1 To 170 'checkbox総数170 Worksheets("判定用シート").Cells(3, i + 3).Value = Controls("CheckBox" & i).Value Next i End Sub
【判定用シート】
2列目にはCbx1から170まで、製品管理シートを参照した製品名が入っています。
C列には入力用シートを参照した概要が入っています。
D3から右下に広がる表の倫理値は、初期値FALSE、ユーザーフォームからチェックを入れると
対応する箇所にTRUEが入ります。
(…や:は行間・列間を省略しているものとお考え下さい)
||B|C|D|E|F|G|...|FQ|||
|:--:|:--:|:--:|:--:|:--:|:--:|:--:|:--:|:--:|:--:|
|2||||りんご|いちご|ぶどう|みかん|...|Cbx170|←"製品管理シート"転記
|3||1月1日|特価セール開始|TRUE|TRUE|FALSE|TRUE|...|FALSE|←倫理値手入力
|4||1月2日|追加発注|TRUE|TRUE|FALSE|FALSE|...|FALSE|←倫理値手入力
|:||:|:|:|:|:|:|:|:|
|200||↑"入力用シート"転記|↑"入力用シート"転記|FALSE|FALSE|FALSE|FALSE|...|FALSE|←倫理値手入力
発生している問題・エラーメッセージ
- 【入力用シート】ユーザーフォームにてチェックした製品を左隣のセルに()付きで入力、
同じ箇所のボタンを2回目以降押す場合にもチェックを維持させたい(再チェックの手間を省きたい)
- 【製品管理シート】から拾ってきた製品名をそのまま各チェックボックスのCaptionとしたい
といった内容で動かしたく、前提のマクロ記述でなんとなく動かせてはいるのですが、
以下2点の問題が生じており、解決方法がわかりません。
- 【入力用シート】2行目以降のボタンが全て1行目のチェック内容を反映してしまう
- ユーザーフォーム内コマンドボタンを押す・×で閉じる、いずれも少し遅い(5~10秒程度)
試したこと
- 【入力用シート】2行目以降のボタンが全て1行目のチェック内容を反映してしまう
→ループの記述に間違いがあるのかと、
Controls("CheckBox" & i).Value = (Worksheets("判定用シート").Cells(3, i + 3).Value)
部分を
Controls("CheckBox" & 1).Value = (Worksheets("判定用シート").Cells(3, 4).Value)
Controls("CheckBox" & 2).Value = (Worksheets("判定用シート").Cells(3, 5).Value)
:
というように10個ほどまで記述したらうまくそれぞれのボタンで反映してくれました。
が、170個全てを記述するのは現実的でなく、うまくループする記述も見つけられませんでした。
- ユーザーフォーム内コマンドボタンを押す・×で閉じる、いずれも少し遅い(5~10秒程度)
→Application.ScreenUpdating や Application.Calculation を各工程に組み込みましたが
速度はほとんど変わりませんでした。5~10秒が妥当でやむを得ない時間なのであれば諦めますが、その判断も出来兼ねています。
EXCEL2019、Windows10を使用しています。
VBA初心者で、変数等の理解も未だ出来ておりません。インターネットから拾ったものを自分のシートのセルに当てはめるのも精一杯で、上記の出来上がっている記述も別サイトにて教えていただいたものです。
(教えていただいた時点ではループ処理やチェック保持等はお伝えしていませんでした)
それを自分なりに改造してしまったのでうまく動作していないのかと思いますが、どういう風に直せば理想の動きに出来るのか、ご教示いただければ幸いです。
よろしくお願いします。
以下、参考までに別サイトで教えていただいた記述を置かせていただきます。(セル参照は異なります)
(フォームモジュール) Option Explicit Private data As String Private Sub UserForm_Initialize() Me.CheckBox1.Caption = Worksheets("製品管理シート").Range("B1").Value Me.CheckBox2.Caption = Worksheets("製品管理シート").Range("B2").Value Me.CheckBox3.Caption = Worksheets("製品管理シート").Range("B3").Value End Sub Private Sub CommandButton1_Click() Dim ctl As MSForms.Control Dim buf As String For Each ctl In Me.Controls If ctl.Name Like "CheckBox*" And ctl.Value = True Then buf = buf & ctl.Caption End If Next data = buf Me.Hide End Sub Public Function GetData() As String Me.Show vbModal GetData = data Unload Me End Function (標準モジュール) Sub 呼び出し() ActiveSheet.Shapes(Application.Caller).TopLeftCell.Offset(, -1).Value _ = UserForm1.GetData End Sub
回答1件
あなたの回答
tips
プレビュー