2016-09-02 4 views
0

Ich habe nach dieser Antwort gesucht, kann aber nicht finden, was ich brauche. Ich habe ein Dokument, in dem Benutzer Daten einfügen, manchmal bis zu 5000 Zeilen (das ist das Limit). Es hat Spalten A-AG. Einige der Spalten sind erforderlich, andere nicht. Mir wurde gesagt, dass Benutzer Daten mit leeren Zeilen veröffentlichen können.Excel VBA Wenn Zeile Daten enthält, kann Zelle nicht leer sein

Ich versuche, an einem Makro zu arbeiten, um Benutzer auf fehlende Daten hinzuweisen. Ich werde dies an eine Benutzerformular-Box binden. Die Art, wie ich dieses Problem angehen wollte, wäre, Zeilen von 19 (wo die Daten starten) bis 5000 zu durchlaufen. Wenn die Zeile irgendwelche Daten hat, dann überprüfe die erforderliche Spalte.

Überprüfen Sie z. B. Zeile 19, wenn Daten vorhanden sind, überprüfen Sie Spalte F. Wenn Daten in Spalte F fehlen, generieren Sie Nachricht Box. Ich hoffe, das macht Sinn, und jede Hilfe würde sehr geschätzt werden.

+0

Verwenden [Range.AutoFilter Methode] (https://msdn.microsoft.com/en-us/library/office/ff193884.aspx) werden alle signifikanten Felder nach Leerzeichen filtern. Zählen Sie mit Suntotal, um zu sehen, dass der Filter nichts gefunden hat, und löschen Sie sie dann. – Jeeped

+1

Wenn eine Spalte erforderlich ist und nichts enthält, warum kümmert es Sie dann überhaupt, was in der restlichen Zeile steht? – Comintern

+0

@Comintern - Wenn eine Zelle etwas enthielt und (zum Beispiel) ein SUM für diese Spalte ausgeführt wurde, ist die Summe möglicherweise nicht sinnvoll, wenn diese Zelle nur Mülldaten ohne die entsprechenden Pflichtfelder in anderen Spalten enthielt. Es wäre daher durchaus sinnvoll zu prüfen, ob die Pflichtfelder ausgefüllt sind, wenn die nicht obligatorischen Felder dies sind. (Oder, anders herum, dass keine der nicht obligatorischen Felder ausgefüllt wurde, wenn die Pflichtfelder nicht ausgefüllt wurden.) – YowE3K

Antwort

2

Der folgende Code überprüft jede der Zeilen von 19 bis 5000. Sehen Sie, ob in den ersten 33 Spalten eine nicht leere Zelle vorhanden ist (dh A bis AG). Überprüfen Sie dann bestimmte Zellen, um sicherzustellen, dass sie sind nicht leer. (I entschieden willkürlich, dass Spalten F, G und J obligatorisch waren.)

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

Sollte die Logik nicht umgekehrt werden? [Siehe obigen Kommentar] (http://stackoverflow.com/questions/39301321/excel-vba-if-row-has-data-cell-cannot-be-blank#comment65936604_39301321). – Comintern

+0

@Comintern - Ich dachte, ** mein Code würde prüfen, ob Daten in der Zeile vorhanden sind, und wenn es eine Fehlermeldung gab, wenn die Spalte F usw. nicht ausgefüllt war. Jetzt muss ich scratchen mein Kopf, weil ich nicht sehen kann, was im Code falsch ist. Vielleicht sollte ich es besser testen. – YowE3K

+0

Es gibt absolut nichts * falsches * über den Code, es ist nur eine unnötig ineffiziente Art, das Problem anzugehen. – Comintern

0

Versuchen Sie, alle Zellen in einer Zeile überprüft zuerst, und wenn alle Daten gefunden wird, dann überprüfen Sie die gewünschten Elemente. So etwas wie diese (meine VBA ist ziemlich rostig, so kann dies nicht kopier verpastbarem sein, aber es sollte in der Nähe sein):

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

Die anderen Antworten arbeiten, sind aber weniger effizient durch mit der Grundregel umgekehrt. Es gibt keinen Grund zu prüfen, ob eine Zeile leer ist , es sei denn, eines der Pflichtfelder fehlt. Von Ihrer Frage aus lautet die Regel:

Zeilen müssen alle Pflichtfelder enthalten, sofern sie nicht leer sind.

Dies kann angepasst werden:

Wenn ein Pflichtfeld leer ist, muss die gesamte Zeile leer sein.

Die Programmierung Test für die zweite ist viel, viel effizienter, da Sie können Kurzschluss, wenn der erste Teil des Tests wahr ist:

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

Ich werde deine Antwort auffrischen, da sie mit ziemlicher Sicherheit effizienter sein wird (obwohl sie dem Benutzer wahrscheinlich nicht auffällt). Aber ich habe das Gefühl, dass viele weniger erfahrene Programmierer Schwierigkeiten haben werden, genau zu verstehen, was passiert, und daher Schwierigkeiten haben werden, sie an ihre eigene Situation anzupassen, wenn sie ein ähnliches Problem wie das OP haben. – YowE3K

+0

@ YowE3K - Man kann nur hoffen, nicht :-) Ich denke, der einzige nicht-offensichtliche Teil sollte sein, dass der 'Select Case' verwendet wird, um den Kurzschluss zu liefern. Ich wollte einfach nicht auf das ganze 'If' eingehen, das in der VBA-Diskussion nicht kurzschließt. – Comintern

Verwandte Themen