Как выгрузить счет-фактуру в XML утвержденного формата ФНС из 1С 7.7 для ЭДО?

Программист 1С v7.7 1C:Бухгалтерия Бухгалтерский учет IT и автоматизация бизнеса
← На главную

При переходе на электронный документооборот (ЭДО) в системах на платформе 1С:Предприятие 7.7 («Бухгалтерия 4.5», «Торговля и Склад 9.2») часто возникает задача сформировать файл электронного счета-фактуры или УПД в утвержденном ФНС формате без приобретения дорогостоящих готовых модулей интеграции. Разберем, как реализовать выгрузку данных в XML собственными силами, с какими техническими трудностями можно столкнуться и как исправить характерные ошибки структуры файла.

Анализ задачи и особенности работы с XML в 1С 7.7

В платформе 1С 7.7 отсутствуют встроенные высокоуровневые объекты сериализации XML, которые появились в версии 8 (такие как ЗаписьXML или ФабрикаXDTO). Поэтому разработчики чаще всего выбирают один из следующих путей:

  1. Прямая генерация текстового файла: построчное наполнение XML-структуры с помощью стандартного объекта Текст.
  2. Использование COM-объектов Windows: программное построение дерева элементов через MSXML2.DOMDocument.
  3. Внешние компоненты: применение штатной библиотеки 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-файл собирается вручную через конкатенацию строк, редакторы кода или валидаторы сервисов ЭДО часто выдают ошибки синтаксиса либо отображают документ как пустой. Проанализируем самые распространенные причины сбоев:

  1. Отсутствие закрывающих тегов: Если в документе открыт тег (например, корневой <Файл> или <Документ>), но пропущен завершающий тег </Файл>, парсер считает XML поврежденным (not well-formed) и не может построить дерево узлов.
  2. Специфика одинарных и двойных тегов: Теги без дочерних элементов должны быть самозакрывающимися (например, <СвОЭДОтпр ... />). Если пропустить косую черту перед закрывающей угловой скобкой, узел останется открытым и нарушит всю структуру ниже по тексту.
  3. Лишние или некорректно экранированные кавычки: В языке 1С 7.7 строковый литерал кавычки внутри строки задается удвоением """". Ошибки в склейке строк приводят к тому, что в итоговом XML атрибут получает вид НаимОрг=""Название"" вместо НаимОрг="Название".
  4. Неэкранированные спецсимволы в данных: Названия контрагентов и номенклатуры могут содержать символы &, <, >, кавычки или апострофы. Любой символ & (например, «ООО & Ко») без преобразования в &amp; делает XML невалидным. Для очистки строковых реквизитов рекомендуется использовать функцию СтрЗаменить.

Требования формата ФНС и интеграция с сервисами ЭДО

Выясним, какие правила регламента ФНС необходимо соблюдать для успешной загрузки выгруженного файла через личный кабинет оператора:

  1. Именование файла: Имя XML-файла строго регламентировано соответствующим приказом ФНС. Оно состоит из префикса формата (например, ON_NSCHFDOPPR или ON_SFAKT), идентификатора получателя, идентификатора отправителя, даты и сгенерированного уникального идентификатора (GUID). При несоблюдении маски имени сервис ЭДО отклонит файл еще на этапе загрузки.
  2. Идентификаторы участников (ИдУчЭДО): В блоке <СвУчДокОбор> должны быть указаны реальные уникальные идентификаторы отправителя и получателя, присвоенные оператором документооборота. Произвольные строки недопустимы.
  3. Генерация GUID: Поскольку в платформе 1С 7.7 нет встроенного генератора GUID, для формирования уникальных идентификаторов документов и имен файлов удобно вызывать системный COM-объект Windows Scriptlet.TypeLib:

Функция ПолучитьНовыйGUID()
    Перем Скрипт;
    Скрипт = СоздатьОбъект("Scriptlet.TypeLib");
    Возврат Сред(Скрипт.Guid, 2, 36);
КонецФункции

Построение документа через COM-объект DOMDocument

Чтобы избежать рутинных ошибок с незакрытыми тегами и экранированием спецсимволов, более надежным подходом является создание 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-теги и корректно передавать идентификаторы участников документооборота.

← На главную