Имя: Пароль:
1C
1С v8
Достать цену из реквизита регистра
, ,
0 d_pinchuk
 
27.08.19
19:21
Цель - запись в регистр с закупочной ценой.
Код, который пришел в голову выглядит не совсем верным решением, подскажите альтернативу...

    // регистр ОстаткиТоваров Расход
    Движения.ОстаткиТоваров.Записывать = Истина;
    Для Каждого ТекСтрокаТовары Из Товары Цикл
        Движение = Движения.ОстаткиТоваров.Добавить();
        Движение.ВидДвижения = ВидДвиженияНакопления.Расход;
        Движение.Период = Дата;
        Движение.Номенклатура = ТекСтрокаТовары.Номенклатура;
        Движение.Количество = ТекСтрокаТовары.Количество;
        
        Запрос = Новый Запрос;
        Запрос.Текст =
        "ВЫБРАТЬ
        |    ОстаткиТоваров.ЗакупочнаяЦена КАК ЗакупочнаяЦена
        |ИЗ
        |    РегистрНакопления.ОстаткиТоваров КАК ОстаткиТоваров
        |ГДЕ
        |    ОстаткиТоваров.Номенклатура = &Номенклатура";
        
        Запрос.УстановитьПараметр("Номенклатура", ТекСтрокаТовары.Номенклатура);
        
        РезультатЗапроса = Запрос.Выполнить();
        
        Выборка = РезультатЗапроса.Выбрать();
        
        Выборка.Следующий();
        
        Движение.Сумма = ТекСтрокаТовары.Количество * Выборка.ЗакупочнаяЦена;
        
    КонецЦикла;
1 d_pinchuk
 
27.08.19
19:21
То есть, если 50 товаров, то 50 запросов.
Как-то ужасно вышло...
2 RomanYS
 
27.08.19
19:46
А у Вас есть понимание, что Ваш запрос может много записей возвращать (по одной номенклатуре), а используете Вы первую попавшуюся?
3 Sapiens_bru
 
27.08.19
19:50
(2) То есть запрос к реальной таблице регистра накопления вас не смутил, только выборка первого?
4 Sapiens_bru
 
27.08.19
19:53
(1) Чтобы вышло чуть менее ужасно можно посмотреть Павел Чистов СпецКурс, бесплатно на Ютубе. На ИТС, куда у вас есть доступ, имеется книга Хрусталевой по языку запросов 1С. Также можно озаботиться платными курсами.
5 d_pinchuk
 
27.08.19
19:54
(3) В виртуальных нет реквизита
6 d_pinchuk
 
27.08.19
19:54
(2) Точно
7 Sapiens_bru
 
27.08.19
20:02
(5) Как думаете, почему?
И что ваш код будет делать если я куплю 5 штук по 100 , потом ещё пять по 200 и продам семь штук?
8 d_pinchuk
 
27.08.19
20:02
(2) Ну а если тот же вопрос и уже такой код:

//регистр ОстаткиТоваров Расход
    Движения.ОстаткиТоваров.Записывать = Истина;
    
    Для Каждого ТекСтрокаТовары Из Товары Цикл
        
        Движение = Движения.ОстаткиТоваров.Добавить();
        Движение.ВидДвижения = ВидДвиженияНакопления.Расход;
        Движение.Период = Дата;
        Движение.Номенклатура = ТекСтрокаТовары.Номенклатура;
        Движение.Количество = ТекСтрокаТовары.Количество;
        
        Запрос = Новый Запрос;
        Запрос.Текст =
        "ВЫБРАТЬ
        |    ОстаткиТоваров.ЗакупочнаяЦена КАК ЗакупочнаяЦена,
        |    ОстаткиТоваров.Количество КАК Количество
        |ИЗ
        |    РегистрНакопления.ОстаткиТоваров КАК ОстаткиТоваров
        |ГДЕ
        |    ОстаткиТоваров.Номенклатура = &Номенклатура";
        
        Запрос.УстановитьПараметр("Номенклатура", ТекСтрокаТовары.Номенклатура);
        
        РезультатЗапроса = Запрос.Выполнить();
        
        Выборка = РезультатЗапроса.Выбрать();
        
        СредняяЦена = 0;
        
        Пока Выборка.Следующий() Цикл
            
            СредняяЦена = Выборка.Сумма / Выборка.Количество;
            
            
        КонецЦикла;
        
        Движение.Сумма = СредняяЦена * ТекСтрокаТовары.Количество;
        
    КонецЦикла;
9 d_pinchuk
 
27.08.19
20:04
СредняяЦена = СредняяЦена + Выборка.Сумма / Выборка.Количество;
10 Sapiens_bru
 
27.08.19
20:13
(9) Купил одну за рубль, затем ещё одну за рубль и ещё одну за рубль - СредняяЦена 3 рубля
11 d_pinchuk
 
27.08.19
20:22
(10) Точно xD

Ну тогда первый вопрос и вот:

    //регистр ОстаткиТоваров Расход
    Движения.ОстаткиТоваров.Записывать = Истина;
    
    Для Каждого ТекСтрокаТовары Из Товары Цикл
        
        Движение = Движения.ОстаткиТоваров.Добавить();
        Движение.ВидДвижения = ВидДвиженияНакопления.Расход;
        Движение.Период = Дата;
        Движение.Номенклатура = ТекСтрокаТовары.Номенклатура;
        Движение.Количество = ТекСтрокаТовары.Количество;
        
        Запрос = Новый Запрос;
        Запрос.Текст =
        "ВЫБРАТЬ
        |    ОстаткиТоваров.ЗакупочнаяЦена КАК ЗакупочнаяЦена,
        |    ОстаткиТоваров.Количество КАК Количество,
        |    ОстаткиТоваров.Сумма КАК Сумма
        |ИЗ
        |    РегистрНакопления.ОстаткиТоваров КАК ОстаткиТоваров
        |ГДЕ
        |    ОстаткиТоваров.Номенклатура = &Номенклатура
        |    И ОстаткиТоваров.Регистратор <> &Ссылка";
        
        Запрос.УстановитьПараметр("Номенклатура", ТекСтрокаТовары.Номенклатура);
        Запрос.УстановитьПараметр("Ссылка", Ссылка);
        
        РезультатЗапроса = Запрос.Выполнить();
        
        Выборка = РезультатЗапроса.Выбрать();
        
        Сумма = 0;
        Количество = 0;
        Пока Выборка.Следующий() Цикл
            
            Сумма = Сумма + Выборка.Сумма;
            Количество = Количество + Выборка.Количество;        
            
        КонецЦикла;
        
        СредняяЦена = Сумма / Количество;
    
        Движение.Сумма = СредняяЦена * ТекСтрокаТовары.Количество;
        
    КонецЦикла;
12 d_pinchuk
 
27.08.19
20:33
подскажите альтернативу...
13 Sapiens_bru
 
27.08.19
20:47
(12) Альтернатива - позвать специалиста, если по каким-то причинам решение из (4) вас не устраивает.
Ваша задача это малая часть экзамена 1С специалист по платформе.
Всё методики решения подробно описаны и доступны.
14 d_pinchuk
 
27.08.19
20:50
(13) Какого специалиста? Я чисто для себя решаю..
Два документа заказ и продажа.
Цель - отчет который показывает на конец дня остаток товара и сумму в закупочных ценах.
Хочу реализовать с  помощью одного регистра.
Решение самому себе не нравится - не оптимально.
15 mikecool
 
27.08.19
20:53
(14) возьми .Остатки(, Номенклатура В (&СписокНоменклатуры))
16 d_pinchuk
 
27.08.19
21:06
(15) Выборка из виртуальной таблицы с условием "Номеклатура совпадает с любой из Списка".
А как это мне поможет оптимизировать проводку документа?
17 mikecool
 
27.08.19
21:10
(16) одним запросом забираешь все остатки, затем делаешь с ними что хочешь
18 RomanYS
 
27.08.19
21:15
(14) Ответьте сначала на вопрос, что такое "сумма в закупочных ценах"
-это количество * цена по прайсу "закупочный"
-оценка товара в закупочных ценах, тогда нужен полноценный партионный учет с последующими уточнениями (по-среднему/фифо)

Ваш вариант никакую задачу не решает, оптимальность здесь не причем
19 d_pinchuk
 
27.08.19
21:29
(18)
Документ-приход записывает "номенклатура, сумма = количество * цена"
Нужно при проведении документа-расхода, то бишь продажи списывать товар, где сумма товара "сумма = количество * средняяцена(себестоимость).
Это все используя один регистр накопления остатки.

Это нужно для того, чтобы корректно работал отчет, который показывает на конец дня остаток товара и сумму в "закупочных" ценах.

Он решает поставленную задачу, но хотелось бы решить более оптимально.
20 RomanYS
 
27.08.19
21:41
(19) У регистра должно быть два ресурса количество и сумма. Цену в регистре хранить смысла нет(если только измерением - но это совершено другая задача).


Если мы (11) рассматриваем

1. "И ОстаткиТоваров.Регистратор <> &Ссылка" - тупо ошибка, регистратора нет в остатках
2. Закупочную цену убрать, тогда ВТ вернет свернутые остатки и цикл по выборке будет не нужен - там будет одна запись(или не будет)
3. Запрос в цикле нужно убирать, тут два варианта: пихать ТЧ в запрос и соединять с остатками или запрос с (15) последующая "хитрая" выборка
21 d_pinchuk
 
27.08.19
21:52
(20) 1. А если я перепровожу документ? Или необходимо установить удаление движение "удалять автоматически"?
2. Убрал давно , получается запрос к остаткам группировку делает по сумме в разрезе номенклатуры. Не знал.
3. Ага, тогда есть логика сделать через "хитрую№ выборку, если происходит группировка
22 mikecool
 
27.08.19
22:01
(21) у меня впечатление, что ты ничего не знаешь про регистр накопления...
23 RomanYS
 
27.08.19
22:02
(21) 1. вроде "классическое" решение - брать остатки на МоментВремени документа.
24 d_pinchuk
 
27.08.19
22:10
(22) С нуля пару месяцев учусь. (23) Вот так получилось.
//регистр ОстаткиТоваров Расход
    Движения.ОстаткиТоваров.Записывать = Истина;
    
    Запрос = Новый Запрос;
    Запрос.Текст =
        "ВЫБРАТЬ
        |    ОстаткиТоваровОстатки.Номенклатура КАК Номенклатура,
        |    ОстаткиТоваровОстатки.КоличествоОстаток КАК Количество,
        |    ОстаткиТоваровОстатки.СуммаОстаток КАК Сумма
        |ИЗ
        |    РегистрНакопления.ОстаткиТоваров.Остатки(
        |            &МоментВремени,
        |            Номенклатура В
        |                (ВЫБРАТЬ
        |                    ПродажаТовараТовары.Номенклатура КАК Номенклатура
        |                ИЗ
        |                    Документ.ПродажаТовара.Товары КАК ПродажаТовараТовары
        |                ГДЕ
        |                    ПродажаТовараТовары.Ссылка = &Ссылка)) КАК ОстаткиТоваровОстатки";
    
    Запрос.УстановитьПараметр("МоментВремени", МоментВремени());
    Запрос.УстановитьПараметр("Ссылка", Ссылка);
    
    РезультатЗапроса = Запрос.Выполнить();
    
    Выборка = РезультатЗапроса.Выбрать();
    
    Пока Выборка.Следующий() Цикл
        
        Движение = Движения.ОстаткиТоваров.Добавить();
        Движение.ВидДвижения = ВидДвиженияНакопления.Расход;
        Движение.Период = Дата;
        Движение.Номенклатура = Выборка.Номенклатура;
        
        СтрокаТЧ = Товары.Найти(Выборка.Номенклатура, "Номенклатура");
        Движение.Количество = СтрокаТЧ.Количество;
        
        СредняяЦена = Выборка.Сумма / Выборка.Количество;
        Движение.Сумма = СредняяЦена * СтрокаТЧ.Количество;
        
    КонецЦикла;
25 RomanYS
 
27.08.19
22:17
(24) лучше.
Но что будет,
если остатка не будет? //у тебя ничего не спишется
если остатка не хватит? //у тебя спишется в минус
если номенклатура встречается в ТЧ не сколько раз //у тебя спишется только первая строка

В общем при всем прогрессе пора уже найти разбор задачи со всеми возможными косяками
26 d_pinchuk
 
27.08.19
22:25
(25) Спасибо)
Понятно, в общем нужно учиться на чужом опыте...
Выдавать глобальные идеи — это удовольствие; искать сволочные маленькие ошибки — вот настоящая работа. Фредерик Брукс-младший