Работа с табличным документом на управляемых формах часто вызывает вопросы у разработчиков (поможет инструмент для автоматического перевода печатных форм), особенно когда речь заходит о получении данных, введенных пользователем вручную или скопированных из внешних источников, таких как Excel. В этой статье мы подробно разберем, как правильно обращаться к данным табличного документа, какие методы использовать на клиенте и сервере, а также разберем типичные ошибки, которые могут возникнуть в процессе разработки.
Первое и самое важное, что нам необходимо усвоить при работе в среде управляемого приложения, — это различие между Элементом формы (визуальным представлением) и Реквизитом формы (самим объектом данных). Проанализируем ситуацию: когда вы добавляете на форму поле табличного документа, в списке реквизитов у вас появляется переменная с типом ТабличныйДокумент, а в дереве элементов — соответствующий визуальный компонент.
Типичная ошибка, которую совершают разработчики (и с которой столкнулся автор темы), заключается в попытке вызвать методы обработки данных у элемента формы — для отладки таких алгоритмов есть консоль для написания и отладки кода 1С. Рассмотрим пример:
// ОШИБОЧНЫЙ ПОДХОД
Область = Элементы.Результат.Область(1, 1); // Вызовет ошибку, так как у элемента нет метода Область()
Для корректной работы мы должны обращаться напрямую к реквизиту формы. Если ваш реквизит называется ТаблицаЦен, то и работать нужно именно с ним, как на клиенте, так и на сервере.
Многие полагают, что работа с содержимым ячеек возможна только на сервере. Однако метод Область() прекрасно работает и на клиенте. Это позволяет нам оперативно реагировать на действия пользователя. Рассмотрим пример получения значения из текущей активной ячейки:
&НаКлиенте
Процедура ОбработатьТекущуюЯчейку()
// Обращаемся к реквизиту формы напрямую
ТекущаяОбласть = ТаблицаЦеныНоменклатуры.ТекущаяОбласть;
// Получаем координаты
НомерСтроки = ТекущаяОбласть.Верх;
НомерКолонки = ТекущаяОбласть.Лево;
// Читаем текст, который видит пользователь
ТекстЯчейки = ТекущаяОбласть.Текст;
// Если в ячейке хранятся данные (например, ссылка на справочник)
Если ТекущаяОбласть.СодержитЗначение Тогда
ЗначениеЯчейки = ТекущаяОбласть.Значение;
КонецЕсли;
КонецПроцедуры
Разберем подробнее разницу между свойствами Текст и Значение. Свойство Текст возвращает строковое представление того, что отображается на экране (с учетом всех форматов и разделителей). Свойство Значение доступно только если для ячейки включена опция "Содержит значение", и оно возвращает типизированные данные (число, дату или ссылку).
Если нам необходимо произвести сложную обработку данных, например, записать их в базу данных или провести через запрос, нам потребуется серверный контекст. В управляемых формах ТабличныйДокумент является сериализуемым объектом, поэтому его можно передавать в серверные процедуры напрямую как параметр.
Выясним причину, почему иногда не работает ПоместитьВоВременноеХранилище. Как мы уже выяснили, нельзя поместить в хранилище Элемент формы. Но сам реквизит (объект ТабличныйДокумент) поместить можно. Однако в большинстве случаев это избыточно, так как реквизиты формы и так доступны в серверных процедурах &НаСервере или могут быть переданы в функции &НаСервереБезКонтекста.
&НаКлиенте
Процедура ЗагрузитьДанныеНаСервер()
// Вызываем серверный метод и передаем наш документ
ОбработатьДокументНаСервере(ТаблицаЦеныНоменклатуры);
КонецПроцедуры
&НаСервереБезКонтекста
Процедура ОбработатьДокументНаСервере(Знач ТабДок)
// Здесь мы можем обходить строки и колонки
Для НомерСтроки = 1 По ТабДок.ВысотаТаблицы Цикл
// Обработка данных
КонецЦикла;
КонецПроцедуры
Иногда удобнее работать не с ячейками, а с привычной ТаблицейЗначений. Существует "хитрый" и эффективный способ сделать это с помощью ПостроителяОтчета (или ПостроителяЗапроса в некоторых контекстах) — так работает импорт данных из Excel через штатный механизм 1С. Этот метод позволяет мгновенно конвертировать визуальную область в структуру данных.
Рассмотрим по шагам, как это реализовать на сервере:
ВысотаТаблицы и ШиринаТаблицы.ОписаниеИсточникаДанных.
&НаСервере
Функция ПреобразоватьТабДокВТЗ(ТабДок)
ПоследняяСтрока = ТабДок.ВысотаТаблицы;
ПоследняяКолонка = ТабДок.ШиринаТаблицы;
// Выбираем всю заполненную область
ОбластьЯчеек = ТабДок.Область(1, 1, ПоследняяСтрока, ПоследняяКолонка);
ИсточникДанных = Новый ОписаниеИсточникаДанных(ОбластьЯчеек);
Построитель = Новый ПостроительОтчета;
Построитель.ИсточникДанных = ИсточникДанных;
// Построитель проанализирует данные и создаст структуру колонок
Построитель.Выполнить();
Возврат Построитель.Результат.Выгрузить();
КонецФункции
Важное замечание: При использовании этого метода 1С попытается определить заголовки колонок по первой строке области. Если ваши данные начинаются сразу с первой строки без "шапки", это стоит учитывать при дальнейшей обработке ТЗ.
Проанализируем ситуацию с объемом данных. Хотя передача табличного документа между клиентом и сервером в 1С реализована достаточно эффективно, стоит помнить, что ТабличныйДокумент передается целиком — вместе со всеми настройками шрифтов, цветов, объединениями ячеек и примечаниями. Если ваш документ содержит десятки тысяч строк с уникальным оформлением каждой ячейки, объем передаваемых данных (сериализованный XML) может стать значительным.
В таких случаях рекомендуется:
Чтобы сделать интерфейс более отзывчивым, мы можем использовать события элемента формы ПолеТабличногоДокумента. Например, событие ПриИзмененииСодержимогоОбласти позволяет сразу проверить корректность введенных цифр или выполнить автоматический пересчет итогов прямо в форме, не заставляя пользователя нажимать специальные кнопки "Рассчитать".
При копировании данных из Excel помните, что 1С интерпретирует данные в зависимости от региональных настроек — задачу решит универсальная загрузка из Excel в любые документы. Если пользователь копирует число с точкой в качестве разделителя, а в системе установлена запятая, автоматическое получение Значение может не сработать. В таких случаях надежнее считывать Текст и обрабатывать его функцией Число(), предварительно удалив лишние пробелы и заменив точки на запятые.
Подводя итог, можно сказать, что работа с табличным документом на управляемой форме — это мощный инструмент для создания гибких интерфейсов ввода данных. Главное — помнить о разделении элементов и реквизитов и выбирать правильное место для обработки данных (клиент или сервер) в зависимости от решаемой задачи.