В процессе разработки на платформе 1С:Предприятие 8.3 программисты часто сталкиваются с необходимостью массовой корректировки документов в прошлых (закрытых) периодах. Типичный сценарий: нужно изменить реквизит в документе и переформировать его движения по регистрам. Однако при попытке сделать это программно возникает цепочка препятствий — от блокировки проведения в режиме загрузки до нарушения прав доступа и дат запрета изменения данных. Разберем подробно, как правильно решить эту задачу на примере конфигурации 1С:ЗУП 3.1.
Проанализируем первую ошибку, с которой сталкивается автор темы. При попытке выполнить программное проведение с установленным флагом ОбменДанными.Загрузка = Истина система выдает исключение: «Действие не может выполняться в режиме загрузки данных».
Почему это происходит: Свойство ОбменДанными.Загрузка предназначено для механизмов обмена (РИБ, синхронизация). Когда оно установлено в значение Истина, платформа отключает выполнение прикладных проверок и, что критично, обработчики события ОбработкаПроведения. Проведение документа — это активное действие, которое подразумевает формирование новых записей в регистрах на основе логики конфигурации. Загрузка данных — это пассивное действие, подразумевающее запись уже готовых данных из другого источника. Эти два режима концептуально несовместимы на уровне ядра платформы 1С.
Рассмотрим пример кода, который гарантированно приведет к ошибке:
ДокОбъект = СсылкаНаДокумент.ПолучитьОбъект();
ДокОбъект.ОбменДанными.Загрузка = Истина;
// ОШИБКА: Платформа не позволит выполнить проведение при Загрузка = Истина
ДокОбъект.Записать(РежимЗаписиДокумента.Проведение);
Решение: Для выполнения полноценного проведения флаг Загрузка необходимо оставить в значении Ложь (по умолчанию).
Как только мы отключаем режим загрузки, мы сталкиваемся со вторым препятствием: документ находится в закрытом периоде. Типовые механизмы БСП (Библиотеки стандартных подсистем) не позволят записать или провести такой объект. Чтобы обойти это ограничение программно, не открывая период для всех пользователей, проанализируем использование параметров сеанса и дополнительных свойств объекта. Для гибкой настройки исключений без отключения контроля для всей базы подойдёт расширение для управления датами запрета изменений в разрезе пользователей и объектов.
В современных конфигурациях проверка даты запрета часто выполняется в подписках на события. Чтобы «убедить» систему пропустить проверку, можно использовать следующий метод:
УстановитьПривилегированныйРежим(Истина);
// Отключаем проверку даты запрета через параметры сеанса (актуально для многих конфигураций БСП)
ПропуститьПроверку = ПараметрыСеанса.ПропуститьПроверкуЗапретаИзменения;
ПараметрыСеанса.ПропуститьПроверкуЗапретаИзменения = Истина;
ДокОбъект = Ссылка.ПолучитьОбъект();
// Также можно попробовать добавить признак в дополнительные свойства объекта
ДокОбъект.ДополнительныеСвойства.Вставить("ПропуститьПроверкуЗапретаИзменения", Истина);
Попытка
ДокОбъект.Записать(РежимЗаписиДокумента.Проведение);
Исключение
Сообщить(ОписаниеОшибки());
КонецПопытки;
// Возвращаем исходное состояние параметров сеанса
ПараметрыСеанса.ПропуститьПроверкуЗапретаИзменения = ПропуститьПроверку;
УстановитьПривилегированныйРежим(Ложь);
Даже если мы используем УстановитьПривилегированныйРежим(Истина), при работе с внешними обработками может возникнуть ошибка «Нарушение прав доступа». Это происходит из-за механизма защиты от опасных действий и безопасного режима работы внешних отчетов и обработок.
Выясним причину: когда вы открываете обработку через Файл -> Открыть, платформа 1С запускает ее в ограниченном контексте. В этом режиме вызов УстановитьПривилегированныйРежим(Истина) игнорируется, и код выполняется с правами текущего пользователя. Если у пользователя нет полных прав или прав на конкретный регистр (например, в ЗУП права на регистры интервалов часто есть только у роли «Полные права»), система выдаст ошибку.
Как правильно запустить обработку:
Сведем все полученные знания в единый алгоритм. Нам нужно изменить реквизит в документе НачальнаяШтатнаяРасстановка и перепровести его в закрытом периоде, чтобы обновились кадровые интервалы.
&НаСервере
Процедура ПровестиДокументВЗакрытомПериоде(ДокСсылка)
// 1. Включаем привилегированный режим для обхода RLS (прав на уровне записей)
УстановитьПривилегированныйРежим(Истина);
// 2. Отключаем проверку даты запрета изменения на время операции
СтароеЗначениеПропуска = ПараметрыСеанса.ПропуститьПроверкуЗапретаИзменения;
ПараметрыСеанса.ПропуститьПроверкуЗапретаИзменения = Истина;
ДокОбъект = ДокСсылка.ПолучитьОбъект();
Если ДокОбъект <> Неопределено Тогда
// 3. Модифицируем данные
// Допустим, нам нужно изменить должность в табличной части
Для Каждого Стр Из ДокОбъект.Сотрудники Цикл
Стр.Должность = НоваяДолжность;
КонецЦикла;
// 4. Обязательно убеждаемся, что режим загрузки выключен
ДокОбъект.ОбменДанными.Загрузка = Ложь;
// 5. Выполняем проведение
Попытка
ДокОбъект.Записать(РежимЗаписиДокумента.Проведение);
Сообщить("Документ " + ДокСсылка + " успешно перепроведен.");
Исключение
Сообщить("Ошибка при проведении: " + ОписаниеОшибки());
КонецПопытки;
КонецЕсли;
// 6. Восстанавливаем настройки безопасности
ПараметрыСеанса.ПропуститьПроверкуЗапретаИзменения = СтароеЗначениеПропуска;
УстановитьПривилегированныйРежим(Ложь);
КонецПроцедуры
В конфигурации 1С:Зарплата и Управление Персоналом (ЗУП) 3.1 существуют особые интервальные регистры (например, КадроваяИсторияСотрудниковИнтервальный). Если вы решите пойти по пути «ручной» записи наборов записей в обычные регистры вместо полноценного проведения, эти интервальные данные не обновятся автоматически. Платформа пересчитывает их только при вызове метода Записать(РежимЗаписиДокумента.Проведение) или при вызове специальных экспортных процедур из общих модулей кадрового учета. Для прямой корректировки таких записей можно использовать обработку для редактирования движений в интервальном регистре кадровой истории.
Проанализируем ситуацию: если вы все же вынуждены использовать ОбменДанными.Загрузка = Истина (например, чтобы просто «подправить» документ без лишних движений), то после этого вам придется вручную инициировать обновление интервалов:
// Пример принудительного обновления интервалов кадровой истории
МассивСотрудников = Новый Массив;
МассивСотрудников.Добавить(СотрудникСсылка);
КадровыйУчет.ОбновитьКадровуюИсториюСотрудников(МассивСотрудников, Истина);
Однако наиболее надежным и рекомендуемым способом остается именно полноценное проведение в привилегированном режиме с временным отключением проверки дат запрета.
Подведем итоги. Чтобы программно провести документ в 1С:
ОбменДанными.Загрузка = Истина, если требуется вызвать ОбработкаПроведения.УстановитьПривилегированныйРежим(Истина) для игнорирования RLS.ПараметрыСеанса.ПропуститьПроверкуЗапретаИзменения или через ДополнительныеСвойства объекта.Такой подход гарантирует корректное формирование движений по всем регистрам, включая специфические интервальные механизмы ЗУП.