「エクセル日記」の作り方~その3~
3回目である。今回は日記シートの各ボタンのプロシージャを取り上げようと思う。今回レビューしてみて、放置されていたバグを数カ所発見してしまった。使わない変数を宣言していたり、不要な行があったりで、何とも冷や汗が出る思いであるが、この機会に修正させて頂いた。
Private Sub CommandButton1_Click() ‘日記入力
With UserForm1
.Label34.Caption = “日付を入力して検索ボタンを押してください。”
.Show vbModeless
.TextBox1.Text = “”
End With
End Sub
日記入力フォームをvbModelessで開いている。これでフォームを開いたままでシートの選択・スクロールが可能になる。「.TextBox1.Text = “”」の行は一見「.TextBox1.Setfocus」で構わないように思えるが、これだと昨日へボタンを押したときに、予期せぬ挙動を起こすことが今回のレビューで判明した。試しに「.TextBox1.Setfocus」にして昨日へボタンを押してみると、その意味が分かるはずだ。あるいはTextBox1に「文字列」を入れたときにも同じ挙動となる。厳密にはエラートラップが必要なのだろうが、さしたる重要性は感じられないため、ここではTextBox1の初期値を空文字(””)にするということでお茶を濁すことにした。
Private Sub CommandButton3_Click() ‘開く
Dim 選択行 As Integer
Dim 呼び出し As String
Dim 応答 As Variant
選択行 = Selection.Row
呼び出し = Cells(選択行, 3)
応答 = MsgBox(呼び出し & ” を開きます。”, _
vbOKCancel + vbExclamation, “開 く”)
If 応答 = vbOK Then
If 選択行 > 4 Then
With UserForm1
.TextBox1.Text = Cells(選択行, 3).Text ‘日付
.TextBox48.Text = Cells(選択行, 2).Text ‘予定
.TextBox45.Text = Cells(選択行, 6).Text ‘日記
.TextBox47.Text = Cells(選択行, 4).Text ‘曜日
.Label34.Caption = “”
.Label33.Caption = “入力できます。”
.Show vbModeless
.TextBox45.SetFocus
End With
Else
MsgBox (” 選択したセルが適当ではありません。やり直してください。”)
End If
Else
Exit Sub
End If
End Sub
開くボタンのClick()イベント。「選択行」は、文字通りシート上で選択した行、変数「呼び出し」は選択した行の3列目(日付)だ。このプロシージャは分かり易いのでことさら解説の必要はないだろう。
Private Sub CommandButton2_Click() ‘印刷
UserForm2.Show vbModeless
End Sub
でUserForm2(印刷フォーム)が表示される。
Private Sub CommandButton1_Click()’実行
Dim 選択行1 As Long
Dim 選択範囲行1 As Long
Dim 参照日付1 As Variant
Dim 日付1 As Date
Dim 選択行2 As Long
Dim 選択範囲行2 As Long
Dim 参照日付2 As Variant
Dim 日付2 As Date
If TextBox1 = “” Or TextBox2 = “” Then
Label3 = “印刷開始日付と印刷終了日付を入れてください。”
TextBox1.SetFocus
Else
On Error GoTo errhandler
参照日付1 = TextBox1.Value
参照日付2 = TextBox2.Value
For 選択範囲行1 = 5 To 65536
日付1 = Cells(選択範囲行1, 3).Value
If 日付1 = 参照日付1 Then
選択行1 = 選択範囲行1
End If
Next 選択範囲行1
For 選択範囲行2 = 5 To 65536
日付2 = Cells(選択範囲行2, 3).Value
If 日付2 = 参照日付2 Then
選択行2 = 選択範囲行2
End If
Next 選択範囲行2
Range(Cells(選択行1, 2), Cells(選択行2, 6)).Select
With ActiveSheet.PageSetup
.RightHeader = TextBox1.Value & “~” & TextBox2.Value
End With
TextBox1.Value = “”
TextBox2.Value = “”
Label3.Caption = “”
UserForm2.Hide
Selection.PrintOut preview:=True
Exit Sub
errhandler:
MsgBox “ その印刷範囲は存在しません。”, vbOKOnly, “印刷範囲検証”
TextBox1.Value = “”
TextBox2.Value = “”
Label3.Caption = “”
TextBox1.SetFocus
End If
End Sub
実行ボタンのClick()イベント。印刷開始日付と印刷終了日付のいずれかが空欄の場合 Label3のCaptionを “印刷開始日付と印刷終了日付を入れてください。”とする。それ以外の場合「参照日付」にTextBox1.Valueの日付を代入する。「選択範囲行」は検索する範囲で、5行目から65536行目まで。その中の3列目(日付)の値を変数「日付」に代入する。「日付」と「参照日付」が一致するまで「選択範囲行」を検索する。一致したらループを抜けて、その行を「選択行」に代入する。この処理を、印刷開始日付と印刷終了日付それぞれについて行なう。以上によって求めた2つの行の2列目から6列目を印刷範囲として印刷プレビュー画面を表示する。errhandler:は、存在しない日付を入力した場合のトラップ。印刷開始日付と印刷終了日付を逆に入力した場合はどうなるか?普通に印刷される。厳密にはトラップすべきだろうが、さしたる重要性は感じられないためそのまま。
Private Sub CommandButton9_Click() ‘検索
With UserForm9
.Show vbModeless
.TextBox1.SetFocus
End With
End Sub
でUserForm9(検索フォーム)が表示される。
Private Sub CommandButton1_Click() ‘検索
Dim 検索値 As Variant
On Error GoTo errhandler
検索値 = UserForm9.TextBox1.Value
If UserForm9.TextBox1.Value = “” Then
MsgBox “ 検索する語句を入れてください。”
UserForm9.TextBox1.SetFocus
Else
Columns(“B:F”).Select
Cells.Find(What:=検索値, After:=ActiveCell, LookIn:=xlValues, LookAt:= _
xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:= _
False, MatchByte:=False).Activate
Label1 = “”
CommandButton2.Enabled = True
errhandler:
Select Case Err.Number
Case 91
MsgBox “ その検索値は存在しません。”
End Select
End If
End Sub
検索ボタンのClick()イベント。TextBox1が空欄の場合 “ 検索する語句を入れてください。”とメッセージ表示する。それ以外の場合に検索を開始する。LookAt:=xlPartは部分一致、SearchOrder:=xlByRowsは列方向に検索するの意。詳しくは「Findメソッド」でググってみて欲しい。
Private Sub CommandButton6_Click() ‘予定一覧
With Sheets(“予定表”)
.Visible = True
.Select
.ScrollArea = “A1:A1”
End With
UserForm6.Show
End Sub
Private Sub CommandButton1_Click() ‘閉じる
UserForm6.Hide
Sheets(“予定表”).Visible = False
Sheets(“日記”).Select
End Sub
Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer)
UserForm6.Hide
Sheets(“予定表”).Visible = False
Sheets(“日記”).Select
End Sub
このように予定一覧フォームは、閉じるボタンで閉じた場合も右上隅の✖で閉じた場合も、日記シートに戻るようになっている。そのため予定表シートの計算式を見ることが出来ない。まずこれを見られるようにしなければならない。そのためにまず上記CommandButton1_Click()プロシージャとUserForm_QueryClose(Cancel As Integer, CloseMode As Integer)プロシージャの次の2行をコメントアウトして欲しい。
‘ Sheets(“予定表”).Visible = False
‘ Sheets(“日記”).Select
次にSheet1(日記)をクリックしてプロシージャを表示し、Private Sub CommandButton6_Click()プロシージャの.ScrollArea = “A1:A1″をコメントアウトする。最後に予定表の計算式解析である。見れば「なぁーんだ」と思うような仕掛けになっているのだ。では予定一覧ボタンを押してみよう。表示された予定一覧フォームはそのまま閉じる。[校閲]-[シート保護の解除]を行なったあと「列幅ゼロ」になっているA列からE列までをドラッグして広げてみて欲しい。A1セルからA1000セルまでは通し番号。B1セルには「=VLOOKUP($A1,日記!$H$5637:$L$65536,2,FALSE)」という計算式が入っている。これは日記シートのI列を参照している。参照元は予定表シートのA1すなわち「通し番号」である。ここで日記シートのH列に入れた「通し番号」が生きてくる。各通し番号の右側のJ列(=日付)K列(=曜日)L列(=予定・行事)をそれぞれ参照し、これが表示されている予定表シートのC列からE列までを予定一覧フォームのListBox1にRowSourceとして表示させているわけだ。
3回に渡って行なってきた「エクセル日記」の作り方。次回は最終回の予定。
続く