При переходе на электронный документооборот (ЭДО) в системах на платформе 1С:Предприятие 7.7 («Бухгалтерия 4.5», «Торговля и Склад 9.2») часто возникает задача сформировать файл электронного счета-фактуры или УПД в утвержденном ФНС формате без приобретения дорогостоящих готовых модулей интеграции. Разберем, как реализовать выгрузку данных в XML собственными силами, с какими техническими трудностями можно столкнуться и как исправить характерные ошибки структуры файла.
В платформе 1С 7.7 отсутствуют встроенные высокоуровневые объекты сериализации XML, которые появились в версии 8 (такие как ЗаписьXML или ФабрикаXDTO). Поэтому разработчики чаще всего выбирают один из следующих путей:
Текст.MSXML2.DOMDocument.V7Plus.dll или специализированных внешних компонент операторов ЭДО.Рассмотрим подробнее наиболее популярный и простой способ — программную сборку структуры XML через объект Текст, а также разберем, почему формируемый файл может не распознаваться XML-парсерами и личным кабинетом оператора.
Посмотрим на типовой алгоритм обхода строк документа и генерации титула продавца. Для корректной кодировки обязательно указываем кодовую страницу Windows перед записью файла.
Функция ВыгрузитьСчетФактуру(Конт, КаталогВыгрузки)
Перем Т, ИмяФайла, ДокОсн, Товар, КодЕдИзм;
Перем ИтогоСумма, ИтогоНДС, ИтогоСуммаБезНДС, НС;
Т = СоздатьОбъект("Текст");
Т.КодоваяСтраница(0); // Кодировка Windows-1251
// Заголовок XML-документа
Т.ДобавитьСтроку("<?xml version=""1.0"" encoding=""windows-1251""?>");
Т.ДобавитьСтроку("<Файл ИдФайл=""ON_SFAKT_" + СокрЛП(Конт.НомерДок) + """ ВерсПрог=""1C 7.7"" ВерсФорм=""5.01"">");
// Служебная часть с информацией об участниках ЭДО
Т.ДобавитьСтроку(" <СвУчДокОбор ИдОтпр=""2AE-ИНН-КПП"" ИдПол=""2AE-ИНН-КПП"">");
Т.ДобавитьСтроку(" <СвОЭДОтпр ИдЭДО=""2AE"" НаимОЭД=""Оператор ЭДО"" ИННЮЛ=""0000000000""/>");
Т.ДобавитьСтроку(" </СвУчДокОбор>");
// Информация о документе
Т.ДобавитьСтроку(" <Документ КНД=""1115125"" Функция=""СЧФ"" ПоФактХЖ=""Документ об отгрузке"">");
Т.ДобавитьСтроку(" <СвСчФакт НомерСчФ=""" + СокрЛП(Конт.НомерДок) + """ ДатаСчФ=""" + Формат(Конт.ДатаДок, "Д ДДММГГГГ") + """>");
Т.ДобавитьСтроку(" <СвПрод>");
Т.ДобавитьСтроку(" <ИдСв>");
Т.ДобавитьСтроку(" <СвЮЛ НаимОрг=""" + СокрЛП(Конт.Фирма.ПолнНаименование) + """ ИННЮЛ=""" + СокрЛП(Конт.Фирма.ИНН) + """ КПП=""" + СокрЛП(Конт.Фирма.КПП) + """/>");
Т.ДобавитьСтроку(" </ИдСв>");
Т.ДобавитьСтроку(" </СвПрод>");
// Табличная часть с товарами
Т.ДобавитьСтроку(" <ТаблСчФакт>");
ИтогоСумма = 0;
ИтогоНДС = 0;
ИтогоСуммаБезНДС = 0;
НС = 0;
Конт.ВыбратьСтроки();
Пока Конт.ПолучитьСтроку() = 1 Цикл
НС = НС + 1;
Товар = СтрЗаменить(СокрЛП(Конт.Номенклатура.Наименование), """", "");
Попытка
КодЕдИзм = СокрЛП(Конт.Номенклатура.БазоваяЕдиница.ОКЕИ.Код);
Исключение
КодЕдИзм = "796"; // шт по умолчанию
КонецПопытки;
Т.ДобавитьСтроку(" <СведТов НомСтр=""" + НС + """ НаимТов=""" + Товар + """ ОКЕИ_Тов=""" + КодЕдИзм + """ КолТов=""" + Конт.Количество + """ ЦенаТов=""" + Конт.Цена + """ СтТовБезНДС=""" + (Конт.Сумма - Конт.СуммаНДС) + """ НалСт=""" + Конт.СтавкаНДС + """ СумНал=""" + Конт.СуммаНДС + """ СтТовУчНал=""" + Конт.Сумма + """/>");
ИтогоСумма = ИтогоСумма + Конт.Сумма;
ИтогоНДС = ИтогоНДС + Конт.СуммаНДС;
ИтогоСуммаБезНДС = ИтогоСуммаБезНДС + (Конт.Сумма - Конт.СуммаНДС);
КонецЦикла;
Т.ДобавитьСтроку(" <ВсегоОпл СтТовБезНДСВсего=""" + ИтогоСуммаБезНДС + """ СумНалВсего=""" + ИтогоНДС + """ СтТовУчНалВсего=""" + ИтогоСумма + """/>");
Т.ДобавитьСтроку(" </ТаблСчФакт>");
Т.ДобавитьСтроку(" </СвСчФакт>");
Т.ДобавитьСтроку(" </Документ>");
Т.ДобавитьСтроку("</Файл>");
ИмяФайла = СокрЛП(КаталогВыгрузки) + "\ON_SFAKT_" + СокрЛП(Конт.НомерДок) + ".xml";
Т.Записать(ИмяФайла);
Возврат ИмяФайла;
КонецФункции
Когда XML-файл собирается вручную через конкатенацию строк, редакторы кода или валидаторы сервисов ЭДО часто выдают ошибки синтаксиса либо отображают документ как пустой. Проанализируем самые распространенные причины сбоев:
<Файл> или <Документ>), но пропущен завершающий тег </Файл>, парсер считает XML поврежденным (not well-formed) и не может построить дерево узлов.<СвОЭДОтпр ... />). Если пропустить косую черту перед закрывающей угловой скобкой, узел останется открытым и нарушит всю структуру ниже по тексту."""". Ошибки в склейке строк приводят к тому, что в итоговом XML атрибут получает вид НаимОрг=""Название"" вместо НаимОрг="Название".&, <, >, кавычки или апострофы. Любой символ & (например, «ООО & Ко») без преобразования в & делает XML невалидным. Для очистки строковых реквизитов рекомендуется использовать функцию СтрЗаменить.Выясним, какие правила регламента ФНС необходимо соблюдать для успешной загрузки выгруженного файла через личный кабинет оператора:
ON_NSCHFDOPPR или ON_SFAKT), идентификатора получателя, идентификатора отправителя, даты и сгенерированного уникального идентификатора (GUID). При несоблюдении маски имени сервис ЭДО отклонит файл еще на этапе загрузки.<СвУчДокОбор> должны быть указаны реальные уникальные идентификаторы отправителя и получателя, присвоенные оператором документооборота. Произвольные строки недопустимы.Scriptlet.TypeLib:
Функция ПолучитьНовыйGUID()
Перем Скрипт;
Скрипт = СоздатьОбъект("Scriptlet.TypeLib");
Возврат Сред(Скрипт.Guid, 2, 36);
КонецФункции
Чтобы избежать рутинных ошибок с незакрытыми тегами и экранированием спецсимволов, более надежным подходом является создание XML через объект MSXML2.DOMDocument. В этом случае парсер операционной системы автоматически контролирует корректность XML-дерева:
Процедура СформироватьЧерезDOM()
Перем XMLДок, КорневойУзел, УзелДокумент;
XMLДок = СоздатьОбъект("MSXML2.DOMDocument");
XMLДок.appendChild(XMLДок.createProcessingInstruction("xml", "version=""1.0"" encoding=""windows-1251"""));
КорневойУзел = XMLДок.createElement("Файл");
КорневойУзел.setAttribute("ИдФайл", "ON_SFAKT_123");
КорневойУзел.setAttribute("ВерсФорм", "5.01");
XMLДок.appendChild(КорневойУзел);
УзелДокумент = XMLДок.createElement("Документ");
УзелДокумент.setAttribute("КНД", "1115125");
КорневойУзел.appendChild(УзелДокумент);
XMLДок.save("C:\Выгрузка\Invoice.xml");
КонецПроцедуры
Таким образом, ручная выгрузка счетов-фактур в формате ФНС из 1С 7.7 реализуется без приобретения сторонних модулей. Главное — строго следовать структуре утвержденного формата, закрывать все XML-теги и корректно передавать идентификаторы участников документооборота.