Tout sur le tuning automobile

Créer et travailler avec des requêtes (pour les débutants). Création et utilisation de requêtes (pour débutants) Type de document 1c dans une requête

Klyuev V.V.

http://prof1c.kklab.ru

Création ettravailler avec des demandes. Opérations les plus simplespour les débutants(Application régulière)

Bon après-midi

Aujourd'hui, je veux vous expliquer comment commencer à travailler avec des requêtes et apprendre (progressivement, bien sûr) à travailler avec des requêtes dans 1C. Pour ceux qui sont familiers avec les requêtes MS
SQL sera bien sûr beaucoup plus simple.

Ouvrons donc le configurateur et créons un nouveau traitement externe.

Après quoi, nous recevrons une fenêtre avec notre traitement. Passons directement aux expérimentations sur les demandes, pour cela nous allons créer un nouveau formulaire dans notre traitement - et pour cela, dans la liste (champ blanc), sélectionner Formulaires - et cliquer sur (+) Ajouter, accepter tous les paramètres de formulaire par défaut proposés , et cliquez sur Terminé.

Nous avons donc créé pour vous un formulaire vide, avec des boutons et. Dans la fenêtre avec le formulaire, sélectionnez les onglets et passez directement à l'écriture du code qui sera exécuté lorsque vous cliquerez sur le bouton exécuter. Pour cela, retrouvez la procédure ButtonExecutePress(Button)

et écrivez le code suivant :

Procédure ButtonExecutePress(Button) Request = New Request() ; Demande. Texte = " SÉLECTIONNER | * | DEPUIS| Document . Facture de paiement à l'acheteur" ; Résultat = Requête. Exécuter (). Décharger (); Fin de procédure

Commentons ce que nous avons écrit ici. Nous avons sélectionné tous les documents « Facture de paiement à l'acheteur » avec la demande. Je précise d'emblée que, selon la configuration dans laquelle vous expérimentez, regardez la composition des documents dans votre configuration et à la place de la « Facture de paiement à l'acheteur » que j'ai indiquée, substituez n'importe quel objet Document du liste des documents de votre configuration, de préférence pour que les documents de ce type soient créés dans la base d'informations, pour éviter d'obtenir un résultat de requête vide. Je tiens également à souligner un point important - s'il y a trop de documents de ce type, l'exécution de la demande peut prendre un certain temps - du fait que nous ne limitons pas la demande aux conditions et sélectionnons tous les champs - dont l'astérisque ( *) nous dit.

Avec le mot-clé « Sélectionner », nous commandons notre demande de sélection de tous les champs (*) (détails du document) du document « Facture de paiement à l'acheteur ».

Important:
Je voudrais également noter que lors de l'écriture d'un langage de requête, les objets de configuration doivent être adressés au singulier et non au pluriel. Dans ce
Dans ce cas, l'objet Documents dans la configuration (branche Documents) - la requête contient un Document. Également à la composition des documents - on passe par le point (.) - et au nom du document.

Nous recevons le résultat de la requête sous la forme d'un tableau de valeurs, comme en témoigne la méthode (paramètre) que nous avons utilisée - Upload, c'est-à-dire que nous avons d'abord exécuté
demande (Exécuter), puis seulement téléchargé le résultat de la requête dans la table de valeurs et la table de valeurs se trouve dans la variable Résultat.

Ensuite, nous sauvegardons notre traitement dans un fichier, pour ce faire, cliquez sur Fichier->Enregistrer sous et écrivez le nom du fichier, pour mon traitement j'ai défini le nom « ExternalProcessing1Demo », afin de ne pas rechercher le traitement pendant longtemps, vous pouvez l'enregistrer sur le bureau, nous devrons alors l'ouvrir)).

Apprenons maintenant quelques bases du débogage. Pour ce faire, maintenant dans le champ à côté du texte Résultat = ... double-cliquez sur le bouton gauche de la souris pour qu'un cercle rouge apparaisse, vous devriez obtenir quelque chose comme ceci :

Nous avons donc maintenant défini un point d'arrêt sur la ligne avec le résultat, exécutons maintenant la configuration pour le débogage en appuyant sur la touche (F 5) ou sur le bouton
dans la barre d'outils :

Maintenant, dans le mode 1C:Enterprise que nous avons lancé, ouvrons notre fichier de traitement enregistré->Ouvrir et trouvons l'endroit où vous avez enregistré le fichier de traitement, sélectionnez-le et cliquez sur Ouvrir. Cliquez sur le bouton « Exécuter » dans notre traitement. Si vous avez tout fait correctement, vous passerez automatiquement en mode configurateur et verrez ce qui suit à l'emplacement où notre point d'arrêt a été installé :

Une flèche est apparue sur notre cercle - nous sommes passés à l'exécution étape par étape de notre code, et nous verrons ensuite la chose la plus intéressante. Si vous avez tout fait correctement, vous pouvez désormais obtenir le résultat de la demande.

Pour visualiser la requête, procédez comme suit : Dans le menu supérieur du configurateur, recherchez le menu Débogage et sélectionnez la commande Tableau.

Une fenêtre vide -> Tableau s'ouvrira en bas de la fenêtre du configurateur. Il y a des lignes vides dans cette fenêtre. Double-cliquez sur la ligne vide en surbrillance et écrivez le mot Résultat. Vous devriez obtenir ce qui suit :

Ainsi, dans la fenêtre que nous avons spécifiée, nous devrions recevoir le résultat de l'exécution de notre code, à savoir maintenant - la variable "Résultat", puisque nous n'avons pas encore exécuté cette ligne de code - nous avons une valeur vide et le type de données de la variable est « Indéfini ».

Faisons un pas - pour exécuter la ligne de code spécifiée. Pour cela, appuyez sur la touche , ou dans le menu Débogage->Pas à pas... (F 10).

Et que voyons-nous dans notre Tableau :

Nous voyons avec vous - la valeur de la variable et le type de variable. Maintenant, nous pouvons également visualiser le contenu de notre tableau de valeurs, pour ce faire, déplacez le curseur de la souris sur le champ de résultat, cliquez avec le bouton droit et sélectionnez « Afficher la valeur dans une fenêtre séparée »

Nous obtenons une fenêtre avec les documents que nous avons sélectionnés, qui se trouvent dans la variable Résultat

Résumer:

Vous avez appris à créer une requête simple, avez également participé au débogage de votre code et avez même regardé le résultat de notre requête dans le configurateur.

J'ai décidé d'apporter ma contribution et de décrire les caractéristiques du langage qui n'ont pas été abordées dans les articles ci-dessus. L'article s'adresse aux développeurs débutants.

1. Conception « IZ ».

Afin d'obtenir des données de la base de données, il n'est pas du tout nécessaire d'utiliser la construction « DE ».
Exemple : nous devons sélectionner toutes les informations sur les banques dans l'annuaire des banques.
Demande:

SELECT Répertoire.Banques.*

Sélectionne tous les champs du répertoire des banques. Et est similaire à la demande :

SELECT Banques.* FROM Répertoire.Banques AS Banques

2. Classement des données par champ de référence

Lorsque nous devons organiser les données de requête par types primitifs : « Chaîne », « Numéro », « Date », etc., alors tout est résolu en utilisant la construction « ORDER BY » si vous devez trier les données par un champ de référence ? Le champ de référence est un lien, un identifiant unique, c'est à dire En gros, un ensemble arbitraire de caractères et un ordre ordinaire peuvent produire un résultat qui n'est pas entièrement attendu. Pour commander les champs de référence, la construction "AUTO ORDER" est utilisée. Pour ce faire, vous devez d'abord trier les données directement par type de référence à l'aide de la construction "ORDER BY", puis de la construction "AUTO ORDER".

Dans ce cas, pour les documents, le classement se fera dans l'ordre "Date->Numéro", pour les ouvrages de référence dans la "Vue principale". Si le classement ne s'effectue pas par champs de référence, alors l'utilisation de la construction "AUTO ORDER" n'est pas recommandée.

Dans certains cas, la construction « AUTO ORDER » peut ralentir le processus de sélection. De même, vous pouvez réécrire sans commande automatique des documents :

3.Obtention d'une représentation textuelle d'un type référence. Conception "PRÉSENTATION".

Lorsque vous devez afficher un champ de type référence, par exemple le champ "Banque", qui est un lien vers un élément du répertoire "Banques", vous devez comprendre que lors de l'affichage de ce champ, une sous-requête vers le " Banques" sera automatiquement exécuté pour obtenir une vue du répertoire. Cela ralentira la sortie des données. Afin d'éviter cela, vous devez utiliser la construction « PRÉPRESENTATION » dans la requête afin d'obtenir immédiatement une représentation de l'objet puis de l'afficher pour la visualisation.

Dans le système de composition de données, ce mécanisme est utilisé par défaut, mais lors de la création de dispositions en cellules, vous devez spécifier la représentation du champ de référence et, par exemple, placer le lien lui-même dans la transcription.

4. Condition d'échantillonnage des données selon un modèle.

Par exemple, vous devez vous procurer les téléphones portables des employés du formulaire (8 -123-456-78-912). Pour ce faire, vous devez définir la condition suivante dans la requête :

SELECT Employee.Name, Employee.Phone AS Phone FROM Directory.Employees AS Employees WHERE Phone LIKE "_-___-___-__-__"

Le caractère "_" est un caractère de service et remplace n'importe quel caractère.

5. Utilisation simultanée de totaux et de regroupements.


Les totaux sont souvent utilisés conjointement avec des regroupements ; dans ce cas, les fonctions d'agrégation peuvent ne pas être spécifiées dans les totaux.

SELECT Prestation de services.Organisation AS Organisation, Prestation de services.Nomenclature AS Nomenclature, SUM(Fourniture de services.Montant du document) AS Somme du document FROM Document.Prestation de services AS Prestation de services GROUP BY Prestation de services.Organisation, Prestation des Services.Nomenclature RÉSULTATS PAR GÉNÉRAL, Organisation, Nomen klatura

Dans ce cas, la requête renverra presque la même chose que la requête suivante :

SELECT Prestation de services.Organisation AS Organisation, Prestation de services.Nomenclature AS Nomenclature, Prestation de services.Montant du document AS Montant du document FROM Document.Prestation de services AS Prestation de services RÉSULTATS MONTANT (Montant du document) PAR GÉNÉRAL, Organisation, Nomenclature

Seule la première requête réduira les enregistrements ayant la même nomenclature.

6. Champs de déréférencement.

Faire référence à des champs par un point est appelé opération de déréférencement de champ de référence. Par exemple Paiement.Organisation.Unité administrative. Dans ce cas, dans le champ de référence « Organisation » du document « Paiement », il fait référence à une autre table « Organisations », dans laquelle sera obtenue la valeur de l'attribut « Unité administrative ». Il est important de comprendre que lors de l'accès aux champs via un point, la plateforme crée implicitement une sous-requête et joint ces tables.

Demande:

Peut être représenté comme :

SÉLECTIONNEZ Paiement.Lien, Paiement.Organisation, Paiement.Organisation, Organisations. AdministrativeUnit FROM Document.Payment AS Payment LEFT JOIN Directory.Organizations AS Organizations Software Payment.Organization = Organizations.Link

Lors du déréférencement de champs de référence d'un type composite, l'infrastructure tente de créer des jointures implicites à toutes les tables qui font partie du type de ce champ. Dans ce cas, la requête ne sera pas optimale. Si l'on sait clairement de quel type de champ il s'agit, il est nécessaire de limiter ces champs par type avec une construction EXPRIMER().

Par exemple, il existe un registre d'accumulation « Paiements non distribués », où plusieurs documents peuvent faire office de conservateur. Dans ce cas, il est incorrect d'obtenir les valeurs des coordonnées du registraire de cette manière :

SELECT UnallocatedPayments.Register.Date, ..... FROM RegisterAccumulation.UnallocatedPayments AS UnallocatedPayments

vous devez restreindre le type du champ composite à logger :

SELECT EXPRESS (UnallocatedPayments.Register AS Document.Payment).Date, ..... FROM RegisterAccumulation.UnallocatedPayments AS UnallocatedPayments

7. Construction "OÙ"

Avec une jointure gauche de deux tables, lorsque vous imposez une condition « WHERE » sur la table de droite, nous obtiendrons un résultat similaire au résultat avec une jointure interne de tables.

Exemple. Il faut sélectionner tous les Clients dans l'Annuaire Clients et pour les clients qui ont un titre de paiement avec la valeur de l'attribut "Organisation" = &Organisation, afficher le document "Paiement", pour ceux qui n'en ont pas, ne pas l'afficher.

Le résultat de la requête renverra les enregistrements uniquement pour les clients pour lesquels le paiement par organisation était défini dans le paramètre et filtrera les autres clients. Il faut donc d'abord recevoir tous les paiements de « telle ou telle » organisation dans une table temporaire, puis la connecter au répertoire « Clients » à l'aide d'une jointure gauche.

SELECT Payment.Link AS Payment, Payment.Shareholder AS Client PLACE toPayments FROM Document.Payment AS Payment WHERE Payment.Branch = &Branch; ///////////////////////////////////////////// // /////////////////////////// SELECT Clients.Link AS Client, ISNULL(tPayment.Payment, "") AS Paiement FROM Annuaire .Clients AS Clients CONNEXION GAUCHE topayments AS topayments LOGICIEL Clients.Link = topayments.Client

Vous pouvez contourner cette condition d'une autre manière. Il faut imposer une condition "WHERE" directement sur la relation entre les deux tables. Exemple:

SELECT Clients.Link, Payment.Link FROM Directory.US_Subscribers AS US_Subscribers GAUCHE CONNEXION Document.Payment AS Payment Software (Clients.Link = Payment.Client AND Payment.Client.Name LIKE "Sugar Packet") GROUP BY Clients.Link, Paiement. Lien

8. Jointures avec des tables imbriquées et virtuelles

Requêtes imbriquées souvent nécessaire pour récupérer des données en fonction de certaines conditions. Si vous les utilisez ensuite avec d'autres tables, cela peut ralentir considérablement l'exécution de la requête.

Par exemple, nous devons obtenir le montant du solde à la date du jour pour certains clients.

SELECT UnallocatedPaymentsRemains.Customer, UnallocatedPaymentsRemains.AmountRemaining FROM (SELECT Clients.Link AS Link FROM Directory.Clients AS Clients WHERE Clients.Link IN(&Clients)) AS NestedQuery LEFT JOIN RegisterAccumulations.UnallocatedPayments.Balances AS UnallocatedPayments BY Nested Request.Link = UnallocatedPaymentsBalances. Client

Lors de l'exécution d'une telle requête, l'optimiseur du SGBD peut commettre des erreurs lors du choix d'un plan, ce qui entraînera une exécution sous-optimale de la requête. Lors de la jointure de deux tables, l'optimiseur de SGBD sélectionne un algorithme de jointure de table en fonction du nombre d'enregistrements dans les deux tables. S'il existe une requête imbriquée, il est extrêmement difficile de déterminer le nombre d'enregistrements que la requête imbriquée renverra. Par conséquent, vous devez toujours utiliser des tables temporaires au lieu de requêtes imbriquées. Alors réécrivons la demande.

SELECT Clients.Link AS Link PLACE tClients FROM Directory.Clients AS Clients OÙ
Clients.Lien B (&Clients) ; ///////////////////////////////////////////// // /////////////////////////// SELECT tClients.Link, UnallocatedPaymentsRemains.AmountRemaining, FROM tClients AS tClients LEFT JOIN RegisterAccumulations.UnallocatedPayments.Balances (, Client IN (SELECT tClients.Link FROM tClients)) AS UnallocatedPaymentsBalances tClients.Link = UnallocatedPaymentsBalances.Clients

Dans ce cas, l'optimiseur pourra déterminer le nombre d'enregistrements utilisés par la table temporaire tClients et pourra sélectionner l'algorithme optimal pour joindre les tables.

Tables virtuelles , permettent d'obtenir des données pratiquement toutes faites pour la plupart des tâches appliquées (Tranche du Premier, Tranche du Dernier, Restes, Chiffres d'affaires, Restes et Chiffres d'affaires) Le maître mot ici est virtuel. Ces tableaux ne sont pas physiques, mais sont compilés par le système à la volée, c'est-à-dire Lors de la réception des données des tables virtuelles, le système collecte les données des tables du registre final, les assemble, les regroupe et les transmet à l'utilisateur.

Ceux. Lors de la connexion à une table virtuelle, une connexion est établie à une sous-requête. Dans ce cas, l'optimiseur de SGBD peut également choisir un plan de connexion non optimal. Si la requête n'est pas générée assez rapidement et qu'elle utilise des jointures dans des tables virtuelles, alors il est recommandé de déplacer l'accès aux tables virtuelles vers une table temporaire, puis de réaliser une jointure entre deux tables temporaires. Réécrivons la requête précédente.

SELECT Clients.Link AS Link PLACER les tClients FROM Directory.Clients AS Clients INDEX BY Link OÙ
Clients.Lien B (&Clients) ; ///////////////////////////////////////////// // /////////////////////////// SELECT UnallocatedPayments.AmountBalance, UnallocatedPayments.Client AS Client PLACER les soldes FROM RegisterAccumulations.UnallocatedPayments.Balances(, Client B ( SELECT tClients.Link FROM tClients)) AS UnallocatedPaymentsBalances ; ///////////////////////////////////////////// // /////////////////////////// SELECT tClients.Link, toRemainders.AmountRemaining AS AmountRemaining FROM tClients AS tClients LEFT JOIN toRemainders AS Remainders BY tClients.Link = tRemainings.Client

9.Vérification du résultat de la demande.

Le résultat de la requête peut être vide ; pour vérifier les valeurs vides, utilisez la construction suivante :

ResRequest = Request.Execute(); Si resQuery.Empty() Then Return; fin si;

Méthode Vide() doit être utilisé avant les méthodes Choisir() ou Décharger(), car la récupération de la collection prend du temps.

Ce n'est une révélation pour personne qu'il est extrêmement indésirable d'utiliser des requêtes en boucle. Cela peut affecter de manière critique la durée de fonctionnement d’une fonction particulière. Il est hautement souhaitable de recevoir toutes les données de la requête, puis de traiter les données en boucle. Mais il arrive parfois qu'il devienne impossible de déplacer la requête en dehors de la boucle. Dans ce cas, pour optimiser, vous pouvez déplacer la création de la requête en dehors de la boucle, et dans la boucle, substituer les paramètres nécessaires et exécuter la requête.

Demande = Nouvelle demande ; Query.Text = "SELECT | Clients.Link, | Clients.Birthdate |FROM | Directory.Clients AS Clients |WHERE | Clients.Link = &Client"; Pour chaque ligne FROM TableClients Boucle Query.SetParameter("Client", Client); QueryResult = Query.Execute().Select(); Fin du cycle ;

Cela évitera au système de vérifier la syntaxe de la requête en boucle.

11. Construction « AVOIR ».

Un design assez rare dans les demandes. Permet d'imposer des conditions sur les valeurs des fonctions d'agrégation (SOMME, MINIMUM, MOYENNE, etc.). Par exemple, vous devez sélectionner uniquement les clients dont le montant du paiement en septembre était supérieur à 13 000 roubles. Si vous utilisez la condition « WHERE », vous devrez d'abord créer une table temporaire ou une requête imbriquée, y regrouper les enregistrements par montant de paiement puis appliquer la condition. La construction « HAVING » aidera à éviter cela.

SELECT Payment.Customer, AMOUNT(Payment.Amount) AS Montant FROM Document.Payment AS Payment WHERE MOIS(Payment.Date) = 9 GROUP BY Payment.Customer HAVING AMOUNT(Payment.Amount) > 13000

Dans le constructeur, pour cela, il suffit d'aller dans l'onglet « Conditions », d'ajouter une nouvelle condition et de cocher la case « Personnalisé ». Alors écris simplement Montant(Paiement.Montant) > 13000


12. Valeur NULLE

Je ne décrirai pas ici les principes de la logique à trois valeurs dans la base de données, il existe de nombreux articles sur ce sujet. Juste brièvement sur la façon dont NUL peut affecter le résultat de la requête. La valeur NULL n'est pas réellement une valeur et le fait que la valeur soit indéfinie est inconnu. Par conséquent, toute opération avec NULL renvoie NULL, qu'il s'agisse d'une addition, d'une soustraction, d'une division ou d'une comparaison. Une valeur NULL ne peut pas être comparée à une valeur NULL car nous ne savons pas quoi comparer. Ceux. ces deux comparaisons sont : NULL = NULL, NULL<>NULL n'est ni vrai ni faux, c'est inconnu.

Regardons un exemple.

Pour les clients qui n'ont pas de paiement, nous devons afficher le champ « Signer » avec la valeur « Aucun paiement ». De plus, nous savons avec certitude que nous avons de tels clients. Et afin de refléter l’essence de ce que j’ai écrit ci-dessus, procédons de cette façon.

SELECT "Aucun paiement" AS Attribut, NULL AS Document PLACE topayments ; ///////////////////////////////////////////// // ////////////////////////// SELECT Clients.Link AS Client, Payment.Link COMMENT Paiement PUT tClientPayment FROM Directory.Clients AS Clients GAUCHE CONNEXION Document. Paiement AS Logiciel de paiement Clients.Link = Payment.Shareholder; ///////////////////////////////////////////// // /////////////////////////// SELECT tClientPayment.Client FROM tClientPayment AS tClientPayment INTERNAL JOIN tPayment AS tTopay BY tClientPayment.Payment = tPayment.Document

Faites attention à la deuxième table temporaire tClientPayment. Avec la jointure de gauche, je sélectionne tous les clients et tous les paiements pour ces clients. Pour les clients qui n'ont pas de paiement, le champ « Paiement » sera NULL. Suivant la logique, dans la première table temporaire « tPayments » j'ai désigné 2 champs, l'un d'eux NULL, la deuxième ligne « N'a pas de paiements ». Dans le troisième tableau, je connecte les tables « tClientPayment » et « tPayment » en utilisant les champs « Payment » et « Document » avec une jointure interne. On sait que dans le premier tableau le champ « Document » est NULL, et dans le deuxième tableau, ceux qui n'ont pas de paiement dans le champ « Paiement » sont également NULL. Que nous rapportera une telle connexion ? Mais cela ne retournera rien. Parce que la comparaison NULL = NULL n’est pas évaluée à True.

Pour que la requête renvoie le résultat attendu, réécrivons-la :

SELECT "Aucun paiement" AS Attribut, VALUE (Document.Payment.EmptyLink) AS Document PLACE toPayments ; ///////////////////////////////////////////// // ////////////////////////// SELECT Clients.Link AS Client, ISNULL(Payment.Link, VALUE(Document.Payment.EmptyLink )) COMMENT Paiement PUT tClientPayment FROM Directory.Clients AS Clients LEFT CONNECTION Document.Payment AS Payment BY Clients.Link = Payment.Shareholder; ///////////////////////////////////////////// // /////////////////////////// SELECT tClientPayment.Client FROM tClientPayment AS tClientPayment INTERNAL JOIN tPayment AS tTopay BY tClientPayment.Payment = tPayment.Document

Maintenant, dans la deuxième table temporaire, nous avons indiqué que si le champ « Paiement » est NULL, alors ce champ = un lien vide vers le document de paiement. Dans le premier tableau, nous avons également remplacé NULL par une référence vide. Désormais, la connexion implique des champs non NULL et la requête renverra le résultat attendu.

Toutes les demandes contenues dans l'article reflètent les situations que je voudrais considérer et rien de plus. À PROPOS Ils ne peuvent pas être délirants ou sous-optimaux, l'essentiel est qu'ils reflètent l'essence de l'exemple.

13. Une fonctionnalité non documentée de la conception "CHOIX WHEN...THEN...END".

Dans le cas où il est nécessaire de décrire la construction « Conditions » dans la requête, nous utilisons la syntaxe standard :

SELECTION WHEN Users.Name = "Vasya Pupkin" ALORS "Notre employé préféré" ELSE "Nous ne le savons pas" END AS Field1 FROM Directory.Users AS Users

Mais que se passe-t-il si, par exemple, nous avons besoin d’obtenir le nom du mois dans une requête ? Écrire une énorme construction dans une requête est laid et prend du temps, donc cette forme d'écriture ci-dessus peut nous aider :

SELECT MOIS (US_CalculationConsumption_ScheduleTurnover.CalculationPeriod) QUAND 1 PUIS "Janvier" QUAND 2 PUIS "Février" QUAND 3 PUIS "Mars" QUAND 4 PUIS "Avril" QUAND 5 PUIS "Mai" QUAND 6 PUIS "Juin" QUAND 7 PUIS "Juillet" K QUAND 8 PUIS "Août" QUAND 9 PUIS "Septembre" QUAND 10 PUIS "Octobre" QUAND 11 PUIS "Novembre" QUAND 12 PUIS "Décembre" FINIR COMME UN MOIS

Désormais, le design semble moins encombrant et facile à comprendre.

14. Exécution de requêtes par lots.


Afin de ne pas multiplier les demandes, vous pouvez créer une seule demande volumineuse, la diviser en packages et travailler avec elle.
Par exemple, j'ai besoin d'obtenir les champs suivants du répertoire « Utilisateurs » : « Date de naissance » et les rôles disponibles pour chaque utilisateur. téléchargez-le dans différentes parties tabulaires du formulaire. Bien sûr, vous pouvez le faire en une seule requête, vous devrez alors parcourir les enregistrements ou les réduire, ou vous pouvez faire ceci :

SELECT Users.Link AS Nom complet, Users.Date of Birth, Users.Role PUT vtUsers FROM Directory.Users AS Users ; ///////////////////////////////////////////// // /////////////////////////// SELECT tueUsers.Nom complet, tueUsers.Date de naissance FROM tueUsers AS tueUsers GROUP BY tueUsers.nom complet, tueUsers . Date de naissance; ///////////////////////////////////////////// // /////////////////////////// SELECT wUsers.Nom complet, wUsers.Role FROM wUsers AS wUsers GROUP BY wUsers.Nom complet, wUsers.Date de naissance

tPackage = Request.ExecutePackage();

TP_BirthDate = tPackage.Upload();
TP_Roles = tPackage.Unload();

Comme nous pouvons le voir, la requête peut être exécutée par lots et le résultat peut être traité sous forme de tableau. Dans certains cas, c'est très pratique.

15. Conditions dans une demande groupée

Par exemple, nous avons une demande par lots, dans laquelle nous obtenons d'abord les champs : « Nom, Date de naissance, Code » du répertoire « Utilisateurs » et souhaitons obtenir des enregistrements avec des conditions pour ces champs du répertoire « Particuliers ».

SELECT Users.Individual.Name AS Nom, Users.Individual.Date of Birth AS Date de naissance, Users.Individual.Code AS Code PLACE vtUsers FROM Directory.Users AS Users ; ///////////////////////////////////////////// // ////////////////////////// SELECT Individus. Lier AS Individu FROM Répertoire. Individus AS Individus

Vous pouvez imposer des conditions comme celles-ci :

OÙ Individus.Code IN (SELECT vtUsers.Code FROM vtUsers) ET Individuals.Name IN (SELECT vtUsers.Code FROM vtUsers) AND Individuals.BirthDate IN (SELECT vtUsers.DateBirth FROM tvUsers)

Et vous pouvez procéder comme ceci :

OÙ (Individus.Code, Individus.Nom, Individus.Date de naissance) DANS (SELECT tueUsers.Code, tueUsers.Name, tueUsers.Date of Birth FROM tueUsers)

De plus, il est nécessaire de maintenir l’ordre.

16. Appel du générateur de requêtes pour « condition » dans une requête par lots

Lorsqu'il faut imposer une condition, comme dans l'exemple ci-dessus, on peut oublier comment tel ou tel champ est appelé dans la table virtuelle.
Par exemple, vous devez imposer une condition sur le champ « Date de naissance », et dans la table virtuelle ce champ s'appelle « Date de naissance du débiteur », et si vous oubliez le nom, vous devrez quitter l'édition de la condition sans sauvegarde et regardez le nom du champ. Afin d'éviter cela, vous pouvez utiliser la technique suivante.

Il faut mettre des parenthèses après la Construction « B » et laisser un espace vide (espace) entre les parenthèses, sélectionner cet espace et appeler le constructeur de requête. Le concepteur aura accès à toutes les tables de la requête batch. La technique fonctionne aussi bien sur les tables de registres virtuels que sur l'onglet « Conditions ». Dans ce dernier cas, il faut cocher la case "P (condition arbitraire)" et entrer dans le mode d'édition "F4".

Les requêtes étaient souvent formulées à la volée et ne servent qu'à illustrer les « techniques » que j'envisageais.

Je voulais examiner l'utilisation des index dans les requêtes, mais c'est un sujet très vaste. Je le mettrai dans un article séparé, ou je l'ajouterai ici plus tard.

mise à jour1. Points 11,12
mise à jour2. Points 13,14,15,16

Livres d'occasion :
Langage de requête "1C:Enterprise 8" - E.Yu. Khrustaleva
Développement professionnel dans le système 1C:Enterprise 8."

Dans cet article, nous voulons discuter de tout avec vous Fonctions du langage de requête 1C, et constructions de langage de requête. Quelle est la différence entre fonction et design ? La fonction est appelée avec des parenthèses et les paramètres possibles, et la construction est écrite sans parenthèses. Indubitablement toutes les structures et fonctions du langage de requête 1C rendre le processus d'acquisition de données flexible et multifonctionnel. Ces fonctions et constructions s'appliquent aux champs de requête, et certaines s'appliquent également aux conditions.

Fonctions du langage de requête 1C

Parce qu'une description claire Fonctions du langage de requête 1C est beaucoup moins courant que les descriptions de structures, nous avons décidé de commencer à nous intéresser aux fonctions. Examinons maintenant chacun séparément, en décrivant son objectif, sa syntaxe et son exemple d'utilisation, donc :

1. Fonction DATE HEURE- cette fonction crée un champ constant de type "Date".

Syntaxe: DATE HEURE (<Год>,<Месяц>,<День>,<Час>,<Минута>,<Секунда>)

Exemple d'utilisation :

2. Fonction DIFFÉRENCE DE DATE- renvoie la différence entre deux dates dans l'une des dimensions (année, mois, jour, heure, minute, seconde). La mesure est passée en paramètre.

Syntaxe: DATE DE DIFFÉRENCE (<Дата1>, <Дата2>, <Тип>)

Exemple d'utilisation :

Query.Text = "SELECT | DIFFERENCEDATE(DATETIME(2015, 4, 17), DATETIME(2015, 2, 1), DAY) | AS Nombre de jours";

3. Fonction VALEUR- définit un champ constant avec un enregistrement prédéfini de la base de données ; vous pouvez également obtenir un lien vide de n'importe quel type.

Syntaxe : VALEUR(<Имя>)

Exemple d'utilisation :

Request.Text = "SELECT //élément prédéfini | VALUE(Directory.Currencies.Dollar) AS Dollar, //lien vide | VALUE(Document.Receipt of Goods and Services.EmptyLink) AS Receipt, //valeur du transfert | VALUE(Transfert . Personne morale. Particulier) AS Particulier, //compte prédéfini | VALUE(Plan comptable. Autonome. Matériels) AS Compte_10" ;

4. Fonction SÉLECTIONNER- nous avons devant nous un analogue de la construction IF, qui est utilisée dans le code, seule celle-ci est utilisée dans les requêtes 1C.

Syntaxe: CHOIX QUAND<Выражение>ALORS<Выражение>SINON<Выражение>FIN

Exemple d'utilisation :

Request.Text = //si le montant est supérieur à 7 500, alors il devrait y avoir une remise de 300 roubles, //donc si la condition est déclenchée alors la fonction //renvoie Montant - 300 //sinon la demande renverra simplement Montant "SELECT | SELECT | WHEN TCReceipts.Amount > 7500 | THEN TCReceipts.Amount - 300 | ELSE TCReceipts.Amount | END AS AmountWithDiscount |FROM | Document.Receipt of GoodsServices.Goods AS TCReceipts" ;

5. Fonction EXPRESSE- permet d'exprimer un champ constant avec un type spécifique.

Syntaxe: EXPRESS (Nom de champ AS Nom de type)

Exemple d'utilisation :

Query.Text = "SELECT DIVERS | Sales.Registrar.Number, | SELECT | WHEN Sales.Registrar LINK Document.Consumable | ALORS EXPRESS (Sales.Registrar AS Document.Consumable) | ELSE SELECT | WHEN Sales.Registrar LINK Document.Implementation | ALORS EXPRESS(Sales.Registrar AS Document.Implementation) | END | ... | END AS Number | FROM | RegisterAccumulations.Purchases AS Purchases";

Existe-t-il une autre option pour utiliser la fonction EXPRESS dans des champs de types mixtes, où se produisent-ils ? L'exemple le plus simple est le « registraire » pour n'importe quel registre. Alors pourquoi pourrions-nous avoir besoin de qualifier le type dans le registraire ? Considérons la situation lorsque nous sélectionnons le champ « Numéro » du registraire, dans quelle table le numéro sera-t-il sélectionné ? La bonne réponse de tous ! Par conséquent, pour que notre requête fonctionne rapidement, nous devons spécifier un type explicite à l'aide de la fonction EXPRESS

Exemple d'utilisation :

Query.Text = "SELECT | EXPRESS(Nomenclature.Comment AS Line(300)) AS Comment, | EXPRESS(Nomenclature.Sum AS Number(15,2)) AS Sum |FROM | Directory.Nomenclature AS Nomenclature";

6. Fonction ISNULL(orthographe alternative ISNULL) - si le champ est de type NULL, alors il est remplacé par le deuxième paramètre de la fonction.

Syntaxe: EST NULL(<Поле>, <ПодставляемоеЗначение>)

Exemple d'utilisation :

Notez également qu'il est conseillé de TOUJOURS remplacer le type NULL par une valeur, car la comparaison avec le type NULL renvoie toujours FALSE même si vous comparez NULL avec NULL. Le plus souvent, les valeurs NULL sont formées à la suite de jointures de tables (tous types de jointures sauf internes).

Query.Text = //Sélectionnez l'article entier et ses soldes //s'il n'y a pas de solde dans un article, alors il y aura un champ //NULL qui sera remplacé par la valeur 0 "SELECT | No. Link, | ISNULL (ProductsInStockRemains.InStockRemaining, 0) AS Reste | DE | Répertoire.Nomenclature AS No. | CONNEXION GAUCHE Registre Accumulations. GoodsInWarehouses. Restes AS GoodsInWarehousesRemains | ON (GoodsInWarehousesRemains. Nomenclature = No. Link)";

7. Fonction REPRÉSENTATION- permet d'obtenir une représentation du champ de la requête.

Syntaxe: PERFORMANCE(<НаименованиеПоля>)

Exemple d'utilisation :

Query.Text = "SELECT | REPRÉSENTATION(FreeRemainingRemains.Nomenclature) AS Nomenclature, | REPRÉSENTATION(FreeRemainingRemaining.Warehouse) AS Entrepôt, | FreeRemainingRemaining.InStockRemaining |FROM |Accumulation Register.FreeRemaining.Remaining AS FreeRemainingRemaining";

Constructions dans le langage de requête 1C

Nous en avons discuté avec vous ci-dessus Fonctions du langage de requête 1C, il est maintenant temps de réfléchir constructions dans le langage de requête 1C, ils n’en sont pas moins importants et utiles, commençons.

1. LIEN Construction- est un opérateur logique pour vérifier un type de référence. Le plus souvent rencontré lors de la vérification d'un champ d'un type complexe par rapport à un type spécifique. Syntaxe: LIEN<Имя таблицы>

Exemple d'utilisation :

Request.Text = //si le type de valeur de l'enregistreur est le document Reçu, // alors la requête renverra "Réception de marchandises", sinon "Ventes de marchandises" "SELECT | SELECT | WHEN Remainings.Registrar LINK Document.Receipt of Goods et Services | ALORS ""Réception"" | ELSE ""Consommation"" | FIN COMME Type de mouvement | DE | Registre d'accumulation. Produits restants dans les entrepôts AS Restes" ;

2. Conception ENTRE- cet opérateur vérifie si la valeur est dans la plage spécifiée.

Syntaxe: ENTRE<Выражение>ET<Выражение>

Exemple d'utilisation :

Request.Text = //récupère la nomenclature complète dont le code est compris entre 1 et 100 "SELECT | Nomenclature.Link |FROM | Directory.Nomenclature AS Nomenclature |WHERE | Nomenclature.Code BETWEEN 1 AND 100" ;

3. Construction B et B HIÉRARCHIE- vérifier si la valeur est dans la liste transférée (les tableaux, tableaux de valeurs, etc. peuvent être transférés sous forme de liste). L'opérateur DANS LA HIÉRARCHIE permet de visualiser la hiérarchie (un exemple d'utilisation du Plan Comptable).

Syntaxe: DANS(<СписокЗначений>), DANS LA HIÉRARCHIE (<СписокЗначений>)

Exemple d'utilisation :

Request.Text = //sélectionnez tous les sous-comptes du compte "SELECT | Autonome. Lien AS Compte | DE | Plan comptable. Autonome AS Autonome | OÙ | Autonome. Lien DANS LA VALEUR DE LA HIÉRARCHIE (Graphique de Comptes. Autofinancement. Biens)" ;

4. Conception SIMILAIRE- Cette fonction nous permet de comparer une chaîne avec un motif de chaîne.

Syntaxe: COMME "<ТекстШаблона>"

Options de modèle de ligne :

% - une séquence contenant un nombre quelconque de caractères arbitraires.

Un caractère arbitraire.

[...] - tout caractère unique ou séquence de caractères répertoriés entre crochets. L'énumération peut spécifier des plages, par exemple a-z, signifiant un caractère arbitraire inclus dans la plage, y compris les extrémités de la plage.

[^...] - tout caractère ou séquence de caractères répertoriés entre crochets, à l'exception de ceux répertoriés après le signe de négation.

Exemple d'utilisation :

Query.Text = //trouver la nomenclature entière qui contient la racine TABUR et commence //soit par une lettre minuscule ou majuscule t "SELECT | Nomenclature. Lien | FROM | Répertoire. Nomenclature AS Nomenclature | WHERE | Produits. Nom LIKE "" [Tt ]abur%""" ;

5. Conception AUTORISÉE- cet opérateur vous permet de sélectionner uniquement les enregistrements de la base de données pour lesquels l'appelant dispose d'une autorisation de lecture. Ces droits sont configurés au niveau de l'enregistrement (RLS).

Syntaxe: ALLOWED est écrit après le mot-clé SELECT

Exemple d'utilisation :

Request.Text = "SELECT ALLOWED | Contreparties. Lien | FROM | Annuaire. Contreparties COMME Contreparties";

6. Conception DIVERS- vous permet de sélectionner des enregistrements dans lesquels il n'y a pas d'enregistrements en double.

Syntaxe: DIVERS s'écrit après le mot-clé SELECT

Exemple d'utilisation :

Request.Text = //sélectionne les enregistrements sur lesquels le lecteur a des droits "SELECT DIVERS | Counterparties.Name |FROM | Directory. Counterparties AS Counterparties" ;

De plus, la construction DIVERS peut être utilisée avec l'opérateur AUTORISÉ et d'autres opérateurs.

Exemple d'utilisation :

Request.Text = //sélectionne divers enregistrements sur lesquels le lecteur a des droits "SELECT ALLOWED DIVERS | Counterparties.Name |FROM | Directory. Counterparties AS Counterparties";

7. Concevoir EN PREMIER- sélectionne le nombre d'enregistrements spécifiés dans le paramètre à partir du résultat de la requête.

Syntaxe : PREMIER<число>

Exemple d'utilisation :

Request.Text = //sélectionnez les 4 premiers numéros CCD du répertoire "SELECT FIRST 4 | Numéros CCD. Lien | FROM | Répertoire. Numéros CCD COMME numéros CCD";

8. Concevoir POUR LE CHANGEMENT- vous permet de verrouiller une table, fonctionne uniquement dans les transactions (pertinent uniquement pour les verrouillages automatiques).

Syntaxe: POUR CHANGER<НаименованиеТаблицы>

Exemple d'utilisation :

Query.Text = "SELECT | Restes libres Restes. Nomenclature, | Restes libres Restes. Entrepôt, | Restes libres Restes. En stock Restant | DE | Registre des accumulations. Restes libres. Restes AS Restes libres Restes | POUR CHANGEMENT | Registre des accumulations . Restes libres. Restes" ;

9. COMMANDER PAR- organise les données par un champ spécifique. Si le champ est un lien, alors lors de la définition du drapeau COMMANDE AUTOMATIQUE Le tri s'effectuera par représentation des liens ; si l'indicateur est désactivé, alors les liens sont triés selon l'ancienneté de l'adresse du lien en mémoire.

Syntaxe: TRIER PAR<НаименованиеПоля>COMMANDE AUTOMATIQUE

Exemple d'utilisation :

Query.Text = "SELECT | Restes libres Restes. Nomenclature AS Nomenclature, | Restes libres Restes. Entrepôt AS Entrepôt, | Restes libres Restes. En stock Restant | DE | Enregistrer les accumulations. Restes libres. Restant AS Restes restants libres | | ORDER BY | Nomenclature | VANIE DE COMMANDE AUTOMATIQUE" ;

10. Conception GROUPE PAR- utilisé pour regrouper les chaînes de requête par champs spécifiques. Les champs numériques doivent être utilisés avec toute fonction d'agrégation.

Syntaxe: PAR GROUPE<НаименованиеПоля1>, .... , <НаименованиеПоляN>

Exemple d'utilisation :

" ;

11. Conception AVOIR- vous permet d'appliquer une fonction d'agrégation à une condition de sélection de données, similaire à la construction WHERE.

Syntaxe: AYANT<агрегатная функция с условием>

Exemple d'utilisation :

Query.Text = //sélectionne les enregistrements groupés où le champ InStock est supérieur à 3 "SELECT | ItemsInStocks.Nomenclature AS Nomenclature, | ItemsInWarehouses.Warehouse, | SUM(ItemsInStocks.InStock) AS INSTOCK |FROM | RegisterAccumulations.ItemsInStocks AS ItemsInStocks | | GROUP BY | ProductsInWarehouses.Nomenclature, | ProductsInWarehouses.Warehouse | |DISPONIBLE | MONTANT(ProductsInWarehouses.InStock) > 3" ;

12. INDICE DE CONSTRUCTION PAR- utilisé pour indexer le champ de requête. Une requête avec indexation prend plus de temps, mais accélère la recherche dans les champs indexés. Ne peut être utilisé que dans les tables virtuelles.

Syntaxe: INDEX PAR<Поле1, ... , ПолеN>

Exemple d'utilisation :

Query.Text = "SELECT | Ts.NameOS, | Ts.FolderNumber, | Ts.CodeOS, | Ts.Term, | Ts.Type | PLACE DataTs | FROM | &Ts AS Ts | | INDEX BY | Ts.NameOS, | Ts .CodeOS" ;

13. Conception OÙ- vous permet d'imposer une condition sur n'importe quel champ de sélection. Le résultat inclura uniquement les enregistrements qui satisfont à la condition.

Syntaxe: OÙ<Условие1 ОператорЛогСоединения УсловиеN>

Exemple d'utilisation :

Query.Text = //tous les enregistrements avec CompensationRemaining sont sélectionnés<>0 et //AmountForCalcCompRemaining > 100 "SELECT | CompensationRPORemains.Counterparty, |CompensationRPORemains.Child, | CompensationRPORemains.CompensationRemaining, | CompensationRPORemains.AmountForCalcCompRemains |Place DataTz |FROM | Accumulation Register.CompensationRP.Remains AS CompensationRPRemains | WHERE |CompensationRPORe maining.CompensationRemaining<>0 | Et CompensationRPORemains.AmountForCalcCompRemaining> 100" ;

14. RÉSULTATS DE CONCEPTION... GÉNÉRAL- utilisé pour calculer les totaux ; la conception spécifie les champs par lesquels les totaux seront calculés et les fonctions d'agrégation appliquées aux champs de totaux. Lorsque vous utilisez des totaux pour chaque champ après la construction TOTAL, les données sont regroupées. Il existe une construction GÉNÉRALE facultative ; son utilisation fournit également un regroupement supplémentaire. Vous verrez un exemple du résultat de la demande ci-dessous.

Syntaxe: RÉSULTATS<АгрегатнаяФункция1, ... , АгрегатнаяФункцияN>PAR<ОБЩИЕ> <Поле1, ... , ПолеN>

Exemple d'utilisation :

Request.Text = "SELECT | Calculs. Accord de contrepartie. Type d'accord AS Type de contrat, | Calculs. Accord de contrepartie AS Contrat, | Calculs. Contrepartie, | Calculs. Montant du règlement mutuel Solde AS Solde | FROM | Registre des accumulations. Mutuelle Règlement AVEC Contreparties. Soldes AS Calculs | TOTAL | MONTANT (Solde) |Logiciel | GÉNÉRAL, | Type d'accord" ;

La figure présente les regroupements qui ont été formés lors de l'exécution de la demande, celui du haut fait référence à la section GÉNÉRAL et le second au champ Type d'accord d'accord de contrepartie.

Une requête est un outil puissant qui permet d'obtenir et de traiter rapidement (par rapport à toutes les autres méthodes) les données contenues dans divers objets de la base d'informations 1C.

Créer une demande

La demande est créée en tant qu'objet distinct doté d'un attribut obligatoire Texte, où la demande elle-même est réellement placée. De plus, divers paramètres nécessaires à son exécution peuvent être transmis à la requête. Une fois le texte et les paramètres de la requête renseignés, la requête doit être exécutée et le résultat de l'exécution placé dans une sélection ou un tableau de valeurs. Tout ressemble à ceci :

//Créer une requête
Demande = nouvelle demande ;

//Remplissez le texte de la demande
Demande. Texte= "Ici, nous écrivons le texte de la demande";

// Passer les paramètres à la requête
Demande. SetParameter("ParameterName" , ParameterValue) ;

//Exécuter la requête
Résultat = Requête. Courir() ;

// Téléchargez le résultat de la requête dans la sélection
Échantillon = Résultat. Choisir() ;

// Téléchargez le résultat de la requête dans la table de valeurs
Tableau = Résultat. Décharger() ;

//Les dernières actions peuvent être combinées
Récupérer = Requête. Courir() . Choisir() ;
//ou
Tableau = Requête. Courir() . Décharger() ;

Bases du langage de requête 1C

Les requêtes les plus simples et les plus fréquemment utilisées sont utilisées pour obtenir des données à partir d'une source donnée. La source peut être presque tous les objets contenant des données quelconques : répertoires, documents, registres, constantes, énumérations, plans de types de caractéristiques, etc.

A partir de ces objets, à l'aide d'une requête, vous pouvez obtenir les valeurs des détails, des parties de tableau, des détails des parties de tableau, des modifications, des ressources, etc.

Pour obtenir le texte de la demande, il est souvent pratique d'utiliser Constructeur de requête. Il est appelé lorsque vous cliquez avec le bouton droit n'importe où dans le module du programme.

Par exemple, si vous avez besoin d'obtenir les valeurs de tous les détails du répertoire Contreparties, alors la requête ressemblera à ceci :

Demande. Texte = "CHOISIR
| *
|DE
| Annuaire. Contreparties"
;

Si vous n'avez besoin d'obtenir que des détails individuels, procédez comme suit :

Demande. Texte = "CHOISIR
| Code,
| Nom,
| Parent
|DE
| Annuaire. Contreparties"
;

Pour recevoir une telle demande par SMS Constructeur de requête vous devez sélectionner les champs appropriés dans l'onglet Tableaux et champs.

Vous pouvez attribuer des alias aux éléments et sources sélectionnés dans la requête et les utiliser ultérieurement à la fois dans la requête elle-même et lorsque vous travaillez avec le résultat. De plus, la requête peut contenir des champs avec une valeur spécifique prédéfinie, ou avec une valeur calculée :

Demande. Texte = "CHOISIR
| Clients.Code AS Numéro,

| 1000 AS ChampAvecValeur
|DE
;

Récupérer = Requête. Courir() . Choisir() ;

Au revoir la sélection. Boucle Suivant()
ClientNumber = Échantillon. Nombre;
ClientName = Sélection. Nom;
Valeur = Échantillon. ChampAvecValeur ;
Fin du cycle ;

Utilisez l'onglet pour définir des alias Syndicats/Alias V Générateur de requêtes.

Un champ à valeur fixe ou calculée est créé manuellement sur l'onglet Tables et champs, dans une colonne Des champs.

Tous les éléments sélectionnés peuvent être disposés dans l'ordre direct ou inverse. Vous pouvez sélectionner un ou plusieurs champs pour la commande. En plus de l'organisation, il peut parfois être utile de sélectionner un ou quelques-uns des premiers éléments.

//Classez les clients par nom de A à Z et sélectionnez les 10 premiers
Demande. Texte = "SÉLECTIONNEZ LES 10 PREMIERS
| Clients.Code AS Numéro,
| Clients.Nom AS Nom,
| 1000 AS ChampAvecValeur
|DE

|COMMANDER PAR
| Nom"
;

//Sélectionnez le client alphabétique le plus récent
Demande. Texte = "SÉLECTIONNER LE TOP 1
| Clients.Code AS Numéro,
| Clients.Nom AS Nom,
| 1000 AS ChampAvecValeur
|DE
| Annuaire Contreparties AS Clients
|COMMANDER PAR
| Nom DIMINUTION"
;

Vous pouvez limiter la sélection des éléments à ceux pour lesquels l'utilisateur dispose de droits d'accès. Ou supprimez les lignes en double du résultat de la requête.

//Données d'échantillonnage autorisées à l'utilisateur
Demande. Texte = "SÉLECTION AUTORISÉE
| Clients.Code AS Numéro,
| Clients.Nom AS Nom,
| 1000 AS ChampAvecValeur
|DE
| Annuaire "Contreparties AS Clients"
;

//Sélection d'éléments non répétitifs
Demande. Texte = " SÉLECTIONNEZ DIVERS
| Clients.Code AS Numéro,
| Clients.Nom AS Nom,
| 1000 AS ChampAvecValeur
|DE
| Annuaire "Contreparties AS Clients"
;

La commande est définie sur l'onglet Commande V Générateur de requêtes le nombre d'éléments sélectionnés, les paramètres de résolution et de répétabilité sont sur l'onglet En plus.

À suivre…