Source de ligne personnalisée pour la liste déroulante sous forme continue dans Access

StackOverflow https://stackoverflow.com/questions/86278

  •  01-07-2019
  •  | 
  •  

Question

J'ai cherché aux alentours et il semble que ceci soit une limitation de MS Access. Je me demande donc quelles solutions créatives d'autres solutions ont été apportées à ce casse-tête.

Si vous avez un formulaire continu et que vous souhaitez qu'un champ soit une liste déroulante d'options spécifiques à cette ligne, Access ne parvient pas à livrer; la source de la ligne de la liste déroulante n’est interrogée qu’une fois au début du formulaire et affiche donc les mauvaises options pour le reste du formulaire.

La prochaine étape que nous essayons tous, bien sûr, consiste à utiliser l'événement onCurrent pour actualiser la liste déroulante, ce qui limite les options à la ligne donnée. Cependant, à ce stade, Access devient fou et interroge toutes toutes les zones de liste déroulante, pour chaque ligne. Le résultat est souvent celui de la disparition et de la réapparition des options dans les autres lignes, en fonction de leur choix. une option valide pour la source de la ligne de l'enregistrement en cours.

La seule solution que j'ai trouvée consiste à répertorier toutes les options disponibles, tout le temps. Des réponses créatives?

Modifier Par ailleurs, il convient de noter que la zone de liste déroulante a pour but de créer une requête sous forme de table de recherche. La valeur réelle doit être masquée et stockée, tandis que la version lisible par l'homme est affichée. ... plusieurs colonnes dans la source de la ligne de la liste déroulante. Par conséquent, changer la limite en liste n'aide pas, car les identifiants qui ne figurent pas dans la requête de source de ligne actuelle ne correspondent à aucune partie lisible par l'homme.

Dans ce cas particulier, les formulaires en continu ont beaucoup de sens, alors ne me dites pas que ce n'est pas la bonne solution. Je demande des réponses créatives.

Était-ce utile?

La solution

Je déteste aussi Access, mais vous devez jouer avec les cartes qui vous sont distribuées. Les formulaires continus sont une chose merveilleuse dans Access, jusqu'à ce que vous rencontriez toute la complexité, comme c'est généralement le cas, comme dans cet exemple.

Voici ce que je ferais face à cette situation (et j'ai déjà implémenté des solutions de contournement similaires):

Placez une liste déroulante UNBOUND sur le formulaire. Placez ensuite une zone de texte BOUND pour le champ que vous souhaitez modifier.

Assurez-vous que la liste déroulante est cachée derrière (NON invisible, mais cachée) derrière la textBox.

Dans l'événement OnCurrent, remplissez le contrôle ListBox avec les données nécessaires. Allez-y et "Limiter à la liste". ça aussi.

Dans l’événement OnEnter ou OnClick de la zone de texte, donnez le focus à la liste déroulante. Cela mettra la liste déroulante au premier plan. Lorsque le focus quitte la liste déroulante, il se cache une fois de plus.

Dans l'événement AfterUpdate de la liste déroulante, définissez la valeur de la zone de texte égale à la valeur de la liste déroulante.

En fonction de votre situation, il peut y avoir d'autres détails à régler, mais cela devrait plus ou moins permettre d'atteindre votre objectif sans ajouter trop de complexité.

Autres conseils

utiliser des formulaires continus .. définitivement. En fait, vous pouvez créer des applications entières avec une interface utilisateur intuitive et intuitive construite sur des formulaires en continu. N'écoutez pas Toast!

Votre solution consistant à répertorier toutes les options disponibles est la bonne. En fait, il n'y a pas d'autre solution propre. Mais vous avez tort quand vous dites que Acccess devient fou. Sur un formulaire continu, vous pouvez voir chaque ligne comme une instance de la section détail, où la liste déroulante est une propriété commune à toutes les instances de la section détail. Vous pouvez mettre à jour cette propriété pour toutes les instances, mais vous ne pouvez pas la définir pour une instance spécifique. C'est pourquoi Access DOIT afficher les mêmes données dans la liste déroulante pour tous les enregistrements!

Si vous devez accepter uniquement les valeurs spécifiques à l'enregistrement dans cette liste déroulante, utilisez l'événement beforeUpdate pour ajouter une procédure de contrôle. Si une nouvelle valeur ne peut pas être acceptée, vous pouvez annuler la mise à jour des données en ramenant la valeur précédente dans le champ.

Vous ne pouvez pas définir la propriété limitToList sur "No" où les données liées (celles stockées dans le contrôle) sont masquées. C’est logique: comment la machine peut-elle accepter la saisie d’une nouvelle ligne de données lorsque le champ lié (non visible) reste vide?

Vous pouvez également transformer la valeur de la liste déroulante en un champ de texte non modifiable, puis lancer une fenêtre contextuelle / modale pour modifier cette valeur. Cependant, si je le faisais, je serais peut-être enclin à éditer tout l'enregistrement dans l'une de ces fenêtres.

Je ne pense pas que les formulaires continus d’Access devraient être condamnés du tout, mais j’ai la conviction que ces formulaires devraient être évités pour l’édition de DONNÉES. Ils fonctionnent très bien pour les listes et vous offrent beaucoup plus de capacités de formatage qu’une simple boîte à liste (et sont beaucoup plus faciles à utiliser, bien qu’ils ne permettent pas la sélection multiple, bien sûr).

Si vous souhaitez utiliser un formulaire continu pour accéder aux enregistrements à modifier, utilisez un sous-formulaire affichant les données détaillées à modifier et utilisez la valeur PK du sous-formulaire pour le champ de lien. Cela peut être fait avec un formulaire continu dans lequel vous placez un sous-formulaire de détail dans l'en-tête ou le pied de page, lié à la PK de la table derrière le formulaire continu.

Si vous utilisez un formulaire continu pour afficher des données enfant dans un formulaire parent, vous pouvez lier le sous-formulaire de détail à une référence à la PK dans le sous-formulaire continu, comme suit:

[MySubForm].[Form]!MyID

Ce serait la propriété principale du lien, et MyID serait la propriété enfant du lien.

Nous rencontrons également cela souvent dans nos applications. Ce que nous avons trouvé être une bonne solution: Il suffit d'afficher toutes les lignes dans les listes déroulantes. Ensuite, dès que l'utilisateur entre la compobox dans une ligne spécifique, ajustez la source de lignes (avec le filtre pour cette ligne). Lorsque la liste déroulante perd le focus, vous pouvez redéfinir la source de lignes pour tout afficher.

J'ai un chemin plus simple que Gilligan. Cela ressemble à beaucoup de travail, mais ce n’est vraiment pas le cas. Ma solution nécessite d'avoir mon formulaire continu en tant que fiche technique de sous-formulaire. Sur mon sous-formulaire, j'ai deux listes déroulantes de recherche, entre autres, intitulées Équipement et Fabricant. Les deux détiennent simplement une clé Long Integer dans la source de données. Le fabricant doit être filtré en fonction de ce qui est sélectionné dans Équipement. La seule fois où je filtre Manufacturer.RowSource se trouve dans l'événement Manufacturer_GotFocus.

Private Sub Manufacturer_GotFocus ()

If Nz(Me.Equipment, 0) > 0 Then
    Me.Manufacturer.RowSource = GetMfrSQL()  '- gets filtered query based on Equipment
Else
    Me.Manufacturer.RowSource = "SELECT MfgrID, MfgrName FROM tblManufacturers ORDER BY MfgrName"
End If

End Sub

Dans Manufacturer_LostFocus, je réinitialise Manufacturer.RowSource à tous les constructeurs. Vous devez le faire car, lorsque vous cliquez pour la première fois dans le sous-formulaire, les événements GotFocus sont déclenchés pour tous les contrôles, y compris le fabricant, même si vous ne mettez à jour aucun champ.

Fabricant privé secondaire_LostFocus ()

Me.Manufacturer.RowSource = "SELECT MfgrID, MfgrName FROM tblManufacturers ORDER BY MfgrName"

End Sub

Dans l’événement Entrer du fabricant, vous devez vérifier si un équipement a été sélectionné, si l’option Équipement n’est pas activée.

Private Sub Manufacturer_Enter ()

If Nz(Me.EquipmentID, 0) = 0 Then
    '-- Must select Equipment first, before selecting Manufacturer
    Me.Equipment.SetFocus
End If

End Sub

Vous devez également actualiser la liste déroulante Fabricant dans l'événement Form_Current (par exemple, Me.Manufacturer.Requery) et définir la propriété Cycle de ce sous-formulaire sur "Enregistrement courant".

Cela semble assez simple, mais vous n’avez pas encore terminé. Vous devez également réinitialiser Manufacturer.RowSource à tous les fabricants de l'événement SubForm_Exit dans le formulaire parent au cas où l'utilisateur accédera à la liste déroulante Fabricant mais ne fait pas de sélection et clique quelque part sur le formulaire parent. Échantillon de code (sous forme parentale):

Private Sub sFrmEquip_Exit (Annuler en tant qu'entier)

Me.sFrmEquip.Controls("Manufacturer").RowSource = "SELECT MfgrID, MfgrName FROM tblManufacturers ORDER BY MfgrName"

End Sub

Il y a encore un morceau de ceci qui n'est pas propre. Lorsque vous cliquez sur Fabricant et que vous avez plusieurs lignes dans la grille de la feuille de données, le champ Fabricant est vide dans les autres lignes (les données sous les listes déroulantes sont toujours intactes) lorsque vous modifiez le Fabricant dans la ligne actuelle. Une fois que vous quittez ce champ, le texte des autres champs du fabricant réapparaîtra.

Cela semble bien fonctionner. CBOsfrmTouchpoint8 est une liste déroulante abrégée en carré uniquement déroulant. CBOsfrmTouchpoint14 est une zone de texte qui constitue le reste de l'espace. Ne jamais dire jamais:

  Private Sub CBOsfrmTouchpoint8_Enter()  

  If Me.CBOsfrmTouchpoint8.Tag = "Yes" Then  
  CBOsfrmTouchpoint14.SetFocus  
  Me.CBOsfrmTouchpoint8.Tag = "No"  
  Exit Sub  
  End If  

  Me.CBOsfrmTouchpoint8.Tag = "No"  
  Me.CBOsfrmTouchpoint8.RowSource = "XXX"  
  Me.CBOsfrmTouchpoint8.Requery  
  Me.CBOsfrmTouchpoint8.SetFocus  
  End Sub 

  Private Sub CBOsfrmTouchpoint8_GotFocus()  
  Me.CBOsfrmTouchpoint14.Width = 0  
  Me.CBOsfrmTouchpoint8.Width = 3420  
  Me.CBOsfrmTouchpoint8.Left = 8580  
  Me.CBOsfrmTouchpoint8.Dropdown  
  End Sub

  Private Sub CBOsfrmTouchpoint8_LostFocus()  
  Me.CBOsfrmTouchpoint8.RowSource = "XXX"  
  Me.CBOsfrmTouchpoint8.Requery  
  End Sub 

  Private Sub CBOsfrmTouchpoint8_Exit(Cancel As Integer)  
  Me.CBOsfrmTouchpoint14.Width = 3180  
  Me.CBOsfrmTouchpoint8.Width = 240  
  Me.CBOsfrmTouchpoint8.Left = 11760  
  Me.CBOsfrmTouchpoint8.Tag = "Yes"  
  End Sub

Que faire si vous désactivez le " Limiter à la liste " et effectuez une validation avant la mise à jour pour confirmer que ce que l'utilisateur a tapé correspond à quelque chose dans la liste que vous lui avez présentée?

Mieux ...

Définissez votre liste déroulante Source de contrôle sur une colonne de la requête dans laquelle les valeurs de votre liste déroulante seront stockées.

Pour moi, le meilleur moyen, le plus simple, consiste à créer une table temporaire contenant tous vos champs liés, plus un champ supplémentaire consistant en un champ oui / non.

alors vous utiliserez cette table comme source de données pour le continu pour. Vous pouvez utiliser onLoad pour remplir la table temporaire avec les données souhaitées.

Je pense qu'après cela, il est facile de boucler les choix, il suffit d'une petite boucle pour lire le champ yeas / no de la table temporaire.

J'espère que cela aidera

Utilisez l'événement OnEnter pour renseigner la zone de liste déroulante. N'utilisez pas de source de lignes fixe .

Je viens de faire la même chose. Ma solution consistait à utiliser une source de ligne fixe liée à une requête. Les clauses WHERE de la requête font référence au contrôle du formulaire, à savoir Client = Forms! FrmMain! ClientTextBox . Cela seul remplira les listes déroulantes avec les données de la première ligne. L'astuce consiste alors à définir un événement ' On Enter ' qui effectue simplement une nouvelle requête sur la liste déroulante, par exemple. ComboBox1.Requery , cela réinterrogera cette liste déroulante uniquement et ne fera glisser que les données associées à cette ligne d'enregistrement.

J'espère que cela fonctionne aussi pour vous!

Avertissement: je déteste Access avec passion.

N'utilisez pas de formulaires en continu. Ils sont un fouillis rouge pour ce que vous voulez accomplir. Les formulaires continus sont le même formulaire répété à plusieurs reprises avec des données différentes. C'est déjà un problème du mode de fonctionnement normal d'Access, car vous ne pouvez pas ouvrir le même formulaire plusieurs fois. Le comportement que vous observez est "tel que conçu". dans Access. Chacun de ces contrôles ComboBox est en fait le même contrôle. Vous ne pouvez pas affecter l'un sans affecter les autres.

En gros, ce que vous avez fait ici a été exécuté dans la zone où Access n'est plus adapté à votre projet (mais ne peut pas être abandonné car il représente déjà une grande quantité de travail).

Ce qui semble être le plan d’action le plus probable ici, c’est de vraiment simuler. Exécutez une requête sur les données, puis créez les éléments de formulaire par programme en fonction des résultats. C’est beaucoup de travail, car vous allez dupliquer vous-même une bonne partie de la fonctionnalité de traitement des données d’Access.

Répondre à Edit:
Mais comme ils sont, les formes continues ne peuvent pas accomplir ce que vous voulez. C'est pourquoi j'ai suggéré de simuler vos propres formulaires en continu, car les formulaires en continu ont de réelles limites à ce qu'ils peuvent faire. Ne restez pas si bloqué sur une implémentation particulière que vous ne pourrez pas vous en séparer quand elle cessera de fonctionner.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top