今日は、生徒さんからの質問を取り上げます。
生徒さんは、どうやら出勤表を作っているようです。
今は、3月までしか作っていませんが、12月まで作りたいそうです。
さて、生徒さんの要望は、次の通りです。
1.出欠の列(B列、D列、F列・・・)には、空白か、「欠」「有給」という文字か、または数字だけを入力したい。
2.もしかしたら、上記2つの文字(「欠」「有給」)以外に、さらに指定文字が増えるかもしれない。
なるほど、出欠の列には、休んだ時の「欠」や「有給」を入力したり、出勤したときの出勤時間
(例えば8時間を意味する8)を入力したりしたいんでしょうね。
こんなとき、どうしたらいいのでしょうか?
エクセルの機能を使うとしたら、「入力規則」になりそうですね。でも、条件指定が、すこしばかりややこしいので、
戸惑いますよね。
VBAは、どうでしょうか?こんな要望に応えることができるのでしょうか?
結論から申し上げますと、「入力規則」でも、VBAでも、どちらでもできるのです。
今回は、VBAを取り上げます。(「入力規則」は、またの機会にご紹介します)
なお、今回の表は、「出欠表」というシートに書かれているとします。
それでは、Altキーを押しながらF11キーを押してください。VisualBasicEditorが起動します。
画面左のプロジェクトエクスプローラの中の「Sheet1(出欠表)」をダブルクリックしてください。
すると、画面右に、「Sheet1(出欠表)」のコードウィンドウが表示されます。
※いつもは、標準モジュールを追加挿入してコーディングしますが、今回は、違いますのでご注意を。
このコードウィンドウ内には、Sheet1のイベントに対応したプロシージャを記述することができます。
つまり、今回は、Sheet1のセルの値が書き換わったときに、上記の条件に沿ってルール違反がないかどうかを
チェックするわけです。
この「Sheet1のセルの値が書き換わったとき」というのが、いわゆるイベントと呼ばれるものです。
このイベントは、あらかじめ用意されているので、該当するイベントを選択して、そのイベント内にコーディングします。
今回は、Worksheetの値がChangeしたとき、というイベントを選択して、コードを書きます。
以下のように、まず、左側のWorksheet を選択して、次に、右側のChangeイベントを選択してください。
自動的に
Private Sub Worksheet_Change(ByVal Target As Range)
End Sub
が、表示されますので、この中に以下を参考にコードを書いてください。(解説もつけておきました。)
Option Explicit
'最終行を定数で指定
Private Const LAST_ROW As Integer = 32
Private Sub Worksheet_Change(ByVal Target As Range)
'B列、D列、F列に関して、数値もしくは、「欠」「有給」のみ入力OK
'今回は、ルール違反は、メッセージを表示して注意を喚起
'最終列を取得
Dim LastColumn As Integer
LastColumn = Range("A1").End(xlToRight).Column
With Target
'データの最終行以降なら処理を打ち切り
If .Row > LAST_ROW Then Exit Sub
'データの最終列以降なら処理を打ち切り
If .Column > LastColumn Then Exit Sub
'変更後の値が空白なら、処理打ち切り
If .Value = "" Then Exit Sub
'ルール違反かどうかの判定用フラグを用意
Dim IsOK As Boolean
IsOK = False
'偶数列ならば(列番号が2で割り切れるならば)
If .Column Mod 2 = 0 Then
'入力された値が数値ならば、ルールOK
If IsNumeric(.Value) Then
IsOK = True
End If
'入力された値が、指定された文字ならルールOK
If (.Value = "欠") Or (.Value = "有給") Then
IsOK = True
End If
'フラグがFalseならば、ルール違反
If IsOK = False Then
MsgBox "ルール違反です", vbExclamation, "注意!"
.Select
End If
End If
End With
End Sub
画像も載せておきます。
このイベントは、とにかくそれがどのセルであろうと、値が書き換わると発生します。
従って、プログラム内で、そのセルが、今回の対象の行や列のセルかどうかをチェックする必要があります。
あとは、値が数値かどうかのチェック(IsNumeric関数を使います)と、指定された文字かどうかのチェックを行います。
その結果によって、判定用の変数にTrue か False が格納されます。
(こうした判定用の変数をフラグと呼びます。旗のことですね。)
それでは、さっそく、エクセルに切り替えて入力してみましょう。
数値は問題なく入力できます。さあ、「欠席」という文字を入力してみました。
これは、ルール違反なので、メッセージボックスが表示されます。
「欠」という文字に修正すると、今度は、問題なく入力できました。
さて、実はまだもう一つの課題が残されています。
「欠」「有給」以外に、さらに指定文字が増えた場合はどうするか、という問題です。
コードの中の指定文字のチェックの条件分岐の部分をそのつど修正すれば、確かに対応できますが、
論理式の部分が、どんどん長くなっていってしまいます。
それに、あまりスマートとは言えません。
工夫の余地がありそうです。
それは、また次回に取り上げましょう。
だい