2016-09-02 41 views
0

我已經搜索了這個答案,但無法完全找到我所需要的。我有一個用戶將粘貼數據的文檔,有時可達5000行(這是限制)。它有專欄A-AG。一些列是必需的,有些則不是。我被告知用戶可能會發布空白行的數據。Excel VBA如果行有數據,單元格不能爲空

我想在宏上工作,以提醒用戶缺少數據。我會將它綁定到用戶表單框。我想要解決這個問題的方法是循環遍歷從19開始(從數據開始的位置)到5000的行。如果該行有任何數據,則檢查所需的列。

例如,檢查第19行,如果有任何數據,請檢查F列。如果列F中缺少數據,則生成消息Box。我希望這是有道理的,任何幫助將不勝感激。

+0

使用[Range.AutoFilter方法]( https://msdn.microsoft.com/en-us/library/office/ff193884.aspx)將所有重要字段篩選爲空白。與Suntotal計數,看看它的過濾器發現任何東西,然後刪除它們。 – Jeeped

+1

如果需要列並且沒有任何內容,那麼爲什麼你甚至不在乎行的其餘部分? – Comintern

+0

@Comintern - 如果一個單元格中有內容,並且(例如)在該列上進行了SUM操作,則該總和可能無意義,如果該單元格只是垃圾數據而沒有在其他列中完成對應的必填字段。因此,如果非必填字段是必填字段,那麼檢查是否填寫了必填字段是非常合理的。 (或者反過來看,如果必填字段未完成,則不填寫非必填字段。) – YowE3K

回答

2

以下代碼將檢查19到5000中的每一行,查看前33列中是否有任何非空單元格(即A到AG),然後檢查某些單元格以確保它們是不是空。 (I任意決定,列F,G和J分別爲強制性的。)

Sub CheckRows 
    Dim r As Long 
    Dim c As Long 
    'Dim emptyRow As Boolean 

    With ActiveSheet 
     For r = 19 to 5000 
      'Edited based on suggestion by Scott Craner 
      If WorksheetFunction.CountA(.Range(.Cells(r, 1), .Cells(r, 33))) > 0 Then 
      'emptyRow = True 
      'For c = 1 To 33 
      ' If Not IsEmpty(.Cells(r, c)) Then 
      '  emptyRow = False 
      '  Exit For 
      ' End If 
      'Next 
      'If Not emptyRow Then 
       If IsEmpty(.Cells(r, "F")) Or _ 
        IsEmpty(.Cells(r, "G")) Or _ 
        IsEmpty(.Cells(r, "J")) Then 
        MsgBox "Row " & r & " has some compulsory cells not filled in" 
       End If 
      End If 
     Next 
    End With 
End Sub 
+0

不應該顛倒邏輯嗎​​? [見上面的評論](http://stackoverflow.com/questions/39301321/excel-vba-if-row-has-data-cell-cannot-be-blank#comment65936604_39301321)。 – Comintern

+0

@Comintern - 我**認爲**我的代碼正在檢查是否有任何數據在行中,如果有的話,如果列F等沒有填寫錯誤信息。現在你有我抓我的頭,因爲我看不出代碼中的錯誤。也許我最好測試一下。 – YowE3K

+0

關於代碼絕對沒有*不正確*,它只是解決問題的一種不必要的低效方法。 – Comintern

0

嘗試首先檢查所有細胞排成一列,並且如果任何數據被發現,然後檢查所需要的物品。像這樣的東西(我的VBA是相當生疏,所以這可能不是複製pastable,但它應該是接近):

Dim row As Integer, col As Integer, hasData As Boolean 
Dim errors() As String, errorText as String 

ReDim errors(1 To 1) As String 

For row = 19 To 5000 
    hasData = False 
    ` Check each cell in this row to see if it has data 
    For col = 1 To 33 
     If IsEmpty(Cells(row, col).Value) = True Then 
      hasData = True 
      Exit For 
     End If 
    Next col 

    If hasData Then 

     errorText = "" 

     `validate data here for this row 
     `set errorText to non-empty if an error found 

     If errorText <> "" Then 
      errors(UBound(errors)) = errorText 
      ReDim Preserve errors(1 To UBound(errors) + 1) As String 
     End If 
    End If 
Next row 

`if errors found, join all the errors together and show to user 
If UBound(errors) > 1 Then MsgBox Join(errors, vbCrLf) 
2

其他的答案工作,但效率較低,由於有逆轉的關鍵規則。沒有理由檢查一行是否爲空,除非其中一個必填字段丟失。從你的問題來看,規則是:

行必須包含所有必填字段,除非它們爲空。

這可以重新表述爲:

如果任何強制性字段爲空,整個行必須爲空。

第二的編程測試得多,高效得多,因爲你可以短路如果測試的第一部分是真實的:

Sub CheckRows() 
    Dim r As Long, c As Long, missingValue As Boolean 

    With ActiveSheet 
     For r = 1 To 5000 
      Select Case True 
       Case .Cells(r, "F") = vbNullString: 
        missingValue = True 
       Case .Cells(r, "G") = vbNullString: 
        missingValue = True 
       Case .Cells(r, "J") = vbNullString: 
        missingValue = True 
       Case Else 
        missingValue = False 
      End Select 
      'This is the ONLY CASE where you need to check if the row is empty. 
      If missingValue Then 
       If WorksheetFunction.CountA(.Range(.Cells(r, 1), .Cells(r, 33))) > 0 Then 
        MsgBox "Row " & r & " has some compulsory cells not filled in" 
       End If 
      End If 
     Next 
    End With 
End Sub 
+0

我會提高你的答案,因爲它幾乎肯定會更有效率(即使它可能不會引起用戶注意)。但是我有一種感覺,即許多經驗不足的編碼人員無法準確理解發生了什麼,因此如果他們遇到與OP相似的問題,將難以適應他們自己的情況。 – YowE3K

+0

@ YowE3K - 人們只能希望不能:-)我認爲唯一不明顯的部分應該是'Select Case'用於提供短路。我只是不想進入整個「如果」在VBA討論中沒有短路。 – Comintern

相關問題