Set focus : invalid procedure call

Signaler
Messages postés
823
Date d'inscription
mercredi 4 août 2010
Statut
Membre
Dernière intervention
20 septembre 2020
-
Messages postés
183
Date d'inscription
mardi 4 juillet 2017
Statut
Membre
Dernière intervention
19 septembre 2020
-
Bonjour,
Ma Form principale est constituée de bouton chacun d'eux appelant une autre Form.
Je vérifie si la Form appelée n'est pas déjà active auquel cas au lieu de la charger je lui donne le focus.
Voici le code de la Form principale
Dim Prgm() As Object
Dim frm As Form

Private Sub Form_Load()
Set Prgm(1) = Salinite    ' Nom de la Form
Set Prgm(2) = CaMgKH
...

et le code de la sub quand on clique sur un des boutons
Private Sub Programme_Click(Index As Integer)
For Each frm In Forms
    If frm Is Prgm(Index) Then
        Prgm(Index).SetFocus
        Exit Sub
    End If
Next
Load Prgm(Index)
Exit Sub
La plupart du temps tout fonctionne très bien.
De façon tout à fait exceptionnelle j'ai Erreur : 5 : Invalid procedure call or argument.
Comment l'expliquer et que faire pour l'éviter ?
Grand merci d'avance

5 réponses

Messages postés
183
Date d'inscription
mardi 4 juillet 2017
Statut
Membre
Dernière intervention
19 septembre 2020
5
 Prgm(Index).SetFocus

Est réalisé sur la fenêtre active, et non présent lors de l’exécution.

Le bon code est:
frm!Prgm(Index).SetFocus

ou
frm.SetFocus
Prgm(Index).SetFocus


Mais, là, tu perds le focus de la fenêtre source... Donc, tu dois entrer la fenêtre active en argument pour la sélectionner à nouveau.( ou stocker l'info en temporaire pour la réactiver en cas de de perte d'infos)
Généralement, l'activation de boutons ne se fait pas, pour ce genre de problème, il est préférable de faire un appel de ce genre dans un fonction Sub ou Fonction directement dans le code de la feuille en Public.

Pour des MDI, ça ce complique car tu dois y placer l'indexation de la fenêtre, mais cela ne semble pas être le cas.
Messages postés
823
Date d'inscription
mercredi 4 août 2010
Statut
Membre
Dernière intervention
20 septembre 2020
2
Bonjour,
Merci pour ta réponse mais je dois avouer que je n'ai rien compris.

"
Prgm(Index).SetFocus
Est réalisé sur la fenêtre active, et non présent lors de l’exécution."
Qu'est-ce qui n'est pas présent lors de l'exécution ?

"tu perds le focus de la fenêtre source... Donc, tu dois entrer la fenêtre active en argument pour la sélectionner à nouveau"
c'est très bien comme ça puisque je veux changer de fenêtre (donner focus à l'autre).

Je parcours les forms ouverts
si un des Forms ouvert est celui que je veux activer je ne le charge pas, je lui donne le focus
99,99 fois sur 100 ça fonctionne très bien; sur des milliers d'exécutions j'ai eu une seule fois Erreur : 5 : Invalid procedure call or argument.
Ça ne me tracasse par parce que c'est tout à fait exceptionnel, je cherche seulement à comprendre.
Messages postés
183
Date d'inscription
mardi 4 juillet 2017
Statut
Membre
Dernière intervention
19 septembre 2020
5
Salut Hervé,

Pour t'assurer que ta form est bien activée, fait un DoEvents avant le Exit sub, car parfois, des routines sont lancée sur le GetFocus de la fenêtre.

Comme l’exécution des routines sont asynchrone et simultanée, il ce peut que l'activation de la fenêtre ne soit pas complète, surtout si tu mets à jour des tableaux, des informations et des textbox qui seront mis à jour à chaque focus.

Les erreurs de latences sont une calamité sur le vb 5 et 6... la mise à jour automatiques ou semi-automatiques des contrôles les rend "invisibles" en cas d'activation... cela peut interagir sur des routines extérieures et même provoquer des boucles de ralentissements de "roues libre" qui plombent la vitesse d'exécution.
Messages postés
823
Date d'inscription
mercredi 4 août 2010
Statut
Membre
Dernière intervention
20 septembre 2020
2
Bonjour,
Tu me conseilles d'ajouter un DoEvents avant Exit Sub.
Mon code
        Prgm(Index).SetFocus
        Exit Sub

L'erreur est sur .SetFocus : je ne vois pas en quoi un DoEvents APRES .SetFocus pourrait empêcher cette erreur.
Messages postés
183
Date d'inscription
mardi 4 juillet 2017
Statut
Membre
Dernière intervention
19 septembre 2020
5
Pardon, oui naturellement après le "For Each frm In Forms" pour validé le processus de chargement en amont.
Enfin je reste sur le fait que tu actives un bouton private en direct avec un focus sur la forme principale et tu bascule sur une autre forum ... toujours en private.
Exporte ta routine en public pour évité que le exit sub retrouve son focus d'avant...

Private Sub Programme_Click(Index As Integer)
MyFocus(Index)
End sub

Public Sub MyFocus(Index As Integer)
For Each frm In Forms
Doevents
    If frm Is Prgm(Index) Then
        Prgm(Index).SetFocus
        Exit Sub
    End If
Next
Load Prgm(Index)
End sub


note; Ce forum ne fonctionne plus sur IE... c'est de pire en pire...