Как программно установить текущую строку в динамическом списке с произвольным запросом без основной таблицы

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

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

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

Разбор проблемы: почему ТекущаяСтрока не принимает привычные значения

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

Шаг 1: Настройка ключевых полей в Конструкторе

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

  1. Откроем форму, на которой расположен наш динамический список.
  2. Перейдем в свойства реквизита (не элемента формы, а именно реквизита с типом ДинамическийСписок).
  3. Нажмем на ссылку «Настройка списка» или откроем конструктор запроса.
  4. Под полем выбора основной таблицы найдем раздел, отвечающий за ключевые поля.
  5. В параметрической настройке выберем ВидКлюча — «Ключевые поля».
  6. В появившемся списке отметим галочками те поля, которые в совокупности обеспечивают уникальность строки. Например, если наш запрос выводит данные по контрагентам и их договорам, ключевым полем может быть Договор или комбинация Контрагент + НомерДоговора.

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

Шаг 2: Программная установка строки через КлючСтрокиДинамическогоСписка

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

Если ключевое поле всего одно, мы можем передать его значение напрямую. Однако правильнее и универсальнее использовать специальный конструктор. Рассмотрим пример ситуации, когда ключевыми полями назначены СтрокаИдентификатор и ЧисловойКод.


// Создаем структуру, где имена ключей совпадают с именами ключевых полей в списке
ПараметрыКлюча = Новый Структура;
ПараметрыКлюча.Вставить("Строка", "НужноеЗначение");
ПараметрыКлюча.Вставить("Число", 123);

// Формируем объект ключа
НужныйКлюч = Новый КлючСтрокиДинамическогоСписка(ПараметрыКлюча);

// Устанавливаем текущую строку в элементе формы
Элементы.Список.ТекущаяСтрока = НужныйКлюч;

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

Шаг 3: Обеспечение видимости строки пользователю

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


// Устанавливаем фокус
Элементы.Список.ТекущаяСтрока = НужныйКлюч;

// Принудительно прокручиваем список к этой строке
Элементы.Список.ОтобразитьСтроку(НужныйКлюч);

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

Особенности работы с методом Обновить() и серверными вызовами

Разберем ситуацию, которая часто сбивает с толку начинающих разработчиков. Если вы вызываете Элементы.Список.Обновить() и сразу за ним пытаетесь установить ТекущаяСтрока, это может не сработать. Причина в том, что обновление данных в динамическом списке происходит асинхронно на клиенте после получения данных с сервера.

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

Получение ключа существующей строки

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


ДанныеСтроки = Элементы.Список.ДанныеСтроки(Элементы.Список.ТекущаяСтрока);
Если ДанныеСтроки <> Неопределено Тогда
    // Теперь мы можем обратиться к любому полю строки, даже не ключевому
    Сообщить(ДанныеСтроки.Строка);
КонецЕсли;

Важно помнить, что метод ДанныеСтроки() возвращает данные только в том случае, если строка физически загружена в кэш клиента. Если вы пытаетесь программно получить данные строки, которая находится далеко за пределами видимости, метод может вернуть Неопределено.

Резюме и рекомендации

Подводя итог, можно выделить основные правила работы с динамическими списками на основе произвольных запросов:

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

← На главную