Механизм контроля даты запрета изменения данных является краеугольным камнем для обеспечения целостности и достоверности бухгалтерского и управленческого учета в системе 1С. Он предотвращает несанкционированные или случайные изменения в уже закрытых отчетных периодах, что критически важно для корректного формирования отчетности и соблюдения законодательства. Однако на практике часто возникает потребность во временном доступе к таким периодам для внесения корректировок, обнаруженных уже после "закрытия". Типовой функционал 1С не предусматривает автоматического предоставления и последующего отзыва доступа по истечении заданного срока. Давайте подробно разберем, как мы можем реализовать такую доработку.
Прежде чем погружаться в доработки, рассмотрим, что предлагает стандартный механизм 1С для управления датой запрета изменения данных:
Несмотря на такую гибкость, стандартный функционал 1С не включает встроенного поля "Срок доступа", которое бы автоматически открывало доступ на заданное количество дней, а затем автоматически его закрывало. Если пользователь просит доступ, например, к маю 2025 года на два дня, администратору приходится вручную изменять дату запрета, а затем вручную ее возвращать обратно. Это не только трудоемко, но и чревато забывчивостью, что может привести к нежелательному продолжительному открытию периода.
Для решения описанной проблемы нам понадобится разработать собственный механизм, который будет интегрирован с существующей системой даты запрета. Представим себе идеальный пользовательский сценарий:
Когда пользователю (например, "Иванову") требуется внести изменения в закрытый период (скажем, май 2025 года) на ограниченное время (например, на два дня), он формирует заявку. Эта заявка содержит:
Заявка отправляется на согласование финансовому директору или другому ответственному лицу. После согласования заявки умный механизм автоматически выполняет следующие действия:
Такой подход минимизирует ручные операции, снижает риск ошибок и обеспечивает прозрачность процесса.
Для реализации описанного функционала нам потребуются следующие объекты платформы 1С:
Давайте разберем процесс реализации такой системы по шагам.
Первым делом мы создадим новый документ или, возможно,
РегистрСведений
ЗаявкаНаВременныйДоступ.
Этот объект должен содержать следующие реквизиты:
Пользователи. Автоматически заполняется текущим пользователем.Пользователи. Тот, кто должен согласовать заявку.ТекущаяДата() + СрокДоступаВДнях при выдаче разрешения.НаСогласовании, Согласована, Отклонена, Выдана, Завершена).Создадим форму документа, удобную для заполнения пользователем и для согласования ответственным лицом.
После создания заявки необходимо обеспечить ее согласование. Мы можем выбрать один из двух путей:
НаСогласовании. Ответственный пользователь (например, финансовый директор) видит эти заявки в своем списке и может изменить статус на Согласована или Отклонена. Это можно реализовать кнопками на форме документа, привязанными к ролям и правам.При переходе заявки в статус Согласована, мы должны инициировать процесс выдачи временного доступа. При изменении статуса документа на Согласована, в обработчике события ОбработкаПроведения или через подписку на событие, мы будем вызывать процедуру, которая создает запись в нашем регистре временных разрешений.
Для хранения информации о фактически выданных разрешениях создадим новый независимый регистр сведений, например, ВременныеРазрешенияНаРедактирование. Этот регистр должен быть непериодическим и содержать следующие измерения и ресурсы:
Измерения:
Пользователи. (Ключевое измерение).Ресурсы:
ТекущаяДата() + СрокДоступаВДнях
ЗаявкаНаВременныйДоступ для прослеживаемости.Когда заявка согласована, мы записываем информацию в этот регистр. Например, в модуле объекта документа ЗаявкаНаВременныйДоступ после установки статуса Согласована:
// Примерный код в модуле объекта документа ЗаявкаНаВременныйДоступ
Процедура ПриИзмененииСтатусаНаСогласована()
Если Статус = Перечисления.СтатусыЗаявокНаДоступ.Согласована Тогда
// Создаем запись в регистре временных разрешений
НаборЗаписей = РегистрыСведений.ВременныеРазрешенияНаРедактирование.СоздатьНаборЗаписей();
НаборЗаписей.Отбор.Пользователь.Установить(Пользователь);
НаборЗаписей.Прочитать();
НоваяЗапись = НаборЗаписей.Добавить();
НоваяЗапись.Пользователь = Пользователь;
НоваяЗапись.ПериодДоступаС = ДатаНачалаПериода;
НоваяЗапись.ПериодДоступаПо = ДатаОкончанияПериода;
// Дата окончания действия рассчитывается от текущей даты
НоваяЗапись.ДатаОкончанияДействия = ТекущаяДата() + СрокДоступаВДнях * 24 * 3600; // Добавляем дни в секундах
НоваяЗапись.ЗаявкаОснование = Ссылка;
НоваяЗапись.Активно = Истина;
НаборЗаписей.Записать();
КонецЕсли;
КонецПроцедуры
Обратите внимание, что расчет даты окончания действия производится от текущей даты, а не от даты периода. Это позволяет предоставлять доступ "на два дня, начиная с сегодня", независимо от того, к какому прошлому периоду запрашивается доступ.
Этот шаг является критически важным. Нам необходимо модифицировать стандартную логику проверки даты запрета изменения данных. В большинстве конфигураций 1С эта проверка выполняется в общем модуле, часто с использованием функции ОбщегоНазначения.ПолучитьДатуЗапретаИзменения() или аналогичной.
Наша задача — встроить логику, которая сначала проверяет наш регистр ВременныеРазрешенияНаРедактирование. Если для текущего пользователя и запрашиваемой даты записи есть активное временное разрешение, то стандартную проверку даты запрета мы должны временно "отключить" или вернуть такую дату запрета, которая позволит изменение.
Предположим, у нас есть функция ПроверитьДатуЗапретаИзмененийДляОбъекта(), которая вызывается перед записью любого объекта. Мы изменим ее примерно так:
// Примерный код в ОбщемМодуле (например, ОбщегоНазначения или АдминистраторскаяПанель)
Функция ПроверитьДатуЗапретаИзмененийДляОбъекта(Объект, ДатаИзменения) Экспорт
// 1. Сначала проверяем наш регистр временных разрешений
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ ПЕРВЫЕ 1
| ВременныеРазрешенияНаРедактирование.Пользователь,
| ВременныеРазрешенияНаРедактирование.ПериодДоступаС,
| ВременныеРазрешенияНаРедактирование.ПериодДоступаПо,
| ВременныеРазрешенияНаРедактирование.ДатаОкончанияДействия
|ИЗ
| РегистрСведений.ВременныеРазрешенияНаРедактирование КАК ВременныеРазрешенияНаРедактирование
|ГДЕ
| ВременныеРазрешенияНаРедактирование.Пользователь = &ТекущийПользователь
| И ВременныеРазрешенияНаРедактирование.Активно = ИСТИНА
| И &ДатаИзменения МЕЖДУ ВременныеРазрешенияНаРедактирование.ПериодДоступаС И ВременныеРазрешенияНаРедактирование.ПериодДоступаПо
| И &ТекущаяДата < ВременныеРазрешенияНаРедактирование.ДатаОкончанияДействия";
Запрос.УстановитьПараметр("ТекущийПользователь", Пользователи.ТекущийПользователь());
Запрос.УстановитьПараметр("ДатаИзменения", ДатаИзменения);
Запрос.УстановитьПараметр("ТекущаяДата", ТекущаяДата());
РезультатЗапроса = Запрос.Выполнить();
Если Не РезультатЗапроса.Пустой() Тогда
// Найдено активное временное разрешение, разрешаем изменение
Возврат Истина;
КонецЕсли;
// 2. Если временного разрешения нет, выполняем стандартную проверку даты запрета
// Здесь должен быть вызов стандартной функции конфигурации для проверки даты запрета
// Например:
ДатаЗапрета = ПолучитьДатуЗапретаИзменения(Объект, ДатаИзменения); // Пример стандартной функции
Если ДатаИзменения <= ДатаЗапрета Тогда
Сообщить("Изменение данных запрещено на " + Формат(ДатаИзменения, "ДФ=dd.MM.yyyy") +
" т.к. дата запрета установлена на " + Формат(ДатаЗапрета, "ДФ=dd.MM.yyyy"), СтатусСообщения.Важное);
Возврат Ложь;
Иначе
Возврат Истина;
КонецЕсли;
КонецФункции
Важно: Найти правильное место для интеграции этой логики может быть непросто. Часто приходится использовать подписки на события или замещать стандартные функции, чтобы избежать снятия конфигурации с поддержки. Мы рекомендуем использовать расширения для таких доработок, чтобы сохранить возможность легкого обновления типовой конфигурации.
Для автоматического отзыва доступа по истечении срока нам потребуется регламентное задание. Создадим новое регламентное задание, например, АвтоматическоеЗакрытиеВременногоДоступа.
Это задание должно запускаться с определенной периодичностью (например, каждые 30 минут или раз в день, в нерабочее время). В его модуле будет выполняться следующий код:
// Примерный код в модуле регламентного задания
Процедура ВыполнитьАвтоматическоеЗакрытиеВременногоДоступа() Экспорт
// 1. Получаем все активные разрешения, срок действия которых истек
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ВременныеРазрешенияНаРедактирование.Пользователь,
| ВременныеРазрешенияНаРедактирование.ПериодДоступаС,
| ВременныеРазрешенияНаРедактирование.ПериодДоступаПо,
| ВременныеРазрешенияНаРедактирование.ДатаОкончанияДействия,
| ВременныеРазрешенияНаРедактирование.ЗаявкаОснование
|ИЗ
| РегистрСведений.ВременныеРазрешенияНаРедактирование КАК ВременныеРазрешенияНаРедактирование
|ГДЕ
| ВременныеРазрешенияНаРедактирование.Активно = ИСТИНА
| И ВременныеРазрешенияНаРедактирование.ДатаОкончанияДействия <= &ТекущаяДата";
Запрос.УстановитьПараметр("ТекущаяДата", ТекущаяДата());
РезультатЗапроса = Запрос.Выполнить();
Выборка = РезультатЗапроса.Выбрать();
НаборЗаписей = РегистрыСведений.ВременныеРазрешенияНаРедактирование.СоздатьНаборЗаписей();
Пока Выборка.Следующий() Цикл
// 2. Деактивируем или удаляем истекшие записи
НаборЗаписей.Отбор.Пользователь.Установить(Выборка.Пользователь);
НаборЗаписей.Отбор.ПериодДоступаС.Установить(Выборка.ПериодДоступаС);
НаборЗаписей.Отбор.ПериодДоступаПо.Установить(Выборка.ПериодДоступаПо);
НаборЗаписей.Прочитать();
Если НаборЗаписей.Количество() > 0 Тогда
Запись = НаборЗаписей.Получить(0);
Запись.Активно = Ложь; // Деактивируем запись
НаборЗаписей.Записать();
// 3. Оповещение пользователей и администраторов
// Здесь можно добавить код для отправки уведомлений
Сообщить("Временный доступ для пользователя " + Выборка.Пользователь +
" к периоду с " + Формат(Выборка.ПериодДоступаС, "ДФ=dd.MM.yyyy") +
" по " + Формат(Выборка.ПериодДоступаПо, "ДФ=dd.MM.yyyy") +
" был автоматически закрыт.", СтатусСообщения.Информация);
// Также можно обновить статус в документе-основании ЗаявкаНаВременныйДоступ
ДокОснование = Выборка.ЗаявкаОснование.ПолучитьОбъект();
Если ДокОснование <> Неопределено Тогда
ДокОснование.Статус = Перечисления.СтатусыЗаявокНаДоступ.Завершена;
ДокОснование.Записать();
КонецЕсли;
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Таким образом, мы гарантируем, что временные разрешения на редактирование будут автоматически отозваны, что обеспечивает безопасность данных и соблюдение учетной политики.
Любые изменения в закрытых периодах должны быть зафиксированы. Мы используем следующие механизмы:
ЗаявкаНаВременныйДоступ будет служить журналом всех запросов, их согласования и статусов завершения.Это обеспечивает полную прозрачность и возможность аудита.
Реализация системы временного автоматического доступа к закрытым периодам в 1С — это комплексная задача, требующая внимательного проектирования и аккуратной разработки. Однако она значительно повысит удобство работы пользователей, обеспечит контроль над изменениями и усилит безопасность данных в вашей информационной базе 1С.