Имя: Пароль:
1C
1C 7.7
v7: 1sqlite и отбор по полю справочника с типом "Справочник"
0 ildary
 
31.10.14
10:50
Уважаемые специалисты, подскажите пожалуйста, как в 1sqlite правильно отфильтровать элементы по значению полю, если его тип - Справочник?

SELECT
  id          [ЭлементСпр :Справочник.Свойства],
  Спр.Элемент [Элемент $Справочник]
FROM
  [Справочник.Свойства] Спр
WHERE ( ismark <> '*' ) AND ( Спр.Элемент IN (select val from СпсЭлементы ) )

Если убрать строку, то выводятся все, с этой строкой - выводитс пустая ТЗ. В списке 0 элемент типа Справочник.Контрагенты.
1 ildary
 
31.10.14
10:52
+(0) ... если убрать строку "AND ( Спр.Элемент IN (select val from СпсЭлементы ) )"
2 orefkov
 
31.10.14
10:59
А СпсЭлементы как делается?
3 ildary
 
31.10.14
11:01
Примерно вот так (код для теста, в реальности по коду я не собираю):

СпрКонтр = СоздатьОбъект( "Справочник.Контрагенты" );
СпрКонтр.НайтиПоКоду( КодКонтр );
СпсЭлементы.ДобавитьЗначение( СпрКонтр.ТекущийЭлемент() );
4 orefkov
 
31.10.14
11:03
Скорее всего ты список делал через УложитьОбъекты, а он 9символьное значение кладет. А надо - 13символьное, у тебя поле Справочник без вида. Создавай список через УложитьТЗ, сделав колонку типа "Справочник", также без указания вида.
5 Ёпрст
 
гуру
31.10.14
11:03
right(Спр.Элемент,9)in ...
6 orefkov
 
31.10.14
11:05
(5)
Ай-я-я-яй, не надо так, серпом по яйцам.
Справочники - не документы, на уровне айдишников не уникальны. Может прихватить справочник другого вида.
7 Ёпрст
 
гуру
31.10.14
11:06
(6) :)
уговорил

where left(Спр.Элемент,4)=:ВидСправочника.Контрагенты and right(Спр.Элемент,9)in ...
8 ildary
 
31.10.14
11:07
(4) делаю вот так:
база.УложитьОбъекты( СпсЭлементы, "СпсЭлементы ", 0, "Контрагенты" );
а правльно надо вот так?
база.УложитьОбъекты( СпсЭлементы, "СпсЭлементы ", 0 );
9 Ёпрст
 
гуру
31.10.14
11:07
(8) нет
10 ildary
 
31.10.14
11:07
Уважаемые гуру я низко кланяюсь Вам обоим, но скажите пожалуйста, какой способ лучше?
11 Ёпрст
 
гуру
31.10.14
11:08
С ТЗ - не самое удачное решение будет - иерархия не построится.
12 Ёпрст
 
гуру
31.10.14
11:08
(10) как в (7) вполне годный способ
13 Ёпрст
 
гуру
31.10.14
11:08
а лучше преписать на оледб, если скорость интересует :)
14 ildary
 
31.10.14
11:08
(11) А где здесь ТЗ, кроме возвращаемого результата?
15 Ёпрст
 
гуру
31.10.14
11:09
(14) см (4)
16 Ёпрст
 
гуру
31.10.14
11:10
И это, поиск по коду зачем нужен ?
Неужели с оле базы тащишь данные ?
Не ?
17 ildary
 
31.10.14
11:12
(13) скорость конечно интересует, но 1sqlite нравится кучей плюшек и уже написанной процедурой формирования текста запроса, которой на вход подаются поля, условия отбора. Жалко будет её бросать.

(15) я правильно понимаю, что проще заменить "( Спр.Элемент IN (select val from СпсЭлементы ) )" на "where left(Спр.Элемент,4)=:ВидСправочника.Контрагенты and right(Спр.Элемент,9)in ."?

(16) поиск по коду - только для наглядности примера, чтобы показать, что в списке значений - правильные данные. В реальности список значений заполняется по другому.
18 Ёпрст
 
гуру
31.10.14
11:15
(17)
2.да
19 Ёпрст
 
гуру
31.10.14
11:15
только дописать еще ин (селект вал фром список)
20 Ёпрст
 
гуру
31.10.14
11:18
Но, если в фильтре только элементы (без групп), то можно и как в (4) попробовать - создать ТЗ с одной колонкой, запихать туда элементы, тип колонки выставить справочник и УложитьТЗ.
в тексте запроса - фильтр по этой ТЗ делать, без всяких проверок на вид и right/left
21 ildary
 
31.10.14
11:18
Сделал вот так:
SELECT
  id          [ЭлементСпр :Справочник.Свойства],
  Спр.Элемент [Элемент $Справочник]
FROM
  [Справочник.Свойства] Спр
WHERE ( ismark <> '*' ) AND ( ( left(Спр.Элемент,4)=:ВидСправочника.Контрагенты ) and ( right(Спр.Элемент,9) in (select val from СпсЭлементы ) ) )

ругается на скобку (
при этом все скобки на своих местах, ничего не понимаю
22 orefkov
 
31.10.14
11:21
WHERE ( ismark <> '*' ) AND ( Спр.Элемент IN (select :ВидСправочника.Контрагенты || val from СпсЭлементы ) )

Так лучше всего :)
23 Ёпрст
 
гуру
31.10.14
11:42
(22) ага, че то сам стал подзабывать синтаксис
24 ildary
 
31.10.14
11:50
Большое сердечное спасибо волшебникам, вразумили неразумного
25 ildary
 
31.10.14
12:08
Заодно хотел бы спросить гуру, а как правильно в этом же запросе сделать отбор по всем элементам определенного вида справочника, например. чтобы все элементы типа Справочник.Контрагенты.
26 Ёпрст
 
гуру
31.10.14
12:25
(25) ну ставь фильтр на вид спроавочника
27 ildary
 
31.10.14
12:33
(26) не умею, гуглил, не нашел.
28 Ёпрст
 
гуру
31.10.14
12:35
left(Спр.Элемент,4)=:ВидСправочника.Контрагенты
29 Ёпрст
 
гуру
31.10.14
12:35
отберет тебе все элементы, где в реквизите только клиентосы..
30 ildary
 
31.10.14
12:40
SELECT
id          [ЭлементСпр :Справочник.Свойства],
Спр.Элемент [Элемент $Справочник]
FROM
[Справочник.Свойства] Спр
WHERE ( ismark <> '*' ) AND ( left(Спр.Элемент,4)=:ВидСправочника.Контрагенты )  

{Глобальный модуль(62991)}: near "(": syntax error
31 Ёпрст
 
гуру
31.10.14
12:42
запрос.Отладка(1) че кажет ?
32 ildary
 
31.10.14
12:46
ничего не выдает, только эту ошибку (другие запросы 1sqlite выдают кучу инфы).
33 Ёпрст
 
гуру
31.10.14
12:59
та ну ?
34 Ёпрст
 
гуру
31.10.14
12:59
полный текст сообщения из Запрос.Отладка(1) покажи
35 ildary
 
31.10.14
13:06
Мамой клянусь - ничего не показывает, кроме ошибки "near "(": syntax error", если же запустить любой другой запрос - выдает кучу отладочной инфы.
36 Ёпрст
 
гуру
31.10.14
13:06
не верю.
37 Ёпрст
 
гуру
31.10.14
13:07
покажи тогда весь код. Ты это где всё пишешь хоть ? В консоли ? Или так, руками код написал ?
38 ildary
 
31.10.14
13:11
процедура формирует код и вызывает Запрос.ВыполнитьЗапрос( ТекстЗапроса );

то, что передается в ТекстЗапроса я описал в (30), если перед Запрос.ВыполнитьЗапрос( ТекстЗапроса ) вызвать запрос.Отладка(1) - то никакой инфы не выводится (кроме ошибки)
39 ildary
 
31.10.14
13:11
+(38) процедура генерирует текст запроса
40 Ёпрст
 
гуру
31.10.14
13:12
Сообщить (текстЗапроса)
41 Ёпрст
 
гуру
31.10.14
13:12
чего там ?
42 Ёпрст
 
гуру
31.10.14
13:13
Ну или Предупреждение(ТекстЗапроса) если он большой
43 Ёпрст
 
гуру
31.10.14
13:15
и это? 1sqlite.dll какой версии хоть ?
44 ildary
 
31.10.14
13:19
(43) версия 1sqlite.dll: 1.0.2.4
текст запроса:
SELECT
id          [ЭлементСпр :Справочник.Свойства],
Спр.Элемент [Элемент $Справочник]
FROM
[Справочник.Свойства] Спр
WHERE ( ismark <> '*' ) AND ( left(Спр.Элемент,4)=:ВидСправочника.Контрагенты )
45 ildary
 
31.10.14
13:20
+ хочу напомнить - Элемент - типа нетипизированный Справочник
46 Ёпрст
 
гуру
31.10.14
13:21
ну а так че ?
SELECT
id [ЭлементСпр :Справочник.Свойства],
Спр.Элемент [Элемент $Справочник]
FROM [Справочник.Свойства] Спр
WHERE ismark <> '*' AND left(Спр.Элемент,4)=:ВидСправочника.Контрагенты
47 ildary
 
31.10.14
13:29
а это точно скобки мешают? Я их наоборот ставлю для правильности вычисления булевых.
48 ildary
 
31.10.14
13:44
+(47) попробовал именно так - остается та же ошибка
49 Ёпрст
 
гуру
31.10.14
13:46
(48) чудес на свете не бывает - ты выпоняешь другой запрос в другом месте.
50 Ёпрст
 
гуру
31.10.14
13:48
ну, вот так есть че ?

SELECT
id [ЭлементСпр :Справочник.Свойства],
Спр.Элемент [Элемент :Справочник]
FROM [Справочник.Свойства] Спр

WHERE ismark <> '*' AND Спр.Элемент like ':ВидСправочника.Контрагенты%'
51 ildary
 
31.10.14
13:55
так ошибку не выдает, но возвращает пустую таблицу
52 ildary
 
31.10.14
13:56
Отладка выдает вот такую строку:
SELECT id [ЭлементСпр :Справочник.Свойства], Спр.Элемент [Элемент $Справочник] FROM [Справочник.Свойства] Спр WHERE ismark <> '*' AND Спр.Элемент like ':ВидСправочника.Контрагенты%'  
Подбор индекса для таблицы SC8815:
    Ограничения:
    Найдено в кэше
    Индекс не выбран.
    Стоимость: 9986
53 orefkov
 
31.10.14
14:12
(48)
Чтобы найти ошибку, убери сначала все условия, включая слово "where", и потом добавляй по одному - вычислишь, на чем ломается.
Что кстати выдает в отладке и в результате простого запроса
select :ВидСправочника.Контрагенты
?
(50)
Спр.Элемент like :ВидСправочника.Контрагенты || '%'
54 orefkov
 
31.10.14
14:17
Если по полю Спр.Элемент есть сортировка/отбор, то лучший вариант
Спр.Элемент between :ВидСправочника.Контрагенты and :ВидСправочника.Контрагенты || 'ZZZZZZZZZ'

попадет в индекс.
55 Ёпрст
 
гуру
31.10.14
14:25
хитро с битвином..
а с лайк разве не попадёт ?
56 ildary
 
31.10.14
14:31
(53) отладка возвращает select '  4S', сам запрос возвращает ТЗ с таким же значением.

Если убрать Where, то запрос возвращает ТЗ с любыми значениями поля "Элемент" - то есть любого вида.
Если сделать WHERE Спр.Элемент like ':ВидСправочника.Контрагенты%' - возвращает пустую таблицу.
Если сделать WHERE left(Спр.Элемент,4)=:ВидСправочника.Контрагенты
то выдает ошибку: near "(": syntax error
и отладчик выдает:
SELECT
id [ЭлементСпр :Справочник.Свойства],
Спр.Элемент [Элемент $Справочник]
FROM [Справочник.Свойства] Спр
WHERE left(Спр.Элемент,4)='  4S'
57 Ёпрст
 
гуру
31.10.14
14:32
а так ?

WHERE Спр.Элемент like ':ВидСправочника.Контрагенты||%'
58 ildary
 
31.10.14
14:43
В общем метод с (54) прекрасно заработал (у поля Элемент был включен отбор! Большое спасибо за помощь!!!
Оптимист верит, что мы живем в лучшем из миров. Пессимист боится, что так оно и есть.