Имя: Пароль:
1C
1С v8
Блокировки
0 SFilchakov
 
20.12.15
11:54
Здравствуйте товарищи.
Решил разобраться с блокировками, так как всё чаще начали возникать конфликты блокировок при проведении документа. В настройках конфы и регистра накопления блокировки управляемые. Обработка проведения документа выполняется без использования объекта "Блокировка данных".
//
Я провел несколько тестов с базой, которую 1С вкладывает в сборник по подготовке к специалисту по платформе.
Поставил точку останова в обработке проведения расхода.
В режиме отладки провожу документ в этой же базе открытой параллельно по другой номенклатуре (Измерению регистра), но блокировка тут как тут.
//
Я наивно пологая, что объект "Блокировка данных" даст возможность проводить одновременно несколько документов, если они не блокируют одинаковые записи.

Тогда в чем смысл объекта блокировок? Если войдя в обработку проведения, проведение других документов регистраторов по регистру невозможна.

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

Процедура ОбработкаПроведения(Отказ, Режим)
    //Установим флаг возможности записи
    Движения.ОстаткиНоменклатуры.Записывать = Истина;
    Движения.Продажи.Записывать = Истина;
    Движения.Управленческий.Записывать = Истина;
    Движения.Управленческий.БлокироватьДляИзменения = Истина;
    
    //Очистим формируемые наборы, чтобы не было проблем с остатками при оперативном проведении
    Движения.ОстаткиНоменклатуры.Записать();
    Движения.Управленческий.Записать();
    
    // Получим данные по учетной политике из периодического регистра сведений
    ТекущаяПолитика = РегистрыСведений.УчетнаяПолитика.ПолучитьПоследнее(Дата).Значение;
    Если ТекущаяПолитика = Перечисления.УчетнаяПолитика.ЛИФО Тогда
        ПорядокПартий = "УБЫВ";
    Иначе
        ПорядокПартий = "ВОЗР";
    КонецЕсли;
    
    //Установим исключительную блокировку на те записи регистров, по которым осуществляется чтение, а потом - запись
    Блокировка = Новый БлокировкаДанных;
    ЭлементБлокировки = Блокировка.Добавить("РегистрНакопления.ОстаткиНоменклатуры");
    ЭлементБлокировки.Режим = РежимБлокировкиДанных.Разделяемый;
    ЭлементБлокировки.ИсточникДанных = СписокНоменклатуры;
    ЭлементБлокировки.ИспользоватьИзИсточникаДанных("Номенклатура", "Номенклатура");
        
    ЭлементБлокировки = Блокировка.Добавить("РегистрБухгалтерии.Управленческий");
    ЭлементБлокировки.Режим = РежимБлокировкиДанных.Исключительный;
    ЭлементБлокировки.УстановитьЗначение("Счет", ПланыСчетов.Управленческий.Товары);
    ЭлементБлокировки.ИсточникДанных = СписокНоменклатуры;
    ЭлементБлокировки.ИспользоватьИзИсточникаДанных(
        ПланыВидовХарактеристик.ВидыСубконто.Номенклатура, "Номенклатура");
        
    Блокировка.Заблокировать();
    
    Запрос = Новый Запрос;
    
    Запрос.Текст = "ВЫБРАТЬ
                   |    РасходнаяНакладнаяСписокНоменклатуры.Номенклатура,
                   |    РасходнаяНакладнаяСписокНоменклатуры.Партия,
                   |    СУММА(РасходнаяНакладнаяСписокНоменклатуры.Количество) КАК Количество,
                   |    СУММА(РасходнаяНакладнаяСписокНоменклатуры.Сумма) КАК Сумма
                   |ПОМЕСТИТЬ РасходнаяНакладная
                   |ИЗ
                   |    Документ.РасходнаяНакладная.СписокНоменклатуры КАК РасходнаяНакладнаяСписокНоменклатуры
                   |ГДЕ
                   |    РасходнаяНакладнаяСписокНоменклатуры.Ссылка = &Ссылка
                   |    И РасходнаяНакладнаяСписокНоменклатуры.Номенклатура.ВидНоменклатуры = ЗНАЧЕНИЕ(Перечисление.ВидыНоменклатуры.Товар)
                   |
                   |СГРУППИРОВАТЬ ПО
                   |    РасходнаяНакладнаяСписокНоменклатуры.Номенклатура,
                   |    РасходнаяНакладнаяСписокНоменклатуры.Партия
                   |;
                   |
                   |////////////////////////////////////////////////////////////////////////////////
                   |ВЫБРАТЬ
                   |    ОстаткиНоменклатурыОстатки.Номенклатура,
                   |    ОстаткиНоменклатурыОстатки.Партия,
                   |    ОстаткиНоменклатурыОстатки.КоличествоОстаток,
                   |    ОстаткиНоменклатурыОстатки.СуммаОстаток
                   |ПОМЕСТИТЬ ВсеОстатки
                   |ИЗ
                   |    РегистрНакопления.ОстаткиНоменклатуры.Остатки(
                   |            &Момент,
                   |            Номенклатура В
                   |                (ВЫБРАТЬ РАЗЛИЧНЫЕ
                   |                    РасходнаяНакладная.Номенклатура
                   |                ИЗ
                   |                    РасходнаяНакладная КАК РасходнаяНакладная)) КАК ОстаткиНоменклатурыОстатки
                   |;
                   |
                   |////////////////////////////////////////////////////////////////////////////////
                   |ВЫБРАТЬ
                   |    ВсеОстатки.Номенклатура,
                   |    ВсеОстатки.Партия,
                   |    ВЫБОР
                   |        КОГДА ВсеОстатки.КоличествоОстаток > РасходнаяНакладная.Количество
                   |            ТОГДА РасходнаяНакладная.Количество
                   |        ИНАЧЕ ВсеОстатки.КоличествоОстаток
                   |    КОНЕЦ КАК КоличествоВыбраннойПартии,
                   |    ВЫБОР
                   |        КОГДА ВсеОстатки.КоличествоОстаток > РасходнаяНакладная.Количество
                   |            ТОГДА РасходнаяНакладная.Количество * ВсеОстатки.СуммаОстаток / ВсеОстатки.КоличествоОстаток
                   |        ИНАЧЕ ВсеОстатки.СуммаОстаток
                   |    КОНЕЦ КАК СуммаВыбраннойПартии,
                   |    1 КАК ПорядокСортировки
                   |ПОМЕСТИТЬ ПартииДокумента
                   |ИЗ
                   |    РасходнаяНакладная КАК РасходнаяНакладная
                   |        ВНУТРЕННЕЕ СОЕДИНЕНИЕ ВсеОстатки КАК ВсеОстатки
                   |        ПО РасходнаяНакладная.Номенклатура = ВсеОстатки.Номенклатура
                   |            И РасходнаяНакладная.Партия = ВсеОстатки.Партия
                   |
                   |ОБЪЕДИНИТЬ ВСЕ
                   |
                   |ВЫБРАТЬ
                   |    ВсеОстатки.Номенклатура,
                   |    ВсеОстатки.Партия,
                   |    ВЫБОР
                   |        КОГДА ВсеОстатки.КоличествоОстаток > РасходнаяНакладная.Количество
                   |            ТОГДА ВсеОстатки.КоличествоОстаток - РасходнаяНакладная.Количество
                   |        ИНАЧЕ 0
                   |    КОНЕЦ,
                   |    ВЫБОР
                   |        КОГДА ВсеОстатки.КоличествоОстаток > РасходнаяНакладная.Количество
                   |            ТОГДА ВсеОстатки.СуммаОстаток - РасходнаяНакладная.Количество * ВсеОстатки.СуммаОстаток / ВсеОстатки.КоличествоОстаток
                   |        ИНАЧЕ 0
                   |    КОНЕЦ,
                   |    2
                   |ИЗ
                   |    РасходнаяНакладная КАК РасходнаяНакладная
                   |        ВНУТРЕННЕЕ СОЕДИНЕНИЕ ВсеОстатки КАК ВсеОстатки
                   |        ПО РасходнаяНакладная.Номенклатура = ВсеОстатки.Номенклатура
                   |            И РасходнаяНакладная.Партия = ВсеОстатки.Партия
                   |;
                   |
                   |////////////////////////////////////////////////////////////////////////////////
                   |ВЫБРАТЬ
                   |    ПартииДокумента.Номенклатура,
                   |    ПартииДокумента.Партия,
                   |    -ПартииДокумента.КоличествоВыбраннойПартии КАК КоличествоВыбраннойПартии,
                   |    -ПартииДокумента.СуммаВыбраннойПартии КАК СуммаВыбраннойПартии,
                   |    2 КАК ПорядокСортировки
                   |ПОМЕСТИТЬ ОстальныеПартии
                   |ИЗ
                   |    ПартииДокумента КАК ПартииДокумента
                   |
                   |ОБЪЕДИНИТЬ ВСЕ
                   |
                   |ВЫБРАТЬ
                   |    ВсеОстатки.Номенклатура,
                   |    ВсеОстатки.Партия,
                   |    ВсеОстатки.КоличествоОстаток,
                   |    ВсеОстатки.СуммаОстаток,
                   |    2
                   |ИЗ
                   |    ВсеОстатки КАК ВсеОстатки
                   |;
                   |
                   |////////////////////////////////////////////////////////////////////////////////
                   |ВЫБРАТЬ
                   |    ОстальныеПартии.Номенклатура,
                   |    ОстальныеПартии.Партия,
                   |    СУММА(ОстальныеПартии.КоличествоВыбраннойПартии) КАК КоличествоВыбраннойПартии,
                   |    СУММА(ОстальныеПартии.СуммаВыбраннойПартии) КАК СуммаВыбраннойПартии,
                   |    ОстальныеПартии.ПорядокСортировки
                   |ПОМЕСТИТЬ СвернутыеОставшиесяПартии
                   |ИЗ
                   |    ОстальныеПартии КАК ОстальныеПартии
                   |
                   |СГРУППИРОВАТЬ ПО
                   |    ОстальныеПартии.Номенклатура,
                   |    ОстальныеПартии.Партия,
                   |    ОстальныеПартии.ПорядокСортировки
                   |;
                   |
                   |////////////////////////////////////////////////////////////////////////////////
                   |ВЫБРАТЬ
                   |    ВложенныйЗапрос.Номенклатура,
                   |    ВложенныйЗапрос.Партия,
                   |    СУММА(ВложенныйЗапрос.КоличествоВыбраннойПартии) КАК КоличествоВыбраннойПартии,
                   |    СУММА(ВложенныйЗапрос.СуммаВыбраннойПартии) КАК СуммаВыбраннойПартии,
                   |    ВложенныйЗапрос.ПорядокСортировки
                   |ПОМЕСТИТЬ СвернутыеВсеПартии
                   |ИЗ
                   |    (ВЫБРАТЬ
                   |        ПартииДокумента.Номенклатура КАК Номенклатура,
                   |        ПартииДокумента.Партия КАК Партия,
                   |        ПартииДокумента.КоличествоВыбраннойПартии КАК КоличествоВыбраннойПартии,
                   |        ПартииДокумента.СуммаВыбраннойПартии КАК СуммаВыбраннойПартии,
                   |        ПартииДокумента.ПорядокСортировки КАК ПорядокСортировки
                   |    ИЗ
                   |        ПартииДокумента КАК ПартииДокумента
                   |    
                   |    ОБЪЕДИНИТЬ ВСЕ
                   |    
                   |    ВЫБРАТЬ
                   |        СвернутыеОставшиесяПартии.Номенклатура,
                   |        СвернутыеОставшиесяПартии.Партия,
                   |        СвернутыеОставшиесяПартии.КоличествоВыбраннойПартии,
                   |        СвернутыеОставшиесяПартии.СуммаВыбраннойПартии,
                   |        СвернутыеОставшиесяПартии.ПорядокСортировки
                   |    ИЗ
                   |        СвернутыеОставшиесяПартии КАК СвернутыеОставшиесяПартии) КАК ВложенныйЗапрос
                   |
                   |СГРУППИРОВАТЬ ПО
                   |    ВложенныйЗапрос.Номенклатура,
                   |    ВложенныйЗапрос.Партия,
                   |    ВложенныйЗапрос.ПорядокСортировки
                   |;
                   |
                   |////////////////////////////////////////////////////////////////////////////////
                   |ВЫБРАТЬ
                   |    Накладная.Номенклатура КАК Номенклатура,
                   |    Накладная.Количество КАК КоличествоВДокументе,
                   |    Накладная.Сумма КАК СуммаВДокументе,
                   |    ЕСТЬNULL(ОстаткиТоваров.Партия, 0) КАК Партия,
                   |    ЕСТЬNULL(ОстаткиТоваров.КоличествоВыбраннойПартии, 0) КАК КоличествоПартии,
                   |    ЕСТЬNULL(ОстаткиТоваров.СуммаВыбраннойПартии, 0) КАК СуммаПартии,
                   |    Накладная.Номенклатура.Представление,
                   |    ЕСТЬNULL(УправленческийОстатки.КоличествоОстатокДт, 0) КАК КоличествоОстатокДт,
                   |    ЕСТЬNULL(УправленческийОстаткиВсе.КоличествоОстатокДт, 0) КАК КоличествоОстатокДтВсе,
                   |    ЕСТЬNULL(УправленческийОстаткиВсе.СуммаОстатокДт, 0) КАК СуммаОстатокДтВсе
                   |ИЗ
                   |    (ВЫБРАТЬ
                   |        РасходнаяНакладная.Номенклатура КАК Номенклатура,
                   |        СУММА(РасходнаяНакладная.Количество) КАК Количество,
                   |        СУММА(РасходнаяНакладная.Сумма) КАК Сумма
                   |    ИЗ
                   |        РасходнаяНакладная КАК РасходнаяНакладная
                   |    
                   |    СГРУППИРОВАТЬ ПО
                   |        РасходнаяНакладная.Номенклатура) КАК Накладная
                   |        ЛЕВОЕ СОЕДИНЕНИЕ СвернутыеВсеПартии КАК ОстаткиТоваров
                   |        ПО Накладная.Номенклатура = ОстаткиТоваров.Номенклатура
                   |        ЛЕВОЕ СОЕДИНЕНИЕ РегистрБухгалтерии.Управленческий.Остатки(
                   |                &Момент,
                   |                Счет = ЗНАЧЕНИЕ(ПланСчетов.Управленческий.Товары),
                   |                &ВидыСубконто,
                   |                Субконто1 В
                   |                        (ВЫБРАТЬ РАЗЛИЧНЫЕ
                   |                            РасходнаяНакладная.Номенклатура
                   |                        ИЗ
                   |                            РасходнаяНакладная КАК РасходнаяНакладная)
                   |                    И Субконто2 = &Склад) КАК УправленческийОстатки
                   |        ПО Накладная.Номенклатура = УправленческийОстатки.Субконто1
                   |        ЛЕВОЕ СОЕДИНЕНИЕ РегистрБухгалтерии.Управленческий.Остатки(
                   |                &Момент,
                   |                Счет = ЗНАЧЕНИЕ(ПланСчетов.Управленческий.Товары),
                   |                &ВидыСубконто,
                   |                Субконто1 В
                   |                    (ВЫБРАТЬ РАЗЛИЧНЫЕ
                   |                        РасходнаяНакладная.Номенклатура
                   |                    ИЗ
                   |                        РасходнаяНакладная КАК РасходнаяНакладная)) КАК УправленческийОстаткиВсе
                   |        ПО (Накладная.Номенклатура = УправленческийОстатки.Субконто1)
                   |
                   |УПОРЯДОЧИТЬ ПО
                   |    ОстаткиТоваров.ПорядокСортировки,
                   |    ОстаткиТоваров.Партия.МоментВремени " + ПорядокПартий + "
                   |ИТОГИ
                   |    МАКСИМУМ(КоличествоВДокументе),
                   |    МАКСИМУМ(СуммаВДокументе),
                   |    СУММА(КоличествоПартии),
                   |    СУММА(СуммаПартии),
                   |    МАКСИМУМ(КоличествоОстатокДт),
                   |    МАКСИМУМ(КоличествоОстатокДтВсе),
                   |    МАКСИМУМ(СуммаОстатокДтВсе)
                   |ПО
                   |    Номенклатура";
    
    Запрос.УстановитьПараметр("Ссылка", Ссылка);
    Запрос.УстановитьПараметр("Момент", МоментВремени());
    Запрос.УстановитьПараметр("Склад", Склад);
    
    //Зафиксируем используемый в запросе порядок субконто, т.к. пользователь может его изменить
    ВидыСубконто = Новый Массив;
    ВидыСубконто.Добавить(ПланыВидовХарактеристик.ВидыСубконто.Номенклатура);
    ВидыСубконто.Добавить(ПланыВидовХарактеристик.ВидыСубконто.Склад);
    
    Запрос.УстановитьПараметр("ВидыСубконто", ВидыСубконто);
    
    Результат = Запрос.Выполнить();
    ВыборкаНоменклатуры = Результат.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам);
    
    ОбщаяСуммаПродаж = 0;
    Пока ВыборкаНоменклатуры.Следующий() Цикл
        Если ВыборкаНоменклатуры.КоличествоВДокументе > ВыборкаНоменклатуры.КоличествоПартии Тогда
            Отказ = Истина;
            Сообщение = Новый СообщениеПользователю;
            Сообщение.Текст = "По " + ВыборкаНоменклатуры.НоменклатураПредставление + " осталось только " + ВыборкаНоменклатуры.КоличествоПартии
                + " необходимо " + ВыборкаНоменклатуры.КоличествоВДокументе;
            Сообщение.Сообщить();
        КонецЕсли;
        Если ВыборкаНоменклатуры.КоличествоВДокументе > ВыборкаНоменклатуры.КоличествоОстатокДт Тогда
            Отказ = Истина;
            Сообщение = Новый СообщениеПользователю;
            Сообщение.Текст = "БУХ: По " + ВыборкаНоменклатуры.НоменклатураПредставление + " осталось только " + ВыборкаНоменклатуры.КоличествоОстатокДт
                + " необходимо " + ВыборкаНоменклатуры.КоличествоВДокументе;
            Сообщение.Сообщить();
        КонецЕсли;
        
        Если Отказ Тогда
            Продолжить;
        КонецЕсли;
        
        //Сформируем записи в регистре "Управленческий"
        Движение = Движения.Управленческий.Добавить();
        Движение.СчетДт = ПланыСчетов.Управленческий.ПрибылиУбытки;
        Движение.СчетКт = ПланыСчетов.Управленческий.Товары;
        Движение.Период = Дата;
        Если ВыборкаНоменклатуры.КоличествоВДокументе < ВыборкаНоменклатуры.КоличествоОстатокДтВсе Тогда
            СуммаСписания =  
                ВыборкаНоменклатуры.КоличествоВДокументе * ВыборкаНоменклатуры.СуммаОстатокДтВсе / ВыборкаНоменклатуры.КоличествоОстатокДтВсе;
        Иначе
            СуммаСписания = ВыборкаНоменклатуры.СуммаОстатокДтВсе;
        КонецЕсли;        
        Движение.Сумма = СуммаСписания;
        Движение.КоличествоКт = ВыборкаНоменклатуры.КоличествоВДокументе;
        Движение.Содержание = "Списана себестоимость";
        Движение.СубконтоКт[ПланыВидовХарактеристик.ВидыСубконто.Номенклатура] = ВыборкаНоменклатуры.Номенклатура;
        Движение.СубконтоКт[ПланыВидовХарактеристик.ВидыСубконто.Склад] = Склад;
        
        //Сформируем записи в регистре "ОстаткиНоменклатуры"
        ВыборкаПартий = ВыборкаНоменклатуры.Выбрать();
        ОсталосьСписать = ВыборкаНоменклатуры.КоличествоВДокументе;
        
        СуммаСписанногоПоТовару = 0;
        Пока ОсталосьСписать > 0 И ВыборкаПартий.Следующий() Цикл
            
            Если ВыборкаПартий.КоличествоПартии = 0 Тогда
                 Продолжить;
            КонецЕсли;
            
            КоличествоСписания = МИН(ОсталосьСписать, ВыборкаПартий.КоличествоПартии);
            Если ВыборкаПартий.КоличествоПартии > ОсталосьСписать Тогда
                СуммаСписания =  ОсталосьСписать * ВыборкаПартий.СуммаПартии / ВыборкаПартий.КоличествоПартии;
            Иначе
                СуммаСписания = ВыборкаПартий.СуммаПартии;
            КонецЕсли;        
            
            Движение = Движения.ОстаткиНоменклатуры.Добавить();
            Движение.ВидДвижения = ВидДвиженияНакопления.Расход;
            Движение.Период = Дата;
            Движение.Номенклатура = ВыборкаПартий.Номенклатура;
            Движение.Партия = ВыборкаПартий.Партия;
            Движение.Количество = КоличествоСписания;
            Движение.Сумма = СуммаСписания;
            
            ОсталосьСписать = ОсталосьСписать - КоличествоСписания;
            
            СуммаСписанногоПоТовару = СуммаСписанногоПоТовару + Движение.Сумма;
        КонецЦикла;
        
        //Сформируем записи в регистре "Продажи"
        Движение = Движения.Продажи.Добавить();
        Движение.Период = Дата;
        Движение.Номенклатура = ВыборкаНоменклатуры.Номенклатура;
        Движение.Количество = ВыборкаНоменклатуры.КоличествоВДокументе;
        Движение.Себестоимость = СуммаСписанногоПоТовару;
        Движение.СуммаПродаж = ВыборкаНоменклатуры.СуммаВДокументе;
        
        ОбщаяСуммаПродаж = ОбщаяСуммаПродаж + Движение.СуммаПродаж;
    КонецЦикла;
    Если Не Отказ Тогда
        // регистр Управленческий
        Движение = Движения.Управленческий.Добавить();
        Движение.СчетДт = ПланыСчетов.Управленческий.Покупатели;
        Движение.СчетКт = ПланыСчетов.Управленческий.ПрибылиУбытки;
        Движение.Период = Дата;
        Движение.Сумма = ОбщаяСуммаПродаж;
        Движение.Содержание = "Продажа товаров";
    КонецЕсли;
    
    //{{__КОНСТРУКТОР_ДВИЖЕНИЙ_РЕГИСТРОВ
    // Данный фрагмент построен конструктором.
    // При повторном использовании конструктора, внесенные вручную изменения будут утеряны!!!
    //}}__КОНСТРУКТОР_ДВИЖЕНИЙ_РЕГИСТРОВ
КонецПроцедуры
3 su_mai
 
20.12.15
11:57
Если да, то блокируется таблица целиком с уровнем Serialazable
4 SFilchakov
 
20.12.15
11:58
(1) в тесте да.
В рабочей сервер.
5 SFilchakov
 
20.12.15
11:59
(3) На сервере отработает параллельно?
6 SFilchakov
 
20.12.15
12:25
//ИЗ СП
Описание:

Предназначен для явной блокировки данных от чтения или изменения другими сессиями.

Доступность:

Сервер, толстый клиент, внешнее соединение.
Возможен обмен с сервером. Сериализуется.

//Что значит "Явная"? Зачем вообще он нужен если обработка проведения выполняется в транзакции, которая и так блокирует возможность записи в регистр?
7 hhhh
 
20.12.15
12:33
(5) тестируйте на серверной базе
8 GROOVY
 
20.12.15
12:43
(4) Вот это у Вас рабочая база? 0_о
Всегда подозревал, что сертификационные задачи кто-то может в итоге внедрить в реале.
9 su_mai
 
20.12.15
12:44
(6) Неявная начинается платформой автоматически в обработчиках событий доступа к данным, типа ПриЗаписи, ОбработкаПроведения и тп.

Книжка есть: http://v8.1c.ru/metod/books/book.jsp?id=499
10 rozer76
 
20.12.15
12:52
Ты еще наборы записей сначала почисть а то если из обычной формы то задвояться или если уф и набор записей читаеться в форме. Ну и в серверной тестируй однозначно вот там и будет вожделенный коммитрид или коммитридснапшот
11 GROOVY
 
20.12.15
13:32
И не надо путать объектные и транзакционные блокировки ;)
12 SFilchakov
 
20.12.15
13:54
(8) Это тестовая база из книги, я взял её за эталон, пологая, что это самый правильный метод проведения, максимально оптимальный. В общем надо курить мат.часть и тестировать на сервере.
13 vde69
 
20.12.15
14:43
Для 99% случаев при проведении документов не требуется никаких явных блокировок. 1с в режиме "управляемые блокировки" работает на ОТЛИЧНО, добиваться ИДЕАЛЬНО нужно только в исключительных случаях...

естественно нужно со SQL нормально поработать в плане регламентов и оптимизации железа...
14 SFilchakov
 
21.12.15
12:59
Разобрался.
1. Конфа и регистр должны иметь вид блокировки "Управляемый".
2. Ресурсы регистра, по которым выполняется запрос в обработке проведения (получение данных из базы) должны быть индексированными. Блокировки выполняются по индексу.
3. Запрос не должен содержать условия "ИЛИ", в таком случае индекс не отрабатывает.
////
Объект "Блокировка" не нужно создавать программно, всё выполняется автоматом.
15 SFilchakov
 
21.12.15
13:03
(14) Пункт 2. Не ресурсы а измерения.
16 rozer76
 
21.12.15
13:11
(14)
>>Ресурсы регистра, по которым выполняется запрос в обработке проведения (получение данных из базы) должны быть индексированными. Блокировки выполняются по индексу.
>>3. Запрос не должен содержать условия "ИЛИ", в таком случае индекс не отрабатывает.

"Все смешалось, люди, кони..."
17 rozer76
 
21.12.15
13:13
18 rozer76
 
21.12.15
13:14
http://its.1c.ru/db/metod8dev#content:5839:hdoc

Прочитайте и все вопросы для себя решите
19 SFilchakov
 
21.12.15
13:15
Спасибо.
20 vde69
 
21.12.15
13:15
измерения ВСЕГДА индексируются !!!

Дополнительный индекс по измерениям нужен далеко не всегда...

а вот как построено условие это важно... для работы индекса условие должно накладываться на начало индекса без пропусков. Например если регистр содержит измерения "Контрагент" + "Договор", то условие только по договору будет работать медленнее чем условие по контрагенту и медленнее чем условие по контрагенту+договору
21 los_hooliganos
 
21.12.15
13:34
(20) Это касается исключительно файловой базы.
22 vde69
 
21.12.15
13:37
(21) нет, это касается любой SQL базы (и напрямую к 1с не относится), другое дело, что скуль фул скан делает очень быстро, но это другой вопрос...
23 los_hooliganos
 
21.12.15
13:49
(22) На самом деле все веселее.
В 1С по РН сейчас на каждое измерение и реквизит (!!) делается свой личный индекс.
Т.е. в отличие от 7.7 все иначе.
Что касается покрывающих индексов, то это отдельная песня.
Кто идет первым а кто следующим роли не играет.
Иными словами отбор по Договор+Контр, либо только Договор, либо только Контр отработают одинаково.
24 los_hooliganos
 
21.12.15
13:50
Регистр накопления

Основная таблица регистра

Индекс

Условие

[ОРРХ | ОРНР1 +] Период + Регистратор + НомерСтроки (Кластерный)

Всегда.

[ОРНР1 + ... +] Регистратор + НомерСтроки

Всегда.
В индекс входят поля независимых разделителей, которые разделяют этот регистр.

[ОРРХ | ОРНР1 +] Измерение + Период + Регистратор + НомерСтроки

Измерению "Измерение" задано свойство "Индексировать".

[ОРРХ | ОРНР1 +] Реквизит + Период + Регистратор + НомерСтроки

Реквизиту "Реквизит" задано свойство "Индексировать".