Контроль уникальности кодов кассиров. УТ11

Пользователям было добавлено дополнительное поле «Код кассира», для того, чтобы при загрузке ОРП из оффлайн-кассы подставлялся кассир.

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

К сожалению, встроенного контроля уникальности для дополнительного реквизита нет:

Решено было добавить контроль в расширение.

Для этого добавляем модуль справочника пользователей, процедуру перед записью, выполняем перед основным кодом (чтобы можно было установить Отказ в Истина):

Чтобы не тянуть в расширение все объекты и поля, код запроса пишет в пустой внешней обработке конструктором. Табличку переименовываю в Т для лаконичности (мой стиль):

При этом если код кассира не заполнен, проверок быть не должно.

А если заполнен, то делаю еще проверку, чтобы он был числом.

В коде закомментирована трассировка, т.к. отладка была не доступна и с первого раза не заработало.


&Перед(«ПередЗаписью»)
Процедура дор_ПередЗаписью(Отказ)

   
ИдентификаторДляФормул = «КодКассира»;
   
Свойство = ПланыВидовХарактеристик.ДополнительныеРеквизитыИСведения.НайтиПоРеквизиту(«ИдентификаторДляФормул», ИдентификаторДляФормул);
   
//Сообщить(«Свойство:» + Свойство);

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

   
Значение = ИскСтрокаСвойства.Значение;
    Если Не
ЗначениеЗаполнено(Значение) Тогда
        Возврат;
    КонецЕсли;
   
//Сообщить(«Значение:» + Значение);

    //Если свойство заполнено, то должно быть числом
   
Попытка
       
Ч = Число(Значение);
    Исключение
       
Сообщить(«Код кассира должен быть числом: » + Значение);
       
Отказ = истина;
        Возврат;
    КонецПопытки;

   
З = Новый Запрос(
   
«ВЫБРАТЬ
    |   Т.Ссылка КАК Ссылка
    |ИЗ
    |   Справочник.Пользователи.ДополнительныеРеквизиты КАК Т
    |ГДЕ
    |   Т.Ссылка <> &Ссылка
    |   И Т.Свойство = &Свойство
    |   И Т.Значение = &Значение»
);

   
З.УстановитьПараметр(«Значение», Значение);
   
З.УстановитьПараметр(«Ссылка», Ссылка);
   
З.УстановитьПараметр(«Свойство», Свойство);
   
Выборка = З.Выполнить().Выбрать();
    Если
Выборка.Следующий() Тогда
       
Сообщить(«Код кассира » + Значение + » не уникальный, встречается у пользователя: » + Выборка.Ссылка);
       
Отказ = истина;
        Возврат;
    Конецесли;
КонецПроцедуры

Время план: 1 час. Среда: УТ 11.4.13.155.

fixin

Программирую на 1С с 1999 года. В 1С просто Гений. В 2020 году ушел из офиса на вольные хлеба фриланса. Принимаю заказы.

Читайте также:

комментариев 10

  1. Zuko:

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

    • тут надо глубоко копать в сторону транзакций, но пользователей у клиента заводит один человек.

  2. Ёся:

    Выборка = З.Выполнить().Выбрать();
    а без выорки слабо?

  3. fajij28770:

    опять какие-то трюки. спрашивается, почему нельзя поставить констрейт на уникальность в поле КодКассира в БД и не писать пол сотни строк кода, который все равно не гарантирует уникальности, как верно заметили выше.

    • Павел:

      Потому что это возможно только для служебных реквизитов и специфических объектов типа регистры сведений — по сути которые являются словарями

    • потому что платформа 1С не позволяет такие констрейт.

Добавить комментарий для fajij28770 Отменить ответ

Ваш адрес email не будет опубликован. Обязательные поля помечены *