• 締切済み

ExcelVBAのFind関数について質問です。

Find関数を使用して検索を行う際に、検索対象のシートに"ヶ月"、"ヵ月"という文字が記載されていると 処理が遅くなってしまします。 解決方法をご存知の方いらっしゃいますでしょうか? 以下、読みにくいプログラムかもしれませんが、ご教授願います。 Sub ボタン1_Click() Dim value As String Dim pass As String Dim template As Workbook Dim object As Object '検索対象文字 value = "A" 'テンプレートのパス pass = "C:\template.xls" 'テンプレートを開く Set template = Workbooks.Open(pass) 'テンプレートをコピー ActiveWorkbook.Sheets.Copy 'テンプレートを閉じる template.Close saveChanges:=False With ActiveWorkbook.ActiveSheet.Range(Cells(1, 1), Cells(10000, 256)) 'テンプレートにAという文字が存在するかのチェック Set object = .Find(What:=value, LookAt:=xlPart, SearchOrder:=xlByRows) Do '存在しない場合は処理を終了 If object Is Nothing Then End '存在する場合はA→Bに置き換える Else object = Replace(object, value, "B") End If '引き続きSheet2にAという文字が存在するかのチェック Set object = .Find(What:=value, LookAt:=xlPart, SearchOrder:=xlByRows) Loop While Not object Is Nothing End With End Sub

みんなの回答

回答No.2

#1です。 なかなか回答がつきませんね。 相変わらずFindメソッドが遅くなることについての解決方法ではありませんが、 前回の回答で書き忘れていたことがあったので、性懲りもなく出てきました。 この手のワークシートのセルの値を逐次変更していくマクロの、実行速度を 上げるのによく効く定番のテクニックがあります。 1. プログラムの最初の方で、以下を挿入  Application.ScreenUpdating = False  プログラムの終了直前に、以下を挿入  Application.ScreenUpdating = True  これを行うと、プログラムが終了するまでの間、画面の更新が抑制されます。 2. プログラムの最初の方で、以下を挿入 Application.Calculation = xlCalculationManual  プログラムの終了直前に、以下を挿入 Application.Calculation = xlCalculationAutomatic  現在のマクロは、一つのセルの値を変更する度に自動的に再計算を実行しますので、  特にセルに計算式が書かれているセルがたくさんある場合にはよく効きます。 以上。

全文を見る
すると、全ての回答が全文表示されます。
回答No.1

処理が遅くなることについては答えを持ち合わせていないので、最初に あやまっておきます。 いくつか突っ込みどころのあるプログラムなので、出てきました。 >Dim object As Object 普通は変数名と変数の型は同じにしません。 あと、Findメソッドの返す変数はRangeオブジェクトなので、ここは Dim rng as Range などとすべきでしょう。 >With ActiveWorkbook.ActiveSheet.Range(Cells(1, 1), Cells(10000, 256)) 処理時間を気にされるなら、もっと検索範囲を絞るべきでは? 使用されていない セルも検索範囲に含めてないですか? With ActiveWorkbook.ActiveSheet.UsedRange >'存在しない場合は処理を終了 >If object Is Nothing Then >End ヘルプによればEndステートメントは「強制的にプログラムを終了させる手段を提供する」 と書かれています。今回の場合は、ukmtさんの思った通りに動くかとは思いますが、 かなり乱暴なやり方と言えます。普通はEndステートメントを使用しなければならない 状態にはなりません。この文脈なら普通は Exit Do を書きます。 >'引き続きSheet2にAという文字が存在するかのチェック >Set object = .Find(What:=value, LookAt:=xlPart, SearchOrder:=xlByRows) 同じ文字を前回のFindメソッドと同じ検索条件で検索する場合にはFindNextメソッド を使用できます。 Set rng = .FindNext(rng) >Loop While Not object Is Nothing ループの終了条件が上記にも、ループの内部にも書かれていて冗長である。 このままなら >'存在しない場合は処理を終了 >If object Is Nothing Then >End の部分はループの一回目だけTrueになる可能性があるだけで、2回目以降は絶対に Falseになる。 だからループ内のIf ... は最初のFind実行直後に持っていく(つまりループの外。 その場合、前述したExit DoはExit Subに書き換えること)か、 >Loop While Not object Is Nothing を Loop と書き換える。 総括すると以下の通りになります。 Sub ボタン1_Click() Dim value As String Dim pass As String Dim template As Workbook Dim rng As Range '検索対象文字 value = "A" 'テンプレートのパス pass = "C:\template.xls" 'テンプレートを開く Set template = Workbooks.Open(pass) 'テンプレートをコピー ActiveWorkbook.Sheets.Copy 'テンプレートを閉じる template.Close saveChanges:=False With ActiveWorkbook.ActiveSheet.UsedRange 'テンプレートにAという文字が存在するかのチェック Set rng = .Find(What:=value, LookAt:=xlPart, SearchOrder:=xlByRows) Do '存在しない場合は処理を終了 If rng Is Nothing Then Exit Do '存在する場合はA→Bに置き換える Else rng = Replace(rng, value, "B") End If '引き続きSheetにAという文字が存在するかのチェック Set rng = .FindNext(rng) Loop End With End Sub なお、Do 以下は次のようにも書ける。 '存在しない場合は処理を終了 If rng Is Nothing Then Exit Sub Do '存在する場合はA→Bに置き換える rng = Replace(rng, value, "B") '引き続きSheetにAという文字が存在するかのチェック Set rng = .FindNext(rng) Loop While Not object Is Nothing End With End Sub 以上

ukmt
質問者

お礼

ありがとうございます。 VBA初心者なもので、知らない事が沢山ありました! ソースレビュー頂き、かなりソースが見やすくなりました。 ただ、肝心の >検索対象のシートに"ヶ月"、"ヵ月"という文字が記載されていると >処理が遅くなってしまします。・・・ の部分の根本的な解決には至っておりません。。。 何か考えられる原因などありますでしょうか???

全文を見る
すると、全ての回答が全文表示されます。

関連するQ&A

  • Findステートメントで別なブックの検索

    Findステートメントで検索した内容のある行のA列にある値をキーワードとして別なブックのA列に検索をかけてヒットしたセルの内容を元のブックの指定したセルに移すという動作をさせたいので次ののように書いてみました。 Private Sub CommandButton2_Click() Dim Yline As Long Dim No As Variant Dim c As Range Dim sh As Worksheet Dim sh_no As Integer Dim findcell As Range Dim add As String Set sh = Worksheets("ブックAの1") No = TextBox1.Text sh_no = 1 'テキストボックスに値が入っていた場合 If No <> "" Then 'Find メソッドの最低のプロパティは入れる。SearchOrder は特にいらない Set c = sh.Range("B:B").Find( _ What:=No, _ LookIn:=xlValues, _ LookAt:=xlPart, _ Searchorder:=xlByRows) '見つかった場合にのみ、値を入れる If Not c Is Nothing Then Yline = c.Row '見つかった行のA列の文字列でブックBに検索をかける add = sh.Cells(Yline, 1).Value Workbooks("B").Activate Set findcell = Workbooks("B").Worksheet(sh_no).Range("A:A").Find( _ What:=add, _ LookIn:=xlValues, _ LookAt:=xlPart, _ Searchorder:=xlByRows) '前Setステートメントからのループ検索開始 If findcell Is Nothing Then Do sh_no = sh_no + 1 If sh_no > ThisWorkbook.Worksheets.Count Then Exit Sub End If Set findcell = Workbooks("B").Worksheets.(sh_no).Range("A:A").Find( _ What:=add, _ LookIn:=xlValues, _ LookAt:=xlPart, _ Searchorder:=xlByRows) Loop While findcell Is Nothing End If End If Workbooks("A").Activate With Worksheets("Aの2")   .Cells(21, 4).Value = sh.Cells(Yline, 14).Value .Cells(20, 4).Value = sh.Cells(Yline, 15).Value .Cells(36, 4).Value = findcell End With Unload Me Else MsgBox No & " は見つかりません。", 48 End If Set sh = Nothing End Sub するとwhat:=addとしてaddが見つかるまでシート番号を増やしていくループのところでエラーがでてキーワードが見つからないと出ます。恐らくブックBを検索してくれているとは思うのです。A列に空白があるためかと思い埋めてみましたが関係ないようです。 構文エラー的なものは無いと思いますが、宜しくお願いします。

  • Find関数内にFind関数をかける場合

    エラー91が発生し、手詰まりです。 どなたかご教授お願いいたします。 Find関数でDo~lppoを行い、初期の検索結果アドレスでLoopを抜けようと思ったのですが。。 エラーしてしまいました。 Find関数内にFind関数を用いることが出来ない と目にしたのですが。 下記のようなVBAの場合 どのように対処したらいいでしょうか? また、VBA初心者のため VBA文が見づらかったり、おかしなところがあると思います。 その部分についても教えて頂けたらと思います。 Sub SAMPLE() Dim TargetDE As String '文字列型 Dim TargetNo As String '文字列型 Dim PODate As String '文字列型 Dim FoundCell As Range ' Dim FoundDate As Range Dim FoundCellNo As Long '長整数型 Dim FoundDateNo As String Dim SearchArea As Object 'オブジェクト型 Dim tar_obj(1) As Object 'オブジェクト型 Dim Addr As String '文字列型 Dim Lastrom As Long ' Dim POLEFT As Range '検索文字列入力(DE) TargetDE = Application.InputBox("Fill in a DE:??", "DE:??", Type:=2) If TargetDE = "False" Then Exit Sub '検索対象範囲 Set SearchArea = Workbooks("Sample sample.xlsx").Sheets("Sample") Set tar_obj(1) = Workbooks("INPUT FORMAT.csv").Sheets("INPUT FORMAT") '表示先をクリア tar_obj(1).Cells(1, 1).CurrentRegion.ClearContents '検索実行 Set FoundCell = SearchArea.Range("C:C").Find(What:=TargetDE, LookIn:=xlValues, _ LookAt:=xlPart, MatchCase:=False, MatchByte:=False) '検索文字列(DE)を含むセルがない場合は終了 If FoundCell Is Nothing Then Exit Sub '検索文字列入力(DE Number) TargetNo = Application.InputBox("Fill in DE nomber", "Nomber", Type:=2) If TargetNo = "False" Then Exit Sub '最初の検索結果の行数を格納 Addr = FoundCell.Address '検索文字列入力(PO Date) PODate = Application.InputBox("Fill in Sample Date", "Date", Type:=2) If PODate = "False" Then Exit Sub Do '検索Cell右横の値がTargetNoと同じ場合 If FoundCell.Offset(0, 1).Value = TargetNo Then '行番号を代入 FoundCellNo = FoundCell.Row '検索の下限値を変数に代入 F_LAST = FoundCellNo + 50 '検索実行 Set FoundDate = SearchArea.Range(SearchArea.Cells(FoundCellNo, 1), SearchArea.Cells(F_LAST, 1)).Find(What:=PODate, LookIn:=xlValues, _ LookAt:=xlPart, MatchCase:=False, MatchByte:=False) '検索文字列を含むセルがない場合は終了 If FoundDate Is Nothing Then 'MsgBox "Find is mistake" '検索文字列を含むセルがある場合 Else '変数に行番号代入 FoundDateNo = FoundDate.Row If FoundDate.Offset(1, 1).Value = "" Then MsgBox "The position of the cell is not correct. Please coordinate macro. " Else POLEFT = FoundDate.Offset(1, 1) For i = 2 To 13 If FoundDate.Offset(1, i) <> 0 Then If FoundDate.Offset(1, i) <> "." Then If IsNumeric(FoundDate.Offset(1, i).Value) = True Then '表示先(INPUT FORMAT)の行数をカウントアップ cnt = cnt + 1 PORIGHT = FoundDate.Offset(1, i).Value tar_obj(1).Range("E" & cnt) = POLEFT & PORIGHT End If End If End If Next i End If End If ElseIf FoundCell.Offset(0, 1) <> TargetNo Then ' MsgBox "Find is mistake" End If '次の検索を実行 Set FoundCell = SearchArea.Range("C:C").FindNext(After:=FoundCell) Loop While Not FoundCell Is Nothing And FoundCell.Address <> Addr ' If FoundCell.Offset(0, 1) <> TargetNo Then ' MsgBox "Not Find Number" ' End If End Sub

  • Excel VBA Findで日付だけのセルが検索できない

    日付のセルを検索するために、以下のような処理をさせていますが、日付だけのセルが検索できません。  【例】(1)は検索できますが、(2)が検索されません。    (1) 2010/03/05が誕生日    (2) 2010/03/05    (※(1)、(2)共に検索できるようにしたいと思っています。) Dim FoundCell as Variant Dim search_words as String search_words = "20??/*/" Set FoundCell = Cells.Find(what:=search_words,After:=ActiveCell, LookIn:=xlValues, LookAt:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:=False, MatchByte:=False) ※Excel2003を使用しています。

  • 【Find関数】あるのに見つからない。

    現在、VBAで、 Find関数で行う処理を記述しています。 以下、記述------------------------ Dim LastRow, onecell As String Dim OrderNew As String LastRow = Range("B38").End(xlDown).Row oldad = 38 For cnt = 38 To LastRow OrderNo = Range("D" & oldad).Value Range("K" & cnt).Value = Range("B" & oldad).Value Range("M" & cnt).Value = Range("C" & oldad).Value Range("N" & cnt).Value = Range("D" & oldad).Value Range("O" & cnt).Value = Range("E" & oldad).Value Range("P" & cnt).Value = Range("F" & oldad).Value Range("P" & cnt).Value = Range("G" & oldad).Value Range("Q" & cnt).Value = Range("H" & oldad).Value Set OrderNoResult = Range("D" & 38 & ":D" & LastRow).Find   (OrderNo, MatchByte:=False, MatchCase:=False,          LookIn:=xlValues, Lookat:=xlWhole, SearchOrder:=xlByRows) OrderResultValue = OrderNoResult.Value Do While OrderNoResult.Value = OrderResultValue       oldad = OrderNoResult.Row Set OrderNoResult = Range("D" & 38 & ":D" &LastRow).FindNext(OrderNoResult) If OrderNoResult Is Nothing Then Exit Do End If Loop Range("L" & cnt).Value = Range("B" & oldad).Value Range("R" & cnt).Value = Range("I" & oldad).Value oldad = oldad + 1 Next cnt 終わり---------------------------- 30週目で必ず止まります。値はあります。Ctrl+Fで同じ値をペーストして、実行して該当したので間違いありません。 また、一度停止し、再度実行すると、その一周は動き、また停止します。これを一回ずつ繰り返す場合は、問題なく処理されます。 オブジェクトの初期化のような処理が必要なのでしょうか? ご教授お願いいたします。

  • エクセルVBAで検索

    エクセルのVBAで文字の検索をしたいと思います エクセルは2000です エクセルのマクロの記録機能を利用して 下記のようなマクロを作成しましたが これでは、別のシートの文字が検索できません 同一ブックの別のシートも検索できるようにするには どうしたら良いでしょうか、よろしくお願いします 以下同一シートしか検索しない例 Sub Macro1() Dim 検索文字 As String 検索文字 = InputBox("検索文字を入力してください") Cells.Find(What:=検索文字, After:=ActiveCell, LookIn:=xlFormulas, LookAt:= _ xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:=False) _ .Activate End Sub

  • 文字ではなく数字で比較

    下のマクロで列を比較しますが,2358と12358が同じ文字になります. 下の文字を数字に変えたいです. Sub 比較して色を付ける() '比較部分 Dim RetRange As Range Range("D2:D35323").Select For i = 1 To 35323 Set RetRange = Selection.Find(What:=Cells(i, 4).Value, _ after:=ActiveCell, LookIn:=xlFormulas, _ LookAt:=xlPart, SearchOrder:=xlByRows, _ SearchDirection:=xlNext) If Not RetRange Is Nothing Then If RetRange.Address <> Cells(i, 4).Address Then RetRange.Interior.ColorIndex = 6 Cells(i, 4).Interior.ColorIndex = 6 End If End If Next END Sub マクロは全然知らない初心者です. よろしくお願いします.

  • EXCEL VBA テキストボックスの文字で置換したい

    いつもお世話になっています。 エクセルのVBAでフォームをつくり、フォーム上のテキストボックスに入力した文字でデータ変換をしようと考えています。たとえば「東京」を「東京都」という具合です。 メニューから実行すれば良いだけの話なのですが 業務上、より作業を簡素化したいためです。 下記のようにマクロを記述しましたが、うまく動作しないのでどうしてでしょうか?よろしくお願いします。 Sub 文字を置き換える() Dim mae As String Dim ato As String Columns("H:H").Select mae = UserForm1.TextBox2.Value ato = UserForm1.TextBox3.Value Selection.Replace What:=mae, Replacement:=ato, LookAt:=xlPart, _ SearchOrder:=xlByRows, MatchCase:=False, SearchFormat:=False, _ ReplaceFormat:=False End Sub

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

    文字検索マクロで質問です。 下記のマクロを作成したのですが、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 以上、宜しくお願い致します。

  • エクセル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

  • マクロの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 ・ ・ ・ ※の箇所で止まってしまいます。