こんにちは、趣味でエクセルVBAを勉強し始めたのですが、
タイトルの方法でうまくいかずに困っています。
教えていただけますと嬉しいです。
<やりたいこと>
シート1のセルA1に入力したキーとなる文字列で、シート2~シート5を検索して、
ヒットしたセルの4列横の文字列を、
シート1のセルA3から下に書き込んでいきたいです。
<現在>
色々と試行錯誤して、コードを書いたのですが、無限ループになってしまいます。
エクセルVBAの本の通りに書いたつもりです。
何度見てもコードは間違えていないように見えるのですが、
必ずエラーになってしまいます。
自分では思いこんでいて気づかない間違いなどがあるのかと思い、
掲示板に書かせてもらいました。
お分かりになる方がいらっしゃったら、教えてください。
よろしくお願いいたします。
エラーになる箇所は、下のコードのうち、◆の箇所です。
<コード>
Sub checksheet()
Dim i, j As Integer
Dim sheetname As String
Dim key As String
Dim myrange As Range
Dim myrange2 As Range
Dim myaddress As String
Dim strrange As Range
key = Worksheets(1).Cells(1, 1).Value
sheetname = ActiveSheet.Name
j = 3
For i = 2 To Worksheets.Count
sheetname = Worksheets(i).Name
Worksheets(sheetname).Select
Set myrange = Range("A1").CurrentRegion
myrange.Offset(1).Resize(myrange.Rows.Count - 1).Select
Set srtrange = Range("A2:A10")
Set myrange2 = srtrange.Find(what:=key, LookIn:=xlValues)
If Not myrange2 Is Nothing Then
Do
Worksheets(1).Cells(j, 1).Value = myrange2.Offset(, 4).Value
◆Set myrange2 = srtrange.FindNext(after:=myrange2)
j = j + 1
If j = 100 Then
’無限ループ対策
Exit Sub
End If
Loop Until myrange2.Address = myaddress
Else
End If
Next i
End Sub
No.3
- 回答日時:
基本的なことですが、
Dim key As String
Dim myrange As Range
Dim myrange2 As Range
Dim myaddress As String
Dim strrange As Range
わざわざ、変数を宣言しているのですから、ここに工夫をして、大文字・小文字を組み合わせましょう。
そうすれば、変数名のミスに気が付きます。最後には、
Option Explicit
を入れれば、確実に分かります。
そして、エラーの原因は、strRange でしょうけれども、
◆Set myrange2 = srtrange.FindNext(after:=myrange2)
srt となって、str ではありません。それら(複数)を直したらエラーは消えます。
それと、
If j = 100 Then
'無限ループ対策
Exit Sub
End If
Find メソッドで無限ループ対策というのは、ほとんどないことですが、万が一に必要な時は、
DoEvents を用いて、Escape ブレークを入れられるようにします。
>Set srtrange = Range("A2:A10")
>Set myrange2 = srtrange.Find(what:=key, LookIn:=xlValues)
8個のセルで、Findメソッドは大掛かりすぎますね。For Each ~ in [領域]でも済むと思います。
ところで、話が飛びますが、
>趣味でエクセルVBAを勉強し始めたのですが、
この言葉がなかったら、書き加えることはなかったのですが、一応、こういうものがあります、とだけお教えします。
今回のコードは、定番がヘルプでは丸々出ていて、それを貼り付けるだけで済んだかもしれません。私は、未だにこの定番の組み込みコードを覚えていません。
ダウンロード版ヘルプより(中身は英語のみ) GitHubに出ているというのは変ですが。
//XLVBACon.chm//
https://github.com/OfficeDev/VBA-content/blob/05 …
With Worksheets(1).Range("a1:a500")
Set c = .Find(2, lookin:=xlValues)
If Not c Is Nothing Then
firstAddress = c.Address
Do
c.Value = 5
Set c = .FindNext(c)
Loop While Not c Is Nothing And c.Address <> firstAddress
End If
End With
ありがとうございます!
さっそく大文字小文字を使い分けてみたところ、スペル間違いがはっきり分かるようになりました。
自動で同じスペルの文字列に大文字小文字が変換されるなんて思ってなかったので、感動しました。
DoEventsについても教えていただいてありがとうございます。
調べたのですが、これを使うと、「Esc」キーで無限ループから抜け出せるということですね?
間違えいたらすみません。
それから、ヘルプやGitHubにもそのまんまの情報があるとのことで、こちらも助かりました。
知らなかったので、有難いです。
本当に様々な情報をありがとうございました。
No.2
- 回答日時:
こんばんは!
他の方がお考えになったコードに手を付けるのは好みでないので
最初から勝手にやってみました。
Sheet2以降のすべてのシートのA2~A10セルの範囲を検索すればよいのですね。
一例です。
Sub Sample1()
Dim k As Long, cnt As Long
Dim myRng As Range, FoundCell As Range, FirstCell As Range
Dim wS As Worksheet
With Worksheets(1)
cnt = 2
For k = 2 To Worksheets.Count
Set wS = Worksheets(k)
Set myRng = wS.Range("A1:A10") '//★//
Set FoundCell = myRng.Find(what:=.Range("A1"), LookIn:=xlValues, lookat:=xlWhole)
If Not FoundCell Is Nothing Then
Set FirstCell = FoundCell
GoTo 処理
Do
Set FoundCell = myRng.FindNext(after:=FoundCell)
If FoundCell.Address = FirstCell.Address Then Exit Do
処理:
cnt = cnt + 1
.Cells(cnt, "A") = FoundCell.Offset(, 4)
Loop
End If
Next k
End With
End Sub
※ コード内の「★」の部分のように範囲は各シートのA1~A10セルとしています。
A2セルからの範囲指定の場合、仮にA2セルと他のセルに複数該当データがヒットした場合
A2セルがそのシートの最後に表示されてしまいます。
(なぜそうなるのかは当方も判りません)
1行目は項目行でSheet1のA1セルと同じデータはない!という考えです。
表示順が変わってもよいのであれば
範囲をA2~A10セルに変更してみてください。m(_ _)m
こちらはFor Next 構文を使ったコードなのですね。
勉強したてなので、こんな風にも書けるというのはとても参考になります。
情報ありがとうございました!
No.1ベストアンサー
- 回答日時:
ループ終了条件の
>Loop Until myrange2.Address = myaddress
にある変数:myaddress って変数の宣言をしたあとで何も値を代入してないから無限ループになるでしょうね。
If Not myrange2 Is Nothing Then
myaddress = myrange2.Address ' ここで myaddress に最初に見つかったアドレスを代入しておく。
Do
◆についてはExcelなしのOSなので検証は出来ませんけど。
少なくともエラーでって事なら『どんなエラー内容が表示されるのか』は情報として必要かも。
なるほどー!
そういわれてみれば、myaddressに何も入れてません!
入れてみたら、無限ループにならなくなりました。
助かりました。
あとは、エラー内容ですね。
エラー内容をどこで見ればいいのかわからず、不勉強で申し訳ないです。
デバッグの仕方をもうちょっと勉強してみます。
本当にありがとうございました!
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Visual Basic(VBA) エクセルVBAのコードで質問です。 下のコードはJ16の文字列をB3を起点とする範囲から探して、見つ 5 2023/04/07 11:07
- Excel(エクセル) VBAについて 3 2022/06/19 18:19
- Excel(エクセル) vba シート名の一覧を2列に分けるには 5 2023/04/24 08:56
- Visual Basic(VBA) VBAコードが作動せず、どこに問題があるのか教えて下さい。 3 2023/06/13 13:20
- Visual Basic(VBA) vbaを早くしたい 5 2022/09/09 10:58
- Visual Basic(VBA) オブジェクトが見つかりません 1 2023/06/24 19:43
- Visual Basic(VBA) 2つのシートの任意のセルの番号が一致したら、一致した行をコピーする VBA 2 2023/06/19 20:48
- Excel(エクセル) なぜExit Subがあるのかわかりません 4 2023/02/19 12:34
- Visual Basic(VBA) VBAが止まります。 3 2022/08/31 14:09
- Visual Basic(VBA) 前回ご教授いただいたコードに覚えたてのループ処理で品名りんごAから順に20回for nextでループ 7 2023/01/13 22:01
このQ&Aを見た人はこんなQ&Aも見ています
-
性格の違いは生まれた順番で決まる?長男長女・中間子・末っ子・一人っ子の性格の傾向
同じ環境で生まれ育っても、生まれ順で性格は違うものなのだろうか。家庭教育研究家の田宮由美さんに教えてもらった。
-
findは動くがfindnextがマクロで動きません。記述は同じはずなのですが…
Visual Basic(VBA)
-
【excelVBA】Findメソッドで検索対象を複数列
Excel(エクセル)
-
EXCEL VBA で指定した範囲に入力があるかどうか?
Visual Basic(VBA)
-
-
4
エクセルのラベルの値(文字列)を垂直方向で中央揃えにするには?
Excel(エクセル)
-
5
VBAでブックを非表示で開いて処理して閉じる方法
Excel(エクセル)
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
VBAマクロ実行時エラーの修正に...
-
Excelで空白セル直前のセルデー...
-
エクセルVBA 配列からセルに「...
-
【Excel VBA】一番右端セルまで...
-
EXCEL VBA 文中の書式ごと複写...
-
Excel UserForm の表示位置
-
入力規則のリスト選択
-
特定の色のついたセルを削除
-
VBA 複数条件の分岐処理の上手...
-
DataGridViewで指定したセルの...
-
DataGridViewのフォーカス遷移...
-
エクセルのカーソルを非表示に...
-
指定した文字から指定した文字...
-
DataGridViewでグリッド内に線...
-
Rangeの範囲指定限界
-
エクセルの選択範囲のセルの値...
-
Excel VBA 同じ処理を複数回行...
-
エクセルの合計を自動で表示さ...
-
Excel VBA IF文がうまく動作し...
-
Excelのセルから日付情報を取得...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
VBAマクロ実行時エラーの修正に...
-
エクセルVBA 配列からセルに「...
-
VBA 複数条件の分岐処理の上手...
-
Excelで空白セル直前のセルデー...
-
Excel UserForm の表示位置
-
EXCEL VBA 文中の書式ごと複写...
-
特定の色のついたセルを削除
-
VBA にて、条件付き書式で背景...
-
VBAでユーザーフォームにセル値...
-
【VBA】写真の貼り付けコードが...
-
【Excel VBA】一番右端セルまで...
-
Excel VBAでCheckboxの名前を変...
-
エクセルの合計を自動で表示さ...
-
【VBA】【ユーザーフォーム_Lis...
-
VBA:日付を配列に入れ別セルに...
-
Excel VBA IF文がうまく動作し...
-
下記のマクロの説明(意味)を...
-
入力規則のリスト選択
-
C# DataGridViewで複数選択した...
-
関数の引数でrangeを指定したとき
おすすめ情報
皆さん、ありがとうございます!
有益な情報なども書いてくださって、感謝します。
帰宅後、また動きを確認してから個々へのご返答とさせていただきます(^-^)