Добрый день. Столкнулся с очередной проблемой. У меня есть внешняя печатная форма, которая может цепляться к любым документам (нестандартная форма МБ-8). Необходимо получить из регистра сведений цену на номенклатуру, которая лежит в документе, на основе которого нужно построить печатную форму. То есть, например, в документе "ВнутреннееПотребление" у нас указано 10 ручек, но цена на ручки лежит в регистре сведений. Чтобы достать цену на эти ручки, я не могу явно указать параметр через док "ВнутреннееПотребление", потому что кроме этого документа, печатную форму формируют ещё, например, 15 документов. Я придерживаюсь следующей логики:

```1c
    Запрос = Новый Запрос ("ВЫБРАТЬ
    | ЦеныНоменклатурыСрезПоследних.Цена КАК Цена
    |ИЗ
    | РегистрСведений.ЦеныНоменклатуры.СрезПоследних(
    | ,
    | ВидЦены = &ВидЦены
    | И Номенклатура.Ссылка = &Номенклатура) КАК ЦеныНоменклатурыСрезПоследних");

    Запрос.УстановитьПараметр("Ссылка", СсылкаНаОбъект.ВидЦены);
    Запрос.УстановитьПараметр("Номенклатура", СсылкаНаОбъект.Товары.Номенклатура);
```
,
Где в
```1c
    Запрос.УстановитьПараметр("Номенклатура", СсылкаНаОбъект.Товары.Номенклатура);
```
 - СсылкаНаОбъект - текущий выбранный документ, Товары - его табличная часть.

Такой вариант не работает. Но я не знаю других вариантов передачи параметра в этот запрос. Подскажите, пожалуйста, как можно решить эту задачу.
---
Если вы хотите выбрать по всем номенклатурам в запросе используйте вместо = "В".
"Конструкция «В» позволяет сравнить значения поля с произвольным списком значения, массива или другого запроса. "
---
А что именно не работает то?
СсылкаНаОбъект содержит ссылку на объект?
---
Да, но при этом в этом параметре поле Номенклатура остаётся незамеченным.
---
Сообщение было скрыто модератором.
---
Вы как-то странно делаете. Непойму как вы номенклатуру как перебираете?
---
Может так надо?
СсылкаНаОбъект.Товары[К].Номенклатура

Где К - номер строки
---
Так да, вы ведь пытаетесь сравнить ссылку на номенклатуру с табличной частью. Колонкой табличной части.
---
Кстати, да, что-то здесь я откровенную глупость сделал.
---
Поставьте точку остановки и посмотрите что у Вас в "СсылкаНаОбъект.Товары.Номенклатура".
---
Может соединением проще будет сделать?

```1c
    ВЫБРАТЬ
    РеализацияТоваровУслугТовары.Номенклатура,
    ЦеныНоменклатурыСрезПоследних.Цена,
    ЦеныНоменклатурыСрезПоследних.ТипЦен
    ИЗ
    Документ.РеализацияТоваровУслуг.Товары КАК РеализацияТоваровУслугТовары
    ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ЦеныНоменклатуры.СрезПоследних(, ТипЦен = &ТипЦен) КАК ЦеныНоменклатурыСрезПоследних
    ПО РеализацияТоваровУслугТовары.Номенклатура = ЦеныНоменклатурыСрезПоследних.Номенклатура
    ГДЕ
    РеализацияТоваровУслугТовары.Ссылка = &Ссылка
    И ЦеныНоменклатурыСрезПоследних.Период >= РеализацияТоваровУслугТовары.Ссылка.Дата
```

Только документ свой подставь.
---
Но у меня может быть неограниченное количество доков, а как их динамически менять - я вообще без понятия.
---
Можно определять тип документа, а в запросе вместо РеализацияТоваровУслуг написать "ТипДокумента" + Товары.Номенклатура.
Так же заменить все найденные значения типа документа.

В переменную ТипДокумента запихивать нужный тип.
---
Попробуйте запросе изменить

```1c
    | И Номенклатура.Ссылка В (&Номенклатура)) КАК ЦеныНоменклатурыСрезПоследних");
```

А в параметр передать всю номенклатуру из таб. части

```1c
    Запрос.УстановитьПараметр("Номенклатура", СсылкаНаОбъект.Товары.ВыгрузитьКолонку("Номенклатура"));
```
---
Вообще правильно было бы убрать отбор по номенклатуре и получать цену сразу для всех номенклатур в табличной части, чтобы потом не получить запрос в цикле
---
Если вы хотите выбрать по всем номенклатурам в запросе используйте вместо = "В".
"Конструкция «В» позволяет сравнить значения поля с произвольным списком значения, массива или другого запроса. "
---
При таком варианте запрос, конечно, работает, но при этом запрос вынимает только одно значение цены.

Т.е. цены у этих наименований должны быть разными. Первое фото - моя форма, второе фото - форма накладной.

```1c
    Запрос = Новый Запрос ("ВЫБРАТЬ
    | ЦеныНоменклатурыСрезПоследних.Цена КАК Цена
    |ИЗ
    | РегистрСведений.ЦеныНоменклатуры.СрезПоследних(
    | ,
    | ВидЦены = &ВидЦены
    | И Номенклатура.Ссылка В (&Номенклатура)) КАК ЦеныНоменклатурыСрезПоследних");
    Запрос.УстановитьПараметр("ВидЦены", СсылкаНаОбъект.ВидЦены);
    Запрос.УстановитьПараметр("Номенклатура", СсылкаНаОбъект.Товары.ВыгрузитьКолонку("Номенклатура"));
```
---
Так да, ведь вы достаете цену без привязки к номенклатуре.Получите не только цену, но и номенклатуру. И потом по номенклатуре свяжите с тем, что у Вас в таблице.
---
Простите, но я откровенно не понимаю, с какой таблицей мне нужно связаться по номенклатуре...
---
Почему-то не могу в личные сообщения написать. На данный момент по тому запросу, что Вы привели вы получаете просто цену. Т.е. она никак не связана с номенклатурой, сделайте так:

```1c
    ВЫБРАТЬ
    | ЦеныНоменклатурыСрезПоследних.Цена КАК Цена,
    | ЦеныНоменклатурыСрезПоследних.Номенклатура КАК Номенклатура
```

И покажите как Вы потом эту цену используете.
---
В итоге запрос оставил вот таким, он прекрасно работает:

```1c
    Запрос = Новый Запрос ("ВЫБРАТЬ
    | ЦеныНоменклатурыСрезПоследних.Цена КАК Цена,
    | ЦеныНоменклатурыСрезПоследних.Номенклатура КАК Номенклатура
    |ИЗ
    | РегистрСведений.ЦеныНоменклатуры.СрезПоследних(
    | ,
    | Номенклатура.Ссылка В (&Номенклатура)
    | И ВидЦены = &ВидЦены) КАК ЦеныНоменклатурыСрезПоследних");
    Запрос.УстановитьПараметр("ВидЦены", СсылкаНаОбъект.ВидЦены);
    Запрос.УстановитьПараметр("Номенклатура", СсылкаНаОбъект.Товары.ВыгрузитьКолонку("Номенклатура"));
```

А далее, я делаю вот так:

```1c
    Выборка = Результат.НайтиСледующий(Новый Структура("Номенклатура", ТекущаяСтрока.Номенклатура));
    Если Выборка <> Неопределено Тогда
    ОбластьСтроки.Параметры.Цена = Результат.Цена;
    Сумма = Колво * Результат.Цена;
    КонецЕсли;
```
 т.е. перебираю выборку. Только сейчас проблема заключается в том, что Результат.Цена не хочет преобразовываться в число. :)
---
Тут либо Выразить в запросе, либо Число() уже по результату.
---
Число() по результату не работало, потому что у определённых документов возвращался пустой результат запроса (соответственно приведение типов не проходило). Однако обработав запрос на пустоту, можно абсолютно без проблем получить результат. Финальный вид вот таков:
```1c
    Запрос = Новый Запрос ("ВЫБРАТЬ
    | ЦеныНоменклатурыСрезПоследних.Цена КАК Цена,
    | ЦеныНоменклатурыСрезПоследних.Номенклатура КАК Номенклатура
    |ИЗ
    | РегистрСведений.ЦеныНоменклатуры.СрезПоследних(
    | ,
    | Номенклатура.Ссылка В (&Номенклатура)
    | И ВидЦены = &ВидЦены) КАК ЦеныНоменклатурыСрезПоследних");
    Запрос.УстановитьПараметр("ВидЦены", СсылкаНаОбъект.ВидЦены);
    Запрос.УстановитьПараметр("Номенклатура", СсылкаНаОбъект.Товары.ВыгрузитьКолонку("Номенклатура"));

    //Строки кода
    //Ещё больше строк
    //И ещё немного

    Выборка = Результат.НайтиСледующий(Новый Структура("Номенклатура", ТекущаяСтрока.Номенклатура));
    Если ВыборкаНаПустоту.Пустой() Тогда
    ОбластьСтроки.Параметры.Цена = NULL;
    ОбластьСтроки.Параметры.Сумма = NULL;
    Иначе
    Если Выборка <> Неопределено Тогда
    ОбластьСтроки.Параметры.Цена = Результат.Цена;
    Сумма = Колво * Результат.Цена;
    ОбластьСтроки.Параметры.Сумма = Сумма;
    СуммаИтог = СуммаИтог + Сумма;
    КонецЕсли;
    КонецЕсли;
```
---
Если честно, мне не очень нравится такой вариант. Я бы скорее в самом запросе проверял на пустую цену, через ЕСТЬNULL, да и следующий кусок как-то немного странно выглядит. Но это уже совсем другая история...
---
С удовольствием бы, на самом деле, послушал её, потому что при проверке работоспособности оказалось, что если существует товар, но для него не указана цена, то ему присваивается последняя записанная на форму цена, что неверно, должен быть ноль. Вероятнее всего, ошибка в сравнении имён номенклатур, но я уже просто закипел с этой печатной формой. :)
---
Честно говоря из того куска кода, что я вижу я вообще мало что понимаю. Что такое ВыборкаНаПустоту мне не понятно.
Вникнуть толком у меня не выходит - голова другим отчетом забита.
Откуда вообще берутся номенклатуры в таблице?
---
Из табличной части документа. Сейчас покажу:

```1c
    СуммаИтог = 0;
    Запрос = Новый Запрос ("ВЫБРАТЬ
    | ЦеныНоменклатурыСрезПоследних.Цена КАК Цена,
    | ЦеныНоменклатурыСрезПоследних.Номенклатура КАК Номенклатура
    |ИЗ
    | РегистрСведений.ЦеныНоменклатуры.СрезПоследних(
    | ,
    | Номенклатура.Ссылка В (&Номенклатура)
    | И ВидЦены = &ВидЦены) КАК ЦеныНоменклатурыСрезПоследних");
    Запрос.УстановитьПараметр("ВидЦены", СсылкаНаОбъект.ВидЦены);
    Запрос.УстановитьПараметр("Номенклатура", СсылкаНаОбъект.Товары.ВыгрузитьКолонку("Номенклатура"));
    ВыборкаНаПустоту = Запрос.Выполнить();
    Результат = ВыборкаНаПустоту.Выбрать();
    ТабличныйДокумент = Новый ТабличныйДокумент;
    МакетПечФормы = ПолучитьМакет("ПФ_MXL_МБ8");

    //Вот тут вывод шапки и заголовка таблицы
    //то есть ничего интересного

    ОбластьСтроки = МакетПечФормы.ПолучитьОбласть("Строка");
    Для Каждого ТекущаяСтрока из СсылкаНаОбъект.Товары Цикл
    ОбластьСтроки.Параметры.МатериалНаименование = ТекущаяСтрока.Номенклатура;
    ОбластьСтроки.Параметры.НоменклатурныйНомер = ТекущаяСтрока.Номенклатура.Код;
    ОбластьСтроки.Параметры.ЕдИзмер = ТекущаяСтрока.Номенклатура.ЕдиницаИзмерения;
    ОбластьСтроки.Параметры.КодЕдиницыИзм = ТекущаяСтрока.Номенклатура.ЕдиницаИзмерения.Код;
    ОбластьСтроки.Параметры.Количество = ТекущаяСтрока.КоличествоУпаковок;
    Колво = Число (ТекущаяСтрока.КоличествоУпаковок);
    Выборка = Результат.НайтиСледующий(Новый Структура("Номенклатура", ТекущаяСтрока.Номенклатура));
    Если ВыборкаНаПустоту.Пустой() Тогда
    ОбластьСтроки.Параметры.Цена = NULL;
    ОбластьСтроки.Параметры.Сумма = NULL;
    Иначе
    Если Выборка <> Неопределено Тогда
    ОбластьСтроки.Параметры.Цена = Результат.Цена;
    Сумма = Колво * Результат.Цена;
    ОбластьСтроки.Параметры.Сумма = Сумма;
    СуммаИтог = СуммаИтог + Сумма;
    КонецЕсли;
    КонецЕсли;
    ТабличныйДокумент.Вывести(ОбластьСтроки);
    КонецЦикла;
```

Собственно, номенклатура достаётся из табличной части документа (Товары - имя таб. части). ВыборкаНаПустоту - строка для проверки результата запроса, пуст он или нет. Разделяю на две переменные для наглядности, чтобы самому потом не путаться.
---
Если я все правильно понимаю, "Выборка" не будет равна неопределенно.
Возвращаемое значение:

Тип: Булево.
Истина - запись найдена; Ложь - в противном случае.
Описание:

Осуществляет поиск записи по указанным условиям и установку указателя выборки на нее.

Доступность:

Сервер, толстый клиент, внешнее соединение, мобильное приложение(сервер).
Примечание:

Текущая запись не рассматривается.
---
Касательно этой строки - здесь все работает так, как должно. Проблема в следующем:

Запрос возвращает, например:

Наименование = ОПГС, Цена = 100
Наименование = ОПГС (продажа), Цена = 0

Однако в форму пишется

Наим Цена
ОПГС 100
ОПГС(продажа) 100

Т.е. при прохождении моих условий, цене присваивается последнее найденное значение.
---
Посмотрте на значение "Выборка" в отладчике по номенклатуре ОПГС(продажа)
---
Да дело в том, что отладчик отключен заказчиком.) Так бы много головной боли не было, будь он включен.
---
Жесть. Мне кажется, что с большой вероятность проблема именно там.
Добавьте:
Если Выборка <> Неопределено Тогда
Сообщить(Выборка.Номенклатура) ;
И там будет видно что за Номенклатуру оно смотрит.
---
Мне стыдно это советовать или говорить, но самое примитивное - попробуйте выгрузить результат запроса в ТЗ, а потом просто ищите там по номенклатуре. Вместо "Выборка = Результат.НайтиСледующий(Новый Структура("Номенклатура", ТекущаяСтрока.Номенклатура));"
Но в запросе добавьте ЕстьNULL
---
Или я могу попробовать посмотреть со свежим взглядом сам, когда разберусь со своими делами - вечером. Но надо мне как то написать, личные сообщения я почему-то слать не могу.
---
Если вас не затруднит, я мог бы написать вам на почту.
---
per0v0yivan Нужный символ rambler
Замените нули на о и дополните последующим.
---
Принял, благодарю. Кстати говоря, что-то я не догадался использовать сообщить. А запрос 2 раза возвращает одну и ту же номенклатуру, проблема в этом. Это вообще жесть какая-то.

UPD. Понял, в чём проблема: в регистре нет записи с ценой для ОПГС (продажа), поэтому и получается хрень. Сейчас нужно подумать, как исключить задвоение записи в таком случае.
---
Сделайте выгрузку в ТЗ, а потом по ней ищите - будет проще. И при условии если потом из нее не будет находиться ставьте нули.
---
Или вообще. Зачем все это. Просто найдите выбранный документ в запросе по ссылке и по нему по каждой строке из таблицы товары соедините с Ценой.
---
Аааа, не всё так просто.) В этом регистре ни один из нужных мне документов не двигается, соответственно, ссылок на него там тоже нет.) Связь с ценой можно наладить именно через номенклатуру (либо её код). Сейчас вот проблема заключается в том, что если в документе встречается номенклатура, которой нет в запросе, запрос пугается и задваивает последнюю запись. Отсюда и баг с ценой. Сейчас вот думаю, как исключить это задваивание. Т.е., если в регистре нет записи на номенклатуру, цена = 0.
---
(40
```1c
    СуммаИтог = 0;
    Запрос = Новый Запрос ("ВЫБРАТЬ
    | ЕстьNULL(ЦеныНоменклатурыСрезПоследних.Цена, 0) КАК Цена,
    | ЦеныНоменклатурыСрезПоследних.Номенклатура КАК Номенклатура
    |ИЗ
    | РегистрСведений.ЦеныНоменклатуры.СрезПоследних(
    | ,
    | Номенклатура.Ссылка В (&Номенклатура)
    | И ВидЦены = &ВидЦены) КАК ЦеныНоменклатурыСрезПоследних");
    Запрос.УстановитьПараметр("ВидЦены", СсылкаНаОбъект.ВидЦены);
    Запрос.УстановитьПараметр("Номенклатура", СсылкаНаОбъект.Товары.ВыгрузитьКолонку("Номенклатура"));
    ВыборкаНаПустоту = Запрос.Выполнить();
    Результат = ВыборкаНаПустоту.Выгрузить();
    ТабличныйДокумент = Новый ТабличныйДокумент;
    МакетПечФормы = ПолучитьМакет("ПФ_MXL_МБ8");

    //Вот тут вывод шапки и заголовка таблицы
    //то есть ничего интересного

    ОбластьСтроки = МакетПечФормы.ПолучитьОбласть("Строка");
    Для Каждого ТекущаяСтрока из СсылкаНаОбъект.Товары Цикл
    ОбластьСтроки.Параметры.МатериалНаименование = ТекущаяСтрока.Номенклатура;
    ОбластьСтроки.Параметры.НоменклатурныйНомер = ТекущаяСтрока.Номенклатура.Код;
    ОбластьСтроки.Параметры.ЕдИзмер = ТекущаяСтрока.Номенклатура.ЕдиницаИзмерения;
    ОбластьСтроки.Параметры.КодЕдиницыИзм = ТекущаяСтрока.Номенклатура.ЕдиницаИзмерения.Код;
    ОбластьСтроки.Параметры.Количество = ТекущаяСтрока.КоличествоУпаковок;
    Колво = Число (ТекущаяСтрока.КоличествоУпаковок);
    ЦенаПоНоменклатуре = Результат.Найти(ТекущаяСтрока.Номенклатура, "Номенклатура")
    ОбластьСтроки.Параметры.Цена = ЦенаПоНоменклатуре.Цена;
    Сумма = Колво * ЦенаПоНоменклатуре.Цена;
    ОбластьСтроки.Параметры.Сумма = Сумма;
    СуммаИтог = СуммаИтог + Сумма;

    КонецЕсли;
    ТабличныйДокумент.Вывести(ОбластьСтроки);
    КонецЦикла;
```
)
Попробуйте
---
Метод объекта не обнаружен (Найти).
---
Тут поправили?
Результат = ВыборкаНаПустоту.Выгрузить();
---
Исправил, да, после того, как вы обратили моё внимание на это.) Но теперь в строке Сумма = Колво * ЦенаПоНоменклатуре.Цена; компилятор не может преобразовать ЦенаПоНоменклатуре.Цена в Число. Это, вероятнее всего, потому что для одной номенклатуры соответствия не найдено.
---
А тут поправили?
| ЕстьNULL(ЦеныНоменклатурыСрезПоследних.Цена, 0) КАК Цена,
---
Блин, туплю:

```1c
    ЦенаПоНоменклатуре = Результат.Найти(ТекущаяСтрока.Номенклатура, "Номенклатура")
    Если ЦенаПоНоменклатуре<> Неопределено Тогда
    ОбластьСтроки.Параметры.Цена = ЦенаПоНоменклатуре.Цена;
    Сумма = Колво * ЦенаПоНоменклатуре.Цена;
    ОбластьСтроки.Параметры.Сумма = Сумма;
    СуммаИтог = СуммаИтог + Сумма;
    Иначе
    ОбластьСтроки.Параметры.Цена = 0;
    ОбластьСтроки.Параметры.Сумма = 0;
    КонецЕсли;
```
---
Везде поправил. Сумма = Колво * ЦенаПоНоменклатуре.Цена; - не может преобразоваться к (Число). Условие Если ЦенаПоНоменклатуре<> Неопределено Тогда, как я понимаю, не выполняется, потому что ТЗ возвращает хотя бы одну запись, а значит она определена. Опять же, как я понимаю.
---
Возвращаемое значение:
Тип: СтрокаТаблицыЗначений, Неопределено.
Строка, в которой содержится искомое значение. Если значение не найдено, то возвращается значение Неопределено.

Не должно. Надо через сообщить вычислить что там за номенклатура и какая цена.
---
Ох, я жёстко ступил, в запросе вместо цены, вытянул ВидЦены, а это действительно ни разу не число.) Как только в запросе сменил на ЕстьNULL(ЦеныНоменклатурыСрезПоследних.ЦЕНА, 0) КАК Цена, сразу всё исправилось. Прошу прощения за последние 10 минут потерянного времени, это исключительно моя невнимательность.)
---
Да ничего. Но имейте ввиду, что решение это очень корявое, по хорошему так лучше не делать.
---
Учту это в своей следующей задаче, ведь новая задача тоже про доработку печатной формы! :)
---
Для обнуления значений выводимой строки, можно ее получать непосредственно в цикле Чтоб наверняка прошлые значения не попали в новую строку.
Для Каждого ТекущаяСтрока из СсылкаНаОбъект.Товары Цикл
    ОбластьСтроки = МакетПечФормы.ПолучитьОбласть("Строка");
..............
---
Метод "НайтиСледующий" аналогичен методу "Следующий", за тем исключением, что "НайтиСледующий" выбирает запись из выборки, которая удовлетворяет условию. Можно было написать так

Для Каждого ТекущаяСтрока из СсылкаНаОбъект.Товары Цикл
ОбластьСтроки = МакетПечФормы.ПолучитьОбласть("Строка");

...............................

Если Результат.НайтиСледующий(Новый Структура("Номенклатура", ТекущаяСтрока.Номенклатура)); Тогда
    ОбластьСтроки.Параметры.Цена = Результат.Цена;
    ..........................
КонецЕсли;
---
Если ваша цель добиться универсальности вашей печатной формы, то самый простой способ - менять текст запроса в зависимости от типа документа из которого она была вызвана.
Этот способ - древний как сама 1С...
Вы просто делаете замену кусочка текста запроса в можуле ЕСЛИ...