Имя: Пароль:
1C
1С v8
Вопрос по запросу из срезпоследних?
,
0 DeniNikitin
 
08.05.12
11:15
Здравствуйте!

Имеется полностью самописная конфигурация, со стандартными объектами Справочники: Номенклатура и ХарактеристикаНоменклатуры, а также регистр сведений ЦеныНоменклатуры.

На данный момент в регистре лежат 3 записи:
Период|Номенклатура|Характеристика|СтараяЦена|НоваяЦена
18.04.2012|М100| |2300|2500
26.04.2012|М100| |2500|2700
26.04.2012|М100|-5|2700|2700

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

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

Запрос.Текст = ТекстЗапроса;
Запрос.УстановитьПараметр("ЦенаПослед", Дата);
Запрос.УстановитьПараметр("ТипЦены", ТипЦен);
Запрос.УстановитьПараметр("Номенклатура", Номенклатура);
Если Характеристика <> Неопределено Тогда
Запрос.УстановитьПараметр("Характеристика", Характеристика);
Иначе
Запрос.УстановитьПараметр("Характеристика", Неопределено);
КонецЕсли;

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

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

Но ни при выборе номенклатуры без характеристики не проставляется цена, ни при выборе характеристики не проставляется цена!

Подскажите в чём ошибка?

Заранее благодарен!
Возврат Цена;
1 vmv
 
08.05.12
11:16
или нул
2 DeniNikitin
 
08.05.12
11:19
Нет ни одной записи при исполнении запроса!
3 Живой Ископаемый
 
08.05.12
11:25
ничего не понятно... ошибки нет, все правильно
4 DeniNikitin
 
08.05.12
11:27
Так подскажите что изменить для того чтобы возвращалась цена на товар как без характеристики так и с характеристикой?
5 Живой Ископаемый
 
08.05.12
11:30
Справочник лево соединяем со срезом последних, классика.
6 DeniNikitin
 
08.05.12
11:37
Ну а пример запроса можно, просто при соединении не понимаю где указать дату из регистра сведений на которую выбирать?
7 Живой Ископаемый
 
08.05.12
11:39
ну погоди 5 минут
8 Живой Ископаемый
 
08.05.12
11:50
http://screencast.com/t/uiaK6SHi
Желтое - справочник, зеленое - срез последних
параметр дата - отмечена оранжевой стрелкой.
9 DeniNikitin
 
08.05.12
11:52
Тогда при таком решении мне надо два запроса, т.к. есть ещё и характеристиканоменклатуры и цена может быть привязана номенклатура и характеристика, а в одном запросе даже с левым соединением мне в условии надо что-то для характеристики указать!
10 Живой Ископаемый
 
08.05.12
11:54
Ты запрос всегда выполняешь для одной номенклатуры, или можешь как у меня выполнить для списка?
11 DeniNikitin
 
08.05.12
11:57
Для одной номенклатуры, или для номенклатуры с характеристикой!
12 Живой Ископаемый
 
08.05.12
11:57
Тогда просто перед этим
Пока ВыборкаДетальныеЗаписи.Следующий() Цикл
Цена = ВыборкаДетальныеЗаписи.СтараяЦена;
КонецЦикла;

проверяй на пустоту результат запроса. Пустой - значит цена 0
13 DeniNikitin
 
08.05.12
11:59
Это не вопрос, просто не охото два запроса делать, один номенклатура левое соединение цены, второй номенклатура левое соединение характеристика левое соединение цена!
14 DeniNikitin
 
08.05.12
12:02
Сейчас попробовал сделать так, но тогда он возращает почуму то последнюю по номенклатуре и характеристики

   ТекстЗапроса = "ВЫБРАТЬ
       |    ЦеныНоменклатурыСрезПоследних.ТипЦены,
       |    ЦеныНоменклатурыСрезПоследних.Номенклатура,
       |    ЦеныНоменклатурыСрезПоследних.Характеристика,
       |    СУММА(ЦеныНоменклатурыСрезПоследних.СтараяЦена) КАК СтараяЦена,
       |    СУММА(ЦеныНоменклатурыСрезПоследних.НоваяЦена) КАК НоваяЦена
       |ИЗ
       //|РегистрСведений.ЦеныНоменклатуры.СрезПоследних(&ЦенаПослед,ТипЦены = &ТипЦены И Номенклатура = &Номенклатура И Характеристика = &Характеристика) КАК ЦеныНоменклатурыСрезПоследних
       |";
       Если Характеристика = Неопределено Тогда
           ТекстЗапроса = ТекстЗапроса + "    РегистрСведений.ЦеныНоменклатуры.СрезПоследних(&ЦенаПослед,ТипЦены = &ТипЦены И Номенклатура = &Номенклатура) КАК ЦеныНоменклатурыСрезПоследних
           |";
       Иначе                                                                                                            
           ТекстЗапроса = ТекстЗапроса + "    РегистрСведений.ЦеныНоменклатуры.СрезПоследних(&ЦенаПослед,ТипЦены = &ТипЦены И Номенклатура = &Номенклатура И Характеристика = &Характеристика) КАК ЦеныНоменклатурыСрезПоследних
           |";
       КонецЕсли;
       ТекстЗапроса = ТекстЗапроса + "СГРУППИРОВАТЬ ПО
           |    ЦеныНоменклатурыСрезПоследних.ТипЦены,
           |    ЦеныНоменклатурыСрезПоследних.Номенклатура,
           |    ЦеныНоменклатурыСрезПоследних.Характеристика";    
       
       Запрос.Текст = ТекстЗапроса;
       Запрос.УстановитьПараметр("ЦенаПослед", Дата);
       Запрос.УстановитьПараметр("ТипЦены", ТипЦен);
       Запрос.УстановитьПараметр("Номенклатура", Номенклатура);
       Если Характеристика <> Неопределено Тогда
           Запрос.УстановитьПараметр("Характеристика", Характеристика);
       КонецЕсли;
15 DeniNikitin
 
08.05.12
12:30
И ещё при таком запросе выдаёт ошибку
   ТекстЗапроса = "ВЫБРАТЬ
   |   Номенклатура.Ссылка,
   |    ЦеныНоменклатурыСрезПоследних.СтараяЦена
   |ИЗ
   |    Справочник.Номенклатура КАК Номенклатура
   |        ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ЦеныНоменклатуры.СрезПоследних(ЦенаПослед,ТипЦены = &ТипЦен) КАК ЦеныНоменклатурыСрезПоследних
   |        ПО Номенклатура.Ссылка = ЦеныНоменклатурыСрезПоследних.Номенклатура
   |ГДЕ
   |    Номенклатура.Ссылка = &Номенклатура
   |";


{ОбщийМодуль.ЗащищённыйМодуль.Модуль(203)}: Ошибка при вызове метода контекста (Выполнить)
   Результат = Запрос.Выполнить();
по причине:
{(9, 2)}: Неоднозначное поле "Номенклатура.Ссылка"
<<?>>Номенклатура.Ссылка = &Номенклатура
16 Живой Ископаемый
 
08.05.12
12:41
А еще Волга впадает в Каспийское море.
===
   ТекстЗапроса = "ВЫБРАТЬ
   |   Номенклатура1.Ссылка,
   |    ЦеныНоменклатурыСрезПоследних.СтараяЦена
   |ИЗ
   |    Справочник.Номенклатура КАК Номенклатура1
   |        ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ЦеныНоменклатуры.СрезПоследних(ЦенаПослед,ТипЦены = &ТипЦен) КАК ЦеныНоменклатурыСрезПоследних
   |        ПО Номенклатура1.Ссылка = ЦеныНоменклатурыСрезПоследних.Номенклатура
   |ГДЕ
   |    Номенклатура1.Ссылка = &Номенклатура
17 DeniNikitin
 
08.05.12
12:46
1.Запрос почему то возвращает три записи
2.Он возвращает и запись для M100? что не есть правильно
может есть идеи как откинуть если заполнена характеристика?
18 wertyu
 
08.05.12
12:53
(0) 1. у тебя несколько характеристик с одинаковым представлением, ты выбираешь ту, с которой нет записей
2.
Если Характеристика <> Неопределено Тогда
Запрос.УстановитьПараметр("Характеристика", Характеристика);
Иначе
Запрос.УстановитьПараметр("Характеристика", Неопределено);
КонецЕсли;

если переписать так

Если Характеристика = Неопределено Тогда
Запрос.УстановитьПараметр("Характеристика", Неопределено);
Иначе
Запрос.УстановитьПараметр("Характеристика", Характеристика);
КонецЕсли;

то становится очевидным, что такое условие не нужно и смысл не потеряется, если написать так

Запрос.УстановитьПараметр("Характеристика", Характеристика);

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

меняешь на

Результат = Запрос.Выполнить();
Если Результат.Пустой() Тогда
Возврат 0;
КонецЕсли;
ВыборкаДетальныеЗаписи = Результат.Выбрать();
19 wertyu
 
08.05.12
12:56
+(18) если как ты говоришь номенклатура и характеристикиноменклатуры стандартные, то второй подчинен первому, поставь на форме связь по владельцу
20 DeniNikitin
 
08.05.12
12:59
А при чём тут форма, связь стоит, но одна и таже номенклатура может быть как с характеристикой так и без!
Попробовал джаже так
ВЫБРАТЬ ПЕРВЫЕ 1
   Номенклатура1.Ссылка,
   ЦеныНоменклатурыСрезПоследних.НоваяЦена
ИЗ
   Справочник.Номенклатура КАК Номенклатура1
       ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ЦеныНоменклатуры.СрезПоследних(&Дата, ТипЦены = &ТипЦен) КАК ЦеныНоменклатурыСрезПоследних
       ПО Номенклатура1.Ссылка = ЦеныНоменклатурыСрезПоследних.Номенклатура
ГДЕ
   Номенклатура1.Ссылка = &Номенклатура И ЦеныНоменклатурыСрезПоследних.Характеристика = ЗНАЧЕНИЕ(Справочник.ХарактеристикаНоменклатуры.ПустаяСсылка)
Вообще ничего не возращает!
21 DeniNikitin
 
08.05.12
12:59
И в регистре сведений может быть запись номенклатура без характеристики и также эта же номенклатура, но с характеристикой
22 wertyu
 
08.05.12
13:04
значит в запросе в параметрах регистрах д.б. такое условие
ВЫБОР КОГДА &ЕстьХарактеристика ТОГДА Характеристика = &Характеристика ИНАЧЕ ИСТИНА КОНЕЦ

Параметры:
Запрос.УстановитьПараметр("ЕстьХарактеристика", ЗначениеЗаполнено(Характеристика));
Запрос.УстановитьПараметр("Характеристика", Характеристика);

если у тебя характеристика однотипна, то

или второй вариант, условие в запросе:

ВЫБОР КОГДА &Характеристика = ЗНАЧЕНИЕ(Справочник.ХарактеристикаНоменклатуры.ПустаяСсылка) ТОГДА ИСТИНА ИНАЧЕ Характеристика = &Характеристика КОНЕЦ
23 wertyu
 
08.05.12
13:05
+(22) возьми всё из (0)

только убери из запроса группировки, какой смысл суммировать цены на разные товары? )
24 wertyu
 
08.05.12
13:09
+(23) немного неправильно написал, какой смысл суммировать цены на один и тот же товар, но с разными датами, да и при срез последних собственно этого и нет )
25 DeniNikitin
 
08.05.12
13:11
С характеристиками разобрался, теперь не могу понять почему срез последних на дату выводит 2 записи так и должно быть или сделать ВЫБРАТЬ ПЕРВЫЕ 1?
26 wertyu
 
08.05.12
13:13
(25) типы цен может разные? )
27 DeniNikitin
 
08.05.12
13:14
В итоге у меня получился запрос
   ТекстЗапроса = "ВЫБРАТЬ ПЕРВЫЕ 1
   |   Номенклатура1.Ссылка,
   |    ЦеныНоменклатурыСрезПоследних.НоваяЦена,
   |    ЦеныНоменклатурыСрезПоследних.Характеристика
   |ИЗ
   |    Справочник.Номенклатура КАК Номенклатура1
   |        ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ЦеныНоменклатуры.СрезПоследних(&Дата,ТипЦены = &ТипЦен) КАК ЦеныНоменклатурыСрезПоследних
   |        ПО Номенклатура1.Ссылка = ЦеныНоменклатурыСрезПоследних.Номенклатура
   |ГДЕ
   |    Номенклатура1.Ссылка = &Номенклатура И ЦеныНоменклатурыСрезПоследних.Характеристика = ЗНАЧЕНИЕ(Справочник.ХарактеристикаНоменклатуры.ПустаяСсылка)
   |";
Возвращает всё правильно! Сейчас займусь написанием с характеристикой! Всем спасибо за помощь!
28 wertyu
 
08.05.12
13:16
(27) кривой у тебя запрос, в (0) более правильный
29 Живой Ископаемый
 
08.05.12
13:17
ВЫБРАТЬ ПЕРВЫЕ 1
это парнуха.
Однажды он вернет не то что ты ожидаешь
30 DeniNikitin
 
08.05.12
13:20
Знаю, что кривой, просто как ни крутил не могу получить записи если на прямую из регистра сведений буду выбирать, сейчас попробую предложенные варианты переделать на запрос напрямую и без всяких соединений, но на сейчас пойдёт, просто срочно нужно было!
31 DeniNikitin
 
08.05.12
13:21
Ну а по поводу ВЫБРАТЬ ПЕРВЫЕ 1, я сейчас экспериминтировал с запросом в отчёте, и у меня как никрутил вибирает несколько записей но с сортировкой от последней даты, если не использовать ВЫБРАТЬ ПЕРВЫЕ 1, то надо просто избавиться от цыкла и просто получить значение первой строчки!
32 Живой Ископаемый
 
08.05.12
13:23
я поучаствовал в написание копрокода... о ужас...
33 DeniNikitin
 
08.05.12
13:34
Всем ещё раз огромное спасибо, вот конечный рабочий код:

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

   Если ВыборкаДетальныеЗаписи.Количество()<>0 Тогда
       Цена = ВыборкаДетальныеЗаписи[0].НоваяЦена;
   КонецЕсли;
   
   Возврат Цена;
   
КонецФункции