С конца прошлого года холдинг где я работаю начал переход на ЗУП 3.1.
Вместе с этим появилось много задач в т.ч. выгрузка проводок в КА 1.1. При этом все нужно сделать в кратчайшие сроки, ведь еще нужно выполнить много других задач.
Типового обмена между вышеуказанными решениями пока нет, а возможно, и никогда не будет.
Готовых решений я не нашел и начал решать задачу собственными силами.
Начал со знакомства с типовым обменом с другими конфигурациями. Технология обмена сильно изменилась, по сравнению с ЗиК, и ЗУП 2.5 (насчет ЗУП 2.5 могу ошибаться), привычной настройки проводок, и обработки выгрузки проводок теперь нет. Но все не так страшно, как кажется при беглом осмотре.
Для знакомства с настройкой обмена пользовался информацией с сайта ИТС.
Информация для формирования бухгалтерских проводок заносится в:
- справочник организации;
- справочник подразделения;
- справочник сотрудники;
- виды начисления;
- некоторые виды документов.
При указании данных для формирования бухгалтерских проводок, используется справочник "Способы отражения зарплаты в бухгалтерском учете".
После заполнения способов отражения в БУ, можно сформировать документ "Отражение зарплаты в бухгалтерском учете". Заполнив документ увидим, что практически вся необходимая информация для формирования проводок у нас есть (скриншот с рабочей базы приложить не могу).
Типовой механизм предусматривает выгрузку элементов справочника "Отражение зарплаты в бухгалтерском учете" с последующим его заполнением (счетами и аналитикой) в бухгалтерской базе.
В книгах пишут, что человеку свойственно ходить привычными путями, пускай и не самыми лучшими. На текущий момент, я считаю, что данный вариант лучше, но когда приступал к реализации выбрал альтернативный вариант, который также предложен на ИТС.
Я решил сделать выгрузку на подобие ЗиК, т.е. настройка формирования проводок настраивается в ЗУП.
В данном варианте нужно будет синхронизировать следующие данные:
- Сотрудников. Данные по сотрудникам заполняются в каждой базе, элементы синхронизируются по реквизиту "ИНН".
- Бухгалтерские счета. Синхронизация по коду.
- Аналитика проводок:
- Перечисления - по имени.
- Элементы справочников по уникальному идентификатору.
Для получения уникального идентификатора элементов справочника и имя значений перечислений, была написана небольшая обработка:
Процедура КнопкаВыполнитьНажатие(Кнопка)
// Вставить содержимое обработчика.
Если Справочники.ТипВсеСсылки().СодержитТип(ТипЗнч(выбСправочник)) Тогда
текGUID = выбСправочник.УникальныйИдентификатор();
Иначе
НужноеЗначение = выбСправочник;
ИмяПеречисления = НужноеЗначение.Метаданные().Имя;
НужныйИндекс = Перечисления[ИмяПеречисления].Индекс(НужноеЗначение);
ИмяЗначения = Метаданные.Перечисления[ИмяПеречисления].ЗначенияПеречисления[НужныйИндекс].Имя;
текGUID = ИмяЗначения;
КонецЕсли;
//Сообщить(СтрДлина(текGUID)); //36
КонецПроцедуры
Для хранения счетов и аналитики добавил дополнительные реквизиты к справочнику "Способы отражения зарплаты в бухгалтерском учете" Администрирование -> общие настройки -> Дополнительные реквизиты и сведения
Для реквизита "Счет" длина строки 10, "Субконто" - 100, GUID - 36.
Далее настроил форму справочника "Способы отражения зарплаты в бухгалтерском учете"
Реквизит "Субконто" используется следующим образом:
- При указании элемента справочника, только информативно.
- При указании значения перечисления - содержит имя перечисления, уникальный идентификатор при этом не заполняется.
Остальная информация для формирования проводок будет вводится в форме обработки выгрузки проводок.
Сначала я пытался хранить данные из вышеуказанной формы в хранилище настроек, у меня так и не получилось сделать чтобы настройки были общими для всех пользователей. В итоге решил добавить дополнительное свойство "НастройкиПроводок" для справочника организации, с типом строка неограниченной длины, как выяснилось позже, нельзя создать дополнительной свойство с типом - строка неограниченной длины. Остановился на варианте: дополнительное свойство для каждого взноса - длинной 830. 10 (длина кода счета) + 6 * (36 (Длина уникального идентификатора) + 100) + символы разделители.
Теперь есть все необходимые данные для формирования проводок, приступаем к выгрузке.
Функции выгрузки выглядят следующим образом (обработки добавлены к статье, в тексте опишу только интересные, на мой взгляд, моменты)
&НаСервере
Функция ВыгрузитьПроводкиНаСервере()
// Вставить содержимое обработчика.
СписокДокументов = ВыгрузитьПроводкиНаСервере_ПолучитьСписокДокументов();
ствСвойстваСпособовОтраженияБУ = ВыгрузитьПроводкиНаСервере_ПолучитьСвойстваОтбораженияБУ(СписокДокументов);
стрВыгрузка = Новый Структура("Организация,НачалоПериода,КонецПериода,Проводки");
стрВыгрузка.Организация = Организация.Наименование;
стрВыгрузка.НачалоПериода = НачДата;
стрВыгрузка.КонецПериода = КонДата;
Проводки = Новый Массив();
ВыгрузитьПроводкиНаСервере_СформироватьПроводкиПоНачислениям(СписокДокументов, ствСвойстваСпособовОтраженияБУ, Проводки);
ВыгрузитьПроводкиНаСервере_СформироватьПроводкиПоВзносам(СписокДокументов, ствСвойстваСпособовОтраженияБУ, Проводки);
ВыгрузитьПроводкиНаСервере_СформироватьПроводкиПоНДФЛ(СписокДокументов, ствСвойстваСпособовОтраженияБУ, Проводки);
стрВыгрузка.Проводки = Проводки;
ТекстXML = СтруктураВXML(стрВыгрузка, "ВыгрузкаЗУП_КА");
Возврат ТекстXML;
КонецФункции
&НаКлиенте
Процедура ВыгрузитьПроводки(Команда)
ТекстXML = ВыгрузитьПроводкиНаСервере();
ЗаписьXML = Новый ЗаписьXML();
ЗаписьXML.ОткрытьФайл(выбФайл, "windows-1251");
ЗаписьXML.ЗаписатьОбъявлениеXML();
ЗаписьXML.ЗаписатьБезОбработки(ТекстXML);
ЗаписьXML.Закрыть();
ПоказатьПредупреждение(, "Обработка завершена");
КонецПроцедуры
В данном случае можно было воспользоваться стандартной сериализацией, собственную функцию я использую, т.к. структура XML получается проще, а соответственно и более читабельной.
Функция СтруктураВXML(вхСтруктура, НаименованиеКорневогоУзла)
ТекстXML = "";
ЗаписьXML = Новый ЗаписьXML();
ЗаписьXML.УстановитьСтроку("windows-1251");
ЗаписьXML.ЗаписатьНачалоЭлемента(НаименованиеКорневогоУзла);
Для Каждого Элемент Из вхСтруктура Цикл
Если ТипЗнч(Элемент.Значение) = Тип("Структура") Тогда
ЗаписьXML.ЗаписатьБезОбработки(СтруктураВXML(Элемент.Значение, Элемент.Ключ));
ИначеЕсли ТипЗнч(Элемент.Значение) = Тип("Массив") Тогда
ЗаписьXML.ЗаписатьНачалоЭлемента(Элемент.Ключ);
Для Каждого СтрокаТаблицы Из Элемент.Значение Цикл
ЗаписьXML.ЗаписатьБезОбработки(СтруктураВXML(СтрокаТаблицы, "Строка"));
КонецЦикла;
ЗаписьXML.ЗаписатьКонецЭлемента();
Иначе
ЗаписьXML.ЗаписатьАтрибут(Элемент.Ключ, XMLСтрока(Элемент.Значение));
КонецЕсли;
КонецЦикла;
ЗаписьXML.ЗаписатьКонецЭлемента();
ТекстXML = ЗаписьXML.Закрыть();
Возврат ТекстXML;
КонецФункции
Данную функция я написал, когда делал обмен между базами 1С8 -> 1С77, также рассматривал стандартную реализацию, но решил что проще написать собственную.
Добавить свою обработку в дополнительные в новых конфигурациях уже не так просто. ЗУП отказывается добавлять обработку в список дополнительных, без нижеуказанной функции в модуле:
Функция СведенияОВнешнейОбработке() Экспорт
РегистрационныеДанные = Новый Структура;
РегистрационныеДанные.Вставить("Наименование", "Выгрузка проводок ЗУП 3.1 -> КА 1.1");
РегистрационныеДанные.Вставить("БезопасныйРежим", Ложь);
РегистрационныеДанные.Вставить("Вид", "ДополнительнаяОбработка");
РегистрационныеДанные.Вставить("Версия", "1.0");
РегистрационныеДанные.Вставить("Информация", "Обработка выгрузки проводок из ЗУП 3.1 в КА 1.1" );
///////////// команды /////////////////////////
тзКоманд = Новый ТаблицаЗначений;
тзКоманд.Колонки.Добавить("Идентификатор", Новый ОписаниеТипов("Строка"));
тзКоманд.Колонки.Добавить("Представление", Новый ОписаниеТипов("Строка"));
тзКоманд.Колонки.Добавить("Модификатор", Новый ОписаниеТипов("Строка"));
тзКоманд.Колонки.Добавить("ПоказыватьОповещение", Новый ОписаниеТипов("Булево"));
тзКоманд.Колонки.Добавить("Использование", Новый ОписаниеТипов("Строка"));
Идентификатор_Команды = "ОткрытьФорму";
строкаКоманды = тзКоманд.Добавить();
строкаКоманды.Идентификатор = Идентификатор_Команды;
строкаКоманды.Представление = "Открыть форму выгрузки проводок ЗУП 3.1 -> КА 1.1";
строкаКоманды.ПоказыватьОповещение = Истина;
строкаКоманды.Использование = "ОткрытиеФормы";
РегистрационныеДанные.Вставить("Команды", тзКоманд);
Возврат РегистрационныеДанные;
КонецФункции
При загрузке проводок, отмечу функцию, которая определяет тип данных по коду счета:
Функция ПолучитьСчетСубконто(СчетКод, Субконто1, Субконто2, Субконто3)
стрСчетСубконто = Новый Структура("Счет,Субконто1,Субконто2,Субконто3");
текСчет = ПланыСчетов.Хозрасчетный.НайтиПоКоду(СчетКод);
стрСчетСубконто.Счет = текСчет;
Если СчетКод = "70" Тогда
Запрос = Новый Запрос();
Запрос.Текст =
"ВЫБРАТЬ ПЕРВЫЕ 1
| ФизическиеЛица.Ссылка
|ИЗ
| Справочник.ФизическиеЛица КАК ФизическиеЛица
|ГДЕ
| ФизическиеЛица.ИНН = &ИНН";
Запрос.УстановитьПараметр("ИНН", Субконто1);
Выборка = Запрос.Выполнить().Выбрать();
Если Выборка.Следующий() Тогда
стрСчетСубконто.Субконто1 = Выборка.Ссылка;
Иначе
стрСчетСубконто.Субконто1 = Справочники.ФизическиеЛица.ПустаяСсылка();
КонецЕсли;
Иначе
Если текСчет.ВидыСубконто.Количество() > 0 Тогда
ВидСубконто = текСчет.ВидыСубконто[0];
Типы = ВидСубконто.ВидСубконто.ТипЗначения.Типы();
текМетаданные = Метаданные.НайтиПоТипу(Типы[0]);
Если Справочники.ТипВсеСсылки().СодержитТип(Типы[0]) Тогда
УИД = Новый УникальныйИдентификатор(Субконто1);
стрСчетСубконто.Субконто1 = Справочники[текМетаданные.Имя].ПолучитьСсылку(УИД);
Иначе
стрСчетСубконто.Субконто1 = Перечисления[текМетаданные.Имя][Субконто1];
КонецЕсли
КонецЕсли;
Если текСчет.ВидыСубконто.Количество() > 1 Тогда
ВидСубконто = текСчет.ВидыСубконто[1];
Типы = ВидСубконто.ВидСубконто.ТипЗначения.Типы();
текМетаданные = Метаданные.НайтиПоТипу(Типы[0]);
Если Справочники.ТипВсеСсылки().СодержитТип(Типы[0]) Тогда
УИД = Новый УникальныйИдентификатор(Субконто2);
стрСчетСубконто.Субконто2 = Справочники[текМетаданные.Имя].ПолучитьСсылку(УИД);
Иначе
стрСчетСубконто.Субконто2 = Перечисления[текМетаданные.Имя][Субконто2];
КонецЕсли
КонецЕсли;
Если текСчет.ВидыСубконто.Количество() > 2 Тогда
ВидСубконто = текСчет.ВидыСубконто[2];
Типы = ВидСубконто.ВидСубконто.ТипЗначения.Типы();
текМетаданные = Метаданные.НайтиПоТипу(Типы[0]);
Если Справочники.ТипВсеСсылки().СодержитТип(Типы[0]) Тогда
УИД = Новый УникальныйИдентификатор(Субконто3);
стрСчетСубконто.Субконто3 = Справочники[текМетаданные.Имя].ПолучитьСсылку(УИД);
Иначе
стрСчетСубконто.Субконто3 = Перечисления[текМетаданные.Имя][Субконто3];
КонецЕсли
КонецЕсли;
КонецЕсли;
Возврат стрСчетСубконто;
КонецФункции