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