Перенос данных по внеоборотным активам (основным средствам) при переходе с устаревшей конфигурации 1С:Управление производственным предприятием (УПП) на современную 1С:ERP Управление предприятием — один из наиболее сложных и ответственных этапов проекта автоматизации. Начинающие разработчики часто пытаются решить эту задачу «в лоб»: создают копию справочника ОсновныеСредства в базе-источнике или пытаются перенести документы принятия к учету за всю историю существования предприятия.
В этой статье мы разберем по шагам, почему классическое дублирование справочников не работает, как устроена архитектура хранения данных ОС в обеих системах, проанализируем рабочий код запроса для извлечения остатков по всем видам учета (БУ, НУ, УУ) и выясним, какими инструментами лучше всего выполнять перенос.
Для начала проанализируем ситуацию, с которой часто сталкиваются разработчики на старте задачи. Попытка создать внутри 1С:УПП дублирующий справочник (например, ОС_Копия) с целью заполнить в нем все реквизиты и затем перенести его в ERP через COM-соединение или XML является тупиковой. Выясним причину этого утверждения.
Справочник ОсновныеСредства в архитектуре систем 1С (как в УПП, так и в ERP) представляет собой лишь «оболочку» — карточку инвентарного объекта. Сам по себе этот справочник практически не хранит значимой финансовой и учетной информации. В нем содержатся лишь базовые реквизиты: наименование, группа ОС, код ОКОФ, амортизационная группа и паспортные данные.
Вся критически важная информация для ведения учета распределена по многочисленным регистрам:
СтоимостьОСБухгалтерскийУчет).Если мы просто скопируем справочник, мы получим «пустые» карточки без истории и остатков стоимости. Попытка записать эти данные напрямую в реквизиты справочника-копии бессмысленна, так как в целевой системе 1С:ERP эти данные все равно должны находиться в совершенно других объектах метаданных.
Разберем различия в подходах к хранению данных основных средств в старой и новой конфигурациях. Это поможет понять, почему прямой перенос документов типа ПринятиеКУчетуОС за прошлые периоды крайне нежелателен.
В 1С:УПП учет внеоборотных активов опирается на традиционную модель, где документы принятия к учету делают непосредственные движения по регистрам сведений и бухгалтерии. При этом управленческий, бухгалтерский и налоговый учет могут вестись параллельно и независимо друг от друга.
В 1С:ERP (особенно в актуальных версиях ветки 2.5) архитектура внеоборотных активов претерпела кардинальные изменения:
ВводНачальныхОстатковВнеоборотныхАктивов с типом операции «Основные средства». Этот документ является универсальной точкой входа. При его проведении система автоматически формирует проводки по балансовым счетам (01, 02) и делает записи во все необходимые регистры сведений (амортизация, события, состояния, параметры).ГруппыФинансовогоУчетаВнеоборотныхАктивов. Именно ГФУ определяет, на каких счетах будет учитываться объект и его амортизация. При переносе остатков нам обязательно нужно сопоставить старые счета учета из УПП с новыми элементами ГФУ в ERP.Вывод: Единственно верный методологический путь — это срез остатков на определенную дату (например, на 31 декабря отчетного года) и их загрузка в ERP через документ Ввод начальных остатков.
Рассмотрим подробнее, как собрать все необходимые реквизиты из базы УПП. Для этого нам потребуется написать запрос, который обращается к срезам последних различных регистров сведений и к остаткам регистров накопления на дату переноса данных.
Посмотрим на пример комплексного запроса, который собирает сведения по управленческому, бухгалтерскому и налоговому учету (включая УСН) для конкретного основного средства.
// Процедура инициализирует запрос и собирает пакет данных по ОС на указанную дату
Процедура ПолучитьСведенияОбОС(ОсновноеСредствоСсылка, ДатаСведений, РезультатТаблица)
// 1. Получение данных по управленческому учету (УУ)
ЗапросУУ = Новый Запрос;
ЗапросУУ.УстановитьПараметр("ОсновноеСредство", ОсновноеСредствоСсылка);
ЗапросУУ.УстановитьПараметр("ДатаСведений", ДатаСведений);
ЗапросУУ.Текст =
"ВЫБРАТЬ РАЗРЕШЕННЫЕ
| ЕСТЬNULL(ПервоначальныеСведенияОССрезПоследних.ПервоначальнаяСтоимость, 0) КАК ПервоначальнаяСтоимостьУУ,
| ПРЕДСТАВЛЕНИЕ(ПервоначальныеСведенияОССрезПоследних.СпособНачисленияАмортизации) КАК СпособАмортизацииУУ,
| ПервоначальныеСведенияОССрезПоследних.ПараметрВыработки КАК ПараметрВыработкиУУ,
| СоставОССрезПоследних.ВСоставе КАК ВСоставе,
| МестонахождениеОССрезПоследних.МОЛ КАК МОЛУУ,
| МестонахождениеОССрезПоследних.Местонахождение КАК ПодразделениеУУ,
| ЕСТЬNULL(ПараметрыАмортизацииОССрезПоследних.СрокПолезногоИспользования, 0) КАК СрокИспользованияУУ,
| ЕСТЬNULL(СтоимостьОСОстатки.СтоимостьОстаток, 0) КАК ТекущаяСтоимостьУУ,
| ЕСТЬNULL(СтоимостьОСОстатки.АмортизацияОстаток, 0) КАК ТекАмортизацияУУ
|ИЗ
| РегистрСведений.ПервоначальныеСведенияОС.СрезПоследних(&ДатаСведений, ОсновноеСредство = &ОсновноеСредство) КАК ПервоначальныеСведенияОССрезПоследних
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.СоставОС.СрезПоследних(&ДатаСведений, ОсновноеСредство = &ОсновноеСредство) КАК СоставОССрезПоследних
| ПО ПервоначальныеСведенияОССрезПоследних.ОсновноеСредство = СоставОССрезПоследних.ОсновноеСредство
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.МестонахождениеОС.СрезПоследних(&ДатаСведений, ОсновноеСредство = &ОсновноеСредство) КАК МестонахождениеОССрезПоследних
| ПО ПервоначальныеСведенияОССрезПоследних.ОсновноеСредство = МестонахождениеОССрезПоследних.ОсновноеСредство
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ПараметрыАмортизацииОС.SрезПоследних(&ДатаСведений, ОсновноеСредство = &ОсновноеСредство) КАК ПараметрыАмортизацииОССрезПоследних
| ПО ПервоначальныеСведенияОССрезПоследних.ОсновноеСредство = ПараметрыАмортизацииОССрезПоследних.ОсновноеСредство
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.СтоимостьОС.Остатки(&ДатаСведений, ОсновноеСредство = &ОсновноеСредство) КАК СтоимостьОСОстатки
| ПО ПервоначальныеСведенияОССрезПоследних.ОсновноеСредство = СтоимостьОСОстатки.ОсновноеСредство";
РезультатУУ = ЗапросУУ.Выполнить().Выгрузить();
// 2. Определение организации по регламентированному учету
ЗапросОрг = Новый Запрос;
ЗапросОрг.УстановитьПараметр("ОсновноеСредство", ОсновноеСредствоСсылка);
ЗапросОрг.УстановитьПараметр("ДатаСведений", ДатаСведений);
ЗапросОрг.Текст =
"ВЫБРАТЬ РАЗРЕШЕННЫЕ ПЕРВЫЕ 1
| ПервоначальныеСведенияОСБухгалтерскийУчетСрезПоследних.Организация КАК Организация
|ИЗ
| РегистрСведений.ПервоначальныеСведенияОСБухгалтерскийУчет.СрезПоследних(&ДатаСведений, ОсновноеСредство = &ОсновноеСредство) КАК ПервоначальныеСведенияОСБухгалтерскийУчетСрезПоследних";
ВыборкаОрг = ЗапросОрг.Выполнить().Выбрать();
Если ВыборкаОрг.Следующий() Тогда
ТекОрганизация = ВыборкаОрг.Организация;
Иначе
ТекОрганизация = Справочники.Организации.ПустаяСсылка();
КонецЕсли;
Если ЗначениеЗаполнено(ТекОрганизация) Тогда
// 3. Получение данных бухгалтерского учета (БУ)
ЗапросБУ = Новый Запрос;
ЗапросБУ.УстановитьПараметр("ОсновноеСредство", ОсновноеСредствоСсылка);
ЗапросБУ.УстановитьПараметр("ДатаСведений", ДатаСведений);
ЗапросБУ.УстановитьПараметр("Организация", ТекОрганизация);
ЗапросБУ.Текст =
"ВЫБРАТЬ РАЗРЕШЕННЫЕ
| ПервоначальныеСведенияОСБухгалтерскийУчетСрезПоследних.ИнвентарныйНомер КАК ИнвентарныйНомер,
| ПРЕДСТАВЛЕНИЕ(ПервоначальныеСведенияОСБухгалтерскийУчетСрезПоследних.СпособПоступления) КАК СпособПоступленияБУ,
| ПРЕДСТАВЛЕНИЕ(ПервоначальныеСведенияОСБухгалтерскийУчетСрезПоследних.СпособНачисленияАмортизации) КАК СпособАмортизацииБУ,
| ЕСТЬNULL(ПервоначальныеСведенияОСБухгалтерскийУчетСрезПоследних.ПервоначальнаяСтоимость, 0) КАК ПервоначальнаяСтоимостьБУ,
| МестонахождениеОСБухгалтерскийУчетСрезПоследних.МОЛ КАК МОЛБУ,
| МестонахождениеОСБухгалтерскийУчетСрезПоследних.Местонахождение КАК ПодразделениеБУ,
| ЕСТЬNULL(ПараметрыАмортизацииОСБухгалтерскийУчетСрезПоследних.СрокПолезногоИспользования, 0) КАК СрокИспользованияБУ,
| СчетаБухгалтерскогоУчетаОССрезПоследних.СчетУчета КАК СчетУчетаСтоимостиБУ,
| СчетаБухгалтерскогоУчетаОССрезПоследних.СчетНачисленияАмортизации КАК СчетУчетаАмортизацииБУ,
| ЕСТЬNULL(СтоимостьОСБухгалтерскийУчетОстатки.СтоимостьОстаток, 0) КАК ТекущаяСтоимостьБУ,
| ЕСТЬNULL(СтоимостьОСБухгалтерскийУчетОстатки.АмортизацияОстаток, 0) КАК ТекАмортизацияБУ
|ИЗ
| РегистрСведений.ПервоначальныеСведенияОСБухгалтерскийУчет.СрезПоследних(&ДатаСведений, ОсновноеСредство = &ОсновноеСредство) КАК ПервоначальныеСведенияОСБухгалтерскийУчетСрезПоследних
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.МестонахождениеОСБухгалтерскийУчет.СрезПоследних(&ДатаСведений, Организация = &Организация И ОсновноеСредство = &ОсновноеСредство) КАК МестонахождениеОСБухгалтерскийУчетСрезПоследних
| ПО ПервоначальныеСведенияОСБухгалтерскийУчетСрезПоследних.ОсновноеСредство = МестонахождениеОСБухгалтерскийУчетСрезПоследних.ОсновноеСредство
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ПараметрыАмортизацииОСБухгалтерскийУчет.СрезПоследних(&ДатаСведений, Организация = &Организация И ОсновноеСредство = &ОсновноеСредство) КАК ПараметрыАмортизацииОСБухгалтерскийУчетСрезПоследних
| ПО ПервоначальныеСведенияОСБухгалтерскийУчетСрезПоследних.ОсновноеСредство = ПараметрыАмортизацииОСБухгалтерскийУчетСрезПоследних.ОсновноеСредство
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.СчетаБухгалтерскогоУчетаОС.СрезПоследних(&ДатаСведений, Организация = &Организация И ОсновноеСредство = &ОсновноеСредство) КАК СчетаБухгалтерскогоУчетаОССрезПоследних
| ПО ПервоначальныеСведенияОСБухгалтерскийУчетСрезПоследних.ОсновноеСредство = СчетаБухгалтерскогоУчетаОССрезПоследних.ОсновноеСредство
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.СтоимостьОСБухгалтерскийУчет.Остатки(&ДатаСведений, Организация = &Организация И ОсновноеСредство = &ОсновноеСредство) КАК СтоимостьОСБухгалтерскийУчетОстатки
| ПО ПервоначальныеСведенияОСБухгалтерскийУчетСрезПоследних.ОсновноеСредство = СтоимостьОСБухгалтерскийУчетОстатки.ОсновноеСредство";
РезультатБУ = ЗапросБУ.Выполнить().Выгрузить();
// Далее выполняем слияние таблиц результатов для передачи в обработку переноса...
КонецЕсли;
КонецПроцедуры
Проанализируем структуру данного запроса. Мы видим, что он обращается к срезам последних на дату переноса. Это критически важно, так как параметры амортизации могли меняться в процессе эксплуатации основного средства (например, в результате модернизации увеличился срок полезного использования или балансовая стоимость).
Вместо записи в промежуточный справочник, собранные данные следует поместить в объект типа ТаблицаЗначений. Это универсальная структура, которую можно легко обработать и подготовить для выгрузки. Разберем по шагам, как выстроить этот процесс:
ТаблицаЗначений с колонками, в точности повторяющими реквизиты будущего документа ВводНачальныхОстатковВнеоборотныхАктивов в 1С:ERP.СтрокаТЗ.УИД = Строка(ОССсылка.УникальныйИдентификатор());.После формирования заполненной таблицы значений у нас есть несколько вариантов доставки этих данных в 1С:ERP:
Создание собственных правил конвертации с нуля может занять много времени, так как структура хранения внеоборотных активов крайне сложна. Опытные специалисты рекомендуют использовать готовые наработки от фирмы «1С».
В дистрибутиве поставки 1С:ERP всегда присутствует папка со вспомогательными файлами для перехода со старых систем. Обычно она находится по пути:
...\1c\ERP\...[версия_релиза]\AddFiles\Переходы с других конфигураций\УПП_КА1\
Там вы найдете правила конвертации (файл .xml) и внешнюю обработку выгрузки. Рассмотрим, почему выгодно использовать именно их, а не писать выгрузку вручную:
Ввод начальных остатков в ERP. При этом система автоматически группирует ОС по организациям, подразделениям и счетам учета, создавая необходимое количество документов.Если ваша конфигурация 1С:УПП была сильно кастомизирована (например, добавлены новые свойства ОС или изменена логика начисления износа), вам достаточно загрузить типовые правила в конфигурацию «1С:Конвертация данных 2», внести точечные изменения в обработчики событий (например, ПередВыгрузкой или ПриЗагрузке) и сохранить собственные модифицированные правила.
Проанализируем основные методические и технические проблемы, которые могут возникнуть при загрузке данных в 1С:ERP, и способы их решения.
В ERP действует строгая последовательность бизнес-логики. Например, дата принятия объекта к учету в системе не может быть позже, чем дата начала начисления амортизации. В УПП из-за ручных корректировок пользователей даты в регистрах сведений часто «разъезжаются». При попытке провести документ ввода остатков с некорректными датами ERP выдаст ошибку проведения.
Решение: Перед выгрузкой запустите проверочный запрос в УПП, который сопоставит даты документов принятия к учету и даты изменения состояния ОС. Все выявленные ошибки и пустые даты необходимо скорректировать до начала выгрузки.
Структура физических лиц и сотрудников в УПП и ERP отличается. В ERP учет сотрудников ведется более строго. Если при переносе остатков ОС указать МОЛ, которого нет в справочнике физических лиц новой базы, поле останется пустым, либо создастся дубликат.
Решение: Настройте предварительный перенос справочника ФизическиеЛица (или Сотрудники) с синхронизацией по ИНН или СНИЛС. Только после успешного сопоставления людей запускайте перенос остатков основных средств.
Поскольку в 1С:ERP счета учета задаются через ГФУ внеоборотных активов, необходимо заранее позаботиться о создании этих групп. Если документ ввода остатков попытается сослаться на незаполненную ГФУ, проводки по счетам 01 и 02 просто не сформируются.
Решение: В обработчике загрузки данных (в КД) или в коде вашей собственной загрузки пропишите алгоритм автоматического создания ГФУ на основе сочетаний счетов учета из УПП. Например, если в УПП у объекта стоял счет учета 01.01 и счет амортизации 02.01, система должна найти или создать ГФУ с именем «Здания и сооружения (01.01 / 02.01)» и подставить ее в загружаемый документ остатков.
Подведем итог и составим краткий чек-лист для реализации задачи:
Ввод начальных остатков.Следуя этой методике, вы сможете перенести основные средства быстро, без потери важных параметров амортизации и с гарантией корректного начисления износа в будущих периодах в системе 1С:ERP.