Загрузка больших прайс-листов (от 60 000 позиций и выше) в типовые конфигурации, такие как 1С:Бухгалтерия 3.0, часто становится серьезной проблемой. Стандартные механизмы могут обрабатывать такой объем данных часами, что неприемлемо для оперативной работы. В этой статье мы разберем, как оптимизировать процесс загрузки, сократив время с 5-8 часов до 10-15 минут, и выясним технические ограничения документов 1С.
Прежде чем приступать к написанию кода, проанализируем, на что именно тратится время. Процесс загрузки состоит из трех этапов:
Excel.Application).НайтиПоАртикулу() или отдельными запросами.Для выявления конкретной "просадки" производительности рекомендуется запустить отладчик и выполнить замер производительности. Как правило, 80% времени уходит на неэффективный поиск в цикле и запись объектов без использования транзакций.
Вместо медленного обращения к Excel через COM-объекты, мы будем использовать встроенные средства платформы 1С. Рассмотрим метод Прочитать() объекта ТабличныйДокумент. Этот метод позволяет загрузить данные из файлов .xlsx или .xls напрямую в память платформы.
Рассмотрим пример кода для быстрого получения данных:
ТабДок = Новый ТабличныйДокумент;
ТабДок.Прочитать(ПутьКФайлу);
// Выгружаем данные в таблицу значений для удобства обработки
Построитель = Новый ПостроительЗапроса;
Построитель.ИсточникДанных = Новый ОписаниеИсточникаДанных(ТабДок.Область());
Построитель.Выполнить();
ТЗ_Прайс = Построитель.Результат.Выгрузить();
Этот метод работает значительно быстрее, так как платформа считывает структуру файла напрямую, минуя интерфейсы Microsoft Office. Кроме того, это решение будет работать на сервере под управлением Linux, где установка Excel невозможна.
Самая распространенная ошибка программиста — выполнение запроса к базе данных внутри цикла. Если у нас 60 000 строк, 1С выполнит 60 000 обращений к SQL-серверу, что фатально для производительности.
Проанализируем правильный алгоритм "пакетного" поиска:
Номенклатура.Пример реализации эффективного поиска:
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ПрайсИзФайла.Артикул КАК Артикул,
| ПрайсИзФайла.Наименование КАК Наименование
|ПОМЕСТИТЬ ВТ_Прайс
|ИЗ
| &ТЗ_Прайс КАК ПрайсИзФайла
|;
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
| ВТ_Прайс.Артикул,
| ВТ_Прайс.Наименование,
| ЕСТЬNULL(Номенклатура.Ссылка, ЗНАЧЕНИЕ(Справочник.Номенклатура.ПустаяСсылка)) КАК Ссылка
|ИЗ
| ВТ_Прайс КАК ВТ_Прайс
| ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Номенклатура КАК Номенклатура
| ПО ВТ_Прайс.Артикул = Номенклатура.Артикул";
Запрос.УстановитьПараметр("ТЗ_Прайс", ТЗ_Прайс);
РезультатПоиска = Запрос.Выполнить().Выгрузить();
Теперь в РезультатПоиска мы сразу видим, для каких артикулов уже есть Ссылка, а какие нужно создать. Мы сделали один запрос вместо 60 000.
При программном создании номенклатуры важно использовать свойство ОбменДанными.Загрузка = Истина. Это отключает тяжелые проверки в подписках на события, которые в типовых конфигурациях (БП 3.0) могут замедлять запись в разы.
Также разберем работу с транзакциями. Записывать каждый объект по отдельности долго. Рекомендуется объединять запись группы объектов (например, по 500-1000 штук) в одну транзакцию:
НачатьТранзакцию();
Для Каждого Строка Из РезультатПоиска Цикл
Если Строка.Ссылка.Пустая() Тогда
НовОбъект = Справочники.Номенклатура.СоздатьЭлемент();
НовОбъект.Артикул = Строка.Артикул;
НовОбъект.Наименование = Строка.Наименование;
НовОбъект.ОбменДанными.Загрузка = Истина;
НовОбъект.Записать();
КонецЕсли;
КонецЦикла;
ЗафиксироватьТранзакцию();
Выясним вопрос о лимитах строк в документах 1С (например, в документе Установка цен номенклатуры). Технически платформа 1С v8.3 позволяет хранить в табличной части практически неограниченное количество строк (до нескольких миллионов). Однако на практике существуют интерфейсные ограничения:
Out of memory.Практический совет: Если ваш прайс содержит 60 000 позиций, лучше программно разделять его на несколько документов (например, по 10 000 строк в каждом). Это обеспечит стабильную работу бухгалтеров и быструю перепроводимость данных.
Подведем итог наших действий по ускорению загрузки:
ТабличныйДокумент.Прочитать() для быстрого чтения файла без участия Excel.ОбменДанными.Загрузка = Истина и используем транзакции при записи новой номенклатуры.Выяснив причину тормозов и применив данные методы, вы сможете добиться загрузки прайса объемом 60 000 строк всего за несколько минут, что значительно повысит эффективность работы в системе.