プロが教える店舗&オフィスのセキュリティ対策術

エクセルでマクロを使ってデータ管理をしています。
そのうちの一つなんですが、下記のようなデータがあります。

[コード][数量]
DESS   10
QWY    2
AFE    12
123BE  300
124BS  200
128BE1   5

と続いていきます(だいたいデータ量が1万件ぐらいです)

このデータのうち、”DESS”と”AFE”、そして末尾に”BE”、”BE1”がつくものだけ
データを抽出し、それ以外のデータを削除をしたいのです。

以前は、抽出するコードがそれほど多くなかったので、
If Cells(i, 5) <> "DESS" And _
Cells(i, 5) <> "AFE" And _
Cells(i, "E") <> "123BE" Then
.Rows(i).Delete

と書いて削除していたのですが、BEの頭につく数字のパターンが
あまりにも多いので(123BE,125BE,342BE等々、約30ほど)
末尾にBEがつくもの、BE1がつくものと、DESS、AFEを残して
それ以外を削除、とマクロを書きたいのですが、どうしてもうまくいかず・・

どなたか教えてください!!

どうぞよろしくお願い致します!!!

質問者からの補足コメント

  • うれしい

    すいません、Goo先生を使ったのがはじめてで、お礼から返信してしまいました(>_<)
    お礼に書き込んだ後に気づいたのですが、
    「BE」も「BE1」もコードの終わりになるので、終わるもの、なのですが
    そのほかのデータに「BE」が含まれることはないんです。
    なので、
    1.「BE」を含むもの、
    2.「DESS」と一致するもの
    3.「AFE」と一致するもの
    それ以外を削除。
    と、マクロが書けたらすごくすごくありがたいです。
    そしていずれの場合も空白も文字列の一部として判定できたらありがたいです!

    どうぞよろしくお願い致します!

    No.2の回答に寄せられた補足コメントです。 補足日時:2016/10/03 10:37
  • HAPPY

    みなさま、ありがとうございました!
    いろいろな方法があるんですね。
    本当に勉強になりました。お時間いただき、ありがとうございました!

      補足日時:2016/10/03 13:19

A 回答 (9件)

すみません


「If Not InStr(Cells(i, 5).Value, "BE") Then」を「If InStr(Cells(i, 5).Value, "BE") Then」にして下さい。
    • good
    • 0
この回答へのお礼

ありがとうございます!!!
やってみますー!
根気よく教えていただき、本当に感謝しております!
ありがとうございましたー

お礼日時:2016/10/03 13:18

No.7です。



たびたびごめんなさい。
全く逆のコトをしていました。
無視してください。

どうも失礼しました。m(_ _)m
    • good
    • 0
この回答へのお礼

あっ。そうなんですか??
すいません、それすらわからず(^^;
いえいえ、とんでもないです。コメントありがとうございました!!

お礼日時:2016/10/03 13:07

こんにちは!



>だいたいデータ量が1万件ぐらいです
というコトですので、オートフィルタで一気にやってみました。
1行目項目行でデータは2行目以降にあるとします。
ただ他の方々の回答を拝見するとE列に「コード」が記載されているのですね?
というコトだとするとE列でオートフィルタをかけています。

Sub Sample1()
Dim lastRow As Long, myRng As Range
lastRow = Cells(Rows.Count, "E").End(xlUp).Row
Application.ScreenUpdating = False
'▼まず「DESS」と「AFE」の完全一致のE列セルを変数「myRng」に格納//
Range("E:E").AutoFilter field:=1, Criteria1:=Array("DESS", "AFE"), Operator:=xlFilterValues
If Cells(Rows.Count, "E").End(xlUp).Row > 1 Then
Set myRng = Range(Cells(2, "E"), Cells(lastRow, "E")).SpecialCells(xlCellTypeVisible)
End If
'▼「BE」が含まれるE列セルを「myRng」に格納//
Range("E:E").AutoFilter field:=1, Criteria1:="*BE*"
If Cells(Rows.Count, "E").End(xlUp).Row > 1 Then
If myRng Is Nothing Then
Set myRng = Range(Cells(2, "E"), Cells(lastRow, "E")).SpecialCells(xlCellTypeVisible)
Else
Set myRng = Union(myRng, Range(Cells(2, "E"), Cells(lastRow, "E")).SpecialCells(xlCellTypeVisible))
End If
End If
ActiveSheet.AutoFilterMode = False
If Not myRng Is Nothing Then
myRng.EntireRow.Delete
End If
Application.ScreenUpdating = True
End Sub

※ コード内の
>Array("DESS", "AFE"), Operator:=xlFilterValues
の部分はExcel2007以降で使用可能だったと思います。
お使いのバージョンが2003以前の場合は
少しコードが変わってきます。m(_ _)m
    • good
    • 0
この回答へのお礼

おぉおお。こんなやり方も!
オートフィルターをかける方法は私もやれないかどうか試してみたんですが
まったくもってこのクォリティには追いついていなかったですね笑
そうなのです、E列にコードが入っています。すいません、説明不足で・・。
今書きかけなのですが、のちほどこれでやってみます!
ありがとうございました!!

お礼日時:2016/10/03 12:05

No.1です。



>Rightのあと、Valueで指定するんですね。
Rightのあと、という訳ではなく、セルの値を書く時はValueを付けた方がいいと思います。
    • good
    • 0
この回答へのお礼

なるほど、なるほどです。ありがとうございますー!
ちょっとだけ頭よくなった、気がしています(笑)
今後の参考にさせていただきますー!

お礼日時:2016/10/03 11:26

それでしたら「No.3」の


「If Right(Cells(i, 5).Value, 2) <> "BE" Then」と「 If Right(Cells(i, 5).Value, 3) <> "BE1" Then」を削除して「If Not InStr(Cells(i, 5).Value, "BE") Then」を追加してください。また「End If」が1つ多くなるので1つ削除して下さい。
    • good
    • 0
この回答へのお礼

むむむ。すいません。
いろいろ変えてしまったせいなのか、BEを含むものが出てこなくなってしまいました。。
以下、変えたコードです。

Dim i As Long
Application.ScreenUpdating = False
For i = Cells(Rows.Count, 5).End(xlUp).Row To 2 Step -1
If Not InStr(Cells(i, 5).Value, "BE") Then
If Cells(i, 5).Value <> "DESS" Then
If Cells(i, 5).Value <> "AFE" Then
Rows(i).Delete
End If
End If
End If
Next
Application.ScreenUpdating = True

どこか間違ってしまっていますでしょうか・・すいません(;;)
ちなみにEnd subはこの後に続くコードの後で書いてあります!

どうぞよろしくお願いいたしますー!

お礼日時:2016/10/03 11:50

No.3 の補足



②「BE1」を含む物
でしたら「If Right(Cells(i, 5).Value, 3) <> "BE1" Then」を「If Not InStr(Cells(i, 5).Value, "BE1") Then」に変更して下さい。
    • good
    • 1
この回答へのお礼

そしてこちらもありがとうございます!
含むもの、というのを選びたいときはこう書くのですねー。
にわかVBAというか、ほぼ初心者で、前任者が書き上げた立派なマクロを
なんとかかんとかしながら、データと向き合っているので、教えていただいたおかげで
少しわかってきた感じがします。
ちなみに、下の注釈につけていただいた、③ですが、ご指摘どおりタイトル行があって
2行目からだったので、書き換えてみました。ありがとうございましたー!

お礼日時:2016/10/03 10:55

それでしたらこんなのはいかがでしょうか?


---------------------------------------------------------
Sub Sample()
Dim i As Long
Application.ScreenUpdating = False
For i = Cells(Rows.Count, 5).End(xlUp).Row To 1 Step -1
If Right(Cells(i, 5).Value, 2) <> "BE" Then
If Right(Cells(i, 5).Value, 3) <> "BE1" Then
If Cells(i, 5).Value <> "DESS" Then
If Cells(i, 5).Value <> "AFE" Then
Rows(i).Delete
End If
End If
End If
End If
Next
Application.ScreenUpdating = True
End Sub
---------------------------------------------------------
以下ループ命令の部分が書かれていなかったので大きなお世話かもしれませんが説明しておきます。
※①「Application.ScreenUpdating = False」と「Application.ScreenUpdating = True」は画面の書き換えを止めてスピードアップを図っています。
※②「Cells(Rows.Count, 5).End(xlUp).Row」はE列の最後の行になります。
※③ タイトル行があって2行目からデータが始まるのならば「For i = Cells(Rows.Count, 5).End(xlUp).Row To 1 Step -1」は「For i = Cells(Rows.Count, 5).End(xlUp).Row To 2 Step -1」に直して下さい。
    • good
    • 0
この回答へのお礼

いろいろな方法があるのですね!すごいです!
①のApplication.ScreenUpdating、やってみました!確かに早い!!
データ量が多くて抽出するのに時間がかかっていたんですがスピードあがりました!
ありがとうございますー!

お礼日時:2016/10/03 10:51

続けて記述されてしまっているので判り難いので条件の確認です。


--------------------------------------------------
次の4つの条件を1つも満たさない物を削除
①「BE」で終わる物
②「BE1」を含む物
③「DESS」と一致する物
④「AFE」と一致する物
--------------------------------------------------
その他確認したい事項
・②の条件の「1」は全角ですよね?
・前後に空白を含んでいた場合、空白も文字列の一部として判定しますか?[ 例:「AFE」はOK、「AFE 」はNG]
この回答への補足あり
    • good
    • 0
この回答へのお礼

ありがとうございます!
なんときれいに整理していただき、恐縮です。
ほとんどご指摘どおりで、②だけ、BE1で終わるもの、です。
そして1は全角になります。
空白があった場合でも文字列の一部と判定し、抽出したいです!
空白まで含めることができるのであればぜひぜひ、知りたいです!!

お礼日時:2016/10/03 10:16

抽出する方をORで記述して、それ以外を削除 とした方が簡単です。



If Cells(i, 5).Value = "DESS" Or _
Cells(i, 5).Value = "AFE" Or _
Right(Cells(i, 5).Value, 2) = "BE" Or _
Right(Cells(i, 5).Value, 3) = "BE1" Then
Else
Rows(i).Delete
End If
    • good
    • 0
この回答へのお礼

うわぁぁぁ!ありがとうございます!ありがとうございます!
できましたできました(;;)涙、感動。助かりましたー!
Rightのあと、Valueで指定するんですね。
いいこと覚えました!ありがとうございますー!

お礼日時:2016/10/03 10:13

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!