Вход | Регистрация

1С:Предприятие :: 1С:Предприятие 8 общая

Подозрение на зацикливание

Подозрение на зацикливание
Я
   madnus
 
07.04.18 - 22:52
Всем привет. Я только учусь программировать, поэтому строго не судите(( Есть документ Расходная накладная, в табличной части для каждого товара пользователь указывает партию, которую необходимо списать. В том случае, если товара по указанной партии не хватает, документ не проводится и выводится соответствующее сообщение о нехватке. Написал код, в случае, если товара хватает, всё проводится нормально. В случае, когда пытаюсь провести товара больше, чем есть партии, всё зависает. Не могу понять в чем ошибка, подозрение на зацикливание. Условия для прерывания цикла вроде сделал. Помогите разобраться ( Код ниже

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

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

    Движения.ОстаткиНоменклатуры.Записывать = Истина;
 
 
   DmitriyDI
 
1 - 07.04.18 - 23:43
(0) по коду вроде все в норме нужно отладчиком пройтись и замеры сделать посмотреть на чем зависает.
   Веселый собака
 
2 - 08.04.18 - 10:28
Отказ = Истина;
Продолжить;
        

Может все же "Прервать"?
А не перебирать все?
   madnus
 
3 - 08.04.18 - 11:21
(1) Отладчиком ходил. Самое интересное, что при прохождении отладчиком иногда всё отрабатывает корректно, хотя я в коде ничего не меняю. Но в 70% случае отладчик проходит и всё снова виснет. Думал ошибка в коде, но видимо у меня что то глючит.
   madnus
 
4 - 08.04.18 - 11:22
(2) Пробовал и через Прервать, пробал и после цикла в процедуре Возврат. Ничего не меняется
   madnus
 
5 - 08.04.18 - 12:08
Решил вопрос. Убрал из параметров РН в запросе Партию и сделал:


        |               Номенклатура В
        |                   (ВЫБРАТЬ
        |                       ВТТовары.Номенклатура
        |                   ИЗ
        |                       ВТТовары КАК ВТТовары)) КАК ОстаткиНоменклатурыОстатки

Теперь всё отрабатывает верно, но я не могу понять почему. Если кто то может, проясните, пожалуйста, почему так, чтобы в будущем я понимал и не допускал таких ошибок.
   youalex
 
6 - 08.04.18 - 12:42
1.ВыборкаДетальныеЗаписи.Номенклатура - так лучше не делать, получай представление в запросе (хоть Номенклатура.Представление), и выводи пользаку его.

2. Не вижу УПОРЯДОЧИТЬ ПО в запросе. Какой метод списания по условию задачи?  

3. Прерывать цикл не нужно, по идее тебе нужно вывести пользаку все товары с отрицательным количеством, а не по одному их выуживать)) . Тут "Продолжить" - правильно.
   youalex
 
7 - 08.04.18 - 12:46
(6) + понял, по п.2 - партии прямо в документе указаны.
Используй замер производительности.
   Borteg
 
8 - 08.04.18 - 13:31
(0)    ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ОстаткиНоменклатуры.Остатки(
        |               &МоментВремени,
        |               (Номенклатура, Партия) В
        |                   (ВЫБРАТЬ
        |                       ВТТовары.Номенклатура,
        |                       ВТТовары.Партия
        |                   ИЗ
        |                       ВТТовары КАК ВТТовары)) КАК ОстаткиНоменклатурыОстатки
        |       ПО ВТТовары.Номенклатура = ОстаткиНоменклатурыОстатки.Номенклатура
        |           И ВТТовары.Партия = ОстаткиНоменклатурыОстатки.Партия";

Убери условия 
(Номенклатура, Партия) В
        |                   (ВЫБРАТЬ
        |                       ВТТовары.Номенклатура,
        |                       ВТТовары.Партия
        |                   ИЗ
        |                       ВТТовары КАК ВТТовары)

Ты это отберешь левым соединением.
Регистр то остатки номенклатуры большой?
   youalex
 
9 - 08.04.18 - 13:47
(8) >>Убери условия ..>> Ты это отберешь левым соединением.

Минус два балла (вроде два) на экзамене.
   madnus
 
10 - 08.04.18 - 16:43
(6) Метод списание в задаче не указан. В табличной части расходной накладной пользователь сам выбирает партию, с которой списывает товар, поэтому рассчитываю себестоимость по каждой партии отдельно
 
 Рекламное место пустует
   madnus
 
11 - 08.04.18 - 16:44
(9) я убрал из условия только Партию и у меня всё заработало нормально. Это будет считаться ошибкой на экзамене ? Оставил только номенклатуру там
   youalex
 
12 - 08.04.18 - 18:10
(11) Ну, буквально, условие ошибки звучит как "Отсутствие значений параметров в виртуальной таблице или использование вместо них условия «ГДЕ»"  
То, что вы не отбираете по партии в параметрах вт - лично мое мнение, это не будет воспринято как ошибка. Но правильно будет  ее использовать.  Убедиться, что тупит именно запрос. Консоль запросов вам в помощь. Далее - убедиться, что тупит именно получение остатков (результат по остаткам есть смысл писать во временную таблицу). Смотреть на структуру регистра (нет ли измерений между Номенклатурой и Партией, например). Если есть возможность - прогнать эти тесты на серверной базе, на мс скуле. Тут вам поможет штатный профайлер скуля.

Список тем форума
Рекламное место пустует  Рекламное место пустует
ВНИМАНИЕ! Если вы потеряли окно ввода сообщения, нажмите Ctrl-F5 или Ctrl-R или кнопку "Обновить" в браузере.
Тема не обновлялась длительное время, и была помечена как архивная. Добавление сообщений невозможно.
Но вы можете создать новую ветку и вам обязательно ответят!
Каждый час на Волшебном форуме бывает более 2000 человек.
Рекламное место пустует