8.х Перебор партий при реализации

Тема в разделе "Конфигурирование на платформе "1С:Предприятие 8"", создана пользователем Geek, 3 май 2008.

  1. TopicStarter Overlay
    Geek
    Offline

    Geek Опытный в 1С

    Регистрация:
    3 апр 2008
    Сообщения:
    105
    Симпатии:
    0
    Баллы:
    26
    В табличной части документа реализации скажем внесена номенклатура 1
    есть две партии этой номенклатуры,
    одна партия - себестоимость 50,количество 100
    вторая партия себестоимость 100, количество 100 например
    В табличной части я набираю количество 30 ( тоесть не перекрываю первую партию при списании),себестоимость должна из запроса выйти 50
    Если я набираю например количество в табличной части 120,
    то нужно что бы из запроса вышли цыфры
    по первой партии кол- во 100 себестоимость 50
    по второй партии количество 20 себестоимость 100

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

    перебор партий должен идти по методу ФИФО тоесть так как партии будут списываться.


    Или может кто то подскажет другой способ контролировать себестоимость при продаже, что бы не было продажи ниже себестоимости.

    По среднему складу не подходит.
  2. TopicStarter Overlay
    Geek
    Offline

    Geek Опытный в 1С

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

    Я продаю первую партию по себестоимости средней по 75 р

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

    В результате первые 100 шт я продал по 75 (при реальн себестоимости 100)
    а вторую по 50 итого убыток.

    Вот я и хочу что бы при вводе в табличную часть номенклатуры и количества , находилось реальная себестоимость этой партии именно которая продается. .
    И если количество больше чем остаток этой партиий нужно искать следующую и искать себестоимость следующей партии, потом сложить суммы /количество и выдать новую себестоимость на данное количество
  3. LordKim
    Offline

    LordKim Опытный в 1С

    Регистрация:
    11 мар 2008
    Сообщения:
    118
    Симпатии:
    0
    Баллы:
    26
    Попробуй так:

    Код:
    НеобходимоСписать = Цифра из табличной части документа списания;
    Пока Не НеобходимоСписать = 0 Цикл
    //Получение себестоимости запросом, рекомендую использовать слова Первые 1 и упорядочивать по возрастанию даты, для FIFO
    НеобходимоСписать = НеобходимоСписать -  Мин(КоличествоВПартии, НеобходимоСписать);
    КонецЦикла;
    
  4. TopicStarter Overlay
    Geek
    Offline

    Geek Опытный в 1С

    Регистрация:
    3 апр 2008
    Сообщения:
    105
    Симпатии:
    0
    Баллы:
    26
    Можно сказать , я не понял :)
  5. LordKim
    Offline

    LordKim Опытный в 1С

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

    А если две себестоимости перекрещиваются - тебе придется разбивать на две строки.
    Или одной строкой, но по макс себестоимости.
  6. LordKim
    Offline

    LordKim Опытный в 1С

    Регистрация:
    11 мар 2008
    Сообщения:
    118
    Симпатии:
    0
    Баллы:
    26
    Для разбивки по строкам... :unsure:

    Код:
    НужноеКоличество = Введенное пользователем количество;
    Пока ВыборкаСебестоимости.Следующий() И НЕ (НужноеКоличество = 0) Цикл
    СтрокаТабличнойЧасти = ТабличнаяЧасть.Добавить();
    МинЦена=Макс(Окр(ВыборкаСебестоимости.Сумма/ВыборкаСебестоимости.Количество,2)); 
    СтрокаТабличнойЧасти.Товар = ТвойТовар;
    СтрокаТабличнойЧасти.Себестоимость=МинЦена;
    НужноеКоличество = НужноеКоличество - Мин(ВыборкаСебестоимости.Количество, НужноеКоличество); 
    КонецЦикла;
    
    
  7. TopicStarter Overlay
    Geek
    Offline

    Geek Опытный в 1С

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

    к строкам тч сейчас привяжу

    Мне еще разную наценку взависимости от контрагентов нужно было зделать. тут это вышло.
  8. LordKim
    Offline

    LordKim Опытный в 1С

    Регистрация:
    11 мар 2008
    Сообщения:
    118
    Симпатии:
    0
    Баллы:
    26
    Вместо этого:
    Код:
    Для Каждого Партия Из Результат Цикл
    Если СтрокаТЧ.Номенклатура=Партия.Номенклатура Тогда
    ...
    КонецЕсли;
    КонецЦикла;
    
    
    
    Можно это:
    Код:
    Отбор = Новый Структура("Номенклатура", СтрокаТЧ.Номенклатура);
    ВыборкаРезультат.Сбросить();
    Пока ВыборкаРезультат.НайтиСледующий(Отбор) Цикл
    ...
    
    КонецЦикла;
    
    
    
    Только тогда не
    Код:
    Результат=Запрос.Выполнить().Выгрузить();
    
    
    а
    Код:
    ВыборкаРезультат=Запрос.Выполнить().Выбрать(ОбходРезультатовЗапроса.Прямой);
    
    
    Хотя можно и так как ты написал)))
  9. TopicStarter Overlay
    Geek
    Offline

    Geek Опытный в 1С

    Регистрация:
    3 апр 2008
    Сообщения:
    105
    Симпатии:
    0
    Баллы:
    26
    То что я выще написал будет при проведении проверка, а для табличной строки я конечно переделаю чуть :)

    спс тебе
  10. LordKim
    Offline

    LordKim Опытный в 1С

    Регистрация:
    11 мар 2008
    Сообщения:
    118
    Симпатии:
    0
    Баллы:
    26
    Не за что, приятная задачка)
  11. TopicStarter Overlay
    Geek
    Offline

    Geek Опытный в 1С

    Регистрация:
    3 апр 2008
    Сообщения:
    105
    Симпатии:
    0
    Баллы:
    26
    Вот думаю ,боком мне такое не выйдет в базе? Каким либо образом.например при перепроведении задним числом и тд :)
  12. TopicStarter Overlay
    Geek
    Offline

    Geek Опытный в 1С

    Регистрация:
    3 апр 2008
    Сообщения:
    105
    Симпатии:
    0
    Баллы:
    26
    Если можешь, подскажи как решить эту задачу, а то есть моя тема ,но все молчат :)

    Подскажите код , я с этим зверем (ПланыВидовХарактеристик) еще плохо знаком :)

    Есть документ Поступление товаров.

    Для этого документа определено свойство и оно постоянно-

    ПланыВидовХарактеристик.СвойстваОбъектов.НайтиПоНаименованию("Альтернативный поставщик");

    У этого свойства есть разные значения,которые находятся -
    Справочники.ЗначенияСвойств (без указания свойств владельца справочник не открывается)

    Нужно в документе создать ЭлементФормы - поле ввода с кнопкой выбора, что бы

    Открывалась форма Справочники.ЗначенияСвойствОбъекта (ФормаСписка)
    для этого при открытии передать указанного выше владельца.

    При изменении() этого поля нужно произвести запись в регистр сведений

    ЗначениеСвойствОбъекта с измерениями
    Объект,свойство

    и ресурс - значение
  13. LordKim
    Offline

    LordKim Опытный в 1С

    Регистрация:
    11 мар 2008
    Сообщения:
    118
    Симпатии:
    0
    Баллы:
    26
    Да, я читал.
    Сходу не подскажу.

    Попробуй перехватывать событие "НачалоВыбора" у поля выбора в диалоге.

    Ставить стандартную обработку в ложь и форму открывать для выбора программно. Задавая владельцем формы этот документ.

    При изменении перехватывай событие "ОбработкаВыбора"
    И пиши в регистр.

Поделиться этой страницей