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
A 回答 (2件)
- 最新から表示
- 回答順に表示
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
以上
ありがとうございます。
VBA初心者なもので、知らない事が沢山ありました!
ソースレビュー頂き、かなりソースが見やすくなりました。
ただ、肝心の
>検索対象のシートに"ヶ月"、"ヵ月"という文字が記載されていると
>処理が遅くなってしまします。・・・
の部分の根本的な解決には至っておりません。。。
何か考えられる原因などありますでしょうか???
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・14歳の自分に衝撃の事実を告げてください
- ・架空の映画のネタバレレビュー
- ・「お昼の放送」の思い出
- ・昨日見た夢を教えて下さい
- ・【お題】絵本のタイトル
- ・【大喜利】世界最古のコンビニについて知ってる事を教えてください【投稿~10/10(木)】
- ・メモのコツを教えてください!
- ・CDの保有枚数を教えてください
- ・ホテルを選ぶとき、これだけは譲れない条件TOP3は?
- ・家・車以外で、人生で一番奮発した買い物
- ・人生最悪の忘れ物
- ・【コナン30周年】嘘でしょ!?と思った○○周年を教えて【ハルヒ20周年】
- ・ハマっている「お菓子」を教えて!
- ・最近、いつ泣きましたか?
- ・夏が終わったと感じる瞬間って、どんな時?
- ・10秒目をつむったら…
- ・人生のプチ美学を教えてください!!
- ・あなたの習慣について教えてください!!
- ・牛、豚、鶏、どれか一つ食べられなくなるとしたら?
- ・都道府県穴埋めゲーム
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
tryの終了
-
数値の定数を付ける時
-
C#で別スレッドの終了を知りたい
-
コンパイラとインタプリタとア...
-
SwingUtilities.invokeLater(ne...
-
Tomcat高負荷時の設定について
-
PHPでDB処理中にプログレスバー...
-
アコーディオンメニューをアン...
-
Javaでのデバッグコード削除
-
WPF C#でF10のイベント取得方法...
-
VBScriptでPing
-
素数判定を再帰処理で
-
Windowsサービスの処理
-
BLOB型の画像データを表示したい
-
ラベルの表示までが異常に遅い...
-
XMLHttpRequestのsendメソッド
-
ftp 同時複数接続の負荷テスト...
-
フリック時フリック方向に矢印...
-
「タイプ初期化子が例外をスロ...
-
エクセルVBAで、条件に一致する...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
tryの終了
-
Javaでのデバッグコード削除
-
Tomcat高負荷時の設定について
-
JavaでVBのDOEVENTSと同様の処...
-
[Java] while(true)の意味
-
ExcelVBA で文字列の特定の文字...
-
JavaScriptからJAVAクラスを呼...
-
アコーディオンメニューをアン...
-
SwingUtilities.invokeLater(ne...
-
重い処理を行っているとGIFアニ...
-
ftp 同時複数接続の負荷テスト...
-
数値の定数を付ける時
-
ラベルの表示までが異常に遅い...
-
特定のforwardパス以外をはじき...
-
C#で別スレッドの終了を知りたい
-
JDBCでテーブルUPDATE後の再検...
-
WPF C#でF10のイベント取得方法...
-
doGetとdoPostの違い
-
Mac上でWindowsのファイルパス...
-
PHPでDB処理中にプログレスバー...
おすすめ情報