現在の日付・時刻を取得

関数によりシステム年月日と時分秒を取得するコード

'システム年月日を取得
Debug.Print Date
'システム時分秒を取得
Debug.Print Time
'システム年月日時分秒を取得
Debug.Print Now

PCのシステム日付および時刻データを取得するには、それぞれの必要な範囲で関数が複数あります

年月日だけの取得には「Date」時分秒だけの取得には「Time」年月日時分秒の全てを取得するのが「Now」です
全て関数で戻り値を取得しますが、引数がないため「()」は使用しません
入力しても消えます

ExcelVBAで主に使用するのはDateで、ワークシート関数でいうところのToday関数と同じ役割です
ユーザーフォームの日付入力ボックスに初期値として、本日日付を取得させたり
処理の実行を日付限定で行う際の判断基準となったりします

「Format」関数と組み合わせることで、和暦の表示も可能です
(和暦の取得方法はこちらの記事へ)

時分秒に関しては、操作履歴を記入する際に添付したり
新しいブックの保存名に使用することで、確実にかぶらないブック名にしたりすることもできます

秒まで取得できるので、ユーザーフォームに秒がリアルタイムで更新されて表示されるデジタル時計を作ってみたくなります
実際作りました、「DoEvents」関数と「Wait」メソッドを併用してCPUに負荷をかけずに無限ループさせてみました

問題なく時計になりましたが、やはりVBAは無限ループによる並行処理が苦手です
システム作成上、かならずどこかで無理がたたります

結果、やっぱり思ったのはデジタル時計って自己満足でしかありませんでした
だってPCに時計あるしね、普通に
時間もそこから取得してるので、別に高精度の時計になるわけでもなかった
でもやりたなるよね~、デジタル時計って

Excelのメッセージを抑止

Excelのメッセージを表示させるかの設定であるDisplayAlertsの切り替えコード

'メッセージを抑止する
Application.DisplayAlerts = False
'メッセージの抑止を解除する
Application.DisplayAlerts = True

Excelからのメッセージを抑止するには「DisplayAlerts」に「False」を設定します

Excelからのメッセージとは、シートの削除確認であったり未保存時の保存確認などのメッセージ表示です

これらは通常は必要なメッセージですが、VBAの処理中に表示されるとそのメッセージが表示されている間処理が停止してしまいます
なので、それらの操作をVBAで実行する際にはこのプロパティで抑止しておく必要があります

メッセージを抑止していますが、ちゃんと内部的には応答はおこなっています
この応答に関してはExcelが自動的に判断して行っていますので、もしその判断で困る場合は都度対処していく必要はありますが、ほとんどは無視する前提を考慮した判断なので困ることは無いと思います

例えば、シート削除に関しては削除が実行できているのでOKの応答をしています
保存確認では、保存が実行されずに閉じるので保存しない(NO)の応答をしています

メッセージは必要なものです、使用後は必ず抑止を解除しておきましょう
例の2つのコードはセットで使用しましょう

ブックが変更されたか調べる

ブックがなんらかの変更を加えられているかを判定するSavedプロパティについて

'ブックが変更されたかを調べる
Debug.Print ActiveWorkbook.Saved

ブックのデータが変更されて未保存かを調べるには「Saved」を使用します

基本的には保存されているかを調べるプロパティですが、戻り値で変更されているかを判定することができます

「True」であれば変更はされていません
「False」であればなんらかの変更が加えられています

ただ、セルを編集状態にしただけでも変更とみなされるようになるので処理中以外ではあまり使用することは無いかもしれません

また、ブックを閉じる記事でもあるようにこのプロパティに「True」を設定すると変更が加えられていても、保存確認メッセージを表示せずにブックを閉じることができます

ブックを閉じる・保存せずに閉じる

ブックを保存してから閉じる、保存せずに閉じるのコードと保存済みにする設定のコード

'アクティブブックを保存して閉じる
ActiveWorkbook.Close True
'アクティブブックを保存せずに閉じる
ActiveWorkbook.Close False
'アクティブブックを保存済みにする
ActiveWorkbook.Saved = True

ブックを閉じるには「Close」を使用します
×ボタンで終了を行う操作と同じ動きをします

引数の指定で保存を実行するかどうかを指定できます
「True」を指定すれば、上書き保存を実行して閉じます
「False」を指定すれば、保存せずに閉じます

データの入力などを行っておけば上書き保存を実行して閉じるし、参照するだけで関数の自動計算などの更新はせずに閉じるときは未保存で閉じます

「False」を指定して、このコードを実行すると保存の状態に関わらずブックは閉じられます

もう一つの方法として保存状態を変更する方法があります
リファレンスではこちらの使用が紹介されています

保存状態の変更は「Saved」を使用します
このプロパティを「True」にすると保存済みの状態になります
なので、この状態でブックを閉じれば保存確認は行われません
引数を指定せずに、「ActiveWorkbook.Close」だけで閉じることができます

そもそも「DisplayAlerts」プロパティにより、メッセージを表示させない設定も可能ですが、プロパティの設定などで対応できるものはそちらで対応したほうが予期せぬ動きには対処しやすいとおもいます

ブックの上書き・名前を付けて保存

処理を実行したブックや新規作成したブックを上書きやマクロ有効・無効の標準ブックとして保存するコード

'アクティブブックを上書き保存する
ActiveWorkbook.Save
'アクティブブックを名前を付けてマクロ有効ブックで保存する(同じ場所)
ActiveWorkbook.SaveAs ThisWorkbook.Path & "\Book2", xlOpenXMLWorkbookMacroEnabled
'アクティブブックを名前を付けて標準形式保存する(同じ場所)
ActiveWorkbook.SaveAs ThisWorkbook.Path & "\Book2", xlOpenXMLWorkbook

ブックを上書き保存するには「Save」を使用します

上書き保存するメソッドですが、未保存の新規作成ブックに実行した場合は現在の名称で、Excelの現在のフォルダに保存されます
Excelの通常操作のように、名前を付けて保存の画面が開かれるわけでは無い点に注意してください

現在のフォルダとは、Excelがその時点で参照中のフォルダで作業フォルダやカレントフォルダともいいます
この現在のフォルダは事前の操作によって変化するので注意が必要です

名前を付けて保存をするには「SaveAs」を使用し、引数にはパス名を含めたファイル名までを指定します
マクロの記録では、拡張子まで含めて指定されますがブックの種類を指定すると自動的に付与されるので必要はありません

2つ目のコードでは、このマクロのあるファイルと同じ場所にマクロ有効ブックとして保存しています
「ThisWorkbook.Path」は、このプロシージャがあるファイルが保存されたフォルダ名までのパスです
なのでこれにフォルダ内を表す「\」を結合してファイル名を入力します

ちなみに、画面で「\」はどう表示されているでしょうか?
実はこれは文字の読み込みで表示が変化します
(この記事内にある解説を確認してください)

「Path」プロパティではフォルダ名までなので、このフォルダ内記号を入力後に、ブック名を含めて指定します

引数の2つ目では、ブックの種類を指定することが出来ます
「~~, xlOpenXMLWorkbookMacroEnabled
種類がどんどん増えていってますが、使用するのはそれほど多くは無いと思います

3つ目の例コードでは標準形式が指定されています
これはマクロを含まない形式なるので、マクロが存在する場合はマクロが消失する旨のメッセージが表示されます

これを継続実行する事でマクロが全て削除されたブックが完成します
この動きを利用して、あえてマクロを削除することでセキュリティに関する対応をいちいち行わなくて済むブックを作成することもできます

また、パス名を省略してファイル名のみで保存することはできますがその際は上記にもあるExcelの現在のフォルダが対象となります

そのフォルダを変更するコードはありますが、そんなコードを実行するぐらいならパス名を指定するほうがいいです


関連の記事

新規ブックの作成

空白のブックを新規作成するコード

'ブックを新規作成する
Workbooks.Add

ブックを新規作成するには「Workbooks.Add」を使用します

このコードを実行すると、Excelでの操作でファイルタブから新規の空白ブックの作成と同じ動作をします

またこの作成時に自動的に「Book連番」という形式で名称がつけられます
引数には新規作成するブックの初期シートを指定でき、指定した場合はシート名に連番が付いたものがブック名になります
あまり引数で指定して作成することはないと思いますので、省略した例の形でいいです

この新規作成は、Excelの設定された初期値が適用されますので変更している場合は注意してください
特にワークシートの初期枚数に処理時は注意が必要です

またこの新規作成ブックを扱う際には、ブック名での指定だとすこし不便になりますので、基本的にはオブジェクト変数に代入して扱うようにしてください

ブック・シート・セルを変数で扱う

ブック・シート・セルの各オブジェクトを変数に代入するコード

'アクティブブックをオブジェクト変数に代入
Dim ブック As Workbook: Set ブック = ActiveWorkbook

'オブジェクトを開放
Set ブック = Nothing
'アクティブシートをオブジェクト変数に代入
Dim シート As Worksheet: Set シート = ActiveSheet

'オブジェクトを開放
Set シート = Nothing
'アクティブセルをオブジェクト変数に代入
Dim セル As Range: Set セル = ActiveCell

'オブジェクトを開放
Set セル = Nothing

オブジェクト変数にそれぞれの代入と処理後に使用する解放のコードです

この処理では、アクティブなものを代入する形になっているので処理中の動的なオブジェクトへの対応が可能になります

また、オブジェクトは変数の型がそれぞれちゃんとあり
それらを使用することで、インテリセンス入力が出来るようになるので代入オブジェクトの型が確定している場合は型宣言もしっかり行います

オブジェクト変数のインテリセンス入力候補の表示された状態
インテリセンス入力ができる

「ブック.」と入力すれば使用可能なメソッドとプロパティが表示されます
他のシートとセルも同じです

一応、全てのオブジェクトはobject型に代入することは可能です

ブックやシートの代入は、主には新規作成した物をを代入することが多いかもしれません

ブックの新規作成を行うと、そのブックがアクティブブックになるのでこのコードを使用して、新規作成ブックを簡単に操作することが可能になります
シートの新規作成も同じ使い方になります

セルの代入は別ブック・シートのセルを代入させることが多いです
別ブックやシートのセルはその上位のオブジェクト名から指定する必要があるので変数を使用しない場合、コードが非常に長くなってしまい可読性が低下します

セルもシートも同じですが、アクティブを代入するだけで上位のオブジェクトも含めて代入されるので、ブック間を移動する処理であれば非常に便利で分かり易くなります

こんな感じのものが実際に代入されています
コード 「Set セル = ActiveCell
実際 「Set セル = ActiveWorkbook.ActiveSheet.ActiveCell

この例文の「セル」の2文字だけで済むのがいかに簡潔になっているかが分かると思います(使用時は分かり易い変数名に変更してください)

最後に変数の解放はしっかり行ってください
上記にあるように、「ブック」という変数にはブックの情報すべてが変数に代入されています
シート情報もその中のセル全ての情報が入っているわけです
これをメモリ上に保持しているわけですから、もう使用しないのに保持しておくことはメモリを無駄に消費している、ということがなんとなくイメージできると思います

なので、1つだけなら処理速度に影響ないし、とは考えずに解放は行ってください

ブックを選択する

ブックを選択する方法の解説とそのコード使用時の注意点について

'起動したブックを選択
Workbooks("Book1.xlsx").Activate
'新規作成したブックを選択
Workbooks("Book2").Activate
'コードのあるブックを選択
ThisWorkbook.Activate
'開いているブックのインデックス番号で選択
Workbooks(2).Activate

ブックを選択するには「Activate」を使用します

ブックの選択方法の違いによる動き
コードの動き、下にちょっとExcelのタイトル

この際にブック名を拡張子まで含めて指定することで、特定のブックを選択できます

例コードの1つ目と2つ目で拡張子を含むか含まないかの違いがあります
これが新規作成ブックの注意点です

ブックの新規作成時は、ファイルの拡張子が決まっていません
そのため、新規ブックに関しては拡張子を含めないファイル名で指定を行います

「Workbooks(“Book1.xlsx“)」標準形式で保存済み
「Workbooks(“Book2“)」未保存

ブックの指定時に名前が間違っていた時のエラー表示
保存済みのブックを拡張子を指定しなかった場合

そして、当然ですが処理の途中でBook2を保存した場合、以降は拡張子を含めないと画像の様にエラーになってしまいます
こういった観点からも、新規作成したブックに処理を継続する場合はオブジェクト変数に代入して処理をしたほうが確実にブックを特定できます

3つ目の例コードでは相対的な選択方法になります
実行中のプロシージャのブックを選ぶには「ThisWorkbook.Activate」を使用します

「ThisWorkbook」というのが、実行中処理の親ブックとなります
上記のブック名指定よりも確実かつ可読性が高いので、自分のブックを使用する場合はこのオブジェクトを使用します

また、オブジェクト変数に入れるのが面倒な場合はインデックス番号で指定する方法もいいと思います
これは起動した順番になっているので、処理のあるブック以外を閉じる処理を入れるか、処理開始時点のブック数を取得しておき新規作成を行えば新規作成されたブックのインデックス番号が特定できます

このインデックス番号で処理を行えば名前が変わっても、保存して拡張子が付いても問題なく処理が行えるようになります

3択のメッセージを表示

MsgBox関数で最大の3択の対話型条件分岐を行うコード

'「中止・再試行・無視」ボタンで分岐
Select Case MsgBox(Prompt:="データ欠損!(無視で強制起動)", Buttons:=vbAbortRetryIgnore)
Case vbAbort
'中止をクリックしたときの処理
Case vbRetry
'再試行をクリックしたときの処理
Case Else
'それ以外(無視)をクリックしたときの処理
End Select
'「はい・いいえ・キャンセル」ボタンで分岐
Select Case MsgBox(Prompt:="データを上書きします(いいえで新規追加)", Buttons:=vbYesNoCancel)
Case vbYes
'はいをクリックしたときの処理
Case vbNo
'いいえをクリックしたときの処理
Case Else
'それ以外(×ボタンかキャンセル)をクリックしたときの処理
End Select

「MsgBox」関数では最大3択のボタンを表示することが出来ます
そのボタンによって対話型のより複雑な処理分岐が可能になります
(MsgBoxの基本の使い方についてはこちら)

また2択ではIf分岐を使用しましたが、ここではSelect分岐を使用します
それぞれのボタン名で分岐の処理を行います
(Select分岐の解説はこちら)

3択には2種類あります

「中止・再試行・無視」の3択のメッセージを表示する
1つ目のコード実行時

引数「Buttons」に「vbAbortRetryIgnore」を指定すると「中止・再試行・無視」の3択になります
それぞれの各大文字部分からがボタンの名前です
なので戻り値の定数もその名前で指定すればいいだけです
また、キャンセルボタンが無いので×ボタンが使用不可になっています(グレー表示になり無効状態)

「はい・いいえ・キャンセル」の3択のメッセージを表示する
2つ目のコード実行時

「vbYesNoCancel」を指定すると「はい・いいえ・キャンセル」の3択になります

単純に2択にあった「はい・いいえ」にキャンセルが追加されただけです

2択の時には無かったキャンセルボタンが追加されたことで、ここでは×ボタンが使用可能になっています
×ボタンとキャンセルは同じ操作とみなされます

数値などの分岐で多数分岐はいくらでもありますが、対話型分岐の3択処理分岐というのはなかなか無いのでシチュエーションが難しかったです
まあ要は2通りの処理と、処理自体のキャンセルという流れになりますがなかなかないで~

2択のデフォルトボタンを変更

MsgBox関数を使用した2択でのデフォルトボタンを変更するコード

'「OK・キャンセル」ボタンで分岐(キャンセルをデフォルト)
If MsgBox(Title:="削除確認", Prompt:="データを削除します", Buttons:=vbOKCancel + vbDefaultButton2) = vbOK Then
'OKをクリックしたときの処理
Else
'×ボタンかキャンセルをクリックしたときの処理
End If
'キャンセルをデフォルト、注意アイコンを表示する
If MsgBox(Title:="削除確認", Prompt:="データを削除します", Buttons:=vbOKCancel + vbDefaultButton2 + vbExclamation) = vbOK Then
'OKをクリックしたときの処理
Else
'×ボタンかキャンセルをクリックしたときの処理
End If

「MsgBox」関数引数「Buttons」でボタンの複数表示をした場合に、最初にフォーカスが取得されているボタンを変更できます
(MsgBox関数の基本的な解説はこちら)

2択の処理分岐を行う際に、Enterキーをうっかり押してしまって処理を実行しないつもりが実行してしまった
という、ミスを防ぐために削除や時間のかかる処理の確認時はキャンセルボタンをデフォルトに設定します

第2ボタンをデフォルトにする
キャンセルボタンをデフォルトにする

ボタンの初期位置の設定には引数「Buttons」にボタンの指定の後に追記します
その際「+」記号を使用します

これで第2ボタンであるキャンセルボタンが最初にフォーカスを取得した状態になりますので、Enterキーを押しても処理実行はキャンセルされますので、誤って実行してしまうことを防ぐことができます

第2ボタンをデフォルトにして注意アイコンも表示する
デフォルトを変更してアイコンも表示

さらにアイコンに関しても追記で指定可能です
この場合も「+」記号を使用します
2つ目はさらに注意アイコンを指定しているので、音もなってより注意を促せる内容になります
音がわずらわしい場合は、1つ目で十分だと思います