Имя: Пароль:
1C
1С v8
v8: Запросы. Результат Null
,
0 Dmitry017
 
28.03.13
12:03
Проблема с запросом. Задача. В форме есть табличная часть Товары, в окторой содержатся поля Номенклатура и Цена. В поле Номенклатура содержится ссылка на справочник СправочникСсылка.Номенклатура.
В справочнике Номенклатура есть поля Наименование и Цена. Надо чтобы автоматически подставлялась цена.
У меня результат запроса пустой.

&НаКлиенте
Процедура ТоварыНоменклатураПриИзменении(Элемент)    
    ТекущаяСтрока = Элементы.Товары.ТекущиеДанные;
    ТекущаяСтрока.Цена =  ПолучитьЦенуПродажи(ТекущаяСтрока.Номенклатура);
КонецПроцедуры


&НаСервере
Функция ПолучитьЦенуПродажи(НаименованиеНоменклатуры)

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

   ВыборкаДетальныеЗаписи = Результат.Выбрать();

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

КонецФункции // ПолучитьЦенуПродажи()
1 vicof
 
28.03.13
12:04
классика жанра
2 scanduta
 
28.03.13
12:05
Передаешь ссылку а ищещь по наименованию
3 Лодырь
 
28.03.13
12:05
Пипец. А зачем тебе запрос?
4 vicof
 
28.03.13
12:05
ищи по ссылке, а не по наименованию.

Пока ВыборкаДетальныеЗаписи.Следующий() Цикл
       // Вставить обработку выборки ВыборкаДетальныеЗаписи

       Цена = ВыборкаДетальныеЗаписи.ЦенаПродажи;
   КонецЦикла;
   Возврат Цена;

угадай, что будет после выполнения этой конструкции
5 НафНаф
 
28.03.13
12:06
Запрос.Текст =
       "ВЫБРАТЬ
       |    Номенклатура.Наименование,
       |    Номенклатура.ЦенаПродажи
       |ИЗ
       |    Справочник.Номенклатура КАК Номенклатура
       |ГДЕ
       |    Ссылка = &Номенклатура";
       
       Запрос.УстановитьПараметр("Номенклатура", Номенклатура);
6 НафНаф
 
28.03.13
12:07
пустой или NULL?
7 SkrAn
 
28.03.13
12:07
запрос ненужен) через ссылку можно вытянуть) ну или тогда уж одним запросом - по всей табличной части)
8 GANR
 
28.03.13
12:09
(0) А почему он должен быть полный??? Наименование и ссылка на элемент никогда не равны. Правильно - см. (5).
9 Dmitry017
 
28.03.13
12:10
спасибо за советы
10 H A D G E H O G s
 
28.03.13
12:12
(9) Херовые советы, если честно.
11 НафНаф
 
28.03.13
12:12
(10) ну давай, выежись нам
12 H A D G E H O G s
 
28.03.13
12:13
ТекущаяСтрока = Элементы.Товары.ТекущиеДанные;
    ТекущаяСтрока.Цена =  ОбщегоНазначения.ПолучитьЗначениеРеквизита(ТекущаяСтрока.Номенклатура,"ЦенаПродажи");
13 H A D G E H O G s
 
28.03.13
12:14
А если ее нет, этой ОбщегоНазначения.ПолучитьЗначениеРеквизита

- ее надо аккуратно написать, ну вы знаете, как.

И немного доработать напильником, чтобы не вываливалась в фэйл при попытке получения реквизита пустого объекта, это да.
14 НафНаф
 
28.03.13
12:14
(12) это писец, неужели так грустно будет всегда с УФ
15 H A D G E H O G s
 
28.03.13
12:14
(14) ЧТо не так?
16 H A D G E H O G s
 
28.03.13
12:15
Типовая
ОбщегоНазначения.ПолучитьЗначениеРеквизита

идеально входит.

Клиент-серверная, вызов сервера без контекста.
Просто пэрсик, мвах!
17 НафНаф
 
28.03.13
12:16
(15) ну почему мне запрещают писать так?

ТекущаяСтрока = Элементы.Товары.ТекущиеДанные;
ТекущаяСтрока.Цена = ТекущаяСтрока.Номенклатура.ЦенаПродажи;

зачем все эти лишние телодвижения?
18 H A D G E H O G s
 
28.03.13
12:18
(17) Потому что ты дятел и твой мозг поражен null-ами.

Как минимум - вот:

v8: Кэши разные нужны, кэши нужные важны.
19 Fragster
 
гуру
28.03.13
12:18
(17) чтобы ты понимал, когда дергается сервер и мог этим управлять
20 H A D G E H O G s
 
28.03.13
12:18
(17) Когда в ссылку добавят свойство "РежимИспользованияКэша", тогда приходите.
21 НафНаф
 
28.03.13
12:19
(18) сам ты дятел, хоть еж, но дятел
(18)(19) платформа могла бы это делать автоматом, все же просто
иначе это никакое не RAD, а УГ
22 Dionis Sergeevich
 
28.03.13
12:20
Процедура ТоварыНоменклатураПриИзменении(Элемент)    
 
   ТекущаяСтрока.Цена = ТекущаяСтрока.Номенклатура.Цена;

КонецПроцедуры
23 scanduta
 
28.03.13
12:23
(12) Тогда уж так:
Не понятно зачем использовать общие модули когда можно просто обратиться к РС напрямую без использования запроса и общих модулей

Если непериодический регистр:

Отбор = Новый Структура("ИмяИзмерения",ЗначениеИзмерения);
Значение = РегистрыСведений.МойНепериодическийРЕгистр.Получить(Отбор).ИмяРесурса;

Если периодический регистр то используем СрезПоследних
24 H A D G E H O G s
 
28.03.13
12:26
(23) Непонятно, зачем писать, если не умеешь читать. У него цена в номенклатуре, как реквизит.
25 H A D G E H O G s
 
28.03.13
12:26
(22) Нельзя так.
26 scanduta
 
28.03.13
12:28
Да точно с РС попутал я
27 Dionis Sergeevich
 
28.03.13
12:38
(25) А если на сервере? =) Вполне можно
28 hhhh
 
28.03.13
12:50
(19) да, действительно. Почему если в обычном приложении когда пишем

Наименование = Номенклатура.Наименование;
Код = Номенклатура.Код;
Цена = Номенклатура.Цена;

элемент справочника на первой строчке считывался из базы в кеш и потом следующие два раза брался уже из кеша. а в УФ такого нельзя сделать?
29 Reset
 
28.03.13
13:06
(28) Можно написать свою простую функцию сразу нескольких реквизитов:

СтруктураРеквизитов=ПолучитьЗначенияРеквизитов(Номенклатура,"Наименование,Код,Цена");

Наименование = СтруктураРеквизитов.Наименование;
Код = СтруктураРеквизитов.Код;
Цена = СтруктураРеквизитов.Цена;
30 Dmitry017
 
30.03.13
18:50
У меня всё заработало.
Только я не понимаю, почему здесь на Номенклатура. Наименование не ругается
&НаКлиенте
Процедура ТоварыНоменклатураПриИзменении(Элемент)    
    ТекущаяСтрока = Элементы.Товары.ТекущиеДанные;
    ТекущаяСтрока.Цена =  ПолучитьЦенуПродажи(ТекущаяСтрока.Номенклатура);
КонецПроцедуры


&НаСервереБезКонтекста
Функция ПолучитьЦенуПродажи(Номенклатура)

   Запрос = Новый Запрос;
   Запрос.Текст =
       "ВЫБРАТЬ
       |    Номенклатура.Наименование,
       |    Номенклатура.ЦенаПродажи
       |ИЗ
       |    Справочник.Номенклатура КАК Номенклатура";

       Запрос.УстановитьПараметр("Номенклатура", Номенклатура.Наименование);
       Результат = Запрос.Выполнить();

   ВыборкаДетальныеЗаписи = Результат.Выбрать();

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

КонецФункции // ПолучитьЦенуПродажи()



А если так написать, то ругается при вызове функции типа в номенклатуре нет поля Наименование, хотя номенклатура - это СправочникСсылка???


&НаКлиенте
Процедура ТоварыНоменклатураПриИзменении(Элемент)    
    ТекущаяСтрока = Элементы.Товары.ТекущиеДанные;
    ТекущаяСтрока.Цена =  ПолучитьЦенуПродажи(ТекущаяСтрока.Номенклатура.Наименование);
КонецПроцедуры


&НаСервереБезКонтекста
Функция ПолучитьЦенуПродажи(Номенклатура)

   Запрос = Новый Запрос;
   Запрос.Текст =
       "ВЫБРАТЬ
       |    Номенклатура.Наименование,
       |    Номенклатура.ЦенаПродажи
       |ИЗ
       |    Справочник.Номенклатура КАК Номенклатура";

       Запрос.УстановитьПараметр("Номенклатура", Номенклатура);
       Результат = Запрос.Выполнить();

   ВыборкаДетальныеЗаписи = Результат.Выбрать();

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

КонецФункции // ПолучитьЦенуПродажи()


&НаКлиенте
Процедура ТоварыКоличествоПриИзменении(Элемент)
   // Вставить содержимое обработчика.
   //расчитываем сумму
   
   ТекущаяСтрока = Элементы.Товары.ТекущиеДанные;
   //обработаем ошибку
   Если ТекущаяСтрока.Цена = Неопределено Тогда
       ТекущаяСтрока.Цена = 0;
   КонецЕсли;
   
   ТекущаяСтрока.Сумма = ТекущаяСтрока.Цена * ТекущаяСтрока.Количество;

КонецПроцедуры


Разница:
Вариант 1:
Запрос.УстановитьПараметр("Номенклатура", Номенклатура.Наименование);

Вариант 2
ТекущаяСтрока.Цена =  ПолучитьЦенуПродажи(ТекущаяСтрока.Номенклатура.Наименование);

Вроде бы результат один и тот же должен быть, просто в первом случае передаём СправочникСсылка, а потом уже в функции обращаемся к нужному полю, а во второнм случае сразу пытаемся передать строку.
31 Dmitry017
 
30.03.13
19:04
Запрос был неправильный, но сам вопрос не в запросе, а в том, почему в одном месте видит поле  Наименование, а в другом нет.

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