Как вывести макет на управляемую форму и программно объединить ячейки

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

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

Шаг 1. Подготовка интерфейса и создание реквизитов

Прежде чем приступать к написанию кода, необходимо подготовить "место" на форме, где будет отображаться наш результат. В управляемом приложении мы не можем просто "нарисовать" макет. Нам нужно использовать специальный тип данных — ТабличныйДокумент.

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

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

Теперь у нас есть область на экране, в которую мы сможем программно выводить данные из макета.

Шаг 2. Получение доступа к макету обработки

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

Способ 1. Через менеджер обработки (наиболее оптимальный). Этот метод позволяет получить макет, не создавая экземпляр всей обработки в оперативной памяти:


&НаСервере
Функция ПолучитьМакетНаСервере()
    Возврат Обработки.ИмяВашейОбработки.ПолучитьМакет("ИмяМакета");
КонецФункции

Способ 2. Через преобразование данных формы в объект. Этот метод используется, если макет должен учитывать текущие данные, заполненные пользователем в объекте:


&НаСервере
Процедура СформироватьТаблицу()
    ТекОбъект = РеквизитФормыВЗначение("Объект");
    Макет = ТекОбъект.ПолучитьМакет("ИмяМакета");
    // Далее работаем с макетом
КонецПроцедуры

Шаг 3. Логика программного объединения ячеек

Для решения задачи, когда 3 часа работы должны отображаться как одна объединенная ячейка, нам потребуется метод Объединить(). Рассмотрим пример, где мы программно определяем область и объединяем её в зависимости от переданных параметров.

Выясним причину, почему это удобно: объединение позволяет не только визуально сгруппировать данные, но и поместить в центр группы один общий текст, который будет центрироваться по всей длине интервала.


// Пример функции для формирования строки графика
&НаСервере
Процедура ЗаполнитьСтрокуГрафика(ТабДок, НомерСтроки, ЧасНачала, Длительность)
    
    // Получаем область из макета (например, одну ячейку-шаблон)
    ОбластьЯчейка = ТабДок.Область(НомерСтроки, ЧасНачала, НомерСтроки, ЧасНачала + Длительность - 1);
    
    // Объединяем ячейки
    ОбластьЯчейка.Объединить();
    
    // Устанавливаем оформление
    ОбластьЯчейка.Текст = "Работа: " + Длительность + " ч.";
    ОбластьЯчейка.ЦветФона = ЦветаСтиля.ЦветФонаВыделения;
    ОбластьЯчейка.ГраницаСверху = Новый Линия(ТипЛинииЯчейкиТабличногоДокумента.Сплошная, 1);
    ОбластьЯчейка.ГраницаСнизу = Новый Линия(ТипЛинииЯчейкиТабличногоДокумента.Сплошная, 1);
    ОбластьЯчейка.ГраницаСлева = Новый Линия(ТипЛинииЯчейкиТабличногоДокумента.Сплошная, 1);
    ОбластьЯчейка.ГраницаСправа = Новый Линия(ТипЛинииЯчейкиТабличногоДокумента.Сплошная, 1);
    
КонецПроцедуры

Шаг 4. Разбор ошибки "Нельзя изменять поле, содержащее объект данных формы"

Часто программисты сталкиваются с ошибкой при попытке обновить таблицу на форме. Проанализируем ситуацию: если вы напишете Объект.РезультатТаблица = Новый ТабличныйДокумент, система выдаст ошибку. Это происходит потому, что реквизит формы уже инициализирован и жестко связан с элементом управления на форме. Вы не можете подменить сам объект, вы можете только изменять его содержимое.

Рассмотрим правильный алгоритм обновления данных:

  1. Очистка: Вместо создания нового объекта используйте метод Очистить() у существующего реквизита.
  2. Заполнение на сервере: Если вы формируете таблицу в локальной переменной на сервере, используйте метод ЗначениеВРеквизитФормы.

Пример правильного вывода:


&НаСервере
Процедура СформироватьНаСервере()
    
    // 1. Создаем временный табличный документ
    ВременныйТабДок = Новый ТабличныйДокумент;
    
    // 2. Получаем макет
    Макет = Обработки.МояОбработка.ПолучитьМакет("МакетГрафика");
    ОбластьШапка = Макет.ПолучитьОбласть("Шапка");
    ВременныйТабДок.Вывести(ОбластьШапка);
    
    // 3. Здесь реализуем логику объединения (как в Шаге 3)
    // ... код заполнения ...
    
    // 4. Копируем результат в реквизит формы
    ЗначениеВРеквизитФормы(ВременныйТабДок, "РезультатТаблица");
    
КонецПроцедуры

Шаг 5. Особенности передачи параметров

Посмотрим на пример ситуации, когда данные передаются между процедурами. Если вы передаете ТабличныйДокумент или другие объекты в процедуры, важно помнить о способе передачи (по ссылке или по значению). В 1С объекты передаются по ссылке, но если вы работаете с данными формы, лучше всегда выполнять финальное присвоение через ЗначениеВРеквизитФормы, чтобы платформа корректно отследила изменения и обновила графический интерфейс пользователя.

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

Резюме

Для успешного вывода макета с объединенными ячейками на форму обработки необходимо:

← На главную