При доработке типовых конфигураций 1С, в частности «1С:Зарплата и управление персоналом 3.1», программисты нередко сталкиваются с необходимостью формирования дополнительных движений по регистрам сведений при проведении расчетных документов. В процессе такой разработки при вызове метода Записать() набора записей может возникнуть платформенная ошибка проверки заполнения измерений или системных реквизитов.
Типичный текст ошибки выглядит следующим образом:
Ошибка при вызове метода контекста (Записать) Движения.БухучетПлановыхНачислений.Записать; по причине: Запись не верна! Значение поля "Сотрудник" не может быть пустым!: БухучетПлановыхНачислений: 01.01.0001, , Организация, Начисление...
Разберем детально, почему возникает такое исключение, как правильно составить запрос к данным документа и какие учетные нюансы конфигурации необходимо учитывать.
Проанализируем исходный код, при выполнении которого возникает сбой. Зачастую данные для формирования набора записей регистра получаются запросом к документу следующим образом:
ВЫБРАТЬ
РазовоеНачисление.Дата,
РазовоеНачисление.Организация,
РазовоеНачисление.Начисление,
РазовоеНачисление.СпособОтраженияЗарплатыВБухучете,
РазовоеНачисление.СтатьяФинансирования,
РазовоеНачисление.СтатьяРасходов,
РазовоеНачисление.ОтношениеКЕНВД,
РазовоеНачисление.Начисления.(
Сотрудник
)
ИЗ
Документ.РазовоеНачисление КАК РазовоеНачисление
ГДЕ
РазовоеНачисление.Ссылка = &Ссылка
Выясним причину, почему поле Сотрудник оказывается не заполненным:
РазовоеНачисление.Начисления.(Сотрудник) при выгрузке результата запроса в объект ТаблицаЗначений создает колонку Начисления, значением которой в каждой строке является подчиненная таблица значений. Процедура формирования движений ожидает плоскую таблицу, содержащую колонку Сотрудник непосредственно на верхнем уровне. Не найдя нужной колонки, алгоритм подставляет пустое значение, что приводит к ошибке контроля целостности регистра.01.01.0001. Регистр БухучетПлановыхНачислений является периодическим. Если в таблицу движений передается колонка с именем Дата, стандартный механизм заполнения не сопоставляет ее со служебным полем Период. В результате в ключ записи регистра попадает пустая дата, вызывая аналогичную ошибку по полю Период.Разберем по шагам, как правильно переписать функцию сбора данных, чтобы получить плоскую выборку строк и корректно передать их в типовые процедуры формирования движений.
ИЗ укажем саму табличную часть Документ.РазовоеНачисление.Начисления.Ссылка.Дата в Период с помощью конструкции КАК Период.Посмотрим на пример правильного текста запроса в функции получения данных:
Функция ПолучитьДанныеДляПроведения(СсылкаНаДокумент)
Запрос = Новый Запрос;
Запрос.УстановитьПараметр("Ссылка", СсылкаНаДокумент);
Запрос.Текст =
"ВЫБРАТЬ
| РазовоеНачислениеНачисления.Ссылка.Дата КАК Период,
| РазовоеНачислениеНачисления.Ссылка.Организация КАК Организация,
| РазовоеНачислениеНачисления.Ссылка.Начисление КАК Начисление,
| РазовоеНачислениеНачисления.Ссылка.СпособОтраженияЗарплатыВБухучете КАК СпособОтраженияЗарплатыВБухучете,
| РазовоеНачислениеНачисления.Ссылка.СтатьяФинансирования КАК СтатьяФинансирования,
| РазовоеНачислениеНачисления.Ссылка.СтатьяРасходов КАК СтатьяРасходов,
| РазовоеНачислениеНачисления.Ссылка.ОтношениеКЕНВД КАК ОтношениеКЕНВД,
| РазовоеНачислениеНачисления.Сотрудник КАК Сотрудник
|ИЗ
| Документ.РазовоеНачисление.Начисления КАК РазовоеНачислениеНачисления
|ГДЕ
| РазовоеНачислениеНачисления.Ссылка = &Ссылка
| И (РазовоеНачислениеНачисления.Ссылка.СпособОтраженияЗарплатыВБухучете <> ЗНАЧЕНИЕ(Справочник.СпособыОтраженияЗарплатыВБухУчете.ПустаяСсылка)
| ИЛИ РазовоеНачислениеНачисления.Ссылка.СтатьяФинансирования <> ЗНАЧЕНИЕ(Справочник.СтатьиФинансированияЗарплата.ПустаяСсылка)
| ИЛИ РазовоеНачислениеНачисления.Ссылка.СтатьяРасходов <> ЗНАЧЕНИЕ(Справочник.СтатьиРасходовЗарплата.ПустаяСсылка)
| ИЛИ РазовоеНачислениеНачисления.Ссылка.ОтношениеКЕНВД <> ЗНАЧЕНИЕ(Перечисление.ОтношениеКЕНВДЗатратНаЗарплату.ПустаяСсылка))";
РезультатЗапроса = Запрос.Выполнить();
ДанныеДляПроведения = Новый Структура;
ДанныеДляПроведения.Вставить("ОтражениеВБухучете", РезультатЗапроса.Выгрузить());
Возврат ДанныеДляПроведения;
КонецФункции
Рассмотрим вызов формирования движений в процедуре ОбработкаПроведения модуля объекта:
Процедура ОбработкаПроведения(Отказ, РежимПроведения)
ДанныеДляПроведения = ПолучитьДанныеДляПроведения(Ссылка);
// Выполнение стандартных движений документа
Документы.РазовоеНачисление.ПровестиПоУчетам(Ссылка, РежимПроведения, Отказ, Неопределено, Движения, ЭтотОбъект, ДополнительныеСвойства);
// Заполнение движений по регистру бухучета плановых начислений
Если ДанныеДляПроведения.ОтражениеВБухучете.Количество() > 0 Тогда
ОтражениеЗарплатыВБухучетеРасширенный.СформироватьДвиженияБухучетПлановыхНачислений(
Движения,
ДанныеДляПроведения.ОтражениеВБухучете
);
КонецЕсли;
КонецПроцедуры
Рассмотрим подробнее методологию типовой конфигурации ЗУП 3.1. Перед внедрением подобной доработки важно понимать назначение используемых объектов конфигурации:
НачисленияУдержанияПоСотрудникам). Итоговый регламентный документ Отражение зарплаты в бухучете подтягивает эту аналитику напрямую из первичных данных, не требуя записи в плановые регистры.РазовоеНачисление добавлен в состав регистраторов регистра БухучетПлановыхНачислений в дереве метаданных. Без этого платформа не сможет очистить движения при отмене проведения или удалении документа.&После("ОбработкаПроведения") в модуле расширения конфигурации.