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

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

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

Различие между элементом формы и реквизитом формы

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

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


// ОШИБОЧНЫЙ ПОДХОД
Область = Элементы.Результат.Область(1, 1); // Вызовет ошибку, так как у элемента нет метода Область()

Для корректной работы мы должны обращаться напрямую к реквизиту формы. Если ваш реквизит называется ТаблицаЦен, то и работать нужно именно с ним, как на клиенте, так и на сервере.

Чтение данных на стороне клиента

Многие полагают, что работа с содержимым ячеек возможна только на сервере. Однако метод Область() прекрасно работает и на клиенте. Это позволяет нам оперативно реагировать на действия пользователя. Рассмотрим пример получения значения из текущей активной ячейки:


&НаКлиенте
Процедура ОбработатьТекущуюЯчейку()
    
    // Обращаемся к реквизиту формы напрямую
    ТекущаяОбласть = ТаблицаЦеныНоменклатуры.ТекущаяОбласть;   
    
    // Получаем координаты
    НомерСтроки = ТекущаяОбласть.Верх; 
    НомерКолонки = ТекущаяОбласть.Лево;
    
    // Читаем текст, который видит пользователь
    ТекстЯчейки = ТекущаяОбласть.Текст;
    
    // Если в ячейке хранятся данные (например, ссылка на справочник)
    Если ТекущаяОбласть.СодержитЗначение Тогда
        ЗначениеЯчейки = ТекущаяОбласть.Значение;
    КонецЕсли;

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

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

Передача табличного документа на сервер

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

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


&НаКлиенте
Процедура ЗагрузитьДанныеНаСервер()
    // Вызываем серверный метод и передаем наш документ
    ОбработатьДокументНаСервере(ТаблицаЦеныНоменклатуры);
КонецПроцедуры

&НаСервереБезКонтекста
Процедура ОбработатьДокументНаСервере(Знач ТабДок)
    // Здесь мы можем обходить строки и колонки
    Для НомерСтроки = 1 По ТабДок.ВысотаТаблицы Цикл
        // Обработка данных
    КонецЦикла;
КонецПроцедуры

Преобразование табличного документа в Таблицу Значений

Иногда удобнее работать не с ячейками, а с привычной ТаблицейЗначений. Существует "хитрый" и эффективный способ сделать это с помощью ПостроителяОтчета (или ПостроителяЗапроса в некоторых контекстах) — так работает импорт данных из Excel через штатный механизм 1С. Этот метод позволяет мгновенно конвертировать визуальную область в структуру данных.

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

  1. Определяем границы заполненной области с помощью свойств ВысотаТаблицы и ШиринаТаблицы.
  2. Получаем нужную область ячеек.
  3. Используем объект ОписаниеИсточникаДанных.
  4. Выгружаем результат в таблицу значений.

&НаСервере
Функция ПреобразоватьТабДокВТЗ(ТабДок)
    
    ПоследняяСтрока = ТабДок.ВысотаТаблицы;
    ПоследняяКолонка = ТабДок.ШиринаТаблицы;
    
    // Выбираем всю заполненную область
    ОбластьЯчеек = ТабДок.Область(1, 1, ПоследняяСтрока, ПоследняяКолонка);
    
    ИсточникДанных = Новый ОписаниеИсточникаДанных(ОбластьЯчеек);
    Построитель = Новый ПостроительОтчета;
    Построитель.ИсточникДанных = ИсточникДанных;
    
    // Построитель проанализирует данные и создаст структуру колонок
    Построитель.Выполнить();
    
    Возврат Построитель.Результат.Выгрузить();
    
КонецФункции

Важное замечание: При использовании этого метода 1С попытается определить заголовки колонок по первой строке области. Если ваши данные начинаются сразу с первой строки без "шапки", это стоит учитывать при дальнейшей обработке ТЗ.

Оптимизация и производительность

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

В таких случаях рекомендуется:

Обработка пользовательского ввода

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

При копировании данных из Excel помните, что 1С интерпретирует данные в зависимости от региональных настроек — задачу решит универсальная загрузка из Excel в любые документы. Если пользователь копирует число с точкой в качестве разделителя, а в системе установлена запятая, автоматическое получение Значение может не сработать. В таких случаях надежнее считывать Текст и обрабатывать его функцией Число(), предварительно удалив лишние пробелы и заменив точки на запятые.

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

← На главную