При разработке интерфейсов на обычных формах 1С программисты часто сталкиваются с ситуацией, когда стандартный функционал динамических списков (например, ДокументСписок) работает «магическим» образом, автоматически отображая иконки проведения или удаления документов. Однако, как только мы переходим к использованию произвольной Таблицы Значений (ТЗ), вся автоматика исчезает. В этой статье мы подробно разберем, как вручную реализовать вывод системных картинок состояния документа, обеспечив при этом высокую производительность и аккуратный внешний вид формы.
Разберем ситуацию: когда вы используете стандартную форму списка, поле Ссылка связано с объектом метаданных, и платформа сама определяет, какую иконку отрисовать в колонке «Картинка». В случае с Таблицей Значений, элемент управления «Табличное поле» не обладает встроенной логикой анализа состояния ссылки. Для него это просто набор данных. Чтобы иконки появились, нам необходимо выполнить три условия: подготовить данные (индексы), назначить коллекцию картинок и правильно настроить отображение в ячейках.
Прежде всего, выясним, откуда берутся эти иконки. В платформе 1С существует системная библиотека картинок. Нам нужна коллекция под названием СостояниеДокумента. Она содержит набор из нескольких пиктограмм, расположенных в строгом порядке:
Чтобы табличное поле «понимало», откуда брать изображения, найдем в свойствах элемента управления ТабличноеПоле (на самой форме) свойство КартинкиСтрок (RowImages). В этом поле необходимо выбрать БиблиотекаКартинок.СостояниеДокумента. Это свяжет числовые индексы в ваших данных с конкретными иконками библиотеки. При необходимости работы с системными пиктограммами можно воспользоваться коллекцией файлов графических ресурсов платформы 1С.
Проанализируем структуру нашей ТЗ. Нам нужна отдельная колонка, которая будет хранить индекс картинки. Назовем ее, например, СостояниеКартинка. При создании таблицы программно это будет выглядеть так:
// Добавляем колонку для хранения индекса состояния
ТаблицаДокументов.Колонки.Добавить("СостояниеКартинка", Новый ОписаниеТипов("Число"));
Важный момент: тип данных этой колонки должен быть числовым, так как именно число определяет, какую иконку из коллекции выведет платформа.
Рассмотрим, как правильно заполнить эту колонку при формировании списка. Если мы используем запрос для получения данных, наиболее эффективно вычислить индекс прямо в тексте запроса. Это позволит избежать лишних обращений к базе данных в цикле.
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Реализация.Ссылка КАК Ссылка,
| ВЫБОР
| КОГДА Реализация.ПометкаУдаления ТОГДА 2
| КОГДА Реализация.Проведен ТОГДА 1
| ИНАЧЕ 0
| КОНЕЦ КАК ИндексКартинки
|ИЗ
| Документ.РеализацияТоваровУслуг КАК Реализация";
РезультатЗапроса = Запрос.Выполнить();
ТаблицаДокументов.Загрузить(РезультатЗапроса.Выгрузить());
Если же вы заполняете таблицу перебором, расчет будет выглядеть следующим образом:
Для Каждого СтрокаТЗ Из ТаблицаДокументов Цикл
Если СтрокаТЗ.Ссылка.ПометкаУдаления Тогда
СтрокаТЗ.СостояниеКартинка = 2;
ИначеЕсли СтрокаТЗ.Ссылка.Проведен Тогда
СтрокаТЗ.СостояниеКартинка = 1;
Иначе
СтрокаТЗ.СостояниеКартинка = 0;
КонецЕсли;
КонецЦикла;
Внимание: Обращение к свойствам Ссылка.Проведен в цикле может замедлить работу, если строк в таблице много. Старайтесь всегда получать эти данные заранее через запрос.
Теперь перейдем к визуальной настройке на форме. Добавим колонку в ТабличноеПоле и выполним следующие действия:
Данные (Data) оставьте пустое значение или укажите путь к данным, если вы хотите выводить там какой-то текст.ДанныеКартинки (DataPicture) выберите нашу колонку СостояниеКартинка.В некоторых случаях использование свойства ДанныеКартинки может быть недостаточно гибким или работать некорректно. Тогда мы можем использовать программную отрисовку. Рассмотрим два способа.
Это событие вызывается для каждой строки, когда она появляется на экране. Мы можем принудительно установить картинку для ячейки.
Процедура ТабличноеПолеПриВыводеСтроки(Элемент, ОформлениеСтроки, ДанныеСтроки)
// Указываем индекс картинки из данных строки
ОформлениеСтроки.Ячейки.КолонкаКартинки.ИндексКартинки = ДанныеСтроки.СостояниеКартинка;
// Гарантируем, что текст не будет отображаться
ОформлениеСтроки.Ячейки.КолонкаКартинки.УстановитьТекст("");
КонецПроцедуры
Выясним причину, почему ПриВыводеСтроки может «подтормаживать» список. Это событие срабатывает очень часто. Более производительным методом является ПриПолученииДанных, который обрабатывает сразу пакет строк, видимых на экране.
Процедура ТабличноеПолеПриПолученииДанных(Элемент, ОформленияСтрок)
Для Каждого Оформление Из ОформленияСтрок Цикл
Данные = Оформление.ДанныеСтроки;
Если Данные <> Неопределено Тогда
Оформление.Ячейки.КолонкаКартинки.ИндексКартинки = Данные.СостояниеКартинка;
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Проанализируем ситуацию, описанную в теме: автор использовал ТЗ, потому что требовался сложный отбор (например, по реквизиту договора контрагента). Однако в 1С 8.2 и 8.3 на обычных формах объект ДокументСписок также поддерживает режим Произвольного запроса.
Если вы переключите тип данных списка на произвольный запрос, вы сможете написать ЛЕВОЕ СОЕДИНЕНИЕ со справочником договоров и наложить любые условия в секции ГДЕ. При этом платформа сама выведет стандартную картинку состояния, и вам не придется писать ни одной строки кода для управления индексами или событиями отрисовки. Это наиболее «правильный» путь с точки зрения архитектуры 1С, так как динамические списки оптимизированы для работы с большими объемами данных и обеспечивают стандартное поведение интерфейса. Для реализации таких доработок можно использовать практические методы модификации динамических списков и добавления полей.
Таким образом, мы рассмотрели все способы решения задачи: от ручного управления индексами в Таблице Значений до использования возможностей динамических списков. Выбор конкретного метода зависит от того, насколько сложная логика формирования данных требуется в вашей конкретной задаче.