2012-12-11 47 views
0

這是另一個問題,我覺得有一個簡單的答案,但我沒有找到它。我遍歷D列中的每個單元格並尋找特定日期(來自用戶輸入),並基於該單元格的日期和某些相應單元格中的日期,我正在更改該行的顏色。如何循環訪問特定列中的單元格並根據其內容刪除整行?

相反着色排的,我希望能夠將其刪除。

這裏是我的代碼,目前顏色的那些行:

Range(Cells(2, 4), Cells(Rows.Count, 4).End(xlUp)).Select 

Dim rCell, otherCell As Range 
Dim TheAnswer$ 
Dim ConvertedDate# 

TheAnswer = InputBox("In M/D/YY format, enter the first day of the month for which this report is being run." & _ 
        vbCr & vbCr & "For example, you would enter ""12/1/2012"" for the December 2012 report.", "Enter Date M/D/YY") 
ConvertedDate = CDate(TheAnswer) 

For Each rCell In Selection 
    If rCell.Value <> "" Then 
     If rCell.Value And rCell.Offset(, 5) < ConvertedDate And rCell.Offset(, 5) <> "" Then rCell.EntireRow.Interior.Color = RGB(255, 102, 0) 

     If rCell.Value < ConvertedDate And rCell.Offset(, 5) = "" Then 

      If rCell.Offset(, 6) < ConvertedDate And rCell.Offset(, 6) <> "" Then rCell.EntireRow.Interior.Color = RGB(255, 102, 0) 

      If rCell.Offset(, 7) < ConvertedDate And rCell.Offset(, 7) <> "" Then rCell.EntireRow.Interior.Color = RGB(255, 102, 0) 

     End If 

    End If 
Next rCell 

當我與rCell.EntireRow.Delete替代rCell.EntireRow.Interior.Color = RGB(255, 102, 0)我得到的錯誤。如果我單步執行代碼,我可以看到它實際上刪除了第一行,但是在下一行發現了錯誤。

我明明有多個「如果那麼」語句,但是如果第一個「如果那麼」條件被滿足,並且行被刪除,就應該移動到下一個單元格。在我看來,它仍然試圖檢查那個被刪除的行。我絕對不是Excel VBA專家,但我認爲應該在rCell.EntireRow.Delete之後添加一些內容,以告訴它移動到下一個單元格。我試過在Next rCell中加入,但是出錯了。 Exit For只是完全停止宏。

+1

這將是很有用的,看你的數據更詳細。刪除行(手動或使用VBA)的一種有效方法是在每行返回TRUE或FALSE時設置布爾IF測試,如果滿足刪除條件,則使用'Autofilter'刪除滿足的條件。範圍循環可能非常緩慢 – brettdj

+0

我的電子表格沒有什麼特別之處。它基本上只是D-K列中的日期列表。我不熟悉'Autofilter',所以我想我不得不考慮這一點。從上面的代碼可以看出,我最初的方法是更改​​行顏色。我也在想我也可以(或者)向其中一個單元格添加某些內容,然後刪除所有添加了內容的單元格的行。 – Mike

回答

2

看下面,我更新了一些重複的條件。最好的兩種方法是將數據添加到變體數組中,然後刪除或作爲brettdj提及的註釋添加標記,過濾然後批量刪除。我更喜歡下面的內容,因爲它可以很好地擴展並且是知道其他數據操作的良好實踐。不作爲沒有模板的基礎上進行測試。見下:

Dim data() As Variant 
Dim i As Double 
Dim deleteRows As Range 
Dim sht As Worksheet 

Dim theAnswer As String 
Dim ConvertedDate As Date 

Set sht = Sheet1 

theAnswer = InputBox("In M/D/YY format, enter the first day of the month for which this report is being run." & _ 
       vbCr & vbCr & "For example, you would enter ""12/1/2012"" for the December 2012 report.", "Enter Date M/D/YY") 
ConvertedDate = CDate(theAnswer) 

data = sht.Range(Cells(2, 4), Cells(Rows.Count, 4).End(xlUp)).Resize(, 8) 

    For i = 1 To UBound(data, 1) 

     If (data(i, 1) <> vbNullString) Then 

      If data(i, 1) <> vbNullString And data(i, 6) < ConvertedDate And data(i, 6) <> vbNullString Then 

       If (deleteRows Is Nothing) Then 
        Set deleteRows = sht.Rows(i + 1) 
       Else 
        Set deleteRows = Union(deleteRows, sht.Rows(i + 1)) 
       End If 

      ElseIf data(i, 1) < ConvertedDate And data(i, 7) <> vbNullString And data(i, 8) <> vbNullString Then 

       If data(i, 7) < ConvertedDate Or data(i, 8) < ConvertedDate Then 

        If (deleteRows Is Nothing) Then 
         Set deleteRows = sht.Rows(i + 1) 
        Else 
         Set deleteRows = Union(deleteRows, sht.Rows(i + 1)) 
        End If 

       End If 

      End If 

     End If 

    Next i 

deleteRows.Delete Shift:=xlUp 
+0

感謝您的幫助,Philip,但我無法讓您的代碼也能正常工作。我注意到的第一件事就是缺少了'End If',但即使我添加了一個,我也會在deleteRows = Sheet1.rows的行上得到運行時錯誤(Object variable或With block variable not set) (i + 1)'。 – Mike

+0

更新了我的帖子。 – InContext

+0

我很抱歉,但現在甚至沒有做任何事情。我想也許它和'Sheet1'部分有關(因爲這不是我用來測試的選項卡的名稱),但改變它只會破壞它。如果我逐句通過代碼,它似乎在工作,因爲它對各種「If Then」語句作出不同反應(即使我在電子表格中沒有看到任何事情發生),但它最終無所作爲。最後一步是否正確?或在正確的位置? 我知道你說過你不能測試它,但是我的電子表格中沒有什麼特別的......真正只是D-K列中的日期列表。 – Mike

2

邁克,當你遍歷範圍設置和刪除行,你需要從最後一排環落後,因爲當你刪除一行,不存在了,它得來的Excel,因爲該行已不再在循環範圍。

試試這個:

Range(Cells(2, 4), Cells(Rows.Count, 4).End(xlUp)).Select 

Dim rCell as Range, otherCell As Range 
Dim TheAnswer$ 
Dim ConvertedDate# 

TheAnswer = InputBox("In M/D/YY format, enter the first day of the month for which this report is being run." & _ 
        vbCr & vbCr & "For example, you would enter ""12/1/2012"" for the December 2012 report.", "Enter Date M/D/YY") 
ConvertedDate = CDate(TheAnswer) 

Dim xrows as Long, i as Long 
xrows = Selection.Rows.Count 

For i = xrows to 1 Step -1 

    Set rCell = Selection.Cells(i,1) 

    If rCell.Value <> "" Then 
     If rCell.Value And rCell.Offset(, 5) < ConvertedDate And rCell.Offset(, 5) <> "" Then rCell.EntireRow.Delete 

     If rCell.Value < ConvertedDate And rCell.Offset(, 5) = "" Then 

      If rCell.Offset(, 6) < ConvertedDate And rCell.Offset(, 6) <> "" Then rCell.EntireRow.Delete 

      If rCell.Offset(, 7) < ConvertedDate And rCell.Offset(, 7) <> "" Then rCell.EntireRow.Delete 

     End If 

    End If 

Next i 

不知道,如果你想都成爲EntireRow.Delete,但你可以很容易地切換回來。

+0

感謝您的幫助,Scott,但我無法讓您的代碼正常工作。如果我按原樣嘗試,則會收到編譯錯誤「當前作用域中的重複聲明」,該錯誤指向「Dim rows Long,i as Long」行。如果我使用與「rows」(如xrows)不同的單詞,我沒有收到編譯錯誤,但是確實出現錯誤,說明我嘗試運行它時下一行出現類型不匹配。 – Mike

+0

@Mike。你的代碼中可能有一個變量聲明爲'rows'。如果是這樣的話,你可以改變所有對'xrows'的引用,就像你開始做的那樣,但是你需要把它貫穿到它被使用的所有時候。所以'Dim xrow as Long','xrows = Selection.Rows','For i = xrows to 1 Step -1'。否則,它會繼續引用您的原始行聲明,這可能與我所做的不一致。 –

+0

這正是我認爲可能是問題所在,因爲當我試圖將它改變爲任何地方的首都** R **時,它一直在改變着我。問題是,我無法在任何地方找到它。我甚至爲整個項目搜索了** row **,結果什麼都沒有。我應該看看這個宣言是否存在,是否有一個全球性的地方? (幸運的是,我知道那很多),但是仍然在下一行出現了這個錯誤 - xrows = Selection.rows'。我現在正在考慮我無法找到的這一行聲明也在搞砸了。 – Mike

相關問題