Подскажите, как подтянуть цену в табличную часть из регистра сведений.

1. user790607 01.04.19 12:25 Сейчас в теме
Доброго времени суток всем участников данного форума!

Пишу самописную конфу, в 1с ещё новичок, но стараюсь.
Конфа для учёта медикаментов.
Есть регистр сведений, который хранит наименование препарата, номер партии, цену за штуку и цену за упаковку.
Есть документ прихода на склад. Где при выборе номенклатуры должна подтягиваться цена из регистра, подскажите как грамотнее реализовать?
Чот сильно туплю с запросом... Срез последних тут не нужен, т.к. цена фиксируется документом-регистратором, он же "документ основание". Т.е. для каждого документа хранится его цена по номенклатуре, временной отбор тут тоже не требуется.
Не пойму как связать регистратор, номерПартии и Наименование в запросе по каждой номенклатурной позиции...

Пока делаю так:
&НаКлиенте
Процедура НоменклатураНаименованиеПриИзменении(Элемент)
	СтрокаТЧ = Элементы.Номенклатура.ТекущиеДанные;
	СтрокаТЧ.ШтукВУпаковке = ПолучитьШтукВУпаковке(СтрокаТЧ.Наименование);
	СтрокаТЧ.ЦенаЭталон = ПолучитьЦенуИзРегистра(СтрокаТЧ.Наименование);
КонецПроцедуры

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


С запросами пока что плоховато дружу, ибо на просторах все всё делают по разному, а где изучить досканально синтаксис не знаю...


И да, делаю это для того, чтобы потом сделать контроль цен введённой оператором в приходе и существующей в документе-основании. Возможно потом скрою столбец с ценой и буду делать сравнение и выдачу ошибки при не правильной цене, т.к. сказать "защита от дурака".
Прилагаю скрины регистра и прихода.

Всем заранее спасибо за помощь!
Прикрепленные файлы:
Найденные решения
2. SedovSU@mail.ru 297 01.04.19 12:54 Сейчас в теме
Вам нужна связь не только по номенклатуре но и по партии, поэтому в функцию должно быть три параметра, затем в запросе где связь тоже должна быть связь с партией

При этом Наименование - это ссылка на справочник а не строка!!!!!
 СтрокаТЧ.ЦенаЭталон = ПолучитьЦенуИзРегистра(СтрокаТЧ.Наименование, СтрокаТЧ.Партия, Объект.ДокументОснование);



&НаСервереБезКонтекста
Функция ПолучитьЦенуИзРегистра(Номенклатура, Партия, ДокументОснования)       
Запрос = Новый Запрос;
Запрос.Текст = "ВЫБРАТЬ
| Цена.Номенклатура, 
|Цена.Партия, 
|Цена.Регистратор, 
|Цена.ЦенаУпаковки 
|    ИЗ РегистрСведений.ЦеныНоменклатуры КАК Цена 
|ГДЕ 
|   Цена.Номенклатура = &Номенклатура И Цена.Партия = &Партия И Цена.Регистратор = &Регистратор"
Запрос.УстановитьПараметры("Номенклатура", Номенклатура);
Запрос.УстановитьПараметры("партия", Партия);
Запрос.УстановитьПараметры("Регистратор", Регистратор);
ВыборкаДетальныеЗаписи = Запрос.Выполнить().Выбрать();
Если ВыборкаДетальныеЗаписи.Количество()  = 0 Тогда 
Возврат 0
ИНаче
ВыборкаДетальныеЗаписи.Следубщий()
Возврат ВыборкаДетальныеЗаписи.ЦенаУпаковки
Конецесли
КонецФункции  
Показать
user790607; +1 Ответить
Остальные ответы
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
5. arsen_botashev 01.04.19 12:56 Сейчас в теме
(1)При выборе номенклатуры в тч, необходимо заполнить ее цену? так?
Если да то, необходимо из регистра сведений получать цену, при этом в запрос передать Значение номенклатуры из тч.
Примерно так.
|Где РегситрСведений.Номенклатура = &номенкатура
запрос.установитьпараметр("номенклатура" ТЧ.номенклатура)
2. SedovSU@mail.ru 297 01.04.19 12:54 Сейчас в теме
Вам нужна связь не только по номенклатуре но и по партии, поэтому в функцию должно быть три параметра, затем в запросе где связь тоже должна быть связь с партией

При этом Наименование - это ссылка на справочник а не строка!!!!!
 СтрокаТЧ.ЦенаЭталон = ПолучитьЦенуИзРегистра(СтрокаТЧ.Наименование, СтрокаТЧ.Партия, Объект.ДокументОснование);



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

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


Теперь хоть заполнил пробелы в знаниях по объявлению и сбору параметров!
3. YannikAlx 43 01.04.19 12:55 Сейчас в теме
У вас немного не понятный подход.
Документ поставки записывает цену покупки, он не должен формировать цену продажи.
Продажная цена обычно формируется совершенно отдельным документом, УстановкаЦенНоменклатуры, в котором указывается цена , по которой товар будет продаваться, заполняется этот документ вполне и по закупочным ценам , скажем определённой наценкой.
Но цены закупки и продажи должны быть разделены. Иначе у вас будет один и тот же товар иметь совершенно различную цену в кассе, что является абсурдом.
То есть 1 бутылка за 100р вторая такая же за 200 а третья такая же за 50.
Покупатель будет счастлив
7. user790607 02.04.19 04:57 Сейчас в теме
(3) согласен, подход не понятный, сейчас поясню:
мы ничего не продаём, организация - больница.
нам нужен учёт между отделениями/постами/складом и заказ по ШК.

цена привязывается к документуОснованию, в нём она статична у каждой номенклатурной позиции.
Кассы у нас нет, цену я хочу подтянуть для сравнения в документах прихода.
Чтобы она не расходилась со спецификацией в контракте на поставку и в документах прихода. Поставщики так любят чудить, а ещё они любят в одну спецификацию хреначить одинаковую номенклатуру по разной цене(для этого и сделана разбивка на партии).

Нужно ещё какую-то схему проверки цен замутить в этом документе, не решил ещё как...
4. SedovSU@mail.ru 297 01.04.19 12:56 Сейчас в теме
Но вы можете и без запроса все это сделать (только в том случае если документ основание - это измерение)

Отбор = Новый Структура("Номенклатура, Партия, ДокументОснование", СтрокаТЧ.Наименование, СтрокаТЧ.Партия, Объект.ДокументОснование);
СрезПоследний = РегистрыСведений.ЦеныНоменклатуры.СрезПоследних(Дата, Отбор);
Цена = СрезПоследний.ЦенаЗаУпаковку;
user790607; +1 Ответить
6. user790607 02.04.19 04:39 Сейчас в теме
(4) нет, документ основание является регистратором(решил что не к чему плодить колонки с одинаковыми данными)
8. SedovSU@mail.ru 297 02.04.19 06:23 Сейчас в теме
(6) Ну тут возможно даже и проще будет

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


Соответственно можно все запросом сделать, установив параметры на номенклатуру, партию, регистратор
10. user790607 02.04.19 06:45 Сейчас в теме
(8) это просто в тело процедуры можно поместить? не совсем не пойму куда...
11. SedovSU@mail.ru 297 02.04.19 06:53 Сейчас в теме
(10) Ну вот смотрите у вас событие возникает когда вы меняете номенклатуру

Первый вариант

&НаКлиенте
Процедура НоменклатураНаименованиеПриИзменении(Элемент)
    СтрокаТЧ = Элементы.Номенклатура.ТекущиеДанные;
    СтрокаТЧ.ШтукВУпаковке = ПолучитьШтукВУпаковке(СтрокаТЧ.Наименование);
    СтрокаТЧ.ЦенаЭталон = ПолучитьЦенуИзРегистра(СтрокаТЧ.Наименование, СтрокаТЧ.Партия);
КонецПроцедуры

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

КонецФункции  
Показать


Второй вариант

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

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

Может подскажете ещё как лучше сделать сравнение эталонной цены с тем, что оператор вобьёт?

Я предполагаю добавить элемент табличной части формы с типом Булево, скрыть столбец эталонной цены и дальше пока не решил в какую процедуру и что лучше сделать... Наверное ПередПроведением проверку...
14. SedovSU@mail.ru 297 02.04.19 07:27 Сейчас в теме
(12) Лучше сделать в момент записи документа или проведения. Вы там добавите контроль. А вот с реквизитом типа булево лучше не нужно делать
15. user790607 02.04.19 07:31 Сейчас в теме
(14) почему?

Сделал вот так проверку:

&НаСервере
Процедура ОбработкаПроверкиЗаполненияНаСервере(Отказ, ПроверяемыеРеквизиты)
	Для Каждого ТекСтрока из Объект.Номенклатура Цикл
		Если ТекСтрока.ЦенаВерна = Ложь Тогда
			Отказ = Истина;
			Сообщить("Цена в спецификации отличается от цены прихода!");
		КонецЕсли
		КонецЦикла
	КонецПроцедуры
Показать
18. SedovSU@mail.ru 297 02.04.19 08:10 Сейчас в теме
(15) Ведь вам нужно всего лишь сделать проверку. В хорошем ведь случае когда все хорошо данный реквизит будет иметь постоянное значение ЦенаВерна - истина. Если вам нужно только лишь для проверки то лучше не добавлять все таки реквизит а проверять. Вот представьте вам нужно проверить реквизит ДокументоОснования - вы ведь для этого не будете делать доп. реквизит ДокументОснованиеЗаполнено с типом булево. Так что смотрите как вам будет удобнее. Конечно можно и с реквизитом и без реквизита
19. user790607 02.04.19 08:40 Сейчас в теме
(18) я не делаю реквизит документа, я делаю реквизит формы, по сути он нигде не хранится, а нужен только для отображения корректности цены по текущей строке
Прикрепленные файлы:
20. SedovSU@mail.ru 297 02.04.19 08:56 Сейчас в теме
(19) аааа ну если так,то я думаю как бы да тоже не плохой и при этом наглядный вариант - то есть пользователь видит верна цена или нет
user790607; +1 Ответить
21. user790607 02.04.19 08:58 Сейчас в теме
13. user790607 02.04.19 07:06 Сейчас в теме
Сделал так пока что:

&НаКлиенте
Процедура НоменклатураСтоимостьОднойУпаковкиПриИзменении(Элемент)
	СтрокаТЧ = Элементы.Номенклатура.ТекущиеДанные;
	СтрокаТЧ.Сумма = СтрокаТЧ.СтоимостьОднойУпаковки * СтрокаТЧ.КоличествоУпаковок;
	Если СтрокаТЧ.СтоимостьОднойУпаковки = СтрокаТЧ.ЦенаЭталон Тогда
		СтрокаТЧ.ЦенаВерна = Истина
	Иначе 
		СтрокаТЧ.ЦенаВерна = Ложь
	КонецЕсли	
КонецПроцедуры
Показать
16. acanta 02.04.19 07:39 Сейчас в теме
В типовой есть скидка, обычно ее меняют при фиксированной цене прайс листа. Цену со скидкой можно вычислять в отдельной колонке.
17. user790607 02.04.19 07:48 Сейчас в теме
(16) мы не торгуем, а соответственно скидки не вводим, поэтому не актуально...
Оставьте свое сообщение

Для получения уведомлений об ответах подключите телеграм бот:
Инфостарт бот