Как загрузить размеры сотрудников из таблицы в регистр сведений «Значения свойств объектов» в 1С:УПП?

Программист 1С v8.3 (Обычные формы) IT и автоматизация бизнеса
← На главную

При переносе кадровой информации или данных по спецодежде из устаревших систем (например, 1С 7.7) в 1С:Управление производственным предприятием (УПП) часто требуется перенести индивидуальные характеристики работников: размер обуви, размер спецодежды и рост. Ручной ввод для сотен и тысяч сотрудников занимает слишком много времени, поэтому рациональнее автоматизировать процесс загрузки через внешнюю обработку.

Разберем по шагам, как выгрузить таблицу из исходной базы, быстро прочитать табличный документ встроенными средствами платформы 1С:Предприятие 8.3, правильно привязать свойства к физическим лицам и избежать критической потери уже внесенных данных в регистре сведений.

Шаг 1. Преобразование табличного документа в таблицу значений

Для быстрой загрузки сформируем в исходной базе отчет или сохраним файл со следующими колонками: Таб (табельный номер), ФИО, РазмерОбуви, РазмерОдежды, Рост. Полученный документ можно вставить в поле табличного документа на форме обработки в 1С 8.

Чтобы не обходить ячейки табличного документа медленными циклами по координатам, используем возможности объекта ПостроительОтчета. Он позволяет мгновенно преобразовать область ячеек в объект ТаблицаЗначений. Имена колонок таблицы значений автоматически формируются из заголовков первой строки таблицы.

Посмотрим на пример функции преобразования:


Функция ПреобразоватьТабличныйДокументВТаблицуЗначений(ТабДокумент)
    
    ПоследняяСтрока = ТабДокумент.ВысотаТаблицы;
    ПоследняяКолонка = ТабДокумент.ШиринаТаблицы;
    ОбластьЯчеек = ТабДокумент.Область(1, 1, ПоследняяСтрока, ПоследняяКолонка);
    
    // Создаем описание источника данных на основании области ячеек табличного документа
    ИсточникДанных = Новый ОписаниеИсточникаДанных(ОбластьЯчеек);
    
    // Выполняем построение отчета для выгрузки структуры в память
    ПостроительОтчета = Новый ПостроительОтчета;
    ПостроительОтчета.ИсточникДанных = ИсточникДанных;
    ПостроительОтчета.Выполнить();
    
    // Результат выгружаем в таблицу значений
    Возврат ПостроительОтчета.Результат.Выгрузить();
    
КонецФункции

Шаг 2. Разбор алгоритма загрузки и поиск сотрудника

В конфигурации 1С:УПП свойства спецодежды привязываются не к элементу справочника СотрудникиОрганизаций, а к справочнику ФизическиеЛица. Это связано с тем, что один человек может быть внутренним совместителем или повторно принятым сотрудником, но его антропометрические данные остаются едиными.

Проанализируем базовый вариант обхода строк загруженной таблицы значений:


Процедура ЗагрузитьРазмеры(ТабЗначений)
    
    Для Каждого Стр Из ТабЗначений Цикл
        
        // Поиск сотрудника по табельному номеру
        Сотрудник = Справочники.СотрудникиОрганизаций.НайтиПоКоду(СокрЛП(Стр.Таб));
        
        Если НЕ ЗначениеЗаполнено(Сотрудник) Тогда
            Сообщить("Сотрудник не найден по коду: " + Стр.Таб + " (" + Стр.ФИО + ")");
            Продолжить;
        КонецЕсли;
        
        Лицо = Сотрудник.Физлицо;
        Если НЕ ЗначениеЗаполнено(Лицо) Тогда
            Сообщить("У сотрудника " + Сотрудник + " не заполнено физлицо!");
            Продолжить;
        КонецЕсли;
        
        // Переход к записи свойств физлица
        ЗаписатьСвойстваФизлица(Лицо, Стр);
        
    КонецЦикла;
    
КонецПроцедуры

Обратим внимание на важную деталь: при сохранении в Excel или табличный документ строковые табельные номера часто теряют лидирующие нули (например, код "000000123" превращается в число 123). Метод НайтиПоКоду ищет точное совпадение строки. Если поиск не находит сотрудников, перед поиском необходимо дополнить код нулями слева до стандартной длины кода справочника через строковые функции.

Шаг 3. Запись в регистр сведений и защита от удаления существующих данных

Выясним причину частой ошибки при записи в регистр РегистрыСведений.ЗначенияСвойствОбъектов. Если создать набор записей, установить отбор только по полю Объект и вызвать метод Записать(), то при записи будут удалены абсолютно все прочие свойства данного человека, внесенные в базу ранее (например, водительские удостоверения, сведения об инвалидности, прочие допреквизиты).

Чтобы не затереть существующие данные в регистре, применим один из двух подходов:

  1. Использование менеджера записи: объект СоздатьМенеджерЗаписи() работает точечно с одной строкой регистра по связке измерений Объект и Свойство. Если запись существует, она обновляется; если отсутствует — создается новая. При этом другие свойства человека не затрагиваются.
  2. Установка полного отбора в наборе записей: перед записью набора устанавливать отбор сразу по двум измерениям — Отбор.Объект.Установить(...) и Отбор.Свойство.Установить(...).

Рассмотрим реализацию через МенеджерЗаписи, как наиболее безопасный и прозрачный метод:


Процедура ЗаписатьСвойствоФизлица(ОбъектСсылка, ПланСвойство, ЗначениеСвойства)
    
    Если НЕ ЗначениеЗаполнено(ЗначениеСвойства) Тогда
        Возврат;
    КонецЕсли;
    
    МенеджерЗаписи = РегистрыСведений.ЗначенияСвойствОбъектов.СоздатьМенеджерЗаписи();
    МенеджерЗаписи.Объект = ОбъектСсылка;
    МенеджерЗаписи.Свойство = ПланСвойство;
    
    // Пробуем прочитать текущую запись
    МенеджерЗаписи.Прочитать();
    
    // Устанавливаем новое значение и фиксируем запись
    МенеджерЗаписи.Объект = ОбъектСсылка;
    МенеджерЗаписи.Свойство = ПланСвойство;
    МенеджерЗаписи.Значение = ЗначениеСвойства;
    МенеджерЗаписи.Записать(Истина);
    
КонецПроцедуры

Шаг 4. Учет типов данных в плане видов характеристик

Проанализируем тип данных в плане видов характеристик СвойстваОбъектов типовой конфигурации УПП. Для свойств спецодежды («Размер обуви», «Размер одежды», «Рост») в конфигурации часто назначен ссылочный тип данных — СправочникСсылка.ЗначенияСвойствОбъектов, а не примитивная строка или число.

Справочник ЗначенияСвойствОбъектов является подчиненным: его владельцем выступает соответствующий элемент плана видов характеристик СвойстваОбъектов. Если попытаться записать обычную строку в поле со ссылочным типом, платформа либо выдаст ошибку несоответствия типов, либо запишет пустую ссылку.

Разберем функцию поиска или автоматического создания значения свойства:


Функция ПолучитьЗначениеХарактеристики(СвойствоСсылка, ЗначениеСтрока)
    
    СтрокаПоиска = СокрЛП(ЗначениеСтрока);
    Если ПустаяСтрока(СтрокаПоиска) Тогда
        Возврат Неопределено;
    КонецЕсли;
    
    // Проверяем, ожидает ли свойство ссылку на подчиненный справочник
    Если СвойствоСсылка.ТипЗначения.СодержитТип(Тип("СправочникСсылка.ЗначенияСвойствОбъектов")) Тогда
        
        Значение = Справочники.ЗначенияСвойствОбъектов.НайтиПоНаименованию(СтрокаПоиска, Истина, , СвойствоСсылка);
        
        Если НЕ ЗначениеЗаполнено(Значение) Тогда
            // Создаем новый элемент подчиненного справочника
            НовыйЭлемент = Справочники.ЗначенияСвойствОбъектов.СоздатьЭлемент();
            НовыйЭлемент.Владелец = СвойствоСсылка;
            НовыйЭлемент.Наименование = СтрокаПоиска;
            НовыйЭлемент.Записать();
            Значение = НовыйЭлемент.Ссылка;
        КонецЕсли;
        
        Возврат Значение;
        
    ИначеЕсли СвойствоСсылка.ТипЗначения.СодержитТип(Тип("Число")) Тогда
        Возврат Число(СтрокаПоиска);
    Иначе
        Возврат СтрокаПоиска;
    КонецЕсли;
    
КонецФункции

Шаг 5. Оптимизация производительности при массовой загрузке

Если необходимо обработать тысячи строк, выполнение операций поиска метаданных внутри цикла приведет к существенному замедлению. Чтобы ускорить загрузку, применим следующие рекомендации:

  1. Вынос ссылок на свойства из цикла: вызовы ПланыВидовХарактеристик.СвойстваОбъектов.НайтиПоНаименованию() следует выполнить один раз до начала обхода строк и сохранить найденные ссылки в переменные.
  2. Использование явных транзакций: запись наборов данных в СУБД по умолчанию фиксирует каждую операцию отдельно. Обернув обработку пачек строк (например, по 500 записей) в конструкции НачатьТранзакцию() и ЗафиксироватьТранзакцию(), мы многократно сократим время дисковых операций записи.
← На главную