Где найти XSD-схемы книг покупок и продаж и как реализовать их выгрузку в 1С без утечек памяти?

Программист 1С v8.3 (Управляемые формы) 1C:Бухгалтерия Налоговый учет IT и автоматизация бизнеса
← На главную

При подготовке к сдаче отчетности по НДС программисты 1С часто сталкиваются с необходимостью доработки механизмов экспорта данных в формат XML. Особенно остро этот вопрос встает в периоды реформирования налогового законодательства, когда новые форматы электронных документов (такие как книги покупок NO_NDS.8_1_003_... и книги продаж NO_NDS.9_1_003_...) уже объявлены, но еще не интегрированы в типовые конфигурации или справочники периодов применения (СППФД). Разработчикам требуется оперативно получить XSD-схемы и написать отказоустойчивый код для выгрузки.

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

Где найти актуальные XSD-схемы ФНС?

Когда новые форматы еще официально не утверждены или только вступают в силу, их может не быть на диске ИТС или в справочниках обновлений 1С. В таких ситуациях самым надежным источником является официальный сайт Федеральной налоговой службы (ФНС РФ). На портале ведомства в разделе документов и приказов регулярно публикуются архивы с XSD-схемами ко всем актуальным и перспективным форматам обмена. Пролистав страницу соответствующего приказа ФНС вниз, вы найдете прямые ссылки на скачивание необходимых xsd-файлов.

Почему Фабрика XDTO не всегда подходит для схем ФНС?

Многие разработчики по привычке пытаются загрузить полученные XSD-схемы в конфигурацию через XDTO-пакеты или прочитать их «на лету» с помощью фабрики платформы. Однако на практике этот подход часто приводит к ошибкам. Давайте разберем основные причины:

  1. Сложная структура налоговых схем. Схемы ФНС содержат множество ограничений (restriction), сложных регулярных выражений (pattern), жестких проверок длины строк и вложенных типов данных. Встроенный парсер 1С (особенно в более ранних релизах платформы) может некорректно обрабатывать подобные конструкции, что вызывает неинформативные системные ошибки еще на этапе инициализации фабрики.
  2. Проблема критического потребления памяти (Out of Memory). Фабрика XDTO работает по объектной модели (DOM). Это означает, что перед записью XML-файла платформа пытается построить в оперативной памяти полное дерево объектов. Если у вашей организации или клиента объем книги покупок или продаж превышает десятки тысяч строк (что стандартно для крупного ритейла или дистрибуции), объем создаваемых объектов XDTO мгновенно заполнит всю доступную память процесса. Это неизбежно приведет к аварийному завершению работы 1С.

Альтернативное решение: Потоковая запись и чтение XML

Для обеспечения стабильной работы и гарантированной выгрузки файлов любого объема мы рекомендуем использовать низкоуровневые, но исключительно быстрые последовательные механизмы платформы — объекты Запись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.НачалоЭлемента Тогда
            
            ИмяЭлемента = ЧтениеXML.Имя;
            
            // Если встретили строку книги покупок
            Если ИмяЭлемента = "КнПокупСтр" Тогда
                
                // Считываем атрибуты прямо из текущего положения курсора
                НомерСтроки = "";
                СтоимостьПокупки = 0;
                
                Пока ЧтениеXML.ПрочитатьАтрибут() Цикл
                    Если ЧтениеXML.Имя = "НомерПор" Тогда
                        НомерСтроки = ЧтениеXML.Значение;
                    ИначеЕсли ЧтениеXML.Имя = "СтоимПокупВс" Тогда
                        СтоимостьПокупки = Число(ЧтениеXML.Значение);
                    КонецЕсли;
                КонецЦикла;
                
                // Вызываем процедуру обработки отдельной строки (например, запись во временную таблицу или документ)
                ОбработатьСтрокуКнигиПокупок(НомерСтроки, СтоимостьПокупки);
                
            КонецЕсли;
            
        КонецЕсли;
        
    КонецЦикла;
    
    ЧтениеXML.Закрыть();

КонецПроцедуры

Как проверить сформированный XML на соответствие XSD-схеме?

Отказываясь от Фабрики XDTO, мы теряем встроенный механизм автоматической валидации документа. Однако выполнять валидацию всё равно необходимо, чтобы гарантировать успешный прием отчета налоговым органом. Сделать это можно двумя надежными способами:

  1. Проверка через внешние библиотеки (COM-объекты): Для ОС Windows можно задействовать системный парсер MSXML, который отлично справляется с проверкой больших файлов по схеме.
    
    Валидатор = Новый COMОбъект("MSXML2.DOMDocument.6.0");
    Схемы = Новый COMОбъект("MSXML2.XMLSchemaCache.6.0");
    Схемы.add("http://link-to-namespace", ПутьКФайлуXSD);
    Валидатор.schemas = Схемы;
    Валидатор.load(ПутьКФайлуXML);
    Если Валидатор.parseError.errorCode <> 0 Тогда
        Сообщить("Ошибка валидации: " + Валидатор.parseError.reason);
    КонецЕсли;
    
  2. Использование специализированных утилит ФНС: Перед отправкой отчета клиенту всегда можно прогнать полученные XML-файлы через официальную утилиту проверки налоговой отчетности (например, встроенный тестер в программах отправки отчетности или «Налогоплательщик ЮЛ»).

Таким образом, сочетание потокового формирования XML и точечной валидации позволяет разработчикам 1С создавать максимально производительные, масштабируемые и отказоустойчивые решения для сдачи даже самых объемных деклараций по НДС.

← На главную