Вход | Регистрация


1С:Предприятие ::

Метки:

Отцы! Поможите кто чем может!!!

Я
   Dron (надеюсь ничейн
13.02.04 - 23:57
Все, наверное, ;-) знают, что у кода справочника, если хочется, есть такое замечательное свойство - уникальность.
Предложите решение для назначения уникальности другому реквизиту справочника. Т.е., чтобы нельзя было записать новый элемент, если значение одного из его реквизитов совпадает со значением этого реквизита у какого-нибудь существующего элемента.
Может, кто уже сталкивался?
---
ПС: Предлагавшиеся решения можно тут посмотреть, только они работают неправильно :(
http://www.1cworld.com/forum/viewtopic.php?t=1067
кстати, перебор в обратном порядке мне почему-то тоже не помог :(((
 
  Рекламное место пустует
   Львенок
 
1 - 14.02.04 - 00:04
Лехко. У реквизита установить св-во "сортировка". Далее в ПриЗаписи() (в форме списка или в форме элемента)
Если НайтиПоРеквизиту("ТотСамыйРеквизит",ТекущееЗначенийТогоСамогоРеквизита)=1 Тогда//Ага такой уже есть

   Предупреждение("Реквизит не уникален!");
   СтатусВозврата(0);//Не будем записывать!

   Возврат;
КонецЕсли;
P.S.: Как-то так...
__
Искренне Ваш, Львенок.
   GrayT
 
2 - 14.02.04 - 00:16
(0)Угу, не работет. Для нового элеиента ТекущийЭлемент() еще не существует. Желательно проверить Выбран()
   Волшебник
 
3 - 14.02.04 - 00:17
Себя найдешь. Нужно проверять
"Если не равно текущий, тогда все ок..."
   Dron (надеюсь ничейн
4 - 14.02.04 - 00:19
Блин, отцы, пробовал этот алгоритм, могу конфу прислать - не работает.
Может ошибка в генах, конечно...
   GrayT
 
5 - 14.02.04 - 00:26
"Метод  можно использовать только для объектов, созданных функцией СоздатьОбъект." из als
   GrayT
 
6 - 14.02.04 - 00:35
Процедура приЗаписи()
    спр = СоздатьОбъект("Справочник.Новый1");
    
    Если спр.НайтиПоРеквизиту("новый1",новый1,1)=1 Тогда//Ага такой уже есть 

      Предупреждение("Реквизит не уникален!"); 
      СтатусВозврата(0);//Не будем записывать! 

      Возврат; 
    КонецЕсли; 
    
КонецПроцедуры//приЗаписи
   GrayT
 
7 - 14.02.04 - 00:37
Если использовать в уже заполненном справочнике (где возможны повторения) то (3) приведет к тому что надо следующий проверить. Те. уже выбирать по реквизиту
   Львенок
 
8 - 14.02.04 - 00:53
(6) Ну я же на вскидку написал, без запуска 1С. Ты, раумеется, более корректен... Но мыслящему человеку достаточно и самой идеи. Логично?
___
Искренне Ваш, Львенок.
   Dron (надеюсь ничейн
9 - 14.02.04 - 00:55
к (6) - в том-то и дело, что этот метод хорош только при создании нового элемента, а если мы редактировали существующий элемент, то этот метод не даст нам и его записать.

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

Процедура ПриЗаписи()
    ТКопия=СоздатьОбъект("справочник.ааа");
    ТекЭл = ТекущийЭлемент();
    ТКопия.ВыбратьЭлементыПоРеквизиту("Реквизитик",ТекЭл.Реквизитик,1,0);
    Пока ТКопия.ПолучитьЭлемент()=1 цикл
        если ТКопия.ТекущийЭлемент()<>ТекЭл тогда
            Сообщить("такой есть");
            СтатусВозврата(0);
            Возврат;
        конецЕсли;
    конецЦикла;
    Сообщить("записан");
КонецПроцедуры
   skunk
 
10 - 14.02.04 - 02:24
сделай проверку уникальности не при записи а при изменении реквизита

Var OldValue;

//*******************************************

Function Check()
    If OldValue <> Value Then
        If Проверка_Уникальности() = "Не найдено" Then
            OldValue = Value;
        Else
            Value = OldValue;
        EndIf
    EndIf;
EndFunction

//*******************************************

Procedure OnOpen()
    OldValue = Value;
EndProcedure
 
  Рекламное место пустует
   GrayT
 
11 - 14.02.04 - 09:58
(9) когда элемент новый то текущийЭлемент() ни чего не вернет, потому он и записывается спокойно, т.е.
ТекЭл = ТекущийЭлемент(); 
не сработает
   GrayT
 
12 - 14.02.04 - 10:01
Внутри цикла 
Если Выбран()=0 тогда//Коль какойто элемент выбран, аэто новый, значит это копия

СтатусВозврата(0)
   Dron
 
13 - 14.02.04 - 11:29
А все-таки нетривиальная задачка.
Волшебник, может быть стоит включить ее в уроки, я думаю, по сложности она сравнима с удалением строк.
=====
Пояснение:
ааа - справочник, с которым работаем;
"Реквизитик" - реквизит справочника, уникальности которого добиваемся;
Реквизитик - предполагается, что на форме для реквизита справочника есть одноименная переменная, как обычно и бывает, если это не так, то переменная Реквизитик содержит новое значение, которое требуется проверить на уникальность.

Процедура ПриЗаписи()
    если Выбран()=1 тогда
        ТКопия=СоздатьОбъект("справочник.ааа");
        ТекЭл = ТекущийЭлемент();
        ТКопия.ВыбратьЭлементыПоРеквизиту("Реквизитик",Реквизитик,1,0);
        Пока ТКопия.ПолучитьЭлемент()=1 цикл
            если ТКопия.ТекущийЭлемент()<>ТекЭл тогда
                Сообщить("такой есть");
                СтатусВозврата(0);
                Возврат;
            конецЕсли;
        конецЦикла;
    иначе
        ТКопия=СоздатьОбъект("справочник.ааа");
        если ТКопия.НайтиПоРеквизиту("Реквизитик",Реквизитик,1)=1 тогда
            Сообщить("такой есть");
            СтатусВозврата(0);
            Возврат;
        конецЕсли;
    конецЕсли;
    Сообщить("записан");
КонецПроцедуры
   GrayT
 
14 - 14.02.04 - 11:39
Зачем так длинно?
       ТКопия=СоздатьОбъект("справочник.ааа"); 
       текЭл = ?(Выбран()=1, ТекущийЭлемент(), "");
       Если ТКопия.НайтиПоРеквизиту("Реквизитик",Реквизитик,1)=1 тогда 
        Если ТКопия.ТекущийЭлемент()<>текЭл тогда
           Сообщить("такой есть"); 
           СтатусВозврата(0); 
           Возврат; 
        конецЕсли; 
         КонецЕсли;
   Сообщить("записан");
   skunk
 
15 - 14.02.04 - 11:40
какая она нетривиальная, решается простым удалением из элементов формы диалога в формулах строк #Записать

запись самого элемента отрабатывать процедурой ПриЗакрытии

Ну еще проще, и правильнее делать проверку после ввода нового реквизита
   GrayT
 
16 - 14.02.04 - 11:41
Ой вместо Если НайтиПоРеквициту - Пока Ткопия.Получить,
Ну а впереди выбрать по реквизиту.
Не тот кусок скопировал :((
   shura
 
17 - 14.02.04 - 11:42
Че то я ничего не понял из всей ветки. Зачем циклы нужны?
Я вот что думаю:

Процедура ПриЗаписи() 
   ТКопия=СоздатьОбъект("справочник.ааа"); 
   ТКопия.ВыбратьЭлементыПоРеквизиту("Реквизитик",Реквизитик,1,0); 
   Если ТКопия.ПолучитьЭлемент()=1 Тогда
       Если ТКопия.ТекущийЭлемент()<>ТекЭл тогда 
           Сообщить("такой есть"); 
           СтатусВозврата(0); 
           Возврат;
       КонецЕсли;
   КонецЕсли; 
   Сообщить("Можно попытаться записать");
КонецПроцедуры
   shura
 
18 - 14.02.04 - 11:44
Млин, пока изголялся и красоту наводил, опередили ;((

И ошибку заодно сделал:
вместо ТекЭл надо ТекущийЭлемент()
   GrayT
 
19 - 14.02.04 - 11:45
(17) Циклы нужны - см.3,7,9
   shura
 
20 - 14.02.04 - 11:48
(19) Все равно не понимаю.
Реквизит должен быть уникальный? Если у нас есть такой реквизит в выборке (а он должен быть один) и он не равен ТекущемуЭлементу, значит это повторение (однозначно)
   GrayT
 
21 - 14.02.04 - 11:52
Допустим справочник заполнялся ранее без обработки уникальности по реквизиту. А твой пример не будет работать для нового элемента - это уже обсуждалось
   shura
 
22 - 14.02.04 - 12:01
А если какой-то дурак возьмет и запустит обработку, которая все реквизиты устанавливает равным "1" что тогда?
Зачем тогда проверять уникальность, если допускать изночально, что есть много таких элементов а не один? Даже если их много, то тогда выборка вернет первый встретившийся. Но это (ИМХО) будет не ТекущийЭлемент(). Ну поставь для пущей важности ТКопия.ПорядокКодов() (или как там?).

Не понимаю проблемы.
   shura
 
23 - 14.02.04 - 12:02
В догонку к (22).
А если уникальность вводишь, то прогони обработку, которая эту уникальность сначала установит
   Dron
 
24 - 14.02.04 - 12:57
to Skunk: а поподробнее можно?
to Shura: "А если какой-то дурак возьмет и запустит обработку, которая все реквизиты устанавливает равным "1" что тогда?" - А если небо упадет на землю? :) давайте рассматривать реальную ситуацию.
to GrayT: да, похоже, так действительно лучше

У меня возникла другая проблема. Все это работает, пока справочник "ааа" остается не подчиненным.
У вот когда он подчиненный, тогда проверка уникальности куда-то пропадает. можно менять старые значения на повторы, можно вводить новые повторяющиеся. В чем дело?
   GrayT
 
25 - 14.02.04 - 13:08
В пределах подчинения? Перед перебором используй ИспользоватьВладельца
   Dron
 
26 - 14.02.04 - 13:46
да я и рад бы, но где его взять-то для нового элемента?
   GrayT
 
27 - 14.02.04 - 13:48
Даже у нового элемента есть Владелец - прямо в модуле
ТКопия.ИспользоватьВладельца(Владелец)
   Dron
 
28 - 14.02.04 - 14:01
точно :) сам пока яишенку кушал допетрил :) в заголовке же светится владелец, значит где-то есть :))
Спасибо, GrayT, за помощь! ;)
--
Ежели кому понадобится на будущее:
Процедура ПриЗаписи()
    ТКопия=СоздатьОбъект("справочник.ааа");
    текЭл = ?(Выбран()=1, ТекущийЭлемент(), "");
    ТКопия.использоватьВладельца(Владелец);
    ТКопия.ВыбратьЭлементыПоРеквизиту("Реквизитик",Реквизитик,1,0);
    Пока ТКопия.ПолучитьЭлемент()=1 цикл
        если ТКопия.ТекущийЭлемент()<>ТекЭл тогда
            Сообщить("такой есть");
            СтатусВозврата(0);
            Возврат;
        конецЕсли;
    конецЦикла;
    Сообщить("записан");
КонецПроцедуры



Список тем форума
Рекламное место пустует   Рекламное место пустует
2 + 2 = 3.9999999999999999999999999999999...
ВНИМАНИЕ! Если вы потеряли окно ввода сообщения, нажмите Ctrl-F5 или Ctrl-R или кнопку "Обновить" в браузере.
Ветка сдана в архив. Добавление сообщений невозможно.
Но вы можете создать новую ветку и вам обязательно ответят!
Каждый час на Волшебном форуме бывает более 2000 человек.
Рекламное место пустует