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

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

Реализация ввода на основании в расширении конфигурации 1С — это задача, которая часто выходит за рамки простого добавления объекта в метаданные. Когда нам необходимо реализовать специфическую логику, например, заполнение 50% суммы от документа-основания, и при этом обеспечить корректную работу прав доступа в типовых конфигурациях на базе Библиотеки стандартных подсистем (БСП), мы сталкиваемся с рядом нюансов. В этой статье мы подробно разберем, как правильно реализовать этот функционал, сохранив документ незаписанным до момента принятия решения пользователем, и как решить критическую проблему "исчезающих" ролей в расширениях.

Механизм заполнения документа: использование ОбработкаЗаполнения

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

Проанализируем ситуацию: если мы добавим логику в форму документа, она не сработает при программном создании объекта. Правильнее всего будет расширить модуль объекта создаваемого документа. Для этого создадим расширение и добавим в него документ-приемник. В модуле объекта этого документа используем аннотацию &После для процедуры ОбработкаЗаполнения.

Разберем пример кода, реализующий заполнение половины суммы:


&После("ОбработкаЗаполнения")
Процедура Расш1_ОбработкаЗаполнения(ДанныеЗаполнения, ТекстЗаполнения, СтандартнаяОбработка)
    
    // Проверяем, что основанием является именно нужный нам документ
    Если ТипЗнч(ДанныеЗаполнения) = Тип("ДокументСсылка.ОтчетКомитенту") Тогда
        
        // Реализуем логику: берем 50% от суммы документа-основания
        ЭтотОбъект.СуммаДокумента = ДанныеЗаполнения.СуммаДокумента * 0.5;
        
        // Заполняем остальные реквизиты, например, контрагента (комитента)
        ЭтотОбъект.Контрагент = ДанныеЗаполнения.Комитент;
        ЭтотОбъект.Организация = ДанныеЗаполнения.Организация;
        ЭтотОбъект.ДокументОснование = ДанныеЗаполнения;
        
        // Документ остается в памяти, форма откроется с этими данными, но записи в БД не произойдет
    КонецЕсли;
    
КонецПроцедуры

Важно помнить: чтобы платформа автоматически вызвала это событие при интерактивном нажатии кнопки "Создать на основании", в метаданных расширения для документа-приемника в свойстве "Является основанием для" должен быть указан документ-источник. Однако в современных конфигурациях этого может быть недостаточно из-за динамического формирования меню БСП.

Интеграция с подсистемой БСП «Печать и ввод на основании»

В современных типовых решениях (БП 3.0, УТ 11, ERP) подменю "Создать на основании" формируется программно. Если мы просто добавим связь в метаданных, кнопка может не появиться в общем списке. Нам необходимо зарегистрировать нашу новую команду в механизмах БСП.

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

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

Проблема прав доступа и ролей в расширениях

Одной из самых коварных проблем при использовании расширений является поведение БСП по отношению к новым ролям. Часто разработчики замечают, что добавленные в расширении права "слетают" у пользователей или вовсе не применяются для администраторов системы. Посмотрим на причину: типовой код БСП при обновлении ролей пользователей может игнорировать роли из расширений, считая их "некорректными" или лишними для профиля администратора.

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

Проанализируем пример "заплатки", которая позволяет сохранить роли расширения для администраторов:


&ИзменениеИКонтроль("ОбновитьРолиПользователей")
Процедура Расш1_ОбновитьРолиПользователей(Знач ОписаниеПользователей, Знач ПарольПользователяСервиса, ЕстьИзменения)
    
    // ... существующий код БСП ...

    #Вставка
    // Гарантируем, что специфические роли из расширения не будут удалены у администраторов
    Если Администраторы[ТекущийПользователь] <> Неопределено Тогда
        Для Каждого КлючИЗначение Из ОбязательныеРолиАдминистратора Цикл
            Если НовыеРоли.Найти(КлючИЗначение.Значение, "РольСсылка") <> Неопределено Тогда
                Продолжить;
            КонецЕсли;
            НовыеРоли.Добавить().РольСсылка = КлючИЗначение.Значение;
        КонецЦикла;
    КонецЕсли;
    #КонецВставки
    
    // ... продолжение кода ...
КонецПроцедуры

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

Рекомендации по обновлению идентификаторов

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

Справочники.ИдентификаторыОбъектовМетаданных.ОбновитьДанныеСправочника()

Или запустить внешнюю обработку "Обновление вспомогательных данных", которая входит в состав инструментов разработчика БСП.

Подведем итог: для успешного создания документа на основании в расширении мы используем ОбработкаЗаполнения в модуле объекта для вычисления 50% суммы, регистрируем команду в механизмах БСП через переопределяемые модули и внимательно следим за тем, чтобы подсистема управления доступом не блокировала наши новые роли, при необходимости применяя исправления в служебных модулях БСП.

← На главную