Из статьи ИТС:
1. Для автоматического заполнения формы № ЗП-образование в форме справочника Должности необходимо заполнить поле Строка отчетности ЗП-Образование (Сфера образования).
2. Если в учреждении ведется штатное расписание, то необходимо проверить заполнение поля Строка отчетности ЗП-Образование (Сфера образования) в строке штатного расписания на закладке Дополнительно при утверждении, изменении штатного расписания.
... В итоге по всем позициям штатного расписания нужно указать категорию, заходя в документы и записывая. Если позиций штатки много (300+), то удобней воспользоваться обработкой.
Данная обработка также подойдёт для оперативной проверки заполнения категорий должностей (привязка должностей к строкам мониторинга по формам ЗП-хх) для выполнения поручения президента пр-366 от 8 марта 2021.
Инструкция по использованию в справке обработки.
// работа по заполнению регистров
&НаСервере
Функция считать_данные_и_проверить(должность_выбр, режим_запуска)
сообщ = Новый СообщениеПользователю;
// две проверки
заполнено_д = Истина;
заполнено_ш = Истина;
// 1-ая проверка
запрос = новый Запрос;
запрос.текст = "ВЫБРАТЬ
| СтрокиОтчетностиМониторингаРаботниковСоциальнойСферы.СтрокаОтчетностиМониторингаРаботниковСоциальнойСферы КАК Значение
|ИЗ
| РегистрСведений.СтрокиОтчетностиМониторингаРаботниковСоциальнойСферы КАК СтрокиОтчетностиМониторингаРаботниковСоциальнойСферы
|ГДЕ
| СтрокиОтчетностиМониторингаРаботниковСоциальнойСферы.Должность = &должн";
запрос.УстановитьПараметр("должн", должность_выбр);
знач_д = запрос.Выполнить().Выгрузить();
Если (знач_д.Количество() = 0) Тогда
// нет строки
заполнено_д = Ложь;
значение_РЕЗ_предв = Справочники.СтрокиОтчетностиМониторингаРаботниковСоциальнойСферы.ПустаяСсылка();
ИначеЕсли (знач_д.Количество() = 1) Тогда
значение_РЕЗ_предв = знач_д.Получить(0).Значение;
Если (значение_РЕЗ_предв = Справочники.СтрокиОтчетностиМониторингаРаботниковСоциальнойСферы.ПустаяСсылка()) Тогда
// пустое значение
заполнено_д = Ложь;
Иначе
// норм
КонецЕсли;
ИначеЕсли (знач_д.Количество() > 1) Тогда
стр_список = "";
Для каждого тек_зн из знач_д Цикл
стр_список = стр_список + " | "+тек_зн.Значение;
КонецЦикла;
сообщ.Текст = "много значений на ВЫБРАННУЮ должность "+стр_список;
сообщ.Сообщить();
КонецЕсли;
// 2-ая проверка
запрос = Новый запрос;
запрос.Текст = "ВЫБРАТЬ
//| ШтатноеРасписание.КатегорияПерсонала КАК категория,
//| ШтатноеРасписание.Должность.КвалификационнаяГруппа КАК квал_гр,
//| ШтатноеРасписание.Должность.КвалификационныйУровень КАК квал_ур,
| ШтатноеРасписание.Ссылка КАК позиция_штат
|ИЗ
| Справочник.ШтатноеРасписание КАК ШтатноеРасписание
|ГДЕ
| (ШтатноеРасписание.Закрыта = ЛОЖЬ
| ИЛИ ШтатноеРасписание.ДатаЗакрытия > &начало_ГОДА)
| И ШтатноеРасписание.Должность = &должн
| И ШтатноеРасписание.ПометкаУдаления = ЛОЖЬ
| И ШтатноеРасписание.Утверждена = ИСТИНА
|
|СГРУППИРОВАТЬ ПО
//| ШтатноеРасписание.Ссылка,
//| ШтатноеРасписание.КатегорияПерсонала
| ШтатноеРасписание.Ссылка
|
|УПОРЯДОЧИТЬ ПО
//| ШтатноеРасписание.КатегорияПерсонала,
| позиция_штат";
дата_год_отчёта = Дата(год_отчёта,1,1);
запрос.УстановитьПараметр("начало_года", НачалоГода(КонецДня(дата_год_отчёта)) );
запрос.УстановитьПараметр("должн", должность_выбр);
тз_исп_штат_по_должн = запрос.Выполнить().Выгрузить();
тз_исп_штат_по_должн.Колонки.Добавить("значение");
// по каждой РАБОЧЕЙ(используемой) позиции проверка заполнения
Для каждого тек_поз из тз_исп_штат_по_должн Цикл
запрос = новый Запрос;
запрос.текст = "ВЫБРАТЬ
| СтрокиОтчетностиМониторингаРаботниковСоциальнойСферы.СтрокаОтчетностиМониторингаРаботниковСоциальнойСферы КАК Значение
|ИЗ
| РегистрСведений.СтрокиОтчетностиМониторингаРаботниковСоциальнойСферы КАК СтрокиОтчетностиМониторингаРаботниковСоциальнойСферы
|ГДЕ
| СтрокиОтчетностиМониторингаРаботниковСоциальнойСферы.Должность = &позиция
|
|СГРУППИРОВАТЬ ПО
| СтрокиОтчетностиМониторингаРаботниковСоциальнойСферы.СтрокаОтчетностиМониторингаРаботниковСоциальнойСферы";
запрос.УстановитьПараметр("позиция", тек_поз.позиция_штат);
тз_штат = запрос.Выполнить().Выгрузить();
Если (тз_штат.Количество() = 0) Тогда
// нет строк
заполнено_ш = ложь;
тек_поз.значение = "";
Иначе
тек_поз.значение = СокрЛП(тз_штат.получить(0).значение);
Если (тек_поз.значение = "") Тогда
// пустое значение
заполнено_ш = ложь;
КонецЕсли;
КонецЕсли;
КонецЦикла;
Если режим_запуска = 1 Тогда
// выбор должности вручную - просто обновление данных формы
значение_РЕЗ = значение_РЕЗ_предв;
значение_установки = Справочники.СтрокиОтчетностиМониторингаРаботниковСоциальнойСферы.ПустаяСсылка();
ЗначениеВРеквизитФормы(тз_исп_штат_по_должн, "тз_всех_позиций_штатного");
Иначе
// в этом режиме обновляем должность
должность = должность_выбр;
// поиск незаполненной должности - обновление если нашли
Если ((заполнено_д = Ложь) или (заполнено_ш = Ложь)) Тогда
значение_РЕЗ = значение_РЕЗ_предв;
значение_установки = Справочники.СтрокиОтчетностиМониторингаРаботниковСоциальнойСферы.ПустаяСсылка();
ЗначениеВРеквизитФормы(тз_исп_штат_по_должн, "тз_всех_позиций_штатного");
КонецЕсли;
КонецЕсли;
//ЭтаФорма.Элементы.тз_всех_позиций_штатного.ТолькоПросмотр = Истина;
Возврат (заполнено_д = Ложь) или (заполнено_ш = Ложь);
КонецФункции
&НаСервере
Процедура должностьПриИзмененииНаСервере()
сообщ = Новый СообщениеПользователю;
Если считать_данные_и_проверить(должность, 1) Тогда
сообщ.Текст = "по выбранной должности есть не заполненные записи - смотрите табличку штатных записей и реквизит ""значение_РЕЗ""";
сообщ.Сообщить();
КонецЕсли;
КонецПроцедуры
&НаКлиенте
Процедура должностьПриИзменении(Элемент)
должностьПриИзмененииНаСервере();
КонецПроцедуры
&НаСервере
Процедура ПриОткрытииНаСервере()
год_отчёта = Год(ТекущаяДата());
// Настройка реквизита формы - Таблица значений 1-ая
// подготовока массива реквизитов для внесения изменений на форму только в РАЗДЕЛ РЕКВИЗИТЫ!
МассивРеквизитов = Новый Массив;
ТЗ = Новый ТаблицаЗначений;
// ТЗ.Колонки.Добавить("С", ОписаниеТиповВремя);
ТЗ.Колонки.Добавить("позиция_штат", Новый ОписаниеТипов("СправочникСсылка.ШтатноеРасписание"));
//ТЗ.Колонки.Добавить("категория", Новый ОписаниеТипов("СправочникСсылка.КатегорииПерсонала"));
//ТЗ.Колонки.Добавить("квал_гр", Новый ОписаниеТипов("СправочникСсылка.КвалификационныеГруппыДолжностей"));
//ТЗ.Колонки.Добавить("квал_ур");
ТЗ.Колонки.Добавить("значение");
Для Каждого Колонка Из ТЗ.Колонки Цикл
МассивРеквизитов.Добавить(Новый РеквизитФормы(Колонка.Имя, Колонка.ТипЗначения, "тз_всех_позиций_штатного"));
КонецЦикла;
// внесение подготовленных изменений в РЕКВИЗИТЫ
ИзменитьРеквизиты(МассивРеквизитов);
// создание элементов на форме!
// коментю - на форме тоже вставил вручную
// 1-ое - сама таблица
//ТаблицаПолейВыбора = Элементы.Добавить("ТЗН", Тип("ТаблицаФормы"));
//ТаблицаПолейВыбора.ПутьКДанным = "ТаблицаРасписания";
//ТаблицаПолейВыбора.Отображение = ОтображениеТаблицы.Список
// 2-ое -- её колонки
Для Каждого Колонка Из ТЗ.Колонки Цикл
НовыйЭлемент = Элементы.Добавить(Колонка.Имя, Тип("ПолеФормы"), Элементы["тз_всех_позиций_штатного"]);
НовыйЭлемент.Вид = ВидПоляФормы.ПолеВвода;
НовыйЭлемент.ПутьКДанным = "тз_всех_позиций_штатного." + Колонка.Имя;
//НовыйЭлемент.Заголовок = Колонка.Заголовок;
КонецЦикла;
// Настройка реквизита формы - Таблица значений 2-ая
МассивРеквизитов2 = Новый Массив;
МассивРеквизитов2.Добавить(Новый РеквизитФормы("должность", Новый ОписаниеТипов("СправочникСсылка.Должности"), "тз_используемые_должности"));
ИзменитьРеквизиты(МассивРеквизитов2);
// иницализация используемых должностей
запрос = Новый запрос;
запрос.Текст = "ВЫБРАТЬ
| ШтатноеРасписание.Должность КАК должность
|ИЗ
| Справочник.ШтатноеРасписание КАК ШтатноеРасписание
|ГДЕ
| (ШтатноеРасписание.Закрыта = ЛОЖЬ
| ИЛИ ШтатноеРасписание.ДатаЗакрытия > &начало_ГОДА)
| И ШтатноеРасписание.ПометкаУдаления = ЛОЖЬ
| И ШтатноеРасписание.Утверждена = ИСТИНА
|
|СГРУППИРОВАТЬ ПО
| ШтатноеРасписание.Должность
|
|УПОРЯДОЧИТЬ ПО
| должность";
дата_год_отчёта = Дата(год_отчёта,1,1);
запрос.УстановитьПараметр("начало_года", НачалоГода(КонецДня(дата_год_отчёта)) );
тз_исп_д = запрос.Выполнить().Выгрузить();
ЗначениеВРеквизитФормы(тз_исп_д, "тз_используемые_должности");
КонецПроцедуры
&НаКлиенте
Процедура ПриОткрытии(Отказ)
ПриОткрытииНаСервере();
КонецПроцедуры
&НаСервере
Процедура следующая_должность_с_незаполнными_значениямиНаСервере()
// очистка
должность = Справочники.Должности.ПустаяСсылка();
значение_РЕЗ = Справочники.СтрокиОтчетностиМониторингаРаботниковСоциальнойСферы.ПустаяСсылка();
значение_установки = Справочники.СтрокиОтчетностиМониторингаРаботниковСоциальнойСферы.ПустаяСсылка();
//тз_всех_позиций_штатного.Очистить();
Для каждого тек_ш из тз_используемые_должности Цикл
Если (СокрЛП(тек_ш.Должность) = "") или
(СтрНайти(Нрег(СокрЛП(тек_ш.Должность)), "несотрудник") > 0) или
(СтрНайти(Нрег(СокрЛП(тек_ш.Должность)), "не сотрудник") > 0) Тогда
Продолжить;
КонецЕсли;
Если (считать_данные_и_проверить(тек_ш.Должность, 2)) Тогда
// незаполненная должность найдена - выход
возврат;
КонецЕсли;
КонецЦикла;
КонецПроцедуры
&НаКлиенте
Процедура следующая_должность_с_незаполнными_значениями(Команда)
следующая_должность_с_незаполнными_значениямиНаСервере();
КонецПроцедуры
&НаСервере
Процедура установить_должностиНаСервере()
сообщ = Новый СообщениеПользователю;
Если (значение_установки = Справочники.СтрокиОтчетностиМониторингаРаботниковСоциальнойСферы.ПустаяСсылка()) Тогда
сообщ.Текст = "не выбрано УСТАНАВЛИВАЕМОЕ значение";
сообщ.Сообщить();
возврат;
КонецЕсли;
// два регистра для заполнения и третий синхронизируется с ними
// начальная инициализация
измерение_свойство = ПланыВидовХарактеристик.ДолжностиПодключаемыеХарактеристики.НайтиПоНаименованию("Строка отчетности мониторинга работников социальной сферы");
// 1-ый регистр подключаемый к должностям
мен_зап = РегистрыСведений.ДолжностиПодключаемыеХарактеристики.СоздатьМенеджерЗаписи();
// поиск
мен_зап.Объект = должность;
мен_зап.Свойство = измерение_свойство;
мен_зап.ИдентификаторИсточника = "СтрСтатСо";
мен_зап.Значение = значение_установки;
мен_зап.Записать(Истина);
// синхронизация с третьим регом
мен_зап = РегистрыСведений.СтрокиОтчетностиМониторингаРаботниковСоциальнойСферы.СоздатьМенеджерЗаписи();
мен_зап.должность = должность;
мен_зап.СтрокаОтчетностиМониторингаРаботниковСоциальнойСферы = значение_установки;
мен_зап.Записать(Истина);
// 2-ой регистр подключаемый к штаному расписанию
Для каждого тек_стр из тз_всех_позиций_штатного Цикл
мен_зап = РегистрыСведений.ШтатноеРасписаниеПодключаемыеХарактеристики.СоздатьМенеджерЗаписи();
// поиск
мен_зап.Объект = тек_стр.позиция_штат;
мен_зап.Свойство = измерение_свойство;
мен_зап.ИдентификаторИсточника = "СтрСтатСо";
мен_зап.Значение = значение_установки;
мен_зап.Записать(Истина);
// синхронизация с третьим регом
мен_зап = РегистрыСведений.СтрокиОтчетностиМониторингаРаботниковСоциальнойСферы.СоздатьМенеджерЗаписи();
мен_зап.должность = тек_стр.позиция_штат;
мен_зап.СтрокаОтчетностиМониторингаРаботниковСоциальнойСферы = значение_установки;
мен_зап.Записать(Истина);
КонецЦикла;
// обновление после исправления
считать_данные_и_проверить(должность, 1);
позиция_штатногоПриИзмененииНаСервере();
КонецПроцедуры
&НаКлиенте
Процедура установить_должности(Команда)
установить_должностиНаСервере();
КонецПроцедуры
&НаСервере
Процедура установить_ВСЕМ_штатным_из_РЕЗ_СЕРВАК()
значение_установки = значение_РЕЗ;
КонецПроцедуры
&НаКлиенте
Процедура установить_ВСЕМ_штатным_из_РЕЗ(Команда)
установить_ВСЕМ_штатным_из_РЕЗ_СЕРВАК();
установить_должностиНаСервере();
КонецПроцедуры
// работа с выбранной позицией штатного
&НаСервере
Процедура установить_позиции_штатНаСервере()
// начальная инициализация
измерение_свойство = ПланыВидовХарактеристик.ДолжностиПодключаемыеХарактеристики.НайтиПоНаименованию("Строка отчетности мониторинга работников социальной сферы");
мен_зап = РегистрыСведений.ШтатноеРасписаниеПодключаемыеХарактеристики.СоздатьМенеджерЗаписи();
// поиск
мен_зап.Объект = позиция_штатного;
мен_зап.Свойство = измерение_свойство;
мен_зап.ИдентификаторИсточника = "СтрСтатСо";
мен_зап.Значение = значение_установки_штат;
мен_зап.Записать(Истина);
// синхронизация с третьим регом
мен_зап = РегистрыСведений.СтрокиОтчетностиМониторингаРаботниковСоциальнойСферы.СоздатьМенеджерЗаписи();
мен_зап.должность = позиция_штатного;
мен_зап.СтрокаОтчетностиМониторингаРаботниковСоциальнойСферы = значение_установки_штат;
мен_зап.Записать(Истина);
// обновление
считать_данные_и_проверить(должность, 1);
позиция_штатногоПриИзмененииНаСервере();
КонецПроцедуры
&НаКлиенте
Процедура установить_позиции_штат(Команда)
установить_позиции_штатНаСервере();
КонецПроцедуры
&НаСервере
Процедура позиция_штатногоПриИзмененииНаСервере()
запрос = новый Запрос;
запрос.текст = "ВЫБРАТЬ
| СтрокиОтчетностиМониторингаРаботниковСоциальнойСферы.СтрокаОтчетностиМониторингаРаботниковСоциальнойСферы КАК Значение
|ИЗ
| РегистрСведений.СтрокиОтчетностиМониторингаРаботниковСоциальнойСферы КАК СтрокиОтчетностиМониторингаРаботниковСоциальнойСферы
|ГДЕ
| СтрокиОтчетностиМониторингаРаботниковСоциальнойСферы.Должность = &позиция
|
|СГРУППИРОВАТЬ ПО
| СтрокиОтчетностиМониторингаРаботниковСоциальнойСферы.СтрокаОтчетностиМониторингаРаботниковСоциальнойСферы";
запрос.УстановитьПараметр("позиция", позиция_штатного);
тз_штат = запрос.Выполнить().Выгрузить();
Если (тз_штат.Количество() = 0) Тогда
// нет строк
значение_РЕЗ_штат = Справочники.СтрокиОтчетностиМониторингаРаботниковСоциальнойСферы.ПустаяСсылка();
Иначе
значение_РЕЗ_штат = тз_штат.получить(0).значение;
//Если (тек_поз.значение = "") Тогда
// // пустое значение
// заполнено_ш = ложь;
//КонецЕсли;
КонецЕсли;
значение_установки_штат = Справочники.СтрокиОтчетностиМониторингаРаботниковСоциальнойСферы.ПустаяСсылка();
КонецПроцедуры
&НаКлиенте
Процедура позиция_штатногоПриИзменении(Элемент)
позиция_штатногоПриИзмененииНаСервере();
КонецПроцедуры
&НаКлиенте
Процедура справка(Команда)
КонецПроцедуры
&НаСервере
Процедура анализ_регистровНаСервере()
// 1. сбор данных из ТРЁХ регистров
запрос = новый Запрос;
запрос.текст = "ВЫБРАТЬ
| СтрокиОтчетностиМониторингаРаботниковСоциальнойСферы.Должность КАК Должность,
| СтрокиОтчетностиМониторингаРаботниковСоциальнойСферы.СтрокаОтчетностиМониторингаРаботниковСоциальнойСферы КАК Значение
|ИЗ
| РегистрСведений.СтрокиОтчетностиМониторингаРаботниковСоциальнойСферы КАК СтрокиОтчетностиМониторингаРаботниковСоциальнойСферы
|
|УПОРЯДОЧИТЬ ПО
| Должность";
тз_монитор = запрос.Выполнить().Выгрузить();
запрос = новый Запрос;
запрос.текст = "ВЫБРАТЬ
| ШтатноеРасписаниеПодключаемыеХарактеристики.Объект КАК Объект,
| ШтатноеРасписаниеПодключаемыеХарактеристики.Свойство КАК Свойство,
| ШтатноеРасписаниеПодключаемыеХарактеристики.ИдентификаторИсточника КАК ИдентификаторИсточника,
| ШтатноеРасписаниеПодключаемыеХарактеристики.Значение КАК Значение,
| ШтатноеРасписаниеПодключаемыеХарактеристики.Объект.Должность КАК Должность
|ИЗ
| РегистрСведений.ШтатноеРасписаниеПодключаемыеХарактеристики КАК ШтатноеРасписаниеПодключаемыеХарактеристики
|
|УПОРЯДОЧИТЬ ПО
| Должность,
| Объект";
тз_штат = запрос.Выполнить().Выгрузить();
запрос = новый Запрос;
запрос.текст = "ВЫБРАТЬ
| ДолжностиПодключаемыеХарактеристики.Объект КАК Должность,
| ДолжностиПодключаемыеХарактеристики.Свойство КАК Свойство,
| ДолжностиПодключаемыеХарактеристики.ИдентификаторИсточника КАК ИдентификаторИсточника,
| ДолжностиПодключаемыеХарактеристики.Значение КАК Значение
|ИЗ
| РегистрСведений.ДолжностиПодключаемыеХарактеристики КАК ДолжностиПодключаемыеХарактеристики
|
|УПОРЯДОЧИТЬ ПО
| Должность";
тз_должн = запрос.Выполнить().Выгрузить();
сообщ = Новый СообщениеПользователю;
// 2. проверка заполнения регистра "СтрокиОтчетностиМониторингаРаботниковСоциальнойСферы" по двум исходным регистрам (характ. по штатке и должностям )
// 2.1 Сравнение по должности данных двух регов: тз_монитор и тз_должн
Для каждого тек_мон из тз_монитор Цикл
Если ТипЗнч(тек_мон.Должность) = Тип("СправочникСсылка.Должности") Тогда
// в реге, подключаемого к ДОЛЖНОСТЯМ, должность это измерение - одна строка на должность
найд_свойство_должн = тз_должн.Найти(тек_мон.Должность, "Должность");
Если (найд_свойство_должн <> Неопределено) Тогда
// сравнение значений свойств из регистра, подключаемого к ДОЛЖНОСТЯМ, по одной должности
Если (тек_мон.Значение <> найд_свойство_должн.Значение) Тогда
сообщ.Текст = "1 --- расхождение --- "+тек_мон.Должность+" --- "+тек_мон.Значение+" --- "+найд_свойство_должн.Значение;
сообщ.Сообщить();
КонецЕсли;
Иначе
// в стандартной ДЕМО базе подключенных характеристик нет - сообщение отключаю
//сообщ.Текст = "1 --- не найдено подключение к должности --- "+тек_мон.Должность;
//сообщ.Сообщить();
КонецЕсли;
КонецЕсли;
КонецЦикла;
// для проверки на пустующие записи прохожу циклом по данным рега: тз_должн
Для каждого тек_должн из тз_должн Цикл
найд_свойство_мон = тз_монитор.Найти(тек_должн.Должность, "Должность");
Если (найд_свойство_мон = Неопределено) Тогда
сообщ.Текст = "1 --- не найдена строка монитор --- "+тек_должн.Должность;
сообщ.Сообщить();
КонецЕсли;
КонецЦикла;
// 2.2 Сравнение по штатке данных двух регов: тз_монитор и тз_должн
Для каждого тек_мон из тз_монитор Цикл
Если ТипЗнч(тек_мон.Должность) = Тип("СправочникСсылка.ШтатноеРасписание") Тогда
// в реге, подключаемого к ШТАТКЕ, штатка это измерение - одна строка на штатку
найд_свойство_штат = тз_штат.Найти(тек_мон.Должность, "Объект");
Если (найд_свойство_штат <> Неопределено) Тогда
// сравнение значений свойств из регистра, подключаемого к ШТАТКЕ, по одной должности
Если (тек_мон.Значение <> найд_свойство_штат.Значение) Тогда
сообщ.Текст = "2 --- расхождение --- "+тек_мон.Должность+" --- "+тек_мон.Значение+" --- "+найд_свойство_штат.Значение;
сообщ.Сообщить();
КонецЕсли;
Иначе
// в стандартной ДЕМО базе подключенных характеристик нет - сообщение отключаю
//сообщ.Текст = "2 --- не найдено подключение к штатному --- "+тек_мон.Должность;
//сообщ.Сообщить();
КонецЕсли;
КонецЕсли;
КонецЦикла;
// для проверки на пустующие записи прохожу циклом по данным рега: тз_штат
тз_штат.Колонки.Добавить("зн_долж");
Для каждого тек_штат из тз_штат Цикл
найд_свойство_мон = тз_монитор.Найти(тек_штат.Объект, "Должность");
Если (найд_свойство_мон = Неопределено) Тогда
сообщ.Текст = "2 --- не найдена строка монитор --- "+тз_штат.Объект;
сообщ.Сообщить();
КонецЕсли;
КонецЦикла;
// 3. проверка расхождений значений категорий по должности со штаткой
// создание колонки только с типом "должность"
тз_монитор.Колонки.Добавить("зн_долж");
Для каждого тек_мон из тз_монитор Цикл
Если ТипЗнч(тек_мон.Должность) = Тип("СправочникСсылка.Должности") Тогда
тек_мон.зн_долж = тек_мон.Должность;
Иначе
тек_мон.зн_долж = тек_мон.Должность.Должность;
КонецЕсли;
КонецЦикла;
тз_мон_сверн = тз_монитор.Скопировать();
тз_мон_сверн.Свернуть("зн_долж, Значение");
тз_мон_сверн.Колонки.Добавить("кол");
Для каждого тек_мон из тз_мон_сверн Цикл
тек_мон.кол = 1;
КонецЦикла;
тз_мон_сверн.Свернуть("зн_долж", "кол");
Для каждого тек_мон из тз_мон_сверн Цикл
Если (тек_мон.кол > 1) Тогда
запрос = новый Запрос;
запрос.текст = "ВЫБРАТЬ
| ШтатноеРасписаниеПодключаемыеХарактеристики.Значение КАК Значение
|ИЗ
| РегистрСведений.ШтатноеРасписаниеПодключаемыеХарактеристики КАК ШтатноеРасписаниеПодключаемыеХарактеристики
|ГДЕ
| ШтатноеРасписаниеПодключаемыеХарактеристики.Объект.Должность = &должн
|
|СГРУППИРОВАТЬ ПО
| ШтатноеРасписаниеПодключаемыеХарактеристики.Значение";
запрос.УстановитьПараметр("должн", тек_мон.зн_долж);
тз_знач_штат = запрос.Выполнить().Выгрузить();
запрос = новый Запрос;
запрос.текст = "ВЫБРАТЬ
| ДолжностиПодключаемыеХарактеристики.Значение КАК Значение
|ИЗ
| РегистрСведений.ДолжностиПодключаемыеХарактеристики КАК ДолжностиПодключаемыеХарактеристики
|ГДЕ
| ДолжностиПодключаемыеХарактеристики.Объект = &должн
|
|СГРУППИРОВАТЬ ПО
| ДолжностиПодключаемыеХарактеристики.Значение";
запрос.УстановитьПараметр("должн", тек_мон.зн_долж);
тз_знач_долж = запрос.Выполнить().Выгрузить();
есть_пустые_значения = Ложь;
Для каждого тек_ш из тз_знач_штат Цикл
Для каждого тек_д из тз_знач_штат Цикл
Если (СокрЛП(тек_д.Значение) <> "") и
(СокрЛП(тек_ш.Значение) <> "") и
(тек_д.Значение <> тек_ш.Значение) Тогда
// вывод РАЗНЫХ и НЕпустых значений
сообщ.Текст = "33333 --- есть РАЗНЫЕ значения по ТИПУ должности --- "+тек_мон.зн_долж+" --- "+тек_д.Значение+" --- "+тек_ш.Значение;
сообщ.Сообщить();
Иначе
есть_пустые_значения = Истина;
КонецЕсли;
КонецЦикла;
КонецЦикла;
Если (есть_пустые_значения = Истина) Тогда
сообщ.Текст = "3 --- есть пустое и НЕпустое значение по ТИПУ должности --- "+тек_мон.зн_долж;
сообщ.Сообщить();
КонецЕсли;
КонецЕсли;
КонецЦикла;
// 4. проверка расхождений значений характеристик по СТРОКЕ должности со штаткой
// создание колонки только со строкой "должность"
тз_монитор.Колонки.Добавить("стр_долж");
Для каждого тек_мон из тз_монитор Цикл
Если ТипЗнч(тек_мон.Должность) = Тип("СправочникСсылка.Должности") Тогда
тек_мон.стр_долж = СокрЛП(тек_мон.Должность.наименование);
Иначе
тек_мон.стр_долж = СокрЛП(тек_мон.Должность.Должность);
КонецЕсли;
КонецЦикла;
тз_мон_сверн = тз_монитор.Скопировать();
тз_мон_сверн.Сортировать("стр_долж Возр");
нов_должн = "";
Для каждого тек_мон из тз_мон_сверн Цикл
Если (нов_должн <> тек_мон.стр_долж) Тогда
первое_знач = "";
второе_знач = "";
третье_знач = "";
нов_должн = тек_мон.стр_долж;
КонецЕсли;
//Если ("Заместитель директора" = тек_мон.стр_долж) Тогда
// ттт = 1;
//КонецЕсли;
Если (СокрЛП(тек_мон.Значение) <> "") Тогда
// обработка
Если (первое_знач = "") Тогда
первое_знач = СокрЛП(тек_мон.Значение);
Иначе
// надо сравнить с первым
Если (первое_знач <> СокрЛП(тек_мон.Значение)) Тогда
// есть неравное значение
// оно новое ?
новое_зн = Ложь;
// проверка - 1
Если (второе_знач = "") Тогда
новое_зн = Истина;
второе_знач = СокрЛП(тек_мон.Значение);
Иначе
Если (второе_знач = СокрЛП(тек_мон.Значение)) тогда
// уже было такое значение - никаких движений
Иначе
// проверка - 2
Если (третье_знач = "") Тогда
новое_зн = Истина;
третье_знач = СокрЛП(тек_мон.Значение);
Иначе
Если (третье_знач = СокрЛП(тек_мон.Значение)) тогда
// уже было такое значение - никаких движений
Иначе
// проверка не будет - вывожу всё
новое_зн = Истина;
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если (новое_зн = Истина) Тогда
сообщ.Текст = "444 --- есть РАЗНЫЕ значения по СТРОКЕЕЕЕЕЕЕЕ должности --- "+тек_мон.стр_долж+" --- "+первое_знач+" --- "+СокрЛП(тек_мон.Значение);
сообщ.Сообщить();
КонецЕсли;
Иначе
// норм - никаких движений
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЦикла;
// 5. проверка полного заполнения характеристик по всем, используеым за год, штатным расписаниям
запрос = Новый запрос;
запрос.Текст = "ВЫБРАТЬ
| ШтатноеРасписание.Ссылка КАК позиция,
| ШтатноеРасписание.Подразделение КАК Подразделение
|ИЗ
| Справочник.ШтатноеРасписание КАК ШтатноеРасписание
|ГДЕ
| (ШтатноеРасписание.Закрыта = ЛОЖЬ
| ИЛИ ШтатноеРасписание.ДатаЗакрытия > &начало_ГОДА)
| И ШтатноеРасписание.ПометкаУдаления = ЛОЖЬ
| И ШтатноеРасписание.Утверждена = ИСТИНА
|
|СГРУППИРОВАТЬ ПО
| ШтатноеРасписание.Ссылка,
| ШтатноеРасписание.Подразделение
|
|УПОРЯДОЧИТЬ ПО
| Подразделение,
| позиция";
дата_год_отчёта = Дата(год_отчёта,1,1);
запрос.УстановитьПараметр("начало_года", НачалоГода(КонецДня(дата_год_отчёта)) );
тз_исп_штат = запрос.Выполнить().Выгрузить();
Для каждого тек_ш из тз_исп_штат Цикл
Если (СокрЛП(тек_ш.позиция) <> СокрЛП(тек_ш.Подразделение)) Тогда
найд_свойство_мон = тз_монитор.Найти(тек_ш.позиция, "Должность");
Если (найд_свойство_мон = Неопределено) Тогда
сообщ.Текст = "55555 --- не найдена строка монитор --- "+тек_ш.позиция;
сообщ.Сообщить();
КонецЕсли;
КонецЕсли;
КонецЦикла;
// 6. проверка пустых значений для штатки
// ... а для должности ничего не вывожу
Для каждого тек_мон из тз_монитор Цикл
Если ТипЗнч(тек_мон.Должность) = Тип("СправочникСсылка.ШтатноеРасписание") Тогда
Если (СокрЛП(тек_мон.Значение) = "") Тогда
сообщ.Текст = "6 6 6 6 --- пустое значение по штатке --- "+тек_мон.Должность;
сообщ.Сообщить();
КонецЕсли;
КонецЕсли;
КонецЦикла;
КонецПроцедуры
&НаКлиенте
Процедура анализ_регистров(Команда)
анализ_регистровНаСервере();
КонецПроцедуры
Тестировал на конфигурация ЗГУ 3.1 (3.1.10.470), 1С:Предприятие 8.3 (8.3.15.1958).
... Также для формы ЗП-Образование можно сделать подробную расшифровку формы ЗП-Образование:
в рабочей конфигурации у отчёта "СтатистикаПерсонала"отредактировать макет "СхемаКомпоновкиДанныхКадры" - на закладке "Настройки" выбрать вариант "Расшифровка" (Расшифровка рег.отчета) и открыть редактирование единственной строки с полем "Сотрудник". Добавить ещё поля в эту строку, к примеру. В очередном обновлении эту правку можно затереть.
Или можно сделать расширение для подробной расшифровки:
В общем модуле "СтатистикаПерсоналаРасширенный" нужно перехватить выбор "СхемаКомпоновкиДанных" и указать свой вариант, который удобно разместить в добавленном в расширение отчёте.
&Вместо ("СформироватьОтчетРасшифровку")
Процедура Расш_СформироватьОтчетРасшифровку(Параметры, ДокументРезультат) Экспорт
ВидСКД = "";
ВнешниеНаборыДанных = Неопределено;
ОпределитьВидСКД(Параметры, , ВидСКД, Ложь, ВнешниеНаборыДанных);
СхемаКомпоновки = Расш_СКДОтчетаСтатистикаПерсонала(ВидСКД, Параметры.ИмяСКД); // переписанная функция
КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
НастройкиОтчета = ЗаполнитьКомпоновщикНастроек(Параметры.ИмяСКД, Параметры, СхемаКомпоновки);
МакетКомпоновкиДанных = КомпоновщикМакета.Выполнить(СхемаКомпоновки, НастройкиОтчета);
ПроцессорКомпоновкиДанных = Новый ПроцессорКомпоновкиДанных;
Если ВнешниеНаборыДанных <> Неопределено Тогда
ПроцессорКомпоновкиДанных.Инициализировать(МакетКомпоновкиДанных, ВнешниеНаборыДанных, , Истина);
Иначе
ПроцессорКомпоновкиДанных.Инициализировать(МакетКомпоновкиДанных, , , Истина);
КонецЕсли;
ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент;
ПроцессорВывода.УстановитьДокумент(ДокументРезультат);
ПроцессорВывода.Вывести(ПроцессорКомпоновкиДанных, Истина);
КонецПроцедуры
Функция Расш_СКДОтчетаСтатистикаПерсонала(ВидСКД, имя_скд)
Если (ВидСКД = "СхемаКомпоновкиДанныхКадры") и (имя_скд = "Расшифровка") Тогда
СхемаКомпоновки = Отчеты.Расш2_СтатистикаПерсонала_верс_2.ПолучитьМакет("СхемаКомпоновкиДанныхКадры_нов");
Иначе
СхемаКомпоновки = Отчеты.СтатистикаПерсонала.ПолучитьМакет(ВидСКД);
КонецЕсли;
Если ВидСКД <> "СхемаКомпоновкиДанныхФормаП4НЗ" Тогда
ЗарплатаКадрыОбщиеНаборыДанных.ЗаполнитьОбщиеИсточникиДанныхОтчета(Новый Структура("СхемаКомпоновкиДанных", СхемаКомпоновки), , Ложь);
ДополнитьСхемуКомпоновкиРегламентированногоОтчета(СхемаКомпоновки);
КонецЕсли;
Возврат СхемаКомпоновки;
КонецФункции
Свою СхемаКомпоновкиДанных создал так:
1. Скопировал макет "СхемаКомпоновкиДанныхКадры" из отчёта "СтатистикаПерсонала" сначала в новый ВНЕШНИЙ отчёт, так как в расширении открытие и редактирование выдаёт ошибки.
2. Доработал макет под свои нужды.
3. Затем добавил НОВый отчёт в расширение и скопировал доработанный макет в него.