2017-07-05 2 views
0

J'ai donc actuellement un formulaire utilisateur avec 3 boîtes de saisie et un bouton de sauvegarde. Les trois entrées doivent être entre 0.0 et 1.0, ce que j'ai fait en utilisant le code ci-dessous.VBA - Comment puis-je donner un code d'erreur basé sur la somme de mes valeurs de zone de texte dans un formulaire utilisateur?

J'ai besoin maintenant la somme de ces 3 entrées à égale 1. Si la somme de ces entrées est pas égal à 1 Je veux afficher un message d'erreur sur le clic du bouton Enregistrer. Vraiment bloqué à ce sujet et ont essayé quelques méthodes différentes qui ont travaillé.

Y at-il un moyen de le faire?

Private Sub CommandButton1_Click() 

Dim textbox1 As Integer 
Dim textbox2 As Integer 
Dim textbox3 As Integer 

On Error GoTo errHandler 
textbox1 = CInt(UserForm1.textbox1.Value) 
If textbox1 > 1 Then 
    MsgBox "Invalid Input, Please enter value between 0.0 and 1.0" 
Else 
    UserForm1.Hide 
End If 

On Error GoTo errHandler 
textbox2 = CInt(UserForm1.textbox2.Value) 
If textbox2 > 1 Then 
    MsgBox "Invalid Input, Please enter value between 0.0 and 1.0" 
Else 
    UserForm1.Hide 
End If 
Exit Sub 

On Error GoTo errHandler 
textbox3 = CInt(UserForm1.textbox3.Value) 
If textbox3 > 1 Then 
    MsgBox "Invalid Input, Please enter value between 0.0 and 1.0" 
Else 
    UserForm1.Hide 
End If 
Exit Sub 
errHandler: 
MsgBox Err.Description 
End Sub 
+1

avez-vous essayé 'IF' et' + 'en manipulant' .hide'? –

+0

avez-vous essayé: 'If (textbox1 + textbox2 + textbox3) = 1 Then'? – tinamou

+0

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

Répondre

0

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.

+0

Merci beaucoup de passer par là pour m'aider. Votre code est en effet beaucoup plus propre et plus logique. Votre explication a également aidé ALOT - Je suis tout nouveau à VBA. Je vous remercie!!! Seul problème que j'ai quand je remplace mon code par le vôtre: Il ajoute seulement la somme de la deuxième décimale - pas le nombre entier. Je joins une photo pour vous montrer ce que je veux dire. [link] (https://i.stack.imgur.com/SE6rL.jpg) Je ne sais pas comment résoudre ce problème. –

+0

@ A.Desai Essayez le code mis à jour (je viens de changer le type de déclaration des entrées de 'Double' à' Variant'). Je n'avais pas réalisé que la valeur par défaut d'un tableau 'Double' est 0 (dans un tableau 'Variant' c'est' Empty') et à cause de cela, la vérification d'entrée invalide était satisfaite par le 0, malgré l'entrée de 1.5 être invalide. Vous devriez maintenant être correctement averti si vous entrez un nombre supérieur à 1. –

+0

Désolé pour la réponse différée. J'ai essayé le nouveau code et ça marche maintenant parfaitement !! Merci beaucoup pour ton aide –