「カレンダー入力」用フォーム:アドイン版

前頁の「カレンダー入力用フォーム」では実装が難しいと思われていた方へ
前頁と同じ、カレンダー表示から日付を選択することで日付を入力するものです。   前頁のものは機能や動作を欲張ったためか、実際に利用者が日付入力が必要なワークブックに組み込むのに手間が掛かるものになってしまいました。 組み込むのに必要な知識などは「初心者ではちょっと無理」なレベルかも知れません。
ユーザーフォームや関連クラスなど実装するメンバが多いだけでなく全てのソースコードが見えてしまうので、 当サイト側では利用者が手を加える必要がないものまで説明することになってしまっていましたから余計に混乱させてしまったかも知れません。



そこで、ワークシート上で「カレンダー入力」は欲しいけれど「VBAは初心者」という方のために「アドイン版」を用意しました。
アドインの内部は非公開といたしますが、ワークシート上での「カレンダー入力」フォームの動作は前頁のものと同じです。



若干の制限事項はありますが、VBA初心者でも理解が比較的簡単で実装まで短距離でご利用いただけるものです。

「カレンダー入力用フォーム」とは?
ワークシート上の日付入力補助として小さいカレンダーのウィンドウを表示させ、そのカレンダーウィンドウ上で日付を選択することで指定セルに日付を入力させるツールです。 ユーザーインターフェイスの説明は前頁と重複しますが、念のため説明します。



シート上で「カレンダー入力フォーム」を表示させたところ

これがサンプルを起動して日付セルでカレンダーを表示させたところです。



本プログラムのカレンダーとしての動作は以下のようになります。
項目内容
日付セルの指定 日付セルは予め呼び出しワークブック側のソースコードで指定する仕組みです。
ですから若干のソースコードの作成が必要になりますが、下記のサンプルで説明する程度の簡単なものです。 これらにより「日付セル」として指定されたセルだけカレンダーが表示され、それ以外のセルではカレンダーは表示されません。
呼び出し方法 日付セルをマウスでダブルクリックするか、日付セルを選択した状態でF4キーを押すことでカレンダーが表示されます。



本プログラムのカレンダーでの日付入力はあくまで「入力補助」であり「強制」ではありません。
Excelではセルに対して「月日」のみの入力で「年」を含めた日付が入力できるためこのようなカレンダーでの日付入力はニーズが薄いと思われがちですが、 年末年始近辺での作業で「月日」のみの入力でよく誤りが起きることはご存じだと思います。 ここでカレンダーでの日付入力を通常に運用されていればこのような誤りは軽減されるでしょう。
カレンダー上での操作 カレンダー上で所望する日付をクリックするか、青反転の日付カーソルを上下左右の矢印キーで移動させてEnterキーを押すことで 日付が決定され日付セルにその日付が入力され、カレンダーは閉じられます。 カレンダーを表示させてから不要になった場合は右上の×ボタンかEscキーで閉じられます。



この他年月の切り替えなどを含めてキーボードでの操作にも留意しており、青反転の日付カーソルを上下左右の矢印キーで移動させる時に現在表示月の範囲を超える場合は 自動的に年月が変更されるなどの対応を行なっています。それぞれは次の表で説明します。
カレンダーの表示位置 カレンダーは上記画像のように呼び出した日付セルの直下に表示されます。 この状態でカレンダーがディスプレィスクリーンからはみ出してしまう場合は直上に表示されます。
表示初回年月 日付セルからカレンダーが呼び出された初回は、日付セルに既に日付が入力されている場合はその日付の年月が選択された状態で表示され、 日付セルに日付が入力されていない場合は処理日(システム日付)の年月が選択された状態で表示されます。
表示年月の変更 カレンダー上部の年月表示からの変更は、カレンダー上部左右の矢印(←、→)の他、 カレンダー上部の年月表示の「年」「月」をマウスでクリックするとプルダウンが表示されるので、直接「年」「月」を変更することも可能です。 キーボードからの年月変更については次の表で説明します。
曜日並びの変更 曜日並びはデフォルトでは上の画像のように一般的なカレンダーと同じで日曜日が左端となる順序ですが、サンプルからコピーしていただく定数の変更だけで 月曜日が左端となる順序に変更できます。
祝日の表示 本プログラムのカレンダーは日本の政令での祝日に対応しており、祝日は上の画像で見られるように赤字で表示されます。 この赤字の日付をマウスでポイントすると祝日名がカレンダー下部のステータス領域に表示されます。



20192021年は天皇誕生日の変更や東京五輪による祝日移動、さらには東京五輪延期による移動などがあり、 本カレンダーもそれらの祝日にも対応しております。
アドインにしたことによる祝日処理への影響は利点・欠点が共にあり、下記で説明しています。
Excelで利用できるカレンダー機能は多数公開されていると思いますが、利用目的や機能、制限事項などはさまざまなようです。 本プログラムはサンプルを含めて動作確認ができるので上記の項目などを確認してご利用いただければと思います。



キーボード入力での各キーの機能は以下のようになっています。(前頁と同じです)
押下キー動作機能
→、Tab、+、6(テンキー)翌日に移動します。(表示範囲を超えると自動的に翌月に移動します。)
←、Shift+Tab、-、4(テンキー)前日に移動します。(表示範囲を超えると自動的に前月に移動します。)
↓、2(テンキー)翌週の同曜日に移動します。(表示範囲を超えると自動的に翌月に移動します。)
↑、8(テンキー)前週の同曜日に移動します。(表示範囲を超えると自動的に前月に移動します。)
Home表示月の月初(1日)に移動します。
End表示月の月末(末日)に移動します。
PageDown翌月に移動します。
PageUp前月に移動します。
F12翌年同月に移動します。
F11前年同月に移動します。
Enter日付を決定してカレンダー入力フォームを閉じます。
Escキャンセルしてカレンダー入力フォームを閉じます。




「アドイン版」とは?
カレンダー入力機能として「初心者向けで実装しやすいもの」を目的としている手段で、実体は「マクロブック」です。 カレンダー入力の主機能をこの「マクロブック」に分けてブラックボックス化したものです。
アドインにすることでExcel上でウィンドウを持たず、開いているワークブックとして見えなくなることを利用しています。



本機能のアドインはExcelに常駐するタイプのアドインではありません。
カレンダー入力機能を利用するワークブック側に実装したマクロコード(VBAソースコード)の動作によってアドインが開かれて利用されます。 カレンダー入力機能を利用するワークブック側ではアドインを明示的に閉じる操作は行なわずにExcelの終了時に閉じられるようになります。
カレンダー入力機能の利用中はアドインに対する更新は発生しないので、閉じる段階での非保存警告は発生しません。
逆にアドインが既に開かれているExcel上で、このアドインを要求する別のワークブックを開く時には既に開かれているアドインが参照されるので、 開き直しがない分レスポンスの向上が見込めます。



Excelに常駐するタイプのアドインでは呼び出す側で全くマクロコードを書かずに動作するものもありますが、 業務で利用するワークブックで「日付入力」と決まったセルだけでカレンダーを表示させるとなるとマクロコードを書かない方法では実現できません。
アドイン化することにより、利用者側が実装する必要があるソースコードは大幅に少なくなるわけですが、それでも前頁と同様の機能が得られます。
カレンダー動作でのワークブック側とアドイン側の担当切り分けとしては、そのセルが日付入力セルかどうかの判定とカレンダー機能の呼び出しまではワークブック側で行ない、 それ以降のカレンダー表示から選択された日付をセルに格納するところはアドイン側の動作で行ないます。



「アドイン版」としての利点、欠点を前頁のようにワークブックに全て実装する方法と比較して説明します。

優劣 項目 内容
利点 必要VBA知識 カレンダーに関する主たる機能部分を全てアドインに収容してブラックボックス化し、利用ワークブックに対しては必要機能を「関数」として提供しているので、 アドイン呼び出しと「関数」利用部分についてサンプルを元に組み込んでいただくことで、簡単に機能するようにできると思います。
VBAの知識はある程度必要ですが、サンプルのソースコードもほとんどはそのままコピーするだけで良く、ワークシート関連での変更箇所はコピーのままで良いところと分けて明記してあります。
実装作業 カレンダーの呼び出し部分は呼び出し元のワークブック側に実装する必要がありますが、前頁のように全機能を実装するのではなく、 呼び出し部分のみなので実装のための作業が大幅に少なくて済みます。
カレンダー機能を実装したいワークブックが多数ある場合などは作業コストの軽減にも繋がります。
アドインの配置先 「主機能をアドイン化する」という時点で「ではアドインはどこに置くのか」という新たな選択肢が発生します。
提供サンプルのままだと、アドインは利用ワークブックと同じフォルダに配置することになりますが、 社内ネットワークが完備している環境であれば配置先(パス)を明示しての社内での一元化も可能です。
利用ワークブックからアドインが参照できない場合は、当サイトからWeb参照されるようになっています。
祝日情報の管理 上記と重複しますが、祝日法の改正などの対応についてもアドインが社内で一元化できていれば、 一元化された場所のアドインを最新に置き換える(上書きコピー)だけで対応できます。
バージョン更新 上記同様にこれらの機能改廃(不具合対応含む)についても 一元化された場所のアドインを最新に置き換える(上書きコピー)だけです。 社内に新旧のバージョンが混在するような状況も避けられます。
欠点 レスポンス 初回にカレンダー等の本機能を呼び出す時に裏でアドインファイルが開かれるため、この初回に限って若干動作レスポンスが悪くなります。 実際の動作レスポンスについては前頁のサンプルと比べてご確認下さい。



元々、アドイン化を対応から外していたのはこの動作レスポンスを考えてのことでしたが、現在の事務用の主力PCであれば初回のカレンダー起動で秒単位に待たされるようなことはありませんでした。
祝日パラメータ 前頁での説明は「祝日パラメータ」については利用者側で変更ができるとしていましたが、 今回のアドインについては内部非公開であり、かつ「祝日パラメータシート」を使わない方法としています。
これは多分に動作レスポンスを意識してのものですが、ソースコード非公開については「VBA初心者向け」での配慮でもあります。
対応範囲 前頁のものはワークシートの他、ユーザーフォームでの利用に対応していましたが、 アドインに関しては現在の実装上でワークシートの対応のみとしています。
ユーザーフォームで利用される方はそもそもVBAの知識もある程度お持ちであろうと考えますので、 前頁のサンプルでの方法をご検討下さい。
環境設定 アドインを配置するフォルダを「信頼できる場所」に登録するなどセキュリティ上の設定が必要になります。

VBA初心者向けということでこういった仕様にしています。

利用ワークブック側の実装要件を確認します。
ここまでの説明の通り、VBA初心者向けといっても全くコード記述せずにカレンダーが動作するわけではありません。
ソースコードの説明に入る前にカレンダーを呼び出す2つ「アクション」と「該当日付セルの選別」について説明します。



日付入力セルのダブルクリック
日付入力セルをダブルクリックする方法です。ダブルクリックするとカレンダーが表示されます。
Excelの通常ではただセル内に入力カーソルが現われる「セル入力モード」になるものですから、日付入力セル以外ではカレンダーが表示されてはなりません。



日付入力セル選択後にF4キーを押す
マウスを使わずに日付入力セルを選択後にF4キーを押すとカレンダーが表示されます。
F4キーとしたのはInternetExplorerに搭載されていた日付入力コントロール(DateTimePicker)で指定されていたキーを踏襲したものです。



日付入力セルの選別について
上記のようにカレンダーを表示させるトリガーは「ダブルクリック」と「F4キー」があるわけです。 マウス操作やキー入力などの利用者操作からVBAのソースコードで記述した動作につなげるところは「イベント」というプロシージャになりますが、 マウスの「ダブルクリック」はワークシート単位のイベント、「F4キー」はExcelアプリ全体のイベントなので記述箇所が異なります。 さらに同じワークブックの中でもワークシートごとに日付入力セルが異なることもあるでしょう。
そこでサンプルではシートごとに日付入力セルの配置が異なることを想定しています。
「カレンダーフォームの表示①」シートは全く個別にバラバラの配置になる場合です。
「カレンダーフォームの表示②」シートはB列とE列について列全体で日付入力になる場合です。
「カレンダーフォームの表示③」シート、「Sheet4」シートは日付入力セルが全くない場合です。



この後で実際のソースコードの説明に入りますが、必要なのはこういった「イベント」からアドイン側のカレンダー表示のプロシージャを呼び出すことと、 その際に日付入力セルかどうかで動作を選別することです。
※ただし、利用者が行列等を変更して日付入力セルがその都度変更されることへの対応はいたしません。

ソースコードの実装箇所とそのソースコードを説明します。
実際にカレンダーの動作をさせたいワークブックへ書き込む必要があるVBAのソースコードはほとんどがサンプルからの「コピペ」で完了するようにしてあるので、 「コピペ」を行なう箇所と必要な「書き換え」について説明します。

プロジェクトを表示させたところ

サンプルが開いている時にVisual Basic Editor(VBE)を開く(Alt+F11)と、左のプロジェクト(プロジェクトエクスプローラ)のウィンドウはこのように表示されると思います。 他のワークブックが開いていなければ「VBAProject」が2つでカッコ内は「AddinCalendar6R.xlam」と「Calendar6サンプル1.xlsm」です。



AddinCalendar6R.xlamはカレンダー表示機能を収容した「アドイン」です。
ワークブックと違い開いてもExcelのウィンドウにワークシート等が表示されません。 今回のカレンダー表示機能についての最初の要求がある時に開かれます。 非公開ということでパスワードロックしているため、プロジェクト内部のメンバは表示されません。



Calendar6サンプル1.xlsmがサンプルのワークブックです。
実際の動作を確認していただく意味では「サンプル」ですが、利用者が最終的に運用するためのワークブックにこの「カレンダー機能」を実装させる時に必要なソースコードの「ひな形」という役目もあります。



このようにワークブックから特定機能のアドインが開かれるのは、ワークブック側にアドインを開くためのソースコードが記述されているからです。 今回の「カレンダー機能」のようなケースでは一緒に開いている複数のワークブックが同じアドインを要求することもあるため、 アドインは既に開いていたら開いているアドインを利用し、同じアドインを再度開くことはないようになっています。



さて、この「Calendar6サンプル1.xlsm」のプロジェクトの内部に並んでいるのはこのプロジェクトのメンバです。 マクロを利用しないワークブックの場合は作成された各ワークシートとThisWorkbookだけで、それぞれにソースコードを書き込めるのですが何も書かれていない状態になります。
Calendar6サンプル1.xlsm」の場合はワークシートが4つとThisWorkbookの他、標準モジュールである「modAboutCalendar6」があり、 この6つのメンバのそれぞれにソースコードが書き込まれた状態になっています。
4つのワークシートは説明上では同じなので、実際には3種類のオブジェクトへのソースコードの書き込みについての説明になります。
別のワークブックへのソースコードの書き込みの場合は、両方のワークブックを開いておけばプロジェクトエクスプローラで縦に並んで表示されるので、コピー・ペーストの作業が楽に行なえます。
作業に先立って「Microsoft Scripting Runtime」の参照設定を追加しておいて下さい。(必須)

modAboutCalendar6 (標準モジュール)
標準モジュールの「modAboutCalendar6」については最初の段階では何も変更せずに利用開始できるので、そのままコピーして下さい。
標準モジュールについてはプロジェクトエクスプローラ上でコピー元、コピー先の両方のワークブックが開いている状態であればドラッグ&ドロップでコピーされます。 コピー先に標準モジュールを追加して、名前を「modAboutCalendar6」に変更し、中身のソースコードを全て選択してコピー・貼り付けでも構いません。

'***************************************************************************************************
'   カレンダーフォーム関連モジュール                        ※modAboutCalendar6(Module)
'
'   参照設定:Microsoft Scripting Runtime
'
'   作成者:井上治  URL:https://www.ne.jp/asahi/excel/inoue/ [Excelでお仕事!]
'***************************************************************************************************
'変更日付 Rev  変更履歴内容------------------------------------------------------------------------>
'23/01/22(2.00)新規作成(シート上でのキー入力に対するカレンダー表示機能追加の対応)
'***************************************************************************************************
Option Explicit
Option Private Module
'===================================================================================================
' カレンダー表示関連定数(公開)
'---------------------------------------------------------------------------------------------------
' カレンダーアドイン所在フォルダ名(ブランクの場合は本ブックのフォルダ)
Private Const g_cnsAddinPath As String = ""
' カレンダーフォームのタイトル
Private Const g_cnsCalCaption As String = "日付選択"
' カレンダーフォームの週開始曜日(1=日曜日、2=月曜日)
Private Const g_cnsStartYobi As Integer = 1                         ' 日曜日
'Private Const g_cnsStartYobi As Integer = 2                         ' 月曜日

'###################################################################################################
' ※ここから下は一切変更せずにご利用下さい。
'###################################################################################################
                                    ・
                                    ・
                                    ・

'----------------------------------------<< End of Source >>----------------------------------------
これが「modAboutCalendar6」の先頭部分です。 実際には260行程度ありますが、利用者が変更できる部分はこの定数3つだけです。
それぞれ初期値が入っているので、とりあえずこのままでも動作できます。
内容は以下の通りです。
定数内容
g_cnsAddinPath アドインの配置先フォルダのフルパスを指定する項目です。
このようにブランクとする場合は実行するワークブックと同じフォルダでアドインを開く動作になります。 この指定箇所にアドイン「AddinCalendar6R.xlam」が存在しない場合は、当サイトからWeb参照で開くように動作します。
アドインの配置先フォルダはExcelのトラストセンターで「信頼できる場所」に登録して下さい。
g_cnsCalCaption 実行時に表示されるカレンダーフォームのタイトルです。
g_cnsStartYobi 実行時に表示されるカレンダーフォームの開始曜日の指定です。 「2」に変更すると月曜日始まりになります。 「2」以外は全て日曜日始まりです。
「※ここから下は一切変更せずにご利用下さい。」より下にはこの他の定数・変数や実際にアドインとやりとりを行なう関数等が配置されていますが、 原則として利用者が変更を行なうものではないのでこの説明には記載していません。

Sheet1,Sheet2... (各ワークシートクラス)
各ワークシートに必要なのは日付入力を行なうセルをダブルクリックした時にカレンダーを表示させるイベントの記述で、これはワークシートごとの記述となります。 この際に「日付入力セルかどうか」の判定を行ないますが、これもワークシートごとに設定するようになっています。

'***************************************************************************************************
'   カレンダーフォーム表示テスト                                Sheet1(Class)
'
'   作成者:井上治  URL:https://www.ne.jp/asahi/excel/inoue/ [Excelでお仕事!]
'***************************************************************************************************
'変更日付 Rev  変更履歴内容------------------------------------------------------------------------>
'23/01/22(2.00)新規作成
'***************************************************************************************************
Option Explicit
'===================================================================================================
' シート上の日付セルアドレス
Private Const g_cnsDateCellAdress = "$A$1,$A$9,$D$13,$B$17,$G$18,$E$21,$C$25,$H$27:$I$28,$F$30"

'###################################################################################################
' ※ここから下は一切変更せずにご利用下さい。
'###################################################################################################
                                    ・
                                    ・
                                    ・

'----------------------------------------<< End of Source >>----------------------------------------
利用者に設定していただくのはこの「日付入力セルかどうか」の判定のための定数「g_cnsDateCellAdress」のみです。
これは「カレンダーフォームの表示①」シートの記述例です。「カレンダーフォームの表示②」シートのように列全体になると、

' シート上の日付セルアドレス
Private Const g_cnsDateCellAdress = "$B$2:$B$1048576,$E$2:$E$1048576"
というようになります。
カレンダーを表示させる必要がないワークシートについてはソースコードを何も記述しない状態で構いません。
「カレンダーフォームの表示③」のように定数「g_cnsDateCellAdress」の値をブランクにした場合もカレンダーは表示されません。
「カレンダーフォームの表示①」のように日付入力セルがシート上に不規則な配置でたくさん存在するような場合は、 「セル選択範囲の取得」を参考にして下さい。
「※ここから下は一切変更せずにご利用下さい。」より下は利用者が変更を行なうものではないのでこの説明には記載していません。

ThisWorkbook (ワークブッククラス)
ThisWorkbookはワークブック全体のイベントを記述します。 サンプルでは「ワークブックを開く」「ウィンドウを切り替える」のイベントを記述しています。

'***************************************************************************************************
'   カレンダーフォーム表示テスト                                ※ThisWorkbookイベント(Class)
'
'   作成者:井上治  URL:https://www.ne.jp/asahi/excel/inoue/ [Excelでお仕事!]
'***************************************************************************************************
'変更日付 Rev  変更履歴内容------------------------------------------------------------------------>
'23/01/22(2.00)新規作成
'***************************************************************************************************
Option Explicit

'***************************************************************************************************
'   ■■■ ワークブックイベント ■■■
'***************************************************************************************************
'* 処理名 :Workbook_Open
'* 機能  :開くイベント
'---------------------------------------------------------------------------------------------------
'* 返り値 :(なし)
'* 引数  :(既定)
'---------------------------------------------------------------------------------------------------
'* 作成日 :2023年01月22日
'* 作成者 :井上 治
'* 更新日 :2023年01月22日
'* 更新者 :井上 治
'* 機能説明:
'* 注意事項:
'***************************************************************************************************
Private Sub Workbook_Open()
    '-----------------------------------------------------------------------------------------------
    Dim dteHoliUpdate As Date                                       ' 祝日情報更新日
    Dim dteAddinUpdate As Date                                      ' アドイン更新日
    Dim strAddinVersion As String                                   ' アドインバージョン
    ' カレンダーバージョン取得
    Call modAboutCalendar6.GetCalendarVer(dteHoliUpdate, strAddinVersion, dteAddinUpdate)
    ' ※この記述は本サンプル限定⇒必須ではありません
    ' カレンダーフォームの表示シート
    With ThisWorkbook.Worksheets(1)
        .Select
        .Protect UserInterfaceOnly:=True
        .Cells(1, 7).Value = "祝日パラメータ更新日:" & Format(dteHoliUpdate, "yyyy/MM/dd")
        .Cells(2, 7).Value = "カレンダーモジュールVer:" & strAddinVersion & _
            "(" & Format(dteAddinUpdate, "yy/MM/dd") & ")"
    End With
    ' 保存済みにする
    ThisWorkbook.Saved = True
End Sub

'###################################################################################################
' ※ここから下は一切変更せずにご利用下さい。
'###################################################################################################
                                    ・
                                    ・
                                    ・

'----------------------------------------<< End of Source >>----------------------------------------
利用者が変更できるように割り当てているのは「Workbook_Open」のみです。
この下に「Workbook_WindowActivate」「Workbook_WindowDeactivate」があり、 「F4キーを押したら特定プロシージャを起動」「F4キー起動プロシージャを解除」を行なっていますが、これらは変更の必要はありません。 削除してしまうとF4キーでのカレンダー表示が行なわれなくなります。
サンプルの「Workbook_Open」はアドイン側のバージョン情報を取得してワークシートに表示させる記述のみです。 バージョン情報の取得が必要なければ「Workbook_Open」自体が必要なくなり、F4キーも不要であれば ThisWorkbookの記述は全て不要ということになります。
但し「Workbook_Open」でバージョン情報取得を行なうと、この時点でアドインが開かれるので、これ以降のカレンダー表示の時点でアドインを開く動作はなくなり、 見かけのレスポンス悪化を避けることができます。 レスポンス重視であればバージョン情報が不要であってもバージョン情報取得だけは行なって、その後のバージョン情報利用の記述は削除して下さい。
「※ここから下は一切変更せずにご利用下さい。」より下は利用者が変更を行なうものではないのでこの説明には記載していません。



アドインを明示的に閉じるという操作(コード記述)はありません。
利用するワークブックを閉じてもExcelが終了するまでは開いたままとなりますが、 読み取り専用であり別のワークブックでアドインを利用する場合は再度アドインを開くのではなく以前から開いているアドインが参照されます。 本機能のアドインが複数同時に開かれることもありません。

動作確認
カレンダー機能を利用するワークブックに上記のソースコードの書き込みが完了したら、まず「コンパイル」で構文エラーがないかチェックして下さい。 この段階でエラーが出る場合はここまでで説明した内容が正しく実装されていません。
コピーのし忘れ、記述誤りや参照設定のし忘れなどがあるはずです。再度確認して下さい。



「コンパイル」でのエラーがなければ動作確認に入ることができるので、作業中のワークブックを保存した上で開き直して所望の動作になるかを確認して下さい。 解決できないようであれば、ページの一番下に問合せの案内があります。

いかがでしょうか
「これなら簡単に実装できそうだ」というようなご理解が得られれば幸いです。
ぜひ、下記よりダウンロードさせてお試し下さい。

ダウンロードはこちら。
←ExcelCalendar6.zip
      (199KB)

Vectorからも「カレンダー入力フォーム(Calendar6:アドイン版)でダウンロードできます。