Всем привет. Вылез совершенно непонятный баг.
Запрос

```1c
    ВЫБРАТЬ Остатки.Номенклатура КАК Товар, Остатки.Номенклатура.СтавкаНДС КАК СтавкаНДС,
    Остатки.Номенклатура.Артикул КАК Артикул,
    Остатки.Номенклатура.ВесЧислитель КАК Вес, Остатки.Номенклатура.ВесЕдиницаИзмерения КАК ЕдиницаИзмерения,
    Остатки.Склад КАК Склад, Остатки.Склад.ДополнительныеРеквизиты.(Значение) КАК Приоритет, // !!!!!!!!!!!!!!!!!!!!
    Остатки.ВНаличииОстаток-Остатки.ВРезервеСоСкладаОстаток-Остатки.ВРезервеПодЗаказОстаток КАК Остаток
    ,ВЫБОР Когда Цены.Цена ЕСТЬ NULL Тогда 0 ИНАЧЕ Цены.Цена КОНЕЦ Как Цена
    ИЗ РегистрНакопления.СвободныеОстатки.Остатки(&ВыбДата) КАК Остатки
    СОЕДИНЕНИЕ РегистрСведений.ЦеныНоменклатуры.СрезПоследних КАК Цены ПО Цены.Номенклатура=Остатки.Номенклатура
    ГДЕ Остатки.Склад.ДополнительныеРеквизиты.Свойство = &СкладИМ И
    Остатки.Склад.ДополнительныеРеквизиты.Значение >= 0 И
    НЕ Остатки.Номенклатура.ЭтоГруппа И Остатки.Номенклатура.ВидНоменклатуры = &ВидТоварИМ И
    Цены.ВидЦены = &ЦенаРозница
    УПОРЯДОЧИТЬ ПО Товар
```

выполненный в консоли разработчика дает совершенно нормальные результаты, в том числе выделенный реквизит в гриде отображается числами (1 или 2), но в доп.обработке вот этим кодом

```1c
    Остатки = ОстаткиНаСкладах.Добавить();
    Остатки.ИдентификаторИМ = Набор.ИдентификаторИМ;
    Остатки.Товар1С = Выборка.Товар;
    Остатки.Склад = Выборка.Склад;
    Остатки.Приоритет = Выборка.Приоритет; // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    Остатки.Остаток = Выборка.Остаток;
```

выделенный реквизит ТЗ получает значение 0. Есть подозрение, что не верно выбран тип реквизита Приоритет в ТЗ ОстаткиНаСкладах (сейчас это Число). Подсмотреть тип в консоли разработчика не получается. Смутно помню, что и реквизит формы типа Таблица значений, созданный в дизайн-тайме совершенно не то же самое, что получается в реал-тайме вот этим кодом

```1c
    ПозицииЗаказа = Новый ТаблицаЗначений;
```

Подскажите, пожалуйста, в чем причина на самом деле. Что сделать, чтобы реквизит Приоритет принимал значения 1 или 2?
---
Я предлагаю иную конструкцию:

```1c
    ВЫБРАТЬ
    ...
    ЕСТЬNULL(СвойствоПриоритет.Значение, 0) КАК Приоритет
    ...
    ИЗ
    ...Остатки
    ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Склады.ДополнительныеРеквизиты КАК СвойствоПриоритет
    ПО Остатки.Склад = СвойствоПриоритет.Ссылка
    И СвойствоПриоритет.Свойство = &Приоритет
```
---
Остатки.Склад.ДополнительныеРеквизиты.(Значение) КАК ПриоритетНе знаю особенностей отображения значений в Консоли разработчика, но такое поле после выполнения запроса в выборке будет иметь тип значения "РезультатЗапроса". Фактически такой конструкцией Вы получаете таблицу, состоящую из строк табличной части "ДополнительныеРеквизиты" (все строки, что есть) и одной колонки "Значение". Т.е. это не просто число.

Упростите конструкцию. Присоедините табличную часть "ДополнительныеРеквизиты" левым соединением к основной таблице, связав их по складу, а также, по хорошему, установив ограничения по полю "Свойство" на случай, если дополнительных реквизитов у склада в будущем окажется больше одного. А в качестве "Приоритета" выберите поле "Значение" уже из присоединенной таблицы.
---
Изначально было
Остатки.Склад.ДополнительныеРеквизиты.Значение КАК Приоритет
Т.е. получается, что возвращается в этом поле некий датасет из одной строки и одного поля для каждой из строк запроса.
То, что одна строка и одно поле - 100%, но как сие засунуть в тип Число?
---
но как сие засунуть в тип ЧислоЕсли говорить грубо, то нужно сократить количество точке в выражении.
---
Извините, но условие в запросе (указанием параметра)

```1c
    Остатки.Склад.ДополнительныеРеквизиты.Свойство = &СкладИМ
```

Отсекает все остальные дополнительные реквизиты, кроме одного... Да там их всего один.
Не совсем понимаю чем поможет это

```1c
    ...
    Склады.ДополнительныеРеквизиты.Значение КАК Приоритет
    ....
    ЛЕВОЕ СОЕДИНЕНИЕ Справочники.Склады КАК Склады ПО Склады.Ссылка = Остатки.Склад.Ссылка
    ...
    ГДЕ
    ...
    Склады.ДополнительныеРеквизиты.Свойство = &СкладИМ
```
---
Отсекает все остальные дополнительные реквизиты, кроме одного...Не понял, какие реквизиты условие отсекает, если их всего один? :-)
---
Ну мало ли потом еще понадобится родить доп.реквизит... Корректно же код нужно стараться писать сразу.
---
Не понимаю тогда, что именно Вы хотите получить в результате запроса под псевдонимом "Приоритет". Коллекцию значений всех возможных дополнительных реквизитов?
---
Все просто. Я получаю остатки номенклатуры по складам, но при этом мне нужно иметь приоритет склада. Их всего три - 0,1 и 2. Товары со складов с допреквизитом (Свойство = СкладИМ) = 0 вообще в выборку не попадают. В момент обработки заказа нужно резервировать товар в приоритеттном рассмотрении складов. Т.е. Остатки отсортированы по Товар, Склад, Приоритет Убыв. Т.е. первым нужный товар на остатках будет со склада с 2-кой. Если остатков не хватит, то следующий остаток товара, если он есть, будет с приоритетом 1. Не будет вообще достаточного кол-ва на отдельном складе - товар не будет зарезервирован - бухгалтер оформит перевод части товара на нужный склад и проведет заказ.
---
Рассмотрите пример в (8)
---
Не совсем понял предлагаемый джойн...
Вы хотите сказать, что СвойствоПриоритет.Ссылка есть Справочник.Склады? Допустим, но
Зачем мне сие - ЕСТЬNULL(СвойствоПриоритет.Значение, 0) КАК Приоритет ?
Просто привести НУЛЛ к 0? Это у меня делается потом при обработке Выборка.
Я попробую конечно, но ... решение какое-то не очень убедительно звучит.
---
Таблица "Справочник.Склады.ДополнительныеРеквизиты" в БД хранит строки всех табличных частей всех элементов справочника, т.е. всех складов. Чтобы понимать, какие строки в этой таблице БД принадлежат какому из складов, используется поле "Ссылка". Для каждого элемента справочника "Склады" ссылка уникальна. Соответственно по значению поля "Ссылка" в таблице "Справочник.Склады.ДополнительныеРеквизиты" можно однозначно судить, какому складу принадлежат те или иные строки.

Поэтому то мы и связываем поле "Склад" таблицы остатков с полем "Ссылка" табличной части.

Функция ЕСТЬNULL используется для того, чтобы однозначно получить в результате число. Бывают ситуации, когда записи в табличной части "ДополнительныеРеквизиты" какого-либо элемента справочника отсутствуют. В этом случае в результате поле "Значение" присоединенной левым соединением табличной части примет значение NULL. Как я понял из задачи, NULL следует интерпретировать как нулевое значение приоритета.
---
Вы хотите сказать, что Остатки.Склад.ДополнительныеРеквизиты - есть ВСЯ таблица ДополнительныеРеквизиты сущности Справочник.Склады, а не та ее часть, которая относится к конкретному Остатки.Склад ???
---
Нет, конечно. :)

Я писал "Справочник.Склады.ДополнительныеРеквизиты", а не "Остатки.Склад.ДополнительныеРеквизиты". И писал для того, чтобы объяснить, откуда же появилась связь по ссылке.

Если есть желание и время, рекомендую почитать книгу "Язык запросов 1С: Предприятие 8". Там описывается как сам язык, так и принцип хранения объектов в информационной базе. И объяснения там значительно лучше, чем могу дать Вам я. :-)
---
У меня нет слов... Кроме... "Господа пассажиры, на нашем самолете есть бассейн, сауна, футбольное поле, бордель на 200 клиентов. Командир корабля приветствует Вас, просит пристегнуть ремни... Сейчас со всей этой ... он попытается взлететь".
Спасибо за ликбез.
---
Я предлагаю иную конструкцию:

```1c
    ВЫБРАТЬ
    ...
    ЕСТЬNULL(СвойствоПриоритет.Значение, 0) КАК Приоритет
    ...
    ИЗ
    ...Остатки
    ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Склады.ДополнительныеРеквизиты КАК СвойствоПриоритет
    ПО Остатки.Склад = СвойствоПриоритет.Ссылка
    И СвойствоПриоритет.Свойство = &Приоритет
```
---
Нет... Этот 1С способен перевернуть нормальное представление о реляционных БД!!!
Поясните, пожалуйста, почему таблица допреквизитов подключенная джойном не тоже самое, что написанная через точку, как реквизит???
Я же фактически делал запросом то же самое!!!
---
Я не могу этого объяснить применительно к теории реляционных БД, т.к. кроме 1С по большому счету ничего и не видел. Очевидно такое решение приняли разработчики платформы: количество строк в результате запроса должно строго соответствовать количеству строк в таблице-источнике с учетом явных связей с прочими таблицами. Следовательно результаты неявных связей, таких как в Вашем примере, должны попадать в результат как вложенные таблицы, дабы не нарушать соглашение о количестве строк самого результата. Видимо так.
---
Просто охренеть!!! Если мы в запросе пишем Остатки.Склад, то получаем конкретную сущность типа Справочник.Склады.
А если мы пишем Остатки.Склад.ДополнительныеРеквизиты, то получаем ВСЮ ТАБЛИЦУ ДополнительныеРеквизиты сущности Справочник.Склады???
Т.е. выделенный кусок Остатки.Склад.ДополнительныеРеквизиты не несет конкретного значения, а служит только для правильной интертрепации (дорожной карты) к таблице ДополнительныеРеквизиты? Охренеть!
---
Нет же, я такого не говорил! :-)

Если мы пишем "Остатки.Склад.ДополнительныеРеквизиты", то получим таблицу конкретного склада, не всех. Но это будет именно таблица значений, а не одно конкретное значение.
---
Э-э-э нет. Так не пойдет! У меня в запросе четко Остатки.Склад.ДополнительныеРеквизиты.Значение
При этом СТРОГО Остатки.Склад.ДополнительныеРеквизиты.Свойство = &СкладИМ
Поэтому с какого перепуга Остатки.Склад.ДополнительныеРеквизиты.Значение - это таблица? Это конкретное значение поля дополнительного реквизита, свойство которого равно параметру &СкладИМ и относящееся к конкретному складу.
Но так НЕ РАБОТАЕТ! Значит Остатки.Склад.ДополнительныеРеквизиты.Значение - непонятно что. Но при этом консоль разработчика нормально отображает результат.
Ладно, не заморачивайтесь. Спасибо еще раз.
---
Остатки.Склад.ДополнительныеРеквизиты.Свойство = &СкладИМЭто где?
---
ГДЕ Остатки.Склад.ДополнительныеРеквизиты.Свойство = &СкладИМ И
        Остатки.Склад.ДополнительныеРеквизиты.Значение >= 0 И
        НЕ Остатки.Номенклатура.ЭтоГруппа И Остатки.Номенклатура.ВидНоменклатуры = &ВидТоварИМ И
            Цены.ВидЦены = &ЦенаРозница
---
ГДЕ Остатки.Склад.ДополнительныеРеквизиты.Свойство = &СкладИМНа всякий случай продублирую. Это условие накладывается на таблицу "Остатки", и не имеет никакого отношения к выражениям, заданным в секции "ВЫБРАТЬ".
---
Не-не-не... Так не пойдет. Секция фильтра накладывается на весь получаемый датасет! Т.е. без этого условия в секции фильтра все строки датасета перемножились на количество допреквизитов сущности Остатки.Склад. Но это условие удалило это перемножение (да его там и не было - допреквизит у Справочник.Склады - ОДИН единственный).
Нет, если Вы скажете, что конкретный экземпляр Справочник.Склады и конкретный экземпляр Остатки.Склад - не одна и та же сущность...
---
Нет. :-) Как я уже описывал в (16), здесь нет никакого перемножения, даже попытки. Перемножение будет при явном соединении таблиц, как у меня в примере (8). При неявном записи берутся исключительно из таблицы остатков и условие накладывается на нее же. А потом каждая запись результата дополняется своей вложенной таблицей доп. реквизитов для своего склада.
---
Ни хрена себе!!! Вот это новость! Вы уверены в этом? Хотя судя по результатам это так и есть, Получаются те же яйца по сути, но в Вашем варианте в интересующем поле сидит именно значение конкретного допреквизита из таблицы ДополнительныеРеквизиты конкретного склада с конкретным свойством, а в моем варианте лежит ТАБЛИЦА из одной записи и одного поля.
---
Кажется я понял, где мой промах в объяснении. Попробую зайти с другой стороны.

Вот Вы написали в секции "ГДЕ" условие: "Остатки.Склад.ДопРеквизиты.Свойство = &Свойство". В результате чтобы вычислить данное выражение к таблице остатков неявно будет добавлено соединение с таблицей БД, где хранятся строки табличной части.

Потом Вы в секцию "ВЫБРАТЬ" добавили выражение "Остатки.Склад.ДопРеквизиты.Значение". Чтобы вычислить это выражение к таблице остатков будет добавлено еще одно соединение с табличной частью.

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

А вот когда Вы явно описываете соединение, Вы для присоединяемой таблицы даете псевдоним, и в дальнейшем обращаетесь к таблице используя именно ее псевдоним. Соответственно пока Вы используете только его, дополнительные соединения уже не появляются.
---
Пипец... Если это действительно так...то я тогда понимаю все свои трудности сертифицированного девелопера СУБД MS SQL Server и самоучки СУБД Postgres. Я просто пытаюсь рассуждать на основах SQL92, а 1С - это Вам не пописать сходить. Мало того, что на русском языке, так и еще язык запросов ничего общего с SQL92.
---
Если бы я знал, что Вы сертифицированный девелопер MS SQL Server сразу, то не стал бы Вам стараться объяснять логику работы платформы. :-) Мои косноязычные рассуждения скорее только Вас запутали. Вам бы лучше послушать комментарии коллег, что хорошо знают, или могут проверить, в какой конечный запрос SQL будет транслирован Ваш запрос на языке 1С. Я, к сожалению, такой компетенцией не обладаю.

P.S. На всякий случай предупрежу, что я говорю совершенно без сарказма.
---
в какой конечный запрос SQL будет транслирован - с конечным запросом все как раз ясно, вопрос только в том, какую сущность подсовывает интертрепатор 1С в результирующий датасет.
Оставим обсуждение сего, я думаю что смысл такого подхода уже никто не помнит, потому как задуманное до конца реализовать не удалось или на каком-то этапе все пошло не туды.
Спасибо за консультацию.
---
В части фильтра запроса, которое в нормальных СУБД начинается с WHERE, а в 1С - с ГДЕ.
Когда меня учили на курсах мелкомягких, то строго не рекомендовали джойны больше одного этажа...
Т.е. соединение двух таблиц должно идти по ОДНОМУ условию, а все дополнительные ограничения должны быть в фильтре запроса, т.е. после WHERE.
---
Выбираемое поле в секции ВЫБРАТЬ (SELECT) никак не связано с условием из секции ГДЕ (WHERE). Это совершенно самостоятельные конструкции.

Фактически в выборке Вы запрашиваете все значения колонки "Значение" табличной части дополнительных реквизитов некоторого склада. Отсюда и в результате таблица значений.

Условием же Вы требуете от платформы включить в результат только те записи исходной таблицы (т.е. таблицы остатков), у которых склад в своей табличной части доп. реквизитов содержит хотя бы одну строку со свойством, равным "СкладИМ".
---
Совсем не возражаю... Но я пишу конкретно в ВЫБРАТЬ - Остатки.Склад.ДополнительныеРеквизиты.Значение, т.е. все значения допреквизита КОНКРЕТНОГО склада. Причем того допреквизита, свойство которого = &СкладИМ. У одного склада не может быть ДВА и более допреквизита одного свойства.