
おせわになっております。
Findメソッドを用いて、先頭から順に値を検索しようとしています。
Set rngSearch = rngList.Find("ゴルフ", rngSearch, , xlPart)
↑
このような方法で、該当するものを一つ一つ探そうとしています。
つまり、仮に一列目で見つかったら、次は二列目以降から探そうと
しています。
FindNextなどを使用しないのは、連続で求めるためではなく、
ボタンを押したときに一つずつ検索するからです。
しかし、この書式ではスタート地点にした、次のセルから検索する
はずが、スタート地点に指定したセルから検索してしまい、
何度行っても同じセルばかりを検索して返してしまいます。
Offsetなどで一行ずつずらしても、同じ場所からしか検索が
始まりません。
これはなぜなのでしょうか?
念のため、他のメソッドなどでは決してrngSearch は代入等の
操作はしておりません。
ちなみに、同じメソッドの中で同じ書式を繰り返すと
Set rngSearch = rngList.Find("ゴルフ", rngSearch, , xlPart)
MsgBox rngSearch.Value
Set rngSearch = rngList.Find("ゴルフ", rngSearch, , xlPart)
MsgBox rngSearch.Value
Set rngSearch = rngList.Find("ゴルフ", rngSearch, , xlPart)
MsgBox rngSearch.Value
Set rngSearch = rngList.Find("ゴルフ", rngSearch, , xlPart)
MsgBox rngSearch.Value
…
うまくいくようなのです。一度でもメソッドを抜けるとうまくいか
なくなるような感じです。
以上、わかりづらい説明で大変申し訳ありませんが、なにとぞお願い
致します。
No.5ベストアンサー
- 回答日時:
pulsaです
No.3の方のおっしゃるとおり、No.1の方への返答で示されたコード
>Set rngList = .UsedRange.Columns(7)
では、7列目しか検索対象になっていません
これが、列が移動しない原因でしょう
簡単に言うと
Columns(7).Select
Set rngSearch = Selection.Find(stKeyword, rngSearch, , xlPart, xlByRows, xlNext)
と変わりません
Set rngList = .UsedRange
で良いと思います(.UsedRangeが実際はなんなのか、は新たな謎ですが^^;)
他の部分はきちんとできているようなので、これだけで目的の動作が可能なはずです
あとは、エラーをどうするかです
今回の場合、同じRangeが検索結果=他に見つかっていない はエラーです
つまりNothing以外に、同じRangeが検索結果もエラーとして拾う必要があります
対応は簡単でしょう
検索結果をいきなりrngSearchにセットするのではなく、別な変数に入れておいて、『Is』でrngSearchと比較し、結果がFalseであれば、その時点でrngSearchにセットすればいい事です
コードを示します
Dim FindRange As Range
Set FindRange = rngList.Find(stKeyword, rngSearch, , xlPart, xlByRows, xlNext)
If Not (FindRange Is Nothing) And Not (FindRange Is rngSearch) Then
Set rngSearch = FindRange
Call review(rngSearch.Offset(0, -4))
End If
返答されたコードを変形しています
Exit Subをそこかしこで使うのが好きでないので、Notで反転しています
And を分解すれば、見つからない時と同じRangeを取ってきた時の動作を、別にする事ができます
この回答への補足
回答していただいた皆様方、何度もありがとうございます。
私の説明の悪さで誤解をさせてしまい、本当に申し訳ありません。
まず、私の表現で勘違いしていまして、列と行を間違えていました。
要は、縦一行の中で検索したいため、特定の七列目のみで検索を
かけています。その為、余計なColumnに検索が移らぬよう、Columns(7)
で絞り込みをしています。
その処理の中で、いちばん上のセルから検索し、仮に二番目に
見つかったら、次は三番目のセルから再び検索…ということを
行っているつもりです。
ためしに、検索をする先頭セルを、下に一つずらして処理させて
みると、一回目はうまくいって次のセルに移るのですが、二回目以降は
やはり動かずに同じセルばかり拾ってきてしまいます。
…これは何となくですが、なんか固定で『2』行目から検索を
始めているような感じに思えます…が、それはただの
思いすごしでしょうか^^;
Findメソッドの説明には、二番目の引数、Afterには、そこで指定した
『次のセル』から検索とありますので、その通りで行くと、コードとしては間違っていないとは思ったのですが…、うまくいきませんでした。
一応Offsetして確かめてみたコードを再度掲載します。
たびたびすみませんが、再びお力添えを何卒お願いいたします。
'フォーム初期化時
With ThisWorkbook.Worksheets("Data")
Set rngList = .UsedRange.Columns(7)
Set rngSearch = rngList.Cells(1, 1)
End With
Private Sub searchKeyword()
If (Me.fldSummary.Text = "") Then
Exit Sub
End If
Dim stKeyword As String
stKeyword = Me.fldSummary.Text
With ThisWorkbook.Worksheets("Data")
' Set rngSearch = rngList.Find(stKeyword, rngSearch, , xlPart, xlByRows, xlNext)
Dim rngBuff As Range
Set rngBuff = rngList.Find(stKeyword, rngSearch.Offset(1, 0), , xlPart, xlByRows, xlNext)
If (rngBuff Is Nothing) Then
MsgBox "見つからないよ"
Exit Sub
End If
Set rngSearch = rngBuff
'Call review(rngSearch.Offset(0, -4))
End With
End Sub
皆様、色々ありがとうございました。
本来は仕様とは違うのですが、Columns(7)を消したところ、
とりあえずスタートポイントの移動は確認できました。
一行単位での動作はいまだにおかしいままですが、とりあえず
目的は達成できたので、この質問は終了させていただきます。
本当にありがとうございました。
No.4
- 回答日時:
質問と補足から、以下のような話でしょうか?
何かすると(たとえばシートの検索のコマンドボタンを押すと)、ユーザーフォームを表示する。
テキストボックスとコマンドボタンがある。
テキストを入力してコマンドボタンを押すと次々に検索する。
違ったら読み飛ばしてください。
ユーザーフォームのモジュール部に、確認用などで若干追加しましたが、補足で書いてあるプログラムをできるだけそのまま書いてみました。
ユーザーフォームにはテキストボックス(fldSummary)とコマンドボタン(CommandButton1)があるとします。
で、動いてるみたいなんですが・・・
どこか間違ってますか?
Option Explicit
Dim rngSearch As Range
Dim rngList As Range
Private Sub UserForm_Activate()
With ThisWorkbook.Worksheets("Data")
.Activate '後で確認のためselectするので一応Activateにしておきます
Set rngSearch = .UsedRange.Columns(7).Cells(1, 1)
Set rngList = ThisWorkbook.Worksheets("Data").UsedRange.Columns(7)
End With
End Sub
Private Sub CommandButton1_Click()
searchKeyword
End Sub
Private Sub searchKeyword()
If (Me.fldSummary.Text = "") Then
Exit Sub
End If
Dim stKeyword As String
stKeyword = Me.fldSummary.Text
With ThisWorkbook.Worksheets("Data")
Set rngSearch = rngList.Find(stKeyword, rngSearch, , xlPart, xlByRows, xlNext)
If (rngSearch Is Nothing) Then
MsgBox "ありません" '無かった場合、一応黙っているのは何なので
Set rngSearch = ThisWorkbook.Worksheets("Data").UsedRange.Columns(7).Cells(1, 1) 'Nothingのままだと次の検索でエラーになるので
Exit Sub
End If
'Call review(rngSearch.Offset(0, -4))
rngSearch.Select 'とりあえず選択部を表示
End With
End Sub
この回答への補足
fumufumu_2006さん、ありがとうございます。
ほぼ、記述してある通りです。
この通りでうまくいくはずなのですが…。
うまくいきません。
何かお心当たりがありましたら、ぜひお力添えをお願いいたします。
No.3
- 回答日時:
最初の質問文で
>仮に一列目で見つかったら、次は二列目以降から探そうとしています。
とあります。
ANo.1の補足に
>それ以外の場所では、前回記述したメソッド以外では、
>rngList、及びrngSearchともに使用しておりません。
とあります。
rngListが固定なら、常に 7 列目しか検索してくれません。
7列目に検索値が1つしかないという事は考えられないのですか?
>ちなみに、同じメソッドの中で同じ書式を繰り返すとうまくいくようなのです。
と書いてありますので、そのケースはないのかもしれませんが念の為。
また、検証するにはごくシンプルなコードでテストしてみる事が必要でしょう。
例えば、メソッドを抜けても次検索できる例をANo.1で提示しました。
新規Bookに適当なデータを入れて、標準モジュールに置いて試してみると良いと思います。
うまく動くようなら、問題のコードでは変数の初期化が関係している可能性が大きいと思うのですが。
(変数の初期化は明示的に = Nothing とするだけでなく、何らかのタイミングで破棄される事も含みます)
[VBA] Public 宣言された変数の有効期間
http://support.microsoft.com/kb/408871/ja
ただ、rngSearch が初期化されてNothingであれば検索時にエラーがかかるはずなのです。
With ThisWorkbook.Worksheets("Data")
MsgBox rngSearch.Address
Set rngSearch = rngList.Find(stKeyword, rngSearch, , xlPart, xlByRows, xlNext)
(エラー制御されていなければ。)
もし、変数初期化が関係しているなら、検索結果アドレスをどこかに記録しておくようにすれば良いです。
それは
Private Sub UserForm_Initialize()
With ThisWorkbook.Worksheets("Data")
Set rngSearch = .UsedRange.Columns(7).Cells(1, 1)
Me.Tag = rngSearch.Address
:
Private Sub searchKeyword()
If (Me.fldSummary.Text = "") Then
Exit Sub
End If
Dim stKeyword As String
stKeyword = Me.fldSummary.Text
With ThisWorkbook.Worksheets("Data")
Set rngSearch = rngList.Find(stKeyword, .Range(Me.Tag), , xlPart, xlByRows, xlNext)
If (rngSearch Is Nothing) Then
Exit Sub
End If
Me.Tag = rngSearch.Address
:
こんな感じで、UserFormのTagプロパティを使っても良いですし、
ダミーな非表示シートのセルにアドレスを書き込んだりしても良いかと思います。
この回答への補足
end-uさん、たびたびありがとうございます。
上記の方法でも試してみましたが、やはりうまくいきません。
どうしても二行目で止まってしまいます(二行目に該当データがあると
ずっと二行目ばかり返す)。
ちなみに、行と列の言葉を組みちがえていました。
大変申し訳ありません。
引き続き、お力添えをいただければ幸いです。
No.2
- 回答日時:
Findは、Rangeのプロパティのひとつと考えると良いと思います
つまり、探すんではなく、有るところを教えてくれます
これが、戻り値がRange『Object』で帰る理由です(無いときはNothing)
ご質問の場合、No.1の方がおっしゃるとおり
これだけの情報では判断が難しいです
上に書いたとおり検索範囲のRangeの内、最初に該当するRangeを返すので、ご質問の内容は最初に見つけた"ゴルフ"のRangeを返します
つまりセルを教えてくれるだけ、です
ですので、実行中のメソッドで複数呼ぶ(この場合、rngSearchが生きてる間と解釈してもOK)と成功するのに、メソッドを抜けると上手く行かないとなります
理由は rngSearch がクリアされる為で、Findの引数でAfterが省略されているときは、指定範囲の左上から検索するとなっています。(因みにNullの場合も左上が検索開始位置になる)
回避方法はいくつかありますが、まず
rngSearch に値が入った直後に、Actveにする方法があります
ただ、この方法は当然、該当セルが存在しない場合、エラーです
ですので、次のようにします
おそらく現状 rngList には Cells か、ざっくりしたRange(行列複数)が指定してあるように思いますが、質問からすると列ごとに検索していくようですので、それであれば rngList を検索が成功するたびに、1列ずつずれるように指定するほうがいいでしょう
コードを示します
Dim rngSearch
Set rngSearch = Columns(1).Find("ゴルフ", , , xlPart) '一回目
If Not rngSearch Is Nothing Then
Set rngSearch = Columns(2).Find("ゴルフ", rngSearch, , xlPart) '二回目
If Not rngSearch Is Nothing Then
Set rngSearch = Columns(3).Find("ゴルフ", rngSearch, , xlPart) '三回目
・
・
・
End If
End If
ただ、これでは面白くありませんので
Dim rngSearch
Dim iCnt As Integer
Set rngSearch = Columns(1).Find("ゴルフ", , , xlPart) '一回目
If Not rngSearch Is Nothing Then
MsgBox rngSearch.Value
For iCnt = 2 To Range("A1").CurrentRegion.Columns.Count
Set rngSearch = Columns(iCnt).Find("ゴルフ", , , xlPart) '二回目以降
If Not rngSearch Is Nothing Then
Exit For
Else
MsgBox rngSearch.Value
End If
Next iCnt
End If
Findは意外と難しく、ハマるんですが、Forなんかよりかなり高速化できますので、使いこなせれば強力な武器になります
がんばれ!
この回答への補足
pulsaさん、ありがとうございます。
1の方にもお返事をしたのですが、rngList,rngSearchは外部で
宣言し、Form_Loadでその値を設定した後、他では決して
操作していません。
フォームを閉じたりしない限りは、外部変数は初期化されないと
思うのですが…。
いただきましたサンプルを元に、いろいろと調べてみますが、
もう少しお力添えいただければ幸いです。
念のため、メソッドを書き込みます。
Private Sub searchKeyword()
If (Me.fldSummary.Text = "") Then
Exit Sub
End If
Dim stKeyword As String
stKeyword = Me.fldSummary.Text
With ThisWorkbook.Worksheets("Data")
Set rngSearch = rngList.Find(stKeyword, rngSearch, , xlPart, xlByRows, xlNext)
If (rngSearch Is Nothing) Then
Exit Sub
End If
Call review(rngSearch.Offset(0, -4))
End With
End Sub
以上、よろしくお願い申し上げます。
No.1
- 回答日時:
こんにちは。
それだけの情報では判断が難しいです。
最初の
>Set rngSearch = rngList.Find("ゴルフ", rngSearch, , xlPart)
引数Afterの rngSearch はどのようにSetされているのですか?
Option Explicit
Dim rngSearch As Range
Dim rngList As Range
Sub try()
If rngList Is Nothing Then
Set rngList = ActiveSheet.UsedRange
End If
If rngSearch Is Nothing Then
Set rngSearch = rngList.Cells(1)
End If
Set rngSearch = rngList.Find("*", rngSearch, , xlPart)
MsgBox rngSearch.Value
End Sub
もし、こういう使い方なら、モジュールレベルの変数が初期化されるような処理がどこかにないですか?
この回答への補足
end-uxyさん、ありがとうございます。
説明が不足しており、大変申し訳ありません。
rngList及び、rngSearchは、Form_Loadの時点で
外部変数としてセットしています。
With ThisWorkbook.Worksheets("Data")
Set rngSearch = .UsedRange.Columns(7).Cells(1, 1)
Set rngList = .UsedRange.Columns(7)
End With
上記の記述で、Columns一行分を範囲として取得し、その先頭を
rngSearchの起点としてセットしています。
それ以外の場所では、前回記述したメソッド以外では、
rngList、及びrngSearchともに使用しておりません。
以上、なにとぞお願い申し上げます。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Excel(エクセル) 日付で矢印マクロ 4 2023/07/25 16:47
- Visual Basic(VBA) エクセルVBAのコードで質問です。 下のコードはJ16の文字列をB3を起点とする範囲から探して、見つ 5 2023/04/07 11:07
- Visual Basic(VBA) オブジェクトが見つかりません 1 2023/06/24 19:43
- Excel(エクセル) マクロで特定日より1日前の日を求めたい 6 2022/05/08 09:23
- Excel(エクセル) マクロで行を追加、削除すると行位置がずれますが、解決方法はありませんか?。 5 2022/05/28 16:03
- Visual Basic(VBA) シフト表のコマで「ブロック」されている前の時間の「出」を同一列の「休」と入れ替えたいがふぇきません。 2 2023/08/02 18:49
- Excel(エクセル) 指定文字列が該当するA列をアクティブセルにするには 3 2022/08/17 13:18
- Visual Basic(VBA) Excle VBA Findメソッドについて 3 2022/07/15 13:56
- Excel(エクセル) 製品番号での整列と、検索に関して 3 2023/06/28 19:20
- Visual Basic(VBA) VBAで実行時エラー'424' オブジェクトが必要ですと出る 2 2022/10/07 09:25
このQ&Aを見た人はこんなQ&Aも見ています
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
エクセルVBAで、条件に一致する...
-
eclipse-Tomcatでのデバッグに...
-
FEM解析の読み方は?
-
final修飾子を使っているのに、...
-
Application.Wait の参照設定
-
Labelコントロールに数字を代入...
-
execute()
-
エクセルVBAで、ユーザーフォー...
-
配列のメソッド
-
『増加する』メソッド名は?
-
エクセルVBAにおけるON TIMEメ...
-
mainメソッドのthrows節で設定...
-
C#.net Define文
-
drawStringで文字間隔の調整
-
0歳児の指しゃぶりに関して
-
ランダム画像のjsをカスタマイ...
-
CALLされていないメソッドを見...
-
処理内容がほぼ同じメソッドの...
-
worksheets & rows メソッドは...
-
boolean型のフィールドとゲッタ...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
エクセルVBAで、条件に一致する...
-
【sendkeysメソッドが動かずに...
-
mainメソッドのthrows節で設定...
-
VBA コピーが出来ません…!
-
DataGridViewでセルクリックイ...
-
コマンドプロンプト実行後に画...
-
0歳児の指しゃぶりに関して
-
エクセルVBAにおけるON TIMEメ...
-
javascriptからjavaを呼び出したい
-
配列のメソッド
-
CALLされていないメソッドを見...
-
final修飾子を使っているのに、...
-
Labelコントロールに数字を代入...
-
VBPをダブルクリックするとたま...
-
ウィンドウを最前面にできません
-
処理内容がほぼ同じメソッドの...
-
Application.Wait の参照設定
-
C#.net Define文
-
C# 演算 最大値 最小値 表現の仕方
-
Excel VBA でExcelを終了したい...
おすすめ情報