При подготовке к сдаче отчетности по НДС программисты 1С часто сталкиваются с необходимостью доработки механизмов экспорта данных в формат XML. Особенно остро этот вопрос встает в периоды реформирования налогового законодательства, когда новые форматы электронных документов (такие как книги покупок NO_NDS.8_1_003_... и книги продаж NO_NDS.9_1_003_...) уже объявлены, но еще не интегрированы в типовые конфигурации или справочники периодов применения (СППФД). Разработчикам требуется оперативно получить XSD-схемы и написать отказоустойчивый код для выгрузки.
В этой статье мы подробно разберем, где получить актуальные схемы ФНС, почему стандартная Фабрика XDTO в 1С может давать сбои при обработке этих файлов, и как реализовать высокопроизводительную потоковую выгрузку данных без риска переполнения оперативной памяти.
Когда новые форматы еще официально не утверждены или только вступают в силу, их может не быть на диске ИТС или в справочниках обновлений 1С. В таких ситуациях самым надежным источником является официальный сайт Федеральной налоговой службы (ФНС РФ). На портале ведомства в разделе документов и приказов регулярно публикуются архивы с XSD-схемами ко всем актуальным и перспективным форматам обмена. Пролистав страницу соответствующего приказа ФНС вниз, вы найдете прямые ссылки на скачивание необходимых xsd-файлов.
Многие разработчики по привычке пытаются загрузить полученные XSD-схемы в конфигурацию через XDTO-пакеты или прочитать их «на лету» с помощью фабрики платформы. Однако на практике этот подход часто приводит к ошибкам. Давайте разберем основные причины:
restriction), сложных регулярных выражений (pattern), жестких проверок длины строк и вложенных типов данных. Встроенный парсер 1С (особенно в более ранних релизах платформы) может некорректно обрабатывать подобные конструкции, что вызывает неинформативные системные ошибки еще на этапе инициализации фабрики.Для обеспечения стабильной работы и гарантированной выгрузки файлов любого объема мы рекомендуем использовать низкоуровневые, но исключительно быстрые последовательные механизмы платформы — объекты ЗаписьXML и ЧтениеXML. Они работают напрямую с диском, не создавая тяжелых объектных моделей в ОЗУ.
Давайте подробно рассмотрим, как реализовать процесс ручной генерации файла книги покупок/продаж по схеме ФНС шаг за шагом.
Проанализируем пример кода, который последовательно формирует XML-структуру книги продаж. Мы используем объект ЗаписьXML для создания элементов и записи их атрибутов прямо «на лету».
Процедура ВыгрузитьКнигуПродажВXML(ПутьКФайлу, ВыборкаДанных)
ЗаписьXML = Новый ЗаписьXML;
// Настраиваем параметры записи: кодировка UTF-8 и автоотступы для читаемости
ПараметрыЗаписи = Новый ПараметрыЗаписиXML("UTF-8", "1.0", Истина, Истина, Символы.Таб);
ЗаписьXML.ОткрытьФайл(ПутьКФайлу, ПараметрыЗаписи);
// Пишем стандартный заголовок XML
ЗаписьXML.ЗаписатьОбъявлениеXML();
// Формируем корневой элемент "Файл" с обязательными служебными атрибутами ФНС
ЗаписьXML.ЗаписатьНачалоЭлемента("Файл");
ЗаписьXML.ЗаписатьАтрибут("ИдФайл", "NO_NDS.9_1_003_03_05_06_01"); // Идентификатор файла по формату
ЗаписьXML.ЗаписатьАтрибут("ВерсПрог", "1С:Предприятие 8.3");
ЗаписьXML.ЗаписатьАтрибут("ВерсФорм", "5.06"); // Версия формата по XSD
// Элемент "Документ"
ЗаписьXML.ЗаписатьНачалоЭлемента("Документ");
ЗаписьXML.ЗаписатьАтрибут("Индекс", "1");
// Сведения о составителе книги (например, Налогоплательщик)
ЗаписьXML.ЗаписатьНачалоЭлемента("СвНП");
ЗаписьXML.ЗаписатьНачалоЭлемента("НПЮЛ");
ЗаписьXML.ЗаписатьАтрибут("НаимОрг", "ОБЩЕСТВО С ОГРАНИЧЕННОЙ ОТВЕТСТВЕННОСТЬЮ ""РОГА И КОПЫТА""");
ЗаписьXML.ЗаписатьАтрибут("ИННЮЛ", "7701010101");
ЗаписьXML.ЗаписатьАтрибут("КПП", "770101001");
ЗаписьXML.ЗаписатьКонецЭлемента(); // НПЮЛ
ЗаписьXML.ЗаписатьКонецЭлемента(); // СвНП
// Переходим непосредственно к табличной части — Книге продаж
ЗаписьXML.ЗаписатьНачалоЭлемента("КнигаПродаж");
НомерСтроки = 0;
// Последовательно обходим выборку из базы данных
Пока ВыборкаДанных.Следующий() Цикл
НомерСтроки = НомерСтроки + 1;
// Начало строки книги продаж
ЗаписьXML.ЗаписатьНачалоЭлемента("КнПродСтр");
ЗаписьXML.ЗаписатьАтрибут("НомерПор", Формат(НомерСтроки, "ЧГ=0"));
// Заполняем стоимостные показатели (приводим к нужному ФНС формату с двумя знаками после запятой)
СтоимостьВсего = ВыборкаДанных.СуммаВключаяНДС;
СуммаНДС = ВыборкаДанных.НДС;
ЗаписьXML.ЗаписатьАтрибут("СтоимПродажВс", Формат(СтоимостьВсего, "ЧДЦ=2; ЧРД=.; ЧГ=0"));
// Пример обработки налоговых ставок
Если ВыборкаДанных.СтавкаНДС = Перечисления.СтавкиНДС.НДС20 Или ВыборкаДанных.СтавкаНДС = Перечисления.СтавкиНДС.НДС22 Тогда
ЗаписьXML.ЗаписатьАтрибут("СумНДСПор", Формат(СуммаНДС, "ЧДЦ=2; ЧРД=.; ЧГ=0"));
КонецЕсли;
// Завершаем формирование текущей строки
ЗаписьXML.ЗаписатьКонецЭлемента(); // КнПродСтр
КонецЦикла;
// Закрываем все открытые узлы в обратном порядке
ЗаписьXML.ЗаписатьКонецЭлемента(); // КнигаПродаж
ЗаписьXML.ЗаписатьКонецЭлемента(); // Документ
ЗаписьXML.ЗаписатьКонецЭлемента(); // Файл
// Закрываем поток записи и освобождаем файл на диске
ЗаписьXML.Закрыть();
КонецПроцедуры
Аналогично, если перед вами стоит задача прочитать входящий XML-файл книги покупок огромного размера, забудьте про попытки загрузить его целиком. Разберем, как с помощью ЧтениеXML организовать быстрый разбор файла без риска переполнить оперативную память:
Процедура РазобратьФайлКнигиПокупок(ПутьКФайлу)
ЧтениеXML = Новый ЧтениеXML;
ЧтениеXML.ОткрытьФайл(ПутьКФайлу);
// Начинаем последовательное чтение узлов файла
Пока ЧтениеXML.Прочитать() Цикл
// Нас интересует только начало элементов
Если ЧтениеXML.ТипУзла = ТипУзлаXML.НачалоЭлемента Тогда
ИмяЭлемента = ЧтениеXML.Имя;
// Если встретили строку книги покупок
Если ИмяЭлемента = "КнПокупСтр" Тогда
// Считываем атрибуты прямо из текущего положения курсора
НомерСтроки = "";
СтоимостьПокупки = 0;
Пока ЧтениеXML.ПрочитатьАтрибут() Цикл
Если ЧтениеXML.Имя = "НомерПор" Тогда
НомерСтроки = ЧтениеXML.Значение;
ИначеЕсли ЧтениеXML.Имя = "СтоимПокупВс" Тогда
СтоимостьПокупки = Число(ЧтениеXML.Значение);
КонецЕсли;
КонецЦикла;
// Вызываем процедуру обработки отдельной строки (например, запись во временную таблицу или документ)
ОбработатьСтрокуКнигиПокупок(НомерСтроки, СтоимостьПокупки);
КонецЕсли;
КонецЕсли;
КонецЦикла;
ЧтениеXML.Закрыть();
КонецПроцедуры
Отказываясь от Фабрики XDTO, мы теряем встроенный механизм автоматической валидации документа. Однако выполнять валидацию всё равно необходимо, чтобы гарантировать успешный прием отчета налоговым органом. Сделать это можно двумя надежными способами:
Валидатор = Новый COMОбъект("MSXML2.DOMDocument.6.0");
Схемы = Новый COMОбъект("MSXML2.XMLSchemaCache.6.0");
Схемы.add("http://link-to-namespace", ПутьКФайлуXSD);
Валидатор.schemas = Схемы;
Валидатор.load(ПутьКФайлуXML);
Если Валидатор.parseError.errorCode <> 0 Тогда
Сообщить("Ошибка валидации: " + Валидатор.parseError.reason);
КонецЕсли;
Таким образом, сочетание потокового формирования XML и точечной валидации позволяет разработчикам 1С создавать максимально производительные, масштабируемые и отказоустойчивые решения для сдачи даже самых объемных деклараций по НДС.