Как при копировании документа в 1С сохранить дату исходного документа?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При работе в программах семейства «1С:Предприятие 8» пользователи часто используют копирование существующих документов (клавиша F9) в качестве удобного шаблона для быстрого ввода новых данных. Однако стандартное поведение платформы при копировании автоматически заменяет дату исходного документа на текущую компьютерную или рабочую дату. Это сделано для того, чтобы новые документы по умолчанию создавались текущим днем.

Тем не менее в практике бухгалтерского и управленческого учета нередко возникает задача: сделать так, чтобы при копировании любого документа (или определенной группы документов) полностью сохранялась дата исходного документа-источника. В этой статье мы подробно разберем, как решить эту задачу наиболее корректным и безопасным с точки зрения архитектуры 1С способом, а также проанализируем неочевидные риски, о которых обязательно нужно предупредить бизнес-пользователей.

Почему не стоит менять код в модулях объектов напрямую?

Если мы заглянем в модуль объекта практически любого типового документа, то в процедуре ПриКопировании() мы увидим принудительную установку даты. Обычно это выглядит следующим образом: Дата = ТекущаяДата() или заполнение рабочей датой системы.

Первая идея, которая может прийти в голову начинающему разработчику, — зайти в каждый документ конфигурации и переопределить это поведение непосредственно в коде модуля каждого конкретного объекта. Разберем, почему делать так категорически не рекомендуется:

  1. Снятие конфигурации с поддержки: Изменение модулей типовых документов приведет к тому, что конфигурацию станет гораздо сложнее обновлять. Каждое обновление будет требовать ручного объединения кода, что делает невозможным автоматическое пакетное обновление нескольких типовых баз.
  2. Трудоемкость процесса: В типовых решениях (например, в «1С:Бухгалтерии» или «1С:ERP») содержатся сотни видов документов. Вносить изменения в каждый из них вручную — неэффективная трата времени.
  3. Сложность сопровождения: Если в будущем требования изменятся (например, бухгалтер попросит вернуть стандартное поведение для определенных документов), вам придется снова вручную переписывать десятки модулей объектов.

Ниже мы рассмотрим правильный, изящный способ решения этой задачи, который полностью сохраняет конфигурацию на стандартной поддержке.

Решение проблемы: Подписка на событие «ПриКопировании»

В платформе «1С:Предприятие 8» реализован мощный механизм подписок на события. Он позволяет «перехватывать» стандартные события объектов (такие как запись, проведение, копирование, заполнение) и выполнять собственный программный код в общих модулях без изменения самих объектов метаданных.

Проанализируем по шагам, как реализовать подписку на событие для принудительного сохранения даты при копировании.

Шаг 1. Создание общего модуля для обработчика

Для начала нам понадобится общий серверный модуль, в котором будет располагаться процедура-обработчик нашей подписки. Если в вашей конфигурации уже есть подходящий неглобальный общий модуль (например, ОбщегоНазначенияСервер или аналогичный кастомный модуль для доработок), вы можете использовать его. Если нет — создадим новый.

  1. Откройте конфигуратор вашей базы данных.
  2. Перейдите в ветку Общие -> Общие модули.
  3. Добавьте новый общий модуль и назовите его, например, _РаботаСДокументамиСобытия.
  4. В свойствах модуля установите флаги Сервер и Вызов сервера (флаг Глобальный должен быть выключен).

Шаг 2. Написание программного кода обработчика

В созданном общем модуле напишем процедуру, которая будет перезаписывать дату нового документа датой исходного. Обратите внимание, что процедура обязательно должна иметь ключевое слово Экспорт.


Процедура ПриКопированииДокументаДляСохраненияДаты(Источник, ОбъектКопирования) Экспорт
    
    // Проверяем, что объект копирования существует и у него заполнена дата
    Если ЗначениеЗаполнено(ОбъектКопирования) И ЗначениеЗаполнено(ОбъектКопирования.Ссылка) Тогда
        
        // Перезаписываем дату нового документа датой из источника копирования
        Источник.Дата = ОбъектКопирования.Дата;
        
    КонецЕсли;

КонецПроцедуры

Разберем параметры этой процедуры:

Шаг 3. Настройка подписки на событие

Теперь свяжем нашу процедуру со стандартным событием копирования документов в системе.

  1. В окне метаданных конфигуратора перейдите в ветку Общие -> Подписки на события.
  2. Добавьте новую подписку на событие. Назовем ее _СохранитьДатуПриКопированииДокументов.
  3. Настройте свойства подписки следующим образом:
    • Источник: Нажмите на кнопку выбора и отметьте типы документов, для которых должно действовать это правило. Если требуется применить настройку абсолютно ко всем документам, разверните ветку ДокументСсылка и установите флаг на самом верхнем уровне ДокументОбъект (в этом случае автоматически выберутся все документы системы).
    • Событие: Выберите из выпадающего списка событие ПриКопировании.
    • Обработчик: Укажите созданную нами на предыдущем шаге процедуру _РаботаСДокументамиСобытия.ПриКопированииДокументаДляСохраненияДаты.
  4. Сохраните изменения в конфигурации и обновите базу данных (клавиша F5 или F7).

Важный нюанс: Порядок выполнения кода платформой 1С

У разработчиков часто возникает логичный вопрос: «В стандартных модулях документов уже прописана очистка даты или установка текущей рабочей даты в процедуре ПриКопировании(). Нужно ли удалять этот стандартный код, чтобы он не конфликтовал с нашей подпиской?»

Выясним причину, почему удалять или комментировать стандартный код не нужно. Платформа 1С строго регламентирует последовательность выполнения обработчиков событий:

  1. Сначала всегда вызывается внутренний обработчик, расположенный непосредственно в модуле объекта самого документа (где прописана стандартная установка текущей или рабочей даты).
  2. И только после успешного завершения работы встроенного обработчика платформа вызывает внешние обработчики из всех зарегистрированных подписок на события.

Таким образом, наша подписка на событие гарантированно отработает последней. Она просто перезапишет дату, которую установил типовой механизм, вернув исходное значение из документа-копии. Никаких конфликтов или зацикливаний при этом не происходит.

Серьезные риски для учета: О чем необходимо предупредить бухгалтера?

Несмотря на то, что технически задача решается очень быстро и просто, её внедрение в реальную рабочую базу несет в себе скрытые риски для ведения учета. Прежде чем отдавать эту доработку пользователям, обязательно обсудите с главным бухгалтером следующие моменты:

  1. Проблемы с автонумерацией документов: В 1С нумерация документов обычно ведется в пределах одного периода (например, года или месяца). Если пользователь скопирует документ, созданный в прошлом году, то новый документ автоматически получит дату прошлого года. При записи такого документа система попытается присвоить ему уникальный номер в рамках прошлого периода. Это может привести к сбоям автонумерации текущего года, дублированию номеров или ошибкам уникальности.
  2. Конфликт с датой запрета редактирования: Если в информационной базе настроена дата запрета изменения данных (например, закрыт прошлый квартал или прошлый год), пользователь столкнется с ошибкой при попытке сохранить новый документ. Так как дата скопированного документа попадает в закрытый период, система заблокирует проведение документа. Бухгалтеру придется вручную менять дату на текущую перед записью, что нивелирует пользу от автоматического сохранения старой даты.
  3. Случайное проведение задним числом: Очень часто пользователи копируют документы многомесячной давности просто как шаблоны, чтобы заново не заполнять объемные табличные части (например, спецификации номенклатуры в реализации или поступлении). Если дата скопированного документа останется старой, а пользователь забудет изменить ее вручную, документ запишется и проведется задним числом. Это неминуемо приведет к искажению остатков на складах на промежуточные даты, нарушению последовательности проведения документов и искажению себестоимости.

Альтернативное решение на уровне интерфейса формы

Если тотальное сохранение дат через подписку признано слишком рискованным, рассмотрим альтернативный вариант решения на уровне конкретных форм документов. Мы можем сохранять дату исходного документа только тогда, когда это действительно нужно пользователю, выводя диалоговое окно с вопросом.

Для реализации этой логики используется параметр формы нового документа ЗначениеКопирования, который содержит ссылку на исходный документ. На клиенте в модуле формы документа мы можем обработать этот сценарий:


&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
    
    // Проверяем, что документ открывается в режиме копирования
    Если Параметры.Свойство("ЗначениеКопирования") И ЗначениеЗаполнено(Параметры.ЗначениеКопирования) Тогда
        
        // Мы можем сохранить ссылку на исходный документ во временный реквизит формы
        // для последующего анализа или вывода вопроса пользователю при открытии
        ОбъектКопированияСсылка = Параметры.ЗначениеКопирования;
        
    КонецЕсли;
    
КонецПроцедуры

Этот способ более трудоемок, так как требует вмешательства в формы конкретных документов (или использования механизма расширений для управляемых форм), но он гораздо безопаснее для стабильности учета в базе данных.

← На главную