Рассмотрим ситуацию, с которой часто сталкиваются разработчики при работе с управляемыми формами 1С. Вы пишете код для автоматического заполнения табличной части, используете метод Добавить() для создания новой строки, но при попытке получить данные этой строки через Элементы.ИмяТаблицы.ТекущиеДанные получаете Неопределено. Разберемся, почему так происходит и как сделать работу с данными корректной и профессиональной.
Важно помнить, что свойство ТекущиеДанные элемента управления таблицей на форме — это не просто хранилище значений. Это «зеркало» текущего состояния пользовательского интерфейса. Оно указывает на ту строку, которая в данный момент выбрана (активизирована) курсором пользователя.
Когда мы программно вызываем метод Объект.Товары.Добавить(), строка физически появляется в коллекции данных объекта, но фокус ввода или выделение в интерфейсе автоматически не переключаются на эту новую строку. Система управления формами «не видит» новую запись как активную для пользователя. Именно поэтому обращение к Элементы.Товары.ТекущиеДанные возвращает Неопределено: вы пытаетесь спросить у интерфейса данные о строке, на которую он еще не «посмотрел».
Разработчикам стоит придерживаться правила: если мы программно создаем или изменяем строку, у нас уже есть прямой доступ к ней через возвращаемое значение метода Добавить(). Использование ТекущиеДанные в таких случаях является избыточным и архитектурно неверным, так как создает зависимость вашей логики от состояния пользовательского интерфейса.
Рассмотрим, как правильно организовать код, чтобы избавиться от Неопределено и ошибок при расчетах.
Вместо того чтобы полагаться на ТекущиеДанные, лучше передавать в процедуру саму строку данных в качестве параметра. Это сделает код универсальным и для ручного редактирования, и для программного заполнения.
Разберем пример правильной структуры процедуры:
&НаКлиенте
Процедура ЗаполнитьДанныеСтроки(СтрокаТаблицы, ВыбНоменклатура, ТекущаяЦена)
// Получаем необходимые для расчета данные с сервера
СтруктураЦен = ПолучитьПоследнееЗначениеЦены(ВыбНоменклатура, ТекущаяДата());
Если СтруктураЦен <> Неопределено Тогда
// Обращаемся напрямую к переданной строке, а не к элементам формы
СтрокаТаблицы.ПроцентИзменения = ОКР(ТекущаяЦена * 100 / СтруктураЦен.ПредыдущаяЦена - 100, 2);
СтрокаТаблицы.ДатаПредыдущейЦены = СтруктураЦен.ДатаПредыдущейЦены;
СтрокаТаблицы.ПредыдущаяЦена = СтруктураЦен.ПредыдущаяЦена;
КонецЕсли;
КонецПроцедуры
Когда мы добавляем новую строку программно, мы просто вызываем эту процедуру, передавая ссылку на созданную строку:
// Создаем строку
НоваяСтрока = Объект.Товары.Добавить();
// Заполняем поля...
НоваяСтрока.Номенклатура = ВыбраннаяНоменклатура;
НоваяСтрока.Цена = РассчитаннаяЦена;
// Вызываем процедуру расчета, передавая саму строку
ЗаполнитьДанныеСтроки(НоваяСтрока, НоваяСтрока.Номенклатура, НоваяСтрока.Цена);
Обратите внимание на то, как часто мы вызываем серверные функции. Если вы загружаете данные из файла и добавляете сотни строк, выполнение функции ПолучитьПоследнееЗначениеЦены для каждой строки в отдельности приведет к множественным обращениям к базе данных. Это называется проблемой «N+1 запросов».
Рекомендуем следующий алгоритм для оптимизации:
ЦеныНоменклатуры, выбрав данные по всему списку номенклатуры сразу.Мы выяснили, что ошибка с Неопределено возникает из-за обращения к элементам управления, которые не синхронизированы с программно добавленными данными. Чтобы код работал стабильно:
Элементы.ИмяТаблицы.ТекущиеДанные из процедур, которые выполняются при программном заполнении данных.Добавить().Соблюдение этих простых правил поможет сделать ваш код чище, понятнее и устойчивее к ошибкам, связанным с архитектурой управляемых форм 1С.