[[20200128223934]] 『VBAのFindNextについて』(きんぐ) ページの最後に飛ぶ

[ 初めての方へ | 一覧(最新更新順) | 全文検索 | 過去ログ ]

 

『VBAのFindNextについて』(きんぐ)

現在、VBAを勉強中の者です。
過去に類似質問があれば申し訳ありません。

Find・FindNextを用いて検索しようとしています。このコードは2回検索して
、その結果(文字列)を取得するものですが上手くいきません。
コード1の様に、メッセージボックスに表示させると期待した値が返ってきます
同じような処理をコード2でも行っているはずですが、セル内で=Test(A)としたときの結果が#VALUE!となります。

どうすれば期待する値がセルに入るでしょうか。また何が原因でしょうか。
よろしくお願いいたします。

以下、コードです。シート名・Rangeの範囲は実際の値と異なります。
"A"はTest(A)の引数で与える文字列を直接書きこんでいます。

コード1
Sub main()

    Dim myRange As Range
    Dim str As String

    Set myRange = ThisWorkbook.Worksheets("1").Range("A1:A10")
    Set rngSearch = myRange.Find(What:="A", LookAt:=xlWhole)

    Set rngSearch = myRange.FindNext(rngSearch)
    str = rngSearch.Value
    MsgBox str
End Sub

コード2
Public Function Test(A) As String

    Dim myRange As Range
    Dim str As String

    Set myRange = ThisWorkbook.Worksheets("1").Range("A1:A10")
    Set rngSearch = myRange.Find(What:=A, LookAt:=xlWhole)

    Set rngSearch = myRange.FindNext(rngSearch)
    str = rngSearch.Value
End Function

< 使用 Excel:Excel2016、使用 OS:Windows10 >


「Excel のユーザー定義関数の制限について」
https://support.microsoft.com/ja-jp/help/170787/description-of-limitations-of-custom-functions-in-excel
に、制約事項があります。こちらを確認して下さい。

(なお、戻り値が定義されていないので、ユーザー定義関数になっていない点もあります。)

(γ) 2020/01/28(火) 23:38


 >"A"はTest(A)の引数で与える文字列を直接書きこんでいます

 それならば
 >セル内で=Test(A)
 ではなく =Test("A") では?
    
(チオチモリン) 2020/01/28(火) 23:52

チオチモリンさん

たしかにそうなってしまいますね。すみません、説明ミスです。
誤:"A"はTest(A)の引数で与える文字列を直接書きこんでいます
正:AはTest(A)の引数で与える文字列を直接書きこんでいます

また説明不足でしたがコード1・2共に、Findの時点では期待する値がセルに入ることを確認しており、引数の問題ではないと思います。

(きんぐ) 2020/01/29(水) 00:11


シート上で使う関数は作ったことほぼないけど、、、、

Public Function Test(A) As String

    Dim myRange As Range
    Dim rngSearch As Range
    Dim str As String

    Stop
    Set myRange = ThisWorkbook.Worksheets("1").Range("A1:A10")
    Set rngSearch = myRange.Find(What:=A, LookAt:=xlWhole)
    str = rngSearch.Value
    Set rngSearch = myRange.FindNext(rngSearch)
    str = str & vbLf & rngSearch.Value
    Test = str
End Function

う〜ん。セル範囲を変数に入れるとこで終わっちゃいますね。
そこがすでに「制約事項」なのかな?
(まっつわん) 2020/01/29(水) 10:10


 >セル内で=Test(A)としたときの結果が#VALUE!
 となるのは
 コード2内の
 >    Str = rngSearch.Value
 がエラーになるためです。
 何故エラーになるかというと
 rngSearchがNothingになるからです
 何故Nothingになるかというと
 γさんが張られたリンク先の説明にあるように

 ワークシートのセル内の数式から呼び出されるユーザー定義関数では、Microsoft Excel の環境を変更できません
。つまり、このような関数では次の処理が実行できません。
 プロパティの設定およびほとんどのメソッドの実行。

 だからです。
 要するにユーザー定義関数として使用するSUBプロシージャーでは FindNext は使えないということです。

 Public Function Test(A) As String

     Dim myRange As Range
     Dim Str As String

     Set myRange = ThisWorkbook.Worksheets("1").Range("A1:A10")
     Set rngSearch = myRange.Find(What:=A, LookAt:=xlWhole)
     Debug.Print rngSearch Is Nothing
     Set rngSearch = myRange.FindNext(rngSearch)
     Debug.Print rngSearch Is Nothing
     Str = rngSearch.Value

 End Function
 Sub TestSUB()
     Call Test("A")
 End Sub

(チオチモリン) 2020/01/29(水) 10:22


ほむ。
基本セル範囲は引数に渡したセル範囲しかセル範囲は使えない。
渡したセル範囲の一部のセルの値(Valueプロパティの値)を読むことすらできない。
という事なんですねー。。。。

Public Function Test(key As Variant, rngArea As Range) As Variant

    Dim v
    Dim i As Long
    Dim flg As Boolean
    Dim s As String

    v = rngArea.Value
    For i = LBound(v, 1) To UBound(v, 1)
        If v(i, 1) Like "*" & key & "*" Then
            s = s & "_" & v(i, 1)
            If flg Then Exit For
            flg = True
        End If
    Next
    Test = Mid(s, 2)
End Function

じゃぁ、ユーザー定義関数をシート上で使う場合、
セル範囲を渡す時は型の指定はRangeで渡す意味がないということかな?
調べれば何かしら情報に当りそうだけども。。。。(独り言)
(まっつわん) 2020/01/29(水) 10:45


 なんとなくなんだけど、ユーザー定義でFindは使えなかったようなきがする?
 97時代作ってはみたものの何も返ってこなかったような・・・。
 そん時は、数式でセルもしくはシート全体をまさぐるように全てを探すのは、ちょっと無理が
 あるのかな?
 で、落ち着いたような。
(BJ) 2020/01/29(水) 11:44

ユーザー定義関数には結構制約がありますね。

例えば、2010から導入されたDisplayFormatプロパティは、
条件付き書式の判定結果による書式を得るのに使える便利なものですが、
ユーザー定義関数の中では使えませんね。

また、最近、別の掲示板の質問であったのは、こんな例でした。
ユーザー定義関数中で、CurrentRegionが正常動作しない、というもの。
回りに連続した隣接セルがあるのに、指定した単一セルを返してしまう。
これは明示的に、幅広のセル範囲を指定することで回避ができますが。

なお、今回の例で言えば、FindNextというメソッドが機能しないわけですが、
じゃなんで Findはそれなりの結果を返すの?と聞かれると明確には答えられない。
MS社に聞いて、ということになるような感じです。
(γ) 2020/01/29(水) 12:07


 >プロパティの設定およびほとんどのメソッドの実行。
 全面否定はしていない。
 限定列挙もしていない。

 現象からは、FindはOK、FindNextはNG

 なので、Unionを使って、第一回目にヒットしたセルを除くRangeオブジェクトをなんとかして取得し、
 再度、Findメソッドを実行すればいい。---私はやる気しないですけども。

(半平太) 2020/01/29(水) 12:34


皆様、回答ありがとうございました。
まさかアプリ側の問題(仕様?)と思わなかったので沼にはまっていました。
別の手段をとって目的を達成できました。
(きんぐ) 2020/01/30(木) 22:26

コメント返信:

[ 一覧(最新更新順) ]


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