Как убрать лишние переносы строк и пробелы при выгрузке УПД в XML из 1С 7.7 для Диадока

Программист Налоговый учет
← На главную

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

Разбор проблемы: Почему Диадок не принимает файл

Проанализируем ситуацию, описанную автором темы. При ручной сборке XML-файла с помощью методов записи в текст (например, через WriteLine) в файл попадают невидимые символы. В примере автора тег БезАкциз выглядит так:


<Акциз>
    <БезАкциз>
        без акциза
    </БезАкциз>
</Акциз>

Для человека это выглядит аккуратно, но для программного парсера значением тега становится не строка без акциза, а строка с символом переноса строки в начале и несколькими пробелами. Согласно приказу ФНС, регулирующему формат УПД, значение этого поля должно строго соответствовать шаблону. Любой лишний символ делает документ невалидным.

Выясним причину в коде. Автор использует процедуру xml_file.WriteLine, которая принудительно добавляет \r\n (перевод строки и возврат каретки) после каждой команды. Кроме того, в коде программно добавляются «отступы» для красоты структуры. Именно эти отступы и переносы внутри текстового узла вызывают ошибку.

Решение №1: Исправление ручной сборки текста

Если мы продолжаем использовать текстовую выгрузку, нам необходимо исключить использование WriteLine для элементов, содержащих конечные данные. Разберем по шагам, как изменить логику записи.

Во-первых, заменим метод WriteLine на Write в тех местах, где мы записываем значение тега. Во-вторых, необходимо отказаться от записи отступов перед закрывающим тегом, если внутри него находится текст. Посмотрим на исправленный фрагмент логики:


// Вместо этого:
xml_file.WriteLine(">");
xml_file.WriteLine(xml_Отступы + прм_Текст);
// Нужно записывать всё в одну строку без перевода:
xml_file.Write(">" + прм_Текст + "</" + стрИмяТега + ">");

Проанализируем ситуацию с тегом Акциз. Чтобы получить правильный результат, код вызова должен выглядеть примерно так:


xml_ЗаписатьНачалоЭлемента("Акциз");
// Для текстового узла пишем все в одну строку без перевода каретки
xml_file.Write("<БезАкциз>без акциза</БезАкциз>"); 
xml_ЗаписатьКонецЭлемента("Акциз");

Важный момент: Обратите внимание на закрывающий слэш. Ошибка в синтаксисе типа /<БезАкциз> или отсутствие слэша в закрывающем теге (как было замечено в обсуждении) приведет к полной нечитаемости XML-структуры.

Решение №2: Профессиональный подход через MSXML (DOM)

Использование текстовых функций в 1С 7.7 — это путь, полный ошибок (экранирование спецсимволов, кодировки, переносы). Рассмотрим более надежный метод с использованием COM-объекта MSXML2.DOMDocument. Этот объект сам следит за тем, чтобы структура была корректной, а текстовые узлы не содержали лишнего мусора.

Разберем реализацию этого метода. Для начала создадим объект и определим базовые функции для работы с узлами. Это позволит нам писать код в стиле, близком к 1С 8.x.

Проанализируем функции-помощники:


// Функция создания узла
Функция ДобавитьУзел(XML_DOM, XML_NODE, Имя)
    XML_CHILD = XML_DOM.createNode(1, Имя, "");
    XML_NODE.appendChild(XML_CHILD);
    Возврат XML_CHILD;
КонецФункции

// Функция добавления текста в узел
Процедура ДобавитьТекст(XML_NODE, Значение)
    XML_NODE.text = Значение; 
КонецПроцедуры

// Функция добавления атрибута
Процедура ДобавитьАтрибут(XML_NODE, Имя, Значение)
    XML_NODE.setAttribute(Имя, Значение);
КонецПроцедуры

Теперь посмотрим, как с помощью этих функций решить задачу автора темы без риска получить лишние пробелы:


XML_DOM = СоздатьОбъект("MSXML2.DOMDocument.6.0");
// Создаем корень и структуру
Root = XML_DOM.createElement("Файл");
XML_DOM.appendChild(Root);

// Добавляем таблицу и сведения о товаре
СведТов = ДобавитьУзел(XML_DOM, Root, "СведТов");
ДобавитьАтрибут(СведТов, "НаимТов", "Известь строительная");

// Формируем блок Акциз
Акциз = ДобавитьУзел(XML_DOM, СведТов, "Акциз");
БезАкциз = ДобавитьУзел(XML_DOM, Акциз, "БезАкциз");
ДобавитьТекст(БезАкциз, "без акциза"); // Здесь DOM никогда не добавит лишний перевод строки!

// Сохраняем файл
XML_DOM.save("C:\exports\upd.xml");

Особенности структуры СумНал и Акциз

В процессе обсуждения возник вопрос о странности структуры <СумНал><СумНал>...</СумНал></СумНал>. Выясним, является ли это ошибкой. Согласно формату ФНС для УПД:

  1. Верхний уровень СумНал — это составной элемент, описывающий налоговую составляющую строки.
  2. Вложенный уровень СумНал — это непосредственное значение суммы налога.

Следовательно, такая иерархия абсолютно корректна и должна сохраняться. При использовании ручного метода записи программисты часто ошибаются и «схлопывают» эти теги, что приводит к отказу в приеме файла со стороны Диадока.

Экранирование символов

При использовании текстового метода (Решение №1) крайне важно не забывать про спецсимволы. Если в наименовании товара встретится амперсанд & или кавычка ", XML «развалится». В 1С 7.7 необходимо вручную обрабатывать каждую строку через СтрЗаменить:

Важный совет: Если вы перейдете на MSXML2.DOMDocument, все эти замены объект будет выполнять автоматически. Вы просто передаете строку как есть в свойство text, и система сама преобразует её в валидный XML-вид.

Итоги и рекомендации

Подводя итог, можно сказать, что проблема автора вызвана исключительно попыткой форматирования вывода (красивые отступы и переводы строк). Для систем ЭДО визуальная красота XML не имеет значения, важна лишь строгость структуры и точность значений.

Мы рекомендуем:

  1. Отказаться от функции WriteLine в пользу Write при формировании содержимого тегов.
  2. Использовать объект ADODB.Stream, если требуется запись в специфических кодировках (например, UTF-8 без BOM), так как стандартные средства 1С 7.7 ограничены в этом плане.
  3. Наилучшим решением будет переход на MSXML2.DOMDocument, что снимет 90% проблем с форматированием, кодировками и спецсимволами.

Следуя этим правилам, вы сможете успешно интегрировать 1С 7.7 с современными системами электронного документооборота и избежать длительных простоев из-за ошибок валидации.

← На главную