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

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

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

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

RS.УстановитьТекстовыйПараметр("ВыбДата", ВыбДатаФорма);
Выдаёт - Неправильный синтаксис около конструкции "sc41" sc41 - справочник "МестаХранения"
21 Mikeware
 
28.08.20
15:38
(20) хреново переделал
22 Mikeware
 
28.08.20
15:40
попробуй объяснить товарищу/коллеге/начальнику/сотруднику - что ты хочешь, чтоб он сделал ("вместо сервера")
т.е. "возьми из таблицы... содержимое столбцов ... там где ... равно... "
23 AAA
 
28.08.20
15:56
Нет запятой в источниках и нет связи по складам )
24 torinn
 
28.08.20
16:03
Спасибо, запятую заметил)
25 torinn
 
28.08.20
16:08
Спасибо, заработало)
26 tgu82
 
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
29 Salimbek
 
31.08.20
13:24
(20) И что за хрень в итоге ты получаешь, ты хотя бы понимаешь?
30 Mikeware
 
31.08.20
13:41
(28) вместо 1000 слов ты предложил ему 10550  :-)
31 Salimbek
 
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.УстановитьТекстовыйПараметр("флОтгрузка", Перечисление.Булево.Да);
32 tgu82
 
31.08.20
20:54
(31) Все вроде понятно кроме
ON Рег.Склад=Скл.id
33 Salimbek
 
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  //<-- тут ошибочно связали ИД от Склада к ИД Товара
В итоге получится мусор, но код отработает без проблем. Поэтому надо внимательно смотреть, что и с чем соединяется.

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

В таблицах 1с поля именуются особым образом: есть предопределенные имена (id, iddoc, descr, deleted, и т.п.) (которым соотвествуют внутренние идентификаторы, или типовые поля - наименование, удален, проведен, дата, и т.п.), а есть добавленные реквизиты, которые в таблице имеют имя SP*****, а в 1с - то, ктоторое им дал разработчик.
к первым образаются напрямую - Журнал.isMark, СправочникНоменклатура.id
ко вторым можно тоже обращаться напрямую, посмотрев соотвествия в dd/dds (т.е. Журнал.SP1234), а можно поручить разыменовывание имен 1с во внутренние имена полей препроцессору 1с++, и написать $Журнал.МойРеквизит
39 torinn
 
01.09.20
12:02
Спсасибо всем. Работает.
40 torinn
 
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","$Рег.Вася=:Федя")
44 Mikeware
 
01.09.20
12:33
(43) как сформировать текст запроса - это вторично.
Я вот не уверен, что он представляет себе, что и зачем он пишет...
хотя в принципе, так тоже можно - "программировать, не приходя в сознание"
45 Андрей_Андреич
 
naïve
01.09.20
12:42
(43) А правильно все фильтры накладывать "внутри" виртуальной таблицы?
46 Mikeware
 
01.09.20
12:46
(45) Ну так меньше остатков-оборотов отберется, быстрее суммируется,  меньше результирующая табличка
47 Андрей_Андреич
 
naïve
01.09.20
12:48
(46) Так и думал а то разнервичался - вдруг столько лет фигней страдал
48 Mikeware
 
01.09.20
12:55
(47) зато я вот задумался - а могут ли "внутренние" фильтры ухудшить работу по сравнению с "внешними".
Вспомнил, что был один какой-то старый (лет 10 или больше назад) случай -с фильтрами внутри запрос вообще не работал. С наружными отрабатывался на ура. Трассировка в 1CQA клала систему. Спрашивал у кого-то из гуру, типа DmitrO или Садовникова, но им некогда было. в общем, забил.
49 Sserj
 
01.09.20
13:19
(48) Да легко могут. Если для фильтра нужно произвести несколько соединений то они будут проводиться с допустим десятком тысяч строк движений.
А после свертки это будет соединение с допустим сотнями или даже десятками. А если уж там что-то не попадающее в индекс при соединении будет то вообще туши свет.
50 Sserj
 
01.09.20
13:23
+(49) К примеру практически всегда отобрать остатки нужной группы быстрее получив все итоги и потом уже их соединять с номенклатурой и отбирать по группам.
51 Ёпрст
 
01.09.20
13:26
(48) если писать без вт Остатки\ОститкиИОбороты , а всё руками, как в дбф, то там таких проблем не возникает :)
52 trad
 
01.09.20
13:29
(48) я тебе больше скажу, в некоторых случаях "внешние" фильтры могут стать "внутренними". Оптимизатор такое может
53 Mikeware
 
01.09.20
13:36
(51) (52) как говаривал Голд, "ненавижу умные компиляторы"©
(49) попадание в индексы - отдельная тема. а отношение количества к вариабельности - да, тут что-то есть...