Имя: Пароль:
1C
1C 7.7
v7: Запись элемента справочника. Выборка "потерялась"
0 BalBess
 
23.12.13
12:54
Тема уже не раз обсуждалась, например Запись элемента. Ночь. Не соображаю уже ;)

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

Функция НайтиКонтрагента(ЭлАдрес)
    НашлиКонтрагента = Ложь;
    
    спрКонтр = СоздатьОбъект("Справочник.Контрагенты");
    Если спрКонтр.НайтиПоРеквизиту("email", СокрЛП(ЭлАдрес), 1) = Истина Тогда
        НашлиКонтрагента = Истина;
    КонецЕсли;
    Если НашлиКонтрагента = Ложь Тогда
        //если не нашли то создаем
        спрКонтр.Новый();
    КонецЕсли;

    спрКонтр.Наименование = ЭлАдрес;
    спрКонтр.email = ЭлАдрес;

    // тут самое интересное
    Контр = спрКонтр.ТекущийЭлемент();
    // если контрагент существует, то все работает
    // а если нет, то Контр пустой, т.к. элемент не записан
    Попытка
        спрКонтр.Записать();
    Исключение
        Сообщить(ОписаниеОшибки());
    КонецПопытки;
    
    спрКонтр.НайтиЭлемент(Контр);
    
    
    Сообщить(спрКонтр.Выбран());
    Сообщить(спрКонтр.Наименование);
    // вопрос как мне вернуть элемент?
    Возврат спрКонтр.ТекущийЭлемент();
  
КонецФункции
1 skunk
 
23.12.13
12:56
а смысл этой строки

Контр = спрКонтр.ТекущийЭлемент();
2 Godofsin
 
23.12.13
12:56
Класс!
3 ДенисЧ
 
23.12.13
12:57
Есмть такое.
Заново найди
4 Godofsin
 
23.12.13
12:57
(1) а смысл вот этой?
спрКонтр.НайтиПоРеквизиту("email", СокрЛП(ЭлАдрес), 1) = Истина
5 Godofsin
 
23.12.13
12:58
Или это доп. опция для 7.7 с булевым...?
6 Chum
 
23.12.13
12:58
// тут самое интересное
    Контр = спрКонтр.ТекущийЭлемент();
    // если контрагент существует, то все работает
    // а если нет, то Контр пустой, т.к. элемент не записан
   Попытка
        спрКонтр.Записать();
    Исключение
        Сообщить(ОписаниеОшибки());
    КонецПопытки;
    
    спрКонтр.НайтиЭлемент(Контр);


++++++++++++++++++++++++++++++++

Делай так:

   Попытка
        спрКонтр.Записать();
    Исключение
        Сообщить(ОписаниеОшибки());
Возврат "";
    КонецПопытки;

Возврат спрКонтр.ТекущийЭлемент()
7 Voronve
 
23.12.13
12:58
(0) Тема за V7, код от V8. Код на писан как в V7, это "   Контр = спрКонтр.ТекущийЭлемент();" самое нажористое.
Каашмарр
8 Chum
 
23.12.13
12:59
> Контр = спрКонтр.ТекущийЭлемент();

У тебя элемент еще не записан, ссылки нет, а потом ты пытаешься по хз чему спозиционироваться, хотя этого и не нужно вообще
9 КонецЦикла
 
23.12.13
13:01
(8) Восьмерочник-прикладник, куле
10 vinogradъ
 
23.12.13
13:11
Функция НайтиКонтрагента(ЭлАдрес)        
    спрКонтр = СоздатьОбъект("Справочник.Контрагенты");
    Если спрКонтр.НайтиПоРеквизиту("email", СокрЛП(ЭлАдрес), 1) = Ложь Тогда
        спрКонтр.Новый();
    спрКонтр.Наименование = ЭлАдрес;
    спрКонтр.email = ЭлАдрес;
    спрКонтр.Записать();
    КонецЕсли;    
    Возврат спрКонтр.ТекущийЭлемент();
КонецФункции
11 BalBess
 
23.12.13
13:14
(7) код от V7, кошмар не в этом )
(10) ближе к теме, но мне надо реквизиты переприсвоить даже если элемент существует (адрес, тел и т.д.)
12 BalBess
 
23.12.13
13:14
т.е. заново его сохранить
13 Godofsin
 
23.12.13
13:18
Мля, поясните, с каких пор в 7.7 появилось булево?!
Это 1с++ или как там она называется...
14 BalBess
 
23.12.13
13:18
(13) Истина = 1; Ложь = 0;
15 BalBess
 
23.12.13
13:23
Вкратце фича V7 в том, что если тип поля строковый, то после
НайтиПоРеквизиту()  и Записать() позиционирование элемента теряется.
16 Godofsin
 
23.12.13
13:24
(14) ну и нахера? ))))
17 Voronve
 
23.12.13
13:26
(15) Даладно
18 Ork
 
23.12.13
13:27
(15) С каких ... оно теряется? Это вы его потеряли.

Если НашлиКонтрагента = Ложь Тогда
    спрКонтр.Новый();
КонецЕсли;

спрКонтр.Наименование = ЭлАдрес;
спрКонтр.email = ЭлАдрес;

// тут самое интересное
Контр = спрКонтр.ТекущийЭлемент();

Тут интересно то, что не записав элемент пытаемся получить ТекущийЭлемент(). А потом у них "выборки сбиваются"...
19 BalBess
 
23.12.13
13:28
(17) Да! именно так, сам ох.. удивился
запустите в отладчике, или здесь можно глянуть Запись элемента. Ночь. Не соображаю уже ;)
(16) привык так уже, не суть важно
20 BalBess
 
23.12.13
13:32
(18) уберите это строчку (дело не в ней), после сохранения элемента  - он теряется. почитайте Запись элемента. Ночь. Не соображаю уже ;)
21 1Сергей
 
23.12.13
13:35
да, теряется. делай так:

Контр = спрКонтр.ТекущийЭлемент();
спрКонтр.Записать();
спрКонтр.НайтиЭлемент(Контр);
22 Ork
 
23.12.13
13:36
(20) Может это у вас платформа эксклюзивная? На обычной фокус никуда не девается.
23 Ork
 
23.12.13
13:37
(21) Звиздетц... Еще один. Что у вас будет в Контр перед Записать()?

Классика жанра - записать - получить позицию. А не так, как у вас :
спрКонтр.Записать();
Контр = спрКонтр.ТекущийЭлемент();
И не нужно ничего искать.
24 1Сергей
 
23.12.13
13:40
(23) мде... пустая ссылка, видимо.
Погоди, вспомню как я выкручивался
25 BalBess
 
23.12.13
13:42
(23) в том то и дело, что после спрКонтр.Записать(); выборка теряется!!!

Давайте проще
Есть код
Функция Упрощенная()

   Спр = СоздатьОбъект("Справочник.Номенклатура");
   Спр.НайтиПоРеквизиту("Реквизит",ЗначениеРеквизита,1)); // здесь все находится

   Сообщить(Спр.Выбран()); // здесь возвращается 1 ... элемент выбран ...

   Спр.Записать();        
   Сообщить(Спр.Выбран()); // а после записи - 0 ... уже не выбран ...

   Спр.Записать(); // здесь получаем ошибку, т.к. элемент не выбран ...
   Возврат ??? // как мне вернуть элемент
КонецФункции

(24) очень жду..
26 1Сергей
 
23.12.13
13:43
(23) в форме списка, кажется, есть баг. После строки "спрКонтр.Записать();" в переменной спрКонтр уже будет не новый записанный объект, а пустой.
27 1Сергей
 
23.12.13
13:44
(25) не выборка теряется, а позиционирование. Выборка - это другое
28 Godofsin
 
23.12.13
13:45
(25) Ты проигнорировал (3)?
29 1Сергей
 
23.12.13
13:45
(3), (28) +1

(25) заново ищи по реквизиту
30 BalBess
 
23.12.13
13:46
(26) нас уже двое! ))
(27) я сначала так и писал, просто слово выборка короче ))
31 BalBess
 
23.12.13
13:47
(29) я искал заново, гляньте код (0)
что мне делать, если элемент НЕ найден
32 1Сергей
 
23.12.13
13:48
Вот выборка:

Спр.ВыбратьЭлементы();
Пока Спр.ПолучитьЭлемент() = 1 Цикл
33 1Сергей
 
23.12.13
13:48
(31)

//спрКонтр.НайтиЭлемент(Контр);
спрКонтр.НайтиПоРеквизиту("email", СокрЛП(ЭлАдрес), 1);
34 vinogradъ
 
23.12.13
13:49
Функция НайтиКонтрагента(ЭлАдрес)        
    спрКонтр = СоздатьОбъект("Справочник.Контрагенты");
    Если спрКонтр.НайтиПоРеквизиту("email", СокрЛП(ЭлАдрес), 1) = Ложь Тогда
        спрКонтр.Новый();    
    КонецЕсли;        
    спрКонтр.Наименование = ЭлАдрес;    
    спрКонтр.email = ЭлАдрес;
    Попытка
        спрКонтр.Записать();    
    Исключение
    Сообщить(ОписаниеОшибки());
    КонецПопытки;
    Возврат спрКонтр.ТекущийЭлемент();
КонецФункции
35 BalBess
 
23.12.13
13:52
(34) 1000 раз писал уже, если элемент найден(!!!) , то после
спрКонтр.Записать();  - спрКонтр, становится пустым!!!
36 BalBess
 
23.12.13
13:54
на хрена бы тогда я делал конструкцию
   Контр = спрКонтр.ТекущийЭлемент();
    Попытка
        спрКонтр.Записать();
    Исключение
        Сообщить(ОписаниеОшибки());
    КонецПопытки;
    спрКонтр.НайтиЭлемент(Контр);

только в таком виде это работает!
вопрос, как сделать если элемент не найден
37 Voronve
 
23.12.13
13:57
спрКонтр = СоздатьОбъект("Справочник.Контрагенты");
спрКонтрДубль = СоздатьОбъект("Справочник.Контрагенты");
Если спрКонтр.НайтиПоРеквизиту("email", СокрЛП(ЭлАдрес), 1) = Ложь Тогда
спрКонтрДубль.Новый();
ИНаче
спрКонтрДубль.НАйтиЭлемент(спрКонтр.ТекущийЭлемент());
КОнецЕсли;
......
бла-бла
.....
спрКонтрДубль.Записать();
Сообщить(спрКонтрДубль.Выбран());

Пользуйся
38 vinogradъ
 
23.12.13
14:01
Функция ыыы()
    Спр = СоздатьОбъект("Справочник.Сотрудники");
    Если Спр.НайтиПоРеквизиту("АдресЭлектроннойПочты", "it_aleksei1@xxx", 1) = 0 Тогда
        Спр.Новый();    
    КонецЕсли;          
    Спр.АдресЭлектроннойПочты = "it_aleksei1@xxx";
    Спр.Наименование = "it_aleksei1@xxx";
    Спр.Записать();
    Возврат Спр.ТекущийЭлемент();
КонецФункции
Процедура Сформировать()
    Сообщить(ыыы());                 
КонецПроцедуры

Работает 100% и когда найден и когда не найден
39 1Сергей
 
23.12.13
14:07
(36) см (33)
40 BalBess
 
23.12.13
15:28
(37) - работает, логично: ищем один, сохраняем другой ))
(38) - не работает, 1001 раз, после записи элемента, он становится пустым
(39) - точно!, надо было просто его заново найти (по реквизиту), как и писал (3)
всем спасибо!
41 BalBess
 
23.12.13
15:43
Кстати проверил, повторный поиск элемента по реквизиту, выполняется быстрее, чем (37), и не нужно еще один справочник создавать. В общем остановился на нем.
Требовать и эффективности, и гибкости от одной и той же программы — все равно, что искать очаровательную и скромную жену... по-видимому, нам следует остановиться на чем-то одном из двух. Фредерик Брукс-младший