エクセル顧客管理
WorksheetFunctionについて

Excelマクロを駆使したカスタマイズ可能なエクセル顧客管理、エクセルVBAの学習教材
公開日:2013年5月以前 最終更新日:2014-11-11

第26回.WorksheetFunctionについて


エクセルで顧客管理を作ります、


今回は、予告通り、期待を裏切らずに、誰も期待してないかもしれないけど(笑)、


やります・・・WorksheetFunctionについてです。


VBAをやれば、必ず使用することになるでしょう。


と言いますか、これを使わないと、エクセルの意味がなくなっちゃいますので。


まあ、関数あってのエクセルですし、関数無けりゃ、ただの作文用紙です。(笑)


ということで、実際に、その関数をVBAで使用して、いろいろ検証してみます。


使用する関数は、VLOOKUPです。


最もよく使う関数の1つですし、作成中のエクセルでも使用しています。



以下の表を使用しました、10000行あります。

Excel VBA 解説


まず、以下で実行しました。

Sub test1()
  Range("E2") = Application.WorksheetFunction.VLookup(Range("D2"), Range("A2:B10001"), 2, False)
End Sub


上の画像のように、検索値があれば何も問題はありません。


しかし、存在しない検索値を指定すると、

Excel VBA 解説


となってしまいます、これでは困ります。


ではどうするか、一番簡単なのは、



Sub test2()
  On Error Resume Next
  Range("E2") = Application.WorksheetFunction.VLookup(Range("D2"), Range("A2:B10001"), 2, False)
  If Err Then
    Range("E2") = "なし"
  End If
  On Error GoTo 0
End Sub


このように、On Errorでエラーを回避します。

On Error Resume Nextは、エラーが発生しても、次のステップに進みます。

そこで、If Errで、エラーがあったかを判定しています。


では次はどうでしょうか。

Sub test3()
  Dim str As String
  str = Range("D2")
  Range("E2") = Application.WorksheetFunction.VLookup(str, Range("A2:B10001"), 2, False)
End Sub


上の表で、検索値が7342であっても、エラーが発生します。

str As Stringにいれているので、型違いで、不一致になります。

この場合は、Variant型に入れる必要があります。

もちろん、この例であれば、数値型でも大丈夫です。


ではでは、これはどうでしょうか。



Sub test4()
  Dim rtn
  Range("E2") = Application.VLookup(Range("D2"), Range("A2:B10001"), 2, False)
End Sub


On Errorがありませんが・・・

これはエラーになりません。

Application.WorksheetFunctionはExcel97からです。

Excel97より前の記述ですが、最新の関数も使えます。

(私は近年まで、これを使っていました。)

ワークシートでVLOOKUPを使って、検索値がない場合と同様に、「#N/A」が返されます。

ですから、全く同一と言う訳ではありません。

しかし、あまり使用はお勧めできません。

WorksheetFunctionクラス(1つのクラスです)を使用するべきだと思います。


エラー回避方法として、以下の方法もあります。

Sub test5()
  Dim rtn
  Set rtn = Range("A2:A10001").find(Range("D2"))
  If rtn Is Nothing Then
    Range("E2") = "なし"
  Else
    Range("E2") = Application.WorksheetFunction.VLookup(Range("D2"), Range("A2:B10001"), 2, False)
  End If
End Sub


非常にスマートなコードだと思います。

「可読性」も良いように思います。

ただ、Findは、少し処理速度が遅いようです、あくまで、Rangeのメソッドですので。

しかし、それは、VLookUpに比べてのことです。

実際に使用するにあたっての問題にはなりません。



5つのパターンを示しましたが、検索値に、9380として実行すると、検索されません。

検索列の9380のセルは文字列になっているのです。

文字列と数値の比較では、例え見た目が同じでも、不一致をおこします。


どちらも、数値である事が分かっていれば、いろいろ対処方法もあると思いますが、

上の表のように、数値・文字が混在の場合の場合に、

見た目の数値でも検索したい場合は、少し難しい事になります。


以下に、それを対処するコードのサンプルを示します。

Sub test6()
  Dim rtn
  Dim ary As Variant
  Dim var As Variant
  Dim i As Long
  ary = Range("A2:B10001")
  var = Range("D2").Value
  rtn = ""
  For i = LBound(ary, 1) To UBound(ary, 1)
    Select Case True
      Case IsNumeric(ary(i, 1)) And IsNumeric(var)
        If CDbl(ary(i, 1)) = CDbl(var) Then
          rtn = ary(i, 2)
          Exit For
        End If
      Case IsDate(ary(i, 1)) And IsDate(var)
        If CDate(ary(i, 1)) = CDate(var) Then
          rtn = ary(i, 2)
          Exit For
        End If
      Case Else
        If CStr(ary(i, 1)) = CStr(var) Then
          rtn = ary(i, 2)
          Exit For
        End If
    End Select
  Next
  If rtn = "" Then
    Range("E2") = "なし"
  Else
    Range("E2") = rtn
  End If
End Sub


あくまで1例です、記述方法はいろいろ考えられます。

数値、日付、文字の3パターンに対応させています。

ブール型等もあり、これでも完全ではありませんが、通常はこれでなんとかなるでしょう。


Cdblは、倍精度浮動小数点実数型への型変換をする関数です。

Cdateは、日付型へのデータ変換をする関数です。

型変換をする関数は、データ型毎に存在します。

まあ数値として比較するだけなら、Cdblで通常は十分ですよね。


処理速度は?との疑問もでますが、

Test5のFindとほぼ同程度の処理速度です。(1000ループで計測しました。)

以前にも解説しましたが、配列に入れての処理は、セルの直接操作よりはるかに高速です。


通常に使用する場合は、test2かtest5になるでしょう。

型の問題があるなら、test6のように、配列を使って処理する事を考える必要があります。


もちろん、元のシートを正しく編集することが王道だとは思います。

しかし、外部データを受け取っての自動処理の場合は、いろいろ工夫する必要が出てきます。



WorksheetFunctionには、ワークシートで使用できる関数の大部分が入っています。


あくまで大部分です、全てではありません。


何が無いかと言うと・・・よく分かりません。


例えば、OFFSETなどは無いようです。


もっとも、VBAではRangeにOffseプロパティもありますし、ロジックで対応できるので必要ありません。


もちろん、Marchは使えます。


Matchは、VLookUpと同様に、検索値が無いとエラーになりますので、同様のエラー処理が必要です。


その他、ワークシートで使った事のある関数なら、


使用方法は同じなので、直ぐに理解できると思います。


WorksheetFunctionは、間違いなく処理速度は速いです。


これを活用しない手はありません。



今回はこの辺までにして、次回はどうしましょうか。


もう1回くらい、復習をかねて、何かやりましょうかね。





同じテーマ「エクセル顧客管理」の記事

第23回.納品書を作成、商品情報を取得(1)
第24回.納品書を作成、商品情報を取得(2)
第25回.納品書を作成、商品情報を取得(3)
第26回.WorksheetFunctionについて
第27回.RangeとCellsの深遠
第28回.納品書データをデータベース化(1)
第29回.納品書データをデータベース化(2)
第30回.配列の使い方について
第31回.売上一覧(伝票合計の一覧)を作成(1)
第32回.売上一覧(伝票合計の一覧)を作成(2)
第33回.売上一覧より納品書を作成


新着記事NEW ・・・新着記事一覧を見る

ExcelマクロVBA入門目次|エクセルの神髄(2024-03-20)
VBA10大躓きポイント(初心者が躓きやすいポイント)|VBA技術解説(2024-03-05)
テンキーのスクリーンキーボード作成|ユーザーフォーム入門(2024-02-26)
無効な前方参照か、コンパイルされていない種類への参照です。|エクセル雑感(2024-02-17)
初級脱出10問パック|VBA練習問題(2024-01-24)
累計を求める数式あれこれ|エクセル関数応用(2024-01-22)
複数の文字列を検索して置換するSUBSTITUTE|エクセル入門(2024-01-03)
いくつかの数式の計算中にリソース不足になりました。|エクセル雑感(2023-12-28)
VBAでクリップボードへ文字列を送信・取得する3つの方法|VBA技術解説(2023-12-07)
難しい数式とは何か?|エクセル雑感(2023-12-07)


アクセスランキング ・・・ ランキング一覧を見る

1.最終行の取得(End,Rows.Count)|VBA入門
2.RangeとCellsの使い方|VBA入門
3.セルのコピー&値の貼り付け(PasteSpecial)|VBA入門
4.繰り返し処理(For Next)|VBA入門
5.変数宣言のDimとデータ型|VBA入門
6.ブックを閉じる・保存(Close,Save,SaveAs)|VBA入門
7.並べ替え(Sort)|VBA入門
8.条件分岐(IF)|VBA入門
9.セルのクリア(Clear,ClearContents)|VBA入門
10.マクロとは?VBAとは?VBAでできること|VBA入門




このサイトがお役に立ちましたら「シェア」「Bookmark」をお願いいたします。


記述には細心の注意をしたつもりですが、
間違いやご指摘がありましたら、「お問い合わせ」からお知らせいただけると幸いです。
掲載のVBAコードは動作を保証するものではなく、あくまでVBA学習のサンプルとして掲載しています。
掲載のVBAコードは自己責任でご使用ください。万一データ破損等の損害が発生しても責任は負いません。



このサイトがお役に立ちましたら「シェア」「Bookmark」をお願いいたします。
本文下部へ