Почему при блокировке записи в 1С 8.3.24 не видно имя пользователя и как это исправить?

Программист 1С v8.3 (Обычные формы) Промышленность, строительство и АПК
← На главную

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

Суть проблемы и причины изменений

Давайте разберем ситуацию. Пользователь пытается открыть документ для редактирования, но он уже открыт у коллеги. Вместо привычного "Заблокировано пользователем Иванов И.И.", система выдает сухой технический отказ без указания виновника. Причина кроется в ужесточении политик безопасности в платформе **8.3.24** (и в некоторых последних сборках 8.3.23). Разработчики платформы реализовали принцип "Security by default" (безопасность по умолчанию). Логика такова:

  1. Информация о том, какой именно сотрудник работает с документом, может считаться конфиденциальной или раскрывать структуру компании.
  2. Пользователи без административных прав не должны видеть метаданные сеансов других пользователей.
  3. Как замечено в ходе обсуждения проблемы, если у пользователя есть **Полные права** (или право на Администрирование данных), кнопка "Подробно" в окне ошибки покажет имя блокирующего. У рядовых пользователей эта информация отсекается на уровне платформы.

Таким образом, это не баг, а "фича" новой платформы. Однако для реальной работы в офисе, где нужно позвонить коллеге и попросить закрыть накладную, это создает огромные неудобства.

Решение №1: Административный подход (Журнал регистрации)

Если вы не хотите или не можете вносить изменения в код конфигурации, у нас остается штатный механизм поиска виновника блокировки — **Журнал регистрации**. Разберем алгоритм действий системного администратора или пользователя с соответствующими правами:

  1. Откройте Журнал регистрации в режиме Конфигуратора или Предприятия.
  2. Установите отбор по конкретному документу (объекту данных), который не удается открыть.
  3. Найдите события "Данные. Изменение" или "Данные. Блокировка", которые не были завершены.
  4. В колонке "Пользователь" и "Компьютер" вы увидите, кто удерживает объект.

Также, если база работает в клиент-серверном варианте, администратор может использовать **Консоль администрирования серверов 1С**. В ветке "Блокировки" можно увидеть текущие наложенные блокировки на таблицы базы данных. Это работает быстрее, чем поиск по журналу, но требует доступа к серверу приложений. Минусы метода: Это долго и требует привлечения администратора каждый раз, когда возникает коллизия. Обычному бухгалтеру этот метод недоступен.

Решение №2: Программная доработка формы документа

Наиболее эффективный способ вернуть пользователям комфорт — перехватить ошибку программно непосредственно в момент открытия формы. Стандартный механизм платформы выдает системное окно ошибки, которое мы не можем контролировать. Однако мы можем попытаться заблокировать объект самостоятельно в коде, и если это не удастся — вывести свое, понятное сообщение. Рассмотрим пример кода, который необходимо разместить в модуле формы документа. Для обычных форм (УПП, УТ 10.3) используется событие ПриОткрытии.

Алгоритм действий:

  1. В процедуре открытия формы пытаемся выполнить метод Заблокировать() для текущего объекта.
  2. Оборачиваем этот вызов в конструкцию Попытка ... Исключение.
  3. Если возникает исключение (значит, объект занят), мы перехватываем описание ошибки.
  4. Выводим пользователю предупреждение с текстом ошибки.
  5. Переводим форму в режим "Только просмотр", чтобы пользователь мог хотя бы ознакомиться с документом.

Пример кода для модуля формы:


Процедура ПриОткрытии()
    
    // Получаем доступ к объекту документа
    ДокументОбъект = ЭтаФорма.ДокументОбъект;
    
    Попытка
        // Пытаемся явно заблокировать объект
        ДокументОбъект.Заблокировать();
        
    Исключение
        // Если попали сюда, значит объект занят
        
        // Получаем информацию об ошибке
        ИнформацияОбОшибке = ИнформацияОбОшибке();
        
        // Формируем текст сообщения. 
        // Важно: в зависимости от прав и режима совместимости, 
        // стандартное описание может быть полным или урезанным.
        ТекстОшибки = ОписаниеОшибки();
        
        // Более детальный вариант получения причины:
        Если ИнформацияОбОшибке.Причина <> Неопределено Тогда
            ТекстПричины = КраткоеПредставлениеОшибки(ИнформацияОбОшибке.Причина);
        Иначе
            ТекстПричины = КраткоеПредставлениеОшибки(ИнформацияОбОшибке);
        КонецЕсли;
        
        // Выводим сообщение пользователю
        Предупреждение("Документ занят! " + Символы.ПС + ТекстПричины);
        
        // Блокируем форму от изменений, раз уж редактировать нельзя
        ЭтаФорма.ТолькоПросмотр = Истина;
        
    КонецПопытки;
    
КонецПроцедуры

Обратите внимание на метод КраткоеПредставлениеОшибки. Он позволяет получить более читаемый текст, чем полный стек вызовов.

Решение №3: Обход ограничений безопасности (Привилегированный режим)

Важный нюанс: если у пользователя урезаны права, то даже функция ОписаниеОшибки() внутри клиентского кода может вернуть текст без имени пользователя (платформа фильтрует текст ошибки на лету). Чтобы гарантированно получить имя пользователя, который заблокировал объект, нам нужно выполнить проверку блокировки "глазами администратора", то есть в **Привилегированном режиме**. Для этого нам потребуется создать общий модуль (или использовать существующий) с установленными галочками "Сервер" и "Привилегированный". Назовем его, например, УправлениеБлокировкамиПривилегированный.

Шаг 1. Создаем функцию на сервере

В привилегированном модуле создаем функцию, которая пытается заблокировать объект по ссылке и возвращает текст ошибки, если блокировка не удалась. Поскольку модуль привилегированный, платформа не будет скрывать имя пользователя.


// Функция в общем модуле с признаком "Привилегированный"
Функция ПопытатьсяЗаблокироватьОбъект(СсылкаНаОбъект) Экспорт
    
    Результат = Новый Структура("Заблокировано, ТекстОшибки", Истина, "");
    
    // Получаем объект по ссылке для попытки блокировки
    // Важно: это создает лишнее чтение из БД, используйте с умом
    Попытка
        Объект = СсылкаНаОбъект.ПолучитьОбъект();
        Объект.Заблокировать();
    Исключение
        Результат.Заблокировано = Ложь;
        // Здесь мы получим полный текст ошибки с именем пользователя,
        // так как код выполняется под полными правами
        Результат.ТекстОшибки = ОписаниеОшибки();
    КонецПопытки;
    
    Возврат Результат;

КонецФункции

Шаг 2. Вызываем функцию из формы документа

Теперь модифицируем код в форме документа (из Решения №2), чтобы обращаться к нашему привилегированному модулю.


Процедура ПриОткрытии()
    
    // Если это новый документ, блокировать нечего
    Если ЭтоНовый() Тогда
        Возврат;
    КонецЕсли;
    
    // Вызываем серверную функцию (для управляемых форм нужен вызов сервера, 
    // для обычных форм УПП это сработает напрямую, если модуль доступен)
    
    ПроверкаБлокировки = УправлениеБлокировкамиПривилегированный.ПопытатьсяЗаблокироватьОбъект(Ссылка);
    
    Если НЕ ПроверкаБлокировки.Заблокировано Тогда
        
        // Парсим полученный текст, чтобы оставить только самое важное
        // Или выводим как есть
        Сообщить("ВНИМАНИЕ! Документ редактируется другим пользователем.");
        Предупреждение(ПроверкаБлокировки.ТекстОшибки);
        
        ЭтаФорма.ТолькоПросмотр = Истина;
        
    КонецЕсли;

КонецПроцедуры

Важные замечания по реализации

При внедрении данного решения следует учитывать несколько моментов:

  1. Режим совместимости. Проверьте свойство конфигурации "Режим совместимости". Если он установлен в старые значения (например, Версия 8.2.13), поведение платформы может отличаться, и блокировка может отрабатывать иначе.
  2. Транзакционные блокировки. В клиент-серверных базах (SQL) существует разница между объектной блокировкой 1С (которую мы рассматриваем) и транзакционной блокировкой СУБД. Описанные методы помогают именно при конкурентном доступе к объектам (справочникам, документам) через формы 1С.
  3. Кнопка проверки. Если вы не хотите нагружать процедуру ПриОткрытии, можно добавить на форму кнопку "Проверить блокировку". Код будет аналогичным, но выполняться только по требованию пользователя, когда он не понимает, почему не может сохранить изменения.

Используя подход с привилегированным модулем, вы сможете обойти ограничения безопасности платформы 8.3.24 и вернуть пользователям информативные сообщения о том, кто именно занял документ, не нарушая общую безопасность системы (так как полные права пользователю мы не выдаем).

← На главную