Как обратиться к реквизиту формы (Таблице Значений) на клиенте и найти строку в 1С?

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

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

Проанализируем суть проблемы и типы данных

Посмотрим на типичный сценарий. Мы добавляем на управляемую форму реквизит с типом ТаблицаЗначений, заполняем его данными, а затем на клиенте пытаемся выполнить поиск строки, обращаясь к нему так: ЭтотОбъект["ТЗ"].Найти(). И тут же получаем ошибку.

Чтобы понять причину, давайте разберем, как платформа 1С:Предприятие 8.3 работает с данными в парадигме клиент-серверного взаимодействия. Полноценный объект ТаблицаЗначений доступен исключительно в серверном контексте. Это сложный, тяжелый объект, который поддерживает индексирование колонок, сложные алгоритмы свертки, сортировки и поиска. Тонкий и веб-клиент не предназначены для работы с такими тяжелыми объектами памяти.

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

Разберем терминологию: Элемент, Реквизит и Объект

Чтобы не путаться в дальнейшем, давайте четко структурируем понятия, с которыми мы работаем на управляемой форме:

  1. Элемент формы — это визуальный компонент, который мы перетащили в дерево элементов формы (например, табличное поле). К нему мы обращаемся через Элементы.ИмяТаблицы. Здесь мы управляем исключительно визуальными свойствами: видимостью, доступностью, цветом фона. Данных здесь нет.
  2. Реквизит формы — это данные, созданные на вкладке "Реквизиты". Обращаться к ним можно напрямую по имени или через ЭтотОбъект.ИмяРеквизита. Именно здесь хранятся наши строки, но на клиенте они представлены типом ДанныеФормыКоллекция.
  3. Реквизит объекта — это данные, добавленные в структуру самой конфигурации (в справочник, документ). На форме к ним обращаются через Объект.ИмяРеквизита, и это тоже будет тип ДанныеФормыКоллекция на клиенте.

Способ 1: Решение проблемы поиска на клиенте

Если нам нужно найти строку на клиенте, и таблица небольшая, мы можем воспользоваться методом НайтиСтроки. В отличие от метода Найти, этот метод поддерживается типом ДанныеФормыКоллекция в клиентском контексте.

Рассмотрим пример того, как правильно организовать такой поиск:


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

КонецПроцедуры

Важно помнить о скрытых механизмах платформы. Платформа передает строки объекта ДанныеФормыКоллекция между сервером и клиентом порциями. Новые данные подгружаются в фоновом режиме по мере того, как мы скроллим таблицу или обращаемся к строкам программно. Поэтому использование метода НайтиСтроки на клиенте оправдано только для маленьких таблиц (по стандартам 1С — не более 20 строк). При большом объеме данных такой поиск вызовет множественные неявные серверные вызовы и сильно затормозит интерфейс.

Способ 2: Перенос логики на сервер (Рекомендуемый подход)

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

Разберем по шагам, как это реализовать:


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

КонецПроцедуры

&НаСервере
Функция НайтиСтрокуНаСервере(ИскомоеЗначение)
    
    // 1. Конвертируем коллекцию формы в полноценную Таблицу Значений
    ПолноценнаяТЗ = РеквизитФормыВЗначение("ТЗ");
    
    // 2. Теперь нам доступен быстрый серверный метод Найти
    НайденнаяСтрока = ПолноценнаяТЗ.Найти(ИскомоеЗначение, "ИмяКолонки");
    
    Если НайденнаяСтрока <> Неопределено Тогда
        // 3. Возвращаем на клиент только нужные данные через Структуру
        Результат = Новый Структура;
        Результат.Вставить("ДополнительнаяИнфо", НайденнаяСтрока.ДополнительнаяИнфо);
        Возврат Результат;
    КонецЕсли;
    
    Возврат Неопределено;

КонецФункции

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

Способ 3: Альтернатива для передачи данных без привязки к форме

Иногда нам вообще не нужно визуализировать таблицу. Если задача заключается просто в передаче табличных данных с сервера на клиент для алгоритмической обработки (например, для цикличного обхода), мы можем использовать стандарт де-факто — преобразование серверной ТаблицаЗначений в массив структур.

Посмотрим на пример такого алгоритма:


&НаСервере
Функция ПолучитьТаблицуДляКлиента()
    
    ТЗ = Новый ТаблицаЗначений;
    // ... заполнение таблицы на сервере ...
    
    МассивДанных = Новый Массив;
    Для Каждого СтрокаТЗ Из ТЗ Цикл
        СтруктураСтроки = Новый Структура("Колонка1, Колонка2");
        ЗаполнитьЗначенияСвойств(СтруктураСтроки, СтрокаТЗ);
        МассивДанных.Добавить(СтруктураСтроки);
    КонецЦикла;
    
    Возврат МассивДанных;
    
КонецФункции

Такая коллекция (массив структур) является "родной" для универсального клиент-серверного взаимодействия и отлично работает в тонком клиенте без привязки к объекту ДанныеФормыКоллекция.

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

← На главную