「エクセル日記」の作り方~その1~
拙作「エクセル日記」は、オンラインソフトを作り始めた私が、最初に作ったソフトだ。それなりに思い入れのある作品である。しかしあまりにも前のことなので、自分でもどうやって作ったのかよく覚えていない。この際、見直してみようという気になった。そこでこれから何回かに分けて「エクセル日記」の作り方を書くことにした。こんな記事に興味のある人はあまりいないと思うが、興味のある方はどうかお読み頂きたい。
まず作られた背景から始めなくてはならないだろう。当時(2002~2003年頃)、私は希死念慮を伴う重度のうつ病だった。通院は今も続けているが、その頃の心療内科の主治医が「日記をつけること」を勧めてくれた。うつ病では、日常の雑多な出来事や感情の整理がつかなくなり、深い焦燥感や抑うつ感、思考力や集中力の低下が起こる。それまで興味のあったことにも意欲を失い、何を見ても聞いても心が動かされない。重度のうつ病というのは、経験したものだけにしか分からない地獄の世界なのだ。
そこで主治医のアドバイスを実践するために、病を押して作ったのがこの「エクセル日記」である。完成した日記には、日常の様々なこと、感じたことはもちろん、当時飼っていたペットのこと、日々の献立、外食の記録など、とりとめもなく書いていった。すると心做しか気持ちが整理され楽になっていった。日記はそのまま「闘病記」として、今でも見返すことがある。あのときの主治医のアドバイスには感謝している。もちろん「エクセル日記」は今でも付けている、頻度はだいぶ減ってきているが。
さて、お付き合い頂ける読者諸氏には、最初に「エクセル日記」をダウンロードしてもらいたい。
まずExcelで日記ソフトを作ることの是非だが、いくつかの疑問点があった。第一に文字数の問題。ひとつのセルに日記本文を書いていく、という仕様は最初から思い描いていた。問題は許容文字数である。「第六回 シート上の選択セルにフォームからテキストを入力する」の記事でも書いたが、Excelのひとつのセルに記入できる日本語は16,383 文字(全角文字)である。これは、ひとつのセルに「源氏物語」一巻が余裕で入る文字数なのである。これだけあれば充分すぎると言って良い。これで1つ目の疑問は払拭された。次に、セル一行を一日として計算したときに行数が足りるのかという問題だ。Excelのシート行数は65,536行(Excel2016以降のバージョンでは1,048,576行)である。これを年数に換算すると、65,536÷365=179。つまり179年間使い続けられることが分かった。どうやら行数も充分なようだ。結局、問題はどちらもクリアされたわけである。実際に「エクセル日記」を見てみよう。以下の方法で日記シート、日付マスターシートの計算式が閲覧可能に出来るのでやってみて欲しい。
①Alt+F11でVBE画面を表示する。
②Sheet1(日記)をクリックしてプロシージャを表示する。Private Sub Worksheet_Activate()プロシージャの一番下Sheets(“日記”).ScrollArea = “B4:F65536″の行をコメントアウトする。同様に、
③Private Sub CommandButton4_Click()プロシージャの.ScrollArea = “A4:R65536″とPrivate Sub CommandButton7_Click()プロシージャの.ScrollArea = “C5:S65536”
の行をそれぞれコメントアウトする。
④Workbookをクリックしてプロシージャを表示する。Private Sub Workbook_Open()プロシージャのSheets(“日記”).ScrollArea = “B4:F65536″をコメントアウトする。
⑤[ファイル]-[オプション]でExcelのオプションを開き-[詳細設定]-[次のシートで作業するときの表示設定(S)]の[行列番号を表示する(H)]にチェックを付けて-[OK]ボタンを押す。これで日記シートに行列見出しが表示される。日記シートで[校閲]-[シート保護の解除]を行なったあとシート全体を選択して(シート左上の⊿をクリック)。そのあとマウスポインターを、シートの中ほどに持って行ってから「再表示(U)を押す。これでそれまで非表示だった1行目が表示される。
⑥次に日記シートの非表示列E,H,I,J,K,Lをドラッグして引き伸ばす。
日付マスターシートを開き[校閲]-[シート保護の解除]を行なったあとシート全体を選択して(シート左上の⊿をクリック)。そのあとマウスポインターを、シートの中ほどに持って行ってから「再表示(U)を押す。これでそれまで非表示だった1行目が表示される。
⑦日付マスターシート、日記シート、写真シート共、一行目に入った計算式は、入力行追加の際に、追加された行にコピーするためのものである。以下に入力行追加のプロシージャを示す。日付マスターシートの「入力行追加」ボタンで呼び出すが、標準モジュールであるから[マクロの表示]-[実行]で走らせることが出来る。実際に試してもらいたい。1から365の間の行数が追加出来る。
Sub 入力行追加()
Dim メッセージ As String
Dim 表題 As String
Dim 規定値 As Integer
Dim 応答 As Variant
Dim 応答2 As Variant
Dim 行番号 As Integer
Dim 行番号2 As Integer
メッセージ = “追加する行数を入力してください(※365行以内)。”
表題 = “入力行追加”
規定値 = “365”
応答 = InputBox(メッセージ, 表題, 規定値)
If 応答 > 365 Or 応答 < 1 Then
MsgBox “365以内の自然数(1~365)を入力してください。”
Else
応答2 = MsgBox(” 指定された行数を追加します。”, _
vbOKCancel + vbExclamation, “入力行追加”)
If 応答2 = vbOK Then
Worksheets(“日付マスター”).Visible = True
Worksheets(“日付マスター”).Select
Worksheets(“日付マスター”).Unprotect
Sheets(“日付マスター”).ScrollArea = “A1:IV65536”
Range(“A2”).Select
行番号 = ActiveSheet.Cells.SpecialCells(xlLastCell).Row + 1
Rows(行番号).Resize(応答).Insert Shift:=xlDown
Range(“A1:Y1”).Copy
Range(Cells(行番号, 1), Cells(行番号 + 応答 – 1, 1)).PasteSpecial
Application.CutCopyMode = False
Cells(行番号 – 応答 – 1, 1).Select
Selection.AutoFill Destination:=Range(Cells(行番号 – 応答 – 1, 1), Cells(行番号 + 応答 – 1, 1)), Type:=xlFillDefault
ActiveSheet.Protect
Worksheets(“日記”).Select
Worksheets(“日記”).Range(“A2”).Select
ActiveSheet.Unprotect
Worksheets(“日記”).ScrollArea = “A1:IV65536”
行番号2 = ActiveSheet.Cells.SpecialCells(xlLastCell).Row + 1
Worksheets(“日記”).Rows(行番号2).Resize(応答).Insert Shift:=xlDown
Worksheets(“日記”).Range(“A1:Y1”).Copy
Worksheets(“日記”).Range(Cells(行番号2, 1), Cells(行番号2 + 応答 – 1, 1)).PasteSpecial ‘※
Application.CutCopyMode = False
Worksheets(“日記”).Cells(行番号2 – 応答 – 1, 3).Select
Selection.AutoFill Destination:=Range(Cells(行番号2 – 応答 – 1, 3), Cells(行番号2 + 応答 – 1, 3)), Type:=xlFillDefault
ActiveSheet.Protect
Worksheets(“写真”).Visible = True
Worksheets(“写真”).Select
Worksheets(“写真”).Range(“A2”).Select
ActiveSheet.Unprotect
Sheets(“写真”).ScrollArea = “A1:IV65536”
行番号2 = ActiveSheet.Cells.SpecialCells(xlLastCell).Row + 1
Worksheets(“写真”).Rows(行番号2).Resize(応答).Insert Shift:=xlDown
Worksheets(“写真”).Range(“A1:Y1”).Copy
Worksheets(“写真”).Range(Cells(行番号2, 1), Cells(行番号2 + 応答 – 1, 1)).PasteSpecial ‘※
Application.CutCopyMode = False
Worksheets(“写真”).Cells(行番号2 – 応答 – 1, 3).Select
Selection.AutoFill Destination:=Range(Cells(行番号2 – 応答 – 1, 3), Cells(行番号2 + 応答 – 1, 3)), Type:=xlFillDefault
ActiveSheet.Protect
Sheets(“日付マスター”).Select
ActiveWindow.SelectedSheets.Visible = False
Worksheets(“写真”).Select
Worksheets(“写真”).Visible = False
MsgBox ” 行追加終了。”
If 応答2 = vbCancel Then
Exit Sub
End If
End If
End If
End Sub
さて日付マスターシートと日記シートの一行目の計算式を順に見て行こうと思う。
①まず日付シートのK列は、J列が空欄でない場合にJ列に入力された日付の曜日を表示する。
②日付シートのM列は、J列がゼロでない場合に数字の1を表示する。
③日付マスターシートC列は、B列が土日のときに数字の1を入れ、更にA列の日付がJ列を参照し、もしJ列にあった場合には数字の1を表示するという計算式でネストされている。
④日付マスターシートD列の計算式は、VLOOKUPのエラーを非表示にする関数(※今回レビューしてみて、この計算式が不要であることに気が付いた)。
⑤日記シートのD列は、C列の日付の曜日を表示している。
⑥日記シートのE列は、VLOOKUPで日付マスターのC列を参照している(※今回レビューしてみて、この計算式は単純に日付マスターのC列とイコールで良かったことに気付いた)。
⑦日記シートのJ列は、本日未満の日付を空欄にし、本日以降の日付を表示している。
⑧日記シートのK列は、本日未満の日付の曜日を空欄にし、本日以降の日付の曜日を表示している。
⑨日記シートのL列は、本日未満の日付の曜日を空欄にし、本日以降の日付のB列(行事・予定)を表示している。
⑩日記シートのI列は、L列がゼロまたは空欄の場合に空欄とし、それ以外の場合に数字の1を表示させている。
⑪日記シートのH列は、I列が数字の1の場合にその行までのI列の合計を表示し、それ以外の場合空欄としている。ちなみに、この計算式は後で述べる予定表シートと予定一覧フォームでじわじわと効いてくるのだ(笑)。