Загрузка данных из внешних файлов Excel — одна из самых частых задач при автоматизации торговых систем на базе BAS Управление торговлей 3.2 (функционального аналога УТ 11). Однако разработчики часто сталкиваются с ситуацией, когда код, написанный «по аналогии» с другими справочниками, отказывается работать или не создает записи без видимых ошибок. Разберем подробно причины возникновения этой проблемы и эффективные способы её решения.
Первая и самая распространенная причина, по которой загрузка «не грузит ничего», заключается в некорректном разделении контекстов выполнения кода. В предоставленном примере процедура ЗагрузитьНаСервере вызывается на клиенте, но фактически пытается работать с COM-объектом Excel. Рассмотрим, что здесь не так.
Если файл Excel выбирается пользователем на локальном компьютере, а процедура обработки данных выполняется на сервере (например, в модуле объекта или через &НаСервере), то сервер 1С просто не увидит этот файл. Путь C:\MyFiles\Data.xlsx на вашем ПК для сервера 1С означает поиск файла на жестком диске самого сервера.
Как правильно организовать процесс:
ПоместитьФайл() или ПоместитьФайлы().ПолучитьИмяВременногоФайла("xlsx").Проанализируем архитектуру справочников в BAS УТ 3.2. В отличие от старых версий (например, УТ 10.3), здесь используется двухуровневая система: Партнеры (управленческий учет) и Контрагенты (регламентированный юридический учет). Проблема автора темы может заключаться в том, что он пытается создать Контрагента, не создав предварительно Партнера.
Если в настройках системы включена опция «Независимо вести партнеров и контрагентов», то запись контрагента без указания владельца-партнера может быть заблокирована на уровне бизнес-логики или контроля целостности данных. В коде автора мы видим попытку заполнения только справочника Контрагенты, при этом ссылка на партнера устанавливается как НеизвестныйПартнер. Это критическая ошибка проектирования для данной конфигурации.
Рассмотрим правильный алгоритм создания:
// Сначала создаем Партнера
НовыйПартнер = Справочники.Партнеры.СоздатьЭлемент();
НовыйПартнер.Наименование = НаименованиеИзФайла;
НовыйПартнер.Клиент = Истина; // или Поставщик
НовыйПартнер.Записать();
// Затем создаем Контрагента и привязываем его к Партнеру
НовыйКонтрагент = Справочники.Контрагенты.СоздатьЭлемент();
НовыйКонтрагент.Партнер = НовыйПартнер.Ссылка;
НовыйКонтрагент.Наименование = НаименованиеЮрЛица;
НовыйКонтрагент.ИНН = ИННИзФайла;
НовыйКонтрагент.Записать();
Использование COMОбъект("Excel.Application") — это устаревший и нестабильный метод. Он требует наличия установленного Microsoft Excel на сервере, что часто невозможно по соображениям безопасности или лицензирования. Кроме того, COM работает крайне медленно из-за постоянных обращений между процессами.
Выясним причину, почему цикл в коде автора может прерываться преждевременно. В строке Пока (НЕ ДокExcel.Sheets(НомерЛиста).Cells(НомерСтроки, КолонкаПрохождения).Value = Неопределено...) используется проверка на Value. Если в файле встретится пустая ячейка в ключевой колонке (например, из-за особенностей форматирования), цикл завершится, даже если ниже есть данные.
Проанализируем альтернативный, более надежный метод через ТабличныйДокумент:
ТабДок = Новый ТабличныйДокумент;
Попытка
ТабДок.Прочитать(ПутьКФайлу, СпособЧтенияЗначенийТабличногоДокумента.Значение);
Исключение
Сообщить("Не удалось прочитать файл: " + ОписаниеОшибки());
Возврат;
КонецПопытки;
КоличествоСтрок = ТабДок.ВысотаТаблицы;
Для НомерСтроки = 2 По КоличествоСтрок Цикл // Начинаем со второй строки (пропуская заголовок)
Наименование = ТабДок.Область(НомерСтроки, 1).Текст;
ИНН = ТабДок.Область(НомерСтроки, 2).Текст;
// Дальнейшая логика обработки...
КонецЦикла;
Этот способ работает в десятки раз быстрее, не требует Excel на сервере и позволяет легко отлаживать данные, просто открыв ТабДок в отладчике.
Обратим внимание на заполнение адресов и телефонов. В коде автора используется прямое добавление в табличную часть КонтактнаяИнформация. В современных конфигурациях 1С (БСП) это работать не будет или приведет к тому, что в карточке контрагента поля будут выглядеть пустыми.
Важный момент: Контактная информация хранится в специальном формате (JSON или XML) в поле ЗначенияПолей. Чтобы корректно записать адрес, необходимо использовать программный интерфейс БСП. Рассмотрим пример записи телефона:
// Используем методы модуля УправлениеКонтактнойИнформацией
ВидТелефона = Справочники.ВидыКонтактнойИнформации.ТелефонКонтрагента;
УправлениеКонтактнойИнформацией.ЗаписатьКонтактнуюИнформацию(ОбъектКонтрагент, "89991234567", ВидТелефона, Перечисления.ТипыКонтактнойИнформации.Телефон);
В исходном коде используется НачатьТранзакцию(), но отсутствует блок Попытка...Исключение вокруг каждой итерации цикла. Рассмотрим ситуацию: если при записи 100-го контрагента возникнет ошибка (например, незаполнен реквизит ЮрФизЛицо), вся транзакция будет отменена, и вы не увидите в базе ни одной записи из загруженных ранее 99.
Проанализируем правильную структуру цикла загрузки:
ЗафиксироватьТранзакцию()) только после успешного завершения всех операций.Чтобы ваша загрузка контрагентов в BAS УТ 3.2 заработала стабильно, выполните следующие шаги:
ТаблицаКонтрагентов инициализирована. В коде автора строка вызова функции чтения закомментирована, что является прямой причиной отсутствия действий.Для каждого МассивТекСтроки Из ТаблицаКонтрагентов Цикл. Если отладчик не заходит в цикл — значит, таблица пуста.Соблюдение этих правил и переход на современные методы работы с данными позволят вам создать надежный инструмент импорта, который не будет зависеть от версии установленного офисного ПО или настроек прав DCOM на сервере.