1С цвет строки динамического списка

Если вы, открыв форму справочника или документа, выполнили некоторое действие, код который должен изменить состояние данных в динамических списках или значение реквизита. Данные изменены, но в открытой форме осталось все как было, можно конечно закрыть форму и открыть снова — все обновится но если нужно обновить сразу в открытой форме, то используйте код:

&НаКлиентеПроцедура ОбработкаДанныхКлиент() Экспорт//Обрабатываем на сервере, например создаем записи в регистре сведений//................ОбработкаДанныхСервер();//................//Обновление динамического списка на формеЭлементы.Список.Обновить();//Обновим реквизитыЭтаФорма.Прочитать();// Обновление данныхЭтаФорма.ОбновитьОтображениеДанных();КонецПроцедуры 

Обновить() — Обновляет данные в таблице.
Прочитать() — Обновляет объект управляемой формы.
ОбновитьОтображениеДанных() — В принудительном порядке обновляет содержание элементов управления. Полезен при изменении значений реквизитов формы вне формы, в тот момент, когда форма отображается на экране.

02.11.2018

Развитие динамических списков с произвольными запросами

Данная статья является анонсом новой функциональности.
Не рекомендуется использовать содержание данной статьи для освоения новой функциональности.
Полное описание новой функциональности будет приведено в документации к соответствующей версии.
Полный список изменений в новой версии приводится в файле v8Update.htm.

Реализовано в версии 8.3.14.1565.

Динамические списки являются удобным инструментом для быстрого отображения и просмотра большого количества записей. Они получают и отображают данные порциями. Благодаря этому пользователи могут одинаково быстро работать и с маленькими, и с большими списками.

Динамическое считывание данных становится возможным благодаря тому, что списку указывается основная таблица. Ключевые поля этой таблицы используются платформой для однозначной идентификации строк списка. Например, если список отображает данные справочника или документа, то в качестве ключевого поля используется поле Ссылка. Если список отображает записи какого-нибудь регистра, то для идентификации отдельных строк платформа использует объекты, содержащие значения нескольких ключевых полей. Эти объекты имеют разные названия для разных таблиц, но у них есть общая часть – «КлючЗаписи». Например, РегистрСведенийКлючЗаписи.<имя регистра>, РегистрРасчетаКлючЗаписи.<имя регистра> и т.д.

Однако возможности динамических списков гораздо шире, чем просто «стандартное» получение данных из одной таблицы. Вы можете написать произвольный запрос для динамического списка. Такой запрос может получать данные из таблиц, которые «в обычной ситуации» не используются для непосредственного отображения в интерфейсе (например, из таблицы остатков регистра или из таблицы регистрации изменений). Также вы можете в произвольном запросе получать данные сразу из нескольких таблиц, соединяя их с помощью языка запросов.

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

В этой ситуации платформа не может считывать данные динамически. Так как в выборке отсутствуют ключевые поля, платформе приходится использовать в качестве них порядковый номер записи, и каждый раз считывать данные с начала, что может занимать значительное время и существенный объем памяти. Также в этой ситуации становится недоступной часть функциональности динамического списка. Например, не поддерживается группировка записей в списке. Кроме этого при обновлении списка текущая строка, с точки зрения пользователя, может самопроизвольно «перепрыгивать» на другую строку, если с момента предыдущего отображения данных количество предшествующих строк списка изменилось.

Для того чтобы устранить перечисленные недостатки и повысить производительность списков, мы добавили в платформу возможность указывать произвольные ключевые поля для запроса динамического списка. Например, вы можете выбрать данные из таблицы остатков регистра накопления, используя ключевые поля Товар и Склад.

001.png

Как вы видите, для произвольного запроса динамического списка появились возможности указать вид ключа, выбрать ключевые поля (из тех, которые доступны в тексте запроса), и включить динамическое считывание данных.

Вид ключа может быть указан следующим образом:

  • ЗначениеПоля – для такого ключа вам нужно выбрать одно единственное ключевое поле, и поведение списка в этом случае будет таким же, как у списка, содержащего ссылочные объекты (список справочника, список документа и т.д.);
  • КлючСтроки – для такого ключа вам нужно выбрать одно или несколько ключевых полей, и поведение списка в этом случае будет таким же, как у списка, содержащего записи (список регистра накопления, список регистра сведений и т.д.);
  • НомерСтроки – это имитация того поведения, которое существовало раньше; в качестве ключа будет использоваться номер строки в выборке со всеми вытекающими из этого недостатками;
  • Авто – в этом случае платформа сама автоматически определит вид ключа как один из трех перечисленных выше: если ключевые поля не заданы, то будет НомерСтроки, если задано одно ключевое поле, то ЗначениеПоля, если более одного ключевого поля, то КлючСтроки.

Таким образом, теперь, если вы выбираете для своего произвольного запроса вид ключа ЗначениеПоля или КлючСтроки, вам становятся доступны:

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

Также при использовании произвольных ключевых полей вы можете использовать объединения. Например, объединив записи из двух таблиц документов, вы получите достаточно эффективный запрос, который имитирует журнал документов:

002.png

003.png

Мы надеемся, что новые возможности помогут вам создавать функциональные и производительные динамические списки с произвольными запросами.

Теги: разработка 8.3.14 списки

Рассказать друзьям:

Многие из тех, кто программировал на платформе 7.7, сталкивались с задачей доработки стандартных форм подбора номенклатуры, например, в ТиС. Пользователи часто желали видеть в одной таблице и остатки, и цены, да чтобы еще можно было отфильтровать список, например, по ненулевым остаткам. Создать произвольную форму списка стандартными средствами, которая бы при этом еще и не тормозила при листании и поиске на списках приличного размера, было не так-то просто. Честно говоря, именно такого рода задачи привели меня в свое время к использованию известных внешних компонент, которые позволяли семерке более эффективно получать данные запросами и отображать списки в альтернативных контролах. Ну а когда я начал осваивать платформу 8.2 и познакомился в общих чертах с ее базовыми механизмами, мне захотелось проверить, насолько проще можно решить подобные задачи теперь.

Итак, на управляемых формах попробуем создать простейшую форму для подбора номенклатуры, так, чтобы в списке отображался остаток и цена, и можно было выводить только те строчки, по которым есть остаток. Предполагаем что у нас уже есть справочник Номенклатура, документ Реализация, регистр накопления ОстаткиНоменклатуры и регистр сведений ЦеныНоменклатуры.

Создаем новую управляемую форму списка для справочника Номенклатура. Если созданная форма прописалась, как основная форма списка справочника, очистим это поле, дабы наша новая форма подбора открывалась только в нужном нам месте, а не везде, где предусмотрено открытие формы списка по умолчанию. Указываем мастеру, какие реквизиты справочника мы желаем видеть в списке, пусть это будут Код и Наименование. Выбираем детищу имя, например ФормаПодбора.

Теперь нас будет интересовать основной реквизит этой формы, имеющий тип ДинамическийСписок и имя ему — просто Список. В списке реквизитов формы основной реквизит отображается жирным шрифтом, я выделил его на картинке. Заглянем в его свойства, система автоматом установила для него основную таблицу, данные из которой и будут помещаться в список и отображаться на форме. Именно установка в качестве основной таблицы справочника позволит списку выглядеть и функционировать именно как список справочника, со всеми присущими ему иконками и командами. Так же установлен флажок «Динамическое считывание данных», это свойство позволяет отображать на лету изменения, происходящие с номенклатурой, например, в сеансах других пользователей — добавление новых записей, например.

Новая форма

Нас же больше всего интересует флажок «Произвольный запрос». Именно его установка позволит нам изменить набор данных, который окажется в нашем списке. Устанавливаем флажок и переходим по появившейся снизу ссылке «Настройка списка — открыть».

Начальный запрос

Видим, что платформа любезно подготовила для нас текст запроса, который пока что позволяет нам получит все тот же обычный список номенклатуры с наименованием, кодом и другими реквизитами справочника. Но теперь у нас есть возможность отредактировать этот запрос! Можем воспользоваться конструктором запроса или написать текст вручную, кто как привык.

Быстренько добавляем левые соединения с виртуальными таблицами остатков и цен, задаем нужные параметры, нам пока достаточно даты получения остатков и цен, и типа цены (конечно, такое измерение уже должно быть в нашем регистре сведений). Запрос готов.

Готовый запрос

Любопытства ради переходим на закладку настройки — и вот оно, счастье вчерашнего семерочника! Без всякого программирования, в самой первой закладке имеем возможность задавать любые интересуюшие нас отборы по полям, отбираемым в запросе! И главное — ровно все то же самое будет доступно и в пользовательском режиме! Выбрав в стандартных действиях пункт «Настроить список», пользователь увидит точно такое же окно настроек. Немного облегчим ему жизнь, заранее добавив отбор по полю Количество. Пользователю останется лишь установить флажок активности созданного нами отбора, когда это потребуется.

Настройки списка

Закрываем форму настройки списка и продолжаем облагораживание нашей формы подбора. Добавляем булевский реквизит ЗапрашиватьКоличество и таблицу значений Корзина, в ней мы будем отображать уже выбранную номенклатуру с количеством, ждущую переноса в документ. Перетаскиваем созданные реквизиты на форму, располагаем, как нам нравится. Кстати, нужно не забыть, что у реквизита Список, благодаря нашему новому запросу, появились новые доступные поля — Количество и Цена, перетаскиваем на форму и их тоже:

Готовая форма

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

Параметры формы

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

&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
Список.Параметры.УстановитьЗначениеПараметра("Период", Параметры.Дата);
Список.Параметры.УстановитьЗначениеПараметра("ТипЦен", Параметры.ТипЦен);
КонецПроцедуры

Прописываем обработку двойного клика по списку номенклатуры. В клиентском контексте, где у нас выполняются все обработчики типа кликов и нажатий, тип данных ТаблицаЗначений недоступен, а созданный нами реквизит формы Корзина лишь «маскируется» под ТЗ, на самом деле это служебный тип данных, ДанныеФормыКоллекция, предназначенный только для отображения ТЗ на форме. Поэтому работу с реальной ТЗ (поиск и добавление строк) переносим в серверную процедуру. Для преобразований между служебным типом данных и настоящей ТЗ и обратно используются две функции глобального контекста: ДанныеФормыВЗначение() и ЗначениеВДанныеФормы(). Отключаем стандартную обработку, чтобы при клике на списке не открывалась форма элемента.

&НаКлиенте
Процедура СписокВыбор(Элемент, ВыбраннаяСтрока, Поле, СтандартнаяОбработка)
СтандартнаяОбработка = Ложь;
Если ЗапрашиватьКоличество Тогда
ДобавитьКоличество = 0;
Если ВвестиЧисло(ДобавитьКоличество, "Введите количество единиц", 15, 3) Тогда
ДобавитьВПодбор(ВыбраннаяСтрока, ДобавитьКоличество);
КонецЕсли;
Иначе
ДобавитьВПодбор(ВыбраннаяСтрока, 1);
КонецЕсли;
КонецПроцедуры
&НаСервере
Процедура ДобавитьВПодбор(Номенклатура, Количество)
ТЗ = ДанныеФормыВЗначение(Корзина, Тип("ТаблицаЗначений"));
Строка = ТЗ.Найти(Номенклатура, "Номенклатура");
Если Строка = Неопределено Тогда
Строка = ТЗ.Добавить();
Строка.Номенклатура = Номенклатура;
КонецЕсли;
Строка.Количество = Строка.Количество + Количество;
ЗначениеВДанныеФормы(ТЗ, Корзина);
КонецПроцедуры // ДобавитьВПодбор()

Теперь корзина у нас заполняется выбранной номенклатурой и количеством. Остается организовать передачу корзины в вызывающий документ. Добавляем команду формы ПеренестиВДокумент, перетаскиваем ее на форму, получаем связанную с командой кнопку. Создаем обработчик команды. Поскольку форму мы изначально создавали как форму списка, а не форму выбора, нам придется принудительно оповестить вызывающую форму о том, что выбор завершен:

&НаКлиенте
Процедура ПеренестиВДокумент(Команда)
Результат = Новый Структура;
Результат.Вставить("Корзина", Корзина);
ОповеститьОВыборе(Результат);
КонецПроцедуры

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

По нажатию на кнопку Подбор вызываем созданную форму и передаем параметры. Обращаю внимание на обязательную передачу в открываемую форму параметра ЭтаФорма (третий параметр в вызове формы, форма-владелец). Если этот параметр не передать, то событие ОбработкаПодбора() не возникнет в контесте формы вызывающего документа.

&НаКлиенте
Процедура Подбор(Команда)
ДатаПодбора = ?(ЗначениеЗаполнено(Объект.Ссылка), Объект.Дата, '00010101');
ПараметрыПодбора = Новый Структура;
ПараметрыПодбора.Вставить("Дата", ДатаПодбора);
ПараметрыПодбора.Вставить("ТипЦен", Объект.ТипЦен);
ФормаВыбора = ОткрытьФорму("Справочник.Номенклатура.Форма.ФормаПодбора", ПараметрыПодбора, ЭтаФорма);
КонецПроцедуры

Ну и, собственно, то, ради чего все затевалось — разбираем «корзину» и добавляем новые строки в табличную часть Товары нашего документа. На всякий случай, не забываем, что Корзина у нас не настоящая ТЗ, а служебная коллекция ДанныеФормыКоллекция:

&НаКлиенте
Процедура ОбработкаВыбора(ВыбранноеЗначение, ИсточникВыбора)
Если ТипЗнч(ВыбранноеЗначение) = Тип("Структура") Тогда
Если ВыбранноеЗначение.Свойство("Корзина") Тогда
Для каждого Элемент Из ВыбранноеЗначение.Корзина Цикл
Элементы.Товары.ДобавитьСтроку();
ТД = Элементы.Товары.ТекущиеДанные;
ТД.Номенклатура = Элемент.Номенклатура;
ТД.Количество = Элемент.Количество;
КонецЦикла;
КонецЕсли;
КонецЕсли;
КонецПроцедуры

Подбор в работе

Вот и все. Надеюсь, моя скромная заметка кому-то поможет побыстрее разобраться с динамическими списками и управляемыми формами.

Добавить комментарий