• 締切済み

VBAのFindメソッドのエラー理由

初歩的な質問ですがよろしくお願いいたします。 シート1のi行6列目の文字列をシート2の3列目から探してその行数をシート1のi行16列目に 引っ張ってくる記述をしたく、下記のようなコードを書いたところ1004のデバック表示がされました。下の記述をどうすれば正常に動くでしょうか。 Range(i, 16) = Worksheets(2).Range(Cells(5, 3), Cells(5, 3).End(xlsown)).Find(Cells(i, 6)).Row

みんなの回答

  • imogasi
  • ベストアンサー率27% (4737/17068)
回答No.3

Range(Cells(),cells())とCellsを2つとRangeを使ってセル範囲を指定する場合は、初心者はワークシートの指定を忘れやすい。 回避策は (1)しつこくワークシート名をかぶせて書くか、または (2)Set ws1=Worksheets(1) Set ws2=Worksheets(2) のような書き方をして Range(Ws2.Cells(5, "c"), Ws2.Cells(1000, "c")のように添えて書くか (3)With Worksheets(2) .Cells(・・・    End With と書くかでしょう(#1のご回答) 全貌が質問に書かれてないので、よくわからないが、1つのやり方をご参考に上げる。 Sub test01() i = 2 'Worksheets(2).Range(Worksheets(2).Cells(5, "c"), Worksheets(2).Cells(5, "c")).End(xlDown).Select Range(Worksheets(2).Cells(5, "c"), Worksheets(2).Cells(1000, "c").End(xlUp)).Select 'Stop Selection.Find(Worksheets(1).Cells(i, "F")).Select Worksheets(2).Cells(i, "J") = Selection.Offset(0, 1) 'Range(i, 16) = Worksheets(2).Range(Cells(5, "c"), Cells(5, "c").End(xlDown)).Find(worksheets(1).Cells(i, 6)).Row End Sub i=2は,全貌が書かれてないので、わたしが仮定した。 上記Stopは範囲を捉えているか途中で確認テスト用。本番では不要。 例データ Sheet2のF2にaa Sheet2 C5:D8 f 12 g 23 ss 25 aa 11 結果 Sheet1 F2  に 11 ーー XLSOWNは誤りだろう。 End(xlUp)もあるよ(このほうが多く使われるのかも)。1000行としているのは、仮の例で、余裕を見てのデータ数の見積もり行のつもり。 Offset(0, 1)としているのは、 ふつうは、見つかった隣列などのデータがほしいのでは。 Findメソッドで第2、第三の該当を見つけに行くとき、くりかえしを探索を続ける場合の終わり判定は初心者にはむつかしいと思うので勉強必要かな。

  • kkkkkm
  • ベストアンサー率65% (1620/2460)
回答No.2

No1です。一部訂正 ドットのないセル指定はコードの書かれているセル ↓ ドットのないセル指定はコードの書かれているシートのセル

  • kkkkkm
  • ベストアンサー率65% (1620/2460)
回答No.1

Worksheets(2)の指定が最初のRangeにしか適用されず以後の検索範囲指定のCellsはコードの書かれているシート(もしくはアクティブシート)のセルを指定していることになりエラーなっています。Worksheets(2)のセルを指定する部分はすべてWorksheets(2).から書かないとエラーになりますが、すべてのセル指定にWorksheets(2).を付けるのは面倒ですので、以下の方法Withで最初に指定しておくという手があります。 ドットで始まるセル指定はWithで指定したシートのセルを、ドットのないセル指定はコードの書かれているセル(もしくはアクティブシート)をそれぞれ指定していることになります。 With Worksheets(2) Cells(i, 16) = .Range(.Cells(5, 3), .Cells(.Cells(5, 3).End(xlDown).Row, 3)).Find(Cells(i, 6)) End With

関連するQ&A

  • EXCEL2000、VBAのFindメソッドの仕様(1行目の取扱)について

    EXCEL2000のVBAでマクロを作っています。 Sheet1のA列に下記の様に数字を入れ、作成したfindcheckのマクロを実行します。検索値の5は一番最初に1行目に現れるので、メッセージボックスによって1と表示されるはずなのですが、4と出ます。 おかしいなぁと思って4行目の5を別の数字にするとメッセージボックスで1が表示されるようになりました。いろいろ検索してみると、フィルタなどでは1行目はタイトルとして扱われる…みたいな記述があったので、この場合も1行目は特別な意味を持つのかなぁと思い質問しました。 今回は検索結果が複数ある場合、1番最初に出たセルの行数を表示したいと思っています。1行目を「数値一覧」として、列タイトルの様にしたところ、うまくいきそうでした。もしこの動作が仕様なのかどうかご存じの方がいらっしゃったら教えていただきたいと思います。 どうぞよろしくお願いします。 ■Sheet1のA行目の数字 ----------------------------------------------------------- 5 3 2 5 4 3 2 1 1 ----------------------------------------------------------- ■VBAのコードサンプル ----------------------------------------------------------- Sub findcheck() Dim searchResult As Range Set searchResult = Worksheets("Sheet1").Columns("A").Find("5") If searchResult Is Nothing Then MsgBox "見つかりません" Else MsgBox searchResult.Row End If End Sub -----------------------------------------------------------

  • マクロのFINDメソッドで質問です。

    マクロの初心者で、いつもお世話になっております。 FINDメソッドを使って別々のシートから同じIDを探す処理をしたいのですが、IDが片方にしか無い場合に検索2rangeが"nothing"になってしまい止まってしまいます。 抜粋ですか以下の様にコーディングしました。 解る方がいましたらアドバイスをお願いします。 IDはIDがセットされている列です。 シート2を上から1つずつ見ていき、 シート1から該当するIDを探す処理をします。 最終的には該当したIDの行数を記憶して、 シート1とシート2をマッチングさせたいのですが。 Dim 検索range As Range Dim 検索2range As Range ID = Sheet2.Cells(LOOP_C1, 検索列).Value Set 検索Range = Range(Sheet1.Cells(F2TOP,検索列),Sheet1.Cells(LASTRow, 検索列)) Set 検索2range = 検索Range.Find(What:=ID, LookAt:=xlWhole, SearchOrder:=xlByRows, searchformat:=True).Row ※ If 検索2range Is Nothing Then Else   検索2range.Activate End If ・ ・ ・ ※の箇所で止まってしまいます。

  • EXCEL VBAのFind について

    VBAで、特定の文字が入っているセル位置(結合セル)を取得したく、 シートのコード記述で --- Private Sub Worksheet_Change(ByVal Target As Range) Dim w_CelObj As Object Set w_CelObj = ActiveSheet.Cells.Find(What:="あああ", LookAt:=xlWhole, MatchByte:=False) MsgBox w_CelObj.Row MsgBox Cells.Find(What:="いいい").Row End Sub ----- と記述し、"aa"も"bb"もどちらの方法でも取得できました。 ですが、これを別のEXCELブック(既にシートがたくさんあり、コードもびっしり記述してあります)で同様のことを行おうとするとエラーになってしまいます。 ※新しいシートを作成し、そのシートにコードをコピーして試しました。 セルの結合を解除すると正常に取得できるのですが、結合セルだとFindされてきません。 調べてみましたが、「Cells.Find」ときちんとセル全体を指定していれば大丈夫のようで、同様の事例を検索できませんでした。 他に何を調べればよいでしょうか? ご協力よろしくお願いします。

  • エクセルVBAのFindの不具合

    入力シートの4~2000行にデータをフォームを使って入力し、そのフォームを閉じる際に集計シートで集計する家計簿を作ってます。集計シートでは、食費・交際費などのコードがB5:B22に入っており、それぞれの合計をC5:C22に表示させたいのです。SUMIFを使えば楽なのですが、勉強のために極力VBAで処理させます。 フォームを閉じた際のソース(抜粋)は以下の通りです。 -------------------------------- Private Sub CommandButton2_Click() Dim i As Integer Dim コード As Integer Dim 金額 As Long Dim 集計行 As Integer Dim コード範囲 As Range Unload Me Set コード範囲 = Worksheets("集計").Range("b5, b22") For i = 4 To 2000 コード = Cells(i, 3).Value 金額 = Cells(i, 5).Value 集計行 = コード範囲.Find(コード).Row Next i End Sub -------------------------------- For~Nextの中はもっと処理を追加しなければならないのですが、とりあえず現段階で、   実行時エラー91(オブジェクト変数またはWithブロックが設定されていません) が   集計行 = コード範囲.Find(コード).Row の行で発生します。行番号だけを取得しようとしているので、Findの行だけを整数型変数に代入したいのですが・・・ 間違っている点をお教え下さい。 ご面倒でなければ、 Application.WorksheetFunctionに置き換える方法も教えていただければ幸いです。 よろしくお願いします。

  • エクセルVBAのFINDの質問です。

    エクセルVBAのFINDの質問です。 シート1    A    B    C     D 1 コード1 コード2 コード3 名 称 2  4    1     1 3  4    2     2 4  4    3     1 シート2    A    B 1 コード1 名 称 2  1   名称1 3  2   名称2 やりたいことは、シート1のD列に、シート1のコード3をもとにシート2から名称を取得したいのです。 下記に記したプログラムだと最初のFINDNEXTは動くのですが、 2回目でエラーになってしまい、次を読んでくれません。 どなたか、ご教授頂けますでしょうか。 シート1の検索条件はコード1の"4"です。 シート1のコード1は重複キーで、一レコードずつ読んで行き、各レコード毎にシート2を読みたい のです。 Dim シート1 As Worksheet Dim シート2 As Worksheet Dim obj As Object Dim Lin As Integer Dim mykey As Integer Dim obj1 As Object Dim Lin1 As Integer Dim mykey1 As Integer Dim st_Lin As Integer Set シート1 = ThisWorkbook.Worksheets("シート1") Lin = シート1.Cells(シート1.Rows.Count, 1).End(xlUp).Row mykey = "4" Set obj = シート1.Range("A1", "A" & Lin).Cells.Find(What:=mykey, _ LookIn:=xlValues, _ lookat:=xlWhole, _ SearchOrder:=xlByColumns) If obj Is Nothing Then   MsgBox ("異常です")   Exit Sub Else   st_Lin = obj.Row   Do Until obj.Row <> st_Lin    Set obj = シート1.Range("A1", "A" & Lin).FindNext(obj)    If obj Is Nothing Then     Exit Do    Else     Set シート2 = ThisWorkbook.Worksheets("シート2")       With シート2          Lin1 = .Cells(シート2.Rows.Count, 1).End(xlUp).Row          mykey1 = シート1.Cells(obj.Row, 3).Value          Set obj1 = .Range("A1", "A" & Lin1).Cells.Find          (What:=mykey1,LookIn:=xlValues,lookat:=xlWhole,SearchOrder:=xlByColumns)          If obj1 Is Nothing Then           MsgBox ("名称取得できませんでした")           Exit Sub          Else            シート1.Cells(obj.Row, 4).Value = .Cells(obj1.Row, 2).Value          End If       End With    End If   Loop End If

  • VBA FindメソッドとMatch関数のところ

    まだVBAに慣れていませんが、下記のソースを書いてみました。 ★印の間の部分の処理を、最初はFor Nextで書いていたのですが、理由が解らないですが…うまく処理されない為、タイトルの2種類(セルのFindメソッドとMatch関数)を使って処理しようと思い書き直したのですがうまく処理されません。 どこがいけないのか解らず数時間も悩んでしまいました。 すみませんが、どなたか教えてください。よろしくお願いします。 Sub 外注別案内書作成() Dim ws As Worksheet 'オブジェクト格納 Dim i As Long, j As Long '繰り返す回数格納 Dim annaicode As Variant '案内場所C格納 Dim addwsname As Variant 'シート名前格納(※案内場所名) Dim flag As Boolean '真偽 Dim r As Range 'Findメソッドの返り値格納 Dim K As Long 'Match関数の返り値格納 'レポート元でQ列の情報が入っている時に、案内場所別で情報を作成する。 'レポート元でQ列に値がある時に、annaicode変数へ格納。 For i = 2 To Worksheets("レポート元").Cells(Rows.Count, "A").End(xlUp).Row If Cells(i, "Q").Value <> "" Then annaicode = Cells(i, "Q").Value End If ★ココから-------- '外注一覧でannai変数と一致した時に、addwsname変数へ格納。 FindメソッドとMatch関数 With Worksheets("外注一覧").Columns("1:1") Set r = .Find(What:=annaicode, LookIn:=xlValues, LookAt:=xlWhole, SearchOrder:=xlByColumns) If r Is Nothing Then MsgBox i & "行目の案内場所Cの入力が不正です。" & vbCrLf & "処理を中断しますね", _ vbOKOnly + vbExclamation, "お知らせ" Else With Worksheets("外注一覧") K = .Match(annaicode, .Range(.Cells(1, "A").Value, .Cells(.Rows.Count, "A").Value), 0) addwsname = .Cells(K, "B").Value + "_案内" End With End If End With ★ココまで-------- 'ワークシートコレクション内でaddwsname変数と一致した時に、flag変数をTrueにする。 For Each ws In Worksheets If ws.Name = addwsname Then flag = True End If Next ws 'flag変数の値により、各々処理をする。 If flag = True Then Worksheets("レポート元").Cells(i, "A").EntireRow.Copy _ Destination:=Worksheets(addwsname).Cells(Rows.Count, "A").End(xlUp).Offset(1, 0) flag = False Else Worksheets.Add ActiveSheet.Name = addwsname Worksheets("レポート元").Cells(i, "A").EntireRow.Copy _ Destination:=Worksheets(addwsname).Cells(Rows.Count, "A").End(xlUp).Offset(1, 0) End If Next i End Sub

  • VBAで複数の行のナンバーを取得し、その行の列の値を参照して値を入れる

    下記のことをしたいのですが、調べてもわかりません。 どなたか教えてください。 よろしくお願いします。 内容: エクセルシートのA列の値が11である行ナンバーを取得(複数ある可能性があります)する。 その行のE列(5列目)の値と他のテーブルの値を参照して所定の値をA列の値が11である行のE列(5列目)に返す。 以下のVBAを書いてみましたがうまくいきません。 ----------------------------------------------------------------- Dim ROWCOUNT As Integer Dim row_array() As Variant Dim i As Integer '全行数を取得 ROWCOUNT=Worksheets("sheet1").Range("A1",Range("A65536").End(xlUp)).Count For i = 1 To ROWCOUNT If Cells(i, 1).Value = 11 Then Cells(i,1).Offset(0,5).Value=WorksheetFunction.VLookup(Cells(i, 1).Offset(0, 5).Value, Worksheets("sheet2").Range("A1:H1786"), 3, False) End If Next I

  • エクセル関数をVBAでやりたい

    IFERROR(INDEX(***,MATCH(***)),"")この式を下記マクロに組み込むことは、可能でしょうか? Sub Macro1() ' Dim line3 As Integer Dim line5 As Integer line5 = 2  '初期値を2行目に設定してます Do While Worksheets("Sheet5").Cells(line5, 1).Value > 0 'sheet5の通し番号をsheet3のH列から検索して、その行数をline3に代入する。   line3 = Worksheets("Sheet3").Range("H:H").Find(what:=Worksheets("Sheet5").Cells(line5, 8)).Row 'A,B列内容のコピー   Worksheets("Sheet5").Range("A" & line5, "B" & line5).Copy Worksheets("Sheet3").Cells(line3, 1) 'D~G列内容のコピー   Worksheets("Sheet5").Range("D" & line5, "G" & line5).Copy Worksheets("Sheet3").Cells(line3, 4)   line5 = line5 + 1    '次の行へ Loop   ( http://soudan1.biglobe.ne.jp/qa8921867.html )

  • ExcelのVBAの配列に関する質問です。

    ExcelのVBAの配列に関する質問です。 sheet1のデータをsheet2に表示するVBAを作成しています。。 sheet1のデータは7行目からスタートし、sheet2のデータは26行目からスタートしています。。 sheet1とsheet2の列は同じ並びではないため、それぞれのシートの列番号をCellsを用いて指定しています。 Sub test1() Dim endrow As Long endrow = Worksheets("sheet1").Range("A65536").End(xlUp).Row Dim i As Long Dim j As Long For i = 7 To endrow j = i + 19 Worksheets("sheet2").Cells(j, 1) = Worksheets("sheet1").Cells(i, 2) Worksheets("sheet2").Cells(j, 8) = Worksheets("sheet1").Cells(i, 28) Worksheets("sheet2").Cells(j, 9) = Worksheets("sheet1").Cells(i, 31) Worksheets("sheet2").Cells(j, 10) = Worksheets("sheet1").Cells(i, 32) ・ ・ ・ ※長いので省略 Next i End Sub 上記のtest1は正常に動くのですが、データ量が多いため、処理に時間がかかってしまいます。 高速化できないかと、以下のように変更しました。 Sub test2() Dim dataRange1 As Variant Dim dataRange2 As Variant dataRange1 = Worksheets("sheet1").Range("A1:GI10006") dataRange2 = Worksheets("sheet2").Range("A1:DZ10018") Dim endrow As Long endrow = Worksheets("sheet1").Range("A65536").End(xlUp).Row Dim i As Long Dim j As Long For i = 7 To endrow j = i + 19 dataRange2(j, 1) = dataRange1(i, 2) dataRange2(j, 8) = dataRange1(i, 28) dataRange2(j, 9) = dataRange1(i, 31) dataRange2(j, 10) = dataRange1(i, 32) ・ ・ ・ ※長いので省略 Next i End Sub test2は、エラーメッセージ等は表示されませんが、sheet2にデータが表示されません。 ちなみに、以下のようにsheet1のみ配列化した場合は、正常に表示されました。 Worksheets("sheet2").Cells(j, 1) = dataRange1(i, 2) Worksheets("sheet2").Cells(j, 8) = dataRange1(i, 28) Worksheets("sheet2").Cells(j, 9) = dataRange1(i, 31) Worksheets("sheet2").Cells(j, 10) = dataRange1(i, 32) test2は、どこが間違っているのでしょうか? ご教示ください。 よろしくお願いいたします。

  • Find2重使用後のFindNextの使用について

    Excel2003にて シート2に記載されている表のD列の中からFindを使用し、条件に該当するものを検索した後、該当する行のE列の値を取り出し、それを条件にしてシート3のL列をFindを使用し検索する。次に該当した行のQ列の値を取り出し、シート2のH列に記載するといった感じの内容をFindNextを使い繰り返すVBAを組んでいるのですが、FindNextを使用した際に検索結果がNothingになってしまいます。Findを2回使用しているのが原因なんでしょうかね?なにか有効な対策方法はないでしょうか?ご教授願います。 <イメージ> 検索条件1:2-1 (シート2)   D   E     H 1 2-1 田中   兵庫  ← H列にシート3で検索した住所を記載させたい。 2 2-2 吉田 3 2-3 山田 4 2-1 田上 検索条件2:(シート2で2-1の条件で検索された)田中 (シート3)    L   Q 1 吉田 大阪 2 田中 兵庫 3 田上 大阪 4 山田 奈良 <コード> Sub add() Dim class(1 To 10) As String class(1) = "2-1" class(2) = "2-2" class(3) = "end" i = 1 Do Until class(i) = "end" Set objFind = Worksheets(2).Columns("D").Find(class(i), LookIn:=xlValues) If Not objFind Is Nothing Then Do Until oldaddress > objFind.Row class_sh2_YLine = objFind.Row class_nm = Cells(class_sh2_YLine, "E") Set objFind2 = Worksheets(3).Columns("L").Find(class_nm, LookIn:=xlValues) If Not objFind2 Is Nothing Then class_sh3_YLine = objFind2.Row class_add = Worksheets(3).Range("Q" & class_sh3_YLine) Worksheets(3).Rows(class_sh3_YLine).Delete Worksheets(2).Cells(class_sh2_YLine, "H") = class_add Else MsgBox "該当する住所がありません" End If oldaddress = objFind.Row Set objFind = Worksheets(2).Range("D:D").FindNext(objFind) Loop End If i = i + 1 Loop End Sub