Стандартный механизм синхронизации между конфигурациями «Зарплата и управление персоналом 3.1» (ЗУП) и «Бухгалтерия предприятия 3.0» (БП), работающий на базе технологии EnterpriseData, в большинстве случаев успешно справляется со своими задачами. Однако на практике разработчики и бухгалтеры часто сталкиваются со следующими проблемами:
В этой статье мы подробно разберем, как реализовать перенос документа ОтражениеЗарплатыВБухучете без включения типовой синхронизации, используя альтернативные и более контролируемые методы.
---
Этот способ является наиболее гибким и надежным. Мы создаем внешнюю обработку выгрузки для ЗУП 3.1, которая сериализует данные документа ОтражениеЗарплатыВБухучете в файл, и обработку загрузки для БП 3.0, которая этот файл читает и заполняет документ в приемнике.
Рассмотрим структуру выгрузки. Поскольку в ЗУП нет плана счетов, документ оперирует справочником СпособыОтраженияЗарплатыВБухучете. Нам необходимо выгрузить текстовые наименования этих способов, суммы, а также информацию о подразделениях и сотрудниках (если включен детальный учет).
Проанализируем пример кода для выгрузки данных из ЗУП 3.1 в формат JSON:
// Функция формирует структуру данных документа для экспорта
Функция ВыгрузитьДокументВJSON(ДокументСсылка) Экспорт
ДанныеДокумента = Новый Структура;
ДанныеДокумента.Вставить("Дата", ДокументСсылка.Дата);
ДанныеДокумента.Вставить("Номер", ДокументСсылка.Номер);
ДанныеДокумента.Вставить("ПериодРегистрации", ДокументСсылка.ПериодРегистрации);
ДанныеДокумента.Вставить("ОрганизацияНаименование", ДокументСсылка.Организация.Наименование);
ДанныеДокумента.Вставить("ОрганизацияИНН", ДокументСсылка.Организация.ИНН);
// Выгрузка табличной части "Начисления"
ТаблицаНачислений = Новый Массив;
Для Каждого СтрокаТЧ Из ДокументСсылка.Начисления Цикл
СтрокаДанных = Новый Структура;
// Получаем родительское подразделение, если требуется свертка
РодительскоеПодразделение = ПолучитьРодительскоеПодразделение(СтрокаТЧ.Подразделение);
СтрокаДанных.Вставить("ПодразделениеНаименование", РодительскоеПодразделение.Наименование);
СтрокаДанных.Вставить("СотрудникФИО", СтрокаТЧ.Сотрудник.Наименование);
СтрокаДанных.Вставить("СотрудникСНИЛС", СтрокаТЧ.Сотрудник.ФизическоеЛицо.СтраховойНомерПФР);
СтрокаДанных.Вставить("СпособОтражения", СтрокаТЧ.СпособОтражения.Наименование);
СтрокаДанных.Вставить("Сумма", СтрокаТЧ.Сумма);
ТаблицаНачислений.Добавить(СтрокаДанных);
КонецЦикла;
ДанныеДокумента.Вставить("Начисления", ТаблицаНачислений);
// Запись в файл JSON
ЗаписьJSON = Новый ЗаписьJSON;
ПараметрыЗаписи = Новый ПараметрыЗаписиJSON(ПереносСтрокJSON.Нет);
ЗаписьJSON.ОткрытьФайл("C:\Temp\SalaryReflection.json", , , ПараметрыЗаписи);
ЗаписатьJSON(ЗаписьJSON, ДанныеДокумента);
ЗаписьJSON.Закрыть();
Возврат Истина;
КонецФункции
При загрузке этого файла в БП 3.0 мы должны решить ключевую задачу: сопоставить текстовые наименования подразделений и способов отражения с существующими объектами в базе бухгалтерии. Если объект не найден, система может либо выдать предупреждение, либо создать его автоматически (в зависимости от настроек обработки).
---
Часто возникает ситуация, когда структура подразделений в ЗУП избыточна для целей бухгалтерского учета. Например, в ЗУП расчет ведется по подразделению «Производство — Производство Железок», а бухгалтерия желает видеть затраты обобщенно на счете 20 по подразделению «Производство».
Чтобы решить эту задачу «на лету» без изменения типовой конфигурации, мы можем применить рекурсивный алгоритм поиска родительского подразделения при выгрузке данных. Выясним, как программно подняться по иерархии справочника до нужного уровня:
Функция ПолучитьРодительскоеПодразделение(ПодразделениеИсточник)
Если Не ЗначениеЗаполнено(ПодразделениеИсточник) Тогда
Возврат Справочники.ПодразделенияОрганизаций.ПустаяСсылка();
КонецЕсли;
// Если у подразделения нет родителя — это и есть корневой элемент
Если Не ЗначениеЗаполнено(ПодразделениеИсточник.Родитель) Тогда
Возврат ПодразделениеИсточник;
КонецЕсли;
// Если нам нужен строго первый уровень вложенности (верхний родитель)
ТекущийЭлемент = ПодразделениеИсточник;
Пока ЗначениеЗаполнено(ТекущийЭлемент.Родитель) Цикл
ТекущийЭлемент = ТекущийЭлемент.Родитель;
КонецЦикла;
Возврат ТекущийЭлемент;
КонецФункции
Важное примечание: Если правила свертки более сложные (например, часть подразделений нужно сворачивать до родителя, а часть оставлять без изменений), мы можем добавить в справочник Подразделения в ЗУП дополнительный реквизит (через механизм «Дополнительные сведения и реквизиты»). Назовем его, к примеру, ПодразделениеДляБухучета. При выгрузке обработка будет проверять этот реквизит: если он заполнен, то подставляется указанное в нем подразделение, в противном случае — текущее.
---
Если в настройках параметров учета БП 3.0 аналитика расчетов с персоналом на счете 70 установлена как «Сводно по всем сотрудникам», то задача существенно упрощается. В этом случае документ ОтражениеЗарплатыВБухучете не содержит детальных записей по физическим лицам, а представляет собой сводные суммы по подразделениям и способам отражения.
В такой ситуации нет необходимости писать сложные XML-парсеры. Достаточно использовать стандартную обработку «Загрузка данных из табличного документа» или написать простую обработку заполнения табличной части:
ОтражениеЗарплатыВБухучете.Пример кода, реализующий заполнение табличной части документа БП 3.0 из предварительно прочитанного табличного документа:
Процедура ЗаполнитьТЧИзТабличногоДокумента(ДокументОбъект, ТабличныйДокумент)
ДокументОбъект.Начисления.Очистить();
// Начинаем обход со строки, где начинаются фактические данные (пропуская шапку)
Для СтрокаНомер = 2 По ТабличныйДокумент.ВысотаТаблицы Цикл
ИмяПодразделения = ТабличныйДокумент.Область(СтрокаНомер, 1).Текст;
ИмяСпособа = ТабличныйДокумент.Область(СтрокаНомер, 2).Текст;
СуммаЗначение = Число(ТабличныйДокумент.Область(СтрокаНомер, 3).Текст);
НоваяСтрока = ДокументОбъект.Начисления.Добавить();
// Поиск объектов в базе БП
НоваяСтрока.Подразделение = Справочники.ПодразделенияОрганизаций.НайтиПоНаименованию(ИмяПодразделения);
НоваяСтрока.СпособОтражения = Справочники.СпособыОтраженияЗарплатыВБухучете.НайтиПоНаименованию(ИмяСпособа);
НоваяСтрока.Сумма = СуммаЗначение;
Если Не ЗначениеЗаполнено(НоваяСтрока.Подразделение) Тогда
ОбщегоНазначенияКлиентСервер.СообщитьПользователю(
НСтр("ru = 'Не найдено подразделение: '") + ИмяПодразделения
);
КонецЕсли;
КонецЦикла;
ДокументОбъект.Записать();
КонецПроцедуры
---
Если мы хотим избавить бухгалтера от ручного запуска внешних обработок, мы можем использовать механизм расширений. Мы можем доработать форму документа ОтражениеЗарплатыВБухучете прямо в БП 3.0, добавив туда индивидуальную кнопку «Загрузить из файла ЗУП».
Разберем, как это реализовать по шагам:
ОтражениеЗарплатыВБухучете.ЗагрузитьИзФайлаЗУП, и выводим её на командную панель формы.Такой подход сохраняет конфигурацию полностью типовой (на поддержке), но предоставляет пользователю удобный бесшовный интерфейс.
---
Чтобы избежать ошибок при переносе без синхронизации, рекомендуем придерживаться следующих правил:
Используя предложенные методы, мы можем полностью отказаться от «капризной» автоматической синхронизации в пользу простого, понятного и полностью контролируемого обмена через внешние файлы или расширения конфигурации.