|
Подскажите оптимальный поиск по справочнику | ☑ | ||
---|---|---|---|---|
0
cube033
23.11.12
✎
12:57
|
Подскажите пожалуйста оптимальный поиск по справочнику
Цель проверить: есть ли в справочнике элемент с определенным наименованием, не являющийся группой. Если такого элемента нет - создать его. Если есть - записать в переменную как объект. Вроде всё просто, но запутавшись в типах данных делал это целый день и пришел к громоздкому коду (работает): Запрос = Новый Запрос; Запрос.Текст = "ВЫБРАТЬ | Здания.Ссылка, | Здания.Наименование |ИЗ | Справочник.КВП_Здания КАК Здания |ГДЕ | НЕ Здания.ЭтоГруппа | И Здания.Наименование = &АдресСД"; Запрос.УстановитьПараметр("АдресСД",АдресСД); ВыборкаЗдания = Запрос.Выполнить().Выгрузить(); Для каждого Строка из ВыборкаЗдания Цикл Попытка СД=Строка[0]; Исключение Сообщить(ОписаниеОшибки()); КонецПопытки; КонецЦикла; ............................................. НовоеЗдание=СД.ПолучитьОбъект(); |
|||
1
Нуф-Нуф
23.11.12
✎
12:59
|
ухтыепт
|
|||
2
kosts
23.11.12
✎
12:59
|
(0) А зачем попытка?
|
|||
3
Нуф-Нуф
23.11.12
✎
12:59
|
кури ПОДОБНО
|
|||
4
cube033
23.11.12
✎
12:59
|
Попытка осталась со времён, когда код не работал)
|
|||
5
kosts
23.11.12
✎
13:00
|
В запрос можно добавить "Первые 1"
|
|||
6
cube033
23.11.12
✎
13:01
|
Да хотелось бы вообще без запроса
|
|||
7
zbv
23.11.12
✎
13:01
|
ВыборкаЗдания = Запрос.Выполнить().Выбрать();
Если ВыборкаЗдания.Следующий() тогда // по идее надо еще расмотреть ситуацию когда есть несколько позиций с одинаковым наименованием. НовоеЗдание = ВыборкаЗдания.Ссылка.ПолучитьОбъект(); Иначе // тут создаем новый элемент. КонецЕсли; |
|||
8
cube033
23.11.12
✎
13:01
|
Типа НайденныеСтроки = ТаблицаДокумента_АРМ_ЛС.НайтиСтроки(Поиск);
|
|||
9
rs_trade
23.11.12
✎
13:01
|
(4) а попытка то не бесплатно работает. таки требует она доп. затрат.
|
|||
10
kosts
23.11.12
✎
13:03
|
(6) А смысл без запроса делать?
|
|||
11
Heckfy
23.11.12
✎
13:04
|
(6)
СправочникМенеджер.<Имя справочника>.НайтиПоРеквизиту (CatalogManager.<Имя справочника>.FindByAttribute) СправочникМенеджер.<Имя справочника> (CatalogManager.<Имя справочника>) НайтиПоРеквизиту (FindByAttribute) Синтаксис: НайтиПоРеквизиту(<ИмяРеквизита>, <ЗначениеРеквизита>, <Родитель>, <Владелец>) Параметры: <ИмяРеквизита> (обязательный) Тип: Строка. Имя реквизита, как он задан в конфигураторе, по значению которого осуществляется поиск. Тип значения произвольный, кроме ХранилищеЗначения и строк произвольной длины. <ЗначениеРеквизита> (обязательный) Тип: Произвольный. Значение реквизита, по которому должен выполняться поиск. <Родитель> (необязательный) Тип: СправочникСсылка. Родитель, в пределах которого нужно выполнять поиск. Если не указан, то поиск будет проводиться во всем справочнике. <Владелец> (необязательный) Тип: СправочникСсылка. Владелец, в пределах которого нужно выполнять поиск. Если не указан, то поиск будет проводиться во всем справочнике. Возвращаемое значение: Тип: СправочникСсылка. Ссылка на найденный элемент справочника. Если не существует ни одного элемента с требуемым значением реквизита, то будет возвращена пустая ссылка. Описание: Осуществляет поиск элемента по значению реквизита. Доступность: Сервер, толстый клиент, внешнее соединение. Примечание: Если существует несколько элементов с указанным значением реквизита, то будет найдет только один из них. Для реквизитов типа Строка поиск осуществляется по точному соответствию. Пример: СтрокаНаименования = "Доллары США"; Валюты = Справочники.Валюты; НайденнаяСсылка = Валюты.НайтиПоРеквизиту("ПолноеНаименование", СтрокаНаименования); Если НайденнаяСсылка = Валюты.ПустаяСсылка() Тогда Сообщить("Валюты """ + СтрокаНаименования + """ еще нет."); Иначе Сообщить("Нашли такую."); КонецЕсли; |
|||
12
Heckfy
23.11.12
✎
13:05
|
Сорри:
СправочникМенеджер.<Имя справочника> (CatalogManager.<Имя справочника>) НайтиПоНаименованию (FindByDescription) Синтаксис: НайтиПоНаименованию(<Наименование>, <ТочноеСоответствие>, <Родитель>, <Владелец>) Параметры: <Наименование> (обязательный) Тип: Строка. Строка, содержащая искомое наименование. <ТочноеСоответствие> (необязательный) Тип: Булево. Определяет режим поиска по полному соответствию. Поиск будет успешным, если строка поиска: в случае значения параметра Ложь - будет соответствовать левой части наименования; в случае значения параметра Истина - будет полностью совпадать с наименованием (за исключением "хвостовых" пробелов в наименовании). Значение по умолчанию: Ложь <Родитель> (необязательный) Тип: СправочникСсылка. Родитель, в пределах которого нужно выполнять поиск. Если не указан, то поиск будет проводиться во всем справочнике. <Владелец> (необязательный) Тип: СправочникСсылка. Владелец, в пределах которого нужно выполнять поиск. Если не указан, то поиск будет проводиться во всем справочнике. Возвращаемое значение: Тип: СправочникСсылка.<Имя справочника>; Неопределено. Ссылка на найденный элемент справочника. Если не существует ни одного элемента с требуемым наименованием, то будет возвращена пустая ссылка. Если для справочника наименование не задано (длина = 0), то будет возвращено Неопределено. Описание: Осуществляет поиск элемента по его наименованию. Доступность: Сервер, толстый клиент, внешнее соединение. Примечание: Если существует несколько элементов с указанным наименованием, то будет найден только один из них. Пример: СтрокаНаименования = "USD"; Валюты = Справочники.Валюты; НайденнаяСсылка = Валюты.НайтиПоНаименованию(СтрокаНаименования); Если НайденнаяСсылка = Валюты.ПустаяСсылка() Тогда Сообщить("Валюты """ + СтрокаНаименования + """ еще нет"); КонецЕсли; |
|||
13
kosts
23.11.12
✎
13:06
|
Сегодня все добрые |
|||
14
cube033
23.11.12
✎
13:06
|
ВыборкаЗдания = Запрос.Выполнить().Выбрать();
Если ВыборкаЗдания.Следующий() тогда Вот на эту конструкцию ругался конфигуратор - мол нет такого метода "следующий". Пока метод был Выбрать, а не выгрузить - вообще не работало Основная беда в типах данных была, что при одинаковом "Выборка=Запрос.Выполнить().Выбрать();" в моём запросе было доступно "Выборка.Получить()", а в другом запросе "Выборка.ПолучитьОбъект()" - не могу понять. |
|||
15
cube033
23.11.12
✎
13:08
|
НайтиПоНаименованию - первое что пробовал, но попадались группы
|
|||
16
kosts
23.11.12
✎
13:10
|
(14) Типы выборок разные
|
|||
17
Alexperumov
23.11.12
✎
13:10
|
(15) Ну добавь отсев по ЭтоГруппа
|
|||
18
cube033
23.11.12
✎
13:14
|
НайтиПоНаименованию(<Наименование>, <ТочноеСоответствие>, <Родитель>, <Владелец>) - не вижу - куда добавить отсев по ЭтоГруппа.
|
|||
19
Heckfy
23.11.12
✎
13:16
|
Поиск=НайтиПоНаименованию(<Наименование>, <ТочноеСоответствие>, <Родитель>, <Владелец>);
Если Поиск.ЭтоГруппа()=Истина Тогда Иначе КонецЕсли; |
|||
20
Reset
23.11.12
✎
13:19
|
(19)
А если есть и группа и элемент с одинаковым наименованием? Тогда уж (если без запроса) СпрМенеджер.Выбрать( с отбором по наименованию и перебирать выборку. Но лучше запросом |
|||
21
cube033
23.11.12
✎
13:19
|
Мне в итоге нужно найти элемент, если он существует, в случае если группа и элемент будут иметь одинаковое наименование - не получиться, так как данный метод находит только первое значение из подобных.
|
|||
22
Heckfy
23.11.12
✎
13:21
|
(20) Запросом по любому лучше эту задачу решать.
|
|||
23
Reset
23.11.12
✎
13:21
|
(22) А я что сказал? :)
|
|||
24
Heckfy
23.11.12
✎
13:22
|
(23) А ТС хочет без запроса. :)
|
|||
25
kosts
23.11.12
✎
13:28
|
Задание такое без запроса, или так хочется?
|
|||
26
cube033
23.11.12
✎
13:31
|
"так хочется" - так как моментов подобных в процедуре встретиться около 5, каждый раз не хочется писать запрос.
Найти по наименованию гораздо короче, к тому же сейчас я указал параметр Истина для "точного поиска" - группы не находит. Не могу понять - почему у меня не работает метод выбрать(), вместо выгрузить() |
|||
27
zbv
23.11.12
✎
13:33
|
(26) код покажи где Выбрать() используешь.
|
|||
28
cube033
23.11.12
✎
13:33
|
вследствие нет метода Следующий() для Выборка. Предлагает ВыбратьСтроку(), ВыбратьКолонку() итд как будто не тот тип переменной
|
|||
29
cube033
23.11.12
✎
13:34
|
Запрос = Новый Запрос;
Запрос.Текст = "ВЫБРАТЬ | Здания.Ссылка, | Здания.Наименование |ИЗ | Справочник.КВП_Здания КАК Здания |ГДЕ | НЕ Здания.ЭтоГруппа | И Здания.Наименование = &АдресСД"; Запрос.УстановитьПараметр("АдресСД",АдресСД); ВыборкаЗдания = Запрос.Выполнить().Выбрать(); |
|||
30
Reset
23.11.12
✎
13:35
|
В (29) не будет говорить (28)
|
|||
31
cube033
23.11.12
✎
13:35
|
Сейчас точнее скажу
|
|||
32
cube033
23.11.12
✎
13:41
|
Вспомнил (точнее попробовал снова)
ВыборкаЗдания = Запрос.Выполнить().Выбрать(); В данном случае ВыборкаЗдания - пустая переменная с правильным типом, при попытке показать значения в отладчике пишет: Наименование - ошибка чтения значения Ссылка - ошибка чтения значения только меняю Выбрать на выполнить - сразу работает |
|||
33
cube033
23.11.12
✎
13:43
|
На счет правильного типа погорячился - тип прочитал не внимательно, но вроде правильный
|
|||
34
kosts
23.11.12
✎
13:44
|
(32) Выборка не позиционирована
|
|||
35
cube033
23.11.12
✎
13:46
|
Не сталкивался. Можно чуть больше теории?
|
|||
36
kosts
23.11.12
✎
13:49
|
(35) Для позиционирования на первой строке можно применить Выборка.Следующий()
|
|||
37
kosts
23.11.12
✎
13:50
|
Синтаксис:
Следующий() Возвращаемое значение: Тип: Булево. Истина - следующая запись выбрана; Ложь - достигнут конец выборки. Описание: Получает следующую запись из результата запроса. Для обхода результата запроса нужно после получения выборки вызвать данный метод для позиционирования на первый элемент и далее вызывать до тех пор, пока не будет возвращено значение Ложь. |
|||
38
cube033
23.11.12
✎
13:55
|
Спасибо всем буду пробовать.
|
Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |