IT Блог Сергея Бобошко
1С Предприятие, конфигурации, обработки, услуги программиста, помощь программиста
1с 8.3 при выводе строки управляемые формы
Куда же подевалось событие «ПриВыводеСтроки» в управляемых формах, и как с этим быть? Убрали его по всей видимости потому, что это был основной источник загруженности сервера. Особенно программисты не очень высокой квалификации любят напихивать в это событие кучу запросов и циклов, которые «бомбят» сервер, при перерисовке каждой строчки, видимой на экране. Так как в управляемых формах клиентское приложение может вообще выполняться на веб-браузере, да ещё с плохим интернетом, такая тактика может привести к тому, что пользователь целый день будет сидеть, тупо уставившись в зависшую 1С.
Поэтому, решив не особо заморачиваться с запретами в коде события, 1С решили вывести основные моменты, связанные с оформлением строк в реквизиты формы, вернее свойства. Это очень похоже на условное оформление в СКД.
Вы нажимаете на шапку формы, заходите в её свойства, и ищете в разделе «Оформление» ссылку «Условное оформление».
Открывается такой же инструментарий, как в СКД для условного оформления
Добавляем новое оформление зеленым плюсом, и нажимаем на три точки, чтобы добавить само оформление. Ото пока что не связано с чем нибудь конкретным. Просто указываем нужный цвет, доступность, штифт и т.д.
Заметьте, в отличии от программной установки параметров в событии «ПриВыводеСтроки», где нужно было делать два варианта оформления — если условие выполнилось, и если условие не выполнилось — чтобы вернуть оформление на место. Здесь этого делать не нужно. Если условие не выполняется, то оформление применяется «по умолчанию», то есть которое вы видите, когда в конфигураторе создаете форму.
Вот какие параметры можно оформлять
Для подавляющего большинства случаев список вполне впечатляет.
Далее пишем условие, нажав на три точки в колонке «Условие»
Вы можете добавлять как группу условий, так и отдельные элементы. Условия между группами всегда «И», так же и между элементами, которые не находятся внутри групп всегда «И»
По сути мы написали условие :
Реквизит1 = 1 И Реквизит2 = 2 ИЛИ (НомерСтроки = 1 ИЛИ НомерСтроки = 3 ИЛИ НомерСтроки=6)
То есть внутри группы условие между отдельными элементами зависит от самой группы.
Мои страдания и разбор «КАК ЭТО РАБОТАЕТ» можете более подробно рассмотреть в этом ролике:
Оформление строки в ПриПолученииДанных или ПриВыводеСтроки
Событие ПриПолученииДанных использется для оформления ячеек строк данных, отображаемых табличным полем. Обработчик данного события вызывается табличным полем в тех же случаях, что и обработчик ПриВыводеСтроки, т.е. при обновлении данных, отображаемых табличным полем или при поиске по подстроке. Важно отметить, что обработчик данного события вызывается табличным полем перед вызовом обработчиков события ПриВыводеСтроки для всех видимых строк табличного поля. Основным отличием данного события от события ПриВыводеСтроки является то, что в обработчике события ПриПолученииДанных можно изменять настройки ячеек группы строк, а не одной строки как в обработчике события ПриВыводеСтроки.
А вот так это выглядит в реальности:
Похожие FAQ
Еще в этой же категории
Как получить строки табличного поля, отобранные отбором? 4
ОтборСтрок = ТабличнаяЧастьИсточник.ОтборСтрок ; ПостроительЗапроса = Новый ПостроительЗапроса; ПостроительЗапроса.ИсточникДанных = Новый ОписаниеИсточникаДанных(ТабличнаяЧастьИсточник); // Добавляются необходимые отборы, такие же как в отбор Отбор по списку значений 3
СозданныйСписок = Новый СписокЗначений; СозданныйСписок.Добавить(Перечисления.СтатусЗаявки.Выполнено); СозданныйСписок.Добавить(Перечисления.СтатусЗаявки.ЗакрытиеЗаявки); СозданныйСписок.Добавить(Перечисления.СтатусЗаявки.ОтклоненаРукОтдЗакупок); Как пользователям запретить удаление условия отбора в форме списка? 3
ЭлементОтбора.РежимОтображения = РежимОтображенияЭлементаНастройкиКомпоновкиДанных.Недоступный; Полный код: ЭлементОтбора = Список.Отбор.Элементы.Добавить(Тип(» ЭлементОтбораКомпоновкиДанных» )); ЭлементОтбора.ЛевоеЗначение = Новый ПолеКомпонов Посмотреть все в категории Список Справочника, Документов, Регистров
Полезная “фишка” 1С 8.3 – вывод произвольных данных в списках без потерь производительности
Сегодня – интересный технический прием для тех, кто занимается разработкой / доработкой конфигураций.
Начиная с версии платформы 8.3.10 работает новое событие динамического списка ПриПолученииДанныхНаСервере.
Разве этого не было раньше?
На первый взгляд это не отличается принципиально от того, что делали уже несколько лет – всегда можно добавить колонку и заполнить её запросом!
Да, можно было добавить колонку : ))
Разница в том, что в запросе нельзя вывести разнородную информацию в одно поле.
Плюс усложнение запроса приводит к тормозам при отображении списков документов.
В общем, посмотрите 10 минут видео, всё станет понятно
Видео – событие “ПриПолученииДанныхНаСервере” динамического списка
В видео рассмотрим вывод складских остатков по товарам с разбивкой по складам.
Эту задачу нельзя было решить через корректировку запроса динамического списка (в 8.3.9 и ранее).
Профессиональная разработка интерфейсов и форм в 1С:Предприятие 8.3
Разработка и доработка интерфейсов – это, пожалуй, одна из самых распространенных задач на проектах. После прохождения курса Вы сможете создавать красивые и удобные формы любого уровня сложности, а также освоите Обычный, Управляемый интерфейс и Такси.
Поддержка тренера – 3 месяца. Объем курса – 49 учебных часов.
Не откладывайте свое обучение!
Комментарии / обсуждение (68):
Спасибо. Статья очень пригодилась. Но, столкнулся с ситуацией.
Пока ВыборкаДетальныеЗаписи.Следующий() Цикл
СчетчикКонтейнеров = СчетчикКонтейнеров +1;
Если НЕ ПерваяСтрока Тогда
Контейнер=Контейнер+» : «;
КонецЕсли;
Контейнер = Контейнер + СокрЛП(ВыборкаДетальныеЗаписи.НомКон);
ПерваяСтрока=Ложь;
СтрокаСписка = Строки[ВыборкаДвижениеПоСкладу.ДвижениеПоСкладу];
СтрокаСписка.Данные.Контейнер = Контейнер;
Если СчетчикКонтейнеров=2 Тогда
СтрокаСписка.Оформление[«Контейнер»].УстановитьЗначениеПараметра(«ЦветТекста», Webцвета.Зеленый);
ИначеЕсли СчетчикКонтейнеров=3 Тогда
СтрокаСписка.Оформление[«Контейнер»].УстановитьЗначениеПараметра(«ЦветТекста», Webцвета.СинеСерый);
ИначеЕсли СчетчикКонтейнеров=4 Тогда
СтрокаСписка.Оформление[«Контейнер»].УстановитьЗначениеПараметра(«ЦветТекста», Webцвета.СинеФиолетовый);
ИначеЕсли СчетчикКонтейнеров>4 Тогда
СтрокаСписка.Оформление[«Контейнер»].УстановитьЗначениеПараметра(«ЦветТекста», Webцвета.РыжеватоКоричневый);
Для поля контейнер в списке установил галку “Использовать всегда” на случай скрытия поля пользователем.
Но при скрытии пользователем поля “Контейнер” в списке все равно не работает строка
СтрокаСписка.Оформление[“Контейнер”].УстановитьЗначениеПараметра(“ЦветТекста”, Webцвета.Зеленый);
Ругается на отсутствие поля Контейнер. Обошел через конструкцию “Попытка”.
Мне кажется, вариант не красивый. Есть какие-то другие способы на будущее?
Использовать всегда работает только для данных строки (СтрокаСписка.Значение.Данные.Контейнер).
Оформление же работает только для отображаемых колонок.
Как вариант, можно написать что-то типа
[cc]
Оформление = СтрокаСписка.Значение.Оформление.Получить(“Контейнер”);
Если Оформление <> Неопределено Тогда
Если СчетчикКонтейнеров=2 Тогда
Оформление.УстановитьЗначениеПараметра(“ЦветТекста”, Webцвета.Зеленый);
КонецЕсли;
КонецЕсли;
Платформа 1С:Предприятие 8.3 (8.3.13.1513).
Процедура СписокПриПолученииДанныхНаСервере(ИмяЭлемента, Настройки, Строки).
Процедура — не вызывается.
Можете пояснить причину?
Добрый день, Дмитрий!
Вот текст из справки “Обработчик вызывается в режиме совместимости конфигурации Версия8_3_8 и выше”
Судя по всему у Вас в свойствах конфигурации установлен режим совместимости более ранней версии.
Жалко, что узнал об этом только сейчас. Спасибо!
А не подскажите как вызвать событие ПриПолученииДанныхНаСервере без Элементы.ДинамическийСписок.Обновить()?
Дело в том что на мобильном устройстве, это событие отрабатывает достаточно долго, и обновляет весь список, а мне нужно обновить только одну строку (ну или хотя бы видимую область). Вот и получается что бы обновить 40 строк, я заново инициирую построение запроса
Добрый день! К сожалению, по поводу мобильной платформы ничего сказать не могу. Если говорить в общем, то событие ПриПолученииДанныхНаСервере связано именно с получением данных, а соответственно и с выполнением запроса. Не думаю, что получится обновить список без повторного выполнения запроса.
Форма подбора. Слева располагается ДеревоИерархии, справа от него ДинамическийСписок в который выводится номенклатура которая в Иерархии конкретно указанной ветки Дерева. В строка ДС (динамического списка) есть количество Номенклатуры выбранного в Корзину. Корзина – РегистрСведений. Когда пользователь нажимает в строке ДС в область колонки Выбранно в обработке Выбора идет внеконтекстная запись в РС Корзина, а потом Элементы.ДС.Обновить();
Проблема в том, что Чем больше содержание ветки дерева, тем дольше идет обновление. При этом, если бы эту же информацию получить в событии ПриПолученииДанныхНаСервере, то там всегда 42 строки, оходятся циклом. Но это событие вызвать просто можно только скролированием, которое к сожалению, не совсем адекватно в данном контексте. Метод УстановитьДействие(), работает только на сервере, но форма для контекстного вызова тяжеловата
Это было очень интересно! Спасибо
Пожалуйста!
Интересного обучения!
Огромное спасибо за эту статью и за курс “Профессиональная разработка интерфейсов и форм 1с 8.3”.
В ERP 2.4 выполнила задачу, которая казалась нерешаемой или затратной.
Познакомившись с данным способом ПриПолученииДанныхНаСервере, применила его для произвольной формы интерфейса и все получилось.
Добрый день, а поиск по этой колонке получается не будет работать?
Добрый день!
Да, все верно.
Отличный мастер-класс от команды профессионалов!
А что если в запросе дин.списка не формировать пустое поле остаток? А вместо этого добавить новое поле в таблицу формы (не связанное с данными), и заполнять его через оформление ячейки… подобно тому как в ОФ методом УстановитьТекст().
Добрый день, Роман! К сожалению, в УФ в таблицу формы динамического списка нельзя добавить поле не связанное с данными.
Здравствуйте Сергей! Да, такой финт и вправду не получится. А точнее поле можно добавить, но оно не отобразится без указания связи с данными. Тогда получается продемонстрированный Вами способ является единственным аналогом события “ПриВыводеСтроки()” обычного приложения.
А возможно ли как то передать в эту процедуру инициализированное значение внешней обработки или СОМ-объекта? чтобы каждый раз не инициализировать его при очередном вызове.
Добрый день, Роман! Корректного способа нет, но можно попробовать использовать временное хранилище.
Общий план такой:
1. При открытии формы инициализируем СОМ-объект, помещаем его в структуру(чтобы ошибок не возникало, так как в хранилище можно помещать только сериализуемые значения, а СОМ-объекты к ним не относятся). Далее структуру помещаем во временное хранилище и полученный адрес помещаем в дополнительные свойства списка.
2. В событии “ПриПолученииДанныхНаСервере” получаем данные из хранилища, проверяем “живой” ли СОМ-объект, если его нет (такое может случится, если хранилище сбрасывалось на диск), тогда придется создавать новый, ну а если есть, тогда пользуемся.
Это все в теории, можете самостоятельно попробовать на практике. Других вариантов я не вижу.
Здравствуйте. Столкнулся вот с какой проблемой: Динамический список, основная таблица Регистр сведений (независимый, непериодический с одним измерением и тремя ресурсами). Добавил два поля для расчета в обработчике “ПриПолученииДанныхНаСервере” (Неопределенно и Ложь). Для правильной работы мне нужно поле из списка. Но в структуре “Данные” доступны только неопределенные поля. Для упрощения приведу запрос:
Чтобы заполнить два последних поля, мне нужно поле “Файл”. Как до него добраться?
Ожидая Ваш вопрос почему мне напрямую не вытащить “ВладельцаФайла” отвечу: Пользователю с ограниченными правами доступны не все таблицы и возникает ошибка с полем “ВладлецФайла” в справочниках (присоединенные файлы). Конфигурация ERP, платформа 8.3.12.1412, режим совместимости не используется.
Нюанс: основная таблица не была указана, но после указания стало еще хуже, т.к. теперь ограниченному пользователю не доступно поле “Файл” (ОпределяемыйТип.ПрисоединенныйФайл)
Решил вопрос: Во-первых не была указана основная таблица (ну бывает), немного расширил права на регистр и на его поля (на всякий случай на все). И все поля стали доступны.
Всем спасибо.
Сергей, спасибо большое! Как всегда, материал на высоте. Вы наш проводник в мир управляемого интерфейса!:)
Всех с наступившим Новым годом!
А можно вывести цифры (строки) и картинку?
Картинку можно вывести, а вот нумерацию строк в динамическом списке (если я правильно понял вопрос) нет.
Переделайте эту часть.
В какой именно момент оптимизатор не будет угадывать, уточните.
Условие ИЛИ оптимизатор не знает как себя вести, для этого рекомендации использовать объединение запросов но использовать условие И – классика. Ну это же из курсов вашего коллеги Андрея Бурмистрова
Ну да конечно, что если взять к примеру порцию 70 записей это зависит от прокрутки и экрана допустим у меня очень большой экран. То скорее всего будет применятся не индекс сик, а сканирование индекса Будет сканироваться таблица регистра на вхождения склада, да конечно вы накроете по кластерному индексу товарами (хотя и тоже не факт)…
Я к тому веду, что запрос и в этом случае будет быстрым потому как порция небольшая. Но если регистр будет огромнейший более несколько миллионов то тут уже будут потери производительности.
Я к чему веду, если вы уж так статью пишите о производительности то и код должен быть 100% максимально идиален.
А еще у Вас потери производительности на сортировке. Вы применили сортировку склада по имени обращаясь к складу через точку. Ну скорее всего потери получения наименования не должно быть поскольку склад должен быть покрыт кластерным индесом и данные должны лежать уже на уровне В-дерева (но это все надо перепроверить).
Базовый принцип программирования управляемой формы в 1С
Цель статьи – показать применение шаблонов Remote Facade и Data Transfer Object к структуризации кода, управляемой формы в среде 1С 8.2.
Введение
Начнем с небольшого описания понятия «управляемая форма» и связанных концепций платформы 1С. Знатоки платформы могут пропустить этот раздел.
Все дальнейшие рассуждения будут о правой части иллюстрации, о том, как структурировать код модуля и какие принципы позволят реализовать эффективное клиент-серверное взаимодействие.
Обозначим проблему
Прошло уже несколько лет как новая версия платформы 1С активно используется и выпущено множество решений (конфигураций) как фирмой 1С, так и ее многочисленными партнерами.
Сложилось ли за это время у разработчиков единое понимание принципов клиент-серверного взаимодействия при создании форм, и изменился ли подход к реализации программных модулей в новых архитектурных реалиях?
Рассмотрим структуру кода (модуль формы) в нескольких формах одной типовой конфигурации и попробуем найти закономерности.
Под структурой будем понимать секции кода (чаще всего это блоки комментариев) выделенные разработчиком для группировки методов и директивы компиляции этих методов.
Пример 1:
Зачем нужна структура кода?
Почему существующий стандарт разработки от фирмы 1С не помогает?
Шаблоны проектирования или мудрость поколений
Примеры шаблонов в платформе 1С
Прикладной программный интерфейс доступный разработчику при разработке управляемой формы, содержит много примеров данных принципов.
Например метод ОткрытьФорму(), типичный «огрубленный» интерфейс.
Сравните с принятым в v8.1 стилем.
Структурируем код
Предотвращение многократного вызова «ПриПолученииДанных» во время поиска в табличном поле в обычных формах
Но есть такое безобразие: если пользователь производит поиск по колонке то платформа ведет себя так, как будто во время поиска перелистываются все страницы для отображения на форме в списке, хотя этого фактически не происходит, пока не будет найдено искомое значение. И все это время происходят события ПриПолученииДанных и ПриВыводеСтроки, со всеми вытекающими негативными последствиями. То есть: срабатывает событие ПриПолученииДанных столько раз сколько типа_страниц перелисталось до искомой строки, и каждый раз после этого срабатывает событие ПриВыводеСтроки столько раз сколько типа_строк помещается в типа_страницу.
Но! Есть такое событие формы ОбновлениеОтображения. Вот оно-то и происходит каждый раз когда на форме что-то реально меняется. И есть метод формы Обновить().
ОбновлениеОтображения выполняется после того как будет найдено значение (или произойдет смещение поля на строку, на страницу, в начало/конец) и ТабличноеПоле обновится. Нам остается запретить запросы, заполнения и раскраски ячеек пока не произойдет изменение на форме. Затем разрешить и запросить обновить форму. После чего снова установить флаг запрета. Код из процедуры события ПриПолученииДанных выполнится всего один раз, как нам и надо было. Примерный код: