Форум 1С
Программистам, бухгалтерам, администраторам, пользователям
Задай вопрос - получи решение проблемы
29 мар 2024, 11:31

Списание по партиям - дополните код

Автор qwedor, 28 мар 2014, 02:23

0 Пользователей и 1 гость просматривают эту тему.

qwedor

Вот написал код. вроде как работает но не полностью.

При условии что Количество в документе товара меньше чем в партии  - проблем нету. а если больше?

ДЛя Каждого СтрокаТовары ИЗ ТаблицаТоваров Цикл
ОсталосьСписать =СтрокаТовары.КоличествоВдокументе;

Для каждого СтрокаПартии Из Партии Цикл

Если СтрокаТовары.Номенклатура = СтрокаПартии.Номенклатура  Тогда

Если ОсталосьСписать <= СтрокаПартии.КоличествоОстаток  Тогда
КолСписание = ОсталосьСписать;

Если ОсталосьСписать =  СтрокаПартии.КоличествоОстаток
ТОгда
СуммаСписания =  СтрокаПартии.СтоимостьОстаток;
Иначе
СуммаСписания = СтрокаПартии.СтоимостьОстаток / СтрокаПартии.КоличествоОстаток *  СтрокаТовары.КоличествоВдокументе;
КонецЕсли;

СтрокаПартии.КоличествоОстаток = СтрокаПартии.КоличествоОстаток - СтрокаТОвары.КоличествоВДокументе;
СтрокаПартии.СтоимостьОстаток = СтрокаПартии.СтоимостьОстаток - СуммаСписания;
ОсталосьСписать = ОсталосьСписать - КОлСписание;
Иначе
ЧТО ТУТ НАПИСАТЬ?


Помогите с выражением. заранее Спасибо.

прилагаю полный листинг.:


Движения.ОстаткиТоваров.Записывать = Истина;
   Движения.Продажи.Записывать = Истина;

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

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

Результат = Запрос.Выполнить();
    ТаблицаТоваров = Результат.Выгрузить();




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

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

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


ДЛя Каждого СтрокаТовары ИЗ ТаблицаТоваров Цикл
ОсталосьСписать =СтрокаТовары.КоличествоВдокументе;

Для каждого СтрокаПартии Из Партии Цикл

Если СтрокаТовары.Номенклатура = СтрокаПартии.Номенклатура  Тогда

Если ОсталосьСписать <= СтрокаПартии.КоличествоОстаток  Тогда
КолСписание = ОсталосьСписать;

Если ОсталосьСписать =  СтрокаПартии.КоличествоОстаток
ТОгда
СуммаСписания =  СтрокаПартии.СтоимостьОстаток;
Иначе
СуммаСписания = СтрокаПартии.СтоимостьОстаток / СтрокаПартии.КоличествоОстаток *  СтрокаТовары.КоличествоВдокументе;
КонецЕсли;

СтрокаПартии.КоличествоОстаток = СтрокаПартии.КоличествоОстаток - СтрокаТОвары.КоличествоВДокументе;
СтрокаПартии.СтоимостьОстаток = СтрокаПартии.СтоимостьОстаток - СуммаСписания;
ОсталосьСписать = ОсталосьСписать - КОлСписание;
Иначе
ЧТО ТУТ НАПИСАТЬ?














КонецЕсли;
//Регистр ОстаткиТоваров
Движение = Движения.ОстаткиТоваров.ДобавитьРасход ();
Движение.Период = Дата;
Движение.Партия = СтрокаПартии.Партия;
Движение.Номенклатура = СтрокаТовары.Номенклатура;
Движение.Количество = ОсталосьСписать;
Движение.Стоимость =  СуммаСписания;

//Регистр Продажи

Движение = Движения.Продажи.Добавить();
Движение.Период = Дата;
Движение.Номенклатура = СтрокаТовары.Номенклатура;
Движение.Контрагент = Контрагент;
Движение.Количество = СтрокаТовары.КоличествоВдокументе;
Движение.Выручка = СтрокаТовары.СуммаВДокументе;
Движение.Себестоимость =  СуммаСписания;





КонецЕсли;


КонецЦикла;


КонецЦикла;

Besart

смотрите тут, там во многих задачах есть списание по партиям

qwedor

Спасибо, нашел решение :zebzdr:.  правда немного другим вариантом.
Осталось конечно еще вопросы :)

qwedor

добрый день.Задачу  то я решил но у меня возник вопрос. Все работает. и правильно считает. 


.....
ВыборкаНоменклатура = Результат.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам);

Пока ВыборкаНоменклатура.Следующий() Цикл
Если НЕ ВыборкаНоменклатура.Номенклатура.Услуга Тогда


Если ВыборкаНоменклатура.Количество > ВыборкаНоменклатура.КоличествоОстаток Тогда


Сообщение = Новый СообщениеПользователю;
Сообщение.Текст = "Не хватает товара " + ВыборкаНоменклатура.Номенклатура  + " из требуемых " +
ВыборкаНоменклатура.Количество + " на складе осталось " + ВыборкаНоменклатура.КоличествоОстаток;
Сообщение.Сообщить();
Отказ = Истина;
КонецЕсли;


  НеобходимоСписать = ВыборкаНоменклатура.Количество;
 
  ВыборкаДетальныеЗаписи = ВыборкаНоменклатура.Выбрать();

Пока ВыборкаДетальныеЗаписи.Следующий() И НеобходимоСписать > 0 Цикл

КоличествоКСписанию = Мин(НеобходимоСписать, ВыборкаДетальныеЗаписи.КоличествоОстаток);


Если

КоличествоКСписанию = ВыборкаДетальныеЗаписи.КоличествоОстаток
Тогда
   СуммаКСписанию = ВыборкаДетальныеЗаписи.СтоимостьОстаток;
   Иначе
   СуммаКСписанию = ВыборкаДетальныеЗаписи.СтоимостьОстаток / ВыборкаДетальныеЗаписи.КоличествоОстаток * КоличествоКСписанию;
   КонецЕсли;

// Движения  для Регистров Остатки ТОваров и Продажи для Не Услуги
   
    Движение = Движения.ОстаткиТоваров.ДобавитьРасход ();
    Движение.Период = Дата;
    Движение.Партия = ВыборкаДетальныеЗаписи.Партия;
    Движение.Номенклатура = ВыборкаДетальныеЗаписи.Номенклатура;
    Движение.Количество = КоличествоКСписанию;
    Движение.Стоимость =  СуммаКСписанию;


// Вот тут
НеобходимоСписать = НеобходимоСписать - КоличествоКСписанию;

    //Регистр Продажи
   
    Движение = Движения.Продажи.Добавить();
    Движение.Период = Дата;
    Движение.Номенклатура =  ВыборкаДетальныеЗаписи.Номенклатура;
    Движение.Контрагент = Контрагент;
        Движение.Количество = КоличествоКСписанию;
    Движение.Выручка = ВыборкаДетальныеЗаписи.Сумма;
    Движение.Себестоимость = СуммаКСписанию;




Если я удалю строку :
       
// Вот тут
НеобходимоСписать = НеобходимоСписать - КоличествоКСписанию;


Списывает с каждой партии по количеству (например 2 партии по 20 штук у меня. продаю 5 штук. - спишет 5 с каждой.  в итоге - остаток 10..:wacko:)
С этой строкой - все в порядке. но в движениях у меня отсутствует: "НеобходимоСписать".
как же оно влияет на движения?
"

l2qwe

Может вывести продажу за внутренний цикл?

   
ПродажаКоличество = 0;
ПродажаСумма  = 0;
ПродажаСебестоимость = 0;

Пока ВыборкаДетальныеЗаписи.Следующий() И НеобходимоСписать > 0 Цикл     
КоличествоКСписанию = Мин(НеобходимоСписать, ВыборкаДетальныеЗаписи.КоличествоОстаток);
Если КоличествоКСписанию = ВыборкаДетальныеЗаписи.КоличествоОстаток Тогда
СуммаКСписанию = ВыборкаДетальныеЗаписи.СтоимостьОстаток;
Иначе
СуммаКСписанию = ВыборкаДетальныеЗаписи.СтоимостьОстаток / ВыборкаДетальныеЗаписи.КоличествоОстаток * КоличествоКСписанию;
КонецЕсли;

// Движения  для Регистров Остатки ТОваров и Продажи для Не Услуги       

Движение = Движения.ОстаткиТоваров.ДобавитьРасход ();
Движение.Период = Дата;
Движение.Партия = ВыборкаДетальныеЗаписи.Партия;
Движение.Номенклатура = ВыборкаДетальныеЗаписи.Номенклатура;
Движение.Количество = КоличествоКСписанию;
Движение.Стоимость =  СуммаКСписанию;

ПродажаКоличество = ПродажаКоличество+КоличествоКСписанию;
ПродажаСумма  = ПродажаСумма+ВыборкаДетальныеЗаписи.Сумма;
ПродажаСебестоимость = ПродажаСебестоимость+ВыборкаДетальныеЗаписи.Сумма;
// Вот тут
НеобходимоСписать = НеобходимоСписать - КоличествоКСписанию;   
//Регистр Продажи                                               
КонецЦикла;
Движение = Движения.Продажи.Добавить();
Движение.Период = Дата;
Движение.Номенклатура =  ВыборкаДетальныеЗаписи.Номенклатура;
Движение.Контрагент = Контрагент;
Движение.Количество = ПродажаКоличество ;
Движение.Выручка = ПродажаСумма;
Движение.Себестоимость = СуммаКСписанию;

qwedor

Цитата: l2qwe от 03 апр 2014, 13:19
Может вывести продажу за внутренний цикл?

так тоже может. но у меня тоже все работает. но я не могу понять значение этой строки:

       
// Вот тут
НеобходимоСписать = НеобходимоСписать - КоличествоКСписанию;


Если  она есть - все работает, в противном случае:
Списывает с каждой партии по количеству (например 2 партии по 20 штук у меня. продаю 5 штук. - спишет 5 с каждой.  в итоге - остаток 10..:wacko:)

l2qwe

Эта строка определяет сколько осталось списать.

То есть надо нам списать 17 пимпачек
Есть 3 партии (4,40,20)
Таким образом у нас внутренний цикл максимум 3 прохода
Но мы должны списать (4,(17-4) = 13 ,0)
На второй итерации мы видим что остаток большем чем нам необходимо списать, досписываем остаток (13) и сбрасывем в 0 после чего по условию цикла мы выходим
НеобходимоСписать > 0

qwedor


Теги:

Похожие темы (5)

Рейтинг@Mail.ru

Поиск