人力検索はてな
モバイル版を表示しています。PC版はこちら
i-mobile

Excelで指定のキーワードを含む行を削除したいです。
既に http://oshiete.goo.ne.jp/qa/3705773.html のようなサイトでも類似の質問があり、試してみたのですが。
どうもうまくいきません。
Inputbox等は必要ありませんので、シンプルに「G列に指定のキーワードを含む行があれば、その行すべてを削除する」といったマクロがあればお教えいただきたいのですが。
データは30万件ほどあり結構重い作業になるかもですが…。
前回も似たような質問をしたのですが。 http://q.hatena.ne.jp/1416654240
応用させる実力がまだありませんでして…よろしくお願い致します。

●質問者: moon-fondu
●カテゴリ:コンピュータ 学習・教育
○ 状態 :終了
└ 回答数 : 4/4件

▽最新の回答へ

1 ● a-kuma3
●100ポイント

こんな感じで、どうでしょうか。

Const SPEED_UP = False  ' True で速くなる

Const MAX_ROW = 300000  ' 突っ走るのが怖いので
Const KEYWORD = "りんご"

Sub Delete_Row_Include_Keyword()

 On Error GoTo ErrorHandler

 If SPEED_UP Then
  'ワークシートに描画しない
 Application.ScreenUpdating = False
 End If

 r = 1
 Do While r < MAX_ROW
 Set c = Cells(r, 7)
 If IsEmpty(c) Or c.Value = "" Then
 Exit Do
 End If

 If InStr(c.Value, KEYWORD) > 0 Then
 c.EntireRow.Delete
 Else
 r = r + 1
 End If
 Loop

FINAL:
 If SPEED_UP Then
  '結果を描画する
 Application.ScreenUpdating = True
 End If
 Exit Sub

ErrorHandler:
 GoTo FINAL


End Sub

行を削除したいシートを選択した状態で、このサブルーチンを実行してください。
先頭の方にある KEYWORD を、適当に変えてください。

G列のセルが、空の行が出てくると、そこで止まります。
処理が延々と終了しないのは、ちょっと恐いので、行数のカウントで最大の行数も指定してます。

SPEED_UP という定数を True にすると、画面の描画を止めるので、少し早くなります。
中程度のノートブックで、2500行くらいで 0.5秒くらいです。
それでも、30万行もあると、パソコンの性能にもよりますが、数分かかると思います。

バックアップを取ってから、試してみてください。


moon-fonduさんのコメント
a-kuma3さんいつもありがとうございます! 実行してみたのですが…何も起きず、エラーメッセージも出ず、無反応でした。 Macでやってみたので、ちょっとWindowsの方でもやってみます!

a-kuma3さんのコメント
Windows だと、どうだったんでしょうか。 # というか、Windows の Excel 2010 で試したコードなので、動くとは思うんですが ポイントはどうでも良いのですけれど、Windows と Mac で、割りと普通っぽいマクロが動いたり、動かなかったりするのか、というところが、ものすごく気になります。

moon-fonduさんのコメント
すみません、やはりWindowsの方でもうまく動きません・・・。 「ThisWorkBook」というので動かすと何も起きず。 「標準モジュール」で動かすと「型が一致しません」と出てきます。 データが30万行以上でファイルサイズが95MBぐらいあるというのも、何かしら動作が不安定になってしまう原因なのでしょうか。 横もAA列までデータが入っております。 削除する手前の、「キーワードに一致したセルを含む行を選択していく」ような処理を行い、複数選択の状態とかでもよいのですが。 そうすれば後は右クリック→削除で何とかなると思います。 度々お尋ねしてすみません。

a-kuma3さんのコメント
>> 「ThisWorkBook」というので動かすと何も起きず。 「標準モジュール」で動かすと「型が一致しません」と出てきます。 << 回答では書き足りなかったのですが、マクロは「標準モジュール」で動作します。 んで、「型が一致しません」についてなのですが、もしかしたらキーワードを探す G列が<u style="color:red;">数式</u>になってないでしょうか? 試した感じでは、G列にエラーになっているセルがあると「型が一致しません」となります。 #REF! とか #DIV/0! とか。 もし、対象のシートがそのようになっているのであれば、エラーになっているセルがあったときに、 -無視して次の行を処理する(つまり、削除しない) -処理を中断する(目で見て、人が判断して、G列の値を手で直す) のどちらにするか決められるのであれば、マクロで処理ができると思います。

moon-fonduさんのコメント
エラーのある行を削除して実行しました。 でも動かなかったんですが・・・G列の1行目と2行目が空白セルだったので、ここにデータを入れてから実行したら、うまくマクロが稼働しました!(88215行目で止まりましたが……データは入ってました) ありがとうございましたm(_ _)m

2 ● ふるるP
●40ポイント

こんな感じでしょうか。

Public Sub DeleteRow()
Dim KeyWord As String
Dim R As Long
Dim MaxRow As Long

KeyWord = "er" '削除の条件

'G列がキーなのでG列で最終行を取得する
MaxRow = Range("G" & Cells.Rows.Count).End(xlUp).Row

'最後の行から1行目まで後ろからループさせることで読み飛ばしを回避する
For R = MaxRow To 1 Step -1
If Range("G" & R) = KeyWord Then
Rows(R).Delete
End If
DoEvents
Next

End Sub


1行目から順に・・・とすると削除すると行がずれてしまうので、後ろから順にまわすのがセオリーです。


moon-fonduさんのコメント
ありがとうございます。 ですが実行ボタンを押しても処理が何も起きない状態でして…。 Windowsの方でも試してみます!

moon-fonduさんのコメント
Windowsで試してみると「実行中」とは出てくるんですが、やはり何も起きない状態です・・・。

ふるるPさんのコメント
対象シートを選んだ状態になっているでしょうか? またKeyWordの条件は完全一致でよろしいでしょうか?それとも部分一致でしょうか? 部分一致の場合はIf文を修正しないといけません。 完全一致の場合、If分の行にブレークポイントを貼って一時停止させ、削除したい行の時に Rows(R).Deleteの行に来るか確認を。

moon-fonduさんのコメント
部分一致です!「#NAME?」と「#N/A」を消してやってみたら、やはり「実行中」とは出てくるんですが、マクロが動作しているときのWindows7の青丸がぐるぐるしている状態ではなく、動作していない白い十字の状態にすぐなってしまいます。 でもご回答いただきまして、ありがとうございます!

ふるるPさんのコメント
部分一致の場合、If文の行を次のようにしてください。 If Instr(Range("G" & R),KeyWord)>0 Then また、DoEventの前の行か後の行に次の行を追加してください。 Application.StatusBar = R & " / " & MaxRow 実行中はステータスバーに進行状況が表示されます。

3 ● ふるるP
●10ポイント

そうそう、速くするには Application.ScreenUpdating = Falseにしておきましょう。 DoEventsで「応答なし」を回避しています。毎回のループではおおすぎるのならDoEventsの行を次のようにしてもいいでしょう。
If R Mod 100 = 0 Then
DoEvents
Application.StatusBar = R & " / " & MaxRow
End If
100行ごとにDoEventsとステータスバーへ進行状況のメッセージを書き込みます。
条件も「含む」であるなら Like とかInstrとかを使って書き直す必要があります。


4 ● Mook
●300ポイント ベストアンサー

まともに行削除をすると数分オーダーなので、削除を一度にする例です。
セルの結合等あるとできないので、そのときは0ポイント配分で結構です。

作業列としてZ列を使用しているので、データがZ列以降にもある場合は、
コード中のZを十分大きな列名に変更してください。

30万行のデータで約3秒でした。

Option Explicit

Sub Main()
 Dim st
 st = Timer()
 DeleteRow "りんご", "G"
 Debug.Print Timer() - st
End Sub


Sub DeleteRow(keyWord As String, searchCol As String)
 Const DelNum = 9999999
 Const WorkCol = "Z"
 Dim lastRow As Long
 lastRow = Cells(Rows.Count, searchCol).End(xlUp).Row
 
 Dim kt
 kt = Cells(1, searchCol).Resize(lastRow)
 
 Dim st
 st = Cells(1, WorkCol).Resize(lastRow)
 
 Dim r As Long
 For r = 1 To lastRow
 If InStr(kt(r, 1), keyWord) = 0 Then
 st(r, 1) = r
 Else
 st(r, 1) = DelNum
 End If
 Next

 Cells(1, WorkCol).Resize(lastRow) = st
 
 ActiveSheet.Sort.SortFields.Clear
 ActiveSheet.Sort.SortFields.Add _
 Key:=Cells(1, WorkCol).Resize(lastRow), SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
 With ActiveSheet.Sort
 .SetRange Range("A1").Resize(lastRow, Cells(1, WorkCol).Column)
 .Header = xlGuess
 .Orientation = xlTopToBottom
 .SortMethod = xlPinYin
 .Apply
 End With
 
 Dim f As Range
 Set f = Columns(WorkCol).Find(DelNum, lookat:=xlWhole)
 If Not f Is Nothing Then Rows(f.Row & ":" & lastRow).Delete
 
 Columns(WorkCol).ClearContents
End Sub

moon-fonduさんのコメント
ありがとうございます!ですが「型が一致しません」というエラーが出てきまして、うまく処理が行われないです…MacのExcelを使っているからでしょうか、ちょっとWindowsの方で試してみます!

Mookさんのコメント
EXCEL のバージョンはいくつでしょうか。 エラーの出た場所は Sort の部分ですか?

moon-fonduさんのコメント
度々すみません。Windowsの方で試してみました。「デバッグ」をクリックすると、 If InStr(kt(r, 1), keyWord) = 0 Then の箇所が黄色くなっておりました。何か改善策等ご教授いただければ幸いです。

Mookさんのコメント
黄色くなったときに、r と keyWord、それから LasrRow の値は何でしょうか。 また G列の r 行にはどのようなデータがあったでしょうか。 変数の中身は、マウスカーソルを変数の上に持っていけば確認できます。

moon-fonduさんのコメント
あ、知らなかったです、確かにマウスカーソルを持っていったらr=77643行目がヒットしておりまして、そこに「#NAME?」と記載されてました! 消してもう1回やると、次は132329行目に「#N/A」とありました。 それも消して、もう1回やると・・・うまくいきました! ありがとうございますヽ(´▽`)/
関連質問

●質問をもっと探す●



0.人力検索はてなトップ
8.このページを友達に紹介
9.このページの先頭へ
対応機種一覧
お問い合わせ
ヘルプ/お知らせ
ログイン
無料ユーザー登録
はてなトップ