前提・実現したいこと
任意の数だけ自動生成されたOLEオブジェクトのチェックボックスを連動させるためにクラスモジュールを使いたい
の続きでまた詰まってしまいました。
1行目の日付とA列の名前の分だけチェックボックスを生成し、セルに入れます。
チェックボックスは1行2列が一単位なので、日付の後ろの列を増やしてチェックボックスを入れていきます。
左のチェックボックスがオンになると右のチェックボックスが入力可能になり、左が外れると右のチェックボックスはオフになったうえで入力不可にします。
これをクラスモジュールでチェックボックスの分だけ関連付けてCollectionオブジェクトに格納したいのですが、エラーになってしまいます。
チェックボックスをユーザーフォームに生成することも考えたのですが、パソコンをいじるのになれていない人も入力する予定で、表のほうがわかりやすいとの意見があったのでこの形で行きたいです。
よろしくお願いいたします。
発生している問題・エラーメッセージ
修飾子が不正ですと出ます。 下から6行目のChkesが反転します。
該当のソースコード
VBA
1Option Explicit 2 3Public chBc As Long 4Private Chkes() As New clsLinkedCheckBoxes'引数に1行上のchBcを入れた 1 To chBcにするとエラーが出るので消しました。定数式が必要ですと出ます。 5Dim myChbes As Collection 6 7 8Private Sub CommandButton1_Click()'日付入力 ここは問題ないです。 9InputYearMonth: 'A1セルに年月を入力させる。日付の形でなければループさせる 10Dim ym As String 11Dim flg As Boolean 12 13 flg = False 14 Do 15 16 ym = InputBox(Prompt:="年月を入力してください", Title:="年月入力") 17 If Len(ym) = 0 Then Exit Sub 18 If IsDate(ym) Then flg = True 19 Loop Until flg = True 20 21Cells(1, 1).Value = ym 22 23InputDays: 24Dim ds As String 25Dim dates As Date 26Dim i As Long 27 28 For i = 1 To 4 29 Do 30 flg = False 31 ds = InputBox(Prompt:=i & "日目の日付を入れてください", Title:="日付入力") 32 If Len(ds) = 0 Then 33 If i = 1 Then 34 Exit Sub 35 Else 36 Exit For 37 End If 38 ElseIf Len(ds) <> 0 Then 39 dates = DateAdd("d", ds - 1, Cells(1, 1).Value) 40 End If 41 If Month(dates) = Month(CDate(ym)) Then flg = True 42 'Debug.Print Month(dates) 43 'Debug.Print Month(CDate(ym)) 44 If flg = False Then MsgBox "月は変えられません", vbExclamation 45 Loop Until flg = True 46 47 Range(Cells(1, i + 1), Cells(2, i + 1)).Value = dates 48 Cells(1, i + 1).NumberFormatLocal = "d" 49 Cells(2, i + 1).NumberFormatLocal = "aaaa" 50 Next i 51 52Inputpts: '名を入力していく キャンセルか入力なしで終わりか聞く 53Dim pts As String 54Dim Result As Long 55Dim k As Integer 56Dim flg2 As Boolean 57Dim dc As Integer 58 59 k = 5 60 pts = 0 61 flg2 = False 62 63Do 64 Do 65 pts = InputBox(Prompt:="名を入れてください", Title:="名前入力") 66 If Len(pts) <> 0 Then 67 Cells(k, 1).Value = pts 68 k = k + 1 69 End If 70 Loop Until Len(pts) = 0 71 72 Result = MsgBox("入力を終了しますか?", vbYesNo + vbExclamation) 73 If Result = vbYes Then 74 flg2 = True 75 End If 76 77Loop Until flg2 = True 78 79Dim apc As Integer 80apc = k - 5 81 If apc = 1 Then 82 With Range("A4") 83 .Interior.Color = RGB(255, 0, 0) 84 .Font.Color = RGB(255, 255, 255) 85 .Value = apc 86 End With 87 ElseIf apc > 9 Then 88 With Range("A4") 89 .Interior.Color = RGB(0, 255, 255) 90 .Value = apc 91 End With 92 Else 93 Range("A4").Value = apc 94 End If 95 96'パブリックのchBcにチェックボックスの数を格納 97dc = Range("A1").End(xlToRight).Column - 2 98chBc = apc * dc 99 100crDdmChb: 'ドロップダウンメニューを生成 101For i = 2 To 5 102 With Cells(3, i).Validation 103 .Delete 104 .Add Type:=xlValidateList, AlertStyle:=xlValidAlertStop, Formula1:="泉,北" 105 End With 106 Cells(3, i).Interior.Color = RGB(255, 255, 204) 107Next i 108 109End Sub 110Private Sub CommandButton2_Click()'後ろから列を挿入すればいいのに力技でレンジに格納する文字列を作ってしまっています。 111Dim apc As Integer 112Dim dc As Integer 113Dim i As Integer 114Dim j As Integer 115Dim pc As Integer 116Dim rg As String 117Dim rgs As String 118Dim edc As String 119Dim edcs As String 120Dim edcs2 As String 121Dim cn As Variant 122Dim chbr As String 123Dim checkBoxCells As Range 124Dim checkBoxCell As Range 125 126'枠組み作製 127dc = Range("A1").End(xlToRight).Column '最終入力列を取得 128 For i = 2 To dc '数字に対応したアルファベットを作ってRange()に格納する範囲を作成 129 rg = Chr(i + 65) 130 edc = Chr((i * 2 - 1) + 64) 131 rgs = rgs + rg + ":" + rg + "," 132 edcs = edcs + edc + ":" + edc + "," 133 edcs2 = edcs2 + edc + "," 134 135 Next i 136rgs = Left(rgs, Len(rgs) - 1) 137edcs = Left(edcs, Len(edcs) - 1) 138edcs2 = Left(edcs2, Len(edcs2) - 1) 139 140 141Range("" + rgs + "").Insert '飛び飛び列挿入 142Range("" + edcs + "").Validation.Delete 143Range("" + edcs + "").ClearFormats 144 145'指定した範囲にチェックボックス生成 146pc = Range("A5").End(xlDown).Row 147cn = Split(edcs2, ",") 'カンマで区切って文字列にする 148Debug.Print VBA.TypeName(cn(0)) 149 For j = 0 To dc - 2 150 chbr = chbr + cn(j) + "5" + ":" + cn(j) + CStr(pc) + "," 151Next j 152 153chbr = Left(chbr, Len(chbr) - 1) 154Set checkBoxCells = Range("" + chbr + "") 155checkBoxCells.Select 156 157 For Each checkBoxCell In checkBoxCells 158 Sample_CheckBox1 checkBoxCell 159 Next 160 161 Set checkBoxCells = Range("" + chbr + "").Offset(0, -1) 162 163 For Each checkBoxCell In checkBoxCells 164 Sample_CheckBox2 checkBoxCell 165 Next 166 167 Call clsLinked 168 169End Sub 170 171Sub Sample_CheckBox2(ByVal checkBoxCell As Range) 172'チェックボックスのみとしてセルの中央に配置する 173 174 Application.ScreenUpdating = False 175 176 With Me.OLEObjects.Add(ClassType:="Forms.CheckBox.1", _ 177 Link:=False, DisplayAsIcon:=False) 178 .Width = ActiveCell.Width - 5 179 .Height = ActiveCell.Height - 5 180 '対象セルの中央配置 181 .Top = checkBoxCell.Top + (checkBoxCell.Height - .Height) / 2 182 .Left = checkBoxCell.Left + (checkBoxCell.Width - .Width) / 2 183 With .Object 184 'テキスト 185 .Caption = "" 186 '背景色 187 .BackColor = rgbWhite '色定数:白 188 'チェックボックスON=True,OFF=False 189 .Value = False 190 End With 191 End With 192 193 Application.ScreenUpdating = True 194 195End Sub 196 197Sub Sample_CheckBox1(ByVal checkBoxCell As Range) 198'チェックボックスのみとしてセルの中央に配置する 199 200 Application.ScreenUpdating = False 201 202 With Me.OLEObjects.Add(ClassType:="Forms.CheckBox.1", _ 203 Link:=False, DisplayAsIcon:=False) 204 '対象セルの枠内に収める 205 .Width = checkBoxCell.Width - 5 206 .Height = checkBoxCell.Height - 5 207 .Top = checkBoxCell.Top + (checkBoxCell.Height - .Height) / 2 208 .Left = checkBoxCell.Left + (checkBoxCell.Width - .Width) / 2 209 With .Object 210 'テキスト 211 .Caption = "リハ" 212 '文字色 213 .ForeColor = rgbBlack '色定数:haiiro H00C0C0C0 214 'フォントサイズ 215 .Font.Size = 9 216 '背景色 217 .BackColor = rgbWhite '色定数:青色 218 'チェックボックスON=True,OFF=False 219 .Value = False 220 .Enabled = False 221 End With 222 End With 223 224 Application.ScreenUpdating = True 225 226End Sub 227Private Sub clsLinked() 228 Dim i As Long 229 230 Set myChbes = New Collection 231 232 With Worksheets("Sheet1") 'チェックボックスのあるシート 233 For i = 1 To chBc 234 Chkes().SetCtrl .OLEObjects("CheckBox" & i + chBc).Object, _'先頭のChkesが修飾子が不正とのエラーが出ます。 235 .OLEObjects("CheckBox" & i).Object 236 End With 237 myChbes.Add Chkes() 238 Next 239End Sub
class
1Private WithEvents Chk1 As MSForms.CheckBox 2Private Chk2 As MSForms.CheckBox 3 4Public Sub SetCtrl(newChk1 As MSForms.CheckBox, newChk2 As MSForms.CheckBox) 5 Set Chk1 = newChk1 6 Set Chk2 = newChk2 7End Sub 8 9Private Sub Chk1_Click() 10 If Chk1.Value = False Then 11 Chk2.Value = False 12 Chk2.Enabled = False 13 Else 14 Chk2.Enabled = True 15 End If 16End Sub 17 18
試したこと
エクセルVBAでクラスのインスタンス生成時に初期データを格納するメソッドを作る方法
リンクの一連の記事でクラスモジュールとCollectionオブジェクトを勉強しました。
VBA
1Option Explicit 2 3Public chBc As Long 4Private Chkes() As clsLinkedCheckBoxes'動的配列を宣言 5 6'コマンドボタン1の中 A3にチェックボックスの数を格納 7dc = Range("A1").End(xlToRight).Column - 2 8chBc = apc * dc 9Range("A3").Value = chBc 10 11Private Sub clsLinked() 12 Dim i As Long 13 Dim Chkes As clsLinkedCheckBoxes 'ここでクラス変数を宣言、生成はしない 14 15 16 chBc = Range("A3").Value 17 With Me 'チェックボックスのあるシート 18 For i = 1 To chBc 19 Set Chkes = New clsLinkedCheckBoxes 'ここでクラスの実体を生成してクラス変数に格納 20 Chkes.SetCtrl .OLEObjects("CheckBox" & i + chBc).Object, _ 21 .OLEObjects("CheckBox" & i).Object 22 23 Next 24 End With 25End Sub 26
回答の前に確認ですが、CommandButton1、CommandButton2 はどこに配置してますか。
画像のシート(チェックボックスのあるシート)上ですか。
また、前のコード(クラスでない方)はこのシートのモジュールに記述してますか。
ありがとうございます。
画像のシートに配置しています。Sheet1に記載できていると思います。
画像を追加しました。
よろしくお願いいたします。
クラスのオブジェクト名がclsLinkedCheckBoxesで
Private Chkes As New clsLinkedCheckBoxes
と
With Worksheets("Sheet1")
For i = 1 To chBc
Chkes.SetCtrl .OLEObjects("CheckBox" & i + chBc).Object, _
.OLEObjects("CheckBox" & i).Object
myChbes.Add Chkes()
Next
End With
でエラーは消えるけど、、、?
ありがとうございます。
エラーは出なくなりましたが、関連付けはできないようです。
デバッグ用にchBcを指定したまま進めると、Collectionオブジェクトに格納する行で
オブジェクトがプロパティかメソッドをサポートしていないというエラーが出てしまいます。
PCちがうのでこちらから回答します。
私のWin10、office365、64bitでは
エラーなく終了しますが、動きませんね
hatena19さんのに書き換えても同じく(chBc=5)動きません
クラスについては勉強中ですが
Collectionに収めて、、、保持する必要は?です
EndSubの前のデバッグでは想定内なのですよね。
chBcはCommandButton1で計算されているのですね
ありがとうございます。
こちらの環境も同じです。
>chBcはCommandButton1で計算されているのですね
その通りです。
回答2件
あなたの回答
tips
プレビュー