和風スパゲティのレシピ

日本語でコーディングするExcelVBA

サンプルコード

FileSystemObjectの呼び出しを短縮する方法

FileSystemObjectはとても便利なのですが、CreateObjectやNewを使った参照・宣言部分が面倒です。これを簡単に行う方法として、Public FSO As New FileSystemObjectとPublic変数でNewまで済まし、全プロシージャで使いまわす方法があります。

フォルダを部分一致(ワイルドカード)で検索する

フォルダを部分一致で検索する方法を解説します。フォルダの検索にはFileSystemObjectを使うのがおすすめです。Dir関数はワイルドカードが使えますが、引数にvbDirectoryを指定してもファイルまで一緒に検索するためコードが煩雑になります。

ファイルを部分一致(ワイルドカード)で検索する

ファイル名を部分一致検索する方法を解説します。単純な部分一致であればDir関数にワイルドカード(*?)を指定することで実行できます。文字数や文字種を絞った部分一致まで行いたい場合は、候補のファイルすべてをLike演算子で比較します。

Range(Cells,Cells)の親シートを指定する方法

Range(Cells,Cells)で取得するセル範囲の親シートを指定する方法を解説します。Cells2つにシートの指定を付けるか、RangeとCells2つの計3つすべてにシートの指定を付けるかで指定してください。ws.Range(Cells,Cells)ではエラーになります。

セル範囲や複数セルから1次元配列を生成する

セル範囲などRangeオブジェクトを格納した1次元配列を生成する方法を解説します。すべてのセルをForEach文でArrayに格納していくコードです。空セルを除外するなど条件を付ける場合は、ReDimPreserveを利用して要素数を動的に処理します。

複数のセル値を区切り付き文字列に結合する

複数のセルの値を文字列に結合する方法を解説します。対象セルがn×1や1×nのセル範囲であればExcelのTEXTJOIN/CONCAT関数、VBAのJoin関数が使えます。対象セルが複数エリアにまたがる場合は、ForEach文で1つずつ結合していきます。

セルの値からフォルダを一括で作成する

セルの値を元に、フォルダを一括で作成するコードを紹介します。対象のセルをFor文やFor Each文ですべて取得、「親フォルダパス & "\" & セル値」で目的のフォルダパスを生成し、MkDirステートメントで実際のフォルダを作成します。

重複しないよう連番付きでフォルダを作成する

必ず新しいフォルダが必要なマクロにおいて、もし同名のフォルダが存在した場合は連番を付けて新規フォルダを作成するコードを解説します。処理の流れは単純で、フォルダ名 & iが存在しないフォルダ名になるまでiを増やしていくコードです。

深い階層まで一気にフォルダを作成する

フォルダを作成する「MkDirステートメント」は、フォルダを1つずつしか作成できないため、親フォルダがないフォルダ作成を指示するとエラーになります。このエラーを考慮し、上の階層から順にフォルダを作成していくコードを解説します。

指定の文字列より左側(前方)を削除する

テキストからある文字列を検索し、それより左側を削除するコードを解説します。Instr関数で検索文字列の位置を知らべてRight/Mid関数で取り出すコードが基本になりますが、Split関数を使って検索文字で区切るコード短縮技も紹介します。

指定の文字列より右側(後方)を削除する

テキストからある文字列を検索し、それより右側を削除するコードを解説します。Instr関数で文字列の位置を調べて、その1文字手前までをLeft関数で取得します。対象文字列が複数登場する場合は、InstrRev関数と使い分けることになります。

フォルダが存在するか判定する-Dir/FSO.FolderExists

フォルダが存在するか調べる方法を解説します。Dir関数の引数にフォルダパスとvbDirectoryを渡して判定します。ただしこれは他のDir関数使用中は実行できないため、その場合はFileSystemObjectのFolderExistsメソッドを使用します。

ブックを上書き保存して閉じる - Closeメソッド

ブックを上書き保存して閉じる方法を解説します。ブックを上書き保存して閉じる処理は、Closeメソッドの第1引数SaveChangeにTrueを指定することで、1行のコードで簡単に実行することができます。

マクロでのみ編集可能なシート保護を設定する

シートの保護でユーザーの操作を制限したシートにおいて、マクロのみ編集ができるように設定する方法を解説します。ProtectメソッドのUserInterfaceOnlyを使うことで実装できますが、この設定は保存することができないため注意する必要があります。

ロックされていないセルをすべて選択/クリアする

ロックされていないセルをすべて選択/クリアする方法を解説します。この手の操作に便利なSpecialCellsメソッドには残念ながら該当の機能がありませんので、For Eachステートメントで地道にLockedを判定して取得していきます。

シートの保護設定を調べる/同じ設定でシートを保護する

ワークシートの保護設定の内容を調べる方法と、それを利用して同じ設定でシートを保護する方法を解説します。シート保護の各設定がONになっているかどうかを調べるには、WorksheetオブジェクトのProtectionプロパティを使用します。

ブックを保存せずに閉じる - Closeメソッド

ブックを保存せずに閉じるコードを解説します。Closeメソッドの引数SaveChangesをFalseに指定する方法、DisplayAlertsをOFFにしてから閉じる方法、保存済フラグ(Savedプロパティ)をTrueにしてから閉じる方法の3パターンがあります。

Dictionaryで要素ごとのデータ数をカウントする

Dictionaryオブジェクトを使って、要素ごとのデータ数をカウントする方法を解説します。Excel上では、要素ごとのCOUNTIFや、ピボットテーブルで行う処理ですが、VBAの内部で行う場合は Dictionaryを使うと、簡単に書けて処理速度も高速です。

Dictionaryで重複のないリストを作る

Dictionaryオブジェクトを使って、重複のないリストを作成する方法を解説します。リストを処理するコードは、Dictionaryを使うと簡潔で処理速度も高速になります。Dictionaryの入り口としてもいい題材なので、ぜひ覚えていってください。

指定のフォルダをエクスプローラーで開く

指定のフォルダをエクスプローラーで開く方法を紹介します。この処理は、Shell "C:\windows\explorer.exe " & フォルダパス & "\", vbNormalFocusで実装できます。局所的な使い方のコードですので、おまじないだと思って使って構いません。

特定のセル範囲内にある図形を処理/選択する

Shapeの位置がセル範囲内にあるかどうかを判定して、その範囲内のShapeを処理する方法を解説します。TopLeftCell/BottomRightCellでShapeを含む最小のセル範囲を取得し、それとセル範囲のIntersectが一致するかを判定して処理を行います。

すべての図形(オブジェクト)を削除する

すべての図形オブジェクトを一括で削除するコードを紹介します。すべて削除したい場合はActiveSheet.DrawingObjects.Deleteで簡単に実行できます。グラフだけを残すような場合は、ForEachでひとつずつShape.Typeを判定して削除します。

テーブル(ListObject)の最終行を取得する

テーブル(ListObject)の最終行取得を解説します。これはListObject.Rangeの最終行で求めますが、そもそもテーブルはListRowプロパティを利用して、1からListRows.Countまで、のようにレコード数でForループが書けることは留意してください。

最終行/最終列を取得する万能関数を作る

ひと口に最終行と言ってもいろいろなやり方があり、UsedRange、End、Range、CurrentRegion、AutoFilterなどが考えられます。こういう処理は関数化が便利ですが、せっかくなので1本で何でもやってくれる万能関数を作ってみましょう。

最終列を取得する - 基本構文とサンプルコード

ExcelVBAにおいて、最終列を取得する方法を紹介します。シート/指定行/セル範囲(Range)/CurrentRegion/AutoFilterの最終列を取得するコードをします。仕組みは最終行を取得するときと変わりませんので、ソースコードのみ記載しました。

CurrentRegionの最終行を取得する

CurrentRegionの最終行を取得するコードを解説します。一発で取得するプロパティは残念ながらありませんので、CurrentRegionをストレートにセル範囲に入れて、CurrentRegionの最終行 = セル範囲.Rows.Count + セル範囲.Row - 1で求めます。

オートフィルターの最終行を取得する

オートフィルターの最終行を取得するコードを解説します。これを一発で取得するプロパティは残念ながらありませんので、AutoFilter.Rangeでフィルターのかかっているエリアを取得し、そのエリアの最終行を取得する手法を用います。

指定のセル範囲(Range)の最終行を取得する

あるセル範囲(Rangeオブジェクト)があったとき、その最終行はセル範囲.Rows.Count + セル範囲.Row - 1で取得できます。行数を数えるRangeオブジェクト.Rows.Countと、第1行を取得するRangeオブジェクト.Rowは必ず覚えておきましょう。

マージソートのサンプルコード

「マージソート」のサンプルコードを掲載します。一気に全部を総当たりをするのではなく、2個に割ってから総当たりをして、そのあと合体(マージ)した方が、総当たりをする空間を小さくできて、結果的に早いという原理のソートです。

アルファベット(ABC)⇔数字(123)を変換する関数

アルファベット(ABC)を数字(123)に、またはその逆の変換をする関数を紹介します。列見出しと列番号の相互変換という需要がほとんどと思いますので、27番以降はAA~と対応させる関数にして、「Rangeプロパティ」を使用して作ります。