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

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

Многие пользователи и администраторы 1С сталкиваются с неприятной ситуацией: в справочнике «Рабочие места» со временем накапливаются дублирующиеся записи для одного и того же пользователя на одном и том же компьютере. Часто это происходит после стандартных процедур, таких как очистка кэша, и приводит к необходимости заново настраивать торговое оборудование и другие персональные параметры. Давайте вместе разберемся, почему это происходит и как раз и навсегда решить эту проблему.

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

Причина смены ClientID: где на самом деле хранится идентификатор

Начнем с главного: утверждение в справке технически верно, но с одним важным нюансом. ClientID действительно уникален и постоянен, но только до тех пор, пока цел файл, в котором он хранится. Этот идентификатор не вычисляется каждый раз на основе аппаратной конфигурации компьютера, а генерируется один раз и записывается в файл настроек профиля пользователя 1С.

Этот файл, как правило, называется 1cv8u.pfl и находится в папке с глобальными настройками пользователя, например, по пути:

C:\Users\<ИмяПользователяОС>\AppData\Local\1C\1cv8\

Содержимое этого файла может выглядеть примерно так, как выяснили участники форума:


{
{""},
{
{"Universal",
{"ClientID",
{"#",fc01b5df-97fe-449b-83d4-218a090e681e,083241ee-94b4-486f-af56-c5f8ed879014},""},
{
{""}
}
},
{""}
}
}

Здесь fc01b5df-97fe-449b-83d4-218a090e681e и есть тот самый ClientID. А теперь рассмотрим самую частую причину его смены.

Когда в 1С возникают ошибки или странное поведение, первый и самый популярный совет от службы поддержки или системного администратора — «почистить кэш». К сожалению, под этой фразой часто подразумевается полное удаление пользовательских папок 1С, таких как %AppData%\Roaming\1C\1cv8 и %AppData%\Local\1C\1cv8. В результате вместе с временными файлами кэша удаляется и файл 1cv8u.pfl. При следующем запуске платформа 1С не находит старый идентификатор и генерирует новый.

Вывод: ClientID меняется не сам по себе, а потому что файл, где он хранится, удаляется при «грубой» очистке кэша. Для системы 1С это выглядит так, как будто пользователь зашел с абсолютно нового, ранее неизвестного рабочего места, что и приводит к созданию новой записи в справочнике.

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

Как решить проблему: создаем надежный идентификатор

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

Для рабочего места идеальным естественным ключом является связка: Имя компьютера + Имя пользователя операционной системы. Эти параметры остаются неизменными при очистке кэша 1С.

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

Решение 1: Реализация через расширение конфигурации (рекомендуемый способ)

Создадим механизм, который будет привязывать непостоянный ClientID к нашей стабильной связке. Это позволит системе «узнавать» рабочее место, даже если системный идентификатор изменится.

Шаг 1. Создаем объект для хранения соответствий

В расширении добавим новый объект — независимый, непериодический Регистр сведений. Назовем его, например, СоответствиеИдентификаторовРабочихМест.

Этот регистр будет хранить нашу надежную привязку.

Шаг 2. Добавляем код для получения данных и поиска рабочего места

Нам понадобится функция, которая будет определять текущее рабочее место. Лучше всего разместить ее в общем модуле расширения с флагами «Клиент (обычное приложение)», «Клиент (управляемое приложение)» и «Вызов сервера».

Сначала напишем код для получения имени компьютера и пользователя ОС. Это можно сделать с помощью объекта WScript.Network на клиенте под Windows.


&НаКлиенте
Функция ПолучитьПараметрыИдентификацииКлиента()
    
    Перем ИмяКомпьютера, ИмяПользователяОС;
    
    // Этот код работает только на клиенте под ОС Windows
    #Если ТонкийКлиент ИЛИ ТолстыйКлиент Тогда
        Попытка
            Network = Новый COMОбъект("WScript.Network");
            ИмяКомпьютера = Network.ComputerName;
            ИмяПользователяОС = Network.UserName;
        Исключение
            // Если COM-объект недоступен (например, на Linux или в веб-клиенте),
            // можно использовать альтернативные методы или сообщить об ошибке.
            // Для простоты оставим пустыми.
            ИмяКомпьютера = "";
            ИмяПользователяОС = "";
        КонецПопытки;
    #КонецЕсли
    
    Результат = Новый Структура;
    Результат.Вставить("ИмяКомпьютера", ВРег(ИмяКомпьютера));
    Результат.Вставить("ИмяПользователяОС", ВРег(ИмяПользователяОС));
    
    Возврат Результат;
    
КонецФункции

Шаг 3. Заполняем регистр и определяем рабочее место при старте системы

Теперь создадим процедуру, которая будет выполняться при каждом запуске сеанса. Для этого в расширении создадим Модуль сеанса и добавим обработчик события УстановкаПараметровСеанса.

Логика будет следующей:

  1. При старте сеанса получаем «естественный ключ» (имя ПК + имя пользователя ОС).
  2. Ищем запись в нашем новом регистре СоответствиеИдентификаторовРабочихМест по этому ключу.
  3. Если запись найдена: значит, мы уже знаем, какому элементу справочника «Рабочие места» соответствует этот компьютер. Используем найденную ссылку.
  4. Если запись не найдена: значит, это либо первый вход с данного ПК, либо вход после смены ClientID. В этом случае мы позволяем типовому механизму создать новое рабочее место (или найти его по новому ClientID), а затем сохраняем связь между нашим «естественным ключом» и найденным/созданным элементом справочника в наш регистр.

Примерный код для модуля сеанса (серверный вызов):


&НаСервере
Процедура ОпределитьИЗаписатьРабочееМесто(ПараметрыИдентификации)
    
    Если НЕ ЗначениеЗаполнено(ПараметрыИдентификации.ИмяКомпьютера) Тогда
        // Не удалось определить параметры, выходим
        Возврат;
    КонецЕсли;
    
    // 1. Ищем запись в нашем регистре
    Отбор = Новый Структура("ИмяКомпьютера, ИмяПользователяОС", 
        ПараметрыИдентификации.ИмяКомпьютера, ПараметрыИдентификации.ИмяПользователяОС);
    
    ЗаписьРегистра = РегистрыСведений.СоответствиеИдентификаторовРабочихМест.Получить(Отбор);
    
    Если ЗаписьРегистра.РабочееМесто <> Неопределено Тогда
        // 2. Запись найдена! Мы знаем рабочее место.
        // Здесь можно установить его в параметры сеанса или глобальную переменную,
        // чтобы другие механизмы использовали именно его.
        ПараметрыСеанса.ТекущееРабочееМесто = ЗаписьРегистра.РабочееМесто;
    Иначе
        // 3. Запись не найдена. Позволяем сработать типовому механизму.
        // Предположим, что типовая функция возвращает нам текущее рабочее место.
        // В разных конфигурациях она может называться по-разному.
        // Для примера назовем ее `ТиповаяФункцияОпределенияРабочегоМеста()`.
        ТекущееРабочееМесто = ОбщегоНазначения.ОпределитьТекущееРабочееМестоПоClientID(); // Это условное название!
        
        Если ЗначениеЗаполнено(ТекущееРабочееМесто) Тогда
            // 4. Записываем новую связку в наш регистр для будущих сеансов.
            МенеджерЗаписи = РегистрыСведений.СоответствиеИдентификаторовРабочихМест.СоздатьМенеджерЗаписи();
            МенеджерЗаписи.ИмяКомпьютера = ПараметрыИдентификации.ИмяКомпьютера;
            МенеджерЗаписи.ИмяПользователяОС = ПараметрыИдентификации.ИмяПользователяОС;
            МенеджерЗаписи.РабочееМесто = ТекущееРабочееМесто;
            
            Попытка
                МенеджерЗаписи.Записать();
            Исключение
                // Обработка возможной ошибки записи
            КонецПопытки;
            
            ПараметрыСеанса.ТекущееРабочееМесто = ТекущееРабочееМесто;
        КонецЕсли;
    КонецЕсли;
    
КонецПроцедуры

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

Решение 2: Правильная очистка кэша

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

Не нужно удалять всю папку 1C в AppData!

Кэш конкретных информационных баз хранится в подпапках с длинными именами, похожими на GUID. Именно их и нужно удалять.

  1. Откройте список информационных баз в окне запуска 1С.
  2. Выделите нужную базу и посмотрите путь к ней внизу окна.
  3. Найдите папки с кэшем в %AppData%\Roaming\1C\1cv8 и %AppData%\Local\1C\1cv8. Внутри них будут папки с именами вида c1e7cf34-e6e2-4a0b-8499-e6884f323565.
  4. Удаляйте только эти папки-GUID, не трогая файлы в корне (например, 1cv8u.pfl, 1cestart.cfg).

Этот способ требует большей аккуратности, но он позволяет избежать смены ClientID без доработки системы.

Итоги

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

← На главную