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

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

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

Анализ проблемы: почему данные попадают «не туда»?

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

Если вы столкнулись с подобным эффектом, проанализируем возможные причины:

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

Способ 1: Использование Ключа Уникальности

Для того чтобы 1С понимала, что каждое открытое окно обработки — это независимый объект, мы должны использовать параметр КлючУникальности. Этот ключ позволяет платформе различать экземпляры одной и той же формы в рамках одного сеанса.

Разберем, как правильно открывать форму, чтобы гарантировать её уникальность. Вместо стандартного вызова без параметров, используем генерацию УникальныйИдентификатор. Это особенно актуально, если один пользователь может открыть несколько окон приемки товара одновременно.


// Пример открытия уникальной формы
Ключ = Новый УникальныйИдентификатор;
ПараметрыФормы = Новый Структура("Ключ", "Значение");
ОткрытьФорму("ВнешняяОбработка.ПриемкаТовара.Форма.ФормаГВХ", ПараметрыФормы, ЭтаФорма, Ключ);

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

Способ 2: Идентификация рабочего места (ПК)

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

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


// В процедуре открытия или инициализации
ИмяКомпьютераСеанса = ИмяКомпьютера();

Если ИмяКомпьютераСеанса = "СКЛАД_ПК_1" Тогда
    // Это рабочее место с весами
    ФормаИзм = ПолучитьФорму("ФормаГВХ", , "ФормаСВесами");
    ФормаИзм.Номенклатура = ТекущаяНоменклатура;
    ФормаИзм.Открыть();
Иначе
    // Обычное рабочее место для ручного ввода
    ФормаИзм = ПолучитьФорму("ФормаГВХ");
    ФормаИзм.Номенклатура = ТекущаяНоменклатура;
    ФормаИзм.Открыть();
КонецЕсли;

Затем, непосредственно в процедуре получения данных, мы проверяем, является ли текущая форма «той самой», которая работает с оборудованием:


Процедура ПолучитьГВХСВесовНажатие(Элемент)
    
    // Проверяем ключ уникальности, заданный при открытии
    Если ЭтаФорма.КлючУникальности <> "ФормаСВесами" Тогда
        Сообщить("Это рабочее место не подключено к весам. Введите данные вручную.");
        Возврат;
    КонецЕсли;

    // Код обращения к HTTP-серверу весов
    HTTP = Новый HTTPСоединение("192.168.1.100", , , , , , );
    // ... логика запроса ...
    
    ЭтаФорма.ФШирина = Число(НаборГВХ["width"]);
    ЭтаФорма.ФВес = Число(НаборГВХ["weight"]);
    
КонецПроцедуры

Способ 3: Работа через Параметры Сеанса

Для более чистого кода рекомендуется использовать ПараметрыСеанса или настройки пользователя в базе данных. Выясним, как это улучшит архитектуру. Вместо жесткого сравнения строк (имен компьютеров), создадим в конфигурации регистр сведений НастройкиРабочихМест, где укажем IP-адрес весов для каждого ПК.

Рассмотрим алгоритм работы:

  1. При открытии формы обработка считывает из регистра IP-адрес весов, привязанный к текущему пользователю или компьютеру.
  2. Если адрес заполнен — кнопка «Получить с весов» становится доступной.
  3. Если адрес пустой — пользователь может только вводить данные руками.

Это исключает ситуацию, когда пользователь с другого конца склада случайно нажимает кнопку и получает данные с чужих весов, так как запрос пойдет на корректный IP-адрес, соответствующий его рабочему месту.

Важные рекомендации по многопользовательской работе

При проектировании подобных интерфейсов следует придерживаться нескольких правил, чтобы избежать «затирания» данных:

1. Отказ от модальности. В современном интерфейсе «Такси» рекомендуется использовать ОткрытьФорму вместо ОткрытьМодально. Это позволяет пользователю переключаться между окнами и не блокирует весь интерфейс программы, что особенно важно при ожидании ответа от медленного оборудования.

2. Проверка модифицированности. Перед заполнением данных из весов в код стоит добавить проверку: Если ЭтаФорма.Модифицированность Тогда.... Это позволит предупредить пользователя, что он уже начал вводить данные вручную, а автоматика может их затереть.

3. Изоляция бизнес-логики. Выносите код работы с HTTP в общий модуль с флагом ВызовСервера. Это позволит централизованно управлять подключениями и логировать ошибки связи с оборудованием в одном месте.

4. Обработка оповещений. Если вам все же нужно передать данные из одной формы в другую, используйте метод Оповестить() и обработчик ОбработкаОповещения. Помните, что стандартное оповещение работает в пределах одного клиентского приложения (одного окна 1С).

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

← На главную