Подсистема БСП «Загрузка данных из файла» — это мощный инструмент, который позволяет пользователям самостоятельно импортировать данные из Excel или CSV в табличные части документов или справочники. Однако при работе со сложными типами данных, такими как Номенклатура с включенными Характеристиками и поиском по Штрихкодам, стандартных примеров из документации часто бывает недостаточно. Разберем подробно, как реализовать этот механизм, опираясь на опыт типовых конфигураций и стандарты разработки.
Прежде всего, проанализируем важный архитектурный нюанс. В конфигурациях «1С:Управление торговлей 11» и «1С:ERP Управление предприятием» часто используется собственная обработка ЗагрузкаДанныхИзВнешнихФайлов. Она похожа на БСП, но имеет более жесткую привязку к бизнес-логике этих систем. Если же ваша задача — внедрить чистый механизм БСП, лучше всего ориентироваться на конфигурацию «1С:Управление нашей фирмой» (УНФ) или демонстрационную базу БСП. Там функционал реализован через переопределяемые модули и модули менеджеров объектов, что является «золотым стандартом» разработки.
Для того чтобы система поняла, какие данные мы хотим загружать, нам необходимо описать структуру в модуле менеджера объекта (например, документа или справочника). Рассмотрим процедуру ОпределитьПараметрыЗагрузкиДанныхИзФайла. Здесь мы указываем состав колонок. Если мы планируем искать номенклатуру по штрихкоду, нам нужно добавить колонку для штрихкода, даже если ее нет в самой табличной части.
Процедура ОпределитьПараметрыЗагрузкиДанныхИзФайла(ПараметрыЗагрузки) Экспорт
// Описываем колонку для номенклатуры
НоваяКолонка = ПараметрыЗагрузки.Колонки.Добавить();
НоваяКолонка.Имя = "Номенклатура";
НоваяКолонка.Заголовок = НСтр("ru = 'Номенклатура'");
НоваяКолонка.Тип = Новый ОписаниеТипов("СправочникСсылка.Номенклатура");
// Описываем колонку для характеристики
НоваяКолонка = ПараметрыЗагрузки.Колонки.Добавить();
НоваяКолонка.Имя = "Характеристика";
НоваяКолонка.Заголовок = НСтр("ru = 'Характеристика'");
НоваяКолонка.Тип = Новый ОписаниеТипов("СправочникСсылка.ХарактеристикиНоменклатуры");
// Колонка для поиска по штрихкоду (в ТЧ документа ее может не быть)
НоваяКолонка = ПараметрыЗагрузки.Колонки.Добавить();
НоваяКолонка.Имя = "Штрихкод";
НоваяКолонка.Заголовок = НСтр("ru = 'Штрихкод'");
НоваяКолонка.Тип = Новый ОписаниеТипов("Строка",,,, Новый КвалификаторыСтроки(200));
// Обязательно указываем количество с явным типом Число
НоваяКолонка = ПараметрыЗагрузки.Колонки.Добавить();
НоваяКолонка.Имя = "Количество";
НоваяКолонка.Заголовок = НСтр("ru = 'Количество'");
НоваяКолонка.Тип = Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(15, 3));
КонецПроцедуры
Важный момент: если вы не укажете тип Число для количества, парсер БСП может интерпретировать данные как строку. Это часто приводит к тому, что при переносе в документ значения зануляются или игнорируются.
Теперь перейдем к самому сложному — процедуре СопоставитьЗагружаемыеДанныеИзФайла. В нее передается таблица значений, содержащая сырые данные из файла. Наша задача — программно заполнить колонки со ссылками (Номенклатура, Характеристика), используя имеющиеся строковые данные (наименования, артикулы или штрихкоды).
Проанализируем эффективный алгоритм сопоставления:
ШтрихкодыНоменклатуры.
Процедура СопоставитьЗагружаемыеДанныеИзФайла(ДанныеЗагрузки) Экспорт
// 1. Выгружаем колонку штрихкодов для поиска
ТаблицаШтрихкодов = ДанныеЗагрузки.Скопировать(, "Штрихкод");
ТаблицаШтрихкодов.Свернуть("Штрихкод");
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Штрихкоды.Штрихкод КАК Штрихкод,
| Штрихкоды.Номенклатура КАК Номенклатура,
| Штрихкоды.Характеристика КАК Характеристика
|ИЗ
| РегистрСведений.ШтрихкодыНоменклатуры КАК Штрихкоды
|ГДЕ
| Штрихкоды.Штрихкод В(&Штрихкоды)";
Запрос.УстановитьПараметр("Штрихкоды", ТаблицаШтрихкодов.ВыгрузитьКолонку("Штрихкод"));
РезультатПоиска = Запрос.Выполнить().Выгрузить();
РезультатПоиска.Индексировать("Штрихкод");
// 2. Переносим найденные ссылки в основную таблицу
Для Каждого СтрокаДанных Из ДанныеЗагрузки Цикл
Если ЗначениеЗаполнено(СтрокаДанных.Штрихкод) Тогда
НайденнаяСтрока = РезультатПоиска.Найти(СтрокаДанных.Штрихкод, "Штрихкод");
Если НайденнаяСтрока <> Неопределено Тогда
СтрокаДанных.Номенклатура = НайденнаяСтрока.Номенклатура;
СтрокаДанных.Характеристика = НайденнаяСтрока.Характеристика;
КонецЕсли;
КонецЕсли;
КонецЦикла;
// 3. Дополнительная логика поиска по наименованию (если не найден штрихкод)
// ... здесь можно реализовать поиск характеристик по владельцу ...
КонецПроцедуры
Выясним причину, почему часто возникают сложности с характеристиками. Характеристика не является уникальной в разрезе всей базы — её поиск имеет смысл только тогда, когда уже определен владелец (Номенклатура). Поэтому в коде сопоставления мы сначала находим ссылку на номенклатуру, и только вторым шагом ищем характеристику среди тех, что принадлежат этой номенклатуре (или её виду номенклатуры, если характеристики общие).
Если вы не хотите менять типовую конфигурацию, этот функционал можно вынести во внешнюю обработку заполнения объекта. Рассмотрим, как это работает:
СведенияОВнешнейОбработке указываем тип команды ОткрытиеФормы.ЗагрузкаДанныхИзФайла.Такой подход позволяет сохранить конфигурацию на поддержке и при этом предоставить пользователям удобный интерфейс загрузки. Основной секрет здесь — правильно связать ВладелецФормы, чтобы данные вернулись в нужную табличную часть.
Разберем типичные ошибки, с которыми сталкиваются разработчики:
ОпределитьПараметрыЗагрузкиДанныхИзФайла имена колонок строго совпадали с именами реквизитов табличной части документа, если вы используете автоматический перенос.Использование этого механизма позволяет создать действительно «умную» загрузку, которая не просто копирует данные из файла, но и проверяет их на логическую целостность, исключая попадание «мусора» в информационную базу.