При разработке интерфейсов на платформе 1С 8.3 программисты часто сталкиваются с ситуацией, когда данные необходимо хранить в табличной части или коллекции, но саму таблицу отображать пользователю не нужно. Типичный сценарий: данные редактируются в отдельных полях ввода, расположенных на форме, а таблица служит лишь внутренним хранилищем. Однако при попытке программно обратиться к свойству ТекущиеДанные скрытой таблицы, разработчик получает Неопределено. В этой статье мы подробно разберем, почему так происходит, и как правильно манипулировать строками «невидимой» таблицы.
Для начала проанализируем техническую сторону работы управляемой формы. В 1С существует четкое разделение между данными (например, Объект.Товары, который является типом ДанныеФормыКоллекция) и элементом управления (Элементы.Товары, тип ТаблицаФормы).
Свойство ТекущиеДанные принадлежит именно элементу управления (интерфейсу). Платформа 1С оптимизирована для работы в веб-клиенте и тонком клиенте: если у элемента установлено свойство Видимость = Ложь, то этот элемент фактически не отрисовывается на стороне клиента. Поскольку визуального выделения строки в невидимой таблице существовать не может, платформа не поддерживает состояние свойства ТекущиеДанные для такого элемента. Как только таблица скрывается, связь между «текущей строкой» в интерфейсе и конкретной строкой в данных разрывается на уровне отображения.
Важно помнить: свойство ТекущаяСтрока (которое хранит числовой идентификатор строки) при этом может сохранять свое значение, но оно перестает автоматически «подтягивать» за собой объект данных в свойство ТекущиеДанные.
Самый надежный и правильный с точки зрения архитектуры способ — это обращение напрямую к коллекции данных, минуя интерфейсные свойства таблицы. Рассмотрим, как это реализовать программно. Вместо того чтобы полагаться на Элементы.ИмяТаблицы.ТекущиеДанные, мы будем использовать идентификатор строки.
Разберем по шагам алгоритм добавления и редактирования строки:
ТекущаяСтрока элемента формы (для порядка, хотя это не заполнит ТекущиеДанные).НайтиПоИдентификатору() самой коллекции.Посмотрим на пример кода:
// Добавляем новую строку в табличную часть (или коллекцию)
НоваяСтрока = Объект.СозданиеМоделей3D.Добавить();
// Получаем внутренний идентификатор строки
Идентификатор = НоваяСтрока.ПолучитьИдентификатор();
// Устанавливаем текущую строку в элементе формы (опционально)
Элементы.СозданиеМоделей3D.ТекущаяСтрока = Идентификатор;
// ТЕПЕРЬ ГЛАВНОЕ: Получаем доступ к данным без использования .ТекущиеДанные
СтрокаДанных = Объект.СозданиеМоделей3D.НайтиПоИдентификатору(Идентификатор);
Если СтрокаДанных <> Неопределено Тогда
СтрокаДанных.ИмяПоля = "Новое значение";
// Здесь можно продолжать работу с полями строки
КонецЕсли;
Если логика вашего приложения предполагает последовательную обработку или вы точно знаете порядковый номер строки, можно использовать индексы. Однако помните, что индекс и идентификатор — это разные вещи. Индекс меняется при сортировке или удалении строк, а идентификатор остается неизменным в течение сеанса работы формы.
Рассмотрим ситуацию, когда нам нужно изменить последнюю добавленную строку в скрытой таблице:
Коллекция = Объект.СозданиеМоделей3D;
Коллекция.Добавить();
ИндексПоследней = Коллекция.Количество() - 1;
// Обращаемся напрямую по индексу к коллекции данных
СтрокаДляРедактирования = Коллекция[ИндексПоследней];
СтрокаДляРедактирования.Параметр = "Значение";
Проанализируем этот подход: он максимально производителен, так как не требует поиска по всей коллекции, но он небезопасен, если в таблице включена автоматическая сортировка, которая может изменить положение строки сразу после добавления.
Часто разработчики связывают поля ввода на форме напрямую с путем Элементы.Таблица.ТекущиеДанные.ИмяПоля. Если таблица скрыта, такие поля станут недоступными или очистятся. Чтобы реализовать редактирование данных скрытой таблицы в отдельных полях, мы рекомендуем следующий алгоритм:
ТекущийИндексСтроки типа Число).Рассмотрим пример процедуры синхронизации:
&НаКлиенте
Процедура ИмяПоляВводаПриИзменении(Элемент)
Идентификатор = Элементы.СозданиеМоделей3D.ТекущаяСтрока;
Если Идентификатор = Неопределено Тогда
Возврат;
КонецЕсли;
СтрокаДанных = Объект.СозданиеМоделей3D.НайтиПоИдентификатору(Идентификатор);
Если СтрокаДанных <> Неопределено Тогда
// Переносим значение из реквизита формы в скрытую таблицу
СтрокаДанных.ИмяПоляВТаблице = РеквизитФормыДляРедактирования;
КонецЕсли;
КонецПроцедуры
Если архитектура вашего решения слишком сильно завязана на использование свойства ТекущиеДанные (например, у вас множество связанных обработчиков событий, которые трудно переписать), можно прибегнуть к интерфейсным хитростям. Вместо установки Видимость = Ложь, мы можем оставить таблицу «видимой» для системы, но скрыть её от пользователя:
ТекущиеДанные) поддерживается.Видимость можно управлять группой, в которой находится таблица, используя программное скрытие через сворачиваемые группы, если это допустимо дизайном.Важное предостережение: использование таких «хитростей» считается плохим тоном в разработке и может привести к непредсказуемому поведению в различных версиях платформы или в веб-клиенте. Использование метода НайтиПоИдентификатору() является приоритетным и стандартным решением.
Мы выяснили, что отсутствие ТекущихДанных у скрытой таблицы — это не ошибка, а особенность оптимизации управляемых форм. Для корректной работы со скрытыми данными всегда разделяйте понятия «интерфейс» и «данные». Работайте напрямую с Объект.ВашаКоллекция, сохраняйте Идентификатор строки и используйте его для поиска нужных данных. Это сделает ваш код более надежным, быстрым и независимым от визуальных настроек формы.