Как очистить историю выбора в полях ввода 1С и управлять механизмом кэширования значений

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

В процессе разработки и сопровождения систем на платформе 1С:Предприятие 8.3 программисты часто сталкиваются с ситуацией, когда механизмы «удобства» платформы начинают конфликтовать с требованиями безопасности или бизнес-логикой. Одним из таких механизмов является история выбора. Это тот самый выпадающий список ранее выбранных значений, который появляется, когда пользователь начинает редактировать поле ввода (например, при выборе номенклатуры, контрагента или договора).

Проблема заключается в том, что этот список кэшируется на уровне настроек пользователя. Если вы ввели ограничение прав доступа (RLS) или изменили алгоритм фильтрации в ОбработкеДанныхВыбора, старые значения, которые теперь запрещены для пользователя, всё равно продолжают «подло» отображаться в истории. В этой статье мы подробно разберем, как программно очистить этот список и какие существуют способы управления историей выбора.

Разберем причину: почему история игнорирует ограничения?

Проанализируем ситуацию: почему, даже если данные закрыты через RLS, они видны в истории? Дело в том, что история выбора — это не запрос к базе данных в реальном времени. Это список ссылок, сохраненный в системном хранилище настроек конкретного пользователя. Платформа отображает этот кэш максимально быстро для повышения комфорта работы. Проверка прав (RLS) происходит только в момент, когда пользователь уже выбирает элемент из этого списка. В этот момент система может выдать ошибку: «Эти данные невозможно выбрать, так как они были ранее удалены или к ним нет доступа».

Однако с точки зрения интерфейса это выглядит некорректно: пользователь видит то, чего видеть не должен. Чтобы решить эту проблему, нам необходимо научиться управлять объектом НастройкиИсторииВыбора.

Способ 1. Программная очистка истории через ХранилищеСистемныхНастроек

Как выяснилось в ходе обсуждения, наиболее эффективным способом очистки является прямое обращение к системному хранилищу. История выбора хранится под ключом "ИсторияВыбора". Важно понимать, что объект НастройкиИсторииВыбора, который мы получаем при загрузке, является своего рода «черным ящиком». У него нет доступных свойств или методов для итерации (перебора элементов), поэтому мы не можем «выкусить» из истории только конкретную номенклатуру.

Рассмотрим код для полной очистки истории выбора для текущего пользователя:


// Очистка истории выбора для текущего пользователя по всем объектам
ХранилищеСистемныхНастроек.Удалить("ИсторияВыбора", , ИмяПользователя());

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


Процедура ОчиститьИсториюВыбораПользователя(ИмяПользователя) Экспорт
    Попытка
        ХранилищеСистемныхНастроек.Удалить("ИсторияВыбора", , ИмяПользователя);
        Сообщить("История выбора для пользователя " + ИмяПользователя + " успешно очищена.");
    Исключение
        ЗаписатьЛогСобытий("Ошибка очистки истории: " + ОписаниеОшибки());
    КонецПопытки;
КонецПроцедуры

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

Способ 2. Отключение истории на уровне свойств поля ввода

Если полная очистка кажется слишком радикальной мерой, мы можем управлять отображением истории для конкретных элементов формы. Проанализируем свойства элементов управления в конфигураторе. У каждого поля ввода, связанного с типом СправочникСсылка, есть свойство «История выбора при вводе» (ChoiceHistoryOnInput).

Мы можем изменить его следующими способами:

  1. В конфигураторе: Установить значение «Не использовать». В этом случае для данного конкретного поля история показываться не будет, хотя в базе она сохранится.
  2. Программно в коде формы: Это удобно, если история должна отключаться только при определенных условиях.

Рассмотрим пример программного управления свойством в событии ПриСозданииНаСервере:


&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
    // Отключаем историю выбора для поля Номенклатура
    Элементы.Номенклатура.ИсторияВыбораПриВводе = ИсторияВыбораПриВводе.НеИспользовать;
КонецПроцедуры

Такой подход позволяет локально решить проблему «подглядывания» старых данных, не затрагивая удобство работы пользователя в других разделах системы.

Способ 3. Глобальное управление в рамках всей конфигурации

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

Для этого в корне конфигурации необходимо найти свойство «Использовать историю выбора при вводе» и установить его в значение «Ложь». Это отключит механизм для всей информационной базы. Однако помните, что это значительно снизит скорость работы пользователей, привыкших к быстрому подбору данных.

Механизм обновления истории: как не допустить попадания лишнего

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

Если вы реализовали сложную логику в ОбработкеДанныхВыбора модуля менеджера, убедитесь, что вы также добавили проверку в событие ПриИзменении на форме или в подписку на событие ПередЗаписью объекта. Это гарантирует, что даже если пользователь применит «хак» и выберет значение из старого кэша, система не позволит сохранить некорректный документ.

Проанализируем пример проверки в форме документа:


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

Резюме и рекомендации

Подводя итог нашему разбору, можно выделить следующую стратегию работы с историей выбора:

Используя эти методы, мы обеспечим чистоту интерфейса и уверенность в том, что пользователи работают только с актуальными и разрешенными данными.

← На главную