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