В процессе разработки конфигураций на платформе 1С часто возникает задача упростить ввод данных для пользователя. Одной из таких задач является автоматическое формирование строки Наименование на основе других реквизитов объекта, например, номера и даты договора. Это не только ускоряет работу, но и позволяет поддерживать единообразие в базе данных. Рассмотрим подробно, как это реализовать, какие существуют подходы и как избежать типичных ошибок, с которыми сталкиваются начинающие разработчики.
Представим ситуацию: у нас есть справочник Договоры, в котором добавлены реквизиты НомерДоговора (тип Строка) и ДатаДоговора (тип Дата). Нам необходимо, чтобы при заполнении этих полей система автоматически собирала строку вида: "№ 005 от 25.03.2020" и подставляла её в стандартный реквизит Наименование. Основная сложность здесь заключается не только в склеивании строк, но и в правильном выборе момента (события), когда этот код должен сработать, чтобы пользователь не получал ошибку о незаполненном поле при записи.
Если мы хотим, чтобы пользователь видел результат формирования наименования сразу же после того, как ввел номер или дату, нам необходимо использовать обработчики событий элементов формы. Это обеспечит высокую интерактивность интерфейса. Разберем по шагам, как это сделать в управляемом приложении.
Для начала создадим общую процедуру на форме, которая будет отвечать за формирование строки. Это позволит нам не дублировать код для номера и для даты. Проанализируем пример кода:
&НаСервере
Процедура СформироватьНаименованиеНаСервере()
ТекстНомера = Объект.НомерДоговора;
ТекстДаты = Формат(Объект.ДатаДоговора, "ДЛФ=Д");
Объект.Наименование = "Договор № " + ТекстНомера + " от " + ТекстДаты;
КонецПроцедуры
&НаКлиенте
Процедура НомерДоговораПриИзменении(Элемент)
СформироватьНаименованиеНаСервере();
КонецПроцедуры
&НаКлиенте
Процедура ДатаДоговораПриИзменении(Элемент)
СформироватьНаименованиеНаСервере();
КонецПроцедуры
В данном примере мы используем метод Формат с параметром "ДЛФ=Д". Это крайне важный момент, так как без форматирования дата в 1С превратится в длинную строку с указанием времени (00:00:00), что выглядит неэстетично в наименовании договора. Мы вызываем серверную процедуру, так как работа с объектом на форме в сложных конфигурациях может потребовать серверного контекста, хотя в простых случаях можно обойтись и клиентским кодом, обращаясь напрямую к Объект.Наименование.
Метод с формой хорош для пользователя, но он имеет существенный недостаток: если договор будет создаваться программно (например, при загрузке из другой программы или через внешнюю обработку), форма не откроется, события элементов формы не сработают, и поле Наименование останется пустым. Чтобы гарантировать заполнение данных в любых условиях, проанализируем использование модуля объекта.
Нам необходимо открыть модуль объекта справочника и найти (или создать) предопределенную процедуру ПередЗаписью. Выясним причину, почему это место является наиболее подходящим: этот код срабатывает непосредственно перед тем, как данные будут записаны в таблицу базы данных.
Процедура ПередЗаписью(Отказ)
// Проверяем, установлена ли автоматическая генерация или поле пустое
Если ЗначениеЗаполнено(НомерДоговора) И ЗначениеЗаполнено(ДатаДоговора) Тогда
Наименование = СтрШаблон("№ %1 от %2", НомерДоговора, Формат(ДатаДоговора, "ДЛФ=Д"));
КонецЕсли;
КонецПроцедуры
В этом примере мы применили современную функцию СтрШаблон. Она делает код гораздо более читаемым по сравнению с классической конкатенацией (склеиванием через "+"). Вместо символов %1 и %2 подставляются значения соответствующих параметров.
Многие начинающие разработчики сталкиваются с тем, что даже при наличии кода 1С выдает ошибку: "Поле 'Наименование' не заполнено". Это происходит потому, что в свойствах реквизита в конфигураторе установлено значение "Проверка заполнения: Выдавать ошибку". Система выполняет проверку раньше, чем срабатывает ваш код в некоторых событиях, или если ваш код не успел отработать до команды записи.
Для решения этой проблемы мы можем пойти двумя путями:
Наименование установите свойство Проверка заполнения в значение Не проверять. Теперь ответственность за наличие текста в этом поле ложится на ваш программный код.ОбработкаПроверкиЗаполнения, чтобы программно добавить Наименование в список проверяемых или заполнить его прямо там.Если вы работаете в современной конфигурации (например, БП 3.0 или УТ 11), в ней наверняка подключена Библиотека стандартных подсистем (БСП). В этом случае мы можем использовать готовые функции для формирования красивых заголовков. Это обеспечит единообразие с типовым функционалом 1С.
Пример использования функций общего назначения:
// Пример формирования заголовка через типовые механизмы
Наименование = ОбщегоНазначенияКлиентСервер.СформироватьЗаголовокДокумента("Договор №", НомерДоговора, ДатаДоговора);
Такой подход позволяет избежать ручного форматирования даты и проверки на пустые значения, так как стандартные функции БСП обычно уже содержат все необходимые проверки "внутри".
Рассмотрим несколько важных моментов, которые помогут сделать ваше решение профессиональным:
Наименование часто имеет ограничение (например, 25 или 50 символов). Если номер договора очень длинный, программа может выдать ошибку при записи. Всегда проверяйте длину итоговой строки или используйте функцию Лев(), чтобы обрезать результат.ЗначениеЗаполнено(). Если пользователь еще не ввел дату, фраза "№ 5 от 01.01.0001" будет выглядеть некорректно. В таких случаях лучше выводить только заполненную часть или не заполнять наименование вовсе.Наименование уже заполнено и отличается от стандартного шаблона, не перезаписывайте его автоматически при каждом изменении даты.Таким образом, мы разобрали основные способы автоматизации. Выбор между модулем формы и модулем объекта зависит от ваших целей: для комфорта пользователя используйте форму, для надежности данных — модуль объекта, а лучше всего — разумное сочетание обоих методов.