Динамический список, ключи записей. Нюансы

07.08.20

Разработка - Механизмы платформы 1С

Заметки об особенностях динамических списков с произвольным запросом и видом ключа, отличным от "Авто"

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

Ситуация изменилась в релизе 8.3.14, где платформа стала поддерживать разные варианты ключей при работе с ДС, в т.ч. для произвольных запросов без основной таблицы. Это хорошо описано в Зазеркалье и на других ресурсах. Мы получили удобный инструмент решения коллизий дублирования ключевых полей, оптимизацию, прозрачность и управляемость (хотя бы фактом кэширования). Поведение системы в целом осталось тем же - контроль реальной уникальности ключа, каким бы он ни был, поддержка возможностей ДС, клиент-серверное взаимодействие и т.д., и при этом интерактивное добавление, удаление, открытие; т.е. то, что раньше было возможно лишь при наличии основной таблицы.

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

 

 
 Если основной таблицы нет

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

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

Также, неработоспособен параметр формы "ТекущаяСтрока". Он автодобавляется при указании ДС, с любым видом ключа, как основного реквизита формы (что видно в подсказке при наборе кода), и поддерживает все возможные содержания при видах ключей, и передаётся, и читается программно, но свою основную задачу - позиционирование, особенно при открытии - не выполняет, игнорируется.

 

Есть особенности в поведении произвольных запросов с разными ключами, рассмотрим их на примере общеизвестных функций получения СКД и настроек ДС (например, описано тут). В качестве задачи возьмём, например, эмуляцию возможностей свойства "ТекущиеДанные" (доступного, в отличие от "ТекущаяСтрока", лишь на клиенте), на сервере.

 
 
 Вид ключа "Авто"

Может указываться и для произвольного запроса без основной таблицы. При этом поле значения ключа сам не очищает и не проверяет.

Если указана основная таблица, то вид ключа "Авто", а поля ключа - пустой фиксированный массив. Вроде бы всё по умолчанию. Но при этом возможна ситуация, когда поле "Ссылка" есть в Наборе, в доступных к выбору и выбранных полях настройки СКД по умолчанию, и в Выбор текущей настройки СКД, но даже при плоской детализации структуры (взятой по умолчанию) его нет в результатной выборке-таблице. Во всех прочих вариантах ключей эффект не наблюдается, поле есть. От флага "ИспользоватьВсегда" этот эффект не зависит.

Если для произвольного запроса указана основная таблица, ПоляКлюча не то что бы недоступны, а именно "не используются" (с) СП. Замечено, что поведение при обращении к полям ключа может разниться для толстого и тонкого клиентов.

Вообще, "ПоляКлюча" согласно СП это "СписокПолей" (для ВводПоСтроке и ПоляКлюча внешних источников), но, в отличие от указанного в СП, т.е., цитирую, "В качестве полей ввода по строке могут выступать такие предопределенные реквизиты, как "Код", "Наименование", "Дата", "Номер" и реквизиты объектов, имеющие примитивный тип данных, для которых свойство объекта метаданных "Индексировать" принимает значение "Индексирование" или "Индексировать с доп. упорядочиванием"." - тут выбор доступных к указанию как поля ввода явно больше - и не только примитивные типы и предопределённые значения. Программно это подтверждается, поэтому и внимания к типизации полей СКД надо больше. Особенно, как всегда, аккуратнее с определяемыми типами, характеристиками, хранилищами, неогр.строками итд.

 

 Вид ключа "Значение поля"

Даёт на выбор в значениях ключа всё, все поля выборки запроса, кроме "ВерсияДанных".
ПоляКлюча - фиксированный массив строк (всегда строго один элемент), где строки это имена полей (опять же, не следует применять разыменования от полей выборки "первого уровня", даже если конструктор ДС это скушал) 
ТекущаяСтрока - текущее значение поля нужного типа.

 

 
 Вид ключа "Ключ строки"

Даёт на выбор вообще всё, любые поля. Явных ограничений ни по типам, ни по составу, ни по разыменованию нет. Но, полагаю, с разыменованиями тоже не следует связываться - опять же, любое поле "через точку" как неявное соединение с другими таблицами негативно скажется на производительности. 
ПоляКлюча - фиксированный массив (возможны N элементов), каждый из элементов это строка с именем поля ключа.
ТекущаяСтрока - КлючСтрокиДинамическогоСписка - коллекция из "КлючИЗначение", причём значения - нужных типов и, если был многотипный, значение уже строго одного типа, типа реального наполнения.

 

 
 Вид ключа "Номер строки"

Выбор настройки ПолеКлюча недоступен, в т.ч. программно; платформа нумерует строки выборки сама. Причём, как показали замеры, это делается на клиенте.
ПоляКлюча - пустой фикированный массив.
ТекущаяСтрока - число (нумерация с 1), причём это не свойство строки как объекта данных, это свойство текущей позиции исключительно при текущем сеансе показе (вывода порции данных на экран), т.е. сортировка по колонке и прочие манипуляции на идентификации не сказываются - всегда идёт по натуральному ряду, и под неким номером каждый раз могут оказываться разные строки выборки.

 

 
 Общее

Для всех случаев ключей нельзя использовать поля, могущие иметь значения "Неопределено" и "Null", даже потенциально. Тут платформу одолевает паранойя даже при очевидных разыменованиях и составных типах. Многотипные, в общем случае, допустимы, в т.ч. смешанные из простых и ссылочных типов.

Если ДС сгруппирован, т.е. Группировки применены, то "ТекущаяСтрока" возвращает значение типа "СтрокаГруппировкиДинамическогоСписка", и её Ключ - значение ТекущиеДанные[ТекущаяКолонока] того поля группировки, где стоит активный курсор.

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

Во всех режимах одинаково полные возможности Отбора, Порядка, Условного оформления. В режиме "НомерСтроки" отсутствует возможность Группировок; при этом возвращаемый ПолучитьОграниченияИспользованияВГруппировке() массив пуст.

Поведение самой СКД также имеет особенности. Для набора (типа "Набор запроса") стоит автозаполнение, но его Поля пусты, и поля Выбор и ДоступныеДляВыбора пусты; пусто и в СКД.НастройкиПоУмолчанию, и в основном варианте настройки. Актуальны и приоритетны именно исполняемые настройки: в Выборе пусто, а в Доступных для выбора - все нужные поля есть и корректно объявлены. Даже для вида ключа "Номер строки" в "ДоступныеПоляГруппировок" есть все поля выборки; в структуре запись детальной группировки (без групп.полей), в её выбранных - все поля выборки.

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

Получение ограничений использования (в отборе, в сортировке, в группировках) совершенно ничем не отличается от "Авто" и интереса не представляет.

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

 

И собственно функция, реализующая демонстрационную задачу

 
 Получение текущих данных на сервере для разных видов ключей

 

Важно: при программной работе со свойствами ДС интерпретатор платформы не проверяет правильность и взаимную связность настроек (это делает только интерфейс настройки ДС), т.е. например "ВидКлюча" не "Авто", и принудительно указывается свойство "ОсновнаяТаблица"; конфликт может вылезти только при исполнении - при первом обращении ДС к данным БД. В лучшем случае это будет ругательный MsgBox, в худшем - захват всей таблицы, которая основная, и повисание сеанса. Следует быть внимательным, а на релизах ниже 8.3.15 вообще лучше не трогать в коде эти свойства.

 

Открытым остаётся вопрос о порции считывания. При установленном флаге "Динамическое считывание данных" (доступном только при указанной основной таблице произвольного запроса, т.е. только в режиме "Авто") платформа читает от 45 до 70 записей таблицы (насколько я понял, в зависимости от постраничной разбивки читаемых таблиц СУБД). А вот различается ли размер порции при других видах ключей и кэшируются ли они промежуточно по внутренним ID либо перестраиваются и перечитываются каждый раз - тема отдельного исследования. Заявленный размер порции в 1000 записей на практике соблюдается не всегда, поэтому, по-хорошему, изучить бы надо и степень горячести запроса/прогретости кэша, и способ (курсор или через темпы), и тот же пейджинг, и всё это в связке с принципом построения итогового внутреннего хеш-ключа. Словом, простор для исследований.
 

Функция создавалась на релизе 8.3.16.1224

 

динамический список вид ключа произвольный запрос СКД ТекущиеДанные на сервере

См. также

Сервисы интеграции без Шины и интеграции

Механизмы платформы 1С Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

Пример использования «Сервисов интеграции» без подключения к Шине и без обменов.

13.03.2024    2627    dsdred    16    

59

Поинтегрируем: сервисы интеграции – новый стандарт или просто коннектор?

Обмен между базами 1C Администрирование СУБД Механизмы платформы 1С Платформа 1С v8.3 Бесплатно (free)

В платформе 8.3.17 появился замечательный механизм «Сервисы интеграции». Многие считают, что это просто коннектор 1С:Шины. Так ли это?

11.03.2024    6077    dsdred    59    

86

Как готовить и есть массивы

Механизмы платформы 1С Платформа 1С v8.3 Бесплатно (free)

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

24.01.2024    5979    YA_418728146    25    

68

Планы обмена VS История данных

Обмен между базами 1C Механизмы платформы 1С Платформа 1С v8.3 Бесплатно (free)

Вы все еще регистрируете изменения только на Планах обмена и Регистрах сведений?

11.12.2023    7075    dsdred    36    

113

1С-ная магия

Механизмы платформы 1С Бесплатно (free)

Язык программирования 1С содержит много нюансов и особенностей, которые могут приводить к неожиданным для разработчика результатам. Сталкиваясь с ними, программист начинает лучше понимать логику платформы, а значит, быстрее выявлять ошибки и видеть потенциальные узкие места своего кода там, где позже можно было бы ещё долго медитировать с отладчиком в поисках источника проблемы. Мы рассмотрим разные примеры поведения кода 1С. Разберём результаты выполнения и ответим на вопросы «Почему?», «Как же так?» и «Зачем нам это знать?». 

06.10.2023    19185    SeiOkami    46    

118

Дефрагментация и реиндексация после перехода на платформу 8.3.22

Механизмы платформы 1С Платформа 1С v8.3 Бесплатно (free)

Начиная с версии платформы 8.3.22 1С снимает стандартные блокировки БД на уровне страниц. Делаем рабочий скрипт, как раньше.

14.09.2023    12903    human_new    27    

76

Валидация JSON через XDTO (включая массивы)

WEB-интеграция Универсальные функции Механизмы платформы 1С Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

При работе с интеграциями рано или поздно придется столкнуться с получением JSON файлов. И, конечно же, жизнь заставит проверять файлы перед тем, как записывать данные в БД.

28.08.2023    9511    YA_418728146    6    

143

Внешние компоненты Native API на языке Rust - Просто!

Механизмы платформы 1С Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

Внешние компоненты для 1С можно разработывать очень просто, пользуясь всеми преимуществами языка Rust - от безопасности и кроссплатформенности до удобного менеджера библиотек.

20.08.2023    6564    sebekerga    54    

95
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. tormozit 7143 07.08.20 18:57 Сейчас в теме
поведение при обращении к полям ключа может разниться для толстого и тонкого клиентов

Можно подробнее?
2. Yashazz 4725 07.08.20 19:17 Сейчас в теме
(1) а, да очень просто. Наблюдалось на 8.3.14 и 15, выглядело так - толстый падал по критической ошибке, а тонкий говорил, что-де в таком режиме работу с ПоляКлюча не поддерживает - и интерфейсно, и в ОписаниеОшибки.
3. terver 3 28.08.20 05:15 Сейчас в теме
//
	рТаблица=Новый ДеревоЗначений;
	рТаблица=Новый ТаблицаЗначений;


Что то здесь лишнее или указано для примера?
4. Yashazz 4725 28.08.20 07:00 Сейчас в теме
(3) Лишнее про Дерево. Не убрал, извиняюсь. Спасибо.
5. KilloN 58 28.01.21 15:39 Сейчас в теме
Сделал простой динамический список из 2 таблиц Номенклатура и Характеристика. Установил ключ строки "Номенклатура, Характеристика" + указал динамическое считывание данных. Все зависло. Динамическое считывание видимо не работает
6. Yashazz 4725 29.01.21 10:12 Сейчас в теме
(5) Конкретику смотреть надо. Ну и от релиза может зависеть, если это 18-й, то вообще не удивлюсь, кривой как хз что.
Оставьте свое сообщение