[ 初めての方へ | 一覧(最新更新順) | 全文検索 | 過去ログ ]
『チェックボックスの一括処理』(あき)
はじめまして、
チェックボックスの処理についてどうしてもできないため、質問させていただきます。
曜日の指定にて下記のチェックボックスを使っています。
※1つのセル内にすべておいています。
□全日
□月 □火 □水 □木 □金 □土 □日
全日を指定した場合、月〜日すべてにチェックが入ります。
【現在使用しているマクロ】
Sub チェック1_Click()
ActiveSheet.CheckBoxes(Array(2, 3, 4, 5, 6, 7, 8)).Value = ActiveSheet.CheckBoxes(1).Value
End Sub
これを1つのシート内で複数設置したいのですが、1つ目のもの以外は動いてくれません。
下記の様な表で、会社毎にチェックボックスを設置したい場合にはどのようにすればよろしいのでしょうか?
| A | B | C | D | 1| 会社名 |チェックボックス | 指定時間| 備考| 2| 会社名 |チェックボックス | 指定時間| 備考| 3| 会社名 |チェックボックス | 指定時間| 備考| 4| 会社名 |チェックボックス | 指定時間| 備考|
皆様お忙しかと思われますが、何卒ご教授ください。
よろしくお願いいたします。
< 使用 Excel:Excel2010、使用 OS:Windows7 >
シートにそんなたくさんのオブジェクトは置かないほうがいいと思いますよ。 メンテナンスしにくいし。
B列を選択したら、ユーザーフォームを出して、チェックさせて 内容に応じてB列に値を入れる、としたほうが効率的ではないでしょうか? コードも一つで済むし。 (稲葉) 2015/02/16(月) 18:03
ご意見ありがとうございます。
上司のこだわりのようで・・・
チェックボックスでやりたいみたいなのです。
自分に決定権がないので…
(あき) 2015/02/16(月) 18:27
だって、チェックボックス分イベント用意するようですよ? そうじゃなければ http://www.h3.dion.ne.jp/~sakatsu/Breakthrough_P-Ctrl_Arrays.htm こちらを読んで、イベントの配列化させる手法学ばないと、100行あれば100イベント作る必要ありますよね?
代替案で、ユーザーフォームを作成して(UserForm1とする)、以下のようにチェックボックス8つと ボタン2つを作る □の右にある数字は、作る順番です。 ┏━━━━━━━━━━━━━━━━━━━━┓ ┃□8 ┃ ┃ ┃ ┃□1 □2 □3 □4 □5 □6 □7┃ ┃ ┃ ┃┌────┐ ┌────┐ ┃ ┃│ボタン1│ │ボタン2│ ┃ ┃└────┘ └────┘ ┃ ┗━━━━━━━━━━━━━━━━━━━━┛
ユーザーフォームのコードに以下を張り付ける
Private CBs As Collection
Private Sub UserForm_Initialize()
Dim i As Long
Set CBs = New Collection
With CBs
.Add Me.CheckBox1, "月"
.Add Me.CheckBox2, "火"
.Add Me.CheckBox3, "水"
.Add Me.CheckBox4, "木"
.Add Me.CheckBox5, "金"
.Add Me.CheckBox6, "土"
.Add Me.CheckBox7, "日"
.Add Me.CheckBox8, "全"
End With
Me.CommandButton1.Caption = "入力"
Me.CommandButton2.Caption = "キャンセル"
For i = 1 To 8
CBs(i).Caption = Mid("月火水木金土日全", i, 1)
Next i
SetValue
End Sub
Private Sub CommandButton1_Click()
Selection.Value = GetValue
Unload Me
End Sub
Private Sub CommandButton2_Click()
Unload Me
End Sub
Private Sub CheckBox8_Click()
Dim i As Long
Dim flg As Boolean
flg = CBs("全").Value
For i = 1 To 7
CBs(i).Value = flg
Next i
End Sub
Private Function GetValue() As String
Dim i As Long
Dim tmp As String
For i = 1 To 7
tmp = tmp & IIf(CBs(i).Value, "■", "□") & CBs(i).Caption & " "
Next i
GetValue = tmp
End Function
Private Function SetValue() As String
Dim i As Long
Dim tmp As String
tmp = Selection.Value
On Error Resume Next
For i = 2 To 18 Step 3
CBs(Mid(tmp, i, 1)).Value = Mid(tmp, i - 1, 1) = "■"
Next i
On Error GoTo 0
End Function
使いたいシートモジュールに
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
If Not Target.Address Like "$B$*" Then Exit Sub
UserForm1.Show
End Sub
を張り付ける
B列を選択すると、ユーザーフォームが立ち上がって、チェックボックスを選択して入力ボタンを クリックすると □月 ■火 ■水 □木 □金 □土 □日 こんな感じで入力されます。
例の場合、火曜と水曜にチェックが入っていた状態です。
こちらでどうですか?
(稲葉) 2015/02/16(月) 18:51
追記 仮にイベントの配列化ができたとしても、曜日がどの行の曜日なのか取得するには、チェックボックスの オブジェクト名称や、オブジェクトの位置情報を基に判断しなければいけないので、かなり煩雑になる のではないかと予想しています。
ichinoseさんなら何とかしてくれそうですが、やっぱり私はお勧めしないなぁ・・・ (稲葉) 2015/02/16(月) 19:04
ありがとうございます。
こちらで作成して一度上司へ提出してみようと思います!
本当にありがとうございました!!
(あき) 2015/02/16(月) 19:27
最近マイブーム(死語?)のチェックボックスもどき案です。
標準モジュールで一度下記を実行し、
−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−
Sub シート作成()
Const データ行数 = 7
Cells.Clear
Columns("A").ColumnWidth = 16
Columns("B").ColumnWidth = 6
Columns("C:I").ColumnWidth = 4
Columns("J:K").ColumnWidth = 16
Range("A1").Value = "会社名"
Range("B1:I1").Merge
Range("B1").Value = "日付チェック"
Range("J1").Value = "時刻"
Range("K1").Value = "備考"
Cells.Interior.ThemeColor = xlThemeColorDark1
Range("A1:K1").Interior.ThemeColor = xlThemeColorAccent5
Range("B2").Resize(データ行数, 1).Interior.Color = 13434879
Range("H2").Resize(データ行数, 1).Interior.Color = 16772300
Range("I2").Resize(データ行数, 1).Interior.Color = 16764159
Range("A1").Resize(データ行数 + 1, 11).Borders.Weight = xlThin
Range("B1").Resize(データ行数 + 1, 8).Borders(xlInsideVertical).LineStyle = xlNone
Dim r As Long
Dim c As Long
For r = 2 To データ行数 + 1
Cells(r, "A").Value = "会社名" & Chr(63 + r)
For c = 0 To 7
If c = 0 Then
曜日 = "全日"
Else
曜日 = Mid("月火水木金土日", c, 1)
End If
Cells(r, 2 + c).NumberFormatLocal = "□" & 曜日 & "[=0];" & ChrW(9745) & 曜日 & "[=1];;"
Cells(r, 2 + c).Value = 0
Next
Next
End Sub
−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−
表のシートモジュール(シートタブから「コードの表示」)に下記を置きます。
−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−
Private Sub Worksheet_BeforeRightClick(ByVal Target As Range, Cancel As Boolean)
If Target.CountLarge <> 1 Then Exit Sub
If Intersect(Range("B2:I8"), Target) Is Nothing Then Exit Sub
Application.EnableEvents = False
If Target.Column = 2 Then
Target.Resize(1, 8).Value = IIf(Target.Value = 0, 1, 0)
Else
Target.Value = IIf(Target.Value = 0, 1, 0)
End If
Cancel = True
Cells(Target.Row, "A").Select
Application.EnableEvents = True
End Sub
−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−
セルの右クリックで操作です。 セルの値は1と0なので、今回は不要かもしれませんが、集計も可能です。
シート作成後は「シート作成」マクロは削除しておいたほうが良いかもしれません。
間違って再実行すると全部消えてしまうので。
行コピーすれば行数は増やせます。その場合、シートモジュールのマクロの
If Intersect(Range("B2:I8"), Target) Is Nothing Then Exit Sub
のクリック範囲("B2:I8")を変更してください。
(Mook) 2015/02/16(月) 19:43
Mookさんの便利ですなぁ! 実体が0,1なのも計算しやすい! (稲葉) 2015/02/17(火) 08:49
ありがとうございます!
まだ試せておりませんが、後程ゆっくり拝見させていただきたいです!
稲葉様
昨日は本当にありがとうござました!上司かGOサインが出ました!
ただ、他のセルにも使いたいといわれたので、編集してみたのですが、どうにもうまくいきません。
安易に変更したのがだめだったのでしょうか?
昨日のものにプラスしPの部分をユーザーフォームを作成してUserForm2として作業いたしました。
| A 〜|〜 O | P | Q | R | 1| 会社名 |チェックボックス |チェックボックス |チェックボックス | 備考 | 2| 会社名 |チェックボックス |チェックボックス |チェックボックス | 備考 | 3| 会社名 |チェックボックス |チェックボックス |チェックボックス | 備考 | 4| 会社名 |チェックボックス |チェックボックス |チェックボックス | 備考 |
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
If Not Target.Address Like "$O$*" Then Exit Sub
UserForm1.Show
End Sub
Private Sub Worksheet_SelectionChange2(ByVal Target As Range)
If Not Target.Address Like "$P$*" Then Exit Sub
UserForm2.Show
End Sub
Private Sub Worksheet_SelectionChange3(ByVal Target As Range)
If Not Target.Address Like "$Q$*" Then Exit Sub
UserForm3.Show
End Sub
Private CBs As Collection
Private Sub CheckBox2_Click()
End Sub
Private Sub CheckBox3_Click()
End Sub
Private Sub CheckBox4_Click()
End Sub
Private Sub UserForm_Initialize()
Dim i As Long
Set CBs = New Collection
With CBs
.Add Me.CheckBox1, "午前"
.Add Me.CheckBox2, "午後"
.Add Me.CheckBox3, "夜間"
.Add Me.CheckBox4, "早朝"
.Add Me.CheckBox5, "全"
End With
Me.CommandButton1.Caption = "入力"
Me.CommandButton2.Caption = "キャンセル"
For i = 1 To 5
CBs(i).Caption = Mid("午前午後夜間早朝全", i, 1)
Next i
SetValue
End Sub
Private Sub CommandButton1_Click()
Selection.Value = GetValue
Unload Me
End Sub
Private Sub CommandButton2_Click()
Unload Me
End Sub
Private Sub CheckBox5_Click()
Dim i As Long
Dim flg As Boolean
flg = CBs("全").Value
For i = 1 To 4
CBs(i).Value = flg
Next i
End Sub
Private Function GetValue() As String
Dim i As Long
Dim tmp As String
For i = 1 To 4
tmp = tmp & IIf(CBs(i).Value, "■", "□") & CBs(i).Caption & " "
Next i
GetValue = tmp
End Function
Private Function SetValue() As String
Dim i As Long
Dim tmp As String
tmp = Selection.Value
On Error Resume Next
For i = 2 To 18 Step 3
CBs(Mid(tmp, i, 1)).Value = Mid(tmp, i - 1, 1) = "■"
Next i
On Error GoTo 0
End Function
お忙しいかと存じますが、再度ご教授いただけましたら嬉しいです。
(あき) 2015/02/17(火) 11:55
稲葉さんが回答を書いているとは思いますが、とりあえずイベント部分だけ、 SelectionChange は固定のものなので、SelectionChange2、SelectionChange3 などは出来ません。
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
If Target.Address Like "$O$*" Then UserForm1.Show
If Target.Address Like "$P$*" Then UserForm2.Show
If Target.Address Like "$Q$*" Then UserForm3.Show
End Sub
のようにしたら、とりあえずユーザフォームは起動しないでしょうか。
(Mook) 2015/02/17(火) 12:04
今書いてましたー。
イベントについてはMookさんの言う通りです!
>Mid("午前午後夜間早朝全", i, 1)
こういうところとか癖がある書き方したのでわかりにくかったですよね。
これは調べてやれって言うのは酷だと思いますのでもう少し情報と時間ください。 コードと説明書きを作ります。
質問 1)ユーザーフォーム分けるの面倒なので、一つのユーザーフォームでOPQ列(B列はただの例だったのかな?) をいじってもよろしいですか?
2)O列は昨日の曜日、 P列は「午前 午後 夜間 早朝 全」として Q列はどうなりますか? (稲葉) 2015/02/17(火) 12:08
なるほど固定なのですね。
そちらの形にしたら確かに起動いたしました!
ちょっと面白い形になってしまいましたが(汗)
最初はそちらだったのですが、後から後から出てまいりましたorz
お手間を取らせてしますいません。
説明書きとても助かります!
一つのユーザーフォームでも問題ございません。
逆にいろいろな場所を触らせるよりわかりやすいかもしれません。
Qは『月初、中旬、月末』です。
何卒よろしくお願いします!
(あき) 2015/02/17(火) 13:13
こちらも聞き忘れましたが、曜日はともかく、 時間と月に関しては、チェックボックスではなくラジオボタンのほうが適していると思うのですが・・・
(稲葉) 2015/02/17(火) 13:22
複数選択をする可能性がある為チェックボックス仕様にしております。
各会社ごとにヒアリングした結果をメモしていく形のようです。
私も自分が使っているのではないので詳しくわからないのですが…。
(あき) 2015/02/17(火) 13:32
遅くなりました。 休憩時間に作業してたんで済みません。
ユーザーフォームを以下のように配置してください。 □がチェックボックスです。 (図がずれていたら、等幅フォントのメモ帳などで張り付けてみてください・・・) ユーザーフォームの名称は、UserForm1 です。 ┏━━━━━━━━━━━━━━━━━━━━┓ ┃□8 ┃ ┃□1 □2 □3 □4 □5 □6 □7┃ ┃ ┃ ┃□13 ┃ ┃□9 □10 □11 □12 ┃ ┃ ┃ ┃□14 □15 □16 ┃ ┃ ┃ ┃┌────┐ ┌────┐ ┃ ┃│ボタン1│ │ボタン2│ ┃ ┃└────┘ └────┘ ┃ ┗━━━━━━━━━━━━━━━━━━━━┛ UserForm1のモジュールに以下を張り付けてください。 Option Explicit
Private WCBs As Collection '曜日チェックボックス
Private TCBs As Collection '時間チェックボックス
Private MCBs As Collection '月チェックボックス
Private rng As Range '入力範囲の設定
'■立ち上げ時の処理
Private Sub UserForm_Initialize()
Dim i As Long
Set WCBs = New Collection
Set TCBs = New Collection
Set MCBs = New Collection
'曜日のチェックボックス群
'EvSet関数を使って、チェックボックスをclsGetChkExに登録し、コレクションに加える
'1つ目の引数がコントロールオブジェクト
'2つ目がCollectionのKeyにあたる値
'3つ目がどのコレクションに入れるか分岐するための数値
'中身は、★印のFunctionを参照
EvSet Me.CheckBox1, "月", 1
EvSet Me.CheckBox2, "火", 1
EvSet Me.CheckBox3, "水", 1
EvSet Me.CheckBox4, "木", 1
EvSet Me.CheckBox5, "金", 1
EvSet Me.CheckBox6, "土", 1
EvSet Me.CheckBox7, "日", 1
EvSet Me.CheckBox8, "全曜日", 1
For i = 1 To 8
WCBs(i).Caption = Split(",月,火,水,木,金,土,日,全曜日", ",")(i)
Next i
'↑Mid関数からSplit関数に変更。
'Split関数は、区切り文字で区切った0からの配列を変える関数
'例では{"",月,火,水,木,金,土,日,全曜日}このような配列を返す
'配列は0から始まるので、1から始まる繰り返し処理のために、ダミーで配列0に""を当てている
'時間のチェックボックス群
EvSet Me.CheckBox9, "午前", 2
EvSet Me.CheckBox10, "午後", 2
EvSet Me.CheckBox11, "深夜", 2
EvSet Me.CheckBox12, "早朝", 2
EvSet Me.CheckBox13, "全日", 2
For i = 1 To 5
TCBs(i).Caption = Split(",午前,午後,深夜,早朝,全日", ",")(i)
Next i
'月のチェックボックス群
EvSet Me.CheckBox14, "月初", 3
EvSet Me.CheckBox15, "中旬", 3
EvSet Me.CheckBox16, "月末", 3
For i = 1 To 3
MCBs(i).Caption = Split(",月初,中旬,月末", ",")(i)
Next i
Me.CommandButton1.Caption = "入力"
Me.CommandButton2.Caption = "キャンセル"
Set rng = Range("O" & Selection.Row).Resize(, 3)
SetValue '▼参照
End Sub
'★クラスにチェックボックスを登録する関数
Function EvSet(ByRef chk As MSForms.CheckBox, ByVal Key As String, ByVal col As Long)
'クラスにチェックボックスを登録して、イベントをクラスに渡すようにする
Dim ev As clsGetChkEv
Set ev = New clsGetChkEv
Set ev.chkbox = chk
Select Case col
Case 1: WCBs.Add ev, Key
Case 2: TCBs.Add ev, Key
Case 3: MCBs.Add ev, Key
End Select
End Function
'▲クラスのクリックイベントから実行されるプロシージャ
Public Sub ChkClick(ByVal Cap As String)
'クラスのイベントから、押されたボタンのCaption情報のみを取得して、条件を分岐させる
Dim i As Long
Select Case Cap
Case "全曜日"
For i = 1 To 8
WCBs(i).Value = WCBs(Cap).Value
Next i
Case "全日"
For i = 1 To 4
TCBs(i).Value = TCBs(Cap).Value
Next i
End Select
End Sub
'■入力ボタンクリック
Private Sub CommandButton1_Click()
rng.Value = GetValue '●参照
Unload Me
End Sub
'■キャンセルボタンクリック
Private Sub CommandButton2_Click()
Unload Me
End Sub
'●入力ボタンクリック時、コレクションからデータを取得して、配列にする
Private Function GetValue() As Variant
'各列でマーク等の設定する可能性があるので、3つの処理に分割
Dim i As Long
Dim tmp(1 To 3) As String
'曜日
With WCBs
For i = 1 To WCBs.Count - 1 '全を除く
tmp(1) = tmp(1) & IIf(.Item(i).Value, "■", "□") & .Item(i).Caption & " "
Next i
End With
'時間帯
With TCBs
For i = 1 To TCBs.Count - 1 '全を除く
tmp(2) = tmp(2) & IIf(.Item(i).Value, "■", "□") & .Item(i).Caption & " "
Next i
End With
'月
With MCBs
For i = 1 To MCBs.Count '全がないのでそのまま
tmp(3) = tmp(3) & IIf(.Item(i).Value, "■", "□") & .Item(i).Caption & " "
Next i
End With
GetValue = tmp
End Function
'▼フォームを立ち上げたときに、各コントロールにデータを入れるサブプロシージャ
Private Sub SetValue()
Dim x
On Error Resume Next
'曜日
With WCBs
For Each x In Split(rng(1, 1).Value, " ") '←半角の空白で区切って配列にしている
.Item(Mid(x, 2)).Value = Left(x, 1) = "■"
' ~~~~~~~~~~~~~~~~~
' =で繋ぐことで、直接True,Flaseを設定している
Next x
End With
'時間帯
With TCBs
For Each x In Split(rng(1, 2).Value, " ")
.Item(Mid(x, 2)).Value = Left(x, 1) = "■"
Next x
End With
'月
With MCBs
For Each x In Split(rng(1, 3).Value, " ")
.Item(Mid(x, 2)).Value = Left(x, 1) = "■"
Next x
End With
On Error GoTo 0
End Sub
┐┐┐┐┐┐┐┐┐┐┐┐┐┐┐┐┐┐┐┐┐┐┐┐┐┐┐┐┐┐
次に、クラスモジュールを挿入してオブジェクト名を「clsGetChkEv」としてください。
クラスモジュールの中に以下のコードを入れてください。
'clsGetChkEv というオブジェクト名にしてください。
Public WithEvents chkbox As MSForms.CheckBox
'▲クリックされたら、ユーザーフォームのプロシージャを実行する
'(ユーザーフォームの▲参照)
Sub chkbox_click()
UserForm1.ChkClick (chkbox.Caption)
End Sub
'↓のプロパティを作らないと、呼び出し先で面倒
'例)WCBs(1).chkbox.Value ←めんどくさい | WCBs(1).Value ←これなら楽
'Valueプロパティ
Public Property Get Value() As Boolean
Value = chkbox.Value
End Property
Public Property Let Value(ByVal Val As Boolean)
chkbox.Value = Val
End Property
'Captionプロパティ
Public Property Get Caption() As String
Caption = chkbox.Caption
End Property
Public Property Let Caption(ByVal Cap As String)
chkbox.Caption = Cap
End Property
┐┐┐┐┐┐┐┐┐┐┐┐┐┐┐┐┐┐┐┐┐┐┐┐┐┐┐┐┐┐┐┐┐┐
次に実際に使用するシートのモジュールに以下のコードを入れてください。
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
If Target.Rows.Count > 1 Then Exit Sub
If Not Intersect(Target, Range("O:Q")) Is Nothing Then
UserForm1.Show
End If
End Sub
これでO:Q列を選択すると、ユーザーフォームで入力したデータをテキストとして 出力できます。
(稲葉) 2015/02/17(火) 16:09
ありがとうございます!!
貴重な休憩中にすいません。
そして月にも全表示が必要でした・・・。
クラスモジュールを作り下記のようにいたしました。
Sub clsGetChkEv()
Public WithEvents chkbox As MSForms.CheckBox
'▲クリックされたら、ユーザーフォームのプロシージャを実行する
'(ユーザーフォームの▲参照)
Sub chkbox_click()
UserForm1.ChkClick (chkbox.Caption)
End Sub
'↓のプロパティを作らないと、呼び出し先で面倒
'例)WCBs(1).chkbox.Value ←めんどくさい | WCBs(1).Value ←これなら楽
'Valueプロパティ
Public Property Get Value() As Boolean
Value = chkbox.Value
End Property
Public Property Let Value(ByVal Val As Boolean)
chkbox.Value = Val
End Property
'Captionプロパティ
Public Property Get Caption() As String
Caption = chkbox.Caption
End Property
Public Property Let Caption(ByVal Cap As String)
chkbox.Caption = Cap
End Property
〜〜〜〜〜〜〜
全月が必要だったため下記のように追加いたしました。
Option Explicit
Private WCBs As Collection '曜日チェックボックス
Private TCBs As Collection '時間チェックボックス
Private MCBs As Collection '月チェックボックス
Private rng As Range '入力範囲の設定
'■立ち上げ時の処理
Private Sub UserForm_Initialize()
Dim i As Long
Set WCBs = New Collection
Set TCBs = New Collection
Set MCBs = New Collection
'曜日のチェックボックス群
'EvSet関数を使って、チェックボックスをclsGetChkExに登録し、コレクションに加える
'1つ目の引数がコントロールオブジェクト
'2つ目がCollectionのKeyにあたる値
'3つ目がどのコレクションに入れるか分岐するための数値
'中身は、★印のFunctionを参照
EvSet Me.CheckBox1, "月", 1
EvSet Me.CheckBox2, "火", 1
EvSet Me.CheckBox3, "水", 1
EvSet Me.CheckBox4, "木", 1
EvSet Me.CheckBox5, "金", 1
EvSet Me.CheckBox6, "土", 1
EvSet Me.CheckBox7, "日", 1
EvSet Me.CheckBox8, "全曜日", 1
For i = 1 To 8
WCBs(i).Caption = Split(",月,火,水,木,金,土,日,全曜日", ",")(i)
Next i
'↑Mid関数からSplit関数に変更。
'Split関数は、区切り文字で区切った0からの配列を変える関数
'例では{"",月,火,水,木,金,土,日,全曜日}このような配列を返す
'配列は0から始まるので、1から始まる繰り返し処理のために、ダミーで配列0に""を当てている
'時間のチェックボックス群
EvSet Me.CheckBox9, "午前", 2
EvSet Me.CheckBox10, "午後", 2
EvSet Me.CheckBox11, "深夜", 2
EvSet Me.CheckBox12, "早朝", 2
EvSet Me.CheckBox13, "全日", 2
For i = 1 To 5
TCBs(i).Caption = Split(",午前,午後,深夜,早朝,全日", ",")(i)
Next i
'月のチェックボックス群
EvSet Me.CheckBox14, "月初", 3
EvSet Me.CheckBox15, "中旬", 3
EvSet Me.CheckBox16, "月末", 3
EvSet Me.CheckBox16, "全月", 3
For i = 1 To 4
MCBs(i).Caption = Split(",月初,中旬,月末,全月", ",")(i)
Next i
Me.CommandButton1.Caption = "入力"
Me.CommandButton2.Caption = "キャンセル"
Set rng = Range("O" & Selection.Row).Resize(, 3)
SetValue '▼参照
End Sub
'★クラスにチェックボックスを登録する関数
Function EvSet(ByRef chk As MSForms.CheckBox, ByVal Key As String, ByVal col As Long)
'クラスにチェックボックスを登録して、イベントをクラスに渡すようにする
Dim ev As clsGetChkEv
Set ev = New clsGetChkEv
Set ev.chkbox = chk
Select Case col
Case 1: WCBs.Add ev, Key
Case 2: TCBs.Add ev, Key
Case 3: MCBs.Add ev, Key
End Select
End Function
'▲クラスのクリックイベントから実行されるプロシージャ
Public Sub ChkClick(ByVal Cap As String)
'クラスのイベントから、押されたボタンのCaption情報のみを取得して、条件を分岐させる
Dim i As Long
Select Case Cap
Case "全曜日"
For i = 1 To 8
WCBs(i).Value = WCBs(Cap).Value
Next i
Case "全日"
For i = 1 To 4
TCBs(i).Value = TCBs(Cap).Value
Next
Case "全月"
For i = 1 To 3
TCBs(i).Value = MCBs(Cap).Value
Next i
End Select
End Sub
'■入力ボタンクリック
Private Sub CommandButton1_Click()
rng.Value = GetValue '●参照
Unload Me
End Sub
'■キャンセルボタンクリック
Private Sub CommandButton2_Click()
Unload Me
End Sub
'●入力ボタンクリック時、コレクションからデータを取得して、配列にする
Private Function GetValue() As Variant
'各列でマーク等の設定する可能性があるので、3つの処理に分割
Dim i As Long
Dim tmp(1 To 3) As String
'曜日
With WCBs
For i = 1 To WCBs.Count - 1 '全を除く
tmp(1) = tmp(1) & IIf(.Item(i).Value, "■", "□") & .Item(i).Caption & " "
Next i
End With
'時間帯
With TCBs
For i = 1 To TCBs.Count - 1 '全を除く
tmp(2) = tmp(2) & IIf(.Item(i).Value, "■", "□") & .Item(i).Caption & " "
Next i
End With
'月
With MCBs
For i = 1 To MCBs.Count - 1 '全を除く
tmp(3) = tmp(3) & IIf(.Item(i).Value, "■", "□") & .Item(i).Caption & " "
Next i
End With
GetValue = tmp
End Function
'▼フォームを立ち上げたときに、各コントロールにデータを入れるサブプロシージャ
Private Sub SetValue()
Dim x
On Error Resume Next
'曜日
With WCBs
For Each x In Split(rng(1, 1).Value, " ") '←半角の空白で区切って配列にしている
.Item(Mid(x, 2)).Value = Left(x, 1) = "■"
' ~~~~~~~~~~~~~~~~~
' =で繋ぐことで、直接True,Flaseを設定している
Next x
End With
'時間帯
With TCBs
For Each x In Split(rng(1, 2).Value, " ")
.Item(Mid(x, 2)).Value = Left(x, 1) = "■"
Next x
End With
'月
With MCBs
For Each x In Split(rng(1, 3).Value, " ")
.Item(Mid(x, 2)).Value = Left(x, 1) = "■"
Next x
End With
On Error GoTo 0
End Sub
〜〜〜〜
以上で実行してみたのですがどこをクリックしても作動しなくなってしまいました。。。
(あき) 2015/02/17(火) 18:12
本当にありがとうございます!
Option Explicit
Private WCBs As Collection '曜日チェックボックス
Private TCBs As Collection '時間チェックボックス
Private MCBs As Collection '月チェックボックス
Private rng As Range '入力範囲の設定
Private Sub CheckBox10_Click()
End Sub
Private Sub CheckBox11_Click()
End Sub
Private Sub CheckBox12_Click()
End Sub
Private Sub CheckBox13_Click()
End Sub
Private Sub CheckBox14_Click()
End Sub
Private Sub CheckBox15_Click()
End Sub
Private Sub CheckBox16_Click()
End Sub
Private Sub CheckBox17_Click()
End Sub
Private Sub CheckBox9_Click()
End Sub
'■立ち上げ時の処理
Private Sub UserForm_Initialize()
Dim i As Long
Set WCBs = New Collection
Set TCBs = New Collection
Set MCBs = New Collection
'曜日のチェックボックス群
'EvSet関数を使って、チェックボックスをclsGetChkExに登録し、コレクションに加える
'1つ目の引数がコントロールオブジェクト
'2つ目がCollectionのKeyにあたる値
'3つ目がどのコレクションに入れるか分岐するための数値
'中身は、★印のFunctionを参照
EvSet Me.CheckBox1, "月", 1
EvSet Me.CheckBox2, "火", 1
EvSet Me.CheckBox3, "水", 1
EvSet Me.CheckBox4, "木", 1
EvSet Me.CheckBox5, "金", 1
EvSet Me.CheckBox6, "土", 1
EvSet Me.CheckBox7, "日", 1
EvSet Me.CheckBox8, "全曜日", 1
For i = 1 To 8
WCBs(i).Caption = Split(",月,火,水,木,金,土,日,全曜日", ",")(i)
Next i
'↑Mid関数からSplit関数に変更。
'Split関数は、区切り文字で区切った0からの配列を変える関数
'例では{"",月,火,水,木,金,土,日,全曜日}このような配列を返す
'配列は0から始まるので、1から始まる繰り返し処理のために、ダミーで配列0に""を当てている
'時間のチェックボックス群
EvSet Me.CheckBox9, "午前", 2
EvSet Me.CheckBox10, "午後", 2
EvSet Me.CheckBox11, "深夜", 2
EvSet Me.CheckBox12, "早朝", 2
EvSet Me.CheckBox13, "全日", 2
For i = 1 To 5
TCBs(i).Caption = Split(",午前,午後,深夜,早朝,全日", ",")(i)
Next i
'月のチェックボックス群
EvSet Me.CheckBox14, "月初", 3
EvSet Me.CheckBox15, "中旬", 3
EvSet Me.CheckBox16, "月末", 3
EvSet Me.CheckBox17, "全月", 3
For i = 1 To 4
MCBs(i).Caption = Split(",月初,中旬,月末,全月", ",")(i)
Next i
Me.CommandButton1.Caption = "入力"
Me.CommandButton2.Caption = "キャンセル"
Set rng = Range("O" & Selection.Row).Resize(, 3)
SetValue '▼参照
End Sub
'★クラスにチェックボックスを登録する関数
Function EvSet(ByRef chk As MSForms.CheckBox, ByVal Key As String, ByVal col As Long)
'クラスにチェックボックスを登録して、イベントをクラスに渡すようにする
Dim ev As clsGetChkEv
Set ev = New clsGetChkEv
Set ev.chkbox = chk
Select Case col
Case 1: WCBs.Add ev, Key
Case 2: TCBs.Add ev, Key
Case 3: MCBs.Add ev, Key
End Select
End Function
'▲クラスのクリックイベントから実行されるプロシージャ
Public Sub ChkClick(ByVal Cap As String)
'クラスのイベントから、押されたボタンのCaption情報のみを取得して、条件を分岐させる
Dim i As Long
Select Case Cap
Case "全曜日"
For i = 1 To 8
WCBs(i).Value = WCBs(Cap).Value
Next i
Case "全日"
For i = 1 To 4
TCBs(i).Value = TCBs(Cap).Value
Next
Case "全月"
For i = 1 To 3
MCBs(i).Value = MCBs(Cap).Value
Next i
End Select
End Sub
'■入力ボタンクリック
Private Sub CommandButton1_Click()
rng.Value = GetValue '●参照
Unload Me
End Sub
'■キャンセルボタンクリック
Private Sub CommandButton2_Click()
Unload Me
End Sub
'●入力ボタンクリック時、コレクションからデータを取得して、配列にする
Private Function GetValue() As Variant
'各列でマーク等の設定する可能性があるので、3つの処理に分割
Dim i As Long
Dim tmp(1 To 3) As String
'曜日
With WCBs
For i = 1 To WCBs.Count - 1 '全を除く
tmp(1) = tmp(1) & IIf(.Item(i).Value, "■", "□") & .Item(i).Caption & " "
Next i
End With
'時間帯
With TCBs
For i = 1 To TCBs.Count - 1 '全を除く
tmp(2) = tmp(2) & IIf(.Item(i).Value, "■", "□") & .Item(i).Caption & " "
Next i
End With
'月
With MCBs
For i = 1 To MCBs.Count - 1 '全を除く
tmp(3) = tmp(3) & IIf(.Item(i).Value, "■", "□") & .Item(i).Caption & " "
Next i
End With
GetValue = tmp
End Function
'▼フォームを立ち上げたときに、各コントロールにデータを入れるサブプロシージャ
Private Sub SetValue()
Dim x
On Error Resume Next
'曜日
With WCBs
For Each x In Split(rng(1, 1).Value, " ") '←半角の空白で区切って配列にしている
.Item(Mid(x, 2)).Value = Left(x, 1) = "■"
' ~~~~~~~~~~~~~~~~~
' =で繋ぐことで、直接True,Flaseを設定している
Next x
End With
'時間帯
With TCBs
For Each x In Split(rng(1, 2).Value, " ")
.Item(Mid(x, 2)).Value = Left(x, 1) = "■"
Next x
End With
'月
With MCBs
For Each x In Split(rng(1, 3).Value, " ")
.Item(Mid(x, 2)).Value = Left(x, 1) = "■"
Next x
End With
On Error GoTo 0
End Sub
(あき) 2015/02/17(火) 18:51
[ 一覧(最新更新順) ]
YukiWiki 1.6.7 Copyright (C) 2000,2001 by Hiroshi Yuki.
Modified by kazu.