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