Как программно добавить пользовательскую кнопку на командную панель формы списка документов в 1С:Предприятии 8.3 рядом с кнопкой 'Создать'?

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

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

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

Основные шаги и анализ проблемы

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

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

Решение 1: Добавление кнопки в командную панель с учетом ее структуры

Мы начнем с общего подхода, который позволяет добавить кнопку на командную панель, а затем уточним, как найти правильное место для ее размещения. Для добавления кнопки нам потребуется:

  1. Найти саму командную панель формы.
  2. Создать новую команду для нашей кнопки.
  3. Добавить кнопку на командную панель (или в ее группу), привязав ее к созданной команде.
  4. Определить обработчик команды, который будет выполнять нужные действия (например, вызывать внешнюю обработку).

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

Шаг 1: Находим командную панель

Командная панель часто имеет имя "КоманднаяПанель" или "ГруппаКоманднаяПанель" или подобное. Мы можем попытаться найти ее по имени:


// В обработчике формы ПриСозданииНаСервере или ПриОткрытии
Перем КоманднаяПанельФормы;
КоманднаяПанельФормы = Элементы.Найти("КоманднаяПанель"); // Или другое имя
Если КоманднаяПанельФормы = Неопределено Тогда
    КоманднаяПанельФормы = Элементы.Найти("ГруппаКоманднаяПанель");
КонецЕсли;

Если нам нужно добавить кнопку в конкретную часть панели, например, в группу с важными командами, мы должны найти эту группу. Часто кнопки "Создать" и другие стандартные команды расположены внутри группы.

Шаг 2: Создаем новую команду

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


// Создаем новую команду
НоваяКоманда = Команды.Добавить("МояНоваяКоманда");
НоваяКоманда.Текст = "Выполнить обработку";
НоваяКоманда.Подсказка = "Запустить внешнюю обработку";
НоваяКоманда.Действие = "ВыполнитьМоюКоманду"; // Имя процедуры-обработчика на клиенте

Шаг 3: Добавляем кнопку к командной панели

Теперь, когда у нас есть команда, мы можем добавить кнопку. Здесь возникает ключевой момент: куда именно добавлять? Хотя в некоторых случаях удобнее использовать динамическое создание реквизитов и элементов формы через расширения без кодирования, программный метод через коллекцию «Кнопки» дает максимальную гибкость в управлении порядком элементов.

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

Рассмотрим пример, где мы найдем кнопку «Создать», а затем добавим нашу кнопку в ее родительский элемент:


// Пример на основе полезных сообщений:
// В обработчике ПриСозданииНаСервере (или ПриОткрытии)

Если Не ЗагрузкаДанных Тогда // Проверяем, что не идет загрузка данных, для оптимизации
    ЭлементСоздать = Элементы.Найти("Создать"); // Пытаемся найти элемент "Создать"
    Если ЭлементСоздать = Неопределено Тогда
        // Если "Создать" не найдено, возможно, оно находится внутри какой-то группы
        // Попробуем найти через путь к данным, если знаем структуру
        // Или ищем универсально, как в следующем примере
        // Для демонстрации, если не нашли, то просто добавим на основную панель
        КоманднаяПанель = Элементы.Найти("КоманднаяПанель");
        Если КоманднаяПанель = Неопределено Тогда
            КоманднаяПанель = Элементы.Найти("ГруппаКоманднаяПанель"); // Частое название
        КонецЕсли;

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

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

            Если КоманднаяПанель <> Неопределено Тогда
                НоваяКнопка = КоманднаяПанель.Кнопки.Добавить("КнопкаВыполнитьОбработку", ТипКнопкиКоманднойПанели.Кнопка);
                НоваяКнопка.Команда = Команды.МояНоваяКоманда;
                НоваяКнопка.Вид = ВидКнопкиКоманднойПанели.ОбычнаяКнопка;
                НоваяКнопка.Положение = ПоложениеКнопкиКоманднойПанели.Рядом;
            КонецЕсли;
        КонецЕсли;
    КонецЕсли;
КонецЕсли;

Обратите внимание, что мы используем РодительСоздать.Кнопки.Добавить(...), а не РодительСоздать.Элементы.Добавить(...), когда работаем с командной панелью.

Решение 2: Более надежный поиск родительской группы кнопки "Создать"

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

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


// В обработчике формы ПриСозданииНаСервере

// 1. Создаем команду
НоваяКоманда = Команды.Добавить("МояНоваяКоманда");
НоваяКоманда.Текст = "Моя обработка";
НоваяКоманда.Подсказка = "Запустить внешнюю обработку";
НоваяКоманда.Действие = "ВыполнитьМоюКоманду"; // Имя процедуры на клиенте

// 2. Находим кнопку "Создать" и ее родительский элемент
ЭлементКнопкаСоздать = Неопределено;
Для Каждого ЭлементФормы Из Элементы Цикл
    Если ЭлементФормы.Имя = "Создать" И ТипЗнч(ЭлементФормы) = Тип("КнопкаФормы") Тогда
        ЭлементКнопкаСоздать = ЭлементФормы;
        Прервать;
    КонецЕсли;
    // Иногда кнопка Создать может быть элементом подчиненной командной панели
    Если ТипЗнч(ЭлементФормы) = Тип("ГруппаФормы") И ЭлементФормы.Вид = ВидГруппыФормы.КоманднаяПанель Тогда
        Для Каждого ПодЭлемент Из ЭлементФормы.Кнопки Цикл
            Если ПодЭлемент.Имя = "Создать" Тогда
                ЭлементКнопкаСоздать = ПодЭлемент;
                Прервать;
            КонецЕсли;
        КонецЦикла;
    КонецЕсли;
    Если ЭлементКнопкаСоздать <> Неопределено Тогда
        Прервать;
    КонецЕсли;
КонецЦикла;

// 3. Если нашли кнопку "Создать", добавляем нашу кнопку в ее родителя
Если ЭлементКнопкаСоздать <> Неопределено Тогда
    РодительскаяПанель = ЭлементКнопкаСоздать.Родитель;
    Если РодительскаяПанель <> Неопределено И ТипЗнч(РодительскаяПанель) = Тип("ГруппаФормы") И РодительскаяПанель.Вид = ВидГруппыФормы.КоманднаяПанель Тогда
        НоваяКнопка = РодительскаяПанель.Кнопки.Вставить(РодительскаяПанель.Кнопки.Индекс(ЭлементКнопкаСоздать) + 1, "КнопкаВыполнитьОбработку", ТипКнопкиКоманднойПанели.Кнопка);
        НоваяКнопка.Команда = Команды.МояНоваяКоманда;
        НоваяКнопка.Вид = ВидКнопкиКоманднойПанели.ОбычнаяКнопка;
        НоваяКнопка.Использование = ИспользованиеКнопкиКоманднойПанели.ОбычнаяКнопка;
    Иначе
        // Запасной вариант: добавляем в основную командную панель формы, если родитель не найден
        // или не является командной панелью
        КоманднаяПанель = Элементы.Найти("КоманднаяПанель"); // Основная командная панель формы
        Если КоманднаяПанель = Неопределено Тогда
            КоманднаяПанель = Элементы.Найти("ГруппаКоманднаяПанель"); // Частый альтернативный вариант
        КонецЕсли;

        Если КоманднаяПанель <> Неопределено Тогда
            НоваяКнопка = КоманднаяПанель.Кнопки.Добавить("КнопкаВыполнитьОбработку", ТипКнопкиКоманднойПанели.Кнопка);
            НоваяКнопка.Команда = Команды.МояНоваяКоманда;
            НоваяКнопка.Вид = ВидКнопкиКоманднойПанели.ОбычнаяКнопка;
        КонецЕсли;
    КонецЕсли;
Иначе
    // Если кнопка "Создать" не найдена вовсе, добавляем в корневую командную панель, если есть
    КоманднаяПанель = Элементы.Найти("КоманднаяПанель"); // Основная командная панель формы
    Если КоманднаяПанель = Неопределено Тогда
        КоманднаяПанель = Элементы.Найти("ГруппаКоманднаяПанель"); // Частый альтернативный вариант
    КонецЕсли;

    Если КоманднаяПанель <> Неопределено Тогда
        НоваяКнопка = КоманднаяПанель.Кнопки.Добавить("КнопкаВыполнитьОбработку", ТипКнопкиКоманднойПанели.Кнопка);
        НоваяКнопка.Команда = Команды.МояНоваяКоманда;
        НоваяКнопка.Вид = ВидКнопкиКоманднойПанели.ОбычнаяКнопка;
    КонецЕсли;
КонецЕсли;

Этот код пытается найти кнопку «Создать», а затем, если она найдена и имеет родительскую панель-группу, вставляет новую кнопку сразу после неё, используя метод Вставить() и индекс существующей кнопки.

Определение обработчика команды и вызов внешней обработки

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


// В модуле формы на клиенте
// Процедура-обработчик команды, указанная в свойстве Действие команды
&НаКлиенте
Процедура ВыполнитьМоюКоманду(Команда)
    // Здесь мы вызываем внешнюю обработку
    // Предположим, что внешняя обработка уже зарегистрирована в базе или доступна по пути
    ПутьКВнешнейОбработке = "ОбщийМакет.МояВнешняяОбработка"; // Пример: если обработка в общем макете
    
    // ... логика вызова ...
КонецПроцедуры

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

Особенности при работе с расширениями конфигураций

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

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

Резюме и практические советы

Давайте еще раз суммируем ключевые моменты и дадим несколько практических советов:

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

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

← На главную