При автоматизации рутинных операций в 1С часто возникает задача переноса данных из одного документа в другой. Например, создание документа ПеремещениеТоваров на основании данных из ИнвентаризацияТоваровНаСкладе. Однако при написании кода разработчики нередко сталкиваются с ситуацией, когда вместо ожидаемых 50 строк в табличную часть попадают тысячи записей. Разберем, почему это происходит и как правильно организовать процесс выборки данных.
Главная причина, по которой количество строк в табличной части нового документа кратно превышает ожидаемый объем, кроется в отсутствии фильтрации данных в запросе. Когда мы обращаемся к табличной части документа в базе данных, система выбирает все записи по всем документам этого вида, если мы явно не укажем, что нам нужны данные только из конкретного объекта.
В примере, который мы рассматриваем, разработчик забыл указать секцию ГДЕ, из-за чего в выборку попали все строки Пересортица из всех когда-либо созданных инвентаризаций в базе. Чтобы этого избежать, всегда проверяйте структуру вашего запроса.
Рассмотрим, как правильно составить алгоритм заполнения табличной части документа ПеремещениеТоваров на основе данных ИнвентаризацияТоваровНаСкладе.
&Ссылка, который передается в запрос перед выполнением.&Ссылка соответствует объекту ДокументСсылка.ИнвентаризацияТоваровНаСкладе.Давайте посмотрим, как должен выглядеть исправленный код запроса с учетом всех рекомендаций:
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ИнвентаризацияТоваровНаСкладеПересорт.НоменклатураРасход КАК НоменклатураРасход,
| ИнвентаризацияТоваровНаСкладеПересорт.ХарактеристикаРасход КАК ХарактеристикаРасход,
| ИнвентаризацияТоваровНаСкладеПересорт.Количество КАК Количество,
| ИнвентаризацияТоваровНаСкладеПересорт.НоменклатураРасход.ЕдиницаХраненияОстатков КАК Единица
|ИЗ
| Документ.ИнвентаризацияТоваровНаСкладе.Пересорт КАК ИнвентаризацияТоваровНаСкладеПересорт
|ГДЕ
| ИнвентаризацияТоваровНаСкладеПересорт.Ссылка = &Ссылка";
Запрос.УстановитьПараметр("Ссылка", ОбъектСсылкаИнвентаризации);
Результат = Запрос.Выполнить();
Выборка = Результат.Выбрать();
ОбъектРасход = Документы.ПеремещениеТоваров.СоздатьДокумент();
// Заполнение шапки документа...
Пока Выборка.Следующий() Цикл
НоваяСтрока = ОбъектРасход.Товары.Добавить();
НоваяСтрока.Номенклатура = Выборка.НоменклатураРасход;
НоваяСтрока.ХарактеристикаНоменклатуры = Выборка.ХарактеристикаРасход;
НоваяСтрока.Количество = Выборка.Количество;
НоваяСтрока.ЕдиницаИзмерения = Выборка.Единица;
НоваяСтрока.Коэффициент = 1;
КонецЦикла;
Для повышения качества вашего кода и упрощения процесса разработки рекомендуем обратить внимание на следующие аспекты:
Использование отладчика. Если результат запроса вызывает сомнения, обязательно ставьте точку останова на строке Выборка = Результат.Выбрать(). Открыв окно просмотра переменной Результат или используя метод Выгрузить(), вы сможете увидеть реальное количество записей в таблице значений до того, как они будут добавлены в документ.
Метод Загрузить(). Вместо использования цикла Пока Выборка.Следующий() можно использовать метод ТабличнаяЧасть.Загрузить(РезультатЗапроса.Выгрузить()). Это работает быстрее, так как перенос данных осуществляется за одну операцию, при условии, что имена колонок в запросе полностью совпадают с именами колонок табличной части документа.
Контроль данных. Всегда проверяйте заполненность характеристик и единиц измерения. В типовых конфигурациях, таких как УТ 10, ошибки в единицах измерения могут привести к невозможности проведения документа из-за неверных движений по регистрам накопления. Если номенклатура имеет сложные настройки единиц, используйте функции типовых модулей для их корректного получения.
Соблюдая эти простые правила, вы сможете избежать досадных ошибок и сделать код более производительным и легким для чтения.