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

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

В процессе обучения или разработки нестандартных интерфейсов в 1С часто возникает задача: не просто разместить кнопку в конфигураторе, а создать её программно (кодом) и заставить выполнять определенные действия. В нашем случае — фиксировать дату и время закрытия заказа, отличные от даты создания документа.

Давайте подробно разберем, как реализовать этот функционал в управляемом приложении. Мы рассмотрим два аспекта: логику работы кнопки (установку даты) и процесс её динамического создания при открытии формы.

Постановка задачи

Нам необходимо реализовать следующий сценарий:

  1. На форме документа должна появиться кнопка (желательно добавленная кодом).
  2. При нажатии на кнопку в реквизит документа ДатаЗакрытия должно записываться текущее время.
  3. Заголовок кнопки должен отображать эту дату (опционально, но полезно для наглядности).
  4. Важно: дата создания документа и дата закрытия должны различаться.

Часть 1. Логика работы: Команда и Обработчик

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

Для реализации логики нам понадобится процедура на клиенте (для перехвата нажатия) и, скорее всего, процедура на сервере (для получения точного времени сервера).

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

Рассмотрим код обработчика, который должен срабатывать при нажатии:


&НаКлиенте
Процедура ЗакрытьЗаказВыполнить(Команда)
    // Вызываем серверную процедуру для установки времени
    УстановитьДатуЗакрытияНаСервере();
КонецПроцедуры

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

Этот код решает задачу фиксации времени. Разница между датой документа и датой закрытия будет обеспечена автоматически, так как Объект.Дата фиксируется при создании, а Объект.ДатаЗакрытия — в момент нажатия кнопки.

Часть 2. Программное создание кнопки

Теперь перейдем к самой сложной части задания — созданию кнопки кодом. Многие новички пытаются писать код создания элементов формы в процедурах, выполняемых на клиенте, или используют устаревшие методы обычных форм (например, указывают координаты Лево, Верх, как в старых версиях 1С). В управляемом интерфейсе это работает иначе.

Важное правило: Изменять структуру формы (добавлять команды и элементы) можно только на сервере и только в момент инициализации формы, то есть в процедуре ПриСозданииНаСервере.

Проанализируем ошибку, которая возникала у автора при попытке выполнить Команды.Добавить на Тонком клиенте. Платформа выдавала ошибку, потому что коллекция команд формы доступна для изменения только на сервере.

Давайте напишем правильный алгоритм создания кнопки. Он состоит из трех шагов:

  1. Создать Команду формы (логику).
  2. Назначить команде Действие (имя процедуры-обработчика).
  3. Создать Элемент формы (визуальную кнопку) и связать его с командой.

Полный код модуля формы будет выглядеть так:


&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
    
    // 1. Создаем команду формы
    // Имя команды "КомандаЗакрытьЗаказ" - по нему будем ссылаться
    НоваяКоманда = Команды.Добавить("КомандаЗакрытьЗаказ");
    НоваяКоманда.Заголовок = "Закрыть заказ (установить дату)";
    
    // Указываем имя процедуры-обработчика, которая должна быть описана &НаКлиенте
    НоваяКоманда.Действие = "ЗакрытьЗаказНажатие";
    
    // 2. Создаем элемент формы (саму кнопку)
    // Тип("КнопкаФормы") обязателен для управляемых форм
    // Добавляем её, например, в командную панель формы или просто на форму
    НовыйЭлемент = Элементы.Добавить("КнопкаЗакрытияЗаказа", Тип("КнопкаФормы"), ЭтаФорма);
    
    // 3. Связываем кнопку с командой
    НовыйЭлемент.ИмяКоманды = "КомандаЗакрытьЗаказ";
    
    // Дополнительные настройки вида кнопки (опционально)
    НовыйЭлемент.Вид = ВидКнопкиФормы.ОбычнаяКнопка; 

КонецПроцедуры

// Обработчик нажатия, имя которого мы указали в свойстве "Действие"
&НаКлиенте
Процедура ЗакрытьЗаказНажатие(Команда)
    
    // Здесь выполняем логику установки даты
    УстановитьДатуНаСервере();
    
КонецПроцедуры

&НаСервере
Процедура УстановитьДатуНаСервере()
    
    Объект.ДатаЗакрытия = ТекущаяДатаСеанса();
    // Обновляем заголовок только что созданной кнопки
    Элементы.КнопкаЗакрытияЗаказа.Заголовок = "Заказ закрыт: " + Формат(Объект.ДатаЗакрытия, "ДЛФ=T"); // Покажем только время
    
КонецПроцедуры

Разберем ключевые нюансы реализации

При использовании метода Элементы.Добавить обратите внимание на третий параметр. В примере выше мы указали ЭтаФорма. Это означает, что кнопка добавится в корень формы (обычно вниз). Если вы хотите поместить кнопку в конкретную группу (например, в шапку документа), вместо ЭтаФорма нужно передать ссылку на эту группу, например Элементы.ГруппаШапка.

Также обратите внимание на свойство Заголовок. В задании требовалось отображать дату и время закрытия. В нашем коде мы делаем это динамически:

Это дает пользователю понятную обратную связь: он видит, что действие выполнено и время зафиксировано.

Итог

Чтобы решить задачу "добавить кнопку кодом с отображением даты закрытия", мы объединили два механизма:

  1. Механизм программной модификации формы в событии ПриСозданииНаСервере (создание команды и элемента).
  2. Механизм клиент-серверного взаимодействия для получения корректного времени через ТекущаяДатаСеанса() и обновления свойства Заголовок у элемента формы.
← На главную