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

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

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

Различие между Таблицей формы и Данными формы

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

Разберем основные ошибки при обращении к этим объектам:

  1. Обращение через Элементы: Если мы пишем Элементы.ТабКлиенты, мы обращаемся к объекту типа ТаблицаФормы. Это визуальный элемент. У него есть свойства Видимость, Доступность, но у него нет метода Выгрузить(). Попытка вызвать его приведет к ошибке.
  2. Тип ДанныеФормыКоллекция: Сам реквизит ТабКлиенты на сервере имеет тип ДанныеФормыКоллекция. У этого типа есть метод Выгрузить(), но он возвращает объект ТаблицаЗначений. Важно помнить, что у ДанныеФормыКоллекция нет метода ВыгрузитьКолонку().

Как выгрузить колонку в массив

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

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


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

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

Загрузка данных запроса в таблицу формы

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

Разберем некорректный пример кода:


// ОШИБОЧНЫЙ КОД
Для каждого СТР из ТЗ Цикл
    ТабКлиенты.ДатаАктивности = ТЗ.Дата; // Ошибка! Нельзя присваивать значение всей таблице
КонецЦикла;

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

Правильный вариант обхода коллекции выглядит так:


&НаСервере
Процедура ОбновитьДатыАктивности(РезультатЗапроса)
    ТЗРезультат = РезультатЗапроса.Выгрузить();
    
    // Предположим, количество строк в ТабКлиенты совпадает с ТЗРезультат
    Для Индекс = 0 По ТабКлиенты.Количество() - 1 Цикл
        СтрокаФормы = ТабКлиенты[Индекс];
        СтрокаРезультата = ТЗРезультат[Индекс];
        СтрокаФормы.ДатаАктивности = СтрокаРезультата.Дата;
    КонецЦикла;
КонецПроцедуры

Оптимальный способ заполнения колонки (ЗаполнитьЗначения)

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

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


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

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

Краткие итоги и правила работы

Для успешной работы с таблицами на управляемых формах придерживайтесь следующих правил:

Разбирая эти ситуации по шагам, мы видим, что работа с данными в 1С требует четкого понимания того, в каком контексте (Клиент или Сервер) и с каким типом объекта мы взаимодействуем в данный момент.

← На главную