В практике бухгалтерского учета часто возникает ситуация, когда в конце отчетного периода необходимо оперативно отразить расходы, но подробная спецификация от поставщика еще не получена. В таких случаях бухгалтеры часто создают документ Поступление (акт, накладная, УПД) с одной строкой Услуги на общую сумму. Когда же контрагент присылает детальный файл УПД в формате Excel, возникает задача: как быстро заменить эту фиктивную строку на десятки или сотни реальных позиций номенклатуры, не перебивая документ вручную.
В данной статье мы разберем, как автоматизировать этот процесс, создав внешнюю обработку, которая будет находить нужный документ в базе и корректно заполнять его данными из файла поставщика.
Прежде чем приступать к написанию собственного кода, проанализируем, что уже предлагает современная платформа 1С:Предприятие 8.3 (особенно в конфигурациях БП 3.0, УТ 11 или ERP):
Если же нам нужно решение, которое само найдет документ по номеру и дате из Excel и само его перезаполнит, мы переходим к программной реализации.
Использование Excel.Application считается устаревшим методом, так как он требует установки Microsoft Office на сервере и работает медленно. Мы рекомендуем использовать объект ТабличныйДокумент, который в современных версиях 1С прекрасно справляется с чтением форматов .xls и .xlsx напрямую.
Рассмотрим пример кода для открытия и чтения файла:
&НаСервере
Процедура ПрочитатьФайлНаСервере(ПутьКФайлу)
ТабДок = Новый ТабличныйДокумент;
Попытка
ТабДок.Прочитать(ПутьКФайлу, СпособЧтенияЗначенийТабличногоДокумента.Значение);
Исключение
Сообщить("Ошибка при чтении файла: " + ОписаниеОшибки());
Возврат;
КонецПопытки;
// Далее начинаем разбор строк табличного документа
КонецПроцедуры
Это критически важный этап. В файле УПД (обычно это ячейки в районе 2-5 строки) содержатся номер и дата документа. Сумма обычно находится внизу. Проблема в том, что номер в 1С часто содержит префиксы и лидирующие нули (например, 0000-000123), а в Excel он может быть записан просто как 123.
Разберем алгоритм поиска:
Функция НайтиДокументПоступления(НомерИзФайла, ДатаИзФайла, СуммаИзФайла)
// Очищаем номер от лишних символов, если нужно
ПоискНомера = СокрЛП(НомерИзФайла);
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ПоступлениеТоваровУслуг.Ссылка КАК Ссылка
|ИЗ
| Документ.ПоступлениеТоваровУслуг КАК ПоступлениеТоваровУслуг
|ГДЕ
| ПоступлениеТоваровУслуг.Дата МЕЖДУ &НачалоДня И &КонецДня
| И ПоступлениеТоваровУслуг.Номер ПОДОБНО &Номер";
Запрос.УстановитьПараметр("НачалоДня", НачалоДня(ДатаИзФайла));
Запрос.УстановитьПараметр("КонецДня", КонецДня(ДатаИзФайла));
// Используем маску, чтобы найти номер с любыми префиксами
Запрос.УстановитьПараметр("Номер", "%" + ПоискНомера);
Результат = Запрос.Выполнить();
Если Не Результат.Пустой() Тогда
Выборка = Результат.Выбрать();
Пока Выборка.Следующий() Цикл
// Проверяем сумму для надежности
Если Выборка.Ссылка.СуммаДокумента = СуммаИзФайла Тогда
Возврат Выборка.Ссылка;
КонецЕсли;
КонецЦикла;
КонецЕсли;
Возврат Неопределено;
КонецФункции
Выясним причину, по которой простое создание новой номенклатуры — плохая идея. У поставщика товар может называться Болт М8х20 сталь, а в вашей базе это Болт 8*20. Для решения этой проблемы в типовых конфигурациях 1С используется справочник (или регистр сведений) Номенклатура поставщика.
Проанализируем алгоритм сопоставления:
НоменклатураКонтрагентов по артикулу или наименованию поставщика.После того как документ найден и файл прочитан, необходимо очистить старую строку Услуги и заполнить документ новыми данными. Посмотрим на пример реализации:
// Получаем объект документа для изменения
ДокОбъект = СсылкаНаДокумент.ПолучитьОбъект();
// 1. Очищаем существующие строки (или ищем только строку с "Услугами")
ДокОбъект.Товары.Очистить();
ДокОбъект.Услуги.Очистить(); // Если "Услуги" были на другой вкладке
// 2. Цикл по строкам Excel (допустим, данные начинаются с 15-й строки)
Для НомерСтроки = 15 По ТабДок.ВысотаТаблицы Цикл
НаименованиеПоставщика = ТабДок.Область(НомерСтроки, 3).Текст; // Колонка с названием
Если ПустаяСтрока(НаименованиеПоставщика) Тогда Прервать; КонецЕсли;
НоваяСтрока = ДокОбъект.Товары.Добавить();
// Вызываем функцию сопоставления номенклатуры
НоваяСтрока.Номенклатура = НайтиНашуНоменклатуру(НаименованиеПоставщика);
НоваяСтрока.Количество = ТабДок.Область(НомерСтроки, 10).Значение;
НоваяСтрока.Цена = ТабДок.Область(НомерСтроки, 11).Значение;
// Важно вызвать типовой механизм пересчета!
ОбработкаТабличнойЧастиТоварыПриИзмененииНоменклатуры(НоваяСтрока, ДокОбъект);
КонецЦикла;
// 3. Записываем документ
ДокОбъект.Записать(РежимЗаписиДокумента.Проведение);
Проанализируем дополнительные моменты, которые могут повлиять на результат:
Мы рассмотрели процесс программного заполнения документа «Поступление» на основе данных из внешнего файла Excel. Реализация такой обработки позволяет существенно сократить время на ввод первичной документации и минимизировать ошибки ручного ввода. Главным секретом успеха здесь является качественный алгоритм поиска документа и использование механизма сопоставления номенклатуры поставщика.
При написании обработки всегда старайтесь использовать серверные методы для работы с данными и встроенные процедуры конфигурации для расчета налогов и итогов, чтобы сохранить целостность учетных данных в вашей системе.