シートのフィルタ設定を取得する

フィルタの適用状態を取得するプロパティ、使用時に注意点があります

'アクティブシートのフィルタ設定状態を取得
Debug.Print ActiveSheet.AutoFilterMode

シートにフィルタが設定適用されているかどうかを調べるには「AutoFilterMode」プロパティを使用します
このプロパティがTrueを返すと適用されており、Falseが返されると適用されていない状態となります

プロパティで設定状態を取得しているときの動き
プロパティ取得の動き

基本的には、フィルタの適用を解除したい場合に解除する前に適用されているかを調べる時に使用します

ちなみに、このプロパティでは設定を行うことも可能ですがFalseだけです
Trueを設定すると実行時エラーが発生します
Falseを代入するとフィルタの適用を解除できます
なので、こちらで解除を行えば十分に感じるかもしれませんがExcelでよく使用されるテーブル使用時に注意点が出てきます

テーブル使用時の注意点

このプロパティはWorksheetオブジェクトのメンバーです
対してテーブルはListObjectというオブジェクトになります
そのため、このプロパティが無効となってしまいます

テーブル使用時にうまくプロパティが取得できていない時の動き
テーブル時の動き

画像を確認してください
この画像ではコードもデータ内容も全く同じものを使用しています

シートのデータ範囲がテーブルに変換されている点が違います

ですが、こちらではフィルタの矢印が表示されていても、いなくてもFalseが返されています
これがこのプロパティでの大きな注意点です

フィルタをかけるメソッド自体は、テーブルかどうかに関わらず使用できます
なので非適用の状態からフィルタを適用する状態にすることは出来ています

ですが、このプロパティは無効となってしまいます
そのため、上記で解説したFalseを設定することによるフィルタの適用解除も使用できません

フィルタの操作自体はテーブルに関わらないので、問題になることはありませんが
AutoFilterModeプロパティ使用時はテーブルの存在にも注意してください

フィルタを解除する

フィルタを解除するコード、解除時には判定を行います

'フィルタが適用されていれば解除する
If ActiveSheet.AutoFilterMode = True Then
Cells.AutoFilter
Else: End If

ワークシートのフィルタを解除するには「AutoFilter」メソッドを引数を全て省略して使用します

ただこのメソッドはプロパティでは無いため、設定の適用・解除という操作が行えず、実行するたびに適用・解除が切り替わります
そのため、このメソッドを使用して解除する場合は事前にフィルタが適用されているかを調べておく必要があります

これを調べてから実行しないと、解除したいのに元々未適用であれば、適用状態になってしまいます

その適用の状態を取得するのがAutoFilterModeプロパティで、こちらはシートのプロパティになります
このプロパティについては以下の記事で解説しています

フィルタの適用設定に関しては、フィルタを指定する際にもこのメソッドを使用するので、未適用状態でフィルタを実行すれば、フィルタの適用と同時にフィルタもかかるので適用する場合にはあまり適用状態を気にする必要はありません
解除する場合のみ例コードの様に判定を行ってください

ちなみに、フィルタを解除するとかかっているフィルタも全て解除されるので、非表示になっているデータは全て表示されます

処理を指定行に移動する

GoToステートメントは指定の行から処理を実行できます

'指定箇所に処理を移動する
GoTo 移動

移動:

処理の途中で条件分岐などにより、指定処理を飛ばして後続処理を実行したい場合があります
その時に使用するのが「GoTo」ステートメントを使用します

このステートメントの後にラベル名を指定することで、そのラベル行に処理が移動します

ラベルに関しては「ラベル名」に「:」を結合して指定します
日本語も使用できますので、わかりやすい名前を付けます

処理の実行が移動している状態の動き
コードの動き

実際の動きの確認です
GoToステートメントの時点でラベル行に処理が移動するので、後続の「MsgBox “”」が実行されていません

また、ラベル行は処理ではありませんので処理実行の黄色にはなりません
ラベル行の次の行から処理が実行されます

ちなみに、行ラベルはタブを挿入できません

このステートメントは一見、便利なコードのように感じるかもしれませんが多用は禁物です

中でも、一番注意してほしいのがループ処理に使用する場面です
ループの途中で強制的にループを抜けさせる場合、配列データがロックしたりする場合があります
ループでそういった移動処理はなるべく使用しないような処理に作成出来るように検討してください

また、あまりにも多く使用するとどこからどこに飛ぶか分かりにくくなる可能性があります
ステートメント自体の使用数は多くても構いませんが、ラベル行は限定するようにします

自分がよく使用する場面は、処理途中で条件が整っていないために処理を終了する際に、その判定までに複数の変数を使用していて全てを解放する必要がある場合に、Exitステートメント実行前にそれら全てを解放するのではなく、通常処理での解放の手前にGoToステートメントで移動させて、解放を1か所だけにする
というような使い方をします

ちなみに、このステートメントは行ラベルの位置に移動するものなので、下方向だけでなく上方向に移動させることも出来ます
条件が整ってなければ、再度上に戻って処理を実行するようなことも可能です
ただ無限ループに注意が必要です

CreateObject関数について

CreateObject関数はExcelVBAとは別の機能を利用するために使用する関数です

'Excelの新規作成
Dim zzExApp As Object
Set zzExApp = CreateObject("Excel.Application")
'新規作成したExcelの表示
zzExApp.Visible = True
'新規作成したExcelの終了と変数の開放
zzExApp.Quit
Set zzExApp = Nothing

CreateObject関数は、アプリのインスタンスを作成する関数です
この作成したインスタンスは必ず変数に代入して使用します
その時に使用するのは、基本的にはObject型を指定します

例コードではExcelを追加で新規起動します
コードのあるExcelとは別のアプリとして起動しますので、Excel関係の設定であったりを使用中のExcelとは別に指定することが出来ます

VisibleプロパティにTrueを指定することで、表示されるようになります
これを行わないとバックグランド実行となり、変数を開放してしまったり処理が強制終了するとVBAから終了させることが不可能となり起動したままになってしまいます

何らかのブックを開いた状態で、そうなってしまうとそのブックが別のユーザーが使用中となり編集が出来なくなります

この場合にはタスクマネージャーからプロセスの終了を行う必要があります

そのため、この関数を使用してアプリを使用する場合はおおよそVisibleプロパティを最初に設定して表示状態にしておく方が無難です
Visibleプロパティに関しては以下の記事で解説しています

ここまでの話であれば、それほど使用場面は無さそうな関数と感じるかもしれません
ですがこの関数の最大の利用場面は、Excel以外のアプリを使用できることにあります

ExcelVBAの標準機能で使用できるExcelファイル以外のデータが扱えるのはせいぜいテキストデータ程度です
しかし、この関数を使用すると同じOfficeソフトであるWord・PowerPoint・Outlook・AccessそれぞれのアプリやファイルをExcelVBAから操作することもできます
またInternetExplorerの操作によるWeb操作も可能になります

それ以外にもFileSystemObjectやDictionaryの利用時にも使用します

VBAをやり込んでいけば、必ずVBAだけで実現できない場面に遭遇します
その時にVBAの限界と諦めるか、VBAから操作できるものは全て使い切ると考えるかこの関数が使えるかによると言っても過言ではありません

アプリのインスタンスを作成するというだけの関数ですが、この関数からの広がる世界はExcelVBAの世界を遥かに超えた世界になります

どうせならその世界を経験して欲しいなと思います
出来ることが劇的に増えて、とんでもなくおもろいねん、これが

警告音を鳴らす

Beepステートメントはシステム警告音を鳴らします

'警告音を鳴らす
Beep

警告音を鳴らすには、「Beep」ステートメントを使用します
このコードを実行するとシステム設定された警告音を鳴らすことが出来ます
この音の設定はシステム設定になるのでVBAから任意に変更することは出来ません

あまり落とを鳴らすというような処理は好まれない場面が多いとは思いますが、例えば何らかの資料を見ながら入力処理を行う場合に、画面上で注意表示をしてもユーザーに認知されない可能性があります

またメッセージボックスでも音を鳴らすことが出来ますが、処理が停止するため入力処理の作業がそこで停止してしまいます
メッセージを確認しないと次の入力も行えません

入力値が制限外のデータであれば、それで構わないのですが、例えば数字を入力する際に前回入力値との差が10%以上あったら注意を促したい場合には有効です

その差が織り込み済みであれば、無視して操作を続けられるし、音が鳴ればユーザーは一度は画面を確認しますので入力時点で異常の検知や間違いに気づくことができるかもしれません

何らかの注意を促す場合に最低限で使用するようにしましょう

表示位置を指定セルに移動する

指定セルにShowメソッドを使用すると見える位置に移動できます

'A10000セルを見える位置に移動
Range("A10000").Show

処理を終了させた段階で指定の個所を見える様にしておきたい場合があります
そんなときに使用するのが「Show」メソッドです

このメソッドを使用すると、指定したセルがウィンドウ内に収まるように自動的にスクロールされます
また、その際に指定したセルは選択状態にはなりません

選択セルは変更したくないけど、画面を移動させたい場合に有効です

ただ、画面内のどこかまでが指定できません
しかも指定セルが画面内にあれば移動しない場合もありますので少し注意が必要です

コードの動き

メソッドの動きの確認
コード実行時の動き

実際にコードを実行してみると、動きがわかりやすいです

画像の動きを確認してください
A10000セルを表示状態にすると、真ん中に表示されるように画面がスクロールされています
そしてその際、選択セルがA1のままで選択範囲が移動していないことも確認できます

そして、このメソッドの最大の注意点が、画面更新を抑止している時には無効になる点です
画面更新を抑止した状態でA1セルを対象に実行しても変化がありません
抑止を解除してから、再度実行するとちゃんと画面が移動します

処理後に画面を移動させたい場合は多いので、あまり問題にならないとは思いますが画面更新を抑止する処理を作成した場合は解除してから実行するようにしてください

ただ、解説したように画面のどこに指定セルが表示されるか分からないので、どうしても指定セルを指定場所に表示させたい場合はApplication.Gotoメソッドを使用してください
こちらのメソッドであれば左上限定ですが、セルの表示位置を指定できます
あとはOffsetプロパティやスクロールさせれば思い通りの表示状態を作成することができます
Application.Gotoメソッドについては以下の記事で解説しています

シートの内部名を取得する

シートの内部名を取得できるCodeNameプロパティについて

'シートの内部名を取得
Worksheets("Sheet1").CodeName

シートを操作する際に使用する、「Worksheets(“Sheet1”)」というオブジェクトはシート名を名称で直接指定しています

これとは別に、内部名としてシートごとにオブジェクト名が存在します
こちらもシート名同様に同じ名前を付けることが出来ないためユニーク名になります
その内部名を取得するのが「CodeName」プロパティです

この内部名を使用することにより、シート名を変更しても処理に影響が出なくなるため、状況によってはシート名より有効に使用できます

内部名とはプロパティでいうオブジェクト名のことになる
プロパティウィンドウ

今回のプロパティは、赤枠内の(オブジェクト名)という部分の文字列です
通常初期値はシート名と同じようにつけられています

またその下のほうにあるNameプロパティはシートのタブに表示されている文字列になります
通常、シート名を変更するとこちらが変更されます

シート名自体も同じ名前を付けることが出来ないので、オブジェクト名を使ったほうがいい場面の方が多いということはないと思います
状況によって使い分けることが重要です

また、この内部名をオブジェクトとして使用することが可能です

シート名を取得するときの動き
シート名の取得

この画像のコードでは、NameプロパティとCodeNameプロパティの両方を使用して、それぞれの名称文字列を取得しています

やっていることは同じですが、指定の仕方が違っています

オブジェクト名の方が、コードを比較的少なくすることが出来ると思います
またシート名をユーザーに変更されても問題が発生しないのは大きな利点です

ただ、Nameプロパティを使用しない場合、シートをコピー作成して同じシート名にして既存のシートを削除する、というようなことをされると使用できなくなります
また、何らかの理由でCodeNameプロパティに相違が出た際にユーザーが簡単に修正することが出来なくなります

シート名は「~~」にしてください、というようなメッセージでシート名を統一させることは出来ても、内部名を編集してもらうのはVBAを知らない人からすれば困難です

なので、シート名の変更にも対応できて、コードを短くすることもできる、この素晴らしいプロパティは状況によってはユーザーに迷惑になる可能性がありますので注意が必要です

やはり、一番相互にいいのはNameプロパティを使用して、それを最初にオブジェクト変数に代入しておくことかもしれません
そうしておけば、もしシート名が変更になっても1か所の修正で済みます

セルが結合されているか調べる

MergeCellsプロパティではセルの結合状態を取得できます

'選択範囲が結合セルかを調べる
Debug.Print Selection.MergeCells
'シート内に結合セルがあるかを調べる(Nullなら存在有)
Debug.Print Cells.MergeCells

指定したセルが結合セルかどうかを調べるには「MergeCells」プロパティを使用します
このプロパティの返し値によって判定を行います

指定したセルが結合されていれば「True」、結合されていなければ「False」をそれぞれ返します
さらに、その両方が含まれていれば「Null」が返されます

なお、このプロパティは設定も可能です
Trueを代入すると結合セルとなり、Falseを代入すると非結合セルとなります
実際の書き方は以下の記事にありますので確認してください

コード解説

結合セルの存在を確認するプロパティの動き
プロパティ取得の動き

この画像の前提として、A2とB2が結合されたセルです

Debug.Print Selection.MergeCells

結合されたセルが選択状態になっていますので、このコードを実行するとTrueが返されます
つまり、選択している範囲は結合されて1セルとなってい状態と判定できます

このプロパティは、単体での判定でしかTrueを返しません
例え指定範囲が全て結合されたセルだとしてもNullが返されてしまいます

逆にすべてが結合されていないセルであればFalseが返されます

そしてその仕様から、シート全体などの範囲で使用することで結合セルの存在を調べられます

Debug.Print Cells.MergeCells

このコードを実行するとNullが返されます
結合セルとされていないセルが範囲内に含まれているからです

画像の最後の動きの部分を確認してください
再度取得する前に、すべての結合を解除しています
その状態でプロパティを取得させると、Falseが返されます
つまり、シート内に結合セルが存在しないことを意味します

どのセルが、という所まではこのプロパティで調べられませんが、存在するかどうかは調べられます

基本的に結合セルとは、見栄えなどの書式的な使い方が多く、VBA泣かせのセルです
あったら何とか解除してしまえないかと思ってしまいますが、この判定や解除をうまく活用して乗り越えてください

セルの結合を解除する

セルの結合を解除するにはUnMergeメソッドを使用します

'選択範囲内セルの結合を解除
Selection.UnMerge
'選択範囲内セルの結合を解除
Selection.MergeCells = False

結合されたセルの結合を解除するには「UnMerge」メソッドを使用します
このメソッドは指定した範囲内にある結合セル全てを一括で解除します

また、本来は結合セルの存在確認を行うMergeCellsプロパティにFalseを代入することでも実行することが出来ます

コード実行時の動き

セル結合の解除の動き
セル結合解除の動き

画像の確認をしてください
前提として、2行目はすでに結合済みのセルです
結合解除を行った際に、そちらは解除されていないことを確認してください

Selection.UnMerge

選択範囲内にあるすべての結合セルの結合を解除します
指定範囲を限定することで、シート内に複数の結合セルがあったとしても限定して解除することが可能です

Cells.UnMerge

なので、逆に指定範囲を広げてシート全てのセル範囲を指定するとシート内にあるすべての結合セルの結合を解除することが出来ます
書式統一のために使用された結合セルが多いので、あまりこういった使い方はしないかもしれませんが、結合セルがシート内に1つしか無いのであれば、そのセル範囲を検索する必要がなく楽に解除することが出来ます

MergeCellsプロパティに関しては別の記事で解説していますので、ここでは割愛します

セル範囲を結合する

セルを結合するにはMergeメソッドを使用します

'選択範囲の結合
Selection.Merge
'選択範囲の横方向への結合
Selection.Merge True

セル範囲を結合するには「Merge」メソッドを使用します
このコードを使用すると指定したセル範囲が結合セルとなります

またメソッドの引数に「True」を指定することで、横方向のみの結合を行うことが出来ます

Selection.MergeCells = True

本来は結合セルの存在確認に使用するMergeCellsプロパティを使用することでも、例コードの1つ目と同じ動きの結合を行うことが出来ます

コードの動きの解説

セル結合時のコードの動き
セル結合時の動き

各結合の後にある「Cells.UnMerge」は結合セルを解除するコードです
結合の動きを確認するために書いています

Selection.Merge

これを実行すると、選択範囲が1つのセルに結合されます
行列ともに1つのセルとして結合されます

Selection.Merge True

このメソッドの引数にTrueを指定することで横方向のみの結合を行うことが出来ます
画像の動きを確認してください
選択範囲が複数行である場合に、横にのみ結合が実行され、縦方向には結合が実行されていないことが確認できます

これは、通常操作の「横方向に結合」と同じ動きをします
複数行で縦には結合しない場合に一括で指定することが出来る方法です

1つ目では省略されていましたが、この引数を省略するとFalseが指定されていることになります

Selection.MergeCells = True

このコードは、通常は選択範囲に結合セルが存在するかを調べて、存在すればTrueを返すプロパティですが、Trueを代入することで例コードの1つ目と同じ動きを実行できます

ただ、このコードでは横方向の指定が出来ません
ですが、解除する場合も使用でき、Falseを代入するだけで可能です

結合するにはTrueを、解除するにはFalseを代入するというのがイメージしやすいので使い勝手はいいと思います
蛇足ではありますが便利なので紹介します

コード実行時の注意点として、指定範囲に複数のデータが存在する場合はExcelの警告が発生します

結合時のデータ欠損の警告メッセージ
データ欠損の警告

結合セルを使用したことがある人なら見たことあると思いますが、複数のデータがある場合にデータの欠損が発生するため警告が表示されます
ここでキャンセルを選択すると、実行時エラーが発生します

動的にセル結合を行う場合にはこの点のみ注意が必要です