6

列 B に特定の値を含まない行を削除するマクロを実行しようとしています。これが私のコードです。

Sub deleteRows()
    Dim count As Integer
    count = Application.WorksheetFunction.CountA(Range("AF:AF"))
    Dim i As Integer
    i = 21
    Do While i <= count
        If (Application.WorksheetFunction.IsNumber(Application.WorksheetFunction.Search("OSR Platform", Range("B" & i))) = False) Then
            If (Application.WorksheetFunction.IsNumber(Application.WorksheetFunction.Search("IAM", Range("B" & i))) = False) Then
                Rows(i).EntireRow.Delete
                i = i - 1
                count = count - 1
            End If
        End If
        i = i + 1
    Loop
End Sub

今、それがすべきことは次のとおりです。

1.)通過する行数を見つけて、それをカウントとして設定します(これは機能します)

2.) 行 21 から開始し、列 B で「OSR プラットフォーム」と「IAM」を探します [この種の作品 (以下を参照)]

3.)どちらも見つからない場合は、行全体を削除し、必要に応じてカウントと行番号を調整します(これは機能します)

なんらかの理由で、コードが最初の If ステートメントに到達するたびに、「400」という赤い X が付いたエラー ウィンドウが表示されます。私が知る限り、私はすべてを構文的にしっかりと書いていますが、明らかに何かが間違っています。

4

2 に答える 2

9

他の方法でループすることから始めたいと思うかもしれません。行を削除すると、それ以前のすべての行がシフトされます。あなたはこれを説明しますが、逆ループは、ループ内で現在の位置をいつオフセットしたかを追跡するよりも理解するのが簡単です(とにかく私にとって):

For i = count To 21 Step -1

また、次のものに頼りすぎていますApplication.WorksheetFunction

(Application.WorksheetFunction.IsNumber(Application.WorksheetFunction.Search("OSR Platform", Range("B" & i))) = False)

InStr(Range("B" & i).value, "OSR Platform") > 0

Application.WorksheetFunctionはるかに多くの処理能力が必要であり、何を達成しようとしているかによっては、かなり長い時間がかかる場合があります。また、この提案された変更により、コード サイズが縮小され、コードなしでも読みやすくなります。

なしcountで取得することもできますA.WF:

  • エクセル 2000/03:count = Range("AF65536").End(xlUp).Row
  • エクセル 2007/10:count = Range("AF1048576").End(xlUp).Row
  • バージョンに依存しない:count = Range("AF" & Rows.Count).End(xlUp).Row

もう 1 つできること (この場合はすべきIfこと) は、ステートメントを 1 つに結合することです。

これらの変更を行うと、次のようになります。

Sub deleteRows()
    Dim count As Integer
    count = Range("AF" & Rows.Count).End(xlUp).Row
    Dim i As Integer
    For i = count To 21 Step -1
        If Len(Range("B" & i).value) > 0 Then
            If InStr(Range("B" & i).value, "OSR Platform") > 0 Or InStr(Range("B" & i).value, "IAM") > 0 Then
                Range("B" & i).Interior.Color = RGB(255, 0, 0)
            End If
        End If
    Next i
End Sub

これで問題が解決しない場合は、コードを 1 行ずつ実行できますか。ブレークポイントを追加し、 でステップスルーしF8ます。コード内の変数を強調表示し、右クリックして [ウォッチを追加...] を選択し、[OK] をクリックします (一般的なデバッグに役立つ優れたリソースです)。次の点に注意してください。

  • どの行でエラーが発生しますか?
  • の価値は何ですか、iそれcountはいつ起こりますか? (これらの変数に監視を追加してください)
于 2012-07-23T15:15:39.653 に答える
3

これは私にとってはうまくいきました。AutoFilter を使用し、ループやワークシート関数を必要としません。

Sub DeleteRows()

Dim currentSheet As Excel.Worksheet
Dim rngfilter As Excel.Range
Dim lastrow As Long, lastcolumn As Long

Set currentSheet = ActiveSheet

' get range
lastrow = currentSheet.Cells(Excel.Rows.Count, "AF").End(xlUp).Row
lastcolumn = currentSheet.Cells(1, Excel.Columns.Count).End(xlToLeft).Column
Set rngfilter = currentSheet.Range("A1", currentSheet.Cells(lastrow, lastcolumn))

' filter by column B criteria
rngfilter.AutoFilter Field:=2, Criteria1:="<>*OSR Platform*", Operator:= _
        xlAnd, Criteria2:="<>*IAM*"

' delete any visible row greater than row 21 which does not meet above criteria
rngfilter.Offset(21).SpecialCells(xlCellTypeVisible).EntireRow.Delete

' remove autofilter arrows
currentSheet.AutoFilterMode = False
End Sub

このコードは、列 B に AutoFilter を適用して、列 B に "OSR Platform" も "IAM" も含まれていない行を確認します。次に、21 より大きい残りの行を単純に削除します。最初にワークブックのコピーでテストします。

フィルタリング後に表示セルを選択するための適切な構文を思い出すことができないため、この OzGridスレッドに大いに敬意を表します。

于 2012-07-23T18:16:46.823 に答える