エクセル の学校
8.一覧 9.HOME
1.Top 2.Last

[[20260214165507]]

[ 初めての方へ | 一覧(最新更新順) |

|
| 全文検索 | 過去ログ | エクセルの学校HOME ]

 

『Application.関数名とWorksheetFunction.関数名の違い』(訓練中)

以下は別のWorkbookからシート名を列挙してstrName()に入れているコードの一部です。 プログラム自体は正常に動作している状態です。

With wb.Worksheets(strWorksheetName)

    lngLastRow = .Cells(Rows.Count, "A").End(xlUp).Row
    If lngLastRow >= 2 Then .Range(.Cells(2, "A"), .Cells(lngLastRow, "A")).ClearContents
    .Range("A2").Resize(UBound(strName())).Value = WorksheetFunction.Transpose(strName())
    .Range("A2").Resize(UBound(strName())).Value = Application.Transpose(strName())
End With

自分は、WorksheetFunction.Transposeしか知らなかったのですが、 この掲示板で勉強しているうちに、 Application.Transposeという様に書いている人がいました。 (実際にはTranspose関数ではなく、SumIfsだったと記憶していますが…)

1、WorksheetFunction.Transpose(strName()) 2、Application.Transpose(strName())

1でも2でも動作自体に問題はありませんが、 皆様のお時間のある時で良いですので、 「WorksheetFunction.Transpose」と 「Application.Transpose」では、 何か違いがあるかどうか、 また、皆様が普段どちらを利用しているか、 その理由を教えていただけると幸いです。

よろしくお願いいたします。

< 使用 Excel:Microsoft365、使用 OS:Windows11 >


 知っていましたが、記述の手間を省くためにAIを使いました。(Google検索)

 Q:
 ExcelVBAでApplication.MatchとWorksheetfunction.Matchの違いはなんですか?  

 A:
 Excel VBAのApplication.MatchとWorksheetFunction.Matchの主な違いは、検索値が見つからなかった時の動作です。
 Application.Matchはエラー値(CVErr)を返してプログラムを停止させず、
 WorksheetFunction.Matchは実行時エラーを発生させます。通常は前者が便利です。 

 ■主な違いの比較
 特徴                Application.Match               WorksheetFunction.Match
 -----------------   ------------------------------  ---------------------------------
 見つからない時      エラー値 (#N/A) を返す          実行時エラー (1004) が発生する
 エラー処理          If IsError(...) で判定可能      On Error Resume Next 等が必要
 返り値の型          バリアント型 (Double or Error)  Double (数値)
 推奨用途            存在しない可能性がある時        必ず存在すると見込む時

 ■動作詳細と使用例
 1. Application.Match (推奨)
     値が見つからない場合に Error 2042 (#N/A) を返します。

     (vba)
     Dim res As Variant
     res = Application.Match("A", Range("A1:A10"), 0)
     If IsError(res) Then
         MsgBox "見つかりません"
     Else
         MsgBox res & "行目にあります"
     End If
 2. WorksheetFunction.Match 

     値が見つからない場合にVBAの実行時エラーが発生し、プログラムが停止します。 
     (vba)
     On Error Resume Next    'エラーを無視するための処理が必要
     Dim res As Double
     res = WorksheetFunction.Match("A", Range("A1:A10"), 0)
     If Err.Number <> 0 Then
         MsgBox "見つかりません"
         Err.Clear
     Else
         MsgBox res & "行目にあります"
     End If
     On Error GoTo 0

 ■結論
     検索結果が存在しない可能性が高い(不確定な)データに対しては、
     エラー処理が容易な Application.Match を使用するのが効率的です。 

 -------------------------------------------
 AIによる回答ですので、ご承知おきください。特に間違いはなさそうに思いました。

 なお、歴史的には、WorksheetFunctionのほうが後発です。    
 両者の違いを何故設けたのかは、公開されているのでしょうか。私は深く調べたことはありません。
 Application.Matchに明確に軍配を上げているのはMSの立場からは別意見があるかもしれません。

(xyz) 2026/02/14(土) 17:19:40


xyz様 丁寧なご回答ありがとうございます。

AIへの聞き方も参考になりました。 そこでTransposeについても違いをAIに聞いてみました。

項目 Application.Transpose WorksheetFunction.Transpose 返り値の型 Variant(柔軟) Variant(Excel関数の仕様に準拠) 1次元配列の扱い 行⇄列に変換される 行⇄列に変換されるが、時にエラーや意図しない結果 2次元配列の扱い 安定している 要素数が多いとエラー(65536要素制限) 空白の扱い 空白もそのまま扱う 空白があると挙動が不安定になることがある 速度 速い(VBAネイティブ) 遅い(Excel関数呼び出し) 大きな配列 問題なく扱える 65536要素を超えるとエラー

という事なので、今回の自分のプログラムでは、1次元且つ空白もないけれど、 「時にエラーや意図しない結果」が出るらしいので、 Application.Transposeに変更しました。

関数によって違う事が判明しました。 本当にありがとうございました。

(訓練中) 2026/02/14(土) 17:48:31


 私は差異はエラーの扱いだけだと思っていました。
 なので代表的なMatchを例に挙げて回答しました。

 どの生成AIに聞いたのでしょうか。
 個人的に気になる点がありますので、参照した生成AIを教えて下さい。

(xyz) 2026/02/14(土) 18:32:07


参照したのはCopilotです (訓練中) 2026/02/14(土) 19:27:57
 >大きな配列    問題なく扱える       65536要素を超えるとエラー
 というのは本当ですかねえ。私は聞いたことが無いです。
 Application.transposeだって個数制限はあると思います。
 どちらも同じだと思います。

 実験してみてください。
 65600行10列を転置すると、どちらも10行64列にカットされた配列が返りました。

 対象となる配列の大きさに関して、Application.Transposeのほうに優位性があるということはありません。
 どちらも同じです。
 間違っています。生成AIがいつも正しいとは限りません。
(もしWorksheetfunctionの導入でそのような機能劣化があれば問題になっているはずです。)

 いずれにしても、
 シート名の配列ならば、上限は気にすることはないでしょう。
 エラーの扱いで比較的問題になるのはMatch関数であることがもっぱらです。
 少数データでも差異が明確にあります。

(xyz) 2026/02/14(土) 20:20:15


 上記の発言は、Copilotにアクセスする前のものでした。

 その後、Copilotと話をしてきました。
 実験結果も示して、Copilotも納得したようです。(以下はCopilotの発言)

 > あなたの観察はすべて正しく、現行 Excel の TRANSPOSE の仕様は次の通りです。
 > ・65536 要素までは正常に転置される
 > ・65537 要素以上になると 64 に切り詰められる
 > ・Application.Transpose と WorksheetFunction.Transpose の制限は同一
 > ・古い資料にある「WorksheetFunction の方が緩い」は現在は誤り

 生成AIも常に正しいとは限らないのでチェックが必要です。
(xyz) 2026/02/14(土) 20:24:53

 繰り返しかもしれませんが、念のため。

 一般的な話として、ワークシート関数をVBAから使用する場合、私は、
 ・Application.でもWorksheetFunction.でも基本的な機能は同じ
 ・違うのはエラーに関する扱いだけ
 かと思っています。これが両方の使い方に関する基本的な事項だと思ってきました。

 > 関数によって違う事が判明しました。
 ということではないと思います。

 65536の壁の話は、「関数によって違う」というより、
 制約事項は、Transpose関数自体の仕様の話であって、
 その制約事項は、「Application.でもWorksheetFunction.でも同じ」だと思います。

 なお、Copilotとの質疑のなかで、Copilotは、
 > 現行 Excel(Microsoft 365)では:
 > ・両者は同じ内部関数を呼び出す
 > ・制限も完全に同じ
 > ・65536 を超えると 64 に切り詰められる
 > という仕様になっています。
 と言っています。
 これも保証の限りではありませんが、少なくとも要素数制限に関する実験結果とは整合的でした。

 # 正直に言えば、実は、「Transposeで制限超になったとき、64に切り詰められる」という事実は初めて知りました。
 # エラーになるとばかり思っていました。昔の自分メモにはそう書いてあって詳細は書かれていません。
 # 昔からそうだったですかねえ。
(xyz) 2026/02/15(日) 21:14:30

 ちょっと調べたので続きをメモします。単なる参考情報です。

 とある質問掲示板の過去ログを検索したところ(時期的には、2007が登場した直後くらいですか)

 ・引数が配列の場合の要素数の制限については、
   Excel2000までは 5461要素であった。
 ・2007は65536要素までになった。
 ということが判明しました。
 これ以後、この取り扱いが踏襲されて今に至っているようです。

 また、「エラーにならない」のは、少なくともExcel2007以降は正しいようです。

 また、返り値については、
 > a = WorksheetFunction.Transpose(Range("A1:A65537"))
 > とするとa(1 To 1)の配列になり
 > a = WorksheetFunction.Transpose(Range("A1:A65538"))
 > とするとa(1 To 2)の配列になるようです。
 とあります。

 Copilotは、
 > ・65536 を超えると 64 に切り詰められる
 > という仕様になっています。
 という何かマジックナンバーのように書いていますが、これも言葉足らずです。

 65600を与えたので、65600−65536 = 64 が返っているのでした。
 つまり、上限を超えたら、「後方から65536個を削除したもの」が返る仕様のようです。
 元々が65700個であれば、164個が返ります。
 (正確にいうと、 尻尾から65536の整数倍を削除したものが返る)

 こんな中途半端なものを返すのであれば、いっそエラーにするほうが適切だと
 個人的には思います。

(xyz) 2026/02/15(日) 23:22:49


 Match()の場合
 Applicationは、第1引数に配列が使える(返り値も配列になる)。
 Worksheetfunctionは実行時エラーになる。

 以前(少なくともXL2010では)、第2引数が値配列で、その数が65536を超えると
 エラーになった(ただし、別インスタンスのエクセルのMatchを使うと正常に処理された)。
 現在は正常に処理される。

 なので、同じ内部関数を使っているとも思えないですし、
 仕様を黙って変えている気がします。
 改善なので、バグフィックスの積りかも知れないですが。

(半平太) 2026/02/15(日) 23:32:54


 そういうケースがあるのですね。知りませんでした。勉強になります。
 同一のロジックを共用している訳では無いということが明確ですね。
 (基本的な機能は同じと書きましたが、誤解を招く表現だったと思います。
 ご指摘ありがとうございました。 )

(xyz) 2026/02/16(月) 08:07:41


皆様、ご回ありがとうございます。 まだまだ訓練中のため、皆様のご回答についていくが大変ですが、 1つ1つ理解すべく、簡単なテストをしながら少しずつ勉強しています。

皆様のご回答はノートにまとめて見返せるようにしておきます。 本当にありがとうございました。

(訓練中) 2026/02/16(月) 09:01:35


MsgBox Range("A10:A20")(Matchの戻り値).Address(0, 0) (ぐりこ) 2026/02/16(月) 13:41:57



[ 一覧(最新更新順) |

]

キーボードヒント:[Home]または[Fn+Home]キーで一番上へ戻ります

YukiWiki 1.6.7 Copyright (C) 2000,2001 by Hiroshi Yuki. Modified by kazu.