Почему при программном добавлении строки в табличную часть свойство ТекущиеДанные равно Неопределено?

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

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

Понимаем причину возникновения ошибки

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

Когда мы программно вызываем метод Объект.Товары.Добавить(), строка физически появляется в коллекции данных объекта, но фокус ввода или выделение в интерфейсе автоматически не переключаются на эту новую строку. Система управления формами «не видит» новую запись как активную для пользователя. Именно поэтому обращение к Элементы.Товары.ТекущиеДанные возвращает Неопределено: вы пытаетесь спросить у интерфейса данные о строке, на которую он еще не «посмотрел».

Правильный подход к работе с данными

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

Рассмотрим, как правильно организовать код, чтобы избавиться от Неопределено и ошибок при расчетах.

Шаг 1: Изменяем структуру процедуры обработки

Вместо того чтобы полагаться на ТекущиеДанные, лучше передавать в процедуру саму строку данных в качестве параметра. Это сделает код универсальным и для ручного редактирования, и для программного заполнения.

Разберем пример правильной структуры процедуры:


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

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

Шаг 2: Унификация вызова процедуры

Когда мы добавляем новую строку программно, мы просто вызываем эту процедуру, передавая ссылку на созданную строку:


// Создаем строку
НоваяСтрока = Объект.Товары.Добавить();
// Заполняем поля...
НоваяСтрока.Номенклатура = ВыбраннаяНоменклатура;
НоваяСтрока.Цена = РассчитаннаяЦена;

// Вызываем процедуру расчета, передавая саму строку
ЗаполнитьДанныеСтроки(НоваяСтрока, НоваяСтрока.Номенклатура, НоваяСтрока.Цена);

Почему стоит избегать вызовов сервера в цикле

Обратите внимание на то, как часто мы вызываем серверные функции. Если вы загружаете данные из файла и добавляете сотни строк, выполнение функции ПолучитьПоследнееЗначениеЦены для каждой строки в отдельности приведет к множественным обращениям к базе данных. Это называется проблемой «N+1 запросов».

Рекомендуем следующий алгоритм для оптимизации:

  1. Соберите список всей номенклатуры, которую нужно обработать, в массив или таблицу значений на клиенте.
  2. Передайте этот массив на сервер одним вызовом функции.
  3. На сервере выполните один запрос к регистру сведений ЦеныНоменклатуры, выбрав данные по всему списку номенклатуры сразу.
  4. Верните таблицу с результатами на клиент и заполните строки таблицы за один проход цикла.

Итоги

Мы выяснили, что ошибка с Неопределено возникает из-за обращения к элементам управления, которые не синхронизированы с программно добавленными данными. Чтобы код работал стабильно:

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

← На главную