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

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

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

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

Суть проблемы и анализ симптомов

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

При этом наблюдаются следующие важные особенности:

  1. Это не физические дубли. Обе строки ссылаются на один и тот же уникальный идентификатор (GUID) в базе данных. При изменении реквизитов в одной карточке данные мгновенно обновляются во всех задублированных строках списка.
  2. Интерфейсная связь. При одиночном клике на любую из строк-дублей платформа визуально выделяет серым или синим цветом обе строки одновременно.
  3. Локализация проблемы. Баг привязан исключительно к конкретным учетным записям пользователей 1С. Если войти под «проблемным» пользователем на абсолютно другом компьютере — баг воспроизводится. Если на компьютере этого пользователя войти под правами администратора — проблема исчезает.
  4. Поведение отборов. Если в форме списка установить жесткий отбор по конкретной ссылке этого товара, в списке остается только одна строка. Дублирование пропадает.
  5. Кэш и тестирование. Очистка локального кэша на компьютере пользователя (удаление каталогов из %appdata%\1C) и стандартное тестирование и исправление (ТиИ) информационной базы не приносят результата.

Проанализируем причины, которые могут приводить к такому поведению платформы «1С:Предприятие».

---

Причина №1: Механизм RLS (Ограничение доступа на уровне записей)

Это самая частая и наиболее вероятная причина возникновения подобных дублей в обычных формах. Когда пользователь открывает список номенклатуры, платформа формирует неявный SQL-запрос к базе данных. Если для роли данного пользователя настроено ограничение доступа на уровне записей (RLS), платформа автоматически модифицирует этот запрос, добавляя к нему условия связи с другими таблицами (например, с группами доступа номенклатуры, разрешенными складами или контрагентами).

Если в шаблоне RLS используется левое соединение (LEFT JOIN) или внутреннее соединение (INNER JOIN) с другой таблицей (например, с регистром сведений), и для данного товара в этой подчиненной таблице по какой-то причине образовалось две записи (например, товар ошибочно включен в две разные группы доступа), то СУБД вернет две одинаковые строки для одной и той же ссылки номенклатуры.

В управляемых формах динамический список при обнаружении дублирующихся ключевых значений сразу выдает критическую ошибку. Однако старый объект СправочникСписок в обычных формах ведет себя иначе: он молча выводит все строки, возвращенные СУБД. Поскольку идентификатор строки в списке — это ссылка на элемент, при активации строки платформа выделяет все элементы с этой ссылкой, что и создает эффект «связанных» дублей.

Как диагностировать и исправить RLS:

Выясним, действительно ли дело в RLS. Для этого проведем простой эксперимент: временно назначим проблемному пользователю полные права. Если после этого дублирование строк исчезло — наша гипотеза верна, проблема кроется в правилах ограничения доступа.

Чтобы локализовать сбойную запись в регистрах доступа, мы можем запустить под проблемным пользователем консоль запросов и выполнить простейший запрос:


ВЫБРАТЬ РАЗРЕШЕННЫЕ
    Номенклатура.Ссылка КАК Ссылка
ИЗ
    Справочник.Номенклатура КАК Номенклатура
ГДЕ
    Номенклатура.Ссылка = &ПроблемныйТовар

Если запрос вернет две строки с одинаковой ссылкой, нам необходимо детально изучить текст RLS для роли этого пользователя по справочнику «Номенклатура». Нам нужно найти регистр или таблицу, из-за которой происходит задвоение результатов в секции ГДЕ или СОЕДИНЕНИЕ, и очистить некорректные (дублирующиеся) записи в этом регистре для данного товара.

---

Причина №2: Сбой в хранилище системных настроек в базе данных

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

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

Как решить проблему очисткой настроек:

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


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

После выполнения этого кода пользователю необходимо перезапустить сеанс работы с базой данных.

---

Причина №3: Персональные алгоритмы в обработчиках событий формы

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

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

Посмотрим на пример опасного кода в событии ПриПолученииДанных:


Процедура СправочникСписокПриПолученииДанных(Элемент, ОформленияСтрок)
    // Если код содержит некорректное соединение с остатками, 
    // это может визуально дублировать строки при определенных условиях
    Если РольДоступна("СпецифическаяРольПользователя") Тогда
        // Неоптимальный или ошибочный запрос к регистру сведений без среза последних
    КонецЕсли;
КонецПроцедуры

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

---

Причина №4: Физическое повреждение индексов или статистик СУБД

Тот факт, что на копии базы данных под теми же пользователями проблема не повторяется, может косвенно указывать на проблемы с индексами или таблицами на уровне СУБД (например, MS SQL Server или PostgreSQL) в рабочей базе.

Для разных пользователей (в зависимости от их прав и условий RLS) SQL Server строит принципиально разные планы выполнения запросов. Если поврежден индекс таблицы, участвующей в соединении при наложении прав RLS, СУБД при определенных условиях может вернуть неверный (в том числе избыточный) результат работы запроса.

Что необходимо сделать администратору СУБД:

  1. Выполнить полную реиндексацию таблиц рабочей базы данных.
  2. Обновить статистики базы данных.
  3. В случае использования MS SQL Server, выполнить команду проверки целостности базы данных: DBCC CHECKDB ('ИмяВашейБазы') WITH NO_INFOMSGS, ALL_ERRORMSGS;

---

Резюме и пошаговый план решения проблемы

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

  1. Проверка прав (исключение RLS): Временно назначьте пользователю полные права. Если дубли пропали — ищите ошибку в шаблонах RLS роли этого пользователя или задвоенные записи в связанных регистрах сведений.
  2. Очистка настроек в БД: Программно удалите сохраненные настройки формы списка номенклатуры для данного пользователя с помощью объекта ХранилищеСистемныхНастроек.
  3. Проверка кода формы: Проанализируйте события ПриПолученииДанных и ПриВыводеСтроки на предмет персональных алгоритмов и запросов.
  4. Радикальный метод (пересоздание пользователя): Если ничего не помогло, создайте в справочнике «Пользователи» и в списке пользователей ИБ новую чистую учетную запись и перенесите в нее настройки. Это часто помогает обойти внутренние системные сбои идентификаторов платформы 1С.
← На главную