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