Часто перед разработчиками встает задача: есть внешний файл (например, Excel) со списком кодов, и нужно найти соответствующих контрагентов в базе 1С, чтобы выгрузить для них дополнительные данные — наименование, ИНН и прочее. Рассмотрим подробнее, как правильно реализовать такую обработку, разберем частые ошибки и проанализируем оптимальные способы работы с файлами.
Самый простой подход, который часто приходит на ум новичкам — прочитать файл построчно и использовать стандартный метод поиска по справочнику. Посмотрим на пример:
Контрагент = Справочник.Контрагенты.НайтиПоКоду(КодИзФайла);
Этот метод работает, но категорически не подходит для больших файлов. Если использовать его в цикле для файла из тысяч строк, 1С будет отправлять к системе управления базами данных (СУБД) тысячи мелких запросов. Это приведет к сильному замедлению работы обработки и неоправданной нагрузке на сервер. Разберем более правильный подход немного позже.
Самая частая ошибка при загрузке и поиске по кодам из Excel — это потеря ведущих нулей. Выясним причину: коды справочника Контрагенты в 1С чаще всего имеют строковый тип (например, "000000123"). Однако Excel по умолчанию воспринимает такие значения как числа и убирает нули, оставляя просто "123". Если передать такое усеченное значение в базу, система ничего не найдет.
Решим эту проблему. Есть несколько путей:
.Text, а не .Value. Это позволит получить строку в том виде, как она отображается на экране.Посмотрим на пример программного восстановления нулей с помощью функции Прав():
КодИзФайла = "123"; // Получили из Excel
// Дополняем нулями до стандартной длины кода (например, 9 символов)
КодДляПоиска = Прав("000000000" + КодИзФайла, 9);
// Результат: "000000123"
Откажемся от поиска в цикле и проанализируем ситуацию с точки зрения производительности. Все прочитанные из файла коды нам нужно собрать в единый Массив или ТаблицуЗначений. Затем мы сформируем один запрос к базе данных. Таким образом, одним запросом мы получим сразу все Наименования и ИНН для всего списка.
Разберем по шагам создание такого запроса:
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Контрагенты.Код КАК Код,
| Контрагенты.Наименование КАК Наименование,
| Контрагенты.ИНН КАК ИНН
|ИЗ
| Справочник.Контрагенты КАК Контрагенты
|ГДЕ
| Контрагенты.Код В(&МассивКодов)";
Запрос.УстановитьПараметр("МассивКодов", МассивПрочитанныхКодов);
РезультатЗапроса = Запрос.Выполнить();
Выборка = РезультатЗапроса.Выбрать();
Пока Выборка.Следующий() Цикл
// Заполняем данные для итогового файла
КонецЦикла;
Если кодов очень много, лучше поместить их во временную таблицу и выполнить соединение (JOIN) со справочником контрагентов. Это наиболее быстрый и надежный вариант.
Поскольку нам нужно не только прочитать коды, но и записать найденные данные в соседние ячейки, выберем наиболее удобный инструмент работы. Рассмотрим три основных варианта:
ТабДок.Прочитать(). Это работает быстро, кроссплатформенно и не требует установленного MS Office на сервере. Извлечь данные можно обходом ячеек или с помощью инструмента ПостроительЗапроса напрямую в таблицу значений. После обработки запишем данные в соседние колонки и сохраним файл обратно методом ТабДок.Записать().Лист.Cells(Строка, 2).Value = НайденноеНаименование). После заполнения результат сохраняется методами Книга.Save() и Книга.Close().Для большинства типовых задач рекомендуется использовать Табличный документ, так как он встроен в платформу и лишен проблем с лицензиями стороннего ПО или фоновыми зависаниями COM-объектов. Применяйте пакетные запросы для поиска, контролируйте типы данных при чтении кодов, и ваши обработки будут работать быстро и безошибочно.