Имя: Пароль:
1C
1С v8
Зачем записывать данные в регистр, а потом уже проверять есть ли отрицательные остатки?
,
0 FrostBite101
 
26.04.20
09:16
Как я понял, что при установке Движения.Название= Истина, после выполнения процедуры Проведения, все данные записанные в движения будут автоматически записаны в регистр. Но все использует Движения.Записать();, чтобы записать данные в регистр, а потом проверить остатки. Для чего? Почему нельзя сначала проверить, а потом записать? Вот пример:

Процедура ОбработкаПроведения(Отказ, Режим)

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



#Область НоменклатурыДокумента


    МенеджерВТ = Новый МенеджерВременныхТаблиц;

        Запрос = Новый Запрос;
        
    // Укажем, какой менеджер временных таблиц использует этот запрос
    Запрос.МенеджерВременныхТаблиц = МенеджерВТ;

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

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

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

    // Установим необходимость блокировки данных в регистрах СтоимостьМатериалов и ОстаткиМатериалов
    Движения.СтоимостьМатериалов.БлокироватьДляИзменения = Истина;
    Движения.ОстаткиМатериалов.БлокироватьДляИзменения = Истина;

    // Запишем пустые наборы записей, чтобы читать остатки без учета данных в документе
    Движения.СтоимостьМатериалов.Записать();
    Движения.ОстаткиМатериалов.Записать();

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

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

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

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

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




КонецПроцедуры
1 shuhard
 
26.04.20
09:34
(0) на ИТС есть статья с позицией отдела разработки
в УПП/УТ 1.2/10.3 проверяли до записи и считали прогноз
в ERP/УТ 2.Х сделано о обратного
2 Fragster
 
гуру
26.04.20
09:43
Чтобы не прописывать управляемые блокировки.
3 Fragster
 
гуру
26.04.20
09:44
Ну и не попасть на дедлоки из-за ручного управления блокировками и человеческого фактора
4 Trier
 
26.04.20
09:54
Гугли новая/старая методика проведения, все станет понятно.
5 Гений 1С
 
гуру
26.04.20
09:57
Жесть...
6 2mugik
 
26.04.20
10:20
Вроде как чтобы остатки прочитать надо пустой набор записать чтобы очистить движения. Лишняя запись делается.
7 H A D G E H O G s
 
26.04.20
11:24
1. Чтобы не делать блокировку до запроса получения, которая будет висеть до конца проведения, а регистров будет Многа.
2. Чтобы запрашивать оперативные остатки, что может быть на порядки оптимальнее неоперативных, даже на туже дату, особенно с мертвой статистикой.
8 Сияющий в темноте
 
26.04.20
12:15
на самом деле,тут даже философский подход:
чего мы боимся?
отрицательных остатков после проведения.
как это проверить?
нужно к текущим движениям добавить движения проведения и посмотреть остатки.

ну и проще просто сделать проведение и посмотреть результат,чем делать проведение по сути два раза.
формально говоря,пока проведение не сделано,движения в базе не зафиксированы.

тут,правда,может получиться ситуация,когда проводятся несколько документов параллельно и все они получают отлуп,так как остаток стал отрицательный.
9 Ненавижу 1С
 
гуру
26.04.20
12:55
Давно пора вынести проверки остатков в вызов в событиях набора записей регистров
10 rozer76
 
26.04.20
17:57
+ Ну еще в запросе проверки не нужно левое соединение делать к данным документа а только к РН.
Компьютеры — это как велосипед. Только для нашего сознания. Стив Джобс