Как настроить движения по подчиненному регистру сведений для заимствованного документа в расширении 1С?

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

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

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

Настройка движений через свойства заимствованного документа в расширении (предпочтительный способ)

С платформы 1С версии 8.3.12 появилась возможность напрямую указать в расширении, по каким регистрам будет делать движения заимствованный документ из основной конфигурации. Это наиболее простой и рекомендуемый способ, если ваш регистр не является оборотным регистром накопления с включенными агрегатами.

Давайте рассмотрим пошагово, как это сделать:

  1. Заимствование объектов: Прежде всего, убедитесь, что в ваше расширение заимствованы как сам документ, так и регистр сведений, по которому вы хотите формировать движения. Для этого в дереве объектов расширения (например, в конфигураторе) найдите нужный документ и регистр в разделе "Общие" или "Данные" и добавьте их в расширение.
  2. Открытие свойств заимствованного документа: В дереве объектов расширения найдите заимствованный документ. В отличие от основной конфигурации, где двойной клик открывает полную карточку объекта, в расширении нужно использовать контекстное меню (правая кнопка мыши) или панель свойств. Выберите пункт "Свойства".
  3. Настройка свойства "Движения": В открывшейся панели свойств документа найдите реквизит (свойство) с именем "Движения". Рядом с ним обычно располагается кнопка с тремя точками (...). Нажмите на неё.
  4. Выбор регистра: Откроется список доступных регистров. Среди них вы увидите ваш заимствованный регистр сведений. Установите галочку напротив имени этого регистра. Это действие явно указывает платформе, что данный документ в контексте расширения должен формировать движения по выбранному регистру.

После выполнения этих шагов платформа 1С будет "знать", что ваш заимствованный документ имеет право формировать движения по указанному регистру. Теперь вы можете использовать стандартный объект Движения в модуле проведения документа, чтобы программно добавлять записи.

Например, в замещенной или дополненной процедуре проведения документа вы можете использовать следующий код:


&Вместо("ОбработкаПроведения")
Процедура ОбработкаПроведения(Отказ, РежимПроведения)
    // ... ваш код до стандартного проведения ...

    // Выполнение стандартного проведения, если это необходимо
    // ПродолжитьВыполнениеПроцедуры("ОбработкаПроведения", Отказ, РежимПроведения);

    // Пример формирования движений по новому регистру
    Если Не Отказ Тогда
        Движения.ВторойРегистр.Записывать = Истина;
        // Очистка существующих записей для данного регистратора
        Движения.ВторойРегистр.Очистить(); 

        // Создание новой записи
        Запись = Движения.ВторойРегистр.Добавить();
        Запись.Период = Дата;
        Запись.Регистратор = Ссылка;
        // ... заполнение других полей записи ...
    КонецЕсли;

    // ... ваш код после стандартного проведения ...
КонецеПроцедуры

Или, если вы используете аннотацию &После для добавления своей логики после стандартного проведения:


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

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

Программное управление движениями через набор записей

В некоторых случаях, когда необходимо более тонкое управление записями регистра (например, при отмене проведения, или если регистр не подчинен регистратору, но нужно работать с его данными из модуля документа), можно использовать механизм набора записей регистра сведений. Автор темы также пытался применить этот подход, но столкнулся с ошибкой "не установлен отбор по регистратору". Давайте разберем правильный порядок действий.

  1. Получение набора записей: Сначала необходимо создать объект НаборЗаписей для нужного регистра. Выполним это с помощью метода РегистрыСведений.<ИмяРегистра>.СоздатьНаборЗаписей().
  2. Установка отбора по регистратору: Для подчиненного регистра сведений обязательно нужно установить отбор по полю Регистратор. Это позволяет работать только с записями, которые относятся к текущему документу. Используем НаборЗаписей.Отбор.Регистратор.Установить(Ссылка), где Ссылка — это ссылка на текущий документ.
  3. Чтение существующих записей (если нужно): Если вам необходимо изменить существующие записи или дополнить их, то после установки отбора следует прочитать текущие записи из базы данных методом НаборЗаписей.Прочитать().
  4. Добавление/изменение записей: Теперь можно добавлять новые записи с помощью НаборЗаписей.Добавить() или модифицировать уже прочитанные. Не забудьте указать Регистратор для каждой добавляемой записи.
  5. Запись набора: После всех изменений необходимо вызвать метод Записать() для объекта НаборЗаписей. По умолчанию, этот метод выполняет замещение, то есть все записи для установленного отбора по регистратору будут удалены, а затем будут записаны текущие записи из набора. Если необходимо добавить записи без удаления существующих (что редко применимо для подчиненного регистра), потребуется более сложная логика.

Пример корректного кода для работы с набором записей в модуле документа:


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

        Запись = НаборЗаписей.Добавить();
        Запись.Регистратор = Ссылка;
        Запись.Период = Дата; 
        // ... Заполните остальные поля записи ...
        
        НаборЗаписей.Записать();
    КонецЕсли;
КонецПроцедуры

Автор в первом сообщении получил ошибку "не установлен отбор по регистратору" потому что, вероятно, он пытался добавить запись до того, как установил отбор, или пытался вызвать Прочитать() без отбора, что для подчиненного регистра недопустимо без предварительного указания регистратора. Отбор по регистратору критически важен при работе с подчиненными регистрами сведений через НаборЗаписей.

Используя этот подход, мы обходим прямое использование объекта Движения и работаем с регистром как с независимым объектом, но с обязательным условием привязки к регистратору.

Особенности подчиненных регистров сведений

Для полного понимания обсуждаемой проблемы и её решения, давайте вспомним ключевые особенности подчиненных регистратору регистров сведений:

  1. Жесткая связь с регистратором: Записи подчиненного регистра сведений всегда привязаны к конкретному документу-регистратору. Без ссылки на документ создать запись невозможно.
  2. Автоматическое удаление: При отмене проведения документа-регистратора все записи подчиненного регистра, связанные с этим документом, автоматически удаляются платформой. При повторном проведении они создаются заново.
  3. Настройка регистраторов: В конфигурации (в основной, не в расширении) на вкладке "Регистраторы" в свойствах подчиненного регистра сведений явно указывается список видов документов, которые могут формировать движения по этому регистру. Наша задача в расширении — фактически "добавить" наш заимствованный документ в этот список с точки зрения платформы 1С. Именно это и достигается через настройку свойства "Движения" документа в расширении.
  4. Работа через объект Движения: В модулях проведения документов, которые являются регистраторами для подчиненного регистра, для работы с записями используется специальный объект Движения.<ИмяРегистра>. Этот объект автоматически управляет связью с регистратором и обеспечивает корректное удаление/запись при проведении/отмене проведения.

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

Важные нюансы и ограничения при работе с расширениями

При работе с расширениями, особенно в контексте взаимодействия с типовыми объектами конфигурации, следует учитывать ряд важных моментов:

  1. Версии платформы:
    • До версии 8.3.12 платформы 1С документ, добавленный в расширении, мог формировать движения только по регистрам, созданным в этом же расширении.
    • С версии 8.3.12 появилась возможность выполнять движения по любому заимствованному регистру, за исключением оборотного регистра накопления с включенными агрегатами.
    • Что касается регистров накопления, создание нового регистра накопления в расширении было невозможно до версии 8.3.13. Также модификация заимствованных регистров накопления в некоторых версиях (например, 8.3.13.1644) могла приводить к нестабильной работе. Всегда проверяйте актуальную информацию для вашей версии платформы.
  2. Добавление реквизитов в заимствованные объекты: Мы не рекомендуем добавлять новые реквизиты непосредственно в заимствованные объекты (документы, справочники) через расширение. Это может привести к сложностям при обновлении конфигурации или удалении расширения. Для хранения дополнительных данных лучше создавать новые регистры сведений или использовать механизмы хранения дополнительных свойств.
  3. Использование аннотаций: Для внедрения своего кода в типовые процедуры (например, ОбработкаПроведения) используйте аннотации &После, &До и &Вместо. Это позволяет точечно модифицировать логику без изменения исходного кода типовой конфигурации и облегчает поддержку.
  4. Обновления: Расширения призваны упростить обновления типовых конфигураций. Однако при слишком обширных или некорректных доработках в расширениях могут возникать сложности при обновлениях платформы или самой конфигурации. Всегда тщательно тестируйте функционал расширений после каждого обновления. При обслуживании большого количества баз операции резервного копирования, обновления и проверки выполняются в автоматическом режиме через программу для пакетного обновления и тестирования 1С.

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

Таким образом, мы видим, что задача движения по другому регистру в расширении вполне решаема, особенно с учетом развития платформы 1С. Предпочтительным методом является настройка свойства "Движения" заимствованного документа, но и программная работа с наборами записей также остается эффективным инструментом в арсенале разработчика. Используя эти подходы, вы сможете гибко адаптировать типовые конфигурации под свои нужды, сохраняя при этом возможность удобного обновления.

← На главную