На 16 месяцев позже первого приёма на работу начиналась история регистраций в налоговом органе, и этого хватило, чтобы "Начисление зарплаты и взносов" за ранний месяц не проводилось. Регистрация в карточке организации при этом заполнена, код налогового органа стоит. Только проведение карточку не читает. Оно берёт регистрацию из истории, причём по подразделению строки начисления, и если история начинается позже месяца начисления, берёт пустоту.
Случай живой, база ERP для Казахстана с зарплатной подсистемой ЗУП. Бухгалтер открывает начисление за один из первых месяцев, нажимает "Провести" и получает:
Запись не верна! Значение поля "Регистрация в налоговом органе" не может быть пустым! (Регистр накопления: Сведения о доходах физических лиц; Номер строки: 1)
В тексте ошибки нет ни организации, ни сотрудника, ни месяца. Есть только имя регистра и номер строки, и строка эта первая: не прошла уже первая запись движений. Ниже разбираю, откуда берётся пустое значение, какие версии я отбросил по дороге и как это лечится: руками в регистре и одной кнопкой.
Кто требует регистрацию
Ошибку выдаёт не документ, а регистр, в который он пишет. У регистра накопления "Сведения о доходах физических лиц" семь измерений, и у четырёх из них стоит запрет пустых значений: Организация, ФизическоеЛицо, ПериодРегистрации и РегистрацияВНалоговомОргане. У измерения Подразделение запрета нет. Поэтому платформа отказывает на записи движений, а документ здесь только носитель: на его месте мог оказаться любой, кто пишет в этот регистр.
Практический вывод: искать надо место, откуда проведение взяло значение измерения. В самом документе и его табличной части ответа нет.
Откуда проведение берёт регистрацию
Движения по этому регистру собирает процедура общего модуля УчетНалоговВзносовОтчислений.СформироватьСведенияОДоходахПоНачислениям. Модуль большой, в выгрузке он весит 3,1 МБ, поэтому искать глазами бесполезно, проще выгрузить его вместе с регистром и читать по имени процедуры.
Внутри регистрация берётся не из справочника организаций. Процедура делает срез последних по регистру сведений "История регистраций в налоговом органе" на конец месяца начисления, и срез этот идёт по подразделению строки начисления. Вот кусок текста запроса из этой процедуры, в типовой он так и выглядит:
ВЫБРАТЬ Начисления.Подразделение КАК Подразделение, ИсторияРегистрацийВНалоговомОрганеСрезПоследних.РегистрацияВНалоговомОргане КАК РегистрацияВНалоговомОргане // остальные поля пропущены ИЗ ВТНачисления КАК Начисления ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ИсторияРегистрацийВНалоговомОргане.СрезПоследних( &КонецМесяцаНачисления, СтруктурнаяЕдиница В (ВЫБРАТЬ Начисления.Подразделение ИЗ ВТНачисления КАК Начисления)) КАК ИсторияРегистрацийВНалоговомОрганеСрезПоследних ПО Начисления.Подразделение = ИсторияРегистрацийВНалоговомОрганеСрезПоследних.СтруктурнаяЕдиница
Параметр КонецМесяцаНачисления процедура ставит как КонецМесяца(МесяцНачисления). Условие среза и условие соединения построены только на подразделении, организации в них нет. Соединение левое, поэтому строка начисления без пары в истории не теряется, а уходит в движения с пустой регистрацией, и на ней платформа останавливает запись.
У регистра истории периодичность "день" и одно измерение СтруктурнаяЕдиница, в которое можно положить организацию, территорию или подразделение. Ресурс один, та самая РегистрацияВНалоговомОргане. Каждая запись говорит: с такого-то дня такая-то структурная единица стоит на учёте в таком-то налоговом органе.
В нашей базе в истории лежали ровно две записи: организация и её "Основное подразделение", обе с 1 февраля, обе с правильным налоговым органом. Сотрудников при этом принимали на работу на шестнадцать месяцев раньше, первые документы "Прием на работу" стояли задолго до февраля, и начисление было за один из тех ранних месяцев. Срез на конец этого месяца по подразделению ничего не находит, и в движение уезжает пустая ссылка.
Карточка организации при этом выглядит идеально, потому что в ней хранится текущая регистрация, без даты. По ней не видно, с какого дня история начинается, и именно поэтому она сбивает со следа.

Второй регистр, о котором обычно забывают
Рядом с историей живёт регистр "История регистраций в налоговом органе вторичный". Он непериодический, измерения у него СтруктурнаяЕдиница, ДатаНачала и ДатаОкончания, то есть он хранит ту же историю, разложенную на интервалы. До исправления в нём было две строки: организация и подразделение, каждая с 1 февраля по 31.12.3999.
Вторичный регистр никто не заполняет руками. Его пересчитывает модуль набора записей основного регистра при записи:
Процедура ПриЗаписи(Отказ, Замещение) Если ЗарплатаКадры.ОтключитьБизнесЛогикуПриЗаписи(ЭтотОбъект) Тогда Возврат; КонецЕсли; СтруктурнаяЕдиница = Неопределено; Если Отбор.СтруктурнаяЕдиница.Использование Тогда СтруктурнаяЕдиница = Новый Массив; СтруктурнаяЕдиница.Добавить(Отбор.СтруктурнаяЕдиница.Значение); КонецЕсли; УстановитьПривилегированныйРежим(Истина); РегистрыСведений.ИсторияРегистрацийВНалоговомОрганеВторичный.ЗаполнитьВторичныеДанные(СтруктурнаяЕдиница); КонецПроцедуры
Это типовой код, я его только привёл целиком. Важна первая проверка: если бизнес-логика при записи отключена (в зарплатных конфигурациях так бывает, например, при записи в режиме загрузки), вторичный регистр остаётся как был. Запомните это место, оно всплывёт ниже, когда дойдём до штатной процедуры исправления.
На форуме Инфостарта ещё в 2019-2020 годах (ветка 2019 года, ветка 2020 года) на похожие вопросы отвечали одним советом: открыть оба регистра через "Все функции" и сравнить периоды с документом. Совет рабочий, но руками это делается долго, и главное, периоды надо проверять у подразделения строки: у организации они могут быть в полном порядке.
Что я проверил и отбросил
Прежде чем писать хоть строку кода, я прогнал несколько очевидных версий. Все они по отдельности выглядели разумно, и все отпали, как только я сверил их с базой и кодом конфигурации.
"В карточке организации не заполнена регистрация"
Первое, что проверяют все. В карточке всё было: регистрация выбрана, код налогового органа заполнен, элемент справочника "Регистрации в налоговом органе" один, не помечен на удаление, владелец правильный. Пустой регистрация была только у "Управленческой организации", по которой зарплату не считают. Версия отпала: заполненная карточка ничего не говорит о том, с какого дня начинается история, а проведение смотрит только в историю.
"Достаточно продлить историю организации"
Если бы срез шёл по организации, хватило бы одной записи задним числом. Но в процедуре проведения регистрация ищется по подразделению строки. Запись для организации без записи для подразделения оставила бы ошибку на месте, причём для любого подразделения, у которого есть начисления. Поэтому история нужна каждой структурной единице, которая попадает в строки начисления.
"Начать историю с даты регистрации организации"
Логичная мысль: организация зарегистрирована тогда-то, с этой даты и продлим историю. Поле "Дата регистрации" оказалось пустым у обеих организаций базы. Гадать дату я не стал и посмотрел, как поступает сама конфигурация. Она пишет начальную запись на дату отсчёта периодических сведений, которую отдаёт функция ЗарплатаКадрыКлиентСервер.ДатаОтсчетаПериодическихСведенийСПериодомМесяц(), в типовой это 01.01.1900. Запись с такой датой покрывает любой месяц начисления и ни с чем не спорит.
"Вызвать штатную процедуру конфигурации"
В модуле менеджера регистра истории такая процедура есть, с длинным говорящим именем ЗаполнитьИсториюРегистрацийВНалоговомОрганеНаДатуОтсчетаПериодическихСведенийСПериодомМесяц. Рядом лежит ОбновитьПодчиненныеСтруктурныеЕдиницы, которая разносит историю головной единицы на её необособленные подразделения.
Загвоздка в первой: она пишет каждый набор с ОбменДанными.Загрузка = Истина. Для обработчика обновления это разумно, а для нас означает, что сработает тот самый Возврат в начале ПриЗаписи и вторичный регистр останется со старыми интервалами. Вторая включает загрузку, только если ей передать РежимОбновления = Истина, по умолчанию пишет обычным порядком. Поэтому первую я как есть звать не стал и повторил её порядок действий без режима загрузки, а вторую вызываю штатно, с параметром по умолчанию.
Как лечить руками
Если база одна и подразделений мало, всё делается без обработок:
- Открыть "Все функции", регистр сведений "История регистраций в налоговом органе" и отсортировать по структурной единице.
- Для организации найти самую раннюю запись. Если она позже первого месяца начислений, добавить запись с периодом 01.01.1900, той же структурной единицей и той же регистрацией, что в самой ранней записи. Сама организация в срез проведения не входит, но от её истории конфигурация разносит историю на необособленные подразделения, поэтому начинать с неё.
- Сделать то же для каждого подразделения, которое встречается в строках начислений. Обособленному подразделению своя регистрация: если истории у него нет совсем, взять её из карточки подразделения, поле "Регистрация в налоговом органе". Необособленному та же, что у организации.
- Открыть регистр "История регистраций в налоговом органе вторичный" и убедиться, что у каждой единицы появился интервал с 01.01.1900.
- Перепровести документ, который падал.
Оговорка: ручной путь я в этой базе не прогонял, прогонял кнопку. Запись из формы регистра идёт обычным порядком, без режима загрузки, поэтому по коду ПриЗаписи вторичный регистр должен пересчитаться. Если в пункте 4 интервала нет, значит, запись прошла мимо бизнес-логики, и дальше это уже вопрос к вашей конфигурации.
Если вы сталкивались с ситуацией, когда документы провелись, но с регистрацией не того подразделения (поздно завели регистрацию, поздно оформили перевод), это другая болезнь той же истории. Для российского ЗУП 3.1 под неё есть готовая обработка исправления регистрации в движениях, она переписывает уже проведённые документы. Здесь документ не проводится вовсе, и документы трогать не нужно.
Как лечить кнопкой
Когда организаций и подразделений больше двух, ручной путь превращается в сверку по списку, и я собрал его в обработку с одной кнопкой. Логика повторяет штатную процедуру конфигурации:
- берёт организации и обособленные подразделения без пометки удаления;
- для каждой находит первую запись истории; если её нет или она позже 01.01.1900, добавляет запись на эту дату с той же регистрацией, а если истории нет совсем, берёт регистрацию из карточки;
- единицы без регистрации и в карточке, и в истории пропускает и пишет об этом в протокол;
- разносит историю головной единицы на необособленные подразделения штатной
ОбновитьПодчиненныеСтруктурныеЕдиницыс параметром по умолчанию, то есть без режима загрузки.
Всё идёт одной транзакцией: либо исправлено всё, либо ничего. Ключевой кусок, запись одной единицы:
Процедура ДобавитьЗаписьИстории(СтруктурнаяЕдиница, Период, Регистрация) Набор = РегистрыСведений.ИсторияРегистрацийВНалоговомОргане.СоздатьНаборЗаписей(); Набор.Отбор.Период.Установить(Период); Набор.Отбор.СтруктурнаяЕдиница.Установить(СтруктурнаяЕдиница); ЗаписьИстории = Набор.Добавить(); ЗаписьИстории.Период = Период; ЗаписьИстории.СтруктурнаяЕдиница = СтруктурнаяЕдиница; ЗаписьИстории.РегистрацияВНалоговомОргане = Регистрация; // Так же пишут штатные процедуры заполнения истории: запись на дату отсчета // лежит глубоко в прошлом и не должна упираться в дату запрета изменения. Набор.ДополнительныеСвойства.Вставить("ОтключитьПроверкуДатыЗапретаИзменения", Истина); // Без режима загрузки: при записи набор сам пересчитывает вторичный регистр. Набор.Записать(); КонецПроцедуры
Отбор по периоду и структурной единице здесь обязателен. Набор записей регистра сведений при записи замещает всё, что попадает под его отбор, и без отбора заменил бы собой весь регистр. Кроме того, именно по отбору ПриЗаписи понимает, для какой единицы пересчитывать вторичный регистр, без него пересчёт шёл бы по всем единицам.
Первая запись истории ищется запросом с группировкой по структурной единице, а регистрация для новой записи берётся из самой ранней записи, если она есть. Так новая запись не спорит с тем, что бухгалтер уже завёл, а продлевает это назад:
ВЫБРАТЬ История.СтруктурнаяЕдиница КАК СтруктурнаяЕдиница, МИНИМУМ(История.Период) КАК Период ПОМЕСТИТЬ ВТПервыеЗаписи ИЗ РегистрСведений.ИсторияРегистрацийВНалоговомОргане КАК История СГРУППИРОВАТЬ ПО История.СтруктурнаяЕдиница
Повторный запуск ничего не меняет: у всех единиц история уже начинается с даты отсчёта, и в протоколе будет "запись не нужна". После прогона протокол печатает всю историю регистраций, какой она стала, и последней строкой просит перепровести документ, который выдавал ошибку.
Как проверял
Сначала логику, до сборки обработки. Тот же код я выполнил прямо в базе внутри транзакции с откатом: добавил запись организации, разнёс историю на подразделение и в той же транзакции перепровёл упавшее начисление. Документ провёлся, после отката в регистре снова лежали две записи с 1 февраля. Первая попытка, кстати, откатилась не из-за логики: проверочный запрос упорядочивал по псевдониму поля, вычисленного функцией ПРЕДСТАВЛЕНИЕ(), и получил "Операция не разрешена в предложении "УПОРЯДОЧИТЬ"". Сортировать надо по самому полю.
Потом собранный файл. Разборка собранного файла обратно в исходники показала, что кнопка, поле протокола, реквизиты и команда пережили сборку. Проверка модулей в контексте самой базы с ЗУП прошла без ошибок: вне такой базы модуль не скомпилируется, потому что зовёт общие модули зарплатной подсистемы. Обработку создал на сервере и вызвал её функцию в транзакции с откатом, вызов занял 664 мс.
Потом обработку запустили в рабочей базе по-настоящему, без отката, и после запуска я проверил состояние регистров. Срезы проверял на конец каждого месяца, начиная с месяца перед первым приёмом, всего 25 месяцев:
| Что | До | После |
|---|---|---|
| Записей в "Истории регистраций" | 2, обе с 1 февраля | 4: у организации и подразделения по записи с 01.01.1900 и с 1 февраля |
| Интервалов во вторичном регистре | 2, с 1 февраля по 31.12.3999 | 4: с 01.01.1900 по 31 января и с 1 февраля по 31.12.3999 |
| Пустых срезов на конец месяца | 17 из 25: все месяцы до февраля | 0 из 25 |
| Перепроведение упавшего начисления | ошибка | проходит, 41 с в транзакции с откатом |
Откуда взялись 4 записи из 2: запись организации на 01.01.1900 добавила сама обработка, а подразделению такая же запись пришла через ОбновитьПодчиненныеСтруктурныеЕдиницы. При трёх подразделениях не ждите 2 + 3: каждому необособленному достанется копия истории организации целиком. Во вторичном регистре интервалов тоже 4, хотя регистрация в обеих записях единицы одна и та же: соседние записи с одинаковым значением он у нас не склеил, интервал резался на каждой записи основного регистра.
Историю исправили по-настоящему, а документ проводит бухгалтер: перепроведение в последней строке я делал в транзакции с откатом. 41 секунда здесь время проведения самого начисления, к обработке она отношения не имеет: вызов обработки в прогоне с откатом занял те самые 664 мс.
Где это не поможет
Если организация за время работы меняла налоговый орган, а в истории записан только нынешний, обработка продлит назад нынешний. Так же поступает и штатное обновление конфигурации, но для отчётности за прошлые периоды это может быть неправдой. Поэтому после запуска стоит глянуть в протоколе блок с итоговой историей и, если смена была, добавить промежуточную запись руками.
Если ошибка про пустую регистрацию идёт не из "Сведений о доходах физических лиц", а из другого регистра, механизм может быть другим. Обработка трогает только историю регистраций, ничего не удаляет и документы не перепроводит, так что лишний запуск документов не испортит, но и ошибку не вылечит.
И учтите, что запись на 01.01.1900 обработка делает в обход даты запрета изменения, так же как штатные процедуры заполнения истории. Проведённые документы закрытых периодов она не трогает, но история регистраций за эти периоды после запуска становится другой.
Проверял на ERP для Казахстана, платформа 8.3.27. На других конфигурациях с той же зарплатной подсистемой (ЗУП для Казахстана, Комплексная автоматизация) регистры и процедуры, скорее всего, называются так же, но их код я не сверял и прогона там не было, так что первый запуск лучше сделать на копии.
Обработка
Кнопка, протокол и всё, что описано выше, собраны в обработку "Исправление истории регистрации в налоговом органе". Открывается через "Файл - Открыть", работает на сервере, в документы не пишет.
Другие наши инструменты
- Тестовая база из бэкапа рабочей - поднять копию и прогнать на ней любое исправление до того, как нажимать кнопку в рабочей базе.
- Чек-ап чистоты базы 1С - прикинуть, сколько в базе мусора и что сломается, если его убрать.
- Выгрузка товаров в Национальный каталог Казахстана из 1С - для тех, кто работает с казахстанскими конфигурациями и госсистемами.
- Карта объёмов базы 1С - понять, какие таблицы и регистры занимают место.
Вопрос
Как у вас начинается история регистраций в налоговом органе: с даты отсчёта, как пишет обновление конфигурации, или с даты, которую кто-то завёл руками? И если вы переносили зарплату из другой базы, проверьте историю у подразделений: интересно, у скольких она тоже начинается с месяца переноса.
Вступайте в нашу телеграмм-группу Инфостарт