Контроль уникальности Справочника

1. AndKB 11.09.18 10:44 Сейчас в теме
Здравствуйте, пытаюсь реализовать контроль уникальности наименования Справочника
Процедура проверяет на дубли и выводит предупреждение, но все равно остается возможность записи В чем ошибка?
Процедура ПередЗаписью(Отказ, Элемент, Источник)
Если ТипЗнч(Наименование) = Тип("Строка") Тогда
		Если Ссылка.Наименование <> Наименование Тогда			
Н = СправочникОбъект.Наименование;
Если Не Справочники.ТМЦ.НайтиПоНаименованию(Н) = Справочники.ТМЦ.ПустаяСсылка() Тогда	
Текст = "ru = ""Справочник не уникален!""";
Предупреждение(НСтр(Текст), 10);
Отказ = Истина;
Возврат;
КонецЕсли;            
КонецЕсли;
КонецЕсли; 
КонецПроцедуры
Показать
По теме из базы знаний
Найденные решения
50. AndKB 12.09.18 12:04 Сейчас в теме
(33) Оказывается если сделать так, то все сработает:
Процедура ПередЗаписью(Отказ,)
Если Не Справочники.ТМЦ.НайтиПоНаименованию(Наименование) = Справочники.ТМЦ.ПустаяСсылка() Тогда    
     Текст = "ru = ""Наименование записи справочника не уникально!""";
     Предупреждение(НСтр(Текст), 10);
     Отказ = Истина;
     ЭтаФорма.Закрыть(Отказ);     
     Возврат;
КонецЕсли;            
КонецПроцедуры
Показать

Всем спасибо за участие в теме
Остальные ответы
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
6. herfis 499 11.09.18 11:40 Сейчас в теме
(1) В смысле "остается возможность записи"?
Если предупреждение выдало, то форма должна остаться открытой, а изменения не записанными (форма со звездочкой в заголовке).
При повторной попытке должно быть то же самое - выдать предупреждение и не записать.
А у вас что происходит?
7. AndKB 11.09.18 11:41 Сейчас в теме
(6) Вот как раз при повторе все записывается, второй день голову ломаю
8. herfis 499 11.09.18 11:43 Сейчас в теме
(7) Предупреждение при повторе выдает?
9. AndKB 11.09.18 11:43 Сейчас в теме
10. herfis 499 11.09.18 11:46 Сейчас в теме
(9) Значит, либо при повторе не срабатывает одно из условий (отладчиком ловите), либо повтор записи вызывается мимо стандартного интерактива.
Повтор вызывается повторным нажатием на кнопку записать? Или как-то иначе?
13. AndKB 11.09.18 11:51 Сейчас в теме
14. ben19791010 11.09.18 11:59 Сейчас в теме
(1)
Процедура ПередЗаписью(Отказ, Элемент, Источник)
	Если ОбменДанными.Загрузка = Истина Тогда
		Возврат;
	КонецЕсли;

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


попробуй так
16. AndKB 11.09.18 12:06 Сейчас в теме
(14) спасибо, теперь при повторной записи выдает ошибку:

ОбщийМодуль.УникальностьТМЦ.Модуль(3)}: Значение не является значением объектного типа (Загрузка)
Если ОбменДанными.Загрузка = Истина Тогда
17. ben19791010 11.09.18 12:07 Сейчас в теме
(16) не заметил что есть объект потому и ругается
19. AndKB 11.09.18 12:11 Сейчас в теме
(17) если убрать, при повторе так же записывает
полностью пустая база, обучалка
24. ben19791010 11.09.18 12:29 Сейчас в теме
(16)СправочникОбъект.ОбменДанными.Загрузка
26. herfis 499 11.09.18 12:32 Сейчас в теме
(24) У него в форме проверка. Нафига ему признак загрузки анализировать?
(25) С чего бы условие на равенство по индексированному полю вызвало жуткие тормоза, коллега?
27. ben19791010 11.09.18 12:32 Сейчас в теме
(26)
У него в форме проверка
в смысле в форме?
28. herfis 499 11.09.18 12:33 Сейчас в теме
(27)
в смысле в форме?

См. (4)
2. user633533_encantado 11 11.09.18 10:49 Сейчас в теме
"ПередЗаписью" откуда вызывается ?
4. AndKB 11.09.18 11:35 Сейчас в теме
(2) в модуле формы в событии "ПередЗаписью"
3. DarkUser 11.09.18 10:49 Сейчас в теме
А зачем вы сравниваете Наименование записываемого элемента с этим же элементом в БД? Просто сразу выполняйте проверку на поиск в справочнике по наименованию.
5. Fox-trot 158 11.09.18 11:38 Сейчас в теме
правильнее в модуле объекта
11. AndKB 11.09.18 11:49 Сейчас в теме
(5) Пробовал и так, проблема та же
12. herfis 499 11.09.18 11:49 Сейчас в теме
Что такое в вашем коде "СправочникОбъект"? Где и как "это" инициализируется?
Вопрос снимается. Уже забыл обычные формы :)
15. herfis 499 11.09.18 12:05 Сейчас в теме
Меня смущает обращение к наименованию через СправочникОбъект. Пока не понимаю, как это может влиять, но давайте для начала упростим код и искать будем по полному совпадению:
Процедура ПередЗаписью(Отказ, Элемент, Источник)
	Если ЗначениеЗаполнено(Справочники.ТМЦ.НайтиПоНаименованию(Наименование, Истина)) Тогда    
		Отказ = Истина;
		Предупреждение(НСтр("ru = ""Справочник не уникален!"""), 10);
	КонецЕсли;            
КонецПроцедуры
20. AndKB 11.09.18 12:13 Сейчас в теме
21. herfis 499 11.09.18 12:19 Сейчас в теме
(20) А у тебя случайно нет реквизитов и переменных с именем "Наименование"? Чую, неспроста это обращение через СправочникОбъект. Явно каких-то костылей нагорожено.
29. AndKB 11.09.18 13:43 Сейчас в теме
(21) По большому счету Справочник.Объект не влияет, можно сказать - это мои жалкие попытки реализовать процедуру, реквизитов нет, к примеру если все заменить на код как в (15) - обрабатывает с такой же проблемой. Справочник "толькочто" созданный. Вопрос почему код, грубо говоря игнорит, "Отказ = Истина"
34. herfis 499 11.09.18 14:19 Сейчас в теме
(29)
Вопрос почему код, грубо говоря игнорит, "Отказ = Истина"

Не игнорит. С твоих слов выполнение вообще в эту ветку не попадает (не выдает предупреждение).
Если совсем печаль - запусти отладчик и поставь точку останова, уже советовал.
18. ben19791010 11.09.18 12:07 Сейчас в теме
22. ben19791010 11.09.18 12:20 Сейчас в теме
23. herfis 499 11.09.18 12:22 Сейчас в теме
Короче, вот это должно работать как надо:
Процедура ПередЗаписью(Отказ, Элемент, Источник)
	
	Запрос = Новый Запрос;
	Запрос.Текст = 
	"ВЫБРАТЬ ПЕРВЫЕ 1
	|	Номенклатура.Ссылка
	|ИЗ
	|	Справочник.Номенклатура КАК Номенклатура
	|ГДЕ
	|	Номенклатура.Ссылка <> &Ссылка
	|	И Номенклатура.Наименование = &Наименование";
	Запрос.УстановитьПараметр("Ссылка", Ссылка);
	Запрос.УстановитьПараметр("Наименование", СправочникОбъект.Наименование);
	Выборка = Запрос.Выполнить().Выбрать();
	Если Выборка.Следующий() Тогда
		Сообщить("В базе уже есть элемент с указанным наименованием", СтатусСообщения.Важное);
		Отказ = Истина;
	КонецЕсли;
	
КонецПроцедуры
Показать
25. Fox-trot 158 11.09.18 12:30 Сейчас в теме
(23)
|ГДЕ
| Номенклатура.Ссылка <> &Ссылка
| И Номенклатура.Наименование = &Наименование";

это ж жуткие тормоза, коллега
53. YanTsys 12 13.09.18 17:37 Сейчас в теме
(25) С чего это тормоза? Вполне нормальный запрос...
55. YanTsys 12 13.09.18 17:54 Сейчас в теме
(25) но если учесть ваше замечание и оптимизировать то можно вот так:

Процедура ПередЗаписью(Отказ, Элемент, Источник)
    
    Запрос = Новый Запрос;
    Запрос.Текст = 
    "ВЫБРАТЬ ПЕРВЫЕ 1
    |    Номенклатура.Ссылка
    |ИЗ
    |    Справочник.Номенклатура КАК Номенклатура
    |ГДЕ
    |    И Номенклатура.Наименование = &Наименование";
    Запрос.УстановитьПараметр("Наименование", СправочникОбъект.Наименование);
    Выборка = Запрос.Выполнить().Выбрать();
    Если Выборка.Следующий() Тогда
        Если Выборка.Ссылка=Ссылка Тогда
           Возврат;
        КонецЕсли;
        Сообщить("В базе уже есть элемент с указанным наименованием", СтатусСообщения.Важное);
        Отказ = Истина;
    КонецЕсли;
    
КонецПроцедуры
Показать
Fox-trot; +1 Ответить
44. Ditron 185 11.09.18 18:58 Сейчас в теме
Ну вы тут проблему устроили из ничего )) в (23) точно должно работать, я бы туда добавил еще проверку на заполненность наименования, а то вдруг забыли его заполнить...
30. Healer 1 11.09.18 13:59 Сейчас в теме
Вот так вот:

Процедура ПередЗаписью(Отказ, Элемент, Источник)
Если Не Справочники.ТМЦ.НайтиПоНаименованию(Объект.Наименование) = Справочники.ТМЦ.ПустаяСсылка() Тогда    
     Текст = "ru = ""Наименование записи справочника не уникально!""";
     Предупреждение(НСтр(Текст), 10);
     Отказ = Истина;
     Возврат;
КонецЕсли;            
КонецПроцедуры
31. Healer 1 11.09.18 14:01 Сейчас в теме
Можно ещё
ЭтаФорма.Закрыть(Отказ);
в конце, если не поможет. "Контрольный", так сказать... :-)
32. Healer 1 11.09.18 14:03 Сейчас в теме
Проверка типов не нужна, поскольку источник не может быть неопределённым и наименование справочника всегда типа "Строка(150)".
33. Healer 1 11.09.18 14:09 Сейчас в теме
То есть вот так вот прям точно всё станет срабатывать:

Процедура ПередЗаписью(Отказ, Элемент, Источник)
Если Не Справочники.ТМЦ.НайтиПоНаименованию(Объект.Наименование) = Справочники.ТМЦ.ПустаяСсылка() Тогда    
     Текст = "ru = ""Наименование записи справочника не уникально!""";
     Предупреждение(НСтр(Текст), 10);
     Отказ = Истина;
     ЭтаФорма.Закрыть(Отказ);     
     Возврат;
КонецЕсли;            
КонецПроцедуры
Показать
35. Fox-trot 158 11.09.18 14:27 Сейчас в теме
(33) этот проверка только для новых корректна?
а что будет, если изменить не наименование, а другой реквизит. запишется?

(1) если sql, то я б решил все на стороне скуля созданием уникального индекса (первичного ключа) и без единой строки кода на стороне 1с. хотя это конечно не тру программирование, потом лицензии и все такое...
36. Healer 1 11.09.18 14:48 Сейчас в теме
(35) Сработает корректно и для новых, и для записанных элементов. Если изменится другой реквизит, запись пройдёт: мы ведь только наименование проверяем.
54. YanTsys 12 13.09.18 17:41 Сейчас в теме
(36) Не пройдет повторная запись, в справочнике элемент уже записан, значит НайтиПоНаименованию вернет непустую ссылку а значит отказ.
47. AndKB 12.09.18 08:18 Сейчас в теме
(33) Тогда вываливается вот это :
Значение не является значением объектного типа (Наименование)
Если Не Справочники.ТМЦ.НайтиПоНаименованию(Объект.Наименование) = Справочники.ТМЦ.ПустаяСсылка() Тогда


Если убрать - не дает вообще возможность записи, даже с именем которое не используется
48. Healer 1 12.09.18 09:20 Сейчас в теме
(47) Раз ругается на Объект, значит он у Вас, видимо, типа "Управляемая форма", а не элемент справочника. К сожалению, сведений о конфигурации и варианте приложения Вы не предоставили, догадаться по коду не получается :-) Используйте "ЭтотОбъект", вместо "Объект".
49. AndKB 12.09.18 09:43 Сейчас в теме
(48) Почему? нет, форма обычного приложения
50. AndKB 12.09.18 12:04 Сейчас в теме
(33) Оказывается если сделать так, то все сработает:
Процедура ПередЗаписью(Отказ,)
Если Не Справочники.ТМЦ.НайтиПоНаименованию(Наименование) = Справочники.ТМЦ.ПустаяСсылка() Тогда    
     Текст = "ru = ""Наименование записи справочника не уникально!""";
     Предупреждение(НСтр(Текст), 10);
     Отказ = Истина;
     ЭтаФорма.Закрыть(Отказ);     
     Возврат;
КонецЕсли;            
КонецПроцедуры
Показать

Всем спасибо за участие в теме
52. YanTsys 12 13.09.18 17:34 Сейчас в теме
(50) Вы пробовали повторно записать уже ранее записанный элемент?
Как я понимаю при текущем коде он найдет сам себя и будет неприлично ругаться :)
37. Healer 1 11.09.18 14:51 Сейчас в теме
Новый элемент от записанного отличается только неопределёнными значениями "Ссылка" и "ВерсияОбъекта".
38. Doreng 27 11.09.18 15:43 Сейчас в теме
Капец :-) А вы не хотите проверить объект на новый?
Короче
Процедура ПередЗаписью(Отказ, Элемент, Источник)
Если ЭтоНовый() Тогда // Для УФ Если Не Параметры.Ключ.Пустая() Тогда
Если Не Справочники.ТМЦ.НайтиПоНаименованию(Объект.Наименование) .Пустая() Тогда
Отказ = Истина;
КонецЕсли;
КонецЕсли;
КонецПроцедуры;
Показать

(14)
(15)
(23)
39. Healer 1 11.09.18 15:55 Сейчас в теме
(38) Извините, но "капец" у Вас в коде: метод "ЭтоНовый()" не рекомендуется 1С-ой к использованию ;-)
40. Healer 1 11.09.18 15:57 Сейчас в теме
(39) А проверять, новый ли объект, 1С предлагает проверкой свойства "Ссылка" на равенство "Неопределено".
41. Doreng 27 11.09.18 15:57 Сейчас в теме
(39)не нравится пишите запрос и в параметр ссылку
возврат истина или ложь и не тычте 1с-ом Вы сами па наименованию ищите
42. Healer 1 11.09.18 15:58 Сейчас в теме
(38) Опять же, проверять надо не только новые записи: мало ли, может наименование поменяют и получится дубль по наименованию, чего и хочет избежать автор.
43. Doreng 27 11.09.18 16:09 Сейчас в теме
(42)
Прикрепленные файлы:
user1639303; config; +2 Ответить
45. Ditron 185 11.09.18 18:58 Сейчас в теме
46. Ditron 185 11.09.18 19:01 Сейчас в теме
И к сведению "НайтиПоНаименованию" будет по скорости хуже чем запрос
51. bmk74 234 13.09.18 14:46 Сейчас в теме
А вопрос странный можно ? а нафига закрывать форму при ошибке ? И возврат зачем то запихнули...она и без возврата отработает...
Оставьте свое сообщение

Для получения уведомлений об ответах подключите телеграм бот:
Инфостарт бот