今回はチェックボックスに書式変更できる機能を実装します。チェックボックスとはエクセルの書式設定ダイアログ等で見るアレの事です。

コレの事です。
普通のボタンと違ってオンとオフの状態が判るのが利点です。チェックを入れたら書式変更、外したら書式を戻す、という仕様にします。
準備
今回はエクセルの「名前の定義」を利用するので適当な範囲を定義して下さい。

[数式]タブの[名前の定義]をクリックするとダイアログが現れます。

名前を付け、参照範囲を設定して下さい。
サンプルはカレンダーの月曜部分を「月曜」と定義していますが、皆さんがテストする分には適当な範囲で構いません。ただし、今回はFor Each ~ Nextステートメントを使用するので範囲がある程度あった方がマクロの動きが分かりやすいと思います。
チェックボックスで書式を変更する
仕様
- チェックボックス「オン」でカレンダーの月曜日全てを「赤字」「太字」「下罫線(赤)」に変更する
- チェックボックス「オフ」で元の書式に戻す
チェックボックスの作成
チェックボックスには「フォームコントロール」と「ActiveXコントロール」の2種類がありますが、違いについて興味のある方は以下のサイトを読んで下さい。
フォームの場合、ボタンはマクロの実行ができますが、ボタン以外(チェックボックスも含まれます)はマクロの実行ができないので今回はActiveXコントロールを使用します。「なんで?」なんて事考えてたら手が止まるので考えないように。

[開発]タブの[挿入]アイコンをクリックします。

[ActiveXコントロール]の[チェックボックス]をクリックします。

適当な場所でドラッグするとチェックボックスが現れます。

[デザインモード]アイコン→チェックボックスを右クリック→[プロパティ]と進み、現れた「プロパティウィンドウ」の[Caption]欄を付けたい名前に変更します。
これでチェックボックスの見た目は完成です。先述のフォームコントロールとの違いですが、ActiveXコントロールはプロパティで見た目の変更ができます。色を付けたいとか書式を変更したいのであればプロパティを適当にいじって遊んでみて下さい。
For Each ~ Nextステートメント
では、コードを書いていきますサンプルを拾ってきます。なかなかヒットしませんでしたが、以下のワードで目的のコードに辿り着けました。
Sub monday_set()
Dim rng As Range '変数宣言
For Each rng In Range("月曜") '「月曜」で定義された範囲を取得
With rng.Borders(xlEdgeBottom) '書式変更_下罫線
.color = vbRed
.Weight = xlMedium
End With
With rng.Font '書式変更_太赤字
.color = vbRed
.Bold = True
End With
Next rng '書式変更を取得した範囲まで繰り返す
End Sub
Sub monday_cancel()
Dim rng As Range '変数宣言
For Each rng In Range("月曜") '「月曜」で定義された範囲を取得
rng.Borders(xlEdgeBottom).LineStyle = xlLineStyleNone '罫線を消す
With rng.Font '書式_黒色、太字キャンセル
.color = vbBlack
.Bold = False
End With
Next rng '書式変更を取得した範囲まで繰り返す
End Sub
前回記事で作成した書式変更コードをそのままサンプルに入れ込みました。キャンセルするコードも一緒に作成しました。早速実行すると、

マクロ「monday_set」を実行すると、月曜で定義した範囲が全て、書式変更されました。「monday_cancel」を実行すると元の書式に戻りました。
すごい、すごいですよFor Each ~ Nextステートメント。これは便利ですね。このステートメントの中に書かれたコードを繰り返し実行してくれる訳です(繰り返す回数は今回の場合、「月曜」で定義された範囲全て)。先ほどのサイトにFor ~ Next(Eachがない)ステートメントのサンプルもありましたが、今回のケースはFor Each ~ Nextでよさそうです。しかしFor ~ Nextも今後お世話になりそうな予感なので、 「For~ は2種類ある」 と頭の片隅に置いておきましょう。
If ~ Thenステートメント
おおよそ狙った動きにはなりましたが、一部想定外の部分があるので修正していきます。
- 日付が入っていない空白部分も下罫線が変更される
- 1セルずつ変更される様子が描画される(見た目が遅そうで嫌)
1番目は「セルが空白でなかったらコードを実行する」でなんとかなりそうな予感。2番目は…ググればなんとかなるさ(毎度適当)。
こんなワードでヒットさせてくれるGoogleは素敵です。
もし〜ならの書き方が If 条件式 Then なので
If Range(“A1”).Value <> “” Then
https://detail.chiebukuro.yahoo.co.jp/qa/question_detail/q10146188485
Ifはエクセル関数にあるので何となく判りますね。ちなみにこのIf ~ Thenステートメント、1行で記述できる場合はEnd ifは省略できるそうです。
Application.ScreenUpdating
続いて2番目ですが、なかなかヒットしません。やっとの思いで辿り着いたこのワードでヒットしました。
このサイトではこの「Application.ScreenUpdatingを勘違いして乱用しても早くならないよ」と教えてくれていますが、今回のケースは使ってもいいよね?間違ってないよね?(独り言)
空白無視、描画ストップ
Sub monday_set()
Dim rng As Range
Application.ScreenUpdating = False '画面の描画と止める
For Each rng In Range("月曜")
If rng.Value <> "" Then 'もし定義した範囲が空白でなかったら
With rng.Borders(xlEdgeBottom)
.color = vbRed
.Weight = xlMedium
End With
With rng.Font
.color = vbRed
.Bold = True
End With
End If 'If ~ Thenが1行で記述できる場合は省略可能
Next rng
Application.ScreenUpdating = True ’画面描画
End Sub
Sub monday_cancel()
Dim rng As Range
Application.ScreenUpdating = False
For Each rng In Range("月曜")
rng.Borders(xlEdgeBottom).LineStyle = xlLineStyleNone
With rng.Font
.color = vbBlack
.Bold = False
End With
Next rng
Application.ScreenUpdating = True
End Sub

空白セルは罫線が引かれなくなり、1セルずつ処理される様子も映らなくなりました。
おまじないでApplication.ScreenUpdatingを使わないようにしましょう(教え)。
チェックボックスでマクロを実行する
私も少し慣れてきたのでここからは自力でできそうです。subプロシージャを実行するのにイベントを使用します。当然、チェックボックスをトリガーにしますが、とりあえずWorksheetイベントプロシージャを覗いてみます。

プロシージャ内にちゃんと「CheckBox1」オブジェクトがありました。「Click」イベントも用意されています。
ここに呼び出すsubプロシージャを書いてやれば解決、とはいきませんでした。チェックボックスのオンオフ判定の仕方がわかりません。結局ググります(全然自力でできなかった)。
Private Sub CheckBox1_Click()
If CheckBox1 Then
‘Trueのときの処理または、Call 処理1
Else
‘Falseのときの処理または、Call 処理2
End If
End Sub
https://detail.chiebukuro.yahoo.co.jp/qa/question_detail/q1197144376
何となくわかるんですけど、これって省略されてね?って事でもうちょっと調べて以下のコードになりました。
チェックボックスでマクロ実行
Private Sub CheckBox1_Click()
If CheckBox1.Value = True Then 'チェックボックスがオンの時
Call monday_set 'マクロ「monday_set」を実行する
Else 'trueでない場合=falseの場合
Call monday_cancel 'マクロ「monday_cancel」を実行する
End If
ActiveCell.Activate 'セルをアクティブにする
End Sub
省略しすぎてもわかりにくいので、わかるように書きました。始めたばかりの自分にはこれくらい書かないと理解できません。
7行目の「セルをアクティブにする」はマクロ実行後、チェックボックスにフォーカスが残っているのが嫌で追加しました(作業性向上)。また、Call ~ですが、以前の記事でマクロ実行はOnActionを使用しました。何が違うか調べてみました。
- Call…Callステートメント
- OnAction…OnActionプロパティ
プロパティはオブジェクトの情報を取得・設定する、Callはステートメントだから命令文、うーん、わかりません(投げやり)。ただ、オブジェクト.プロパティとかオブジェクト.メソッドみたいな感じでコードを書けば動くのはわかってきたかも。とりあえずエラーが出たらググって直してを繰り返していけばステートメントもプロパティもその内理解できると信じています。
完成
今回の出来高です。
Worksheetイベントプロシージャ
Private Sub CheckBox1_Click()
If CheckBox1.Value = True Then
Call monday_set
Else
Call monday_cancel
End If
ActiveCell.Activate
End Sub
subプロシージャ(標準モジュール内)
Sub monday_set()
Dim rng As Range
Application.ScreenUpdating = False
For Each rng In Range("月曜")
If rng.Value <> "" Then
With rng.Borders(xlEdgeBottom)
.color = vbRed
.Weight = xlMedium
End With
With rng.Font
.color = vbRed
.Bold = True
End With
End If
Next rng
Application.ScreenUpdating = True
End Sub
Sub monday_cancel()
Dim rng As Range
Application.ScreenUpdating = False
For Each rng In Range("月曜")
rng.Borders(xlEdgeBottom).LineStyle = xlLineStyleNone
With rng.Font
.color = vbBlack
.Bold = False
End With
Next rng
Application.ScreenUpdating = True
End Sub
チェックボックスのオンオフでマクロが実行できるコードが完成しました。これも以前紹介した「右クリックメニュー」同様、subプロシージャを書き換えれば色々な機能が実装できるので今後も重宝しそうです。
これで「万年カレンダー」に実装した機能の骨組みは全て紹介できました。初めて本格的にVBAに取り組み、何とか動く機能を実装する事ができましたが、やっと初心者の仲間入りといった所でしょうか。次回は「差し込み印刷」に挑戦したいと思います。実務で役立つ機能に仕上げていきたいと思うので、出来上がった際には是非ダウンロードしてみて下さい。
では、最後までご高覧いただきありがとうございました。