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