j'ai pris quelques libertés pour répondre à vos questions parce que j'ai vu des occasions d'améliorer votre code contre seulement vous amener à la réponse. Le code ci-dessous devrait être plus facile à lire/gérer et j'espère qu'il vous aidera à écrire un meilleur code dans le futur ci-dessous. Code d'abord, puis je vais vous expliquer le processus:
Private Sub CommandButton1_Click()
Dim Inputs(1 To 3) As Variant
Dim Total As Double
' It is better to anticipate errors (check the values that could cause an error) than it is to
' use a GoTo block that catches everything.
' On Error GoTo errHandler
Inputs(1) = GetInputFromTextbox(UserForm1.textbox1)
Inputs(2) = GetInputFromTextbox(UserForm1.textbox2)
Inputs(3) = GetInputFromTextbox(UserForm1.textbox3)
' Handle the errors all in the same block (simply for readability)
If IsEmpty(Inputs(1)) Then
InvalidInput "Textbox1"
UserForm1.Hide
ElseIf IsEmpty(Inputs(2)) Then
InvalidInput "Textbox2"
UserForm1.Hide
ElseIf IsEmpty(Inputs(3)) Then
InvalidInput "Textbox3"
UserForm1.Hide
Else
' This will only execute if the three previous inputs are valid
Total = Application.WorksheetFunction.Sum(Inputs)
If Total <> 1 Then
TotalInputsInvalid Total
End If
End If
End Sub
' Define the function as a variant so it can return a null value
' This is important since the user could enter a 0 value and the default return of
' the function, if defined as a numeric type, would be 0. This would, in turn, prevent error handling.
Private Function GetInputFromTextbox(ByVal InputMember As Object) As Variant
If IsNumeric(InputMember.Value) Then
If CDbl(InputMember.Value) < 1 Then
GetInputFromTextbox = Round(CDbl(InputMember.Value), 2)
End If
End If
' Notice that, if the conditions for a valid input are not met, nothing happens.
' This allows us to handle errors within the calling routine.
End Function
' This will alert the user if the input given is invalid.
Private Sub InvalidInput(ByVal MemberName As String)
MsgBox "There is an invalid input in " & MemberName & ". Please enter value between 0.0 and 1.0."
End Sub
Private Sub TotalInputsInvalid(ByVal TotalValue As Double)
MsgBox "The total value of all inputs must equal 1. The current total is " & Round(TotalValue, 2) & ". Please adjust the inputs accordingly."
End Sub
D'abord, je l'ai défini une variable pour les valeurs d'entrée. Le principal avantage de ceci est que votre code est plus propre et plus logique. Avoir des variables telles que Foo1, Foo2, Foo3, etc rend votre code un peu plus désordonné. Un tableau peut rendre ce processus plus facile, surtout si cette application doit s'adapter pour accueillir plus de zones de texte.
Notez également que, par suggestion de YowE3k, j'ai déclaré le tableau comme un tableau de double
s, et de même avec Total
. Double
s permettent flottante de précision des points alors que Long
s et Integer
s ne permettent que des nombres entiers (sidenote sur ce point, ne jamais utiliser Integer
. Prenez l'habitude d'utiliser seulement désire ardemment tout ce que vous utilisez un Int pour).
Ensuite, j'ai défini une fonction qui obtient l'entrée propre de la zone de texte. C'est une bonne habitude à prendre. Gardez à l'esprit qu'un copier-coller implique inévitablement des temps supplémentaires de débogage/correction plus tard. Il y a de rares cas où cela est quelque peu inévitable dans les circonstances actuelles, mais le plus souvent, une fonction ou un sous-marin fera des merveilles.
Dans le cas de la fonction que j'ai définie, il vérifie d'abord une entrée numérique (en évitant l'erreur de type) et vérifie ensuite que la valeur n'est pas supérieure à 1. Si ces deux conditions réussissent, la valeur (arrondie à la deuxième décimale), sinon elle ne renvoie rien.
J'utilise cette fonction pour obtenir les trois valeurs, puis-je tester la validité des trois valeurs dans le même cas/bloc ElseIf. Cela garantira que les trois valeurs sont valides avant d'effectuer la vérification finale.
Dans le dernier contrôle, il assure que le total est égal à 1, et si elle est alors rien ne se passe. Si ce n'est pas le cas, il avertit l'utilisateur que les entrées ne sont pas valides.
Le processus est d'utiliser des fonctions pour renvoyer des valeurs, puis d'utiliser la logique pour gérer les erreurs. C'est beaucoup plus efficace que les blocs GoTo, et cela rend le code de débogage beaucoup plus facile (du moins dans mon expérience).
Si vous avez des questions, s'il vous plaît demander. Bonne chance!
EDIT: Modification de la déclaration des entrées de double à variante.Le type Double définit automatiquement les valeurs de base sur 0 par rapport à Empty
. Cela empêche à son tour de vérifier les valeurs invalides par rapport aux zéros. Le type Variant corrige ceci.
avez-vous essayé 'IF' et' + 'en manipulant' .hide'? –
avez-vous essayé: 'If (textbox1 + textbox2 + textbox3) = 1 Then'? – tinamou
Si les valeurs doivent être comprises entre 0,0 et 1,0 **, vous pouvez repenser en plaçant les valeurs dans des variables entières, ce qui rendra tout moins de 0.50000 égal à 0 et quelque chose entre 0.50000 et 1.49999 égal à 1. So 0.4 + 0.35 + 0.25 sera équivalent à 0 + 0 + 0, ce qui ne sera pas égal à 1. (Peut-être utiliser Double, ou Devise si vous n'autorisez pas plus de 4 chiffres décimaux.) – YowE3K