Как изменить оклад программистам в 1С 7.7, исключая уволенных сотрудников?

Программист 1С v7.7 Управленческий учет IT и автоматизация бизнеса
← На главную

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

Анализ базового алгоритма

В исходном варианте, предложенном автором темы, используется простой перебор справочника Сотрудники с фильтром по реквизиту Должность. Давайте проанализируем этот код:


Процедура Выполнить2()
    Должн = СоздатьОбъект("Справочник.Должности");
    Должн.НайтиПоНаименованию("Программист");
    Сотрудник = СоздатьОбъект("Справочник.Сотрудники");
    Сотрудник.ВыбратьЭлементыПоРеквизиту("Должность", Должн, 0, 0);
    Пока Сотрудник.ПолучитьЭлемент() = 1 Цикл
        Сотрудник.Оклад = Число(200000);
        Сотрудник.Записать();
        Сообщить("Заменен оклад для сотрудника: " + СокрЛП(Сотрудник.Наименование)); 
    КонецЦикла;
КонецПроцедуры

Проанализируем слабые места этого кода:

  1. Отсутствие проверки на увольнение: Цикл обрабатывает всех сотрудников, у которых указана должность "Программист", включая архивных и уволенных.
  2. Работа с объектом поиска: Метод ВыбратьЭлементыПоРеквизиту требует точной ссылки на элемент. Если НайтиПоНаименованию не сработает, код может повести себя непредсказуемо.
  3. Группы справочника: Если в справочнике есть папки (группы), программа может попытаться записать оклад для группы, что вызовет ошибку.
  4. Тип реквизита: Оклад в типовых конфигурациях 7.7 часто является периодическим реквизитом, и простая запись через оператор присваивания может быть некорректной.

Вариант 1: Простая проверка флага увольнения

Самый простой способ — добавить условие внутри цикла Пока. Если в вашей конфигурации предусмотрен реквизит Уволен (типа Число или Булево), решение будет выглядеть следующим образом:


Пока Сотрудник.ПолучитьЭлемент() = 1 Цикл
    // Проверяем, не является ли элемент группой
    Если Сотрудник.ЭтоГруппа() = 1 Тогда
        Продолжить;
    КонецЕсли;

    // Проверяем статус увольнения
    Если Сотрудник.Уволен = 1 Тогда
        Продолжить; // Пропускаем уволенного
    КонецЕсли;

    Сотрудник.Оклад = 200000;
    Сотрудник.Записать();
КонецЦикла;

Вариант 2: Использование перечислений (типовые конфигурации)

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


// Предположим, статус хранится в реквизите "Состояние"
Если Сотрудник.Состояние = Перечисление.СостоянияФизЛиц.Уволен Тогда
    Продолжить;
КонецЕсли;

Или, как было предложено в обсуждении, через проверку статуса сотрудника:


Если Сотрудник.Статус = Перечисление.СтатусыСотрудников.Уволен Тогда
    Продолжить;
КонецЕсли;

Вариант 3: Работа с периодическими реквизитами

Разберем важный нюанс платформы 1С 7.7. Если Оклад является периодическим, его значение зависит от даты. Присваивание Сотрудник.Оклад = 200000 запишет значение на текущую рабочую дату. Если нам нужно установить оклад с определенного числа, правильно использовать метод Установить.

Проанализируем улучшенный код с учетом всех правок:


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

Вариант 4: Прямой SQL-запрос (для опытных администраторов)

Если ваша база данных работает на Microsoft SQL Server, для ускорения процесса (особенно если сотрудников тысячи) можно использовать прямой SQL-запрос. Посмотрим на пример, предложенный в сообщении 6, но с важным уточнением: прямое изменение таблиц SQL обходит бизнес-логику 1С и должно применяться только в крайних случаях.


-- Пример логики запроса (метакод)
UPDATE $Справочник.Сотрудники 
SET $Справочник.Сотрудники.Оклад = 200000
WHERE $Справочник.Сотрудники.Должность = (SELECT TOP 1 id FROM $Справочник.Должности WHERE descr = 'Программист')
AND ismark = 0 -- Не помечен на удаление
AND $Справочник.Сотрудники.Уволен = 0;

Важное замечание: В 1С 7.7 поле ismark означает только пометку на удаление. Факт увольнения обычно хранится в отдельных полях таблиц справочника или в таблицах периодических реквизитов (const или 1svprop).

Рекомендации по выполнению задачи

Чтобы ваша обработка прошла проверку (преподавателем или заказчиком), следуйте этим правилам:

  1. Всегда проверяйте ЭтоГруппа(). Попытка записать данные в папку справочника — частая причина аварийного завершения обработок.
  2. Используйте точные ссылки. При поиске должности через НайтиПоНаименованию всегда проверяйте результат возврата (1 — найдено, 0 — нет).
  3. Логируйте действия. Используйте команду Сообщить(), чтобы видеть прогресс выполнения и понимать, сколько сотрудников было обработано.
  4. Тестируйте на копии. Любое массовое изменение данных в 1С 7.7 необратимо (нет стандартной функции "отмены").

Таким образом, комбинируя проверку должности и анализ реквизитов состояния (или даты увольнения), мы получаем надежный инструмент для управления кадровыми данными, который не затронет архивные записи организации.

← На главную