Имя: Пароль:
1C
1С v8
Помогите разобраться с контролем остатков
0 RICK
 
05.05.14
11:26
Здравствуйте!
Делал контроль остатков по Радченко, вроде бы код такой же писал только по своей теме но что то у меня не получилось.
При поступлении 1 товара я могу его списать больше чем он есть на складе
Помогите пожалуйста вот код:



Процедура ОбработкаПроведения(Отказ, Режим)
    //{{__КОНСТРУКТОР_ДВИЖЕНИЙ_РЕГИСТРОВ
    // Данный фрагмент построен конструктором.
    // При повторном использовании конструктора, внесенные вручную изменения будут утеряны!!!

    // регистр ОстаткиАвтомобилей Расход
    Движения.ОстаткиАвтомобилей.Записывать = Истина;
    Для Каждого ТекСтрокаАвтомобили Из Автомобили Цикл
        Движение = Движения.ОстаткиАвтомобилей.Добавить();
        Движение.ВидДвижения = ВидДвиженияНакопления.Расход;
        Движение.Период = Дата;
        Движение.Автомобили = ТекСтрокаАвтомобили.Автомобиль;
        Движение.МестоХранения = МестоХранения;
        Движение.Количество = ТекСтрокаАвтомобили.Количество;
    КонецЦикла;

    // регистр Продажи
    Движения.Продажи.Записывать = Истина;
    Для Каждого ТекСтрокаАвтомобили Из Автомобили Цикл
        Движение = Движения.Продажи.Добавить();
        Движение.Период = Дата;
        Движение.Автомобили = ТекСтрокаАвтомобили.Автомобиль;
        Движение.Клиент = Покупатель;
        Движение.Сотрудник = Менеджер;
        Движение.Количество = ТекСтрокаАвтомобили.Количество;
        Движение.Выручка = ТекСтрокаАвтомобили.Сумма;
        Движение.Стоимость = ТекСтрокаАвтомобили.Цена;
    КонецЦикла;

    //}}__КОНСТРУКТОР_ДВИЖЕНИЙ_РЕГИСТРОВ
    МенеджерВТ = Новый МенеджерВременныхТаблиц;
    
    Запрос = Новый Запрос;
    
    // Укажем, какой менеджер временных таблиц использует этот запрос
    Запрос.МенеджерВременныхТаблиц = МенеджерВТ;

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

    Результат = Запрос.Выполнить();
    
    
    
  
                   Движения.Записать();

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


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




Платформа 8.3
1 shuhard
 
05.05.14
11:30
(0) у Радченко есть свой форум, там мозг ему и высасывай
2 МойКодУныл
 
05.05.14
11:36
Радченко теперь так советует проверять?
Создать движения, а потом проверить отрицательный остаток.
Что-то мне кажется, что запись, а потом чтение в одной неоконченной транзакции проведение одного и того же регистра -  это не очень. Даже термин противный - грязное чтение.
Раньше просто проверялось до. Получил остаток - сравнил, ч тем что хошь списать - отсек. А то движения сначала сделай, потом проверь, потом транзакцию откати...
3 ДенисЧ
 
05.05.14
11:36
(2) Грязное чтение - это из другой оперы
4 Defender aka LINN
 
05.05.14
11:38
(2) Ащета 1С нынче советует (и делает в типовых) именно так.
5 МойКодУныл
 
05.05.14
11:40
(3) он читает в транзакции, которая не завершена и может быть откачена. это не то?
(4) Пичаль тоска. А если документ на 10000 строк и там еще их по партиям разобрать надо? Легче же сразу общее количество проверить.
Устарел я.
6 Лодырь
 
05.05.14
11:43
(5) На самом деле не легче. Поскольку в контроле тебе придется повторить логику проведения. И не факт что она проста и банальна. А так - сделал движения, проверил какие хошь остатки - откатил если надо.
7 fisher
 
05.05.14
11:43
(5) Это не то. Грязное чтение, это когда транзакция читает данные еще не зафиксированные ДРУГОЙ транзакцией.
Это методика абсолютно правильная, хотя выглядит сложнее и неестественнее. При оптимистическом подходе, который имеет место быть в реальной жизни (остатков обычно хватает) - минимизируются блокировки и повышается параллелизм транзакций.
8 МойКодУныл
 
05.05.14
11:45
(6) Согласен, если для контроля нужно повторять логику проведения. А не просто оценить достаточность общего количества.
(7) Учту. Не смотрел новых типовых давно.
9 Ненавижу 1С
 
гуру
05.05.14
11:48
записи у тебя нет перед чтением
10 fisher
 
05.05.14
11:50
(8) Но классическая партионка в эту схему укладывается плохо. Вернее - вообще не укладывается. Ведь перед списанием партий все равно придется блокировать весь их возможный диапазон. Т.е. выигрыша никакого. Поэтому РАУЗ и рулит. А до него - отложенное проведение по партиям.
11 Timon1405
 
05.05.14
11:51
Дату остатков в витруальной таблице установить не помешает
12 ДенисЧ
 
05.05.14
11:52
(5) Грязное - это когда ты читаешь данные другой транзакции
13 saaken
 
05.05.14
11:52
(11) помешает
14 saaken
 
05.05.14
11:52
(9) движения.записать() перед проверкой на оперативность
15 saaken
 
05.05.14
11:53
он возможно проводит не оперативно, или просто оперативность у документа выключил, а код весь правильный
16 saaken
 
05.05.14
11:57
(0) заремь условие и отпишись
17 FireAlex
 
05.05.14
12:29
надо же ещё остатки заблокировать перед
Движения.Записать();

а то кто нить пока проверяешь возьмет и изменит их.
скорей всего режим неоперативный.
по идее при любом режиме надо проверять остатки.
просто в одном случае дату можно не указывать, а в другом на момент времени документа, включая его движения (через границу)
18 RICK
 
05.05.14
12:52
(17) В документе стоит разрешить оперативное проведение
Может вам на почту скинуть базу?Чтобы нагляднее было
Оптимист верит, что мы живем в лучшем из миров. Пессимист боится, что так оно и есть.