エラー処理(無視して継続)

On Error Resume Nextステートメントを使用することでエラー発生による処理停止を防ぐことが出来ます

'後続のエラーを無視する
On Error Resume Next

実行時に発生するエラーを無視して処理を継続するには「On Error Resume Next」ステートメントを使用します

このコード以降に発生するエラーで処理の停止が無くなり、処理が継続されるようになります
エラー発生が意図したもので、予想の範囲内である場合に使用します
なお、エラーが発生しなくなるわけではありません

フォルダの作成は、すでに存在する名前を指定するとエラーになりますがそのエラーは無視することで、フォルダの作成が出来るときはする、出来ない時はしない、という動きにすることにできます

また、オブジェクト取得の際に存在しないオブジェクトを取得しようとするとエラーが発生しますが、そのオブジェクトの生成を待ったり、判定に使用したりする際にエラーを無視させます

エラーの発生は基本的には必要な情報の提示になります
これを抑止する事で、予想外のエラーが発生しても気づかないこともありますので多用すべきコードではありません

また、このコードは以降の全ての処理に適用されるので無視するべき処理が終わったらすぐに「On Error GoTo 0」ステートメントを使用してこの無視する設定を解除してください

処理を一時停止させてデバッグモードにする

処理の一時停止に使用する、Stopステートメントとブレークポイントについて

'処理の一時停止
Stop

処理の一時停止には「Stop」ステートメントを使用します
引数はなにもなくこのコードのみで可能です

ブレークポイントについて

また、処理の一時停止にはブレークポイントの設定でも可能です
こちらはコードには保存されないため、デバッグ時の一時使用の際に使用します

ブレークポイントの設定方法
メニューから設定する項目

ブレークポイントの設定は、設定したい行に入力カーソルを置いた状態で画像のメニューを選択します
デバッグメニュー内の、ブレークポイントの設定/解除を選択します
設定/解除とありますので、ここで切り替えを行います

また、メニューにもありますが「F9」キーでも設定可能です

ブレークポイントのコード画面での設定方法
コード画面での設定

F9キー、もしくは画像のマウスカーソルのある個所をクリックすることで設定の切り替えが可能です

コード行の左のスペースの範囲です

なお、このブレークポイントはコードが実行される行でしか設定はできませんので空白行であったり、変数の宣言などのコンパイル処理行には設定できません

また、このブレークポイントは保存されないため、ブックを開きなおすと設定は解除されています

使い分けについて

ブレークポイントとStopステートメントの動き
処理実行時の動き

処理を実行すると、ブレークポイントとStopステートメントのどちらでも処理が一時停止します

Stopステートメントとブレークポイントの使い分けに関しては、上記にあるように保存したいかどうかで使い分けます

例えば、処理作成中にループ処理後からデバッグモードを行いたい場合はブレークポイントを設置して対応します

Stopステートメントは、別のブックの処理を開きなおして実行する場合や、ブックのOpenイベントでの確認を行いたい場合に使用します
どちらもブックを一度閉じてからデバッグを行いたい場合です

ステップインで最初からすべてを確認するには時間がかかる場合には重宝する処理の一時停止です
デバッグ力につながるので、使いこなしてください

ファイルを削除する

Killステートメントでファイルの削除を行うコード。VBAでの削除に関しての注意点

'Wordファイルを全て削除する
Kill ThisWorkbook.Path & "\*.doc*"

ファイルの削除には「Kill」ステートメントを使用します
引数に削除対象のパスを指定します
パスにはワイルドカードが使用できます、例コードではコードのあるExcelファイルと同じフォルダ内の全てのWordファイルを削除します

Wordはバージョンによって拡張子が3文字と4文字がありますが3文字目までは同じなのでワイルドカードを使用することでバージョンの違うものも一括で削除可能です

VBAでのファイルの削除について

VBAのコードでのファイルの削除は復元が不可能な状態での削除になります
ファイルの削除に関して注意が必要です、特にワイルドカードでの削除は予期しないファイルまで削除してしまう可能性もあります

ゴミ箱に移動させる方法は、VBA標準機能には搭載されていません
WinAPIを使用することで可能ですが、少し難しくなります

なので、デスクトップなどの分かり易い場所に「不要ファイル」などの名前でフォルダを作成して、そこに移動させるようにします
その後、一定期間後にファイルを削除するように処理を組むことでWinAPIを使用せずに目的は達成できると思います

フォルダを削除する

RmDirステートメントを使用してフォルダを削除するコード。このコードの使用上の難点

'フォルダを削除する
RmDir ThisWorkbook.Path & "\新しいフォルダー"

フォルダを削除するには「RmDir」ステートメントを使用します
引数にはフォルダ名までを含むパスを指定します

存在しないフォルダパスを指定するとエラーが発生します
MkDirステートメントと同様にエラー無視による削除実行は可能ではありますが、後述のエラーも発生することから、削除できていない状態になることがあるのでエラー無視には意味がありません

上記のエラーの他に、削除対象フォルダ内にファイルが存在しているとエラーが発生し削除できません

このコードで削除を実行する場合は、フォルダ内にあるファイルを全て削除してから実行します
ただ、すべて削除してフォルダも削除する目的で無条件削除で良いのならFileSystemObjectのDeleteFolderメソッドを使用するほうが便利です
こちらであれば、フォルダ内にファイルが存在していても削除が可能です

フォルダを作成する

MkDirステートメントを使用してフォルダの作成を行うコード。エラー無視による作成コードもあります

'処理ブックと同じ場所にフォルダ作成
MkDir ThisWorkbook.Path & "\新規フォルダ"

フォルダの作成には「MkDir」ステートメントを使用します
引数はフォルダの名前までを含めたパスを指定します

例コードでは「ThisWorkbook.Path」(コードのあるブックのパス)と同じ場所に「新規フォルダ」を作成します

同名作成時のエラー処理について

このコードはすでに存在するフォルダ名を指定するとエラーが発生します

'フォルダ作成済みのエラーを無視する
On Error Resume Next
MkDir ThisWorkbook.Path & "\新規フォルダ"
On Error GoTo 0

上記のコードは、エラーを無視する処理の上で作成を実行します
この処理であれば、作成済みのフォルダ名を指定した場合はエラーが発生しますが無視して処理を継続できます

その際に、既存のフォルダが上書きされたりすることはありません

これは乱暴なコードかもしれませんが、いちいちフォルダの存在確認を行うのも面倒ですし、そもそもフォルダの存在を確認することが目的では無いので無駄な処理だと思います
とはいえ、Dir関数を使用すれば簡単に存在確認は行えます

ただ、やらなくてもいいことはやらなくて良いと思います


関連の記事

ScrollTop・ScrollLeftプロパティ

ScrollTop・ScrollLeftプロパティはスクロール移動値の設定です、これを使えばフォーム内移動が行えます

'高さの表示位置の変更
Me.ScrollTop = 50
'横の表示位置を変更
Me.ScrollLeft = 50

「ScrollTop」プロパティはスクロールの高さ位置の設定
「ScrollLeft」プロパティはスクロールの横位置の設定

これら2つのプロパティは、スクロール位置の調整数値です
「0」というのが、スクロールしていない状態になるので、最左上の位置になります
ここからスクロールの動いた分が、これらのプロパティ設定になります

初期値で数値を指定しておけば、広大なフォームだったとしても初期表示位置を指定できます
なお、このプロパティはデザイン画面でスクロールバーを動かした時点で自動的に数値が入力されるので、この画面で調整する場合は数値の入力は必要ありません

ある程度の広さを持ったフォームを作ってしまうと、どこに何があるか分かりにくくスクロールして目的のコントロールを探すことになります
そんなときに、ボタンなどでこのプロパティで位置調整を行えば利便性が上がります

'Frame1を左上に移動
Me.ScrollTop = Frame1.Top
Me.ScrollLeft = Frame1.Left

このコードを実行すると、フォームにあるFrame1コントロールの左上を表示領域の左上に合わせます
ただ、この数値と実際のフォームサイズの差が範囲内でなければ移動しきれず中途半端な位置になります

ようは、Webページでもよくあるページ内リンクと同じような役割を持たせられます
このサイトではトップページにそのページ内リンクがあります

どうしても、広い領域のフォームが必要になった場合は、こういったプロパティを活用してユーザーが迷子にならないようにフォームを作成しましょう

ScrollHeight・ScrollWidthプロパティ

ScrollHeight・ScrollWidthプロパティはフォームのサイズを超える領域の高さと横幅の設定です

'フォームの表示領域の高さを増やす
Me.ScrollHeight = Me.Height + 50
'フォームの表示領域の横幅を増やす
Me.ScrollWidth = Me.Width + 50

「ScrollHeight」プロパティはフォームの表示領域の高さの設定
「ScrollWidth」プロパティはフォームの表示領域の横幅の設定

これら2つの数値をフォームのサイズより大きな数値に設定することで、スクロールにより作成したフォームのサイズ以上の表示領域を扱うことが出来るようになります

なお、この設定を行っても表示領域自体は拡張されますが、スクロールバーは表示されません
スクロールバーの表示設定も合わせて行っておきます
(表示設定の記事はこちらから)

これらのプロパティをフォームサイズを超える数値にすることで、画面に収まりきらないコントロールを配置することが出来ます

基本的にはデザイン画面のプロパティウィンドウで設定を行います
デザイン画面で設定すれば、その画面でスクロールさせて実際の動きを確認できるのでこちらで行ってください

コード中に設定するには、例コードのように数値を設定する形になります

表示外という領域を作成する注意点

この表示領域の拡大に関しては初期表示ではどこに何があるかわからない状態です
この状態ではユーザーにとっては少しわかりづらいフォームになってしまうので、このプロパティを使用する場合は、デザインを特に意識してください

画面スクロールすることで、他のコントロールがあることや目的のコントロールがどの位置にあるかを分かり易くするデザインは工夫が必要です

そして、VBAの弱点の1つでもありますが、マウスのホイールは使用できません
なので、マウス操作になれていればスクロールバーの上でホイールで移動させようとするのは無意識の操作です

これが行えないので、少し使っている人にはわずらわしく感じる可能性がありますので正直あまり多用しないほうがユーザーにはやさしいかなと思います

CreateFolderメソッド

CreateFolderメソッドはフォルダを作成するメソッドです。ここで作成したフォルダは変数に代入します

'フォルダを新規作成して変数に代入
Dim bhFSOFolder As Object
Set bhFSOFolder = bhFSO.CreateFolder("作成するフォルダのパス")

フォルダを作成するには「CreateFolder」メソッドを使用します

メソッドの書式

引数(太字は必須引数)
CreateFolder foldername

「foldername」は新規作成するフォルダの絶対パスです

フォルダの作成について

このメソッドは同名のフォルダを作成しようとするとエラーになります

この「フォルダを作成する」という目的であれば、わざわざFileSystemObjectを使用しなくてもMkDirステートメントで作成は可能です

ただ、この「フォルダを作成する」という目的で処理が完了することはあまり無いと思います
基本的には、フォルダを作成してそのフォルダにファイルをコピーや移動を行うといった処理に続くことになると思います
その際に、この新規作成したフォルダをオブジェクトとして取得できるFSOのほうが利便性があります

なので、フォルダの新規作成で処理が完了するならMkDirステートメント
作成してそのフォルダを扱うならCreateFolderメソッド
というような使い分けを行えばいいかなと思います

オブジェクト変数として扱うには、このメソッドの引数を「()」で囲んで代入させます
例コードの様に、変数を宣言してそこにオブジェクトとして代入させることでその新規作成したフォルダをオブジェクトとして使用が可能になります
この「bhFSOFolder」に対してメソッドやプロパティの変更を行い処理を継続します


関連の記事

DeleteFile・DeleteFolderメソッド

DeleteFile・DeleteFolderメソッドはファイル・フォルダを削除するメソッドです。フォルダの削除にはこれを使用します

'ファイルの削除(読み取り専用も削除)
bhFSO.DeleteFile "削除先のファイルパス", True
'ファイルの削除(読み取り専用があるとエラー)
bhFSO.DeleteFile "削除先のファイルパス"

DeleteFile(ファイルの削除)

'フォルダの削除(読み取り専用も削除)
bhFSO.DeleteFolder "削除先のフォルダパス", True
'フォルダの削除(読み取り専用があるとエラー)
bhFSO.DeleteFolder "削除先のフォルダパス"

DeleteFolder(フォルダの削除)

ファイルを削除するには「DeleteFile」メソッドを使用します
フォルダを削除するには「DeleteFolder」メソッドを使用します

メソッドの書式

引数(太字は必須引数)(2つのメソッドは引数が同じ)
DeleteFile filespec, force
DeleteFolder filespec, force

「filespec」は削除を実行するファイルやフォルダの絶対パスを指定します
また、この引数にはワイルドカードの使用も可能なので関連するファイル名や拡張子でまとめて削除を実行することが出来ます

「force」は読み取り専用ファイルがあった場合に削除を許可するかの設定です
省略可能で、省略した場合はFalseが指定され、削除は許可されません
許可されない設定で、削除を実行しようとするとエラーが発生します

フォルダの削除はDeleteFolderメソッドが便利

なお、DeleteFolderメソッドではフォルダの中にデータがあるかどうかは判定せず、無条件で削除が実行されます
RmDirステートメントではフォルダ内にデータがあるとエラーとなり削除は実行されませんが、こちらでは削除が実行されるので削除対象には細心の注意を払いましょう
当然ですが、削除後にデータを復旧させることはできません

削除したいフォルダにファイルやフォルダが何階層にもあるような場合、いちいち全ての階層まで下りて削除しなくてないけないRmDirステートメントですが、DeleteFolderメソッドであれば一括削除ができるので処理が簡潔になります

バックアップ処理においては特にこちらのコードの方が便利なのが分かると思います

CopyFile・CopyFolderメソッド

CopyFile・CopyFolderメソッドは、ファイルやフォルダをコピーするメソッドです

'上書きするコピー
bhFSO.CopyFile "ファイル拡張子までのパス", "コピー先のフォルダ名までのパス"
'上書きしないコピー(既存がある場合はエラー発生)
bhFSO.CopyFile "パス文字列\*.txt", "\コピー先のフォルダ名までのパス", False

CopyFile(ファイルのコピー)

'上書きするコピー
bhFSO.CopyFolder "元のフォルダパス", "コピー先のフォルダパス"
'上書きしないコピー(既存がある場合はエラー発生)
bhFSO.CopyFolder "元のフォルダパス", "コピー先のフォルダパス", False

CopyFolder(フォルダのコピー)

FileSystemObjectを使用して、フォルダをコピーするには「CopyFolder」メソッドを使用し、ファイルをコピーするには「CopyFile」メソッドを使用します

FileSystemObjectでのコピーであれば、ワイルドカードにより対象を複数にして一括で処理を行うことができます
また、フォルダのコピーに関しては、中にあるファイルも全てそのままコピーされるのでバックアップ処理にはうってつけです

メソッドの書式

引数(太字は必須引数)(2つのメソッドは引数が同じ)
CopyFile source, destination, overwrite
CopyFolder source, destination, overwrite

「source」は対象となるファイルの絶対パスを指定します、ワイルドカードの使用が出来ますので複数のファイルを一括で指定することが可能です

「destination」はコピー先のフォルダ名までの絶対パスを指定します
上記2つの引数は必須で、指定したパスが見つからない場合はエラーが発生します
特にワイルドカード使用時は注意が必要です

「overwrite」はコピー先に同名のファイルやフォルダがあった場合に上書きするかどうかの設定です。
省略可能で、省略時はTrueが指定され上書きが許可されます

ファイルは上書きされれば当然既存のものはなくなります
フォルダに関しては差分が更新される形になります

コピー元に2つのファイルがある状態で、コピー先にその2つと別のファイルがあった場合は、重複するファイルが上書きされます
重複していないファイルは削除されたりはせずそのままの状態になります

つまり、コピーしてもコピー元と全く同じファイル内容にならない可能性があるということです

完全にコピー元と同じ内容にする場合は、コピー先を一度削除してからコピーするようにします
削除にはFileSystemObjectのDeleteFolderメソッドを使用します
RmDirステートメントではフォルダ内にデータが存在すると削除が行えないのでFileSystemObjectのほうが便利です

コピーしたファイル・フォルダを変数に代入して扱う

'上書きコピーしてそのファイルを変数に代入
Dim bhFSOFile As Object
Set bhFSOFile = bhFSO.CopyFile("ファイル拡張子までのパス", "コピー先のフォルダ名までのパス")

また、コピーしたファイルやフォルダにさらに処理を続ける場合は、このメソッドを変数に代入させることで利便性が上がります
取得させる場合は、関数のように引数を「()」で囲むようにすればいいだけです