Есть таблица с товарами и ценами в документе Поставка. Есть справочник контрагентов с таблицей цен для каждого контрагента. Нужно из таблицы цен контрагента вытащить цену на нужный товар. Для этого написал такой код:

Но вот получить цену так и не удалось. Где здесь может быть ошибка?

При отладке данного кода такой результат:
<Документ.Поставка.Форма.ФормаДокумента.Форма(40)>: Поле объекта не обнаружено (Цена)
Возврат Результат.Цена;

  • Вопрос задан более трёх лет назад
  • 11663 просмотра

Имейте ввиду, что если в результате запроса возвращается несколько строк, то вы получите результат последней строки.

Константин Нагибович: &НаСервере
Функция ПолучитьЦены(Контрагент, Номенклатура)
Запрос = Новый Запрос;
Запрос.Текст = "ВЫБРАТЬ
| Контрагент.Цены.Цена КАК Цена
|ИЗ
| Справочник.Контрагенты КАК Контрагент
|ГДЕ
| Контрагент.Ссылка = &Контрагент
| И Контрагент.Цены.Номенклатура = &Номенклатура";
Запрос.УстановитьПараметр("Контрагент", "Иванов К.Е.");
Запрос.УстановитьПараметр("Номенклатура", "Металлочерепица");
РезультатЗапроса = Запрос.Выполнить();
ВыборкаДетальныеЗаписи = РезультатЗапроса.Выбрать();
Цена = 0;
Пока ВыборкаДетальныеЗаписи.Следующий() Цикл
Цена = ВыборкаДетальныеЗаписи.Цена;
КонецЦикла;
Возврат Цена;
КонецФункции

Разве не так должно быть?

Константин Нагибович:
"Запрос.УстановитьПараметр("Контрагент", "Иванов К.Е.");
Запрос.УстановитьПараметр("Номенклатура", "Металлочерепица");"

Это я просто проверял один из методов. Сейчас там уже стоят ссылки на объекты.

Константин Нагибович: Использую. Конечный вариант так выглядит:

&НаСервере
Функция ПолучитьЦены(Контрагент, Номенклатура)
Запрос = Новый Запрос;
Запрос.Текст = "ВЫБРАТЬ
| Контрагент.Цены.Цена КАК Цена
|ИЗ
| Справочник.Контрагенты КАК Контрагент
|ГДЕ
| Контрагент.Ссылка = &Контрагент
| И Контрагент.Цены.Номенклатура = &Номенклатура";
Запрос.УстановитьПараметр("Контрагент", Контрагент);
Запрос.УстановитьПараметр("Номенклатура", Номенклатура);
РезультатЗапроса = Запрос.Выполнить();
ВыборкаДетальныеЗаписи = РезультатЗапроса.Выбрать();
Цена = 0;
Пока ВыборкаДетальныеЗаписи.Следующий() Цикл
Цена = ВыборкаДетальныеЗаписи.Цена;
КонецЦикла;
Возврат Цена;
КонецФункции

Константин Нагибович: Нашел похоже где ошибка. При вызове функции выходит:

<Документ.Поставка.Форма.ФормаДокумента.Форма(24)>: Ошибка при вызове метода контекста (ПолучитьЦены)
ЦенаТовара = ПолучитьЦены(Контрагент, Номенклатура);
по причине:
Ошибка передачи данных между клиентом и сервером. Значение недопустимого типа.
по причине:
Ошибка преобразования данных XDTO:
Запись значения свойства ‘param’:
форма: Элемент
имя: param
по причине:
Ошибка отображения типов:
Отсутствует отображение для типа ‘ПолеФормы’

gunsmyth: Использую Ваш код, достиг такого:

<Документ.Поставка.Форма.ФормаДокумента.Форма(57)>: Значение не является значением объектного типа (Цена)
Возврат Результат.Цена;

Попробуйте вместо "Результат = Запрос.Выполнить().Выбрать().Следующий();" использовать

РезультатЗапроса = Запрос.Выполнить();
ВыборкаДетальныеЗаписи = РезультатЗапроса.Выбрать();
Цена = 0;
Пока ВыборкаДетальныеЗаписи.Следующий() Цикл
Цена = ВыборкаДетальныеЗаписи.Цена;
КонецЦикла;

Спасибо Вам большое! Работает!

Полученный рабочий код:

&НаКлиенте
Процедура ТоварыНоменклатураПриИзменении(Элемент)
Контрагент = Объект.Контрагент;
СтрокаТабличнойЧасти = Элементы.Товары.ТекущиеДанные;
Номенклатура = Элементы.Товары.ТекущиеДанные.Номенклатура;
ЦенаТовара = ПолучитьЦены(Контрагент, Номенклатура);
СтрокаТабличнойЧасти.Цена = ЦенаТовара;
КонецПроцедуры

&НаСервере
Функция ПолучитьЦены(Контрагент, Номенклатура)
Запрос = Новый Запрос;
Запрос.Текст = "ВЫБРАТЬ
| ЦеныКонтрагента.Цена КАК Цена
|ИЗ
| Справочник.Контрагенты.Цены КАК ЦеныКонтрагента
|ГДЕ
| ЦеныКонтрагента.Ссылка = &Контрагент
| И ЦеныКонтрагента.Номенклатура = &Номенклатура";
Запрос.УстановитьПараметр("Контрагент", Контрагент);
Запрос.УстановитьПараметр("Номенклатура", Номенклатура);
РезультатЗапроса = Запрос.Выполнить();
ВыборкаДетальныеЗаписи = РезультатЗапроса.Выбрать();
Цена = 0;
Пока ВыборкаДетальныеЗаписи.Следующий() Цикл
Цена = ВыборкаДетальныеЗаписи.Цена;
КонецЦикла;
Возврат Цена;
КонецФункции

В дополнение к возвращенному запросом результирующему набору данных можно также получить следующую информацию:

  • Функция mysql_affected_rows() возвращает количество строк, подвергшихся воздействию во время последнего запроса при выполнении INSERT , UPDATE или DELETE . Исключение составляет случай использования команды DELETE без выражения WHERE , когда таблица воссоздается как пустая, а это намного быстрее! В таком случае функция mysql_affected_rows() в качестве количества подвергшихся воздействию записей возвращает нуль.
  • Функция mysql_num_rows() возвращает количество строк в результирующем наборе данных. Функция mysql_num_rows() может вызываться сразу же после возвращения функции mysql_store_result() . Совместно с функцией mysql_use_result() функция mysql_num_rows() может вызываться только после того, как извлечены все строки с помощью функции mysql_fetch_row() .
  • Функция mysql_insert_id() возвращает идентификатор, созданный последним запросом, внесшим строку в таблицу с автоинкрементным полем ( AUTO_INCREMENT , mysql_insert_id() ).
  • Некоторые запросы ( LOAD DATA INFILE . , INSERT INTO . SELECT . , UPDATE ) возвращают дополнительную информацию. Ее можно получить с помощью функции mysql_info() . Описание формата возвращаемой строки смотрите в описании функции mysql_info() . Если дополнительная информация отсутствует, то функция mysql_info() возвращает указатель NULL .

Запросы в системе "1С:Предприятие 8" предназначены для выборки информации из базы данных. По сути, запрос — это обращение к системе с просьбой выбрать определенную информацию из базы данных, а часто не только выбрать, но и произвести некоторую обработку: сгруппировать, отсортировать, вычислить. Например, с помощью запроса можно легко узнать объем продаж каждого товара в течение года с детализацией до месяца или выбрать элементы справочников по определенному условию. Заметьте, что изменять данные с помощью запросов в 1С:Предприятии не разрешается.

Язык запросов 1С:Предприятия 8 основан на стандартном SQL, но при этом содержит значительное количество расширений, ориентированных на финансово-экономические задачи, и значительно облегчает разработку бизнес-приложений.

Для работы с запросами в системе "1С:Предприятие 8" предусмотрено несколько специальных объектов, а именно:

  • Запрос
  • РезультатЗапроса
  • ВыборкаИзРезультатаЗапроса.

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

  1. Создание объекта "Запрос" с нужным текстом запроса на специальном языке запросов.
  2. Установка параметров запроса с помощью метода УстановитьПараметр.
  3. Выполнение запроса, получение результата.
  4. Получение выборки из результата запроса или выгрузка результата в таблицу значений / дерево значений. Также есть возможность использовать результат запроса для формирования сводной таблицы.
  5. Обработка выборки или таблицы значений (например, перебор строк) и выполнение действий, для которых был нужен запрос, например, вывод области при формировании отчета

Графически это можно представить следующим образом:

Цифрами на схеме обозначены следующие действия:

1. Установка текста запроса

Объект "Запрос" имеет свойство "Текст", которое содержит строку с текстом запроса на языке запросов. Этому свойству, во-первых, можно явно присвоить значение или, во-вторых, воспользоваться конструктором объекта "Запрос". В последнем случае текст запроса передается в качестве параметра в конструктор объекта "Запрос" при его создании.

2-й вариант (с другим текстом запроса):

2. Установка параметров запроса

Объект "Запрос" имеет метод "УстановитьПараметр", с помощью которого в запрос передаются значения параметров. Параметры запроса обычно используются в условиях отбора (конструкции ГДЕ, ИМЕЮЩИЕ) или в качестве параметров вызова виртуальных таблиц. В тексте запроса параметры обозначаются знаком "&" (например, параметр "ВыбГруппа" в первом запросе).

В качестве параметров используются значения, которые указываются пользователем в диалоге или значения типов, для которых нет литералов, например, пустых ссылок на элементы справочников. Литералы же есть только у примитивных типов данных, а именно, число, строка, дата, булево, Null, Неопределено.

3. Выполнение запроса

После присвоения текста и установки параметров, запрос запускается на выполнение с помощью метода "Выполнить()" объекта "Запрос". Этот метод возвращает другой объект "РезультатЗапроса", содержащий выбранные данные из базы данных.

Далее возможны три варианта:

  • во-первых, из результата запроса может быть получена выборка (линейная, иерархическая и т.д.),
  • во-вторых, результат запроса может быть выгружен в таблицу или дерево значений,
  • в-третьих, результат запроса может являться источником данных для сводной таблицы.

4. Получение выборки из результата запроса

Объект "РезультатЗапроса" имеет метод "Выбрать()", который возвращает новый объект "ВыборкаИзРезультатаЗапроса". В зависимости от параметра метода "Выбрать()" выборка будет линейной (по умолчанию), иерархической или по группировкам. Далее выборка обходится с помощью цикла "Пока Выборка.Следующий() Цикл", а в теле цикла производятся какие-то действия, например, вывод областей в табличный документ.

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

Объект "РезультатЗапроса" имеет метод "Выгрузить()", который возвращает таблицу значений или дерево значений, в зависимости от переданного параметра . Если устанавливается прямой тип обхода (по умолчанию), то будет создана таблица значений, иначе — дерево значений. Далее таблица значений (дерево значений) может быть обработана средствами встроенного языка или показана пользователю в табличном поле.

6. Формирование сводной таблицы

Результат запроса может быть использован как источник данных для сводной таблицы. При этом итоги (см. предложение ИТОГИ в тексте запроса) становятся ресурсами (отображаются в области данных), а группировочные поля, по которым они подсчитываются, становятся измерениями сводной таблицы. В качестве источника данных для сводной таблицы может быть также использован объект "ПостроительОтчета", но ему на вход тоже подается запрос, поэтому можно сказать, что основа любой сводной таблицы — это запрос к базе данных.