和風スパゲティのレシピ

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

仕様・考察

4種のAIによるExcelVBAコーディング性能比較

ChatGPT、Copilot、Gemini、Claudeに同じマクロを作ってもらい性能を比較をしてみました。「VBA&AI初学者に優しい生成AIはどれ?」をテーマに採点しましたので、どのAIをお供にするかの参考にしてみてください。

プロシージャのCall元/先でのOnError挙動まとめ

プロシージャをCallする際、親子どちらでOnErrorを設定したかによって、どのように処理内容が変化するかをまとめました。エラー処理を行う際の参考にして下さい。

Dictionaryの格納件数による速度低下検証

処理が超速なことで知られるDictionaryですが、実はデータ件数が増えすぎると急に遅くなるという欠点もあります。件数の二乗に比例して処理が遅くなる傾向があるため、Dictionaryを分割するなどで対応します。

空の配列Array()の仕様と活用方法

Array()やParamArrayの省略時に「空の配列」が生成されます。この空の配列は要素数が0でFor/ForEachをノーエラースキップできるため、配列を受け取る関数と相性がよく、汎用関数の返り値に活用することができます。

複数領域を持つRangeのプロパティ挙動について

複数のセル領域を格納したRangeオブジェクトの各プロパティがどんな挙動かを検証します。Valueのように第2エリア以降を無視して第1エリアだけを見るプロパティと、全エリアを見るプロパティの2種類があります。

For Each文の中身を途中でいじるとどうなるか

今日はFor Eachステートメントで遊んでみようと思います。For Eachステートメントの変数を途中で変更したり、対象のCollectionを追加・削除して、それがForEachのループに影響するか試してみます。

0,1始まりでない配列(Array)をセルに出力する

例えば「インデックスが2~5の配列」を全然違う番地のセル範囲に吐き出してみても、特にはありません。両者の大きささえ一致していれば、配列インデックスとセル番地は一致している必要はありません。

クラスのメンバーに配列(Array)を定義する

クラスモジュールのメンバーに配列(Array)を定義する方法を解説します。Variant変数で定義することはできますが、そのままでは要素の書き換えが出来ないため、入出力用のPropertyプロシージャを作成して対応します。

Range、Cellsの「.Value」は省略してよいか

VBAにおいてセル(Rangeオブジェクト)を扱う際、「.Value」を省略しても同じ動きになることが多いです。.Valueはどんな時に書く必要があるのか、書く必要がなかったとして省略しても良いのかを解説します。

ByRefの引数にただの値や定数を渡したときの動き

ByRefで定義された引数にただの値や定数を渡したらどうなるかを検証します。ByRefで定義された引数に値や定数を渡したときは、ByValと同じ動き(値が入った変数が新しく作られる)をしてくれます。

WithとNameステートメントは併用できない

WithステートメントでWorksheetを参照中に、Name .Cells(1, 1) As .Cells(2, 1)のような記述を実行しようとすると、構文エラーが発生します。原因は不明ですが、Nameの直後に「.」を打つことはできないようです。Name (.Cells(1, 1))とやれば解決します。

Worksheets("○○"). の入力選択肢を出す方法

Worksheets("○○")でシートを取得したとき困るのが、「.」を入れても入力選択肢が出ないことです。この対処法として「変数にSet」「シートオブジェクト名」がありますが、第3の方法「Worksheet型にキャストする関数を作る」方法を解説します。

Dir関数でサブフォルダの一覧を取得する方法

Dir関数を使ってサブフォルダの一覧を取得する方法を解説します。これは非推奨な方法で、FileSystemObjectを使った方が簡単なことに注意してください。Dirの場合は相対パスとファイルも検索されてしまい、これをはじくコードが必要になります。

変数宣言(Dim)とNewを1行で済ませてよいか

Collection/Dictionary/FileSystemObject/自作クラスを使用するとき、Dim x As X、Set x = New Xと2行で宣言する方法と、Dim x As New X と1行で宣言する方法があります。この違いはNothing時の動きと、Initializeの実行タイミングに現れます。

深い階層のフォルダ作成を再帰関数で行う

MkDirステートメントやFileSystemObjectのCreateFolderメソッドは、作りたいフォルダの親フォルダがないとエラーになります。この対策は[\]でSplitしてからのForEach文がストレートですが、再帰関数を使用した方法もあるため紹介します。

同じコードなのにエラーが変わるRangeの不思議

Range(Cells,Cells)のシート指定ミスは、「Rangeメソッドは失敗しました:Worksheetオブジェクト」「Rangeメソッドは失敗しました:Globalオブジェクト」「アプリケーション定義またはオブジェクト定義のエラーです。」と3種もエラーがあります。

Dimを省略していきなりReDimを書いてもいい?

動的配列において、要素数を設定/変更するときには、ReDimステートメントを使用しますが、実はこのときDimステートメントは省略できます。しかし「変数の宣言を強制」問題と同じデメリットがあるため、動的配列のDimはしっかり書きましょう。

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

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

コンストラクタ(Initialize)に引数を渡せない問題

クラスモジュールに関する小ネタです。VBAについての意見のなかでよく目にするのが、「コンストラクタ(Class_Initializeプロシージャ)に引数を設定できなくて困る」です。これがどういう意味なのか、どう対処すればよいかを、手短に説明していきます。

VBAにおいて「隠蔽」ってどのくらい重要?

VBAにおける隠蔽について考察します。隠蔽とは「2つのPropertyプロシージャによって変数を包み、代入と参照に何らかの制約をつけること」です。VBAにおいて隠蔽はそこまで重要でなく、むしろ隠蔽のないクラスの利便性に着目することが大事です。