Как сделать, чтобы реквизит в 1С заполнялся сам: пять механизмов платформы
Содержание
Чтобы задать значение по умолчанию в 1С 8.3, откройте реквизит в Конфигураторе, в палитре свойств найдите Значение заполнения и укажите нужное значение. Если оно должно вычисляться (текущий пользователь, склад из настроек, дата), пишите код в обработчике ОбработкаЗаполнения модуля объекта.
Частая ошибка: путать значение по умолчанию со свойством поля формы Подсказка ввода. Подсказка лишь рисует серый текст в пустом поле, в реквизит ничего не записывается, и документ уходит в базу с пустым значением. Вторая ошибка: ждать, что Значение заполнения сработает при создании документа из кода через СоздатьДокумент(). Без вызова Заполнить() не сработает.
Какой механизм выбрать под задачу
Платформа даёт несколько уровней, где можно подставить значение. Они срабатывают в разное время и решают разные задачи.
| Механизм | Где настраивается | Когда срабатывает | Подходит для |
|---|---|---|---|
Свойство Значение заполнения | Палитра свойств реквизита | При заполнении нового объекта | Фиксированных значений: Истина, элемент перечисления, предопределённый элемент |
ОбработкаЗаполнения | Модуль объекта | Новый объект, ввод на основании, вызов Заполнить() | Вычисляемых значений и логики «если пусто» |
ЗначенияЗаполнения и отбор | Параметры открытия формы | Открытие формы нового объекта | Подстановки из контекста: из списка с отбором, из другой формы |
| События таблицы формы | Модуль формы | Добавление строки | Значений в новой строке табличной части |
| Константы и хранилище настроек | Метаданные, модуль менеджера настроек | Читаются из кода заполнения | Значений, которые меняет пользователь или администратор без доработки |
Правило простое: фиксированное значение задавайте свойством, вычисляемое кодом, а «настраиваемое пользователем» храните в константе или настройках и читайте в ОбработкаЗаполнения.
В типовой конфигурации на поддержке не меняйте объекты напрямую. Свойства и обработчики добавляйте через расширение конфигурации, иначе следующее обновление превратится в ручное сравнение и объединение.
Значение заполнения в свойствах реквизита
Это самый быстрый способ без программирования.
- Откройте Конфигуратор, в дереве метаданных раскройте нужный справочник или документ.
- Дважды щёлкните реквизит, откроется палитра свойств.
- Найдите свойство
Значение заполненияи выберите значение из списка или введите его. - Сохраните конфигурацию и выполните
Конфигурация → Обновить конфигурацию базы данных(F7).
Что можно указать в этом свойстве:
- ✅ для булева реквизита —
Истина(по умолчанию флажок и такЛожь); - ✅ для перечисления — конкретное значение, например
СтавкаНДС20; - ✅ для ссылки на справочник — предопределённый элемент;
- ✅ для числа и строки — константу вида
1или"шт"; - ❌ «текущую дату», «текущего пользователя», «основную организацию» — это вычисление, оно делается кодом.
Ограничение для ссылок: выбрать можно только предопределённый элемент, а не любой элемент из базы. Обычный элемент справочника существует только в конкретной базе, и в другой копии конфигурации его не будет. Поэтому, если по умолчанию нужен склад «Основной», есть два пути. Либо сделать его предопределённым элементом справочника, либо хранить ссылку в константе и подставлять кодом, как описано ниже. Второй вариант гибче: администратор поменяет склад без обновления конфигурации.
Рядом в палитре есть флажок Заполнять из данных заполнения. Если он включён, платформа сама перенесёт в реквизит значение с тем же именем из структуры данных заполнения. Например, из отбора списка или из параметра ЗначенияЗаполнения при открытии формы. Для реквизитов вроде Организация и Контрагент его стоит включать почти всегда.
Не путайте с Проверка заполнения. Это свойство не подставляет значение, а запрещает записать объект с пустым реквизитом. Хорошая пара: значение заполнения подставляет вариант по умолчанию, проверка заполнения не даёт его стереть.
Программное заполнение при создании объекта
Когда значение нужно вычислить, используйте событие ОбработкаЗаполнения в модуле объекта. Оно вызывается при интерактивном создании, при вводе на основании и при явном вызове метода Заполнить().
Обработчик в модуле объекта
Процедура ОбработкаЗаполнения(ДанныеЗаполнения, ТекстЗаполнения, СтандартнаяОбработка)
// Заполняем только пустое: отбор или основание имеют приоритет
Если Не ЗначениеЗаполнено(Ответственный) Тогда
Ответственный = Пользователи.ТекущийПользователь();
КонецЕсли;
Если Не ЗначениеЗаполнено(Склад) Тогда
Склад = Константы.ОсновнойСклад.Получить();
КонецЕсли;
Если Не ЗначениеЗаполнено(ДатаОплаты) Тогда
ДатаОплаты = НачалоДня(ТекущаяДатаСеанса()) + 5 * 86400;
КонецЕсли;
КонецПроцедуры
Здесь Пользователи.ТекущийПользователь() — функция Библиотеки стандартных подсистем. В конфигурации без БСП ищите текущего пользователя своим способом, например через параметр сеанса.
Проверка Не ЗначениеЗаполнено нужна обязательно. Стандартная обработка уже могла заполнить реквизит из отбора или основания, и без проверки ваш код молча затрёт выбор пользователя.
Ввод на основании
Тот же обработчик получает документ-основание в параметре ДанныеЗаполнения. Тип проверяйте явно, потому что туда же приходит структура из отбора или Неопределено:
Если ТипЗнч(ДанныеЗаполнения) = Тип("ДокументСсылка.ЗаказПокупателя") Тогда
Контрагент = ДанныеЗаполнения.Контрагент;
Склад = ДанныеЗаполнения.Склад;
ИначеЕсли ТипЗнч(ДанныеЗаполнения) = Тип("Структура") Тогда
// значения из отбора и параметров формы платформа уже перенесла
КонецЕсли;
Ветку по основанию ставьте первой, а значения «по умолчанию» после неё, с проверкой на пустоту. Тогда основание всегда важнее общих правил.
Создание объекта из кода
Метод СоздатьДокумент() или СоздатьЭлемент() возвращает пустой объект. Ни Значение заполнения, ни ОбработкаЗаполнения сами не сработают. Вызовите заполнение явно:
НовыйДокумент = Документы.ЗаказПокупателя.СоздатьДокумент();
НовыйДокумент.Заполнить(Неопределено); // сработают свойства и ОбработкаЗаполнения
НовыйДокумент.Дата = ТекущаяДатаСеанса();
НовыйДокумент.Контрагент = Контрагент;
НовыйДокумент.Записать();
Можно передать в Заполнить() структуру, тогда реквизиты с флажком Заполнять из данных заполнения возьмут значения из неё:
ДанныеЗаполнения = Новый Структура("Организация, Склад", Организация, Склад);
НовыйДокумент.Заполнить(ДанныеЗаполнения);
Копирование
При копировании объекта ОбработкаЗаполнения не вызывается, значения переносятся из оригинала. Если что-то нужно сбросить или пересчитать, используйте ПриКопировании:
Процедура ПриКопировании(ОбъектКопирования)
Ответственный = Пользователи.ТекущийПользователь();
НомерВходящего = "";
КонецПроцедуры
Через расширение в типовой конфигурации
В расширении добавьте объект в расширение, откройте модуль объекта и создайте обработчик с аннотацией &После. Исходный код типовой не трогается:
&После("ОбработкаЗаполнения")
Процедура Расш_ОбработкаЗаполнения(ДанныеЗаполнения, ТекстЗаполнения, СтандартнаяОбработка)
Если Не ЗначениеЗаполнено(Склад) Тогда
Склад = Константы.ОсновнойСклад.Получить();
КонецЕсли;
КонецПроцедуры
Значения по умолчанию через форму и команды
Иногда значение зависит не от объекта, а от того, откуда пользователь его создаёт.
Параметр ЗначенияЗаполнения
При открытии формы нового объекта передайте структуру ЗначенияЗаполнения. Платформа отдаст её в ОбработкаЗаполнения как ДанныеЗаполнения и заполнит реквизиты с флажком Заполнять из данных заполнения:
&НаКлиенте
Процедура СоздатьЗаказ(Команда)
ЗначенияЗаполнения = Новый Структура("Контрагент, Договор", Объект.Ссылка, Объект.ОсновнойДоговор);
ПараметрыФормы = Новый Структура("ЗначенияЗаполнения", ЗначенияЗаполнения);
ОткрытьФорму("Документ.ЗаказПокупателя.ФормаОбъекта", ПараметрыФормы);
КонецПроцедуры
Так работает, например, команда «создать заказ» из карточки контрагента: заказ сразу открывается с подставленным клиентом.
Отбор в списке
Если в динамическом списке установлен отбор по полю на равенство, новый элемент, созданный из этого списка, получит это значение. Отбор попадает в данные заполнения автоматически. Это удобно для подчинённых справочников: договоры, открытые из карточки контрагента, сразу привязываются к нему.
Значения только для формы
ПриСозданииНаСервере подходит для настроек самой формы: какую страницу открыть, какие поля скрыть, значения реквизитов формы, а не объекта. Новый объект проверяйте так:
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
Если Объект.Ссылка.Пустая() Тогда
Элементы.ГруппаДополнительно.Видимость = Ложь;
КонецЕсли;
КонецПроцедуры
Не переносите сюда заполнение реквизитов объекта. Код в форме не сработает при создании объекта из обработки, обмена или HTTP-сервиса, и правило «по умолчанию» будет выполняться через раз.
Для обработок и отчётов есть ещё один приём: у реквизита формы включите флажок Сохраняемые данные. Платформа запомнит последнее введённое значение и подставит его при следующем открытии.
Новая строка табличной части
Строки табличной части заполняются по-другому: сам объект уже создан, а строки добавляет пользователь. Подходящее место — событие таблицы формы ПриНачалеРедактирования.
&НаКлиенте
Процедура ТоварыПриНачалеРедактирования(Элемент, НоваяСтрока, Копирование)
Если НоваяСтрока И Не Копирование Тогда
ТекущиеДанные = Элемент.ТекущиеДанные;
ТекущиеДанные.Количество = 1;
ТекущиеДанные.СтавкаНДС = Объект.СтавкаНДСПоУмолчанию;
КонецЕсли;
КонецПроцедуры
Проверка Не Копирование оставляет скопированной строке её значения. Без неё копия строки получит Количество = 1 вместо исходного.
Если строки добавляются кодом на сервере, заполняйте их сразу после Добавить():
НоваяСтрока = Объект.Товары.Добавить();
НоваяСтрока.Номенклатура = Номенклатура;
НоваяСтрока.Количество = 1;
Значение, которое зависит от шапки (склад, ставка НДС), лучше брать из реквизита документа, а не из константы. Тогда пользователь меняет его один раз в шапке, а не в каждой строке.
Константы и пользовательские настройки как источник значений
Жёстко прописанное в коде значение придётся менять доработкой. Если основной склад или ставку меняют сами пользователи, вынесите значение в данные.
Константа: одно значение на всю базу
- В Конфигураторе создайте константу, например
ОсновнойСкладс типомСправочникСсылка.Склады. - Добавьте её на форму настроек или в подсистему, чтобы администратор мог её изменить.
- Читайте её в
ОбработкаЗаполнения:Константы.ОсновнойСклад.Получить().
У ролей пользователей должно быть право на чтение константы. Иначе создание документа упадёт с ошибкой нарушения прав.
Настройка пользователя: у каждого своё
Если у каждого менеджера свой склад, константа не подходит. Используйте хранилище общих настроек:
// Сохранить выбор пользователя
ХранилищеОбщихНастроек.Сохранить("ЗначенияПоУмолчанию", "Склад", Склад);
// Прочитать при заполнении
СкладПользователя = ХранилищеОбщихНастроек.Загрузить("ЗначенияПоУмолчанию", "Склад");
Если ЗначениеЗаполнено(СкладПользователя) Тогда
Склад = СкладПользователя;
КонецЕсли;
В типовых конфигурациях этот механизм уже готов: основную организацию, склад и подразделение пользователь задаёт в персональных настройках или в карточке пользователя, а документы подтягивают их сами. Найдите эти настройки через поиск по меню по слову «настройки» и задайте нужное значение там, прежде чем дорабатывать код.
Рабочий порядок выбора источника в ОбработкаЗаполнения:
- Значение из данных заполнения (отбор, основание, параметр формы).
- Настройка текущего пользователя.
- Константа на всю базу.
- Ничего: поле остаётся пустым, его отловит
Проверка заполнения.
Почему значение не подставляется
Как проверить, что правило работает везде
Значение по умолчанию легко настроить для одного сценария и забыть про остальные. После доработки пройдите все пути создания объекта в тестовой копии базы:
Если в каком-то сценарии поле осталось пустым или получило чужое значение, причину почти всегда видно по таблице механизмов в начале: значит, правило записано не в том месте.
Отдельная ловушка — параметр СтандартнаяОбработка. Если в ОбработкаЗаполнения присвоить ему Ложь, платформа не применит ни Значение заполнения, ни перенос из данных заполнения. Ставьте Ложь, только если сознательно заполняете всё сами.