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


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);
            Возврат;
        конецЕсли;
    конецЦикла;
    Сообщить("записан");
КонецПроцедуры



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