Версия для печати темы (https://pro1c.org.ua/index.php?s=c4a39168f3d248f70568f0dc022fbd95&showtopic=23945)

Нажмите сюда для просмотра этой темы в обычном формате

Украинский 1С форум: всё про 1С 8.3, 1С 8.2, 1С 8.1, 1С 8.0, 1С 7.7 _ Программирование управляемых форм 1С 8.2 _ Расчитать учетную цену и учетную сумму

Автор: Анна Команкова 04.07.15, 21:25

Уважаемые программисты, прошу помогите, пожалуйста.

Есть расходная накладная с реквизитами: Контрагент, Склад, ВидЦены, ТЧРасхНакл с реквизитами: ТМЦ, Цена, Количество, Сумма, УчЦена, УчСумма. И есть регистр накопления ТМЦ с измерениями ТМЦ, Склад и ресурсами Количество, Сумма.
Необходимо рассчитать УчЦену и УчСумму при проведении расходной накладной по дате.
Я в 1с вообще мало, что знаю. Пыталась делать сама. Из того, что нашла поняла, что нужно сначала в модуле объекта Процедура ПередЗаписью получить запросом остатки по количеству и сумме, а потом в Процедуре ОбработкаПроведения посчитать уч. цену и уч. сумму используя временные таблицы.
Запрос я сделала, остатки получила, а вот что и как нужно делать с временными таблицами вообще понять не могу.

До последнего не хотела никого напрягать, думала сама разберусь. Не получается((

Процедура ПередЗаписью(Отказ, РежимЗаписи, РежимПроведения)
    Для Каждого СтрТЧ ИЗ ТЧРасхНакл Цикл
        Запрос = Новый Запрос;
        Запрос.Текст =     
        
        "ВЫБРАТЬ
        |    ТМЦОстатки.КоличествоОстаток,
        |    ТМЦОстатки.СуммаОстаток,
        |    ВЫРАЗИТЬ (ЕСТЬNULL(ТМЦОстатки.СуммаОстаток, 0) / ЕСТЬNULL(ТМЦОстатки.КоличествоОстаток, 1) КАК ЧИСЛО(15,2)) КАК УчЦена
        |ИЗ
        |    РегистрНакопления.ТМЦ.Остатки(&Дата, ) КАК ТМЦОстатки
        |ГДЕ
        |    ТМЦОстатки.ТМЦ = &ТМЦ
        |    И ТМЦОстатки.Склад = &Склад";
        Запрос.УстановитьПараметр("ТМЦ",СтрТЧ.ТМЦ);
        Запрос.УстановитьПараметр("Склад", Склад);
        Запрос.УстановитьПараметр("Дата", Дата);
        Результат = Запрос.Выполнить();
        ВыборкаИзЗапроса = Результат.Выбрать();
        Если ВыборкаИзЗапроса.Следующий() Тогда
            Если СтрТЧ.Количество > ВыборкаИзЗапроса.КоличествоОстаток Тогда
            Сообщить("Товара "+СтрТЧ.ТМЦ +" не хватает на складе");
            Отказ = Истина;
            КонецЕсли;
        Иначе
            Сообщить("Товара "+СтрТЧ.ТМЦ +" нет на складе");
            Отказ = Истина;
        КонецЕсли;
    КонецЦикла;
КонецПроцедуры

Автор: 1cnovice 05.07.15, 13:14

Проверка на остаток лучше делать в процедуре "ОбработкаПроведения".

Вообще, запрос в цикле для проверки остатка (и вобще) это мягко говоря не красиво.

я бы проверил остатки тех товаров которые в документе так:


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

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



Рассчитать УчЦену и УчСумму. тут не понятно, куда ее алгоритм должен заполнять. Если в документ расходной то не понятен практический смысл от этого. Может все таки нужно списать товары с регистра ТМЦ?












Автор: Анна Команкова 05.07.15, 14:36

ну по заданию заполнить в табличной части накладной два последних поля, а для чего я если честно не знаю. Я что в бухгалтерии, что в 1с мягко сказать не разбираюсь


Спасибо большое, что вы откликнулись))
А то я уже в отчаянии((

Извините, а Вы не могли бы объяснить, что такое Левое соединение?

Если я правильно понимаю, то Вы запросом по каждому товару определяете суммарное количество и записываете в временную таблицу, потом в этой таблице уже определяете остатки по количеству и что потом происходит? Остатки из временной таблицы переносятся в остатки регистра накопления ТМЦОстатки или что((?

Если Вам не сложно, можете изменить созданный запрос, что бы в поля табличной части (ТЧРасхНакл) УчЦена и УчСумма заполнились при проведении. Я понимаю, что это наглешь и что Вы и так потратили свое время и помогли, но просто я ВООБЩЕ не знаю что и куда. Пожалуйста.



Я когда перечитываю, что пишу, понимаю, что написала какую то ахинею и знающий человек наверняка просто в шоке с того, какие есть бестолковые люди((

Автор: logist 05.07.15, 15:20

Цитата(Анна Команкова @ 05.07.15, 15:36) *
поля табличной части (ТЧРасхНакл) УчЦена и УчСумма заполнились при проведении.

Это не логично и не принято - изменять данные документа в проведении и записи, т.к. это вызывает повторную запись документа.
Если Вам нужно заполнять эти поля в документе, то это надо делать ПередЗаписью.

Автор: Анна Команкова 05.07.15, 16:05

та я не против, Вы понимаете, мне дали задание. Дословно: организовать расчет учетных цен при проведении расходной накладной по дате.

Перед этим было задание создать расх. накладную (еще пока без полей уч. цена и уч. сумма) и провести его по регистру накопления ТМЦ, что я и сделала.
Потом, задание усложнили: добавить в табл часть ТЧРасхНакл 2 поля - уч. цена и уч. сумма, посчитать эти значения при новом проведении того же, уже проведенного, документа. Хорошо вы говорите, что это не правильно так делать и нужно перед тем как записывать посчитать, а потом уже проводить. А как, как это сделать?
Проблема вся в том, что я не знаю как сделать не при проведении, ни при перед записью. Никак((

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


Автор: 1cnovice 05.07.15, 16:34


Автор: Анна Команкова 05.07.15, 17:52

Спасибо, спасибо, спасибо Вам огромное, что Вы такой отзывчивый человек, что помогаете таким бестолковым как я)). Когда оно заработало очень обрадовалось, теперь осталось разобрать что к чему и что куда))

а можете еще ответить, если в расходной накладной первая запись ручка и вторая запись ручка, то почему учетная цена и сумма записывается только в поле там,где первая запись ручка, а в следующей нету ничего))






Это вопрос к 1сnovice))


и это по первому предложенному варианту

А во втором ошибку выдает((


Ошибка при выполнении обработчика - 'ПередЗаписью'
по причине:
{Документ.РасходнаяНакладная.МодульОбъекта(50)}: Значение не является значением объектного типа (УчЦена)
ТоварВТЧ.УчЦена = УчЦена;

Автор: 1cnovice 05.07.15, 19:11

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

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


Сорри, упустил в запросе указать ссылку на текущий документ. Вот так должно работать

Такс... Версия 1.100500 процедуры перед записью smile.gif

Чтото я туплю. Ссылки на документ процедуре перед записью еще нету.

О так правильнее будет.

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


ОбработкаПроведения без изменений

Автор: Анна Команкова 05.07.15, 19:16

Да работает, только значения уч. цен записываются после 2-го проведения документа. С чем это может быть связано?

Большое спасибо, я уже где то 2-ю неделю с этим заданием мучаюсь, а вы так с ним расправились быстро)) Надеюсь, что в будущем я тоже смогу помогать другим)
Спасибо!


А можно, если что то будет не понятно по этому коду, спросить?


Автор: 1cnovice 05.07.15, 19:25

Цитата(Анна Команкова @ 05.07.15, 20:16) *
Да работает, только значения уч. цен записываются после 2-го проведения документа. С чем это может быть связано?


В последней версии "ПередЗаписью" должно с первого проведения рассчитываться.

Цитата
А можно, если что то будет не понятно по этому коду, спросить?


Пишите, как смогу отвечу

Автор: Анна Команкова 05.07.15, 20:36

Все равно первое проведение первого документа срабатывает со 2-го раза.
А все последующие документы срабатывают сразу


Все работает, извините))

Украинский 1С форум: всё про 1С 8.3, 1С 8.2, 1С 8.1, 1С 8.0, 1С 7.7
https://pro1c.org.ua