• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:[VBA]指定の範囲から指定の文字列の行を削除する)

[VBA]指定の範囲から指定の文字列の行を削除する

このQ&Aのポイント
  • VBAを使用して、指定範囲から指定の文字列の行を削除する方法について質問しています。具体的には、A列に入っている値が'FALSE'か'TRUE'の場合、昇順で並び替えて'FALSE'の行を削除したいです。質問者はColumnDifferencesメソッドを使用して試みましたが、'TRUE'か'FALSE'どちらかしか含まれていない場合にエラーが発生するため、別の方法を模索しています。
  • VBAを使用して特定の範囲から特定の文字列を含む行を削除したい場合の質問です。具体的には、A列に入っている値が'FALSE'か'TRUE'の場合、昇順で並び替えて'FALSE'の行を削除したいです。質問者はColumnDifferencesメソッドを使用した方法について調査していますが、'TRUE'か'FALSE'どちらかしか含まれていない場合にエラーが発生します。どのようなコードが適しているかのアドバイスをお願いします。
  • VBAを使用して指定範囲から特定の文字列の行を削除する方法についての質問です。具体的には、A列に入っている値が'FALSE'か'TRUE'の場合、昇順で並び替えて'FALSE'の行を削除したいです。質問者はColumnDifferencesメソッドを使用して試みましたが、'TRUE'か'FALSE'どちらかしか含まれていない場合にエラーが発生するため、別の方法を模索しています。どのような方法が最適か教えてください。

質問者が選んだベストアンサー

  • ベストアンサー
回答No.4

こんにちは。 > ColumnDifferencesメソッドの引数ComparisonはVariant型のようですが、文字列を指定することはできないのでしょうか? 少なくとも、文字列値を基準に列範囲を切り分けることは出来ません。 ComparisonはRange型専用 (改めて訊かれると詳しく調べた訳ではないので自信が揺らぎますが) と考えておいていいと思います。 Range型として受け取ることの出来るオブジェクト、 というような意図でそうした仕様になっているのでしょうが、 古めのVBAのメソッドには、特に理由も見当たらないのに オブジェクト型引数をVariant型にしていることが多々ありますね。 元々はExcelの一般機能をVBAから呼び出せるようにしたものですから、 列範囲を選択して、ショートカット Ctrl+Shift+| キーを押したタイミングの、 アクティブセルにあたるのが、引数Comparisonですので、値を指定する余地は無いような。 例外を挙げるなら、 selection.ColumnDifferences(null).select を実行すると、アクティブセルを無視して、 選択範囲の先頭セルがComparisonになりますから、 もしかしたらNull値を受け取る為のVariant型だったのかなぁ?とか。 それならObject型やRange型ではない、という理由の説明としては十分のような。 該当するオブジェクトが無い場合にエラーを返すメソッド の扱い方として基本通りのやり方として、2通り、 用途に合わせて使い分けてみて下さい。 勿論、単に   On Error Resume Next だけでも用途によっては十分というケースもあると思います。 ' /// Dim rng As Range   Set rng = Range("A1:A100")   On Error Resume Next   Set rng = rng.ColumnDifferences(rng(2))   If Err.Number <> 0 Then     MsgBox "ないよ!"   Else     rng.EntireRow.Delete   End If   On Error GoTo 0 ' /// ' /// Dim rng As Range Dim rng2 As Range   Set rng = Range("A1:A100")   On Error Resume Next   Set rng2 = rng.ColumnDifferences(rng(2))   On Error GoTo 0   If Not rng2 Is Nothing Then     rng2.EntireRow.Delete   Else     MsgBox "ないよ!"   End If ' /// (MsgBoxは仮設) range.ColumnDifferences メソッドは私も良く使いますが、 設計時によく迷う他の方法として、  AutoFilterで抽出後に表示・非表示の差分に対して処理(削除)する方法  セル範囲にフラグを出力しておいて、.SpecialCells()で切り分けて処理(削除)する方法   フラグを2種類のデータ型  [数値or文字列、 数値orエラー値、論理値or数値、、、]   の組合わせで建てておけば、range.SpecialCells(Type, Value)の引数Valueに [xlErrors,xlLogical,xlNumbers,xlTextValues]を指定して判別出来るので、.EntireRow.Delete などがあります。  前者は、抽出の前後で表示行数に変動があるかどうか、  後者は、該当するオブジェクトが無い場合にエラーを返すので、   .ColumnDifferences同様エラートラップで、判別します。   フラグの方でよく使うのは、    =(条件式)/1 みたいなExcel数式をセルに計算させておいて、    数値orエラー値で切り分けるとかですね。    場合によっては、二次元配列に格納したものを出力するとか、    Evaluateメソッドで丸ごと計算させる場合もあります。 いずれの方法でも、XL2010でしたら、ご承知のように、 ソートしてから削除するのが処理速度的にベターです。 2種の値だけを切り分ける目的でしたら、ソートした上で、 下方に位置する値の先頭行をrange.Findメソッドで取得して、 以降の行を削除する手もあります。 range.Findメソッドの場合は、 該当するオブジェクトが無い場合にもエラーにはなりませんから、   If Not Is Nothing Then みたいな判別だけで、 エラートラップ無しでも行けます。 エラートラップというと腰が引けちゃう人結構いるみたいですが、 エラーを放置して実行時エラーで処理が中断するこは問題になりますが、 エラートラップについては、オブジェクトを扱う以上は扱いに熟れた方がいいです。 野菜も食べましょうね!的なニュアンスで、これは閲覧者さん向けのメッセージです。 実例を見れば、もう少し絞り込んだ提案も出来ると思いますが、一般論として、 とりあえず、以上です。 何か不足、不明があれば、遠慮なくお尋ねください。

rihitomo
質問者

お礼

例を2つもあげていただきありがとうございます。 また、Comparisonについても解説も分かりやすくご説明いただきありがとうございます。 仰るようにSpecialCellsで判定できるようにする方法もありますね。 ちょっと目から鱗でした、ありがとうございます。 エラートラップ、Findメソッド、SpecialCellsを使い分けられるよう精進したいと思います。

その他の回答 (4)

回答No.5

No.4です、訂正です。 誤) > =(条件式)/1 正)  =1/(条件式) でした。 条件式がFalseならdiv0エラーを返す、という意味です。 取り急ぎ訂正のみ。失礼しました。

  • kagakusuki
  • ベストアンサー率51% (2610/5101)
回答No.3

Dim rng As Range  rng = Range("A1:A100")  rng.ColumnDifferences(”TRUE”).EntireRow.Delete としたのでは、例えA1:A100の範囲にTRUEが入力されているセルが存在している場合でもエラーになると思います。  一例としては次の様にされては如何でしょうか。 Sub QNo9090068_指定の範囲から指定の文字列の行を削除する() Dim rng As Range, c As Range Set rng = Range("A1:A100") Set c = rng.Find(True, , xlValues, xlWhole) If Not c Is Nothing Then rng.ColumnDifferences(c).EntireRow.Delete End Sub

rihitomo
質問者

お礼

true値が指定範囲にあるかどうかをFindメソッドで調べるということですね。 処理分岐もできるしとても参考になりました。ありがとうございます。

  • dogs_cats
  • ベストアンサー率38% (278/717)
回答No.2

スマートなやり方ではありませんが、ソート後にfalseの最初の行番号をワークシート関数のmatchで取得、終了位置はcountif関数で取得し、行を削除する。 match関数なのでセル範囲がA1から指定しないと行がずれます。 Sub test() Dim StRow, EndRow, cnt As Integer Dim rng As Range Set rng = Range("A1:A100") On Error GoTo myError rng.Sort _ Key1:=Range("A1"), Order1:=xlAscending StRow = Application.Match(False, rng, 0) cnt = Application.CountIf(rng, False) EndRow = StRow + cnt - 1 Rows(StRow & ":" & EndRow).Delete myError: End Sub

rihitomo
質問者

お礼

参考になりました。ありがとうございます。

  • ushi2015
  • ベストアンサー率51% (241/468)
回答No.1

こんにちは Sub test() Dim rng As Range Set rng = Range("A1:A100") On Error Resume Next rng.ColumnDifferences(rng(2)).EntireRow.Delete On Error GoTo 0 End Sub これでいいのかと思います。 後はオートフィルタかけて行削除するとか。

rihitomo
質問者

お礼

参考になりました。ありがとうございます。

関連するQ&A

専門家に質問してみよう