Excel VBA 質問スレッド No.146 (解決済)

C列のi行目の値が文字列abcではなかったら行を削除する

投稿者 : tikdom     投稿日時 : 2020/12/17(Thu) 16:19:21     OS : Windows 7     EXCEL : Excel 2010
標題の通りです。
以下のvbaで思い通りにいかない実行結果がでます
Dim i As Long
Dim MR As Long
MR = Cells(Rows.Count, 1).end(xlUp).Row
Range("C2").Select
For i = 2 To MR
If Cells(i, "C").Value <> "abc" Then
Rows(i).delete
End If
Next i

VBAど初心者です。原因が分からないので解決策を説明つきでお願いします。

[返信 1] Re : C列のi行目の値が文字列abcではなかったら行を削除する
投稿者 : EUNO     投稿日時 : 2020/12/17(Thu) 20:10:52
スマホからなので間違ってたらすみません。

> Range("C2").Select
この行は不要です。

> For i = 2 To MR

行削除する場合は下から削除していきます。
上の行から削除すると、例えば
3行目を削除→4行目が条件に一致するかみる
というときに見ている4行目は元の5行目になります。
説明が下手だけど、ご理解いただけますか。
答えは書きませんが、stepキーワードを使います。

> If Cells(i, "C").Value <> "abc" Then

これでも動くのでしょうけど、通常は行も列も数値で指定します。
Cells(i,3).value

[返信 2] Re : C列のi行目の値が文字列abcではなかったら行を削除する
投稿者 : tikdom     投稿日時 : 2020/12/17(Thu) 23:18:47
アドバイスありがとうございます!
下の行から削除するように記述して実行してみたらできました。
ちなみに、これって何故下から削除しないとできないんでしょうか?

[返信 3] Re : C列のi行目の値が文字列abcではなかったら行を削除する
投稿者 : ヘンリー     投稿日時 : 2020/12/18(Fri) 10:03:17
■[返信 2] tikdomさん(2020-12-17 23:18:47)の記事
> アドバイスありがとうございます!
> 下の行から削除するように記述して実行してみたらできました。
> ちなみに、これって何故下から削除しないとできないんでしょうか?


EUNO様からの回答を、何回も読み直してみて下さい。
EUNO様のおっしゃる通りです。

【EUNO様回答引用】
>上の行から削除すると、例えば
>3行目を削除→4行目が条件に一致するかみる
>というときに見ている4行目は元の5行目になります。

※読み直してもわからない場合、行削除の後に、
Debug.Print i
と入れて、For文のiという変数が何行目を指していくかを
イミディエイトウィンドウで確認するか、
或いは、F8キーで1行ずつデバッグして、変数の値の変化を見てて下さい。
※「F8キーで1行ずつデバッグ」は、今後も必ず役に立つと思います。


上から削除したいのであれば、Do~Loopを使うことで
実現可能かと思います。

①何行目をみるための変数iに2を格納(2行目から開始している為)

②i行目の1列目のセルの値が、""(長さ0の文字列)になるまで繰り返し(③~⑤)

③i行目のC列の値と、文字列"abc"を否定の比較

④③が真の場合のみ、i行目を削除

⑤③が偽の場合のみ、変数iに1を足したものを変数iに格納(インクリメント)‌

⑥繰り返し処理ここまで(③~⑤)

この様に、日本語で書けてしまえば、
あとは、ネット検索すれば何とかなります。

まずは、Do~Loop文②と⑥について調べてみて下さい。
注意点は、繰り返しをぬける条件です。
②のように、繰り返し処理をぬける条件を、
長さ0の文字列""とする場合、比較対象のセルの内容も、
長さ0の文字列""になるようにしなければなりません。
※長さ0の文字列とは、文字数をカウントすると0になる文字列です。
 VBAでは「文字列はダブルコーテーションでくくる」というルールがありますので、
 ""と書くことで、文字のない文字列、つまり長さ0の文字列となります。

例)Do Until Trim(Cells(1, 1).Value & "") = ""
これは、1行目の1列目のセルの値をトリミングして
長さ0の文字列を付けた物と、長さ0の文字列を比較して
繰り返し処理をぬける条件としています。
人間の目には、セルの中身がなにもないように見えますが、
(巷では、「セルが空白」などと言われている)
セルの書式設定などの状況によっては、Temp、Null、長さ0の文字列なのか、
半角スペース又は全角スペースが入っているかどうかは、わかりません。
なので、Trim(トリミング)でスペースを取り除き、
長さ0の文字列を「&」で文字列結合することで、
長さ0の文字列に置き換えて比較しています。

Do~Loop文を調べて、長さ0の文字列と比較できれば、
tikdom様が書いたコードを書けるくらいの力で十分です。
①、③、④、⑤の部分は、tikdom様自身で、出来ると思います。

[返信 4] Re : C列のi行目の値が文字列abcではなかったら行を削除する
投稿者 : tikdom     投稿日時 : 2020/12/19(Sat) 00:24:39
■[返信 3] ヘンリーさん(2020-12-18 10:03:17)の記事
> ■[返信 2] tikdomさん(2020-12-17 23:18:47)の記事
> > アドバイスありがとうございます!
> > 下の行から削除するように記述して実行してみたらできました。
> > ちなみに、これって何故下から削除しないとできないんでしょうか?
> >

> EUNO様からの回答を、何回も読み直してみて下さい。
> EUNO様のおっしゃる通りです。

> 【EUNO様回答引用】
> >上の行から削除すると、例えば
> >3行目を削除→4行目が条件に一致するかみる
> >というときに見ている4行目は元の5行目になります。

> ※読み直してもわからない場合、行削除の後に、
> Debug.Print i
> と入れて、For文のiという変数が何行目を指していくかを
> イミディエイトウィンドウで確認するか、
> 或いは、F8キーで1行ずつデバッグして、変数の値の変化を見てて下さい。
> ※「F8キーで1行ずつデバッグ」は、今後も必ず役に立つと思います。


> 上から削除したいのであれば、Do~Loopを使うことで
> 実現可能かと思います。

> ①何行目をみるための変数iに2を格納(2行目から開始している為)

> ②i行目の1列目のセルの値が、""(長さ0の文字列)になるまで繰り返し(③~⑤)

> ③i行目のC列の値と、文字列"abc"を否定の比較

> ④③が真の場合のみ、i行目を削除

> ⑤③が偽の場合のみ、変数iに1を足したものを変数iに格納(インクリメント)‌

> ⑥繰り返し処理ここまで(③~⑤)

> この様に、日本語で書けてしまえば、
> あとは、ネット検索すれば何とかなります。

> まずは、Do~Loop文②と⑥について調べてみて下さい。
> 注意点は、繰り返しをぬける条件です。
> ②のように、繰り返し処理をぬける条件を、
> 長さ0の文字列""とする場合、比較対象のセルの内容も、
> 長さ0の文字列""になるようにしなければなりません。
> ※長さ0の文字列とは、文字数をカウントすると0になる文字列です。
>  VBAでは「文字列はダブルコーテーションでくくる」というルールがありますので、
>  ""と書くことで、文字のない文字列、つまり長さ0の文字列となります。

> 例)Do Until Trim(Cells(1, 1).Value & "") = ""
> これは、1行目の1列目のセルの値をトリミングして
> 長さ0の文字列を付けた物と、長さ0の文字列を比較して
> 繰り返し処理をぬける条件としています。
> 人間の目には、セルの中身がなにもないように見えますが、
> (巷では、「セルが空白」などと言われている)
> セルの書式設定などの状況によっては、Temp、Null、長さ0の文字列なのか、
> 半角スペース又は全角スペースが入っているかどうかは、わかりません。
> なので、Trim(トリミング)でスペースを取り除き、
> 長さ0の文字列を「&」で文字列結合することで、
> 長さ0の文字列に置き換えて比較しています。

> Do~Loop文を調べて、長さ0の文字列と比較できれば、
> tikdom様が書いたコードを書けるくらいの力で十分です。
> ①、③、④、⑤の部分は、tikdom様自身で、出来ると思います。


アドバイスありがとうございます。
実はDo 〜Loop文でできるかなと思い、既に試したのですが、ヘンリーさんと同じ様に考えて同じ様
に記述し、そうすると定義またはメゾットが存在しませんみまいなメッセージがでて実行されませんでした。
調べても原因が私には分からなかったため、実行自体はされたFor Nextで行削除をできるようにしようと思い、ここに質問を投げました。

[返信 5] Re : C列のi行目の値が文字列abcではなかったら行を削除する
投稿者 : ヘンリー     投稿日時 : 2020/12/19(Sat) 09:54:57
> アドバイスありがとうございます。
> 実はDo 〜Loop文でできるかなと思い、既に試したのですが、ヘンリーさんと同じ様に考えて同じ様
> に記述し、そうすると定義またはメゾットが存在しませんみまいなメッセージがでて実行されませんでした。
> 調べても原因が私には分からなかったため、実行自体はされたFor Nextで行削除をできるようにしようと思い、ここに質問を投げました。

解決済みとなってはいましたが、
私としても、まだ勉強中の身ではありますが、
こちらとしては、サンプルを作って成功してから
解説をしたつもりです。

以下のコードでもダメか、是非お試しいただき、
結果を教えていただけると幸いです。

Sub RowDeleteSample()
Dim lngRow As Long

lngRow = 2

Do Until Trim(Cells(lngRow, 1).Value & "") = ""
If Cells(lngRow, 3).Value <> "abc" Then
Rows(lngRow).Delete
Else
lngRow = lngRow + 1
End If
Loop

End Sub

当掲示板について
返信入力フォーム
お 名 前  :
内  容   :
ステータス  : この質問を解決済みにする

認証コード  :
        キャプチャ画像


( 処理日時 : 2021-01-27 13:08:51 )

Page
Top