Afficher le rapport du message 1s 8.3. Messages à l'utilisateur dans les formulaires gérés (encore)

  • 10.01.2022

Mais certains aspects du travail avec l'objet "Message à l'utilisateur" n'y étaient pas couverts. Par exemple, quoi écrire dans le champ "Champ" si le nom

L'attribut est différent du nom du champ sur le formulaire. Quoi écrire dans le champ "Chemin des données". Et enfin, le plus délicieux, comment travailler avec la partie tabulaire.

Toutes les enquêtes sont collectées dans une base de données test. Il contient quelques ouvrages de référence et un document. Il existe plusieurs boutons dans le formulaire du document, en cliquant sur lesquels des messages de différentes natures sont affichés. Eh bien, maintenant à propos de chaque moment dans l'ordre, allons-y !!!

Tout ce que j'écris ci-dessous est testé sur 1C: Enterprise 8.3 (8.3.7.1860). Pas le dernier en date, mais j'écris tel quel.

1. Juste un message.

Commençons par une simple : affichez simplement le message dans le formulaire, sans lier les champs, les données, etc.

J'en ai parlé plus tôt, mais pour l'intégrité de l'article, je vais écrire à nouveau. Surtout avec quelques ajouts.

Message1 = nouveau MessageToUser ;
Message1.Text = "1. juste un message sans liaison" ;
Message1.Notify();

Ce code peut être exécuté aussi bien sur le client que sur le serveur. C'est presque un analogue complet de la ligne:

Notify("1. juste un message sans liaisons");

Pourquoi est-il plus correct de signaler non pas par une procédure, mais par un objet. Le fait est que les messages émis dans une tâche en arrière-plan (par exemple, lors de l'exécution d'une procédure de routine selon un calendrier) ne sont affichés nulle part. Mais ce qui est communiqué par un objet peut être

accéder au serveur dans la session client à l'aide de la méthode "GetMessagesToUser(...)" pendant que le travail d'arrière-plan est actif.

Ici, je vous ai un peu menti, je n'ai jamais vérifié cela. Il est tout à fait possible que des messages émis par la procédure "Etat(...)" soient également reçus d'un job de fond, ou non. La documentation n'en parle pas, ce qui signifie que nous

nous ne ferons pas.

Donc, conclusion : faites toujours des messages un objet, c'est un peu un bon nouveau style de plate-forme, mais oubliez la procédure. Si vous n'aimez pas écrire un message en trois lignes, alors écrivez votre procédure dans un module commun et réjouissez-vous. Ce sera même

très bon ton, car Vous bénéficierez de plusieurs avantages :

1. Fonctionnalité étendue du nouvel objet (plus de détails ci-dessous)

2. La possibilité d'afficher des messages à votre manière. Par exemple, dans un champ de texte ou un fichier, pas dans une boîte de message.

3. Possibilité de journalisation. Par exemple, vous pouvez enregistrer tous les messages dans la base de données ou dans un fichier, ou les dupliquer dans le journal, pour ce faire, il vous suffit de bricoler votre procédure de module commune. Et puis les disputes que le programme n'est rien pour l'utilisateur

n'a pas dit que ça s'arrêterait pour toujours.

2. Message attaché à l'attribut de l'objet.

Comme je l'ai écrit dans l'article précédent, pour la liaison, vous devez remplir les champs "Field" et "Path toData". Mais je n'ai pas développé le sujet dans l'article.

Ainsi, le 2ème exemple du document a les accessoires de l'en-tête "Client", vous devez vous positionner dessus et signaler quelque chose dans la procédure client. Voici le code qui le fait :

Message2 = nouveau MessageToUser ;
Message2.Text = "2. Message joint à l'attribut d'en-tête Client" ;
Message2.Champ = "Client" ;
Message2.DataPath = "objet" ;
Message2.Notify();

Et voici les nuances :

1. Un champ n'est pas un champ, car dans mon exemple, le contrôle est nommé "FieldClient" et les accessoires de l'objet sont "Client". Avec la ligne Message2.Field = "FieldClient" ne fonctionne pas.

2. Datapath n'est pas "Object.Client", mais simplement "Object", car nous devons montrer le message non pas sous la forme de la contrepartie, mais sous la forme du document actuel. "Objet.Client" - ne fonctionne pas.

3. Ceci est un exemple de travail sur un client. Dans les procédures serveur, c'est un peu différent. Ceci est IMPORTANT, ne confondez pas la connexion entre les messages sur le serveur et sur le client.

Je vais donner un autre exemple pour que vous sentiez la différence entre un client et un serveur. Le fait est que nous avons à notre disposition une méthode de l'objet "SetData(...)". L'aide à la syntaxe indique "L'objet avec lequel le

message est connecté". C'est important. Par exemple, écrivons le code suivant :

Message3 = nouveau MessageToUser ;
Message3.SetData(Objet);
Message3.Text = "3. Le message est lié à l'attribut d'en-tête Numéro, mais il ne sera pas lié, car l'Objet n'est pas un objet" ;
Message3.Champ = "Numéro" ;
Message3.Notify();

Ce code ne fonctionnera pas car sur le client, l'attribut de formulaire "Objet" n'est pas du tout un objet, mais une sorte de chose dégoûtante, voici ce que le débogueur nous dit à propos de la variable objet :

Plus précisément, l'utilisateur verra bien sûr le message, mais un double claquement dessus ne mènera à rien.

Et maintenant essayons la même chose, mais sur le serveur. Créons une procédure serveur "Report4OnServer()" et appelons-la depuis le client

&Sur le serveur
Procédure Report4AtServer()
Message4 = nouveau MessageToUser ;
Message4.SetData(FormAttributeToValue("Objet"));
Message4.Text = "4. Message lié à l'attribut d'en-tête Organisation" ;
Message4.Field = "Organisation" ;
Message4.Notify();
FinProcédure

Tout ira bien ici, la seule remarque sur le code est que la variable "object" doit être convertie de "FormDataStructure" en un objet réel en appelant la procédure "FormAttributeToValue(...)".

Conclusion : la méthode "SetData(...)" n'est utilisable que sur le serveur, car c'est seulement sur le serveur qu'il est possible d'obtenir l'objet.

3. Messages liés à l'attribut de la partie tabulaire de l'objet

J'avais omis ce sujet dans un article précédent. Connaissant les nuances décrites ci-dessus, il ne devrait y avoir aucun problème ici. Voici le code client fonctionnel :

Message5 = nouveau MessageToUser ;
Message5.Text = "5. Quantité de champ Ligne 1" ;
Message5.Field = "Produits. Quantité" ;
Message5.DataPath = "objet" ;
Message5.Notify();

Bien que les nuances soient presque les mêmes, mais la répétition est l'apprentissage de la mère :

1. Le champ n'est pas le nom du champ, le champ est nommé "ProductsQuantity", et pas seulement "Quantity". "Produits" est le nom de la section tabulaire, pas le contrôle associé à la section tabulaire.

2. Le chemin vers les données est un objet, juste un objet.

3. Le numéro de ligne entre crochets est numéroté à partir de zéro et correspond au numéro de ligne, et non à l'ID de ligne dans la collecte de données du formulaire. Lors du déplacement de lignes, en les supprimant, l'identifiant attribué lors de l'ouverture du formulaire est enregistré et les numéros de ligne sont recalculés.

C'est tout pour cette fois. J'exprimerai immédiatement des sujets non divulgués, sur lesquels j'écrirai plus tard:

1. Comment lier les messages non pas à l'objet courant, mais à n'importe lequel, de sorte qu'un autre formulaire s'ouvre au double-clic

2. Comment lier des messages à un formulaire où il n'y a pas d'objets

3. Comment recevoir des messages sur l'état d'exécution d'un long travail d'arrière-plan

4. Qu'est-ce qu'une "DataKey" et quand l'utiliser

Ci-dessous se trouve une base avec un exemple, allez dans le document et appuyez sur trois boutons à tour de rôle. Code dans le module de formulaire de document.

Dans les programmes basés sur la plate-forme 1C:Enterprise, un message peut être affiché à l'utilisateur de différentes manières.

1. Méthode Afficher l'avertissement.

AfficherAvertissement(< ОписаниеОповещенияОЗавершении> , < ТекстПредупреждения> , < Таймаут> , < Заголовок> )

Lors de l'utilisation de cette conception, une fenêtre d'avertissement apparaît au centre de l'interface du programme.

Option :

DescriptionNotificationsTerminé(facultatif)
Type : DescriptionAlertes. Contient une description de la procédure qui sera appelée après la fermeture de la fenêtre d'alerte avec les paramètres suivants : AdditionalParameters - la valeur qui a été spécifiée lors de la création de l'objet AlertDescription. Si le paramètre n'est pas spécifié, aucune procédure ne sera appelée à la fin.

TexteAvertissements(requis)
Tapez : Chaîne ; Chaîne formatée. Le texte de l'avertissement.

Délai d'attente (facultatif)
Tapez : Nombre. Intervalle de temps en secondes pendant lequel le système attendra la réponse de l'utilisateur. Lorsque l'intervalle expire, la fenêtre d'avertissement se ferme. Si le paramètre n'est pas spécifié, le délai d'attente est illimité. Si le paramètre est négatif, une exception sera levée. Valeur par défaut : 0.

Titre (facultatif)
Tapez : Chaîne. Contient le titre de la fenêtre d'alerte. Description : affiche une fenêtre d'alerte, mais n'attend pas qu'elle se ferme.

Disponibilité : Client léger, client Web, client lourd, application mobile (client).

Remarque : Si un code doit être exécuté après que l'utilisateur a fermé la fenêtre d'avertissement, il doit être placé dans une procédure de module distincte et décrit dans un paramètre.

2. Méthode d'avertissement.

Une fenêtre d'avertissement apparaît au centre de l'interface du programme. Cependant, si la propriété de configuration ModeUseModality est défini sur Ne pas utiliser , la méthode ne fonctionne pas.

Disponibilité : Client léger, client Web, client mobile, client lourd, application mobile (client).

3. Méthode Afficher l'utilisateur d'alerte.

AfficherAlerteUtilisateur(< Текст> , < ДействиеПриНажатии> , < Пояснение> , < Картинка> , < СтатусОповещенияПользователя> , < КлючУникальности> )

Lorsque vous utilisez cette méthode, un message apparaît dans le coin inférieur droit de l'interface.

Disponibilité : client léger, client Web, client lourd.

4. Méthode de rapport.

Signaler(< ТекстСообщения> , < Статус> )

Disponibilité : Client léger, client web, client mobile, serveur, client lourd, connexion externe, application mobile (client), application mobile (serveur).

5. Objet MessageToUser.

Conçu pour stocker les paramètres de message qui doivent être affichés à l'utilisateur. Si le message n'a pas encore été montré à l'utilisateur (cela peut être lors d'une exécution côté serveur, dans une tâche en arrière-plan, une connexion externe ou des services Web), vous pouvez obtenir les messages cumulés à l'aide de la méthode GetMessagesUser.

Propriétés: Identifiant du destinataire(ID cible); Clé de données (DataKey); Champ (Champ); Chemin de données (DataPath); Texte.

Méthodes : Rapport (Message) ; InstallData(SetData).

Le message apparaît en bas de l'interface, dans une ligne.

Message = Nouveau MessageVersUtilisateur() ; Message. Texte = "Pas assez de nomenclature"; Message. Champ = "Nomenclature. Quantité"; Message. SetData(DataObject) ; Message. Signaler() ;

1C MessageUser affiche un message à l'utilisateur (une fois le traitement terminé) ou l'enregistre dans la file d'attente si le message ne peut pas être affiché « maintenant », par exemple :
Message = Nouveau MessageVersUtilisateur();
Message.Text = "Bonjour le monde !" ;
Message.Notify();

Dans de nombreux cas, les messages sont générés en masse lors de certains traitements. Par exemple, lors de la vérification d'un grand tableau, de nombreux messages d'erreur peuvent apparaître - dans différentes lignes du tableau. Ou lors du traitement de l'exploitation. Dans ce cas, le traitement peut être effectué sur le serveur ou dans une tâche planifiée, et il est difficile d'afficher ces messages.

1C Message à l'utilisateur écrit des messages dans "certaines" files d'attente et, une fois le traitement terminé, les affiche à l'utilisateur, si possible. Sinon, la liste complète des messages peut être obtenue à l'aide de la méthode GetMessagesToUser().

Pour afficher un message à l'utilisateur à l'aide de 1C User Message dans un formulaire spécifique déjà ouvert, vous devez en outre définir l'identifiant du formulaire :
Message.DestinationId = Form.UniqueId ;

Pour que le message 1C Message à l'utilisateur s'affiche dans une fenêtre contextuelle à proximité d'un champ de formulaire spécifique dans le module dont le code est exécuté, vous devez spécifier le "chemin" vers celui-ci :
Message.Champ = "Nom" ; //où Nom est un attribut de formulaire
Message.Champ = "Objet.Nom" ; //où Name est l'attribut de l'objet (c'est-à-dire le répertoire dont le formulaire est en cours d'édition)
Message.Champ = "Produits.Prix" ; //où Marchandises est un onglet du formulaire, Prix est une colonne de cet onglet.

Pour faire la même chose, mais dans le module d'un autre objet (module commun), vous devez spécifier en plus l'objet (DirectoryObject, DocumentObject, etc.) :
Message.Champ = "Nom" ; //où Name est l'attribut DirectoryObject
Message.SetData(CatalogObject);
// Double-cliquer sur un message ouvrira un formulaire d'objet avec un message pop-up à côté du champ requis

Une autre façon de lier le message 1C Message à l'utilisateur avec les données de l'objet :
//pour référence, document..
Message.DataKey = DirectoryReference ;
Message.DataPath = "Objet" ;

//pour les entrées de registre
Message.DataKey = RegisterRecordManager.OriginalRecordKey ; //généralement l'attribut principal du formulaire associé à la casse
Message.DataPath = "Enregistrer" ;

Dans les configurations typiques sur les formulaires gérés pour un client léger, par exemple, "Trade Management, édition 11" et "Accounting, édition 3", dans le module général de General PurposeClientServer il y a une fonction NotifyUser(), qui "universalise" le travail avec cet objet. La syntaxe des fonctions dans différentes configurations est différente.

Étant donné que 1C Message to User génère une liste de messages afin de le réinitialiser (par exemple, avant d'effectuer un traitement complexe), vous pouvez appeler la fonction :
GetMessagesToUser(True);

Bon après-midi.

Aujourd'hui, nous allons parler d'une chose aussi simple que les messages à l'utilisateur.

DANS 1C 8 méthode migrée de 7.7 - " Signaler(...)". Cette méthode est très simple, elle ouvre une fenêtre de message si elle n'est pas ouverte, et y ajoute le texte du message. Comme en 1C 7.7, elle possède un deuxième paramètre qui définit une icône en face du message. Cette icône détermine le l'importance du message.

Le temps a passé et nous avons mis la main sur des formulaires contrôlés. Les formulaires gérés n'ont pas de boîte de message unique. Cependant, la méthode est toujours prise en charge. Dans la nouvelle interface, les messages restent dans la fenêtre active. Lorsque vous passez à une autre fenêtre, les messages disparaissent de la vue et lorsque vous revenez, ils s'affichent à nouveau. Dans certains cas, ce n'est pas pratique, mais rien ne peut être fait à ce sujet, un formulaire géré suppose qu'il n'y a pas de fenêtre principale à laquelle les messages pourraient être attachés.

Cependant, le message étant associé à un formulaire spécifique, cela permet aux auteurs de la plateforme d'étendre les fonctionnalités d'un simple message. Peut-être avez-vous déjà vu dans des configurations typiques que maintenant les messages sont intégratifs, cliquer sur le message nous positionne dans un certain champ, un double-clic peut ouvrir un autre élément de la base.

Le fait est que maintenant il est d'usage d'utiliser non pas la méthode de contexte global "Report (...)", mais l'objet " MessageToUser". Cet objet est disponible partout, à la fois sur le client et sur le serveur. Il a plusieurs propriétés et quelques méthodes.

En général, si vous avez besoin de donner à l'utilisateur un message simple, sans aucun interactif, alors il suffit d'écrire :



Message.Notify();

Ces trois lignes sont absolument identiques à la méthode que nous connaissons déjà, et cela n'a donc aucun sens d'utiliser cet objet pour un tel message.

Les principaux champs qui élargissent les possibilités du message sont :

  • Clé de données
  • Champ

clé de données- référence d'objet base d'informations Le auquel ce message fait référence, ou la clé de l'entrée. C'est ce qu'il dit dans le manuel. Si nous mettons ici un lien vers un document ou un répertoire, un double-clic ouvrira cet objet, quelle que soit la forme sous laquelle le message a été affiché. En conséquence, si le message est sorti sous la forme d'un document et que la clé de données contient un lien vers celui-ci, le nouveau formulaire ne s'ouvrira pas.

Un non-sens peut arriver si nous émettons un message sous la forme d'un objet qui n'a pas encore été enregistré. Dans ce cas, nous avons un lien vide. Mais la plate-forme n'est pas perdue et n'ouvre tout simplement rien, c'est-à-dire Vous restez dans la forme qui était.

Champ est une chaîne avec le nom du champ à activer. Et peu importe si le formulaire d'un autre objet s'ouvre ou si nous restons dans le formulaire actuel.

Voici un exemple de comment cela fonctionne :

Supposons qu'avant d'écrire un élément de répertoire dans le module de formulaire, nous vérifions l'unicité de l'attribut "Id" et, s'il existe déjà, émettons un message :


Si select.Next() Alors
Rejet = vrai ;
Message = Nouveau MessageVersUtilisateur ;
Message.DataKey = Select.Link ;
Message.Champ = "id" ;
Message.Text = "La section avec cet identifiant existe déjà" ;
Message.Notify();
Fin si;

Dans cet exemple, un double-clic ouvrira un élément de répertoire avec le même identifiant, et le champ Id sera actif et il y aura un indice dedans :

Cela semble pratique, on peut soit changer l'Id du nouvel élément soit éditer l'ancien, il est facile d'y entrer en cliquant sur le message. Mais le champ de l'élément courant n'est pas activé, ce qui, avec un grand nombre de champs, peut être plus utile que d'ouvrir le formulaire d'un autre objet. Après tout, un autre objet a déjà été enregistré et est utilisé, et la probabilité que l'erreur soit faible. Très probablement, nous devons modifier l'élément actuel.

Pour ce faire, nous modifions notre code comme suit :

//s'il y a des doublons, il y aura des données dans la sélection
Si select.Next() Alors
Rejet = vrai ;
Message = Nouveau MessageVersUtilisateur ;
Message.DataKey = Objet.Référence ;
Message.Champ = "id" ;
Message.Text = "La section avec cet identifiant existe déjà" ;
Message.Notify();
Fin si;

La seule différence est que dans Clé de données nous passons une référence à l'élément que nous avons ouvert. Malheureusement, ce code ne fonctionne pas : (Double-cliquer ouvrira une fenêtre modale.

Pour que cela fonctionne, il y a une nuance qu'il faut renseigner dans le champ " CheminVersDonnées". Je ne peux pas expliquer exactement pourquoi, j'ai juste besoin de m'en souvenir. Nous ouvrons un autre objet - Chemin de données pas nécessaire, positionné à l'intérieur de l'actuel - nécessaire. Conclusion - il vaut mieux toujours remplir, vous ne vous tromperez pas. Ajoutez une ligne au code :

Message.DataPath = "objet" ;

Et tout est beau :

Il y a une autre nuance dont je veux parler. Si le "champ" est laissé vide, le positionnement sur l'élément de contrôle n'aura pas lieu et aucune info-bulle n'apparaîtra à côté. Si le "champ" est mal renseigné, alors le positionnement se fera sur l'ensemble du formulaire et l'infobulle le sera, mais en fin de formulaire, sans référence au champ de saisie réel.

La nuance suivante est que le message a une méthode - " InstallData". Il remplit les champs en fonction de l'objet Clé de données Et CheminVersDonnées. C'est beaucoup plus pratique de tout faire en une seule ligne. En règle générale, sous la forme d'un élément / document, nous avons un objet. La seule chose qui doit être écrite sur le serveur est :

Message.SetData(FormAttributeToValue("Object"));

Mais dans la procédure de formulaire prédéfinie BeforeWritingOnServer en fait il y a déjà un paramètre ObjetCourant. Et sur le client, nous ne recevrons pas du tout l'objet. Aussi dans le module objet (pas dans le formulaire) vous devez écrire comme ceci :

Message.SetData(ThisObject);

En conclusion, je veux dire des choses désagréables sur les formulaires gérés. Ceci s'applique à la fois au TAXI et aux UV conventionnels. Le fait est que les listes d'interfaces sont transmises très mal aux UV. Un tableau contenant 1000 lignes est dessiné très lentement, et dans un navigateur web il peut même s'ouvrir pendant plusieurs minutes. Ceci s'applique également à la liste des messages. pour expérimenter, affichez 1000 messages et essayez de basculer entre les fenêtres. Le système mourra immédiatement. et il est clairement visible comment le système pense à la sortie des messages. La transition vers une fenêtre avec un tas de messages ressemble à ceci :

Le contenu de la fenêtre s'affiche
-qui clignote brusquement et la barre de message apparaît
-tout se bloque et vous regardez comment le défilement dans la fenêtre de message rampe vers le bas

Ceux. comme auparavant, il est impossible d'afficher le journal des traitements à long terme dans le panneau des messages, dans lequel il y a plusieurs milliers d'enregistrements. Je vous conseille de vous limiter à 10 messages. Les journaux doivent être affichés sur une ligne multiligne, ils sont affichés presque instantanément, quel que soit le nombre de lignes. Bien sûr, si vous vérifiez l'intégralité des détails de la partie tabulaire, il y a 1000 lignes et il y a des erreurs dans chacune, alors oui, vous devrez souffrir :) Bien que dans ce cas, vous puissiez penser à votre manière d'afficher des messages, par exemple, dans le champ du document HTML.