Переход со старых версий программного обеспечения на новые платформы — это всегда ответственный процесс, который нередко сопровождается появлением различных артефактов в данных. При переносе кадровых данных из устаревшей конфигурации 1С:Зарплата и Управление Персоналом 2.5 (или 2.0) в современную 1С:ЗУП 3.1 многие пользователи сталкиваются со странным поведением системы: у некоторых сотрудников в наименовании появляются приписки вида (совм.) или (осн.).
В этой статье мы подробно разберем, откуда берутся эти суффиксы, проанализируем типичные ошибки при попытке их программного удаления, напишем безопасный и эффективный код для исправления базы данных, а также рассмотрим стандартные альтернативные способы решения проблемы без программирования.
Для начала выясним первопричину возникновения проблемы. В старой редакции 1С:ЗУП 2.5 (или 2.0) для корректного разделения учета по основному месту работы и совместительству одного и того же физического лица система принудительно дописывала суффиксы к строковому реквизиту Наименование в справочнике Сотрудники. Это было заложено в саму архитектуру конфигурации.
При переносе данных в 1С:ЗУП 3.1 элементы справочника переносятся «как есть» — вместе со статически прописанными суффиксами. Однако в новой редакции 1С:ЗУП 3.1 подход к формированию представлений кардинально изменился. Теперь программа умеет динамически формировать и выводить информацию о виде занятости сотрудника в отчетах и документах. За это отвечает глобальная настройка в разделе Настройки — Кадровый учет — Правило формирования представления элементов справочника сотрудники в отчетах и документах.
Если в базе данных остались старые «жесткие» суффиксы в наименованиях, и при этом включена новая динамическая настройка, бухгалтеры увидят некрасивое задвоение информации в интерфейсе и печатных формах, например: «Иванов Иван Иванович (совм.) (совм.)». Наша задача — полностью очистить строковые реквизиты справочника Сотрудники от старых приписок, не нарушив при этом целостность базы данных.
Попытка написать собственную обработку «на коленке» без глубокого понимания структуры метаданных часто приводит к плачевным последствиям. Проанализируем типичный пример неоптимального и опасного программного кода, который часто пытаются использовать начинающие разработчики:
// Фрагмент кода с критическими ошибками!
СотрудникСсылка = Выборка.Ссылка.ПолучитьОбъект();
СотрудникСсылка.Наименование = Лев(СотрудникСсылка.Наименование, СтрДлина(СотрудникСсылка.Наименование) - 7);
СотрудникСсылка.ГоловнойСотрудник = Лев(СотрудникСсылка.ГоловнойСотрудник, СтрДлина(СотрудникСсылка.ГоловнойСотрудник) - 7);
СотрудникСсылка.Записать();
Разберем детально, почему этот код категорически нельзя запускать в рабочей базе данных:
ГоловнойСотрудник имеет тип СправочникСсылка.Сотрудники, а вовсе не строковый тип. Попытка применить к нему функции работы со строками, такие как Лев() или СтрДлина(), приведет к тому, что платформа 1С не сможет распознать тип данных и при записи объекта просто очистит это поле (запишет туда пустую ссылку). В результате вы полностью разрушите иерархическую связь между основными сотрудниками и их совместителями, что приведет к серьезным ошибкам в кадровом и налоговом учете.СтрДлина(...) - 7) крайне ненадежно. Если у какого-то сотрудника в базе в конце наименования случайно окажется пробел (например, "Иванов И.И. (совм.) ") или суффикс будет написан без точки, функция «откусит» важную часть фамилии или отчества.СотрудникСсылка для хранения объекта, полученного через метод ПолучитьОбъект(), ухудшает читаемость кода и может запутать других разработчиков при дальнейшей поддержке конфигурации.Теперь напишем правильный, отказоустойчивый и безопасный код для внешней обработки. Мы исключим любые манипуляции со ссылочными реквизитами и заменим небезопасное усечение строки на использование встроенных функций поиска и замены текста. Также мы добавим обработку транзакций и исключений.
Рассмотрим структуру процедуры, выполняемой на сервере:
&НаСервере
Процедура УдалитьСуффиксыНаСервере()
// Шаг 1. Инициализируем запрос для поиска записей с суффиксами
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Сотрудники.Ссылка КАК Ссылка,
| Сотрудники.Наименование КАК Наименование
|ИЗ
| Справочник.Сотрудники КАК Сотрудники
|ГДЕ
| (Сотрудники.Наименование ПОДОБНО &ШаблонСовмещаемый
| ИЛИ Сотрудники.Наименование ПОДОБНО &ШаблонОсновной)";
// Задаем параметры поиска с использованием спецсимвола шаблона "%"
Запрос.УстановитьПараметр("ШаблонСовмещаемый", "%(совм.)%");
Запрос.УстановитьПараметр("ШаблонОсновной", "%(осн.)%");
РезультатЗапроса = Запрос.Выполнить();
Если РезультатЗапроса.Пустой() Тогда
Сообщить("Сотрудники с суффиксами '(осн.)' или '(совм.)' в базе данных не найдены.");
Возврат;
КонецЕсли;
Выборка = РезультатЗапроса.Выбрать();
МодифицированоЗаписей = 0;
// Шаг 2. Обходим выборку в цикле
Пока Выборка.Следующий() Цикл
// Получаем объект для редактирования
СотрудникОбъект = Выборка.Ссылка.ПолучитьОбъект();
СтароеНаименование = СотрудникОбъект.Наименование;
// Шаг 3. Безопасно производим замену подстрок
НовоеНаименование = СтароеНаименование;
НовоеНаименование = СтрЗаменить(НовоеНаименование, "(совм.)", "");
НовоеНаименование = СтрЗаменить(НовоеНаименование, "(осн.)", "");
// Удаляем концевые пробелы, которые неизбежно останутся после удаления суффиксов
НовоеНаименование = СокрЛП(НовоеНаименование);
// Записываем изменения только в том случае, если наименование реально изменилось
Если СтароеНаименование <> НовоеНаименование Тогда
СотрудникОбъект.Наименование = НовоеНаименование;
Попытка
// Шаг 4. Запись объекта с транзакционной защитой
СотрудникОбъект.Записать();
МодифицированоЗаписей = МодифицированоЗаписей + 1;
Исключение
// Обрабатываем возможные блокировки или системные ошибки записи
ЗаписьЖурналаРегистрации("УдалениеСуффиксовСотрудников",
УровеньЖурналаРегистрации.Ошибка,
СотрудникОбъект.Метаданные(),
СотрудникОбъект.Ссылка,
"Не удалось обновить наименование для сотрудника: " + СтароеНаименование + ". Ошибка: " + ОписаниеОшибки());
КонецПопытки;
КонецЕсли;
КонецЦикла;
Сообщить("Процедура успешно завершена. Изменено сотрудников: " + МодифицированоЗаписей);
КонецПроцедуры
Проанализируем преимущества представленного кода. Мы использовали функцию СтрЗаменить, которая гарантированно удалит только целевые сочетания символов, независимо от их положения в строке. Применение функции СокрЛП очистит результирующую строку от «висящих» пробелов. Блок Попытка ... Исключение застрахует выполнение обработки от аварийного завершения в случае, если какой-то элемент справочника окажется заблокирован другим пользователем.
Если вы не хотите создавать внешние обработки и запускать кастомный программный код в боевой базе данных, вы можете прибегнуть к стандартным механизмам, заложенным в платформу «1С:Предприятие 8».
Этот способ идеально подходит для администраторов баз данных. Мы воспользуемся встроенной обработкой изменения реквизитов:
Наименование ПОДОБНО %(совм.)%.Наименование. В колонке «Новое значение» перейдем в режим ввода формулы (доступно в режиме разработчика) и пропишем выражение: СтрЗаменить(Объект.Наименование, " (совм.)", "").(осн.).Важное предупреждение: Перед запуском любых групповых обработок или кастомных скриптов в рабочей базе данных обязательно создайте резервную копию (бэкап) базы данных! Всегда тестируйте алгоритмы сначала на копии базы данных.
Если в вашей базе данных количество сотрудников с некорректными суффиксами исчисляется единицами (например, до 10-15 человек), то проще всего исправить их вручную, задействовав внутренние механизмы обновления представлений 1С:ЗУП 3.1:
Сотрудники.После того как мы успешно очистили наименования сотрудников от статичных суффиксов, кадровики и бухгалтеры могут столкнуться с проблемой визуального поиска: в списках и журналах документов теперь отображаются абсолютно одинаковые фамилии сотрудников, имеющих несколько мест работы в одной организации. Из-за этого становится сложно определить, где основная карточка сотрудника, а где — его совместительство.
Выясним, как решить эту проблему современным и правильным методом, предусмотренным разработчиками 1С:
Перейдем в раздел Настройки — Кадровый учет. Найдем пункт «Правило формирования представления элементов справочника сотрудники в отчетах и документах». Мы можем выбрать один из вариантов настройки системы:
Иванов Иван Иванович (совм.), формируемое системой динамически «на лету».Выберем наиболее подходящий вариант. Теперь база данных будет содержать только чистые имена сотрудников без лишнего мусора, а визуальное разделение в отчетах и кадровых документах возьмет на себя сама платформа 1С.
Чтобы окончательно решить проблему одинаковых строк в рабочих списках пользователей программы (например, в общем списке сотрудников), выполним простую кастомизацию интерфейса формы без изменения конфигурации:
Сотрудники через меню Кадры — Сотрудники.Наименование (или Имя) и снимем с нее флажок видимости.Ссылка (который отвечает за вывод ссылки на объект сотрудника), установим для него флажок видимости и поднимем его вверх списка. По желанию в свойствах этого элемента в поле «Заголовок» можно написать «Сотрудник» или «ФИО».Поскольку элемент Ссылка отображает данные динамически с учетом всех глобальных кадровых настроек представления, в списке сотрудников у всех пользователей сразу появятся корректные системные суффиксы, информирующие о виде занятости сотрудника, его статусе (например, «уволен») и других важных параметрах. При этом сами физические записи в таблицах базы данных останутся чистыми и защищенными от ошибок.