• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:マクロのCells.Findについて)

エクセルマクロのCells.Findについて

matsu_junの回答

  • matsu_jun
  • ベストアンサー率55% (146/265)
回答No.7

tktkmanureさん、おはようございます。ANo.6のmatsu_junです。 FindSpecialというファンクションを作ってみました。 FindSpecialの書式は以下のとおりです FindSpecial(TgtKey, TgtRng, ExcKey(), SplKey, AftRng)  TgtKey : 検索したい文字列です。質問中の「スペル」に相当します。  TgtRng : 検索する範囲を示します。質問中では「Cells」に相当します。  ExcKey() : 検索から除外したい文字列です。質問中の「ゴスペル」に相当しますが、       例えば「ゴスペル」だけでなく、「スペルチェック」や「スペルリスト」も除外したい場合        ExcKey(0) = "ゴスペル"        ExcKey(1) = "スペルチェック"        ExcKey(2) = "スペルリスト"       とします。配列は必ず(0)から記載してください。       除外したいリストにない、上の例の場合、「スペルミス」などは検索対象となります。  SplKey : セルの中で、幾つかの単語が続けて記載されている時に、単語どうしを分割している       記号です。質問中の「、」に相当します。実際の用途では区切り文字がないという場合でも       適当な文字(「、」のままでよいです)を入れておいて下さい。  AftRng : TgtRngで指定した範囲における、検索スタートの位置を示します。一つのセル(例えばRange("A1"))で示します。       検索範囲を"A1:B10"とした時、ここにRange("A5")と記載すれば、1行目から4行目およびA5は検索対象に含まず       B5とA6からB10までの範囲で検索を行います。(Find関数のafterと同じものです)       省略はできないので、初めて検索する際は、検索範囲の左上のセルを記載してください。 FindSpecial は、Rangeオブジェクトになります。 なので、  Dim ResultCell As Range  Set ResultCell = FindSpecial( 以下 引数 … ) といった形で御利用ください。 さて、実際のコードを以下に示します。 試しに、以下をSheet1のモジュールにコピーしてください。 '------------------------------ここからコピー------------------------------------ Private Function FindSpecial(TgtKey As String, TgtRng As Range, ExcKey() As String, SplKey As String, AftRng As Range) As Range 'TgtKey : 検索対象となる文字 'TgtRng : 検索範囲(レンジで指定) 'ExcKey : 検索から除外する文字(配列で指定) 'SplKey : 検索するセルに複数の単語が含まれている際、それらを区切るためのキャラクター(例通りなら"、") 'AftRng : AftRngより先のセルから検索   Dim FirstFind As Range  '最初の検索結果を保持(検索が一周したことを検知するため)   Set FindSpecial = TgtRng.Find(TgtKey, After:=AftRng)   If Not (FindSpecial Is Nothing) Then     Set FirstFind = FindSpecial     'とりあえず「TgtKey」を含むセルの検索が終了。以下、検索結果から除外されるかどうかの判断     If FindExeclude(FindSpecial.Value, ExcKey(), SplKey) Then Exit Function  '除外する文字で検索されていなければ、このセルを返り値として終了     Do Until (FindSpecial Is Nothing)  'とりあえず検索した結果が、実は除外する文字でも検索されていたならば、次のセルを検索       Set FindSpecial = TgtRng.FindNext(FindSpecial)       If FindSpecial.Address = FirstFind.Address Then Exit Do  '検索結果が1周したら、結果なしとして終了       If FindExeclude(FindSpecial.Value, ExcKey(), SplKey) Then Exit Function  '除外する文字で検索されていなければ、このセルを返り値として終了     Loop   End If   Set FindSpecial = Nothing  'ルーチンが本行まで実行された場合は結果なしと判断されるので、返り値をNothingとして終了 End Function Private Function FindExeclude(TgtStr As String, ExcKey() As String, SplKey As String) As Boolean 'FindSpecialの補助関数(ユーザーは実際に呼び出さない) 'TgtStr : とりあえず検索したセルの中身 'ExcKey : 検索から除外する文字(配列で指定) 'SplKey : 検索するセルに複数の単語が含まれている際、それらを区切るためのキャラクター(例通りなら"、")   Dim SplStr() As String   Dim FindCnt As Integer   FindExeclude = False   'TgtStrをSplKeyで分割し、配列に格納   SplStr = Split(TgtStr, SplKey)   For i# = 0 To UBound(SplStr)     FindCnt = 0     For j# = 0 To UBound(ExcKey)       FindCnt = FindCnt + InStr(SplStr(i), ExcKey(j))  '配列データが、除外データに相当するかどうかの検索(除外データが含まれていたら、FindCntは、1以上の値となる     Next j     If FindCnt = 0 Then  '全ての除外データについて確認し、それらが含まれていなければTrueを返す       FindExeclude = True       Exit Function     End If   Next i End Function '------------------------------ここまでコピー------------------------------------ 試験方法として、以下をお試しください。 ExcelのシートのA1セルに、検索したい文字として スペル と入力してください。 A2セルに、検索から除外したい文字として ゴスペル、スペルチェック、スペルリスト と入力してください。(読点もそのまま入力してください) 後は同じシート上に、適当にデータを記入してみてください。 (上記の通り「スペルミス」は除外文字として登録していないので検索対象です。 適当なセルに「スペルミス」と入力してください) それができたら、シート上にボタン(CommandButton1)を配置します。 で、以下をコピーして、同じモジュールに貼り付けます。 '------------------------------ここからコピー------------------------------------ Private Sub CommandButton1_Click()   Dim JOGAI() As String   Dim ResultRange As Range      JOGAI = Split(Range("B2"), "、")  '…(1)   FindSpecial(Range("B1"), Cells, JOGAI, "、", ActiveCell).Select End Sub '------------------------------ここまでコピー------------------------------------ シートに戻って、ボタンを押してみてください。検索できた場所にカーソルが移っていきます。 そのまま連打すれば、次の検索場所にカーソルが移ります。 今回の例では、検索から除外したい文字列を、「、」で区切って1つのセルに入れています。 これを1つずつ配列に格納するには、上のコードの(1)の部分 (Split関数) を利用します。 1セル内に複数の文字列を改行して入れている場合(セルに文字入力中 Alt+Enterで改行させていた場合) 上の(1)の行は   JOGAI = Split(Range("B2"), Chr(10)) と書き換えられます。 今回作成した FindSpecial関数内の引数 SplKey についても、もし区切りの文字が改行であった場合は Chr(10)を利用します。 よろしければお試しください。

tktkmanure
質問者

お礼

matsu_junさん 大変お手数をおかけしました。ありがとうございました。 大変有用なファンクションだと思いますし、マクロ作成における物事の考え方が大変参考になります。ただ、これまた私の質問の仕方や情報が悪いのですが、複数の単語が含まれているセル内の区切り文字が、私の手元にある表の場合、「、」だったり、「,」だったり、改行だったり、スペースだったり、数字だったり、1つの表の中で統一されておらず、しかも1つのセルの中でそれらが混ざっていたりしています。作っていただいたマクロの修正を考えたのですが、ちょっと厳しそうです。今のところは、mt2008さんのANo.5やANo.8のロジックがより汎用的だと思いますので、そちらを使わせていただこうかと思います。

関連するQ&A

  • エクセルマクロ・Cells.Find のエラー

      VBA初心者です。 ファイルA の C列 に入力されているデータが ファイルB に含まれているかどうか検索するマクロを Cells.Find を使って作ろうとしています。 データがファイルBに存在する場合は問題ありませんが存在 していない場合エラーが出て止まってしまいます。 ヘルプを見ると「セルが見つからなかった場合は、Nothingを返します」 と書かれていますが、どうもNothingとは返ってきません。 このエラーを回避する方法を教えてください。 例えばこんなマクロを組みました。  For tate = 0 To 19    Windows("ファイルA.xls").Activate    Range("C1").Offset(tate, 0).Select    データ = Range("C1").Offset(tate, 0)    Windows("ファイルB.xls").Activate    Cells.Find(データ, MatchCase:=False).Activate  Next tate 例えば最後の2行を    結果 = Cells.Find(What:=ISISDate, MatchCase:=False).Activate      MsgBox (結果)  Next tate とするとデータが含まれている場合は「True」と返ってきますが、 含まれていない場合は MsgBox が表示される前にエラーとなってしまいます。 とりあえずこのエラーを回避する方法をご存知でしたらお教えください。  

  • マクロCellsがわからなくて困っています

    マクロのCellsについて、夜も眠れないほど悩んでいます。 助けてください。 相談は以下です。 Cells(1,1).Select の行、列部分に、他のセルに入力済みの数値を指定したり、算出することはできますか? たとえば、あらかじめセルに数値が入っていたら Cells(1,A1).Select Cells(1,B1-A1).Select のように。(誤った文章ですが・・・) またこの方法に使えるCells以外の言葉があれば、教えてくださいませ!

  • 文字検索マクロで質問です。

    文字検索マクロで質問です。 下記のマクロを作成したのですが、A1に検索する文字を入力してA列(A5:11700)のみを検索して該当が有ったらそのセルを色を付けし、又,該当が無ければMSG BOXで”該当なし”と表示するマクロを御教授頂けますか。 Cells.Find(What:=Range("A1").Value, After:=ActiveCell, LookIn:=xlFormulas,   LookAt:= _ xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:=False _ , MatchByte:=False, SearchFormat:=False).Activate End Sub 以上、宜しくお願い致します。

  • 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」ときちんとセル全体を指定していれば大丈夫のようで、同様の事例を検索できませんでした。 他に何を調べればよいでしょうか? ご協力よろしくお願いします。

  • Excelファイル内の検索マクロがエラーになってしまいますので、その解

    Excelファイル内の検索マクロがエラーになってしまいますので、その解決方法を教えて戴きたいと思います。 (ExcelのVer.はPCによって異なり2002と2003です) 現在3つのExcelシートがありまして、内訳は ・検索.xls : 検索文字列入力用、マクロ実行用 ・文字列が含まれない.xls : データベース(検索文字列が含まれない) ・文字列が含まれる.xls : データベース(検索文字列が含まれる) となっております。 (デバッグの為にデータベースは意図的に作成しております) ここで『検索.xls』のマクロで以下のように作成をしてみました。 Sub 検索() Dim SearchWord As String Workbooks("検索.xls").Activate SearchWord = Worksheets("Sheet1").Cells(1, 1) ' 検索.xlsのSheet1のA1に検索文字入力 Workbooks.Open Filename:="D:\文字列が含まれない.xls" Windows("文字列が含まれない.xls").Activate Cells.Find(What:=SearchWord).Activate Workbooks.Open Filename:="D:\文字列が含まれる.xls" Windows("文字列が含まれる.xls").Activate Cells.Find(What:=SearchWord).Activate End Sub しかし、このマクロを実行しますと『文字列が含まれない.xls』の処理でエラーになってしまいます。 この『文字列が含まれない.xls』の処理をコメントアウトしますと『文字列が含まれる.xls』の処理はちゃんと実行してくれますので、データベースに検索文字が無かった場合の処理のさせかたが問題だとは思うのですけど、ネット検索をしても、上手なキーワードが思い浮かばずに欲しい情報がヒットしてくれません。 なにか単純な問題だと思うのですけれども、Excelにお詳しいかたがいらっしゃいましたら、回避策を教えて戴きたいと思います。

  • マクロの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でセルに任意の文字列をペーストします。そのセルは別のブックにリンクしているのでペーストする度にリンク先のセルでは文字列が更新されます。リンク先のブックにはワークシートが10あっていづれかのシートのA列にその文字列がある事になっています。更新された文字列を検索する作業を繰り返すのでマクロで組み込もうと思ったのですがFIND関数にしても、VBでCell.Find(What:=....と書くにも参照する文字列を直接指定してやらないと動きません。参照する文字列が相対的に変化するので「特定のセルの中に入力された文字列」を参照してブック内を検索したいということなのですが、実現するにはどうしたらようでしょうか?と質問して moji = "B1" Set c = Range("A:A").Find(What:=moji, LookIn:=xlValues, LookAt:=xlWhole) If Not c Is Nothing Then c.Select というコードをしめしていただきました。このままだと検索対象がRangeオブジェクトになっているのでActivesheet上でしか検索がかからないのでCellsにすればブック内のすべてのシートに検索がかけられるかな?と思っていたのですがエラーがでます。ブック内を検索範囲に入れるためにはどうしたらよいでしょうか?

  • vbaのFindメソッドで取得するにはどうすれば

    A1に「あ」B1に「い」と入れて、 A2に「=A1&B1」としました。 この時、A2は「あい」と表示されます。 今回やりたいことは、 Sub test() Debug.Print Cells.Find(What:=" あい").Row End Sub で、2を返したいのですが、 実行時エラー91になってしまいます。 セル内に該当の文字列がないからだと思いますが、 数式でつなげた文字列を、 vbaのFindメソッドで取得するにはどうすれば良いでしょうか?

  • エクセルのマクロ コマンドのCells

    マクロ初心者です Cells(4,5)=5 とかで目的のセルに数字を代入したいのですが全然違うところに代入されてしまいます。 (一行目ばっかりにはいる、しかも列もずれている) なぜでしょうか? ご存知の方お願いします。

  • エクセル マクロ 検索

    お世話になります。 範囲がA2からK221までの表があります。 検索して検索されたセルの左のセルを表示するマクロを組みたいのですが、検索する文字(数値)はE1に、検索結果はK1に表示するようにするにはどのようにしたらいいでしょうか? Sub FIND_DATA1() ' FIND_DATA1 Macro ' マクロ記録日 : 2006/9/1 ユーザー名 : ' Cells.Find(What:=Range("E1").Value, After:=ActiveCell, lookAt:=xlWhole).Activate End Sub Sub Data_Find3() Dim 対象セル As Range Dim 最初のセル番地 As String Dim 検索件数 As Long Cells.Interior.ColorIndex = xlNone If Range("E1").Value = "" Then Exit Sub End If Set 対象セル = Cells.Find(What:=Range("E1").Value, After:=ActiveCell, lookAt:=xlWhole) 最初のセル番地 = 対象セル.Address Do 対象セル.Interior.ColorIndex = 37 検索件数 = 検索件数 + 1 Set 対象セル = Cells.FindNext(対象セル) Loop While 対象セル.Address <> 最初のセル番地 MsgBox "検索件数は" & 検索件数 - 1 & " 件です" End Sub 本を見たり調べたりでここまでできたんですがこれだと検索件数、検索結果が色付きになるだけで使い勝手がいまいちです。 よろしくお願いします。