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