При разработке расширений или доработке конфигураций 1С часто возникает задача реализации механизма "Ввод на основании". Стандартный функционал платформы отлично справляется с созданием одного документа на основании другого. Однако, когда пользователь выделяет в списке несколько документов (например, несколько "Счетов покупателю") и пытается создать на их основании один сводный документ (например, "Спецификацию" или "Реализацию"), поведение системы может отличаться от ожидаемого.
В этой статье мы подробно разберем, почему в процедуру заполнения приходит только одна ссылка вместо массива, и реализуем правильный алгоритм группового ввода на основании, аналогичный тому, что используется в типовых конфигурациях, таких как "1С:Бухгалтерия 3.0".
Давайте сначала разберемся, как работает платформа "из коробки". Когда вы указываете в свойствах объекта, что он вводится на основании другого документа, платформа автоматически добавляет команду "Создать на основании" в командную панель формы списка документа-основания.
Если пользователь выделит в списке несколько строк (например, 3 счета) и нажмет эту кнопку, платформа выполнит следующие действия:
ОбработкаЗаполнения, передав туда одну конкретную ссылку из списка выделенных.Именно поэтому, когда вы пытаетесь отловить массив ссылок внутри процедуры ОбработкаЗаполнения, вы видите там только ДокументСсылка. Это стандартное поведение платформы: "Один документ основания — один создаваемый документ".
Наша цель — изменить это поведение. Мы хотим, чтобы при выделении нескольких документов открывалась одна форма нового документа, а табличная часть этого документа заполнялась данными из всех выбранных оснований.
Для этого нам потребуется отказаться от автоматической команды платформы и создать свою собственную команду, которая будет собирать выделенные ссылки и передавать их в создаваемый объект.
Поскольку стандартный механизм нам не подходит, создадим команду вручную. Если вы работаете в расширении, добавьте новую общую команду или команду формы списка документа-основания.
Алгоритм действий:
СоздатьСпецификациюНаОсновании).Ложь (обычно для создания на основании это не требуется).Массив (состоящий из ссылок на документ-основание), чтобы команда была доступна при множественном выделении.Теперь напишем код обработчика команды. Наша задача — получить массив выделенных ссылок и передать их в открываемую форму нового документа. Важный момент: передача данных осуществляется через параметры формы, а конкретнее — через параметр ЗначенияЗаполнения.
Рассмотрим код модуля команды:
&НаКлиенте
Процедура ОбработкаКоманды(ПараметрКоманды, ПараметрыВыполненияКоманды)
// 1. Получаем массив ссылок.
// Если команда параметризуемая, то ПараметрКоманды уже может содержать массив.
// Если нет, получаем выделенные строки через контекст формы.
МассивОснований = Новый Массив;
// Если ПараметрКоманды - это массив (множественный выбор)
Если ТипЗнч(ПараметрКоманды) = Тип("Массив") Тогда
МассивОснований = ПараметрКоманды;
// Если одиночный выбор (ссылка)
Иначе
МассивОснований.Добавить(ПараметрКоманды);
КонецЕсли;
// 2. Формируем структуру параметров для открытия формы.
// Ключ "ЗначенияЗаполнения" (FillingValues) - это стандартный ключ платформы.
// Данные, переданные в него, попадут в ОбработкаЗаполнения.
ПараметрыФормы = Новый Структура;
ПараметрыФормы.Вставить("ЗначенияЗаполнения", МассивОснований);
// 3. Открываем форму нового документа
ОткрытьФорму("Документ.ВашНовыйДокумент.ФормаОбъекта", ПараметрыФормы, ПараметрыВыполненияКоманды.Источник, ПараметрыВыполненияКоманды.Уникальность, ПараметрыВыполненияКоманды.Окно, ПараметрыВыполненияКоманды.НавигационнаяСсылка);
КонецПроцедуры
Обратите внимание на использование ключа ЗначенияЗаполнения. Это зарезервированное имя параметра расширения управляемой формы. Все, что вы положите в этот ключ структуры, платформа передаст первым параметром в процедуру ОбработкаЗаполнения модуля объекта.
Также можно передать структуру внутри структуры, если вам нужно передать дополнительные параметры:
СтруктураДанных = Новый Структура;
СтруктураДанных.Вставить("Основание", МассивОснований);
СтруктураДанных.Вставить("ДополнительныйПараметр", Истина);
ПараметрыФормы = Новый Структура("ЗначенияЗаполнения", СтруктураДанных);
Теперь перейдем в модуль объекта создаваемого документа (в нашем примере это "Спецификация"). Нам нужно адаптировать процедуру ОбработкаЗаполнения, чтобы она умела работать как с одиночной ссылкой (если документ создается программно или стандартно), так и с массивом/структурой, который мы передаем из нашей команды.
Разберем пример кода модуля объекта:
Процедура ОбработкаЗаполнения(ДанныеЗаполнения, ТекстЗаполнения, СтандартнаяОбработка)
// Проверяем тип пришедших данных
// ВАРИАНТ 1: Пришел массив ссылок (наша новая команда)
Если ТипЗнч(ДанныеЗаполнения) = Тип("Массив") Тогда
// Заполняем шапку по первому документу (например, Контрагент, Организация)
Если ДанныеЗаполнения.Количество() > 0 Тогда
ЗаполнитьПоСчету(ДанныеЗаполнения[0]);
КонецЕсли;
// Заполняем табличную часть данными из всех документов
Для Каждого ЭлементОснования Из ДанныеЗаполнения Цикл
ДобавитьСтрокиИзСчета(ЭлементОснования);
КонецЦикла;
// ВАРИАНТ 2: Пришла Структура (если мы упаковали массив в структуру)
ИначеЕсли ТипЗнч(ДанныеЗаполнения) = Тип("Структура") И ДанныеЗаполнения.Свойство("Основание") Тогда
МассивДок = ДанныеЗаполнения.Основание;
// ... логика обхода массива ...
// ВАРИАНТ 3: Стандартный ввод на основании (одиночная ссылка)
ИначеЕсли ТипЗнч(ДанныеЗаполнения) = Тип("ДокументСсылка.СчетПокупателю") Тогда
ЗаполнитьПоСчету(ДанныеЗаполнения);
ДобавитьСтрокиИзСчета(ДанныеЗаполнения);
КонецЕсли;
КонецПроцедуры
При реализации данного подхода стоит учитывать несколько моментов, особенно если вы работаете с типовыми конфигурациями вроде 1С:Бухгалтерия или УТ:
ТаблицаЗначений, сворачивать их методом Свернуть() по номенклатуре (суммируя количество и суммы) и только потом загружать в табличную часть нового документа.Для передачи структуры или массива выделенных документов при создании на основании необходимо:
ОткрытьФорму, передав данные в параметре ЗначенияЗаполнения.ОбработкаЗаполнения обработать входящий массив данных.Такой подход обеспечивает гибкость и позволяет реализовать удобные сценарии групповой обработки документов для пользователей.