Как получить ссылку и данные из текущей и выделенных строк динамического списка в управляемых формах 1С?

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

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

Особенности работы с данными текущей строки динамического списка (включая программное перемещение колонок)

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

  1. Добавление поля "Ссылка" в динамический список: Прежде всего, для корректной работы с ссылками, нам необходимо убедиться, что в запросе вашего динамического списка присутствует поле, которое является ссылкой на основной объект (доработка динамического списка может быть выполнена несколькими способами). Обычно это поле называется Ссылка. Мы должны добавить его в состав полей динамического списка.

  2. Флаг "Использовать всегда": Если поле Ссылка не нужно отображать на форме, но требуется программный доступ к нему, установите для этого поля флаг "Использовать всегда" в свойствах реквизита формы, который связан с динамическим списком. Это гарантирует, что поле будет загружено, даже если оно невидимо.

  3. Методы получения текущей строки:

    • Метод Элементы.Оплаты.ТекущаяСтрока возвращает идентификатор текущей строки (это актуально, когда используются главная и подчиненная таблицы). Это числовой идентификатор, а не ссылка на объект.

    • Метод Элементы.Оплаты.ТекущиеДанные возвращает объект, содержащий данные текущей строки. Если в динамическом списке установлена основная таблица и добавлены поля, этот объект будет содержать все доступные поля, включая поле Ссылка.

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

Клиент-серверное взаимодействие при работе со ссылками

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

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


// Пример серверной функции для получения значения реквизита по ссылке
&НаСервереБезКонтекста
Функция ПолучитьЗначениеСсылки(Ссылка, ИмяРеквизита)
    Попытка
        Возврат Ссылка[ИмяРеквизита];
    Исключение
        Возврат Неопределено;
    КонецПопытки;
КонецФункции

// Пример вызова этой функции с клиента
&НаКлиенте
Процедура ПриИзмененииТекущейСтроки(Элемент)
    ТекущиеДанныеСтроки = Элементы.Оплаты.ТекущиеДанные;
    Если ТекущиеДанныеСтроки <> Неопределено Тогда
        СсылкаДокумента = ТекущиеДанныеСтроки.Ссылка;
        // Переходим на сервер, чтобы получить наименование документа по ссылке
        НаименованиеДокумента = ПолучитьЗначениеСсылки(СсылкаДокумента, "Наименование");
        Если НаименованиеДокумента <> Неопределено Тогда
            Сообщить("Наименование текущего документа: " + НаименованиеДокумента);
        КонецЕсли;
    КонецЕсли;
КонецПроцедуры

Работа с выделенными строками (метод "ВыделенныеСтроки")

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

Использование метода "НайтиПоИдентификатору"

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


&НаКлиенте
Процедура ОбработатьВыделенныеСтрокиПоИдентификатору(Команда)
    // Предполагаем, что "Оплаты" - это имя реквизита формы, 
    // связанного с динамическим списком или таблицей
    Если ТипЗнч(Оплаты) = Тип("ДинамическийСписок") Тогда
        Для Каждого ТекущаяВыделеннаяСтрокаИД Из Элементы.Оплаты.ВыделенныеСтроки Цикл
            ТекущиеДанныеСИдентификатора = Оплаты.НайтиПоИдентификатору(ТекущаяВыделеннаяСтрокаИД);
            Если ТекущиеДанныеСИдентификатора <> Неопределено Тогда
                // Здесь ТекущиеДанныеСИдентификатора - это объект, содержащий поля строки, 
                // включая Ссылка, если она добавлена в ДС
                СсылкаОбъекта = ТекущиеДанныеСИдентификатора.Ссылка;
                Сообщить("Выделена строка с ссылкой: " + СсылкаОбъекта);
                // Если нужно получить реквизит ссылки, обращаемся на сервер:
                // Наименование = ПолучитьЗначениеСсылки(СсылкаОбъекта, "Наименование");
            КонецЕсли;
        КонецЦикла;
    Иначе
        Сообщить("Реквизит 'Оплаты' не является динамическим списком.");
    КонецЕсли;
КонецПроцедуры

Важное замечание: Мы должны быть осторожными с методом НайтиПоИдентификатору(). Идентификаторы строк могут быть нестабильными и меняться после обновления данных в таблице (например, при повторном открытии формы или программном обновлении динамического списка). Это может привести к тому, что по старому идентификатору будет найдена не та строка, или строка не будет найдена вообще.

Использование метода "ДанныеСтроки" (Рекомендуемый способ)

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


&НаКлиенте
Процедура ОбработатьВыделенныеСтроки(Команда)
    // Элементы.Оплаты - это элемент формы Таблица, связанный с динамическим списком
    ВыделенныеСтрокиИдентификаторы = Элементы.Оплаты.ВыделенныеСтроки;

    Если ВыделенныеСтрокиИдентификаторы.Количество() > 0 Тогда
        Для Каждого ИдентификаторСтроки ИЗ ВыделенныеСтрокиИдентификаторы Цикл
            // Получаем объект, содержащий данные текущей выделенной строки
            ДанныеВыделеннойСтроки = Элементы.Оплаты.ДанныеСтроки(ИдентификаторСтроки);

            Если ДанныеВыделеннойСтроки <> Неопределено Тогда
                // Предполагаем, что в динамическом списке есть поле "Ссылка"
                СсылкаОбъекта = ДанныеВыделеннойСтроки.Ссылка;

                Сообщить("Обрабатываем выделенную строку. Ссылка: " + СсылкаОбъекта);

                // Если нужно получить реквизиты ссылки, обращаемся на сервер
                // Например, получим наименование, используя серверную функцию:
                НаименованиеОбъекта = ПолучитьЗначениеСсылки(СсылкаОбъекта, "Наименование");
                Если НаименованиеОбъекта <> Неопределено Тогда
                    Сообщить("Наименование объекта: " + НаименованиеОбъекта);
                КонецЕсли;

                // Продолжаем работу с ДанныеВыделеннойСтроки или СсылкаОбъекта
            КонецЕсли;
        КонецЦикла;
    Иначе
        Предупреждение("Не выбрано ни одной строки.");
    КонецЕсли;
КонецПроцедуры

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

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

Подводя итоги, для эффективной работы с данными и ссылками в управляемых формах 1С мы рекомендуем следующий подход:

  1. Всегда включайте поле Ссылка в запрос вашего динамического списка.
  2. Для невидимых, но программно используемых полей, устанавливайте флаг "Использовать всегда".
  3. Для получения данных текущей строки используйте Элементы.Таблица.ТекущиеДанные.
  4. Для получения данных выделенных строк перебирайте массив Элементы.Таблица.ВыделенныеСтроки и для каждого идентификатора используйте метод Элементы.Таблица.ДанныеСтроки(ИдентификаторСтроки) для получения объекта данных. Этот метод предпочтительнее, чем НайтиПоИдентификатору, из-за стабильности.
  5. При необходимости доступа к реквизитам ссылочных типов или выполнения других операций с объектами базы данных, всегда переходите на сервер, используя функции с директивой &НаСервереБезКонтекста.

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

← На главную