[ 初めての方へ | 一覧(最新更新順) | 全文検索 | 過去ログ ]
『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 >
(なお、戻り値が定義されていないので、ユーザー定義関数になっていない点もあります。)
(γ) 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
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
[ 一覧(最新更新順) ]
YukiWiki 1.6.7 Copyright (C) 2000,2001 by Hiroshi Yuki.
Modified by kazu.