Tous ceux qui ont travaillé avec le code de quelqu'un d'autre dans 1C ont au moins une fois éprouvé le même sentiment : vous ouvrez un module, et il y a une procédure de 800 lignes avec le nom « Traiter les données ». Sans commentaires. Avec les variables « a », « b » et « Temps ». Et vous comprenez que dans six mois, votre propre code peut provoquer exactement les mêmes émotions chez quelqu'un.
Voyons voir, comment écrire des procédures et des fonctions dans 1C afin que le code reste lisible, prévisible et facile à maintenir, même après des années.
Procédure vs fonction : quelle est la différence fondamentale
À première vue, tout est simple : la fonction renvoie une valeur, la procédure ne le fait pas. Mais derrière cette simplicité se cache un principe de conception important.
Fonction — c'est une question. Vous demandez quelque chose au système et obtenez une réponse. Elle ne doit pas modifier l'état de la base de données, ne doit pas afficher de messages à l'utilisateur. Elle calcule simplement et renvoie le résultat.
Функция РассчитатьСуммуСоСкидкой(Сумма, ПроцентСкидки)
Возврат Сумма - Сумма * ПроцентСкидки / 100;
КонецФункцииProcédure — c'est une commande. Vous demandez au système de faire quelque chose : enregistrer un document, envoyer une lettre, remplir une partie tabulaire. Elle effectue une action et ne renvoie pas de résultat.
Процедура ЗаполнитьЦеныВТабличнойЧасти(ТабличнаяЧасть, ТипЦен)
Для Каждого Строка Из ТабличнаяЧасть Цикл
Строка.Цена = ПолучитьЦенуНоменклатуры(Строка.Номенклатура, ТипЦен);
Строка.Сумма = Строка.Количество * Строка.Цена;
КонецЦикла;
КонецПроцедурыSi vous vous surprenez à écrire des données et à renvoyer un résultat, c'est un signal qu'il vaut la peine de diviser la logique en deux parties.
Nommer : votre code est lu par des personnes, pas par un compilateur
Le nom d'une procédure ou d'une fonction est un contrat avec la personne qui lira le code après vous. Un bon nom rend le commentaire inutile.
Mauvais noms - ce sont des noms qui ne disent rien sur la destination :
// Que traite-t-il ? Quelles données ? Pourquoi ?
Процедура ОбработатьДанные()
// Que vérifie-t-il exactement ? Quel document ?
Функция Проверка(Док)
// « Exécuter » est le mot le plus inutile dans le titreроцедура ВыполнитьОперацию()Bons noms contiennent un verbe et décrivent une action spécifique :
Процедура РассчитатьСебестоимостьПоПартиям(ДокументОбъект)
Функция ПолучитьОстатокНоменклатурыНаСкладе(Номенклатура, Склад, Дата)
Функция ЕстьПравоНаСкидку(Контрагент, СуммаЗаказа)Quelques règles qui fonctionnent vraiment :
Les fonctions-questions commencent par les mots « Obtenir », « Calculer », « Trouver », « Il y a » (pour les valeurs booléennes).
Les procédures de commande commencent par les mots « Remplir », « Enregistrer », « Envoyer », « Supprimer », « Définir ».
N'ayez pas peur des noms longs. « Recevoir le montant du paiement pour la période de la contrepartie » est plus clair que « Recevoir le montant ».
Paramètres : moins, c'est mieux
Si votre procédure a plus de cinq paramètres, quelque chose ne va pas. Ce n'est pas seulement une question d'esthétique : un grand nombre de paramètres signifie que la procédure en fait trop ou que les données sont mal structurées.
Problème :
Процедура СоздатьЗаказ(Контрагент, Склад, Менеджер, ДатаОтгрузки,
ТипЦен, ВалютаДокумента, Организация, Комментарий, Приоритет)
// ... 40 lignes de création de document
КонецПроцедурыSolution - structure :
Функция НовыеПараметрыЗаказа()
Параметры = Новый Структура;
Параметры.Вставить("Counterparty");
Параметры.Вставить("Warehouse");
Параметры.Вставить("Manager");
Параметры.Вставить("Date of shipment", ТекущаяДата());
Параметры.Вставить("PriceType");
Параметры.Вставить("Currency");
Параметры.Вставить("Organization");
Параметры.Вставить("Comment", "");
Параметры.Вставить("Priority", 0);
Возврат Параметры;
КонецФункции
Процедура СоздатьЗаказ(ПараметрыЗаказа)
// Propre, clair, extensible
КонецПроцедурыLe modèle « fonction-constructeur de paramètres » est l'une des techniques les plus utiles de 1C. Il vous permet d'ajouter de nouveaux paramètres sans casser les appels existants.
Principe de responsabilité unique
C'est peut-être le principe le plus important qui est violé dans le code 1C le plus souvent. Une procédure doit faire une chose.
Antipattern — « procédure-combine » :
Процедура ОбработатьДокумент(ДокументОбъект)
// Vérification du remplissage — 50 lignes
// Calcul des montants — 30 lignes
// Formation des mouvements - 100 lignes
// Envoi d'une notification — 20 lignes
// Mise à jour du statut de la contrepartie — 25 lignes
// Journalisation — 15 lignes
КонецПроцедурыCette procédure ne peut pas être testée, elle est difficile à déboguer, et quand quelque chose se casse - et elle se casse - vous relirez les 240 lignes.
La bonne approche :
Процедура ОбработатьДокумент(ДокументОбъект)
ОшибкиЗаполнения = ПроверитьЗаполнениеДокумента(ДокументОбъект);
Если ОшибкиЗаполнения.Количество() > 0 Тогда
ВывестиОшибкиЗаполнения(ОшибкиЗаполнения);
Возврат;
КонецЕсли;
РассчитатьСуммыДокумента(ДокументОбъект);
СформироватьДвижения(ДокументОбъект);
ОтправитьУведомление(ДокументОбъект);
ОбновитьСтатусКонтрагента(ДокументОбъект.Контрагент);
КонецПроцедурыMaintenant, chaque opération est isolée. Si vous avez besoin de changer la logique de calcul des montants, vous savez exactement où chercher. Si l'envoi de notifications est interrompu, il n'est pas nécessaire de relire le code de calcul.
Traitement des erreurs : ne cachez pas les problèmes
L'une des erreurs les plus courantes est l'acceptation silencieuse des exceptions.
Ce qu'il ne faut pas faire :
Процедура ОтправитьДанныеВоВнешнююСистему(Данные)
Попытка
// ...envoi
Исключение
// Vide. Eh bien, ça n'a pas été envoyé et c'est bon.
КонецПопытки;
КонецПроцедурыTrois mois plus tard, le comptable vient et dit : « Les données ne sont pas parties depuis l'été dernier. » Et dans les journaux, il n'y a que du silence.
Comment bien faire :
Процедура ОтправитьДанныеВоВнешнююСистему(Данные)
Попытка
// ...envoi
Исключение
ТекстОшибки = ОписаниеОшибки();
ЗаписьЖурналаРегистрации("IntegrationExternalSystem",
УровеньЖурналаРегистрации.Ошибка, , , ТекстОшибки);
ВызватьИсключение "Failed to send data: " + ТекстОшибки;
КонецПопытки;
КонецПроцедурыRègle d'or : ne corrigez que les erreurs que vous savez gérer. Le reste, enregistrez-le et lancez-le plus haut.
Exportation : ne rendez pas tout public
Dans 1C, il est tentant de mettre « Export » sur chaque fonction, au cas où cela serait utile. Cela conduit au fait que le module se transforme en une décharge, où il est impossible de comprendre ce qui est une API publique et ce qui est une cuisine interne.
La règle est simple : une procédure ou une fonction ne reçoit le modificateur « Export » que lorsqu'elle est réellement nécessaire pour d'autres modules. Tout le reste est une implémentation privée que vous êtes libre de changer comme vous le souhaitez.
// Il s'agit d'une API publique du module — bien documentée, contrat stable
Функция РассчитатьСтоимостьДоставки(Параметры) Экспорт
// ...
КонецФункции
// Ceci est un détail interne de la mise en œuvre - sans exportation
Функция ПолучитьТарифнуюЗону(АдресДоставки)
// ...
КонецФункцииValeurs retournées : soyez prévisible
La fonction doit toujours renvoyer une valeur d'un seul type. Si une fonction peut renvoyer une chaîne, un nombre ou un indéfini selon la situation, chaque code appelant devient un détective.
Mauvais :
Функция НайтиКонтрагента(ИНН)
Запрос = Новый Запрос("...");
Результат = Запрос.Выполнить();
Если Результат.Пустой() Тогда
Возврат Ложь; // Parfois booléen
КонецЕсли;
Возврат Результат.Выгрузить()[0].Контрагент; // Parfois, un lien
КонецФункцииBien :
// Renvoie TOUJOURS un lien. Lien vide = introuvable.
Функция НайтиКонтрагентаПоИНН(ИНН)
Запрос = Новый Запрос("...");
Результат = Запрос.Выполнить();
Если Результат.Пустой() Тогда
Возврат Справочники.Контрагенты.ПустаяСсылка();
КонецЕсли;
Возврат Результат.Выгрузить()[0].Контрагент;
КонецФункцииCommentaires : expliquez « pourquoi » et non « quoi »
Un bon code n'a presque pas besoin de commentaires — il s'explique par des noms compréhensibles. Mais parfois, les commentaires sont nécessaires : lorsqu'il faut expliquer une règle commerciale non évidente ou la raison d'une décision non standard.
Commentaire inutile :
// Nous obtenons la date
Дата = ТекущаяДата();Commentaire utile :
// Nous utilisons la date de début du mois suivant, car les tarifs
// sont mis à jour le premier jour du mois et la facturation doit être calculée en fonction des nouveaux prix
ДатаРасчёта = НачалоМесяца(ДобавитьМесяц(ТекущаяДата(), 1));Pour les fonctions d'exportation, assurez-vous d'ajouter une description des paramètres et de la valeur renvoyée. Ce n'est pas une formalité, c'est la documentation de votre API :
// Calcule les frais de livraison en fonction de la zone et du poids.
// // Paramètres :
// Adresse de livraison - Ligne - adresse complète au format FIAS
// PoidsGramme - Nombre - poids de l'envoi en grammes
// // Valeur de retour :
// Nombre - frais de livraison en roubles, 0 si la livraison est gratuite
// Fonction Calculer le coût de livraison (Adresse de livraison, Poids en grammes) ExportSi vous souhaitez approfondir vos connaissances en programmation et découvrir les technologies modernes, consultez l'application Code. Il s'agit d'une plateforme éducative proposant des cours de Python, JavaScript, HTML, CSS et d'autres langages, où les choses complexes sont expliquées dans un langage simple et la théorie est immédiatement soutenue par la pratique.
Et dans notre Chaîne Telegram une communauté amicale de plus de 2 000 développeurs vous attend, où vous pouvez toujours poser une question, obtenir de l'aide et trouver des personnes partageant les mêmes idées. Rejoignez-nous — grandir ensemble dans la profession est beaucoup plus facile !
