При проектировании прикладных решений на платформе «1С:Предприятие 8» разработчики постоянно взаимодействуют со стандартными реквизитами объектов. Одним из наиболее значимых и часто используемых является реквизит Наименование. По умолчанию система считает его ключевым идентификатором элемента для отображения в пользовательском интерфейсе и жестко требует его заполнения при записи в базу данных.
Однако в реальной практике нередко возникают задачи, когда стандартное наименование избыточно или неудобно. Например, при создании справочника сотрудников или пользователей системы гораздо логичнее хранить отдельно фамилию, имя и отчество, не заставляя пользователя дублировать эти данные в отдельную строку. В данной статье мы подробно разберем, как правильно управлять обязательным заполнением наименования, рассмотрим различные варианты решения этой задачи и проанализируем типичные ошибки начинающих разработчиков.
Для начала выясним причину классической ошибки, описанной автором темы на форуме. Попытка написать простую строчку кода Наименование = Фамилия; непосредственно в общем теле модуля объекта приводит к критическому сбою и выводу сообщения «Ошибка инициализации модуля: Элемент не выбран!».
Разберем детально, почему платформа ведет себя именно так. Код, расположенный в модуле объекта вне каких-либо процедур и функций (в так называемом теле модуля), выполняется системой в момент инициализации программного объекта в оперативной памяти — например, при вызове метода СоздатьЭлемент(). В этот момент физическая запись в базе данных еще не создана, контекст объекта не определен до конца, а его реквизиты недоступны для непосредственной модификации. Попытка прямого присвоения значений свойствам на этом этапе является грубой синтаксической ошибкой контекста.
Если перед нами стоит задача автоматически формировать Наименование на основе других реквизитов (например, копировать туда значение из реквизита Фамилия), правильным подходом будет перенос программного кода в предопределенное событие модуля объекта — ПередЗаписью.
Этот обработчик вызывается системой непосредственно перед транзакцией записи данных в базу, когда все реквизиты на управляемой форме уже заполнены пользователем и доступны для чтения и записи в коде модуля объекта. Давайте посмотрим на пример правильной реализации:
Процедура ПередЗаписью(Отказ, Замещение)
// Проверяем, заполнено ли базовое поле, чтобы избежать записи пустой строки
Если ЗначениеЗаполнено(Фамилия) Тогда
Наименование = СокрЛП(Фамилия);
КонецЕсли;
КонецПроцедуры
Если структура нашего справочника более сложная и содержит отдельные поля для имени и отчества, мы можем прямо в этой процедуре реализовать красивое автоматическое формирование представления пользователя с инициалами. Рассмотрим следующий практический пример:
Процедура ПередЗаписью(Отказ, Замещение)
// Формируем строковое представление ФИО с инициалами
ИнициалыИмени = ?(ЗначениеЗаполнено(Имя), Лев(СокрЛП(Имя), 1) + ".", "");
ИнициалыОтчества = ?(ЗначениеЗаполнено(Отчество), Лев(СокрЛП(Отчество), 1) + ".", "");
ПолноеПредставление = СокрЛП(Фамилия) + " " + ИнициалыИмени + " " + ИнициалыОтчества;
// Записываем результат в стандартный реквизит
Наименование = СокрЛП(ПолноеПредставление);
КонецПроцедуры
Использование обработчика ПередЗаписью гарантирует, что в базе данных всегда будут корректные и актуальные текстовые наименования, по которым платформа сможет выполнять быстрый поиск, сортировку и построение стандартных отчетов.
Иногда нет необходимости писать программный код, если задача заключается лишь в том, чтобы сделать интерфейс программы понятным для конечного пользователя. По умолчанию поле на форме подписано как «Наименование», но мы можем изменить его название (синоним) на «Фамилия» или «ФИО» на уровне конфигурации.
Поскольку реквизит Наименование является стандартным, он не отображается в общем списке реквизитов справочника в дереве метаданных. Разберем по шагам, как получить доступ к его свойствам:
Пользователи).Наименование и откроем ее свойства (нажатием клавиши F4 или через контекстное меню).После сохранения конфигурации база данных продолжит оперировать системным именем Наименование в программном коде, но на всех автоматически генерируемых управляемых формах пользователи увидят красивую и понятную подпись поля.
Если бизнес-логика вашей конфигурации вообще не предполагает использование текстового наименования для элемента, мы можем полностью отключить его обязательность на уровне платформы. Самый быстрый способ сделать это — установить длину наименования равной нулю.
Для этого в окне редактирования справочника на вкладке «Данные» найдем числовое поле «Длина наименования» и установим его значение в 0. Платформа мгновенно скроет поле с форм и перестанет требовать его заполнение. Однако у этого радикального метода есть серьезные технологические последствия, о которых обязательно нужно знать:
Как решить: Обязательно перейдите на вкладку «Поле ввода» свойств справочника, найдите свойство «Ввод по строке» и удалите оттуда поле Наименование, оставив только Код или другие значимые текстовые реквизиты.
<...>.Для того чтобы избежать избыточного дублирования информации в базе данных и при этом не столкнуться с проблемой «пустых ссылок» в интерфейсе, разработчики используют самый современный и правильный механизм платформы «1С:Предприятие 8.3» — переопределение представления объекта в его модуле менеджера.
Этот подход позволяет физически не хранить текст в поле Наименование (или скрыть его с формы), но динамически формировать строковое представление элемента «на лету» из любых других реквизитов (например, полей Фамилия, Имя и Отчество).
Разберем по шагам, как настроить этот механизм:
ОбработкаПолученияПолейПредставления и ОбработкаПолученияПредставления.Напишем следующий эффективный программный код:
// Сообщаем платформе, какие именно реквизиты необходимы для построения текста ссылки
Процедура ОбработкаПолученияПолейПредставления(Поля, СтандартнаяОбработка)
СтандартнаяОбработка = Ложь;
Поля.Добавить("Фамилия");
Поля.Добавить("Имя");
Поля.Добавить("Отчество");
КонецПроцедуры
// Динамически собираем строковое представление элемента для вывода на экран
Процедура ОбработкаПолученияПредставления(Данные, Представление, СтандартнаяОбработка)
СтандартнаяОбработка = Ложь;
// Собираем фамилию и инициалы, аккуратно обрабатывая пустые значения
СтрокаФИО = СокрЛП(Данные.Фамилия);
Если ЗначениеЗаполнено(Данные.Имя) Тогда
СтрокаФИО = СтрокаФИО + " " + Лев(СокрЛП(Данные.Имя), 1) + ".";
КонецЕсли;
Если ЗначениеЗаполнено(Данные.Отчество) Тогда
СтрокаФИО = СтрокаФИО + " " + Лев(СокрЛП(Данные.Отчество), 1) + ".";
КонецЕсли;
// Если все поля пустые, выводим резервный текст
Представление = ?(ЗначениеЗаполнено(СтрокаФИО), СтрокаФИО, "Пользователь с незаполненным ФИО");
КонецПроцедуры
Преимущества этого решения очевидны. Во-первых, мы полностью избавляемся от дублирования данных в таблицах СУБД. Во-вторых, если пользователь решит изменить свою фамилию в карточке, новое представление автоматически и мгновенно отобразится во всей истории документов, отчетах и связанных справочниках без необходимости принудительного перезаписывания объектов базы данных.
Часто разработчикам приходится сталкиваться с необходимостью решения подобных задач не в пустых базах, создаваемых с нуля, а в типовых конфигурациях от фирмы 1С (таких как Бухгалтерия предприятия, Управление нашей фирмой или ERP), которые находятся на поддержке поставщика. Прямое изменение стандартных реквизитов в таких конфигурациях крайне нежелательно, поскольку это усложнит процедуру регулярного обновления системы.
В этой ситуации на помощь приходит механизм **Расширений конфигурации**. Выполним задачу безопасным способом:
ФизическиеЛица) в дереве основной конфигурации, кликнем по нему правой кнопкой мыши и выберем команду «Добавить в расширение».Наименование добавленного справочника.Не проверять.ПередЗаписью модуля объекта с использованием аннотации &Перед или &Вместо.Благодаря использованию расширения основная база данных останется полностью типовой и сохранит возможность автоматического обновления в один клик, а пользователи получат необходимый функционал без лишних трудозатрат.