ダウンロードとコピペで使えるExcelVBAのカレンダーコントロール
セルをダブルクリックしたらカレンダーコントロールが開いて、日付をクリックすると最初のセルに入力される、というマクロです。難しいところはわからなくてもいいから、かんたんシンプルにサクッと使える方向性を目指しました。
はじめに
当ブログでは2014年に「イチから自作」コンセプトでExcelのカレンダーコントロールを作りましたが(当時の記事)、その後、書籍へ掲載したり改良を重ねて、ここで紹介しているのはバージョンアップしているものです。
なお、がんばってマクロでやるより、きぬあささんのアドインも超便利です! こちらもぜひどうぞ!
動画版もあります
今回の記事は動画でも解説してます。テキストよりそっちのほうが好きという方はこちらからどうぞ!
ダウンロード
こちらからzipファイルをダウンロードして、展開してください。環境の制限によってダウンロードできない方は、こちらを参考に自作することも可能です。
DLの前にお読みください
Windows10/11、Microsoft365のExcelで動作確認を行っています。ご利用の際はOfficeを最新バージョンへアップデートしてください。OSやOfficeのバージョンが古い場合、一部動作しない可能性があります。
また、コードには細心の注意を払っておりますが、無保証のコントロールとさせていただいています。いかなる理由により損害等が発生しても一切責任を負いかねますので、あらかじめご了承のうえご利用ください。
更新履歴
- ターゲットが結合セルだった場合の日付を読めないバグに対応(2022/11/4)
ダブルクリックしたセルの近くにカレンダーが表示されるように改良(2022/11/14)- カレンダーの表示位置をデフォルト(画面中央)へ戻しました(2022/12/5)
※変更により、動画で映っている画面と異なる部分があります。
以下の3つのファイルが入っています。
- F_CalenderForm.frm
- F_CalenderForm.frx
- M_CalendarSetting.bas
インポート
VBEのプロジェクトエクスプローラー内の「VBAProject」を右クリックして「ファイルのインポート」を選択し、「F_Calendar.frm」と「M_CalendarSetting.bas」をそれぞれ読み込みます。
プロジェクトエクスプローラーがこのようになっていれば、フォームモジュール「F_Calendar」と標準モジュール「M_CalendarSetting」が正しく読み込まれています。
シートモジュールを開く
「カレンダー」フォームを利用したいシートモジュールを選びます。ダブルクリックで開きます。
シートモジュールにコピペするコード
該当のシートモジュールに以下をコピペします。
Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean) Call setCalendarDateForCell(Target) End Sub
これで、コードを書いたシートのいずれかのセルをダブルクリックすると「カレンダー」フォームが起動し、クリックした日付が対象セルに挿入されます。右上のスピンボタンで、左側が-1月、右側が+1月へ遷移します。
(2024/3/20追記)デフォルトでは、カレンダーから日付が挿入された直後は、セルが「編集モード(セルの中にカーソルが入っている状態)」になります。これは、セルをダブルクリックした操作によるものです。以下の1文を入れると、編集モードを回避できます。お好みでどうぞ。
Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean) Cancel = True Call setCalendarDateForCell(Target) End Sub
カレンダー起動の範囲を指定するときは、Call setCalendarDateForCell
の直前の行にCancel = True
を入れてください。
カスタマイズ
特定のセルだけ
そのままだと全セル動いてしまうので、特定のセルだけカレンダーを起動したい場合は、以下のコードに差し替えます。「”$A$1″」の部分を好きなセルに書き換えてください。「”」と「$」は必要です。
Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean) If Target.Address <> "$A$1" Then Exit Sub 'A1セル以外なら終了 Call setCalendarDateForCell(Target) End Sub
結合セルは以下の形で書きます。「”$A$1:$B$2″」部分はすべて大文字・半角英数字です。
Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean) If Target.Address <> "$A$1:$B$2" Then Exit Sub 'A1:B2の結合セル以外なら終了 Call setCalendarDateForCell(Target) End Sub
(2023/7/15追記)コメント欄で教えていただきました! 結合セルで上のコードでうまくいかない場合、こちらでも試してみてください。
Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean) If Intersect(Target, Range("A1:B2")) Is Nothing Then Exit Sub 'A1:B2の結合セル以外なら終了 Call setCalendarDateForCell(Target) End Sub
特定セルを複数にする
カレンダーを起動したいセルを複数セルで指定したい場合は、以下のコードに差し替えます。好きなセルに書き換えてください。増やす場合は「,」で区切ります。
Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean) If Intersect(Target, Range("A1, B2, C3")) Is Nothing Then Exit Sub '指定セル以外なら終了 Call setCalendarDateForCell(Target) End Sub
以下のようにセルは単一でも範囲でも大丈夫です。
Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean) If Intersect(Target, Range("A1, B2:C3, D4:E5")) Is Nothing Then Exit Sub '指定セル以外なら終了 Call setCalendarDateForCell(Target) End Sub
特定の列/行だけ
特定の列だけカレンダーを起動したい場合は、以下のように書きます。A列なら1、B列なら2、という具合に数値で指定します。
Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean) If Target.Column <> 4 Then Exit Sub '4列目(D列)以外なら終了 Call setCalendarDateForCell(Target) End Sub
特定の行だけカレンダーを起動したい場合は、以下のように書きます。数値で指定します。
Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean) If Target.Row <> 2 Then Exit Sub '2行目以外なら終了 Call setCalendarDateForCell(Target) End Sub
A~C列のとき、のように書く場合は以下です。行にする場合はTarget.Column
をTarget.Row
に変更してください。
Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean) If 1 <= Target.Column And Target.Column <= 3 Then 'A~C列のとき Call setCalendarDateForCell(Target) End If End Sub
AまたはCまたはE列のとき、のように書く場合は以下です。行にする場合はTarget.Column
をTarget.Row
に変更してください。
Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean) If Target.Column = 1 Or Target.Column = 3 Or Target.Column = 5 Then 'AまたはCまたはE列のとき Call setCalendarDateForCell(Target) End If End Sub
表示できる年数を変更する
カレンダー上の年数を変更したい場合は、VBEでF_Calendarを右クリックして、「コードの表示」を選択します。
「UserForm_Initialize」プロシージャの、図でハイライトしてある -3 To 3 の部分をお好きな数値に変更してください。±5年とかにしてもいいですし、前後で違う数でも大丈夫です。
For i = 0 To 5 にすると、以下のような表示になります。
以上です! 選択肢の1つとして、こんな方法もあるんだ~と思っていただけたら嬉しいです。
追記1: 祝日対応
リクエストをいただいたので作ってみました。こちらのwebAPI(Holidays JP API (日本の祝日API))をお借りしており、永続的ではないこと、トラブルなどに対して無保証であることをご了承ください。
こちらのカスタマイズではインターネット環境が必須です。年を切り替える際にその年の祝日を取得するため、PCスペックやネット回線速度などによって読み込みに時間がかかる場合があります。ご自身の環境にて実用に耐えうるかご判断ください。
以下、実装方法です。最新版をDLしてインポートしてからはじめてください。
フォームモジュール「F_Calendar」を右クリックして、「コードの表示」を選択してください。一番上のOption Explicit
の次に以下のハイライト部分を追加してください。
'# 「カレンダー」フォーム Option Explicit Private holidayList As String '祝日リスト格納用
続いて、同じ「F_Calendar」モジュール内の「cmb_year_Change」プロシージャへ、ハイライト部分を追加してください。
Private Sub cmb_year_Change() '## 年が変更された時 'その年の祝日の取得 Holidays JP API (日本の祝日API) https://holidays-jp.github.io/ をお借りしています Dim httpReq As Object Set httpReq = CreateObject("MSXML2.XMLHTTP") 'HTTPリクエスト用オブジェクト作成 httpReq.Open "GET", "https://holidays-jp.github.io/api/v1/" & Me.cmb_year.Value & "/date.json" httpReq.send '送信 Do While httpReq.readyState < 4 '待機 DoEvents Loop holidayList = httpReq.ResponseText Set httpReq = Nothing Call setCalendar End Sub
続いて、同じ「F_Calendar」モジュール内の「setCalendar」プロシージャへ、ハイライト部分を追加してください。
Private Sub setCalendar() '## カレンダーの作成と表示 '略 For i = 1 To 37 'ラベルの初期化 With Me("lbl_day" & i) .Caption = "" 'キャプション .BorderStyle = fmBorderStyleNone '枠なし .BackColor = Me.BackColor 'フォームと同じ背景色へ Select Case i Mod 7 Case 1 .ForeColor = vbRed '日曜は文字色を赤 Case 0 .ForeColor = vbBlue '土曜は文字色を青 Case Else .ForeColor = vbBlack 'その他(平日)は文字色を黒 End Select End With Next '略 Dim tgtDay As Date '日付生成用変数 For i = 1 To endDay '1日から月末日まで tgtDay = yy & "/" & mm & "/" & i '該当日付生成 With Me("lbl_day" & n + i) '該当のラベルに対して .Caption = i '日を入れる If tgtDay = Date Then '今日なら .BorderStyle = fmBorderStyleSingle '枠を付ける End If If tgtDay = g_cldCurrentDate Then 'TextBoxの日と同じなら .BackColor = RGB(200, 200, 200) '背景色を付ける End If If InStr(holidayList, Format(tgtDay, "yyyy-mm-dd")) <> 0 Then '祝日リストに含まれていたら .ForeColor = vbRed '文字色を赤 End If End With Next i End Sub
以上で祝日が赤くなります。
追記2: ユーザーフォームのテキストボックスで使う
リクエストをいただきましたので、ユーザーフォームへのカスタマイズ方法を紹介した動画を作りました。
テキストボックス用にコピペするコード
標準モジュール「M_CalendarSetting」をダブルクリックして開き、一番下の空いている部分に下記をコピペします。
Public Sub setCalendarDateForTextBox(ByVal tgtTxb As MSForms.TextBox) '## カレンダーで選択した日付をテキストボックスに入力する If IsDate(tgtTxb.Value) = False Then '日付が入ってなければ g_cldCurrentDate = Date '今日の日付を格納 Else g_cldCurrentDate = tgtTxb.Value 'テキストボックスの日付を格納 End If F_Calendar.Show 'カレンダーを開く If g_isCldCancel = True Then Exit Sub 'キャンセル(バツボタンで閉じられた)なら終了 tgtTxb.Value = g_cldPickedDate 'クリックされた日付を上書き End Sub
その後、任意のユーザーフォーム上に作成したコマンドボタンのクリックイベントから、上に書いたプロシージャをCall setCalendarDateForTextBox(引数)
のように呼び出します。引数にはカレンダーの日付を入力したいテキストボックスを設定してください。動画のほうで詳しく説明しています。
追記3: 年を和暦にする
カレンダーの「〇〇」年の部分を、「2023」→「令和5」のような和暦表示にするカスタマイズです。「F_Calendar」モジュール内のコードです。
「UserForm_Initialize」プロシージャの以下のハイライト部分を書き換えます。
Private Sub UserForm_Initialize() '## フォーム読込時 Dim i As Long '汎用変数 g_isCldCancel = False 'キャンセルフラグをFalseにしておく For i = -3 To 3 '前後3年分の年をリストに追加 Me.cmb_year.AddItem Format(DateAdd("yyyy", i, g_cldCurrentDate), "ggge") Next i For i = 1 To 12 '月をリストに追加 Me.cmb_month.AddItem i Next i Me.cmb_year.Value = Format(g_cldCurrentDate, "ggge") '年を指定 Me.cmb_month.Value = Month(g_cldCurrentDate) '月を指定 End Sub
「setCalendar」プロシージャの以下のハイライト部分を書き換えます。
Private Sub setCalendar() '## カレンダーの作成と表示 Dim i As Long '汎用変数 If Me.cmb_year.Value = "" Or Me.cmb_month.Value = "" Then Exit Sub '年か月どちらか入ってなければ中止 Dim yy As String '年取得 yy = Me.cmb_year.Value Dim mm As Long '月取得 mm = Me.cmb_month.Value '略 Dim n As Long '月はじめの位置用変数 n = Weekday(yy & "年" & mm & "月" & "1日") - 1 'その月の1日の曜日番号に、-1したもの Dim endDay As Long '月末日用変数 endDay = Day(DateAdd("d", -1, DateAdd("m", 1, yy & "年" & mm & "月" & "1日"))) '算出 '略 End Sub
「spn_monthUpDown_SpinUp」プロシージャの以下のハイライト部分を書き換えます。
Private Sub spn_monthUpDown_SpinUp() '## スピンボタンのアップクリック時 On Error GoTo ErrHandler 'エラー時に「ErrHandler」行へジャンプする宣言 If Me.cmb_month.Value = 12 Then '12月だったら Me.cmb_year.Value = Format(DateAdd("yyyy", 1, Me.cmb_year.Value & "/1/1"), "ggge") '年を+1 Me.cmb_month.Value = 1 '1月へ Else Me.cmb_month.Value = Me.cmb_month.Value + 1 '月を+1 End If '略 End Sub
「spn_monthUpDown_SpinDown」プロシージャの以下のハイライト部分を書き換えます。
Private Sub spn_monthUpDown_SpinUp() '## スピンボタンのダウンクリック時 On Error GoTo ErrHandler 'エラー時に「ErrHandler」行へジャンプする宣言 If Me.cmb_month.Value = 1 Then '1月だったら Me.cmb_year.Value = Format(DateAdd("yyyy", -1, Me.cmb_year.Value & "/1/1"), "ggge") '年を-1 Me.cmb_month.Value = 12 '12月へ Else Me.cmb_month.Value = Me.cmb_month.Value - 1 '月を-1 End If '略 End Sub
「putTgtDate」プロシージャの以下のハイライト部分を書き換えます。
Private Sub putTgtDate(ByVal i As Long) '## グローバル変数に取得した日付をセットする If Me("lbl_day" & i).Caption = "" Then Exit Sub 'ラベルが空だったら中止 g_cldPickedDate = Me.cmb_year.Value & "年" & Me.cmb_month.Value & "月" & Me("lbl_day" & i).Caption & "日" '日付を生成して変数に格納 Unload Me 'カレンダーを閉じる End Sub
追記1の祝日対応をしている場合は、「cmb_year_Change」プロシージャの以下のハイライト部分を書き換えます。
Private Sub cmb_year_Change() '## 年が変更された時 'その年の祝日の取得 Holidays JP API (日本の祝日API) https://holidays-jp.github.io/ をお借りしています Dim httpReq As Object Set httpReq = CreateObject("MSXML2.XMLHTTP") 'HTTPリクエスト用オブジェクト作成 httpReq.Open "GET", "https://holidays-jp.github.io/api/v1/" & Year(Me.cmb_year.Value & "/1/1") & "/date.json" httpReq.send '送信 Do While httpReq.readyState < 4 '待機 DoEvents Loop holidayList = httpReq.ResponseText Set httpReq = Nothing Call setCalendar End Sub
以上でカレンダーの表示は和暦になりますが、セルの表示は別です。該当のセルに対して「セルの書式設定」で「分類」を「日付」、「カレンダーの種類」を「和暦」にするなど、お好みのものへ変更してください。
追記4: イベントを一括制御する
リクエストをいただいたので別記事で書きました。このカレンダーの日付部分、37個のラベルのイベントプロシージャをクラスモジュールを使って省コード化する方法です。
ExcelVBAに興味をお持ちの方は、こちらの記事もどうぞ!
- これからExcelのマクロを始めたいという方に!簡単な練習問題作りました。
- 私がExcelVBAでよく使う便利なコード・スニペットまとめ
- プログラム初心者さんへ贈る、エラーが起きたら試してみて欲しいこと
- ExcelVBAのクラスモジュールって何?という人向けの使い方まとめ
書籍を執筆しています。
87件のコメント
カレンダー起動時の日付を今日ではなく、excelの表の中で一番最後の日を基準にするにはどうしたら良いですか?
コメントありがとうございます。表を指定のセル範囲と仮定して、セル範囲内の日付で一番大きいものを起動時の初期値にする方法を考えてみました。
インポートした標準モジュール「M_CalendarSetting」内の「setCalendarDateForCell」プロシージャへハイライト部分を追加し、8行目のセル範囲を任意のものに変更してみてください。
失礼します。ありがたく使用させていただこうとしている者なのですが、
結合したセルをターゲットにしたい場合はどうすればいいですか?
コメントありがとうございます。結合セルで試したところ、入力済みの日付を認識できない問題がありましたので、修正して更新いたしました。再度ダウンロードしてお試しください。自分では結合セルで使ったことがなかったので思わぬバグを発見させていただき、ありがとうございました。
調べて調べて調べまくってこちらに辿り着くことができました。
とても素晴らしいものを与えてくださりありがとうございます。
以下対応方法などお分かりでしたら教えてもらうことはできますか?
・祝日の反映は可能なのか。
・テーブル機能に使おうとしていて、最初のセルには反映できるのですが、追加行のセルへの対応がわかりません。
コメント&暖かいお言葉を、ありがとうございます。
祝日対応ですが、外部APIを利用すれば不可能ではなさそうです。私も興味があるので作ってみようかと思いますので、少々お時間をください。ただ、外部サービスを利用するので永続的ではないこと、トラブルなどに対して無保証であることをご了承ください。
> テーブル機能に使おうとしていて、最初のセルには反映できるのですが、追加行のセルへの対応がわかりません
こちらの件は、テーブルに対して行列の挿入を行って試してみたのですが、現象の再現ができませんでした。再現できないことには対処ができず、申し訳ありません。
お返事ありがとうございます。
需要がありそうな際のご対応で大丈夫ですので、何卒ご無理なさらずにお願い致します。
最後に一つ、紹介されている列指定について複数の列はどのように指定したらいいのでしょうか?
例えば、A列、C列、E列に指定したいなどの時です。もしくはA列~C列に指定などの時です。
お忙しいところ恐縮ですが是非ご回答頂ければ幸いです。
祝日対応、本文に追記しましたので見てみてくださいね。
列指定は、例では1つの条件を扱ったので、「If Target.Column <> ○ Then Exit Sub(○以外なら終了)」という書き方をしていますが、複数条件だと以下のような書き方のほうがわかりやすいかと思います。
お返事が遅くなってしまってすみません。
2点とも対応してくださりありがとうございます。
とても参考になり、助かります!
ご返信ありがとうございます。お役に立てて光栄です!
ターゲットのセルが結合セルだった場合に対応(2022/11/4)となっておりますが、結合セルで反応しません。
対処方法を教えてください。
コメントありがとうございます。Windows10/11、Microsoft365のExcelで動作することを確認しております。OSやOfficeのバージョンが古い場合、一部動作しない可能性があります。Microsoft365をお使いの場合、Officeを最新バージョンへアップデートしてください。また、新規ブック状態から試して、拡張子は.xlsではなく.xlsmで動くかどうかお試しください。(既存ブックだと先に組み込まれている環境が動作に影響する場合があります。)
ダブルクリックした際のコントロールの表示位置が、だんだん下がってしまい30行以降になるとフレームアウトしてしまします。
コントロール表示がフレームアウトすると、EXCELがフリーズしてしまいます。
コントロール表示位置の調整は可能でしょうか??
コメントありがとうございます。2022/11/14の更新でダブルクリックしたセルの近くに表示されるようにしたのですが、画面やウィンドウの大きさによって動作が不安定であることがわかりました。デフォルト位置(画面中央表示)へ戻しましたので、お手数ですが最新版をDLし直してお試しください。
当方トリプルモニターで作業しているのですが、複数のセルに指定していまして、ダブルクリックした時にカレンダーの表示がすごい離れたところに表示されてしまいます。入力セルが横にずれればずれる程、隣の画面にカレンダーが現れ、更に隣の画面へと遠くなっていき、隠れてしまったら消すこともできずに強制終了するしかできませんでした。
何か表示を指定のセルに近くする対処法はありますか?
先程質問したものです。
もう一度こちらの操作方法の通常通りでやってみたらちゃんとできていました。
何かそのファイルの中で他の改修をした際におかしくなってしまったようです。
差し支えなければ、セルの近くに置く場合はどこをいじるのか教えて頂きますとこちらでやってみようかと思います。
まとめてのお返事で失礼いたします。上の方の回答と同じく、以前の更新でセルの近くを判定するコードを入れたものが、画面やウィンドウの大きさによって動作が安定しなかったのが原因のようです。デフォルト位置(画面中央表示)へ戻しましたので、お手数ですが最新版をDLし直してお試しください。
何とかこちらに辿り着くことができました。
大変ありがたいサイトです。
当方でも試してみました。
他の方のご意見にもあります通り、結合セルでは反応しません。
単一セルの場合のみ反映します。
併せてPC環境を変えて試してみましたが、いずれも反応しておりません。
こちらで試した環境は、
・Windows 10 Enterprise + Microsoft 365 Apps for enterprise
・Windows 10 Professional + Microsoft Office Standard 2016
またワークシートは既存のファイルを使用して、このサイトからダウンロードしたカレンダーモジュールを反映させております。
当方にVisual Basicの知見がないため、ご面倒をお掛け致しますが、対処法をご教授いただけますと幸いです。
よろしくお願い致します。
あたたかいお言葉、ありがとうございます! 結合セルの件、以前コメントをいただいてからできる限り環境を変えて試しているのですが、どうしても「結合セルで反応しない」現象に巡り逢うことができずにおります、すみません…。しかしながら、複数の方からのご報告があるので少なくない現象なのではと思っております。一応のご確認ですが、新規ブックで試しても反応しない、ということでよろしいでしょうか?(既存ブックだと先に組み込まれている環境が影響する場合があるため)
現状だと手詰まり状態でして、もしもよろしかったらメールで詳細をお聞かせ願えませんでしょうか? お問い合わせのメールフォームからご連絡をいただけますと幸いです。よろしくお願いいたします。
素晴らしいソフトを公開していただきありがとうございます。
娘に依頼されて、EXCEL VBAでデータの入力・検索・修正・削除・印刷ができるコードを書いております。
任意のセルへのカレンダー入力はできましたが、ユーザーフォームからの入力において、テキストボックスへのカレンダー入力コードがわからず、ネットで探してはみたのですが、なかなか見つかりません。
お暇な時で結構ですので、ご指導いただけると幸甚です。
余談ですが、娘は現在産休でじかに帰ってきております。わたくしは70歳を過ぎましたが、ボケ防止にACCESSで簡単なソフトを作っておりましたが、EXCEL VBAを知り、その素晴らしさにはまりました。
嬉しいお言葉、ありがとうございます。ExcelもAccessも楽しいですよね! その楽しみの一助になれて光栄です。元気な娘さん&お孫さんにお会いできること、お祈りしております。
実は元々ユーザーフォームとテキストボックスで使うために作ったカレンダーだったのですが、セルのほうが汎用的かなと変更したので、需要をいただけて嬉しいです。ここからのカスタマイズだと工程が多いので、せっかくなのでYouTubeのほうで続きの動画として作らせていただこうかと思います。少々お待ちくださいませ。(追記:動画作成しました!)
お世話になります。
とてもいいものをありがとうございます。仕事が捗ります。
結合セルで使えない現象ですが、A1:A2の結合セルで使いたいときに、特定のセルででご紹介されていたコードのセル指定部分を$A$1のまま使っていると発生しました。私は初心者なので試行錯誤してどうにか$A$1:$A$2に書き換えて使用することができました。他の失敗談としては$a$1のように小文字だとできなかったです。
私以外の初心者の助けになればと思います。
他にはドロップダウンリストで日付を選択できるセルと併用して使いたいと思ったのですが、そのシートに保護をかけるとカレンダーが起動できませんでした。
以上、windows10のexcel2010の報告でした。
【「特定セルの条件をつけているときに」結合セルが反応しない】ということだったんですね!!? 本当にありがとうございます、条件をつけない状態で試していたのでまったく再現ができずに途方に暮れていました。。おっしゃるとおり、単一セルは「$A$1」の形ですが、結合セルは「$A$1:$A$2」の形で取得されるので、結合セル用の条件を書かないと起動しません。取り急ぎ、本文にも追記させていただきます。これでほかの方も解決すると良いのですが……。
多くの動作と掛け合わせると競合が起きてしまう可能性は十分にありますので、組み合わせてダメだったら、相性が悪かったんだなと思っていただけますとありがたいです。色々試していただいて、さらに暖かいお言葉&情報をご提供くださって本当にありがとうございます。
YouTubeから辿り着きました。
デフォルトで搭載してほしいくらい、デザインも機能もすべて気に入ってます!
一点お聞きしたいのですが、以下のような使い方は出来るのでしょうか…?
1. ユーザーフォーム上のコマンドボタンをクリックすると、このカレンダーコントロールが表示される
↓
2. 日付をクリックすると、ユーザーフォーム上に設置してあるテキストボックスに日付が入る
1については、シートモジュールにコピペするコード「Call setCalendarDateForCell(Target)」を、コマンドボタンクリック時のPrivate Sub内に貼り付ければ良さそう(?)ですが、2のやり方が分からず、、、
VBA歴が短いので、基本的なことでしたらすみません。ご助言いただけますと幸いです。
ご視聴&コメントありがとうございます、気に入っていただけて嬉しいです! ユーザーフォームでもお使いいただけます。同じご要望をいただいておりまして、続きの動画を作っているところなので、できたら本文に追記いたしますね。少々お待ちくださいませ。(追記:動画作成しました!)
動画拝見しました〜!
まさに求めていたものそのものでした!
声も大変聞きやすく、チャプターや字幕なども便利で分かりやすく、すぐ高評価つけちゃいました!
今後も楽しみにしております!
ご覧いただき、ありがとうございます! 動画はまだ始めたばかりで「こんな感じでいいのかな…?」と不安に思いながらやっているので、そう言っていただけてとっても嬉しいです!
先日コメントした者です。
新情報のご提供ありがとうございます。
私の方でも結合セルの対応を試してみました。
結合セルの場合は、結合しているセルの範囲を指定することで解決することが確認できました。
また試した環境は以下です。
・Windows 10 Enterprise + Microsoft 365 Apps for enterprise
・Windows 10 Professional + Microsoft Office Standard 2016
・Windows 10 Professional + Microsoft Office Professional Plus 2021
この度は大変お世話になりました。
ありがとうございました。
フィードバックありがとうございます! 解決して安心しました~!!
活用させていただいてます!
フォーム起動時に年数が1899年の12月となってしまい、更に12月の12の部分が選択された状態で起動してしまうのですが、何が原因なのでしょうか?
コメントありがとうございます。おそらく、なんらかの原因で数値の0をシリアル値と判定しているものと思われます。該当のブックで、セルにゼロが入っていて表示形式が日付、のような設定になっていないかご確認ください。オプションの詳細設定で「ゼロ値のセルにゼロを表示する」のチェックが外れていると、0が入っていても表示されません。
また、月のコンボボックスが選択されているのは仕様です。操作可能な「年」「月」コンボボックス、または月移動のスピンボタンのどれかにフォーカスがあたって起動するので、便宜上「月」にしています。コンボボックスのフォーカスは文字が反転して嫌な場合は、VBEのオブジェクト表示でスピンボタンの「TabIndex」プロパティを「0」にすると、起動時のフォーカスをスピンボタンにできます。
初めましてOhideと申します。
まだVBAを始めて2ヶ月の者ですが、カレンダーからの日付選択がしたくこちらのサイトに辿り着きました。
動画は解りやすい解説で大変有難う御座います。
それで質問なのですが、CalendarSetup_221205.zipをVBAにインポートし祝日対応(ネット接続版?)は
カレンダーに反映するのですが、ネット接続せず休日シート版でやりたく思い後日のブログでupされています
プログラムを入れたのですが途中で停止してしまいます。
DLしましたプロシージャと、”前回書いてるはず”のプロシージャの内容が違う為?か上手くいきません。
助言をいただけますでしょうか。 よろしくお願いします。
はじめまして、コメントありがとうございます。オフラインの休日シート版というのは、大昔に書いたこの記事(2014/8/7公開)のことですね。これは、その前の記事(2014/8/4公開)で紹介しているコードに追記する前提で書いています。過去のものは「カレンダーをフォームからすべて自作してみよう」というコンセプトで書いたのですが、その後だいぶ経ってから「難しいところはわからなくてもいいから、かんたんシンプルにサクッと使える」方向性で2022年に書き直したのが、このページです。そのため、過去のものとコードが異なっています。
オンラインAPI版があれば休日シート版は需要ないかなと思って書かなかったのですが、掘り起こしてチャレンジしていただいてありがとうございます。シート構造は当時の記事の通り作っていただいて、このページからDLできるバージョンへの対応コードを下に書いておきます。「F_Calendar」モジュール内の「setCalendar」プロシージャへ、ハイライト部分を追加してください。
なお、当時の記事にもあるように「休」なら赤、「出」なら黒にしたい場合は上の47~49行目を以下のようにしてください。
こんばんはOhideです。
*yukoさん過去のプログラムなのに、迅速な対応誠にありがとうございます。
上記のプログラムで無事!いけました!!
有難く使わせて頂きます。
また勉強させて頂きますので宜しくお願い致します。
フィードバックありがとうございます! ちゃんと動いてよかったです~!!
こんにちは。Windows10へとver.が変更になり、DateAndTimePickerが使えなくなり、困り果ててこちらへたどり着きました。
とても詳しく説明されているので利用させていただきました。
ご説明の通りにコピーさせていただき、カレンダー表示したいエクセルのセルをダブルクリックしました。
「コンパイルエラー:プロジェクトまたはライブラリーがみつかりません」表示され、
「M_CalendarSetting」
Public Sub setCalendarDateForCell(ByVal tgtRange As Range) ←黄色く表示
‘## カレンダーで選択した日付をテキストボックスに入力する
If IsDate(tgtRange.Cells(1.1).Value) = False Then ‘日付が入ってなければ
g_cldCurrentDate = Date ‘今日の日付を格納 ← Date が青く表示
VBを最近勉強しはじめたばかりで何がたりないのかわかりません。
初級の初級とおもわれますがご説明いただけますでしょうか。
よろしくお願いいたします。
コメントありがとうございます。おそらく個々のPC環境によるものと推測され、同様のエラーを再現することができないためお力になれず申し訳ありません。ただ、エラー箇所と内容から関数のライブラリ参照がうまくいっていないのかな? という印象を受けました。参考になりそうなリンクを貼っておきますので、お試しください。
丁寧な回答ありがとうございます。
参考に頂いた内容を検証してみましたがうまくできませんでした。
やはり、PC環境がうまくできていないよう気がします。
Windows10の再インストールをしなおしてみます。
ありがとうございました。
フィードバックありがとうございます。OSのほか、Officeの修復や再インストールも効果があるかもしれません。また、新規ブックで動くのであれば、既存ブックに組み込まれている環境との相性の問題も考えられます(すでにお試しでしたらすみません)。解決できることをお祈りしております!
素敵なプログラムを公開頂きありがとうございます。
和暦表示にするにはどこを変更したら良いか教えていただけますでしょうか。
(「ExcelVBAでカレンダーコントロールを自作する」の記事も拝見しましたが分からず恐縮です)
コメントありがとうございます。こちらも昔の記事にあったものですね。ちょっと修正箇所が多かったので、本文のほうに追記しましたのでご覧ください。
早々のご対応頂き感謝申し上げます。
今後の業務に活かさせて頂きたく存じます。
フィードバックありがとうございます! お役にたてて光栄です~!
素晴らしいツールを公開していただきありがとうございます。
カレンダーから日付を選択できるようになって業務の効率化に大変役立ってます。
1点教えて頂きたいのですが、カレンダーの下部に今日の日付を入力できるようなボタンを追加するにはどのようにしたら出来ますでしょうか?ご教授をお願いいたします。
嬉しいお言葉、ありがとうございます。現在は、セルが空だった場合は今日の日付に枠が付きますが、それとは別に今日の日付専用のボタンがほしいということでしょうか? 今日ではない年月が表示されているときでも今日の日付を入れたいという意図ですかね? 今日の日付専用ボタンもできますが、別の年月が表示されているときに今月へ移動するボタン、ではどうでしょうか?
回答有難うございます。
よく考えればカレンダーとは別にボタンを追加して今日の日付を入力するマクロを設定するだけでした。お騒がせしました。
フィードバックありがとうございます。自己解決がいちばん勉強になると思ってるので、答えが出て嬉しいです!
質問させていただきます。
初心者です。
ダブルクリックではなく、シングルクリックでカレンダーを表示させるには
どうしたらよいでしょうか?
☆☆動画も拝見しました。
なかなかピンと来るものが見当たらず困っていたのですが、
こちらを見つけた時は「コレコレ!」と思わず声が出てしまいました!
まさに求めていたものでした!
わかりやすくて初心者の私にも上手くできて感激しました。
ありがとうございます!
コメント&嬉しいお言葉ありがとうございます。
「シートモジュールにコピペするコード」の最初の行に書いてある「Worksheet_BeforeDoubleClick」は、「ワークシートをダブルクリックしたとき」を意味しているのですが、利用できるイベントはあらかじめ決まっていて、「Worksheet_BeforeSingleClick」というものはありません。代わりとするならば「Worksheet_SelectionChange(選択セルが変更されたとき)」が考えられます。以下のように書きます。
ただしこのイベントはシングルクリックで選択したときはもちろん、キーボード操作でセルを移動したときもその都度実行されてしまうのでご承知ください。「特定のセルだけカレンダーを起動」するカスタマイズを加えたほうがよいと思います。
分かりやすい解説・動画で勉強させていただきありがとうございます。
質問させていただきたいのですが,カレンダーからテキストボックスに日付を入力した際にテキストボックス内の表示も和暦にするにはどうしたらいいのでしょうか?
また、日付の後に曜日を追加することも出来るのでしょうか?
大変恐縮ですが,御指導のほどよろしくお願いします。
コメントありがとうございます。「テキストボックス用にコピペするコード」として、「M_CalendarSetting」モジュールに追加した「setCalendarDateForTextBox」プロシージャのハイライト部分を以下のようにしてみてください。
なお、曜日も表示したい場合は以下のようにしてください。
和暦+曜日だと文字数が多くなるのでテキストボックスの横幅は広めにしたほうが良さそうです。お試しください。
素早い対応と回答ありがとうございました!
テキストボックス内の表示も曜日も無事にいけました!
しっかりと業務に活用させていただきます!
ちゃんと動いてよかったです~! フィードバックありがとうございました!!
こんにちは、カレンダーコントロールを探していて辿り着きました。
年の表示を「yyyy(ggge)」に変更して使っています。
とても有用なコードを提供して頂き感謝します。
別件ですが、
結合セルを認識しない件については
Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean)
If Target.Address “$A$1:$B$2” Then Exit Sub ‘A1:B2の結合セル以外なら終了
Call setCalendarDateForCell(Target)
End Sub
ではなく
Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean)
If Intersect(Target, Range(”A1:B2”)) Is Nothing Then Exit Sub ‘A1:B2の結合セル以外なら終了
Call setCalendarDateForCell(Target)
End Sub
で行えないでしょうか
Target.Addressはうまく拾えない事がある様な記事を見た事があって私はIntersectを使用しています。
記事があれば良いのですが失念しており見つけられなかったです。
ご参考までに
コメント&情報ありがとうございます。こんな方法もあるのですね! たいへん勉強になりました。ありがたく本文にも追記させていただきます。
素晴らしいプログラムを公開して頂きありがとうございます。
当方初心者でございます。
上記のやり方で、インポートさせて頂いたのですが、やり方がよくないのか
年を選択するコンボボックスが1896年から1902年しか選択できないようになってしまいます。
お忙しいところ申し訳ございませんが、教えて頂きたく思います。
コメントありがとうございます。おそらく、なんらかの原因で数値の0をシリアル値と判定しているものと思われます。該当のブックで、セルに0が入っていて表示形式が日付、のような設定になっていないかご確認ください。オプションの詳細設定で「ゼロ値のセルにゼロを表示する」のチェックが外れていると、0が入っていても表示されません。
こんにちは
このようなサイトを作成していただきありがとうございます。
質問なんですが、インターネットを接続できない職場環境で、外部からのダウンロードしたものを職場のパソコンに入れることができないのでダウンロードが利用出来なくて困っています。
今回のようなカレンダーを手入力で入れて行きたいのですがインポートするデータのマクロを見せて頂けると助かります。
コメントありがとうございます! DLするF_Calendar.frmとM_CalendarSetting.basはメモ帳などテキストアプリで開いていただければコードが閲覧できます。
追記:Excelのカレンダーコントロールをダウンロードできない方向けの自作マニュアルを書きました。そちらで閲覧いただけます。
こんにちは、
この度エクセルで日付入力ミスを解消したいと思いこちらのカレンダーアプリを利用させて頂くことになりました。
特定の列だけで動くコードについてですが
例えば「C列4行目からC列任意の行まで」
または「C列4行目からC列最終行まで」で動かしたいのですがコードを教えていただけませんでしょうか。
昨日、今村様の書籍「ExcelVBAユーザーフォーム&コントロール」を取り寄せ購入してきたのですが、こちらについての記載を見つけることが出来ませんでした。
VBA初心者ですが何卒ご対応の程よろしくお願いします。
コメントありがとうございます。「C列4行目からC列任意の行まで」は以下で、
「C列4行目からC列最終行まで」は以下のように書きます。
また、「ExcelVBA ユーザーフォーム&コントロール 実践アプリ作成ガイド」に収録されているカレンダーコントロールはフォームを使ったアプリ内での利用方法を記載しているので、今回のようなご要望には添えずに申し訳ありません。フォームを扱えるとExcelの利用幅が広がりますので、せっかくなので、ぜひご活用くださいね。
早々のご対応ありがとうございます♪
仰る通り、フォームを扱える様になるとかなり業務改善になるので書籍とYouTubeを参考に勉強してみます。
今後も機会がありましたら、ご指導宜しくお願い致します。
フィードバックありがとうございます! ぜひぜひ、がんばってみてください~!
こんばんは
一番 最近のコメントを送られた方に似ているのですが
複数の範囲指定の場合 どのように指定すればいいのでしょうか?
例えば
「C列4行目からC列10行と E列4行目からE列10行」
VBA初心者なので 参考にさせてもらってます
よろしくお願いします。
こんにちは、コメントありがとうございます。範囲が多いと条件が長くなるので、以下のように2つに分けちゃうと良いと思います!
早急のご対応ありがとうございます。
「ary = Array(“$C$4”, “$C$5”, “$C$6”, “$C$7”, “$C$8”, “$C$9”,...」と
気の遠くなる 打込みをしてたので助かりました。
電子版ですが書籍の方も買わせて頂きました。
参考にしたいと思います。
ありがとうございました。
フィードバックありがとうございます、確かに気が遠くなりますね…! あの後さらに考えてみたら、下記のコードのほうが断然スマートにできることに気づいたのでお試しください。本文も直しておきました。書籍のほうもありがとうございます! 嬉しいです!
探し求めていたものがここにありました!ありがとうございました!
大変恐縮なのですが、質問がございます。
結合されている別々のセルをダブルクリックした時、用途の違う別々のカレンダーを表示したいのですが、色々試してみたののできませんでした。
なにか方法はございますでしょうか?
あと私はユーザーフォームの表示場所を下記で指定してみました。
Private Sub UserForm_Initialize()
‘## フォーム読込時
StartUpPosition = 0
Top = 200
Left = 500
‘ユーザーフォームの表示場所指定
コメントありがとうございます。「用途の違う」という部分を、具体的にどのようにしたいのか詳しくお聞かせ願えたらと思います。別デザイン(?)のカレンダーを用意して、「Aセルから起動したらAデザインのカレンダー、Bセルから起動したらBデザインのカレンダー」のようなことでしょうか?
お返事いただきありがとうございます。
例えば、A1のセルをダブルクリックすると ±3年のカレンダーを表示(来客時)
B1のセルをダブルクリックすると 現在から-100年のカレンダーを表示(誕生日)
のようなものですが・・・
宜しくお願い致します
なかなかおもしろい使い方ですね。F_CalenarモジュールのUserForm_Initializeプロシージャを、以下のハイライト部分のように書き換えていただけると良いのではないかと思います。A1セルなら±3年、B1セルなら-100年~今年、それ以外だったらデフォルトとして±5年という例で書いてあります。
-100年~今年と固定すると、あらかじめ入っていた日付がその範囲外にあったときにエラーになってしまうので、そのあたりのエラー処理を12~15行に入れてあります。お試しください。
ご返信ありがとうございます。
とても助かります、色々と自身でも勉強して応用していきたいと思います!
時間を割いていただき本当にありがとうございました。
お役に立てて光栄です! いろいろカスタマイズしてみてくださいね。
大変使いやすく、自分のイメージにぴったりのカレンダーです。提供して頂き心から感謝しております。
下記教えて頂きたいことがあります。
日付を文字列で出力させることは可能でしょうか?
例えば、2024/02/20 → ’2024ー02ー20 です。
コメント&嬉しいお言葉、ありがとうございます。表示だけで良ければセルの書式設定から変更できますが、頭にシングルクォーテーションを付けた文字列出力ということですよね。M_CalendarSettingモジュールのsetCalendarDateForCellプロシージャの以下のハイライト部分を変更してみてください。
余談ですが、出力で「’」を付けちゃったら呼び出すときに「’」を外さないと日付として認識できないかと思ったら、そのまま動きますね。VBAはこういうところけっこう融通が利いて楽ですね。
お忙しい中、早々にご対応頂き有難うございました。
私の願っていた通りの動きになり感激しております。私は今業務効率化でエクセルのデータ資産をSQLiteに移行出来ないか試行錯誤しているところです。
日付の表示形式をどうしても文字列で取得したかったので、コードを色々弄ってみましたが旨く行かず、ご教示お願いいたしました。コードの変更も大変勉強になりました。
これで、また一歩前に進む事が出来ます。
本当に有難うございました。
フィードバックありがとうございます、私もデータベース使うので、そっち方面のご要望かなと思ってました! 一助になれて光栄です。がんばってくださいね!
すごく参考になりました。ありがとうございます。
一つ質問なのですが、フォームから特定セルに日付を入力できるようになったのですが、それが日付と認識されてないのか、別セルの関数が反応しません。また、表示形式もm/dに変更したいのですがマクロから変更されません。
マクロ初心者でわからないことが多いので変なことを言ってるかもしれません。教えていただけると助かります。
コメントありがとうございます。マクロは年月日が正しく特定できる日付データをセルに渡すのが目的で、渡されたデータを日付と扱うか、どんな表示形式にするのかは、セルの書式設定に依存します。そちらの設定をお確かめください。
1点もしやと思ったのは、このカレンダーはセルのダブルクリックで起動する性質上、日付挿入後にセルが編集状態になります。セルが編集中だと、そこを参照しているほかのセルが正常に表示されない場合もあるかもしれません。シートモジュールに書くプロシージャに以下の1文を追記すると、編集状態にならずに日付挿入できるようになるので、試してみてください。本文にも追記しておきました。
本当にわかりやすくて、ものすごく助かりました!
本当にありがとうございます
こちらこそ、とっても嬉しいコメント、ありがとうございます。励みになります!
エクセルVBAの超初心者ですが、カレンダーをいれるところまでできました。ありがとうございました。
質問させてください。
シートのセルB2にカレンダーで「○月○日」と表記できるようになったのですが、
もう一つ別のセルC1に、「○月○日の週間予定」というセルがほしいです。
B2にカレンダーで日付を入力すると、C1も自動でB2と同じ日付で「○月○日の週間予定」という風に
かわってほしいのですが、何か方法はございますでしょうか。
コメントありがとうございます。
C1セルに
=MONTH(B2)&"月"&DAY(B2)&"日の週間予定"
と入力してみてはいかがでしょうか?なんと!できました!ありがとうございました。
フィードバックありがとうございます。ご期待に添えたみたいで良かったです~!
カレンダー機能を探してこの記事に辿り着きました。
Zipファイルをダウンロードしてフォームと標準モジュールはインポートできたのですが、
起動したいシートに起動用のコードをコピペしてもカレンダーが出てきません。
(セルがアクティブになるだけで通常のダブルクリックの動作になってしまいます…)
皆さんできているようなのでおそらく当方が悪いような気がしますが、
他のマクロは問題なく起動するので謎が深まるばかりです。
差し支えなければ解決方法をご教示いただけると幸いです。
コメントありがとうございます。シートモジュールにコピペするコードは「イベントプロシージャ」という種類で、「シートがダブルクリックされた」動作をきっかけに自動で実行される特徴を持ちます。通常のダブルクリックの動作になるということは、コードが「イベントプロシージャ」と認識されていないのだと思います。
コピペされているのであれば記述ミスなどはないと思いますが、コピペの経由途中でなんらかの変換が挟まってしまい、余計なスペースが挿入されたり、スペースが全角に変換されたり、変なところで改行されたり、といった現象はないでしょうか?
また、正しい位置に正しい記述で入力されていても、入力直後は一時的にイベントプロシージャだと認識されないことが稀にあります。その場合はいったんExcelを保存、終了して起動しなおしたり、PCを再起動することで認識されることがあります。
コメントは承認制ですので、反映までしばらくお待ち下さい。(稀にスパムの誤判定にて届かないこともあるようですので、必要な際はお問い合わせからお願い致します。)
YouTubeでQ&Aコンテンツを企画しています
運営しているYouTubeチャンネルで、ご相談やご質問を募集しています。動画のコメントやお問い合わせページからお気軽にご相談をお寄せください。