1. Мегаконкурс в апреле "Приведи друзей на codeby". Дарим деньги, подписку на журнал хакер и выдаем статус "Paid Access". Подробнее ...

    Скрыть объявление

Списание по партиям

Тема в разделе "1C и всё что с ней связано", создана пользователем NocturnalMortum, 11 мар 2011.

Наш партнер Genesis Hackspace
  1. NocturnalMortum

    NocturnalMortum Гость

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

    Заранее благодарен.
     
  2. unknown181538

    unknown181538 НеГуру
    1C Team

    Регистрация:
    28 дек 2008
    Сообщения:
    1.418
    Симпатии:
    0
    Так ведь одна накладная в результате запроса остается.
     
  3. NocturnalMortum

    NocturnalMortum Гость

    Он все так же не берет 1-ю накладную в цикл. Еще не получается условие отбора в запросе построить, он выбирает всю информацию из регистра. Может поменять таблицу регистра? И как сделать условие?
     
  4. unknown181538

    unknown181538 НеГуру
    1C Team

    Регистрация:
    28 дек 2008
    Сообщения:
    1.418
    Симпатии:
    0
    Таблицу остатков надо брать!
     
  5. NocturnalMortum

    NocturnalMortum Гость

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

    //КонецЕсли;
    КонецЦикла;
    КонецЦикла;
     
  6. unknown181538

    unknown181538 НеГуру
    1C Team

    Регистрация:
    28 дек 2008
    Сообщения:
    1.418
    Симпатии:
    0
    Это неправильно. Функция Следующий() делает перемещение по выборке.
     
  7. NocturnalMortum

    NocturnalMortum Гость

    не могли бы подсказать как будет вернее?
     
  8. unknown181538

    unknown181538 НеГуру
    1C Team

    Регистрация:
    28 дек 2008
    Сообщения:
    1.418
    Симпатии:
    0
    Надо еще сделать выборку из выборки вложенную и обойти партии.
     
  9. puh14

    puh14 Well-Known Member
    1C Team

    Регистрация:
    11 июл 2008
    Сообщения:
    1.412
    Симпатии:
    0
    В такой структуре очень геморно получится - лучше сделать так - первый запрос, выборка номенклатуры и количества в накладной. Во время обхода его выборки запоминается количество к списанию и запускается второй запрос к партиям по номенклатуре текущей выборки - его результат выгружается в ТЗ, сортируется (если надо fifo lifo), а дальше списывается пока количество к списанию не станет равным нулю. Важен еще один момент - если партия списывается целиком, то и себестоимость списывается целиком, без всяких пропорциональных расчетов, иначе могут вылезти копеечные остатки при нулевом количестве.
     
  10. NocturnalMortum

    NocturnalMortum Гость

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


    КонецЦикла;
    КонецЦикла;

    тока он все равно не работает =)
     
  11. puh14

    puh14 Well-Known Member
    1C Team

    Регистрация:
    11 июл 2008
    Сообщения:
    1.412
    Симпатии:
    0
    1)А записать движения? хотя если это проведение - должно и так сработать


    2)собственно выше писал про пропорциональное списание. пример - себестоимость 300,01 колво на списание 30000, остаток 30000. Из-за округлений ресурсов регистра у вас зависнет 1 копейка при нулевом количестве.

    А в отладчике что видно? по второй выборке он идет? и кстати как идет? не спишет ли он партию от другой номенклатуры?
     
  12. unknown181538

    unknown181538 НеГуру
    1C Team

    Регистрация:
    28 дек 2008
    Сообщения:
    1.418
    Симпатии:
    0
    Запрос в цикле? Еще и в ТЗ?... А вдруг кто увидит?) Простейшее списание надо учиться делать, а то потом что-нибудь посложнее попадется...
    300.01*30000/30000 = 300.01. Неужели нет? Это не тот случай.

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

    NocturnalMortum Гость

    блин один фиг делает одно движение и списывает одной массой...
     
  14. unknown181538

    unknown181538 НеГуру
    1C Team

    Регистрация:
    28 дек 2008
    Сообщения:
    1.418
    Симпатии:
    0
    А запрос правильный результат возвращает?
     
  15. NocturnalMortum

    NocturnalMortum Гость

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


    Запрос.УстановитьПараметр("Ссылка",ссылка);
    Запрос.УстановитьПараметр("МоментВремени", МоментВремени());
    ВыборкаИтоги = Запрос.Выполнить().Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам);
    Пока ВыборкаИтоги.Следующий() цикл
    СписатьКол=ВыборкаИтоги.КоличествоНакл;

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

    Если Отказ Тогда
    Продолжить;
    КонецЕсли;

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


    КонецЦикла;
    КонецЦикла;


    КонецПроцедуры
    все работает, спасибо за помощь.
     
  16. unknown181538

    unknown181538 НеГуру
    1C Team

    Регистрация:
    28 дек 2008
    Сообщения:
    1.418
    Симпатии:
    0
    Да, забыл это посоветовать)
     
Загрузка...

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