データを処理する際に、オートフィルタで見えてる行だけを対象に処理を行いたい場合があるんです。
このようなデータはデータベースで処理を行う方が効率がいいのですが...
それはさておき、ユーザーがフィルタした後にと言うこともありますからね。
2024年10月13日(日) 16:04 JST
データを処理する際に、オートフィルタで見えてる行だけを対象に処理を行いたい場合があるんです。
このようなデータはデータベースで処理を行う方が効率がいいのですが...
それはさておき、ユーザーがフィルタした後にと言うこともありますからね。
前回、[Excel VBA] 特定条件を満たすセルを見つけるにて特定のセルを見つける方法を記載したが、問題が見つかった。
そこで、その問題に対策を施したバージョンをご紹介する。
Excel で以下の様な番号と名前のデータがあったときに、番号をキーにして名前を取得するようなことは多いだろう。
このようなケースを処理するためには、Find メソッドを使用するとうまくできる。
Excel で以下の様な番号と名前のデータがあったときに、番号をキーにして名前を取得するようなことは多いだろう。
このようなケースを処理するためには、Find メソッドを使用するとうまくできる。
特定条件を満たすセルを見つけた後、削除するような処理では以下の方法が使用できない。
この様な場合には、[Excel VBA] 特定条件を満たすセルを見つける2を参照いただきたい。
マクロ記録などを応用して作った Excel VBA マクロ。
きちんと文法どおりできているか、実行するまでわからないと思っている人も多いのでは?
Excel VBA はデバッグメニューの一番上に[VBA Project のコンパイル]があります。
VBA で配列の中身を順番に処理する場合、LBound から UBound をまでを順に処理します。
しかし、要素が 0 個の空配列は LBound も UBound も同じく 0 なので、必ず一度処理されてしまいます。
空になる可能性のある配列を扱う場合には、配列の宣言後以下の処理を行っておくと便利です。
SafeArrayAllocDescriptor 1, [配列]
この関数を使用するには、以下の定義文を Decralation に記述しておく必要があります。
Private Declare Function SafeArrayAllocDescriptor Lib "oleaut32" (ByVal cDims As Long, _ ByRef ppsaOut() As Any) As Long
この関数 (Windows API) を使用すると、UBound の値が -1 になります。
ですから、
for i = LBound([配列]) to UBound([配列])
と書いても、空配列の場合には一度も処理されることはありません。
もちろん、要素がある場合には要素数の回数だけループします。
要素数を求める場合には、以下の式で求めることができます。
UBound([配列]) - LBound([配列]) + 1
VB/VBAでは引数にOptional が使える。Delphi、C++、VB.Net にはない機能だ...
関数を作る際に、Optional A As Variantなど Optional付で指定したパラメータは省略ができるようになる。
そしてその関数を利用する際に、Optional のパラメータが省略されたかどうかを調べることができるのが、IsMissing というわけ!
しかし、VB6以前には Optional パラメータには Variant 型しか指定できなかったのが、VB6からは Boolean 型なども指定できるようになった。しかし、Variant 型以外を指定した場合には、IsMissing 関数が使用できないのだ!!
知らんかった...
型指定の省略可能パラメータを省略した場合には、デフォルトの省略値が最初からセットされた形で関数が処理されている。
Boolean であれば False、数値型であれば 0、文字列型であれば空文字列がデフォルトの省略値。
変数宣言して初期値で初期化しなかったときのデフォルトと同じですな...
Boolean 型の省略パラメータに対し、 IsMissing を使用して省略判定しようとして期待した結果にならないからと、デバッグして初めてわかったポカミスでした。(T_T)
なぜ、今まで知らなかったのだろう...
というか何で今までちゃんと調べなかったのだろう?
セルの形式をR1C1形式からA1形式に変換するのに自作関数まで作ってたことがとてもばからしい...
あるはずだとは思っていたのだが、見つからなかった。ヘルプでキーワード検索しても、全文検索しても... オブジェクトパッケージャで上から順に怪しいメソッドを順に試せば、わかったはずだった。しかしやらなかった。
結論を言うと、Cells もしくは Range オブジェクトには Address というプロパティがあって、それを利用するとセルもしくは範囲がA1形式の絶対表記で取得できる。セル自体を参照する分には必ずしも必要ではないが、列を選択する際にはA1形式の方が圧倒的に表記が楽だ!
使い方はこんな感じ...
With Worksheets(1) Debug.Print .Range(.Cells(1, 1), .Cells(1, 1)).Address Debug.Print .Cells(1, 1).Address End With
Excelには便利な機能があるが、使い方を知らないものたくさんある。
今一番知りたいのは、オートフィルタでフィルタされずに表示されている行だけ、ループで順に処理できる方法。わかったらまたここにメモしておくことにしよう。
しかし、最近の Office のヘルプはとても使いづらい...