Вход | Регистрация
 
1С:Предприятие :: 1С:Предприятие 7.7 и ранее

v7: Прямой запрос к регистру не срабатывает условие "перечисление.булево.да"

v7: Прямой запрос к регистру не срабатывает условие "перечисление.булево.да"
Я
   torinn
 
28.08.20 - 14:39
ВыбДок = СоздатьОбъект("Документ");
RS = СоздатьОбъект("ODBCRecordset");
RS.УстБД1С();
ТекстЗапроса = "
|
|SELECT
|    Рег.Товар as [Тов $Справочник.ТМЦ],
|    Рег.Склад as [Скл $Справочник.МестаХранения],
|    Рег.КолЕдИзм1Остаток  as Кол
|FROM  
|    $РегистрОстатки.ОперСклады as Рег
|WHERE
|    $Скл.РазрешенаОтгрузка = :ВыбСклад";

RS.УстановитьТекстовыйПараметр("ВыбСклад",Перечисление.Булево.Да);

RS.УстановитьТекстовыйПараметр("ВыбДата", ВыбДатаФорма);
ТЗ = RS.ВыполнитьИнструкцию(ТекстЗапроса);
   torinn
 
1 - 28.08.20 - 14:39
Выдаёт: Meta name parser error: неизвестное метаимя или алиас "$Скл"
   Mikeware
 
2 - 28.08.20 - 14:41
Продолжайте наблюдения.
Ну, или все-так разбенитесь, что вы хотите, и что предлагаете сделать программе...
   torinn
 
3 - 28.08.20 - 14:45
Добавление строки |    Скл.ID as [Элемент $Справочник.МестаХранения],
тоже ни к чему не привело)
   Kesim
 
4 - 28.08.20 - 14:45
(0) не секу в 77, но может быть "ПеречислениЯ....", или просто "Истина"
   torinn
 
5 - 28.08.20 - 14:48
Смысл, в том, чтобы в запрос попадали только те места хранения, у которых реквизит справочника "РазрешенаОтгрузка" был перечислением булево.да
   Kesim
 
6 - 28.08.20 - 14:53
(5) в дереве конфигурации как правильно пишется перечисления или перечисление?
   Mikeware
 
7 - 28.08.20 - 14:54
(5) смысл понятен.
Но программа все-таки не обладает искусственным интеллектом. поэтому попробуйте разъяснить ей, что вы хотит сделать (что из каких таблиц брать, как связаны эти таблицы и т.д.)
   torinn
 
8 - 28.08.20 - 14:54
перечисление
   AAA
 
9 - 28.08.20 - 14:56
Надо в источники запроса (после FROM) добавить справочник складов, связать его по Id c измерением регистра и наложит на этот справочник требуемое условие отбора
   mikecool
 
10 - 28.08.20 - 14:57
ошибка то не в параметре, а в условии
   mikecool
 
11 - 28.08.20 - 14:58
+10 ОШИБКА - Выдаёт: Meta name parser error: неизвестное метаимя или алиас "$Скл"
при чем здесь перечисление в параметре???
   mikecool
 
12 - 28.08.20 - 14:59
намекаю - откуда у тебя $Скл ?
   mikecool
 
13 - 28.08.20 - 15:00
прицепить левым Склады и фильтровать по ним
   AAA
 
14 - 28.08.20 - 15:01
(11)естественно
FROM  
|    $РегистрОстатки.ОперСклады as Рег,
|    $Справочник.Склады as Скл
Откуда бы кй значть что такое у Вас "Скл"
По моему рановато Вам прямые запросы писать
   Mikeware
 
15 - 28.08.20 - 15:01
(13) Не левым, а внутренним. Но это не столь важно. Важно понять, что в регистре нет никакого "Скл"
   Mikeware
 
16 - 28.08.20 - 15:01
(14) начинать никогда не рано.
   AAA
 
17 - 28.08.20 - 15:04
|    $Справочник.МестаХранения as Скл
   mikecool
 
18 - 28.08.20 - 15:14
(15) хрен значет, говорят левое быстрее, понимаю, что условие на правую таблицу даст внутреннее, но вдруг )
   AAA
 
19 - 28.08.20 - 15:19
Левое или внутреннее к данному вопросу не имеет отношения, это ловля блох
   torinn
 
20 - 28.08.20 - 15:32
Спасибо) Переделал вот так: |
|SELECT
|    Рег.Товар as [Тов $Справочник.ТМЦ],
|    Рег.Склад as [Скл $Справочник.МестаХранения],
|    Рег.КолЕдИзм1Остаток  as Кол
|FROM  
|    $РегистрОстатки.ОперСклады as Рег
|    $Справочник.МестаХранения as Скл
|WHERE
|    $Скл.РазрешенаОтгрузка = :ВыбСклад";

RS.УстановитьТекстовыйПараметр("ВыбСклад", Перечисление.Булево.Да);

RS.УстановитьТекстовыйПараметр("ВыбДата", ВыбДатаФорма);
Выдаёт - Неправильный синтаксис около конструкции "sc41" sc41 - справочник "МестаХранения"
   Mikeware
 
21 - 28.08.20 - 15:38
(20) хреново переделал
   Mikeware
 
22 - 28.08.20 - 15:40
попробуй объяснить товарищу/коллеге/начальнику/сотруднику - что ты хочешь, чтоб он сделал ("вместо сервера")
т.е. "возьми из таблицы... содержимое столбцов ... там где ... равно... "
   AAA
 
23 - 28.08.20 - 15:56
Нет запятой в источниках и нет связи по складам )
   torinn
 
24 - 28.08.20 - 16:03
Спасибо, запятую заметил)
   torinn
 
25 - 28.08.20 - 16:08
Спасибо, заработало)
   tgu82
 
26 - 31.08.20 - 12:22
А почему не так:
SELECT
|    Рег.Товар as [Тов],
|    Рег.Склад as [Скл],

Для чего надо as [Тов $Справочник.ТМЦ] ?
Это же итак программе очевидно
   Ёпрст
 
27 - 31.08.20 - 12:24
(26) это нужно вк 1сpp для типизации результата, то что в (26) выведет тебе просто id элементов как есть
   Ёпрст
 
28 - 31.08.20 - 12:25
Ну и.. вместо 1000 слов..
https://www.1cpp.ru/docum/html/ODBC.html
   Salimbek
 
29 - 31.08.20 - 13:24
(20) И что за хрень в итоге ты получаешь, ты хотя бы понимаешь?
   Mikeware
 
30 - 31.08.20 - 13:41
(28) вместо 1000 слов ты предложил ему 10550  :-)
 
 Рекламное место пустует
   Salimbek
 
31 - 31.08.20 - 14:04
(30) Эт точно )))
Товарищу из (20) надо бы просто, сначала, сделать запрос:

|SELECT TOP 10
|    Рег.Товар as Товар,
|    Рег.Склад as Склад,
|    Рег.КолЕдИзм1Остаток  as Кол
|FROM  
|    $РегистрОстатки.ОперСклады as Рег";

И посмотреть на то, что в итоге в табличке получит. А будут там просто ИД-шники.

И на этот ИД-шник никак условие $Скл.РазрешенаОтгрузка = :ВыбСклад не натягивается.

Потом надо сделать запрос

|SELECT TOP 10
|    Спр.Id as Идшник,
|    Спр.Descr as Наименование,
|    $Спр.РазрешенаОтгрузка as Отгрузка,
|FROM  
|    $Справочник.МестаХранения as Спр";

И тоже посмотреть, что вот тут его ИД-шники лежат, и флаги отгрузки.
А затем все это останется соединить. Как и писали автору в (7)

Выбери такие-то поля из Таблицы Рег, соедини ее с таблицей МестаХранения по условию (поле Рег.Склад должно равняться МестаХранения.ИД). В полученной выборке отбери записи, у которых МестаХранения.РазрешенаОтгрузка = чему-то там.

И, кстати, параметры в запросе можно называть как угодно. Не обязательно ставить Перечисление с именем ВыбСклад. Больше подойдет имя флОтгрузка.
В итоге получим:

|SELECT
|    Рег.Товар as [Тов $Справочник.ТМЦ],
|    Рег.Склад as [Скл $Справочник.МестаХранения],
|    Рег.КолЕдИзм1Остаток  as Кол
|FROM  
|    $РегистрОстатки.ОперСклады as Рег INNER JOIN
|    $Справочник.МестаХранения as Скл ON Рег.Склад=Скл.id
|WHERE
|    $Скл.РазрешенаОтгрузка = :флОтгрузка";

RS.УстановитьТекстовыйПараметр("флОтгрузка", Перечисление.Булево.Да);
   tgu82
 
32 - 31.08.20 - 20:54
(31) Все вроде понятно кроме
ON Рег.Склад=Скл.id
   Salimbek
 
33 - 31.08.20 - 23:58
(32) Ну смотри, у тебя из Рег получается табличка:

Товар      | Склад      | КолЕдИзм1Остаток 
ХХХ_ИД_ХХХ | YYY_ИД_YYY | 50


А в справочнике МестаХранения
ID         | Descr               | РазрешенаОтгрузка 
YYY_ИД_YYY | Мой Склад           | _тут_ИД_Перечисления_Да_


На самом деле, поля РазрешенаОтгрузка в SQL-е нет, там что-то типа SP327. И, чтобы можно было указывать человеческое "РазрешенаОтгрузка", разработчики 1с++ сделали такую фишку, что можно перед именем поля указать $ и тогда на этапе подготовки этого запроса, 1С++ сама найдет правильное имя для этого поля и подставит его в запрос. Поэтому к ID мы обращаемся как Скл.id, а к РазрешенаОтгрузка - как $Скл.РазрешенаОтгрузка.

Далее, вот эти таблицы надо связать между собой. Для этого и используется соединение таблиц командой JOIN которому указываем условие связывания Рег.Склад(например, значение "YYY_ИД_YYY")=Скл.ID(тот же "YYY_ИД_YYY") Получается такая табличка:

Рег.Товар  | Рег.Склад  | Рег.Кол... | Скл.ID     | Скл.Descr           | $Скл.РазрешенаОтгрузка
ХХХ_ИД_ХХХ | YYY_ИД_YYY | 50         | YYY_ИД_YYY | Мой Склад           | _тут_ИД_Перечисления_Да_


И вот для этой таблички мы уже ставим условие:
$Скл.РазрешенаОтгрузка = :флОтгрузка
Если надо будет добавить условие на Товар, или какие-то дополнительные поля товара вытащить, то, аналогично, добавляем связывание JOIN к таблице Справочник.ТМЦ с условием Рег.Товар(ХХХ_ИД_ХХХ)=ТМЦ.ID(ХХХ_ИД_ХХХ)

Отдельно замечу, что SQL-ю, в общем-то, пофиг, что и с чем связывать, так что ему вполне можно дать команду
|    $РегистрОстатки.ОперСклады as Рег INNER JOIN
|    $Справочник.МестаХранения as Скл ON Рег.Товар=Скл.id  //<-- тут ошибочно связали ИД от Склада к ИД Товара
В итоге получится мусор, но код отработает без проблем. Поэтому надо внимательно смотреть, что и с чем соединяется.

Поэтому и претензия к именованию переменных, т.к. условие идет на флаг "РазрешенаОтгрузка", а имя переменной ВыбСклад. Можно легко запутаться. Особенно если запросы километровой длинны.
   Mikeware
 
34 - 01.09.20 - 08:03
(32) см.(22)
   tgu82
 
35 - 01.09.20 - 09:53
(34) ДА, спасибо!
А вот это что: SELECT A.* в SQL-запросе ?
Я помню давно из работы с фокспро
select поля from базы затем если баз несколько то какие-то варианты их соединения
затем where и т.д.
А.* это все поля из таблицы А что ли?
   tgu82
 
36 - 01.09.20 - 10:03
(35)+ Спасибо. Разобрался вроде. Теперь бы еще разобраться как имена 1С в запросе получаются через $
   Mikeware
 
37 - 01.09.20 - 10:13
(35) Да, это все поля из таблицы А
   Mikeware
 
38 - 01.09.20 - 10:23
(36) Всё очень просто:
Сказки-обман!©
:-)

В таблицах 1с поля именуются особым образом: есть предопределенные имена (id, iddoc, descr, deleted, и т.п.) (которым соотвествуют внутренние идентификаторы, или типовые поля - наименование, удален, проведен, дата, и т.п.), а есть добавленные реквизиты, которые в таблице имеют имя SP*****, а в 1с - то, ктоторое им дал разработчик.
к первым образаются напрямую - Журнал.isMark, СправочникНоменклатура.id
ко вторым можно тоже обращаться напрямую, посмотрев соотвествия в dd/dds (т.е. Журнал.SP1234), а можно поручить разыменовывание имен 1с во внутренние имена полей препроцессору 1с++, и написать $Журнал.МойРеквизит
   torinn
 
39 - 01.09.20 - 12:02
Спсасибо всем. Работает.
   torinn
 
40 - 01.09.20 - 12:02
Процедура Сформировать()
    ТЗ=СоздатьОбъект("ТаблицаЗначений");
    ВыбДок = СоздатьОбъект("Документ");
    Если СокрЛП(ВыбТовар) = "" Тогда
        ДопУсловие ="(Товар <> '')";
    Иначе 
        ДопУсловие ="(Товар = :ВыбТовар)";
    КонецЕсли;
    Если СокрЛП(ВыбСклад) = "" Тогда
        ДопУсловие2 ="(Склад <> '')";
    Иначе 
        ДопУсловие2 ="(Склад = :ВыбСклад)";
    КонецЕсли;  
    Если СокрЛП(ВыбГрузополучатель) = "" Тогда
        ДопУсловие3 ="(Заказ <> '')";
    Иначе 
        ДопУсловие3 ="($Зак.Заказчик = :ВыбГрузополучатель)";
    КонецЕсли;
    
    RS = СоздатьОбъект("ODBCRecordset");
    RS.УстБД1С();
    ТекстЗапроса = " 
    |SELECT 
    |    Рег.Товар as [Тов $Справочник.ТМЦ],
    |    Рег.Склад as [Скл $Справочник.МестаХранения],
    |    Рег.Заказ as [Зак $Справочник.Заказы],
    |    Рег.КолЕдИзм1Остаток  as Кол
    |FROM  
    |    $РегистрОстатки.ОперСклады as Рег
    | INNER JOIN
    |    $Справочник.ТМЦ as Тов ON Рег.Товар=Тов.id
    |INNER JOIN
    |    $Справочник.МестаХранения as Скл ON Рег.Склад=Скл.id
    | INNER JOIN
    |    $Справочник.Заказы as Зак ON Рег.Заказ=Зак.id
    |WHERE
    |    ($Скл.РазрешенаОтгрузка = :флОтгрузка) AND "+ДопУсловие+" AND "+ДопУсловие2+" AND "+ДопУсловие3+"      "; 
    RS.УстановитьТекстовыйПараметр("флОтгрузка", Перечисление.Булево.Да);
    RS.УстановитьТекстовыйПараметр("ВыбТовар", ВыбТовар);   
    RS.УстановитьТекстовыйПараметр("ВыбСклад", ВыбСклад);
    RS.УстановитьТекстовыйПараметр("ВыбГрузополучатель", ВыбГрузополучатель);   
    ТЗ = RS.ВыполнитьИнструкцию(ТекстЗапроса);
    ТЗ.ВыбратьСтроки();
    Пока ТЗ.ПолучитьСтроку() = 1 Цикл
        й=1; 
    КонецЦикла;  
КонецПроцедуры
   Ёпрст
 
41 - 01.09.20 - 12:06
Товар <> '' ...это пять
   Ёпрст
 
42 - 01.09.20 - 12:08
И как бэ..соединение лишние
 INNER JOIN
    |    $Справочник.ТМЦ as Тов ON Рег.Товар=Тов.id
   Ёпрст
 
43 - 01.09.20 - 12:23
(40) и это...смотри параметры виртуальной таблицы Остатки и накладывай фильтры туда + либо вообще не добавляй условий в текст запроса (свои +Допусловия)

или хотя бы так  where 1=1 and 2=2 ....Текст запроса = СтрЗаменить(ТекстЗапроса,"1=1","$Рег.Вася=:Федя")
   Mikeware
 
44 - 01.09.20 - 12:33
(43) как сформировать текст запроса - это вторично.
Я вот не уверен, что он представляет себе, что и зачем он пишет...
хотя в принципе, так тоже можно - "программировать, не приходя в сознание"
   Андрей_Андреич
 
45 - 01.09.20 - 12:42
(43) А правильно все фильтры накладывать "внутри" виртуальной таблицы?
   Mikeware
 
46 - 01.09.20 - 12:46
(45) Ну так меньше остатков-оборотов отберется, быстрее суммируется,  меньше результирующая табличка
   Андрей_Андреич
 
47 - 01.09.20 - 12:48
(46) Так и думал а то разнервичался - вдруг столько лет фигней страдал
   Mikeware
 
48 - 01.09.20 - 12:55
(47) зато я вот задумался - а могут ли "внутренние" фильтры ухудшить работу по сравнению с "внешними".
Вспомнил, что был один какой-то старый (лет 10 или больше назад) случай -с фильтрами внутри запрос вообще не работал. С наружными отрабатывался на ура. Трассировка в 1CQA клала систему. Спрашивал у кого-то из гуру, типа DmitrO или Садовникова, но им некогда было. в общем, забил.
   Sserj
 
49 - 01.09.20 - 13:19
(48) Да легко могут. Если для фильтра нужно произвести несколько соединений то они будут проводиться с допустим десятком тысяч строк движений.
А после свертки это будет соединение с допустим сотнями или даже десятками. А если уж там что-то не попадающее в индекс при соединении будет то вообще туши свет.
   Sserj
 
50 - 01.09.20 - 13:23
+(49) К примеру практически всегда отобрать остатки нужной группы быстрее получив все итоги и потом уже их соединять с номенклатурой и отбирать по группам.
   Ёпрст
 
51 - 01.09.20 - 13:26
(48) если писать без вт Остатки\ОститкиИОбороты , а всё руками, как в дбф, то там таких проблем не возникает :)
   trad
 
52 - 01.09.20 - 13:29
(48) я тебе больше скажу, в некоторых случаях "внешние" фильтры могут стать "внутренними". Оптимизатор такое может
   Mikeware
 
53 - 01.09.20 - 13:36
(51) (52) как говаривал Голд, "ненавижу умные компиляторы"©
(49) попадание в индексы - отдельная тема. а отношение количества к вариабельности - да, тут что-то есть...


Список тем форума
Рекламное место пустует  Рекламное место пустует
ВНИМАНИЕ! Если вы потеряли окно ввода сообщения, нажмите Ctrl-F5 или Ctrl-R или кнопку "Обновить" в браузере.