入力を簡単にする方法
今回の勤務シフト表は、○、◎、明、休などで勤務形態を分けています。
これらをいちいち入力するのは面倒ですし、間違って入力する可能性もあります。
このような時は、セルの入力規則を使うのが良いでしょう。入力の候補となる文字をリスト化してコンボボックスから選ぶようにすれば入力ミスを防ぐことができます。
ただ、これでも大量にある升目にいちいち入力していくのは面倒です。
そこで入力用のユーザーフォームを出しておいて、セルを選択してボタンを押せば値が入力できるようにして見ます。
選択はShiftキーやCtrlキーを押して複数選択しても全て入力できるようにしてみます。
さらに、○、◎、明、休と連続したパターンを一度に入力できるようにしてみます。

シートにボタンを配置
まずは勤務表に「入力用ダイアログ」という名前でコマンドボタンを配置します。
標準モジュールには、このボタンを押すとユーザーフォームが表示されるようにしましょう。
今回はUserForm2とします。
'/// 標準モジュール
Sub 入力用ダイアログ()
UserForm2.Show
End Sub
ユーザーフォームを追加
プロジェクトウインドウから右クリックで「挿入」>「ユーザーフォーム」としてユーザーフォームを追加します。
追加したユーザーフォームにボタンやラベルを追加していきます。

今回は以下のようになります。
・Label1 「選択されたセルに値を入力します。」など説明を書きます。
・CommandButton1 ○ボタン
・CommandButton2 ◎ボタン
・CommandButton3 明ボタン
・CommandButton4 休ボタン
・CommandButton5 ○◎明休ボタン
・CloseButton 閉じるボタン
UserForm2の設定
今回は、モードレスで動作させますので、ShoeModal を False にしておきます。

また、 Caption には 「勤務シフト入力」 と書いておきます。
閉じるボタン
ユーザーフォームを閉じるボタンは以下のようになります。
’UserForm2のモジュール
Private Sub CloseButton_Click()
Unload Me
End Sub
値入力用のボタン
○、◎、明、休などのボタン入力の処理は殆ど同じ内容です。
手順としては以下ように進めます。
1.Selectionから1つずつセルを取り出す。
2.セルの行番号、列番号が範囲内にあるか判定
3.更に日付のある列か?氏名のある行か?を判定
4.全てクリアしていれば、該当する値を入力
3では、範囲内であっても小の月で日付が無い場合を考慮し、また氏名がない場合は入力しないようにしています。
また、共通する部分を1つの関数にまとめるようにします。
関数名は setCellItem とし、引数には入力する行、列、文字を取ることにしました。
'UserFrom2のモジュール
Sub setCellItem(r As Long, c As Long, item As String)
'入力範囲内にあるか?
If r > 4 And r < 15 And c > 1 And c < 33 Then
'日付のある列か?氏名はあるか?
If Cells(3, c) <> "" And Cells(r, 1) <> "" Then
Cells(r, c).Value = item
End If
End If
End Sub
入力する文字ごとに以下のようにコードを書いていきます。
内部で、先ほどの setCellItem を呼び出しています。
'UserFrom2のモジュール
'○
Private Sub CommandButton1_Click()
Dim c
For Each c In Selection
Call setCellItem(c.Row, c.Column, "○")
Next c
End Sub
'◎
Private Sub CommandButton2_Click()
Dim c
For Each c In Selection
Call setCellItem(c.Row, c.Column, "◎")
Next c
End Sub
'明
Private Sub CommandButton3_Click()
Dim c
For Each c In Selection
Call setCellItem(c.Row, c.Column, "明")
Next c
End Sub
'休
Private Sub CommandButton4_Click()
Dim c
For Each c In Selection
Call setCellItem(c.Row, c.Column, "休")
Next c
End Sub
最後に、○◎明休と連続で入力する部分です。
こちらは列を移動させるながら入力しています。
共通部分に For Each c In Selection を組み込まなかったのは、この関数で何度も For Each が呼び出されないようにするためです。
'UserFrom2のモジュール
Private Sub CommandButton5_Click()
Dim c
For Each c In Selection
Call setCellItem(c.Row, c.Column, "○")
Call setCellItem(c.Row, c.Column + 1, "◎")
Call setCellItem(c.Row, c.Column + 2, "明")
Call setCellItem(c.Row, c.Column + 3, "休")
Next c
End Sub
動作確認
入力用ダイアログボタンを押すとボタンを押して値入力ができるようになっています。
最初にセルを選択してから好きなマークのボタンを押して入力できます。
ShiftキーやCtrlキーで複数選択してからボタンを押すと選択した部分に一度で入力できます。
また、関係のない範囲には入力しないように配慮されています。