Как сохранить зарплатную ведомость из 1С в формате XML для Сбербанка

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

При отправке реестров на выплату заработной платы в банк бухгалтеры часто сталкиваются с требованием предоставить данные в определенном электронном формате — чаще всего XML. Попытка просто сохранить печатную форму ведомости (табличный документ) через стандартное меню «Сохранить как...» в формат XML не принесет желаемого результата. Банк не сможет принять такой файл, так как ему требуется строго структурированный файл обмена (реестр), соответствующий определенной XML-схеме (обычно это стандарт электронного обмена Сбербанка на основе формата WAGES.XSD).

В этой статье мы подробно разберем, как решить эту задачу в программе «1С:Зарплата и Управление Персоналом» (на примере редакции 2.5, актуальной для многих пользователей со старыми базами данных). Мы рассмотрим два основных пути решения: использование штатного (типового) механизма программы, который не требует программирования, и создание собственной внешней обработки с индивидуальной выгрузкой XML-пакета.

Решение №1: Использование типового механизма «Обмен с банками по зарплатным проектам»

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

Давайте разберем этот процесс по шагам:

  1. Настройка зарплатного проекта. Перейдем в меню «Расчет зарплаты по организации», далее откроем раздел «Касса, банк» и выберем пункт «Зарплатные проекты». Создадим новый проект для Сбербанка. В настройках обязательно укажем расчетный счет организации, БИК банка, а также установим флаг «Использовать обмен электронными документами». Здесь же выбирается кодировка файла (для Сбербанка традиционно используется windows-1251) и формат обмена (например, универсальный стандарт или специализированный формат Сбербанка).
  2. Ввод лицевых счетов сотрудников. Чтобы ведомость выгружалась корректно, у каждого сотрудника в базе должен быть зарегистрирован номер его лицевого счета. Для этого используется специальный документ «Ввод лицевых счетов сотрудников» (доступен в том же разделе «Касса, банк»). Если лицевые счета не будут привязаны к конкретному зарплатному проекту организации, программа просто проигнорирует этих людей при автоматической выгрузке.
  3. Подготовка ведомости к выплате. Создадим документ «Зарплата к выплате организаций». В поле «Способ выплаты» обязательно укажем «Через банк» и выберем наш настроенный зарплатный проект. Заполним документ сотрудниками и рассчитаем суммы. После заполнения проведем документ.
  4. Выгрузка реестра. Перейдем в специализированное рабочее место «Импорт/экспорт операций с лицевыми счетами сотрудников» (или «Обмен с банками по зарплатным проектам»). В блоке экспорта выберем наш зарплатный проект, укажем путь для сохранения файлов на диске компьютера и нажмем кнопку «Выгрузить». Программа автоматически сформирует корректный XML-файл, содержащий заголовки с реквизитами организации, перечень сотрудников с их лицевыми счетами и суммами к зачислению, а также итоговые контрольные суммы.

Этот способ является наиболее предпочтительным, поскольку встроенный механизм регулярно обновляется фирмой «1С» при изменении требований законодательства или банковских стандартов.

Решение №2: Создание собственной внешней обработки для выгрузки в XML

Бывают ситуации, когда типовой обмен по каким-то причинам использовать невозможно: например, конфигурация сильно изменена, база данных повреждена или банк требует специфическую структуру XML-файла, которая отличается от стандартной. В этом случае мы можем написать собственную внешнюю обработку.

Давайте разберем, как создать такую обработку в конфигураторе 1С и какой программный код для этого потребуется.

Для создания инструмента выполним следующие действия:

  1. Откроем информационную базу в режиме «Конфигуратор».
  2. В меню выберем «Файл» — «Новый», укажем тип объекта «Внешняя обработка».
  3. Назовем обработку, например, «ВыгрузкаРеестраСбербанкXML».
  4. Создадим форму обработки, добавив на нее необходимые параметры для фильтрации: Организация, Банк, Договор, НачалоПериода, КонецПериода, а также поле выбора пути для сохранения готового файла.
  5. Добавим кнопку «Выгрузить», по нажатию на которую будет выполняться программный код.

Проанализируем структуру запроса и алгоритм генерации XML-файла. Ниже представлен готовый листинг кода, который необходимо поместить в модуль формы обработки:


// Определяем способ выплаты зарплаты
СпособВыплаты = Перечисления.СпособыВыплатыЗарплаты.ЧерезБанк;

Запрос = Новый Запрос;
Запрос.УстановитьПараметр("ДатаНачало", ДатаНачало);
Запрос.УстановитьПараметр("ДатаКонец", ДатаКонец);
Запрос.УстановитьПараметр("Организация", Организация);
Запрос.УстановитьПараметр("СпособВыплаты", СпособВыплаты);
Запрос.УстановитьПараметр("Банк", Банк);

// Формируем текст запроса к табличной части документа и регистрам сведений
Запрос.Текст = 
"ВЫБРАТЬ
|	ЗарплатаКВыплатеОрганизацийЗарплата.Ссылка.Дата КАК Дата,
|	ЗарплатаКВыплатеОрганизацийЗарплата.Ссылка.Организация КАК Организация,
|	ЗарплатаКВыплатеОрганизацийЗарплата.Ссылка.Организация.ОГРН КАК ОГРН,
|	ЗарплатаКВыплатеОрганизацийЗарплата.Сумма КАК Сумма,
|	ЛицевыеСчетаРаботниковОрганизации.НомерЛицевогоСчета КАК НомерСчета,
|	ФИОФизЛиц.Фамилия,
|	ФИОФизЛиц.Имя,
|	ФИОФизЛиц.Отчество,
|	ЗарплатаКВыплатеОрганизацийЗарплата.Ссылка.СуммаДокумента,
|	ЗарплатаКВыплатеОрганизацийЗарплата.НомерСтроки
|ИЗ
|	Документ.ЗарплатаКВыплатеОрганизаций.Зарплата КАК ЗарплатаКВыплатеОрганизацийЗарплата
|	ПОЛНОЕ СОЕДИНЕНИЕ РегистрСведений.ЛицевыеСчетаРаботниковОрганизации КАК ЛицевыеСчетаРаботниковОрганизации
|		ПО ЗарплатаКВыплатеОрганизацийЗарплата.Физлицо = ЛицевыеСчетаРаботниковОрганизации.ФизЛицо
|	ПОЛНОЕ СОЕДИНЕНИЕ РегистрСведений.ФИОФизЛиц КАК ФИОФизЛиц
|		ПО ЗарплатаКВыплатеОрганизацийЗарплата.Физлицо = ФИОФизЛиц.ФизЛицо
|ГДЕ
|	ЗарплатаКВыплатеОрганизацийЗарплата.Ссылка.ПометкаУдаления = ЛОЖЬ
|	И ЗарплатаКВыплатеОрганизацийЗарплата.Ссылка.Проведен = ИСТИНА
|	И ЗарплатаКВыплатеОрганизацийЗарплата.Ссылка.Дата МЕЖДУ &ДатаНачало И &ДатаКонец
|	И ЗарплатаКВыплатеОрганизацийЗарплата.Ссылка.СпособВыплаты = &СпособВыплаты
|	И ЗарплатаКВыплатеОрганизацийЗарплата.Ссылка.Организация = &Организация
|	И ЗарплатаКВыплатеОрганизацийЗарплата.Ссылка.Банк = &Банк
|	И ЛицевыеСчетаРаботниковОрганизации.Организация = &Организация
|
|СГРУППИРОВАТЬ ПО
|	ФИОФизЛиц.Фамилия,
|	ЗарплатаКВыплатеОрганизацийЗарплата.Ссылка.Дата,
|	ЗарплатаКВыплатеОрганизацийЗарплата.Ссылка.Организация,
|	ЗарплатаКВыплатеОрганизацийЗарплата.Ссылка.Организация.ОГРН,
|	ЗарплатаКВыплатеОрганизацийЗарплата.Сумма,
|	ЛицевыеСчетаРаботниковОрганизации.НомерЛицевогоСчета,
|	ФИОФизЛиц.Имя,
|	ФИОФизЛиц.Отчество,
|	ЗарплатаКВыплатеОрганизацийЗарплата.Ссылка.СуммаДокумента,
|	ЗарплатаКВыплатеОрганизацийЗарплата.НомерСтроки";

Выборка = Запрос.Выполнить().Выгрузить();

ТекстДата = Формат(ДатаПлатежки, "ДФ=""гггг-ММ-дд""");
ЗаписьXML = Новый ЗаписьXML;

// Открываем файл для записи с кодировкой Windows-1251
ЗаписьXML.ОткрытьФайл(Путь + "\" + "Реестр по карточкам " + Организация.Наименование + "z.xml", "windows-1251");
ЗаписьXML.ЗаписатьОбъявлениеXML();

// Записываем корневой элемент и его атрибуты
ЗаписьXML.ЗаписатьНачалоЭлемента("СчетаПК");
ЗаписьXML.ЗаписатьАтрибут("ДатаФормирования", ТекстДата);
ЗаписьXML.ЗаписатьАтрибут("НомерДоговора", Договор);
ЗаписьXML.ЗаписатьАтрибут("НаименованиеОрганизации", Организация.НаименованиеПолное);
ЗаписьXML.ЗаписатьАтрибут("ИНН", Организация.ИНН);
ЗаписьXML.ЗаписатьАтрибут("РасчетныйСчетОрганизации", Банк.ОсновнойБанковскийСчет.НомерСчета);
ЗаписьXML.ЗаписатьАтрибут("БИК", Банк.ОсновнойБанковскийСчет.Банк.Код);
ЗаписьXML.ЗаписатьАтрибут("НомерРеестра", ТекНомер);
ЗаписьXML.ЗаписатьАтрибут("ДатаРеестра", ТекстДата);

ЗаписьXML.ЗаписатьНачалоЭлемента("ЗачислениеЗарплаты");

НомерСтроки = 0;
Для Каждого Стр из Выборка Цикл
    // Проверяем наличие лицевого счета у сотрудника
    Если ПустаяСтрока(Стр.НомерСчета) Тогда
        Продолжить; // Пропускаем сотрудников без карт
    КонецЕсли;

    НомерСтроки = НомерСтроки + 1;
    ЗаписьXML.ЗаписатьНачалоЭлемента("Сотрудник");
    
    Нпп = Строка(НомерСтроки);
    ЗаписьXML.ЗаписатьАтрибут("Нпп", Нпп);
    
    ЗаписьXML.ЗаписатьНачалоЭлемента("Фамилия");
    ЗаписьXML.ЗаписатьТекст(Стр.Фамилия);
    ЗаписьXML.ЗаписатьКонецЭлемента(); // Фамилия
    
    ЗаписьXML.ЗаписатьНачалоЭлемента("Имя");
    ЗаписьXML.ЗаписатьТекст(Стр.Имя);
    ЗаписьXML.ЗаписатьКонецЭлемента(); // Имя
    
    ЗаписьXML.ЗаписатьНачалоЭлемента("Отчество");
    ЗаписьXML.ЗаписатьТекст(Стр.Отчество);
    ЗаписьXML.ЗаписатьКонецЭлемента(); // Отчество
    
    ЗаписьXML.ЗаписатьНачалоЭлемента("ОтделениеБанка");
    ЗаписьXML.ЗаписатьТекст("8635"); // Код вашего отделения Сбербанка
    ЗаписьXML.ЗаписатьКонецЭлемента(); // ОтделениеБанка
    
    ЗаписьXML.ЗаписатьНачалоЭлемента("ФилиалОтделенияБанка");
    ЗаписьXML.ЗаписатьТекст("0");
    ЗаписьXML.ЗаписатьКонецЭлемента(); // ФилиалОтделенияБанка
    
    ЗаписьXML.ЗаписатьНачалоЭлемента("ЛицевойСчет");
    ЗаписьXML.ЗаписатьТекст(Стр.НомерСчета);
    ЗаписьXML.ЗаписатьКонецЭлемента(); // ЛицевойСчет
    
    ЗаписьXML.ЗаписатьНачалоЭлемента("Сумма");
    // Форматируем число без разделителей групп и с точкой в качестве разделителя дробной части
    СуммаСтрокой = Строка(Формат(Стр.Сумма, "ЧГ=0; ЧРД='.'"));
    ЗаписьXML.ЗаписатьТекст(СуммаСтрокой);
    ЗаписьXML.ЗаписатьКонецЭлемента(); // Сумма
    
    ЗаписьXML.ЗаписатьКонецЭлемента(); // Сотрудник
КонецЦикла;

ЗаписьXML.ЗаписатьКонецЭлемента(); // ЗачислениеЗарплаты

// Заполняем служебную информацию
ЗаписьXML.ЗаписатьНачалоЭлемента("ВидЗачисления");
ЗаписьXML.ЗаписатьТекст("01"); // Код зачисления зарплаты
ЗаписьXML.ЗаписатьКонецЭлемента(); // ВидЗачисления

ЗаписьXML.ЗаписатьНачалоЭлемента("ПлатежноеПоручение");
ЗаписьXML.ЗаписатьТекст(НомерПлатежки);
ЗаписьXML.ЗаписатьКонецЭлемента(); // ПлатежноеПоручение

ЗаписьXML.ЗаписатьНачалоЭлемента("ДатаПлатежногоПоручения");
ЗаписьXML.ЗаписатьТекст(ТекстДата);
ЗаписьXML.ЗаписатьКонецЭлемента(); // ДатаПлатежногоПоручения

// Записываем контрольные суммы
ЗаписьXML.ЗаписатьНачалоЭлемента("КонтрольныеСуммы");

ЗаписьXML.ЗаписатьНачалоЭлемента("КоличествоЗаписей");
КоличествоЗаписей = Строка(НомерСтроки);
ЗаписьXML.ЗаписатьТекст(КоличествоЗаписей);
ЗаписьXML.ЗаписатьКонецЭлемента(); // КоличествоЗаписей

ЗаписьXML.ЗаписатьНачалоЭлемента("СуммаИтого");
Итого = Выборка.Итог("Сумма");
СуммаИтого = Строка(Формат(Итого, "ЧГ=0; ЧРД='.'"));
ЗаписьXML.ЗаписатьТекст(СуммаИтого);
ЗаписьXML.ЗаписатьКонецЭлемента(); // СуммаИтого

ЗаписьXML.ЗаписатьКонецЭлемента(); // КонтрольныеСуммы

ЗаписьXML.ЗаписатьКонецЭлемента(); // СчетаПК

// Закрываем файл и освобождаем ресурсы
ЗаписьXML.Закрыть();
Предупреждение("Выгрузка успешно завершена! Файл сохранен.");

Разбор важных технических нюансов кода

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

Современные изменения: почему старые файлы могут не пройти контроль

Если вы будете использовать предоставленный код, примите во внимание важное изменение в законодательстве РФ. Начиная с июня 2020 года, согласно Указанию ЦБ РФ № 5286-У, все работодатели обязаны передавать в банк коды видов доходов (например, код «1» для заработной платы) и указывать удержания по исполнительным листам.

Для соответствия современным стандартам (актуальные версии XML-форматов обмена 3.6 и 3.7) в XML-схему были добавлены новые обязательные атрибуты. В связи с этим в тег <ЗачислениеЗарплаты> или внутрь тегов <Сотрудник> современные банковские платформы требуют передавать код дохода. При использовании встроенного типового обмена 1С (Решение №1) программа сформирует эти параметры автоматически на основании настроек начислений. Если же вы используете Решение №2, вам может потребоваться дополнить код запроса и вывод тегов новыми атрибутами (например, ЗаписьXML.ЗаписатьАтрибут("КодВидаДохода", "1")), чтобы файл успешно прошел валидацию в «СберБизнес».

← На главную