通常のエクセルファイル(.xlsx)ファイルに対して、マクロを使用した入力支援を行いたい場合の体系について記述していきたいと思います。
例として、カレンダーを表示させるマクロを通常のエクセルファイル(.xlsx)上に表示させようと思います。
一つ目は、ショートカットキーを利用する方法になります。このページでは、ショートカットキーを利用する方法について記述していきます。
進捗を管理する報告書にはよく日付を入力することがあると思います。
通常のエクセルファイル(.xlsx)ファイルに対して、マクロを動作させる方法の一つに、ショートカットキー割り当てがあります。
まずは、マクロの入っているエクセルファイル(.xlsm)を開きます。このファイルには、カレンダーを表示させるマクロが組まれています。
上の記事で、カレンダーに祝日対応を追加したため、こちらの記事のダウンロードにも、祝日対応版を追加しています。祝日対応版のダウンロード
表示させるカレンダー
ショートカットキーの左側(B7セル)では、「Ctrl」又は「Alt」を選択可能です。
ショートカットキーの初期設定を行った後に、「ショートカットキー割り当て」ボタンをクリックします。
2024/05/13 追記:このマクロ有効ブックを閉じるとショートカットキー割り当ても解除されるため、意図して閉じないように、「ショートカットキー割り当て」ボタン押下後のファイルの非表示制御は削除しました。
通常エクセルファイル(.xlsx)を開き、日付を入力したいセルを選択します。登録したショートカットキーを押すと、マクロが動作し、カレンダーが表示されます。
エクセルで呼び出すユーザフォームは、呼び出したエクセルにつながります。
複数ブックでカレンダーを呼び出そうとすると、前にカレンダーを呼び出していたエクセルが前面にでてしまい新しくカレンダーを使用したいブックの裏に隠れてしまう問題がありました。
その対処を行いました。
起動されるエクセルブックの変更を検出したら、カレンダーを再起動します。前に表示していた年月は維持させています。ブック切り替え時は、再起動のため、表示に多少時間がかかります。
'*******************************************************
' ショートカットキー割り当て
'
'*******************************************************
Sub キー割り当て_Click()
'別ブックから呼び出すことを考慮して、動作させるマクロのモジュール名に
'ファイル名を指定する
Call setShortCutKey(Range("B7").Text, Range("C7").Text, _
ThisWorkbook.Name & "!" & "calender_show")
End Sub
上記で呼び出しているsetShortCutKey()は、標準モジュールに記載しています。
第1引数は、ショートカットキー左側("Ctrl"又は"Alt")、第2引数は、ショートカットキー右側(英字一文字)を登録しているセルから取得しています。
第3引数の ThisWorkbook.Name & "!" & "calender_show" でこのブックの標準モジュールを登録しています。ショートカットキーに登録できるのは、標準モジュール関数に限ります。(フォームを直接呼び出せません)
同一関数名が存在しない限り、標準モジュール名のcalender_showのみでも問題ありません。念のため、明示的にファイル名を指定しました。
ショートカットキーに登録する標準モジュールの関数。表示させたいフォームのオブジェクト名をCalenderFormとしています。
Showメソッドの引数 vbModeless は、表示中にエクセルを操作することを許可する命令です。
'************************************************
' 標準モジュールからCalenderFormを表示
'************************************************
Public Sub calender_show()
'カレンダーフォームの呼び出し
CalenderForm.Show vbModeless
End Sub
ショートカットキー割り当てのメインコード。
'*****************************************************************************
' ショートカットキー割り当て
' first_key : "Ctrl","Alt" のどちらか
' second_key : 英字一文字
' macro : 実行マクロ
'*****************************************************************************
Function setShortCutKey(first_key As String, second_key As String, macro As Variant)
Dim find_error As Boolean
'エラーなしで初期化
find_error = False
If StrComp(first_key, "Ctrl", vbTextCompare) = 0 Then
'1つ目のキーが"Ctrl"の場合
first_key = "^"
ElseIf StrComp(first_key, "Alt", vbTextCompare) = 0 Then
'1つ目のキーが"Alt"の場合
first_key = "%"
Else
'1つ目のキーが"Ctrl"でも"Alt"でもない場合
'エラーありを設定
find_error = True
End If
If find_error = False And Not second_key = "" And Len(second_key) = 1 _
And second_key Like "[a-z]" And second_key = StrConv(second_key, vbNarrow) Then
'1つ目のキーにエラーなし、かつ、2つ目のキーが空白ではない かつ 1文字である
' かつ a - zの間である、かつ、半角である
On Error Resume Next
'エラー発生時、警告画面を表示しない
'ショートカットキー割り当て
Application.OnKey first_key & second_key, macro
Else
'エラーありを設定
find_error = True
End If
'OnKeyからのエラーなし かつ 文字チェックエラーなし
If Err.Number = 0 And find_error = False Then
'このブックの表示を非表示にする
'ショートカットキーで呼び出される度に、
'このブックが上に表示されてしまうため
Windows(ThisWorkbook.Name).Visible = False
Else
MsgBox "そのショートカットキーは無効です"
End If
End Function
エクセルアプリが閉じられるときに、非表示となっているためブックは閉じる前に保存するコードを追加しています。また、ブック起動時にブックが非表示になっている場合があるため、初期設定値として表示を有効にしています。閉じる直前の処理(BeforeClose)で表示を有効にすると、ブックが閉じなくなります。明示的にThisWorkbook.Closeを呼ぶことで閉じることも可能でしたが、再起処理のようで嫌だったので、Open側で表示を変更しています。
'****************************************************
' 閉じる直前の処理
'****************************************************
Private Sub Workbook_BeforeClose(Cancel As Boolean)
On Error Resume Next
'保存する
ThisWorkbook.Save
End Sub
'****************************************************
' 起動時
'****************************************************
Private Sub Workbook_Open()
'ブック非表示を表示に変更
Windows(ThisWorkbook.Name).Visible = True
End Sub
CalenderFormオブジェクトへ追加します。また、SetMonthDateモジュールの宣言についていた、「Private」を削除してください。
Private Sub UserForm_Activate()
'カレンダーを表示させるエクセルブックの付け替え判定
DispFront
End Sub
'以下からPrivateの削除
'Function Private SetMonthDate(disp_year As Integer, disp_month As Integer)
Function SetMonthDate(disp_year As Integer, disp_month As Integer)
標準モジュールの「ShowCalender」に下記を追加します。「グローバル変数宣言」は、ページの一番上に記述します。
'グローバル変数宣言
Public DispBookname As String
Public t_year As Integer
Public t_month As Integer
'************************************************
' カレンダーを表示されるブックの変更対応
'************************************************
Function DispFront()
'新しいブック名保存用
Dim NewDispName As String
Dim wb As Workbook '2024/05/13 バグ対応
If DispBookname = "" Then
'初回なら、起動エクセル名を登録
DispBookname = ActiveWorkbook.Name
Else
If StrComp(DispBookname, ActiveWorkbook.Name, vbTextCompare) = 0 Then
Else
'一致しないなら、カレンダーを呼び出すエクセルブックが変更された
'表示済みの年月を保存
t_year = Year(CalenderForm.disp_day)
t_month = Month(CalenderForm.disp_day)
NewDispName = ActiveWorkbook.Name
'2024/05/13 バグ対応↓
'前に起動したエクセルブックが開いている状態なら最小化
Application.ScreenUpdating = True
For Each wb In Workbooks
If wb.Name = DispBookname Then
Workbooks(DispBookname).Activate
ActiveWindow.WindowState = xlMinimized
Exit For
End If
Next
'2024/05/13 バグ対応↑
Workbooks(DispBookname).Activate
ActiveWindow.WindowState = xlMinimized
'新しいブックをActiveにしたい
Workbooks(NewDispName).Activate
'カレンダー起動エクセル変更のため終了する
Unload CalenderForm
'カレンダー接続ブック名をグローバル変数に保存
DispBookname = NewDispName
'カレンダーの再起動
calender_show
Call CalenderForm.SetMonthDate(t_year, t_month)
End If
End If
End Function
ユーザフォームのActiveイベント時にActiveWorkbookが変更されているか確認をします。
起動エクセルとActiveWorkbookが異なる場合、カレンダーをUnloadし、再起動しています。
前回表示されていた年と月の情報も再設定しています。
WorkbooksオブジェクトのActivateだけでは、新しくカレンダーを起動したいブックが裏に隠れてしまったので、前にカレンダーを起動したエクセルブックを明示的に最小化指示を出しています。これで回避できました。
追加対応を含みます。
ダウンロードしたエクセルファイルを起動し、コンテンツの有効化を行う。
マクロの有効化手順については、こちらも参考にしてください。
カレンダーのショートカットキー割り当てマクロファイル(xlsm)のダウンロード
追加対応を含みます。
ダウンロードしたエクセルファイルを起動し、コンテンツの有効化を行う。
マクロの有効化手順については、こちらも参考にしてください。
祝日対応カレンダーを含むカレンダーのショートカットキー割り当てマクロファイル(xlsm)のダウンロード
カレンダーを表示するマクロを含むファイルを毎回開くのを面倒に感じる場合は、マクロをアドインとして登録するとマクロを含むエクセルファイルが自動的に裏で開かれます。(表面上、ユーザにはエクセルファイルとして表示されません。Visual Basic編集画面には、表示されます)。
但し、初期設定画面を出すことができないため、何のキーを割り当てるのかをマクロの中に固定で組み込む必要があります。
Workbook_Open時の処理の中で、ショートカットキー割り当て関数(キー固定)で呼び出すことで、アドイン向けになります。
マクロ有効ファイルを名前をつけて保存する画面で、エクセルアドイン(.xlam)を選択すると、保存すべきフォルダが開かれるため、指定されたフォルダにそのまま保存します。
エクセルの開発タブにある「Excelアドイン」にてチェックをつけることで、常にマクロが有効になります。