Rendre les lignes obligatoires si la première cellule est renseignée

1

J'ai un fichier Excel dans lequel je veux que les gens remplissent des informations spécifiques. Je souhaite rendre obligatoire une plage de cellules d'une ligne si la première cellule de la ligne est remplie. Par exemple, si la cellule A7 est remplie, les cellules B7-07 doivent être renseignées. Et cela se répète jusqu'à ce qu'il y ait une cellule dans la colonne A qui n'est pas renseignée.

J'ai essayé quelques codages VBA pas très bons ici

Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean)

    If Sheets("Sheet1").Range("A7").Value <> "" And Sheets("Sheet1").Range("B7").Value = "" Or Range("C7").Value = "" Or Range("D7").Value = "" Or Range("E7").Value = "" Or Range("F7").Value = "" Or Range("G7").Value = "" Or Range("H7").Value = "" Or Range("I7").Value = "" Or Range("J7").Value = "" Or Range("K7").Value = "" Or Range("L7").Value = "" Or Range("M7").Value = "" Or Range("N7").Value = "" Or Range("O7").Value = "" Then
        MsgBox "Alla celler i en rad måste vara ifyllda för att du skall kunna spara. Kontrollera detta och spara igen."
        Cancel = True

    ElseIf Sheets("Sheet1").Range("A8").Value <> "" And Sheets("Sheet1").Range("B8").Value = "" Or Range("C8").Value = "" Or Range("D8").Value = "" Or Range("E8").Value = "" Or Range("F8").Value = "" Or Range("G8").Value = "" Or Range("H8").Value = "" Or Range("I8").Value = "" Or Range("J8").Value = "" Or Range("K8").Value = "" Or Range("L8").Value = "" Or Range("M8").Value = "" Or Range("N8").Value = "" Or Range("O8").Value = "" Then
        MsgBox "Alla celler i en rad måste vara ifyllda för att du skall kunna spara. Kontrollera detta och spara igen."
        Cancel = True

    ElseIf Sheets("Sheet1").Range("A9").Value <> "" And Sheets("Sheet1").Range("B9").Value = "" Or Range("C9").Value = "" Or Range("D9").Value = "" Or Range("E9").Value = "" Or Range("F9").Value = "" Or Range("G9").Value = "" Or Range("H9").Value = "" Or Range("I9").Value = "" Or Range("J9").Value = "" Or Range("K9").Value = "" Or Range("L9").Value = "" Or Range("M9").Value = "" Or Range("N9").Value = "" Or Range("O9").Value = "" Then
        MsgBox "Alla celler i en rad måste vara ifyllda för att du skall kunna spara. Kontrollera detta och spara igen."
        Cancel = True

    End If

End Sub

Cela fonctionne jusqu'à ce que j'arrive à:

ElseIf Sheets("Sheet1").Range("A9").Value <> "" And Sheets("Sheet1").Range("B9").Value = "" Or Range("C9").Value = "" Or Range("D9").Value = "" Or Range("E9").Value = "" Or Range("F9").Value = "" Or Range("G9").Value = "" Or Range("H9").Value = "" Or Range("I9").Value = "" Or Range("J9").Value = "" Or Range("K9").Value = "" Or Range("L9").Value = "" Or Range("M9").Value = "" Or Range("N9").Value = "" Or Range("O9").Value = "" Then
    MsgBox "Alla celler i en rad måste vara ifyllda för att du skall kunna spara. Kontrollera detta och spara igen."
    Cancel = True
End If

Ensuite, la MsgBox apparaît même si A9 n’est pas renseigné.

Je sais que ce n’est pas la meilleure façon de réaliser ce que je veux mais c’est ce que j’ai trouvé. Des suggestions pour un meilleur code?

Stax82
la source
Juste une suggestion: au lieu de Sheets("Sheet1").Range("B9").Value = "" Or Range("C9").Value = "" Or Range("D9").Value = "" Or Range("E9").Value = "" Or Range("F9").Value = "" Or Range("G9").Value = "" Or Range("H9").Value = "" Or Range("I9").Value = "" Or Range("J9").Value = "" Or Range("K9").Value = "" Or Range("L9").Value = "" Or Range("M9").Value = "" Or Range("N9").Value = "" Or Range("O9").Value = ""vous pouvez utiliserWorksheetfunction.countif(Sheets("Sheet1").Range("B9:O9"),"=")=0
Máté Juhász le
autre chose: vous n’avez utilisé Sheets("Sheet1")que pour les premières références, c’est très risqué, car d’autres pourraient changer de contexte.
Máté Juhász
Pourquoi ne pas essayer DATA VALIDATION est beaucoup plus facile !!
Rajesh S
@ RajeshS Désolé. Ne mentionnez pas que j'utilise déjà la validation des données pour contrôler si le contenu des cellules respecte certains critères. Puis-je avoir plus d'une validation de données dans une cellule?
Stax82
@ Stax82, puisque vous travaillez ligne par ligne, chaque ligne doit faire l'objet d'une validation distincte.
Rajesh S

Réponses:

2

Vous avez une erreur dans votre chaîne de conditions:

cond1 And cond2 Or cond3 Or cond4évaluera toujours Truesi (ou les deux) de cond3ou cond4sont True. C'est parce que Andsera évalué avant Or. Voir la documentation pour plus d'informations.

Vous pouvez utiliser des parenthèses pour ajuster l'ordre d'évaluation:

cond1 And (cond2 Or cond3 Or cond4)

Cette expression n'évaluera Trueque si cond1 et quels cond2, cond3, cond4sont True.


Dans votre cas, je recommanderais les améliorations suivantes à votre code:

  • Tout d’abord, découvrez les boucles dans VBA. For ... Nextet Do ... Loop sont les deux types que vous devez savoir.
  • Ensuite, pour rendre les choses un peu plus claires (c’est-à-dire que vos intentions soient visibles dans le code), insérez ce code de validation dans son propre sous-programme / fonction.
  • Et enfin, pour rendre encore plus évident ce qui se passe, vous pouvez diviser ces longues chaînes de conditions.

Si nous examinons maintenant la Workbook_BeforeSaveprocédure, il n’est pas immédiatement évident de savoir ce qu’elle fait ici (c’est peut-être pour vous, car vous venez de mettre le code là-bas et vous en avez l’esprit en tête - mais revenons à cette feuille dans 3/6 / 12 mois et vous aurez d’abord besoin de comprendre ce qu’il fait). Remédions à cela:

Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean)

    Cancel = IsUserInputMissing

End Sub

Private Function IsUserInputMissing() as Boolean

    ' Validation code goes in here

End Function

Désormais, tous ceux qui consultent le code peuvent savoir en un coup d’œil ce qui se passera lors de la sauvegarde du classeur.

Cette ligne

If Sheets("Sheet1").Range("A7").Value <> "" And Sheets("Sheet1").Range("B7").Value = "" Or Range("C7").Value = "" Or Range("D7").Value = "" Or Range("E7").Value = "" Or Range("F7").Value = "" Or Range("G7").Value = "" Or Range("H7").Value = "" Or Range("I7").Value = "" Or Range("J7").Value = "" Or Range("K7").Value = "" Or Range("L7").Value = "" Or Range("M7").Value = "" Or Range("N7").Value = "" Or Range("O7").Value = "" Then

n'est pas très amical aux yeux. Verbatim dit-il If FirstCellIsNotEmpty And AnyFollowingCellIsEmpty Then. Codons cela de cette façon.

Dim FirstCellIsEmpty as Boolean
FirstCellIsEmpty = Sheets("Sheet1").Range("A7").Value = ""

Dim AnyFollowingCellIsEmpty as Boolean
AnyFollowingCellIsEmpty = WorksheetFunction.CountBlank(Sheets("Sheet1").Range("B7:O7")) > 0

If Not FirstCellIsEmpty And AnyFollowingCellIsEmpty Then
    MsgBox "I don't know any Swedish. But please fill out the necessary cells."
End If

Notez l'utilisation de WorksheetFunction.CountBlankpour éviter de devoir taper chaque cellule à vérifier.


En fin de compte, je vais donner un exemple de ce à quoi votre IsUserInputMissingfonction pourrait ressembler. (Cependant, il reste encore beaucoup à faire.)

Private Function IsUserInputMissing() As Boolean

    ' Easy way to set the beginning of the range
    Const FirstRowToBeChecked As Long = 7
    ' Set a reference to the sheet that needs checking
    Dim Ws As Worksheet
    Set Ws = ThisWorkbook.Worksheets("Sheet1")

    Dim iRow As Long
    iRow = FirstRowToBeChecked

    Do

        Dim FirstCellIsEmpty As Boolean
        FirstCellIsEmpty = Ws.Cells(iRow, 1).Value = vbNullString ' vbNullString is a clearer way of saying ""
        ' Exit loop at the first empty row
        If FirstCellIsEmpty Then Exit Do

        Dim AnyFollowingCellIsEmpty As Boolean
        AnyFollowingCellIsEmpty = WorksheetFunction.CountBlank(Ws.Range(Ws.Cells(iRow, 2), Ws.Cells(iRow, 15))) > 0

        If AnyFollowingCellIsEmpty Then
            ' Any time the requirements are not met, notify user and abort checking and saving
            ' This is not as elegant as checking the whole range and collecting info about all missing inputs
            ' But it's way easier to code :)
            MsgBox "I don't know any Swedish. But please fill out the necessary cells. Tack!"
            IsUserInputMissing = True
            Exit Function
        End If
        ' Don't forget to increment the counter, otherwise you've got yourself an endless loop
        iRow = iRow + 1

    Loop

    ' If execution reaches this line, all rows fulfil the requirement
    ' IsUserInputMissing will have its Default value: False
End Function

Prenez votre temps et travaillez à travers. J'ai essayé de rendre les choses aussi claires que possible. Mais si quelque chose n'est pas clair. N'hésitez pas à demander. :)

Inarion
la source
Merci de votre aide. Maintenant, je vais développer ce code pour en faire un peu plus.
Stax82