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

Программист 1С v8.3 (Управляемые формы) Управленческий учет Промышленность, строительство и АПК
← На главную

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

Ошибки при присвоении значений

Первая и самая распространенная ошибка — попытка присвоить реквизиту табличной части объект вместо ссылки. В 1С реквизиты ссылочного типа (справочники, документы) всегда должны содержать ссылку. Если вы получили объект через ПолучитьОбъект(), то при присвоении его в реквизит BS_Склад система не сможет корректно сопоставить данные.

Вместо передачи объекта, используйте непосредственно ссылку на элемент справочника. Также избегайте избыточного использования метода ПолучитьОбъект(), так как он считывает все данные элемента из базы в память сервера, что неоправданно замедляет работу.

Правильная работа с табличной частью

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

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


Отбор = Новый Структура;
Отбор.Вставить("Номенклатура", ТекСтрокаМатериалы.Номенклатура);
НайденныеСтроки = ТекСтрокаМатериалы.ЗаявкаНаМатериалы.ЗаказНаПроизводство.Резервы.НайтиСтроки(Отбор);

Если НайденныеСтроки.Количество() > 0 Тогда
    // Работаем с найденной строкой напрямую через коллекцию
    СтрокаДляИзменения = НайденныеСтроки[0];
    СтрокаДляИзменения.BS_Склад = Склад; // Передаем ссылку напрямую
    
    // Записываем только если это действительно необходимо
    МенеджерОбъект = ТекСтрокаМатериалы.ЗаявкаНаМатериалы.ЗаказНаПроизводство.ПолучитьОбъект();
    МенеджерОбъект.Записать();
КонецЕсли;

Почему использование НайтиПоНаименованию — это риск?

В коде автора встречалась конструкция Справочники.Склады.НайтиПоНаименованию(Склад.Наименование). Это считается плохой практикой (антипаттерном) по нескольким причинам:

  1. Отсутствие уникальности: Наименование может дублироваться. Система вернет первый попавшийся элемент, что приведет к непредсказуемому результату.
  2. Производительность: Поиск по строковому полю выполняется медленнее, чем по индексированным полям (коду или ссылке).
  3. Избыточность: Если у вас уже есть переменная Склад, которая содержит ссылку, используйте ее напрямую, не обращаясь к поиску в базе данных.

Важные рекомендации по разработке

Проанализируем ключевые моменты, которые помогут вам избежать проблем в будущем:

Следуя этим правилам, вы сможете писать более стабильный и быстрый код, который будет легко поддерживать и масштабировать.

← На главную