エクセル顧客管理 | 第26回.WorksheetFunctionについて | Excelマクロを駆使したカスタマイズ可能なエクセル顧客管理、エクセルVBAの学習教材



最終更新日:2014-11-11

第26回.WorksheetFunctionについて


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


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


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


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


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


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


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


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


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



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



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

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


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


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


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


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

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回くらい、復習をかねて、何かやりましょうかね。






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

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

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

SUMIFの間違いによるパフォーマンスの低下について|エクセル関数超技(6月17日)
条件式のいろいろな書き方:TrueとFalseの判定とは|ExcelマクロVBA技術解説(6月15日)
空白セルを正しく判定する方法2|ExcelマクロVBA技術解説(5月6日)
フルパスをディレクトリ、ファイル名、拡張子に分ける|ExcelマクロVBA技術解説(4月15日)
テキストボックスの各種イベント|Excelユーザーフォーム入門(4月9日)
フォルダ(サブフォルダも全て)削除する、Optionでファイルのみ削除|ExcelマクロVBAサンプル集(4月4日)
最後の空白(や指定文字)以降の文字を取り出す|エクセル関数超技(3月26日)
先頭の数値、最後の数値を取り出す|エクセル関数超技(3月26日)
Excelファイルを開かずにシート名をチェック|ExcelマクロVBAサンプル集(3月23日)
数式の参照しているセルを取得する|ExcelマクロVBAサンプル集(3月18日)

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

1.最終行の取得(End,Rows.Count)|ExcelマクロVBA入門
2.RangeとCellsの使い方|ExcelマクロVBA入門
3.Range以外の指定方法(Cells,Rows,Columns)|ExcelマクロVBA入門
4.変数とデータ型(Dim)|ExcelマクロVBA入門
5.徹底解説(VLOOKUP,MATCH,INDEX,OFFSET)|エクセル関数超技
6.セルのコピー&値の貼り付け(PasteSpecial)|ExcelマクロVBA入門
7.定数と型宣言文字(Const)|ExcelマクロVBA入門
8.セルの参照範囲を可変にする(OFFSET,COUNTA,MATCH)|エクセル関数超技
9.CSVの読み込み方法|ExcelマクロVBAサンプル集
10.ひらがな⇔カタカナの変換|エクセル基本操作



  • >
  • >
  • >
  • WorksheetFunctionについて

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


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

    ↑ PAGE TOP