При отправке реестров на выплату заработной платы в банк бухгалтеры часто сталкиваются с требованием предоставить данные в определенном электронном формате — чаще всего XML. Попытка просто сохранить печатную форму ведомости (табличный документ) через стандартное меню «Сохранить как...» в формат XML не принесет желаемого результата. Банк не сможет принять такой файл, так как ему требуется строго структурированный файл обмена (реестр), соответствующий определенной XML-схеме (обычно это стандарт электронного обмена Сбербанка на основе формата WAGES.XSD).
В этой статье мы подробно разберем, как решить эту задачу в программе «1С:Зарплата и Управление Персоналом» (на примере редакции 2.5, актуальной для многих пользователей со старыми базами данных). Мы рассмотрим два основных пути решения: использование штатного (типового) механизма программы, который не требует программирования, и создание собственной внешней обработки с индивидуальной выгрузкой XML-пакета.
Перед тем как приступать к написанию собственного кода, всегда важно проверить возможности типовой конфигурации. Фирма «1С» совместно со Сбербанком давно разработала и внедрила стандарт обмена данными. Для его использования не нужно быть программистом, достаточно правильно настроить программу.
Давайте разберем этот процесс по шагам:
windows-1251) и формат обмена (например, универсальный стандарт или специализированный формат Сбербанка).Этот способ является наиболее предпочтительным, поскольку встроенный механизм регулярно обновляется фирмой «1С» при изменении требований законодательства или банковских стандартов.
Бывают ситуации, когда типовой обмен по каким-то причинам использовать невозможно: например, конфигурация сильно изменена, база данных повреждена или банк требует специфическую структуру XML-файла, которая отличается от стандартной. В этом случае мы можем написать собственную внешнюю обработку.
Давайте разберем, как создать такую обработку в конфигураторе 1С и какой программный код для этого потребуется.
Для создания инструмента выполним следующие действия:
Проанализируем структуру запроса и алгоритм генерации 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.Закрыть();
Предупреждение("Выгрузка успешно завершена! Файл сохранен.");
Давайте выясним причину возможных ошибок, с которыми вы можете столкнуться при адаптации этого кода под свои нужды, и проанализируем ключевые моменты алгоритма:
ПОЛНОЕ СОЕДИНЕНИЕ по полю Физлицо между начислениями, ФИО и регистром сведений ЛицевыеСчетаРаботниковОрганизации. Если у вас крупная организация, очень важно убедиться, что у всех сотрудников в документе выплаты действительно заполнены карточки. В коде мы добавили проверку Если ПустаяСтрока(Стр.НомерСчета) Тогда Продолжить; КонецЕсли;. Это позволит избежать создания пустых тегов <ЛицевойСчет>, из-за которых банк гарантированно отклонит файл.ГДЕ запроса. Это позволяет собирать информацию по компании в один общий файл.Формат(Сумма, "ЧГ=0; ЧРД='.'"). Это критически важно! По умолчанию платформа 1С выводит числа с разделителями триад (например, "150 000.00"), что вызовет синтаксическую ошибку при парсинге XML на стороне Сбербанка. Параметр форматирования ЧГ=0 убирает пробелы между тысячами, а ЧРД='.' жестко задает точку в качестве разделителя дробной части.ЗаписьXML принимает вторым параметром кодировку. Сбербанк требует именно кодировку windows-1251 для корректного распознавания кириллических символов (ФИО сотрудников, названия организации) в автоматизированных банковских системах.Если вы будете использовать предоставленный код, примите во внимание важное изменение в законодательстве РФ. Начиная с июня 2020 года, согласно Указанию ЦБ РФ № 5286-У, все работодатели обязаны передавать в банк коды видов доходов (например, код «1» для заработной платы) и указывать удержания по исполнительным листам.
Для соответствия современным стандартам (актуальные версии XML-форматов обмена 3.6 и 3.7) в XML-схему были добавлены новые обязательные атрибуты. В связи с этим в тег <ЗачислениеЗарплаты> или внутрь тегов <Сотрудник> современные банковские платформы требуют передавать код дохода. При использовании встроенного типового обмена 1С (Решение №1) программа сформирует эти параметры автоматически на основании настроек начислений. Если же вы используете Решение №2, вам может потребоваться дополнить код запроса и вывод тегов новыми атрибутами (например, ЗаписьXML.ЗаписатьАтрибут("КодВидаДохода", "1")), чтобы файл успешно прошел валидацию в «СберБизнес».