2017-06-24 2 views
0

J'ai créé un userform avec 2 zones de texte, 3 boutons et une zone de liste avec deux colonnes. Si je clique sur une entrée dans la zone de liste, l'entrée de liste sélectionnée est transférée dans deux zones de texte différentes.Dans VBA, pourquoi placer une valeur textbox dans une cellule déclenche une boucle for dans un autre sous-programme userform?

Voir le code ci-dessous:

Private Sub NewSourceListBox_Click() 

Dim i As Integer 

'Show the selected data in the corresponding text boxes 
For i = 0 To NewSourceListBox.ListCount - 1 
    If NewSourceListBox.Selected(i) Then 
     'Hide the add button and show the change button 
     NewSourceBtnChange.Top = 168 
     NewSourceBtnChange.Visible = True 
     NewSourceBtnAdd.Visible = False 

     NewSourcesIDTxtBox.Value = NewSourceListBox.List(i, 0) 
     NewSourcesSourceTxtBox.Value = NewSourceListBox.List(i, 1) 

     'Pass on the selected item row to another subroutine 
     selectedItem = i 
     Exit For 
    End If 
Next i 

End Sub 

selectedItem est une variable globale créée dans un autre module, que je dois utiliser dans un autre sous-programme. Si je modifie les entrées dans les zones de texte dans le formulaire utilisateur et que vous cliquez sur le bouton de modification, le code suivant est exécuté.

Ce code:

Private Sub NewSourceBtnChange_Click() 

Dim row As Integer 

row = 6257 + selectedItem 

'Change the selected data in the list box to the corresponding data in the text boxes 
Sheets("Datensätze").Range("A" & row).Value = NewSourcesIDTxtBox.Value 
Sheets("Datensätze").Range("B" & row).Value = NewSourcesSourceTxtBox.Value 
'Another duplicate entry to make vLookup work 
Sheets("Datensätze").Range("C" & row).Value = NewSourcesIDTxtBox.Value 

Unload Me 
'Unload the new entry user form to repopulate the comboboxes 
Unload NewEntryUserForm 
NewEntryUserForm.Show 

End Sub 

Si je regarde cette étape par étape via F8 alors le suivant se produit: Dès que je clique sur le bouton « NewSourceBtnChange » le sous-programme correspondant NewSourceBtnChange_Click() démarre. Lorsque j'atteins Sheets("Datensätze").Range("A" & row).Value = NewSourcesIDTxtBox.Value, le programme passe à la routine NewSourcesListBox_Click(), l'exécute deux fois et revient à Sheets("Datensätze").Range("B" & row).Value = NewSourcesSourceTxtBox.Value, puis exécute deux fois la routine NewSourcesListBox_Click() et revient à la dernière entrée Sheets("Datensätze").Range("C" & row).Value = NewSourcesIDTxtBox.Value et exécute le reste de la routine NewSourceBtnChange_Click(). Cela ne permet pas d'obtenir les nouvelles données des zones de texte dans leurs cellules destinataires.

Edit:

Juste pour le rendre plus facile de reconstituer le comportement décrit, j'exporté le userform et son code et uploaded il.

+1

Avez-vous des gestionnaires d'événements 'Worksheet_Change' dans le classeur? –

+1

J'ai essayé votre code et il n'y a pas de comportement comme vous l'avez mentionné. Cela doit être lié à un autre code que vous avez déjà. Comme joseph4tw l'a mentionné, 'Worksheet_Change' ou' Worksheet_SelectionChange' pourrait le déclencher. Vérifiez votre code à nouveau. – Tehscript

+0

@ joseph4tw et Tehscript. La seule chose que j'ai est un 'Worksheet_SelectionChange' qui repositionne les boîtes de commentaires au milieu de l'écran visible. J'ai commenté l'ensemble du bloc de code, mais le comportement est toujours le même. Je téléchargerai l'ensemble du formulaire utilisateur, peut-être que cela aidera à faire le tri. – d3x

Répondre

1

Voici ce que votre code traverse (seulement les parties importantes):

1) Lors de l'initialisation UserForm, il remplit la zone de liste avec:

.RowSource = "Datensätze!A6257:B" & 6257 + Sheets("Datensätze").Range("F2").Value - 1

2) Lorsque vous cliquez sur l'élément de la zone de liste, vous déclenchez le code NewSourceListBox_Click, remplissez les zones de texte avec les éléments sélectionnés et définissez le numéro d'index de l'élément sur la variable selectedItem. (Qui est géré mal. Vous devez déclarer selectedItem comme variable publique.)

3) Ensuite, vous cliquez sur NewSourceBtnChange qui déclenche NewSourceBtnChange_Click.Il définit le numéro de ligne de l'article sélectionné:

row = 6257 + selectedItem

Ensuite, vous modifiez cette très cellulaire à l'aide:

Sheets("Datensätze").Range("A" & row).Value = NewSourcesIDTxtBox.Value

que vous avez utilisé pour remplir votre liste avec:

.RowSource = "Datensätze!A6257:B" & 6257 + Sheets("Datensätze").Range("F2").Value - 1

À ce moment, la liste est à nouveau remplie, mais cette S'il a déjà été sélectionné, il déclenche le code NewSourceListBox_Click.

Chaque fois que vous modifiez la plage RowSource, si la zone de liste est sélectionnée, elle se comportera comme ceci. Vous devez donc désélectionner l'élément de liste déroulante pour contourner ce problème.

TL; DR:

Après:

row = 6257 + selectedItem 

Insérer:

NewSourceListBox.Selected(NewSourceListBox.ListIndex) = False 

également être en mesure d'obtenir la valeur selectedItem dans d'autres sous-marins, vous devez déclarer comme variable publique. En dehors des sous-marins, tout en haut, insérez:

Public selectedItem As Long 
+0

Merci beaucoup pour cette explication! Je ne pensais pas que 'Sheets (" Datensätze "). Range (" A "& row) .Value = NewSourcesIDTxtBox.Value' déclencherait un bloc de code que je pensais être seulement déclenché quand j'active pour la première fois le userform. Maintenant, il est logique que 'NewSourceBtnChange' déclenche la boucle for 2 fois (à cause des 2 colonnes) et pourquoi la dernière modification ne déclenche pas la boucle for (car elle n'est pas utilisée pour remplir la zone de liste). Cela a vraiment aidé beaucoup! Pourquoi une modification de 'Userform_Initialize()' ne fonctionnerait-elle pas aussi? – d3x