Загрузка данных из внешних файлов Excel — одна из самых распространенных задач в практике программиста 1С. Часто возникает ситуация, когда текстовые данные из таблицы (например, название товара или его артикул) нужно превратить в полноценные ссылки на объекты информационной базы. В этой статье мы подробно разберем, как реализовать этот механизм, избегая типичных ошибок производительности и соблюдая правила клиент-серверного взаимодействия.
При простом чтении ячейки Excel мы получаем строковое значение. Если мы просто присвоим это значение реквизиту табличной части, который имеет тип СправочникСсылка.Номенклатура, 1С не сможет автоматически распознать объект. Нам необходимо программно найти соответствующий элемент в справочнике и подставить ссылку на него. Рассмотрим, как это сделать правильно.
Для начала разберем базовый подход с использованием COMObject. Этот метод требует установленного Microsoft Excel на компьютере. Проанализируем пример кода, который считывает данные и пытается найти номенклатуру по наименованию.
&НаКлиенте
Процедура Загрузка(Команда)
// Инициализируем соединение с Excel
Excel = Новый COMObject("Excel.Application");
Книга = Excel.Workbooks.Open(Объект.Файл);
Лист = Книга.Sheets(1);
// Определяем количество строк
ВсегоСтрок = Лист.Cells(1,1).SpecialCells(11).Row;
Для Счетчик = 2 По ВсегоСтрок Цикл
// Считываем текст из второй колонки
ТекстовоеИмя = СокрЛП(Лист.Cells(Счетчик, 2).Value);
Если ЗначениеЗаполнено(ТекстовоеИмя) Тогда
НоваяСтрока = Объект.ТЧ.Добавить();
// Нам нужно найти ссылку на сервере
НоваяСтрока.Номенклатура = НайтиНоменклатуруНаСервере(ТекстовоеИмя);
КонецЕсли;
КонецЦикла;
Excel.Quit();
КонецПроцедуры
Важное замечание: Обратите внимание, что поиск объекта в базе данных (обращение к справочникам) нельзя выполнять на клиенте. Это приведет к ошибке или крайне медленной работе. Поэтому мы вызываем серверную функцию НайтиНоменклатуруНаСервере.
Рассмотрим серверную функцию, которая будет отвечать за поиск. Поиск по наименованию (НайтиПоНаименованию) — самый простой способ, но он может быть неточным, если в базе есть дубли или похожие названия. Программисты рекомендуют использовать поиск по артикулу или штрихкоду, так как они более уникальны.
&НаСервереБезКонтекста
Функция НайтиНоменклатуруНаСервере(НаименованиеИзФайла)
// Сначала попробуем найти по полному совпадению наименования
Ссылка = Справочники.Номенклатура.НайтиПоНаименованию(НаименованиеИзФайла, Истина);
// Если по наименованию не нашли, можно добавить логику поиска по артикулу
Если Ссылка.Пустая() Тогда
Ссылка = Справочники.Номенклатура.НайтиПоРеквизиту("Артикул", НаименованиеИзФайла);
КонецЕсли;
Возврат Ссылка;
КонецФункции
Разберем ситуацию, когда в Excel-файле тысячи строк. Если мы будем вызывать поиск для каждой строки отдельно, программа будет работать очень долго из-за постоянных обращений к базе данных. Проанализируем более эффективный подход: массовая загрузка данных одним запросом.
Алгоритм эффективной загрузки выглядит так:
Номенклатура, чтобы найти сразу все ссылки.Посмотрим на пример реализации серверной части этого метода:
&НаСервере
Процедура ЗаполнитьТЧИзМассива(МассивИмен)
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Номенклатура.Ссылка КАК Ссылка,
| Номенклатура.Наименование КАК Наименование
|ИЗ
| Справочник.Номенклатура КАК Номенклатура
|ГДЕ
| Номенклатура.Наименование В (&МассивИмен)";
Запрос.УстановитьПараметр("МассивИмен", МассивИмен);
Результат = Запрос.Выполнить().Выгрузить();
// Создаем соответствие для быстрого поиска в памяти
СоответствиеОбъектов = Новый Соответствие;
Для Каждого Стр Из Результат Цикл
СоответствиеОбъектов.Вставить(Стр.Наименование, Стр.Ссылка);
КонецЦикла;
// Теперь заполняем ТЧ
Для Каждого Имя Из МассивИмен Цикл
НоваяСтрока = Объект.ТЧ.Добавить();
НоваяСтрока.Номенклатура = СоответствиеОбъектов.Получить(Имя);
// Если ссылка не найдена, можно оставить поле пустым или создать новый элемент
КонецЦикла;
КонецПроцедуры
Современная платформа 1С позволяет отказаться от использования COMObject. Это значительно ускоряет работу и позволяет загружать файлы даже на серверах под управлением Linux, где Microsoft Excel не установлен. Выясним, как использовать метод Прочитать объекта ТабличныйДокумент.
&НаСервере
Процедура ПрочитатьExcelНаСервере(АдресФайлаВоВременномХранилище)
ТабДок = Новый ТабличныйДокумент;
ДвоичныеДанные = ПолучитьИзВременногоХранилища(АдресФайлаВоВременномХранилище);
// Читаем данные напрямую из потока (поддерживает XLSX)
Поток = Новый ПотокВПамяти(ДвоичныеДанные);
ТабДок.Прочитать(Поток, СпособЧтенияЗначенийТабличногоДокумента.Значение);
// Теперь обходим строки ТабДока как обычную таблицу
Для НомерСтроки = 2 По ТабДок.ВысотаТаблицы Цикл
ТекстНаименования = ТабДок.Область(НомерСтроки, 2).Текст;
// Далее применяем логику поиска, описанную выше
КонецЦикла;
КонецПроцедуры
При работе с данными из Excel важно помнить о "чистоте" данных. Рассмотрим несколько советов, которые помогут избежать ошибок:
СокрЛП() для удаления лишних пробелов. Excel часто добавляет невидимые пробелы в начале или конце строки.Подводя итог, можно сказать, что ключ к успешной загрузке из Excel — это вынос логики поиска на сервер и использование пакетных запросов. Это обеспечит стабильную работу системы даже при больших объемах данных.