Продвинутый курс. Домашнее задание №12

Эта запись посвящена второму потоку продвинутого курса по программированию.

Для выполнения рекомендуется изучить следующие главы 2-го блока.

Глава 3. Агрегаты
Глава 4. Запросы к регистрам
Глава 5. Блокировка данных
Глава 6. Последовательности
Глава 7. Складской учет

К сожалению, у Вас недостаточно прав для просмотра этой записи. Если Вы еще не залогинены на сайте
залогиньтесь.

Если не активировали токен — посмотрите видео-инструкцию (видео N5)

Если вы залогинены, у Вас активирован токен доступа, но вы все равно видите эту запись —
напишите нам на e-mail поддержки.

комментариев 11 на “Продвинутый курс. Домашнее задание №12”

  1. Задание выполнил. Нечасто в практической работе применю блокировку данных, так что здесь пришлось подумать.

  2. Задание выполнил.
    Добавил в конфигурацию документ Заказ и регистр накопления ЗарезервированныйТовар вида Остатки с измерениями Номенклатура, Заказ (тип ДокументСсылка.Заказ) и ресурсом Количество. Режим блокировки управляемый. Регистраторами нового регистра являются документы Заказ и РеализацияТоваровИУслуг. В табличную чать Товары документа РеализацияТоваровИУслуг добавлен реквизит Заказ (тип ДокументСсылка.Заказ). У документа Заказ свойство «Удаление движений» принимает значение «Удалять автоматически при отмене проведения», а свойство «Запись движений при проведении» – «Записывать выбранные».
    При проведении, документ Заказ создает «приходные» движения в регистре ЗарезервированныйТовар, а документ РеализацияТоваровИУслуг – «расходные». При этом остаток по номенклатуре в регистре ЗарезервированныйТовар не может превышать остатка по этой же номенклатуре в регистре ОстаткиТоваров. Для блокировки регистра ЗарезервированныйТовар при проведении документов, используется свойство БлокироватьДляИзменения набора записей регистра накопления (присваивается значение Истина).
    Текст модуля объекта документа Заказ:
    <code>
    Процедура ОбработкаПроведения(Отказ, РежимПроведения)
     
    НаборДвижений = Движения.ЗарезервированныйТовар;
    НаборДвижений.БлокироватьДляИзменения = Истина;
    НаборДвижений.Очистить();
     
    Для каждого ТекСтрока Из Товары Цикл
    НоваяЗапись = НаборДвижений.Добавить();
    НоваяЗапись.ВидДвижения    = ВидДвиженияНакопления.Приход;
    НоваяЗапись.Период                                  = ЭтотОбъект.Дата;
    НоваяЗапись.Номенклатура   = ТекСтрока.Номенклатура;
    НоваяЗапись.Заказ                                       = ЭтотОбъект.Ссылка;
    НоваяЗапись.Количество                         = ТекСтрока.Количество;
    КонецЦикла;
    НаборДвижений.Записать();
     
    Запрос = Новый Запрос;
    Запрос.Текст =
    “ВЫБРАТЬ
    |             ЗаказТовары.Номенклатура,
    |             СУММА(ЗаказТовары.Количество) КАК Количество,
    |             МИНИМУМ(ЗаказТовары.НомерСтроки) КАК НомерСтроки
    |ПОМЕСТИТЬ Товар
    |ИЗ
    |             Документ.Заказ.Товары КАК ЗаказТовары
    |ГДЕ
    |             ЗаказТовары.Ссылка = &Ссылка
    |
    |СГРУППИРОВАТЬ ПО
    |             ЗаказТовары.Номенклатура
    |
    |;
    |
    |////////////////////////////////////////////////////////////////////////////////
    |ВЫБРАТЬ
    |             Товар.Номенклатура,
    |             Товар.НомерСтроки,
    |             ЕСТЬNULL(ОстаткиТоваровОстатки.КоличествоОстаток, 0) – ЕСТЬNULL(ЗарезервированныйТоварОстатки.КоличествоОстаток, 0) КАК СвободныйОстаток
    |ИЗ
    |             Товар КАК Товар
    |                             ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ЗарезервированныйТовар.Остатки(
    |                                                            ,
    |                                                            Номенклатура В
    |                                                                            (ВЫБРАТЬ
    |                                                                                            Товар.Номенклатура
    |                                                                            ИЗ
    |                                                                                            Товар КАК Товар)) КАК ЗарезервированныйТоварОстатки
    |                             ПО Товар.Номенклатура = ЗарезервированныйТоварОстатки.Номенклатура
    |                             ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ОстаткиТоваров.Остатки(
    |                                                            ,
    |                                                            Номенклатура В
    |                                                                            (ВЫБРАТЬ
    |                                                                                            Товар.Номенклатура
    |                                                                            ИЗ
    |                                                                                            Товар КАК Товар)) КАК ОстаткиТоваровОстатки
    |                             ПО Товар.Номенклатура = ОстаткиТоваровОстатки.Номенклатура
    |ГДЕ
    |             ЕСТЬNULL(ОстаткиТоваровОстатки.КоличествоОстаток, 0) – ЕСТЬNULL(ЗарезервированныйТоварОстатки.КоличествоОстаток, 0) < 0”;
     
    Запрос.УстановитьПараметр(“Ссылка”, Ссылка);
     
    Результат = Запрос.Выполнить();
     
    Если НЕ Результат.Пустой() Тогда
     
    Отказ = Истина;
    ВыборкаДетальныеЗаписи = Результат.Выбрать();
     
    Пока ВыборкаДетальныеЗаписи.Следующий() Цикл
    Сообщение = Новый СообщениеПользователю;
    Сообщение.Текст = “Не хватает свободного остатка по номенклатуре ” + ВыборкаДетальныеЗаписи.Номенклатура + ” в количестве ” + (-ВыборкаДетальныеЗаписи.СвободныйОстаток);
    Сообщение.Поле = “Товары[” + (ВыборкаДетальныеЗаписи.НомерСтроки – 1) + “].Количество”;
    Сообщение.УстановитьДанные(ЭтотОбъект);
    Сообщение.Сообщить();
    КонецЦикла;
     
    КонецЕсли;
     
    КонецПроцедуры
    </code>
    При проведении документа РеализацияТоваровИУслуг сначала выполняются движения по регистру ЗарезервированныйТовар (при этом контролируются остатки по номенклатуре в разрезе заказов), затем по регистру ОстаткиТоваров (при этом контролируется «свободный», не зарезервированный остаток).
    Были созданы подписки на события ПодпискаНаСобытиеПередЗаписьюРегистраЗарезервированныйТовар и ПодпискаНаСобытиеПриЗаписиРегистраЗарезервированныйТовар, обработчик подписки ПодпискаНаСобытиеПриЗаписьюРегистраОстатки был модифицирован с учетом требования контроля «свободного »остатка. Текст обработчиков созданных подписок:
    <code>
    Процедура ПодпискаНаСобытиеПередЗаписьюРегистраЗарезервированныйТоварПередЗаписью(Источник, Отказ, Замещение) Экспорт
    Перем МенеджерВТ, ЭтоНовый;
     
    ДопСвойства = Источник.ДополнительныеСвойства;
    ВыполнятьКонтрольОстатков = Истина;
    ДопСвойства.Свойство(“ВыполнятьКонтрольОстатков”, ВыполнятьКонтрольОстатков);
     
    Если ВыполнятьКонтрольОстатков = Истина Тогда
     
    Если НЕ ДопСвойства.Свойство(“МенеджерВТ”, МенеджерВТ) Тогда
     
    Сообщение = Новый СообщениеПользователю;
    Сообщение.Текст = “Не определен менеджер временных таблиц. Проведение докумнета невозможно!”;
    Сообщение.Сообщить();
    Отказ = Истина;
    Возврат;
     
    КонецЕсли;
     
    Запрос = Новый Запрос;
    Запрос.МенеджерВременныхТаблиц = МенеджерВТ;
     
    ДопСвойства.Свойство(“ЭтоНовый”, ЭтоНовый);
     
    Если ЭтоНовый = Истина Тогда
    Запрос.Текст =
    “ВЫБРАТЬ
    |             1 КАК Номенклатура,
    |             2 КАК Заказ,
    |             3 КАК Количество
    |ПОМЕСТИТЬ ПрошлоеСостояниеДокументаРезервы
    |ГДЕ
    |             1 = 2”;
    Иначе
    Запрос.Текст =
    “ВЫБРАТЬ
    |             Резервы.Номенклатура,
    |             Резервы.Заказ,
    |             Резервы.Количество
    |ПОМЕСТИТЬ ПрошлоеСостояниеДокументаРезервы
    |ИЗ
    |             РегистрНакопления.ЗарезервированныйТовар КАК Резервы
    |ГДЕ
    |             Резервы.Регистратор = &Регистратор
    |             И Резервы.Заказ <> ЗНАЧЕНИЕ(Документ.Заказ.ПустаяСсылка)
    |             И Резервы.Заказ ЕСТЬ НЕ NULL “;
    Запрос.УстановитьПараметр(“Регистратор”, Источник.Отбор.Регистратор.Значение);
    КонецЕсли;
    Запрос.Выполнить();
     
    КонецЕсли;
    КонецПроцедуры
     
    Процедура ПодпискаНаСобытиеПриЗаписиРегистраЗарезервированныйТоварПриЗаписи(Источник, Отказ, Замещение) Экспорт
    ДопСвойства = Источник.ДополнительныеСвойства;
    ВыполнятьКонтрольОстатков = Ложь;
    ДопСвойства.Свойство(“ВыполнятьКонтрольОстатков”, ВыполнятьКонтрольОстатков);
     
    Если ВыполнятьКонтрольОстатков = Истина Тогда
     
    Запрос = Новый Запрос;
    Запрос.МенеджерВременныхТаблиц = ДопСвойства.МенеджерВТ;
     
    Запрос.Текст =
    “ВЫБРАТЬ
    |             ЗарезервированныйТовар.Номенклатура,
    |             ЗарезервированныйТовар.Заказ,
    |             ЗарезервированныйТовар.Количество
    |ПОМЕСТИТЬ ТекущееСостояниеДокумента
    |ИЗ
    |             РегистрНакопления.ЗарезервированныйТовар КАК ЗарезервированныйТовар
    |ГДЕ
    |             ЗарезервированныйТовар.Регистратор = &Регистратор
    |             И ЗарезервированныйТовар.Заказ <> ЗНАЧЕНИЕ(Документ.Заказ.ПустаяСсылка)
    |             И ЗарезервированныйТовар.Заказ ЕСТЬ НЕ NULL
    |;
    |
    |////////////////////////////////////////////////////////////////////////////////
    |ВЫБРАТЬ
    |             ТекущееСостояниеДокумента.Номенклатура,
    |             ТекущееСостояниеДокумента.Заказ
    |ПОМЕСТИТЬ ИзмененияДокумента
    |ИЗ
    |             ТекущееСостояниеДокумента КАК ТекущееСостояниеДокумента
    |                             ЛЕВОЕ СОЕДИНЕНИЕ ПрошлоеСостояниеДокументаРезервы КАК ПрошлоеСостояниеДокумента
    |                             ПО ТекущееСостояниеДокумента.Номенклатура = ПрошлоеСостояниеДокумента.Номенклатура
    |                                             И ТекущееСостояниеДокумента.Заказ = ПрошлоеСостояниеДокумента.Заказ
    |ГДЕ
    |             ТекущееСостояниеДокумента.Количество <> ЕСТЬNULL(ПрошлоеСостояниеДокумента.Количество, 0)
    |;
    |
    |////////////////////////////////////////////////////////////////////////////////
    |ВЫБРАТЬ
    |             ЗарезервированныйТоварОстатки.Номенклатура,
    |             ЗарезервированныйТоварОстатки.Заказ,
    |             ЗарезервированныйТоварОстатки.КоличествоОстаток,
    |             МИНИМУМ(ДокументыТовары.НомерСтроки) КАК НомерСтроки
    |ИЗ
    |             РегистрНакопления.ЗарезервированныйТовар.Остатки(
    |                                             &МоментВремени,
    |                                             Номенклатура В
    |                                                            (ВЫБРАТЬ
    |                                                                            ИзмененияДокумента.Номенклатура
    |                                                            ИЗ
    |                                                                            ИзмененияДокумента КАК ИзмененияДокумента)
    |                                             И
    |                                             Заказ В
    |                                                            (ВЫБРАТЬ
    |                                                                            ИзмененияДокумента.Заказ
    |                                                            ИЗ
    |                                                                            ИзмененияДокумента КАК ИзмененияДокумента)
    |             ) КАК ЗарезервированныйТоварОстатки
    |                             ЛЕВОЕ СОЕДИНЕНИЕ ДокументТоварыПараметр КАК ДокументыТовары
    |                             ПО ЗарезервированныйТоварОстатки.Номенклатура = ДокументыТовары.Номенклатура
    |                                             И ЗарезервированныйТоварОстатки.Заказ = ДокументыТовары.Заказ
    |ГДЕ
    |             ЗарезервированныйТоварОстатки.КоличествоОстаток < 0
    |
    |СГРУППИРОВАТЬ ПО
    |             ЗарезервированныйТоварОстатки.Номенклатура,
    |             ЗарезервированныйТоварОстатки.КоличествоОстаток,
    |             ЗарезервированныйТоварОстатки.Заказ
    |;
    |////////////////////////////////////////////////////////////////////////////////
    |УНИЧТОЖИТЬ ТекущееСостояниеДокумента
    |;
    |
    |////////////////////////////////////////////////////////////////////////////////
    |УНИЧТОЖИТЬ ИзмененияДокумента”;
     
    Регистратор = Источник.Отбор.Регистратор.Значение;
    Запрос.Текст = СтрЗаменить(Запрос.Текст, “ДокументТоварыПараметр”, “Документ.”+Регистратор.Метаданные().Имя+”.Товары”);
    Запрос.УстановитьПараметр(“Регистратор”, Регистратор);
    Запрос.УстановитьПараметр(“МоментВремени”, Новый Граница(Регистратор.МоментВремени(), ВидГраницы.Включая));
     
    РезультатЗапроса = Запрос.Выполнить();
    Если НЕ РезультатЗапроса.Пустой() Тогда
    Отказ = Истина;
    ВыборкаНехватка = Запрос.Выполнить().Выбрать();
     
    Пока ВыборкаНехватка.Следующий() Цикл
    Сообщение = Новый СообщениеПользователю;
    Сообщение.Текст = “Нехватка номенклатуры “+ВыборкаНехватка.Номенклатура + ” по заказу” + ВыборкаНехватка.Заказ +” в количестве “+(-ВыборкаНехватка.КоличествоОстаток);
    Сообщение.Поле = “Товары[“+(ВыборкаНехватка.НомерСтроки-1)+”].Количество”;
    Сообщение.УстановитьДанные(ДопСвойства.ДокументОбъект);
    Сообщение.Сообщить();
     
    КонецЦикла;
     
    КонецЕсли;
     
    ДопСвойства.МенеджерВТ.Закрыть();
     
    КонецЕсли;
    КонецПроцедуры
    </code>
     

  3. Задание выполнил. Создал регистр “ЗаказыПокупателей” (Измерения- номенклатура, документ “Заказ”).  При проведении документа “Заказ” списываем номенклатуру с “Остатки” и ставим на “ЗаказыПокупателей”. Контроль остатоков по регистру “ЗаказыПокупателей” (расход по которому делает “РеализацияТоваровУслуг”) анналогичный контролю “Остатки” (только еще учитывается дополнительное измерение “Заказ”).

  4. 1.Взагрузил ИБ предыдущей задачи. Сделал регистр “Заказы покупателей”(измерения: номенклатура, номер заказа; ресурс кол-во) и документ “Заказ покупателя” . При проведении документа “Заказ покупателя” производится списание данных с регитсра “Остатки” и зачисление на регистр “Заказы покупателей”. В процедуру  проведения установил контролль остаков по новой методе (перед фиксацией транзакции).
    2.Т.к. один документ может использовать несколько заказов в табличную часть “Товары” документа “Реализация Товаров и Услуг” добавил реквизит “НомерЗаказ”.
    3.В модуле документа “Реализация товаров и услуг” модифицировал списание т.о. что строки с указаным заказом списываются из регистра “Заказы покупателей”, а без указания заказа из рагитсра “Остатки”. Сдедлал 2 новых подписки (“ПередЗаписью” и “ПриЗаписи”) на регистр “Заказы покупателей”. Аналогичные подписки по регистру “Остатки” модифицировал т.о. что-бы они работали толлько по номенклатуре без  указания заказа.

    Потренироваться в тестировании блокировок удаётся только умозрительно т.к. дома 1с только файловая.

    В план-графике названия глав 3-7 блока 2 не соответствуют тому как они указаны в учебной конф. и в заголовке этой стринички.

  5. ДЗ Выполнено.
    Добавил новый документ ЗаказПокупателя и регистр накопления РезервыТоваров (регистраторы Заказ и Реализация).  Модифицировал обработку заполнения Реализации по Заказу.
    В качестве допущения принял, что заказ покупателя списывает товар из регистра ОстаткиТоваров и делает приход по регистру РезервыТоваров.
    Модифицировал подписки на события из прошлого ДЗ.  Вместо параметра ТоварыДляКонтроля сделал два: ТоварыДляКонтроляОстатков и ТоварыДляКонтроляРезервов.
    Соответственно при проведении Заказа проверяю только остатки, при проведении Реализации и остатки и резервы в зависимости от переданных параметров.
    Т.к. мы используем новую технологию проведения – сначала запись, потом чтение – то для реализации корректной работы во многопользовательской среде можем использовать новое свойство набора записей регистров накопления – БлокироватьДляИзменения, для автоматического наложения блокировок в транзакции проведения.

  6. Задание выполнено.

    Создал документ ЗаказПокупателя с табличной частью Товары.
    Создал РН остатков ТоварыВРезерве, измерения – Номенклатура, Заказ. Ресурс – Количество. Указал регистраторы для этого регистра. Документ ЗаказПокупателя выполняет приход по РН ТоварыВРезерве.
    В табличную часть документа РеализацияТоваровИУслуг добавил реквизит Заказ (ссылка на документ ЗаказПокупателя). Модифицировал контроль остатков сделанный в ДЗ№ 11. Внес измерения в обработку проведения документа РеализацияТоваровИУслуг, где расход по РН ОстаткиТоваров формируется по строке с незаполненным реквизитом Заказ, а расход по РН ТоварыВРезерве по строке с заполненным реквизитом Заказ. Контроль отрицательных остатков реализовал в подписке на событие ОбработкаПроведения() для документа РеализацияТоваровИУслуг. Для этого контроль пришлось разбить на два этапа, собирая на первом этапе количество товара в резерве по РН ТоварыВРезерве, для того, чтобы затем определить свободный остаток по РН Остатки с учетом зарезервированного.
    Т.к. проверка остатков выполняется после записи движений, то для того, чтобы обеспечить корректную работу в клиент-серверном режиме, накладывал блокировку при записи движения с установкой свойства БлокироватьДляИзменения, а потом уже проверял остатки. Насколько я понял из видео-уроков это свойство обеспечивает блокировку в регистре по тем комбинациям измерений, которые записываются в наборе записей. И если нужно заблокировать именно те комбинации, по которым записываются записи, то лучше использовать это свойство (вместо объекта БлокировкаДанных). Т.к. не нужно формировать состав блокировки, то свойство БлокироватьДляИзменения сокращает код и уменьшает количество действий платформы.

  7. Задание сделал.
    Создал документ ЗаказПокупателя со структурой документа реализации и включил его в подписки ПередЗаписью и ПриПроведении, созданные в прошлом задании. В табличную часть реализации добавил реквизит ЗаказПокупателя. Создал РН РезервыТоваров вида остатки с измерениями Номенклатура, Заказ и ресурсом Количество. Указал соотв.регистраторы для регистров РезервыТоваров и Остатки. Скорректировал процедуру контроля остатков из подписки при проведении. 
    Для документа реализации для строк с заполненным заказом делается движение по регистру РезервыТоваров,  иначе – по регистру Остатки. Далее проверяю объединенным запросом по двум регистрам наличие отрицательных остатков.
    Для документа ЗаказПокупателя делаются расходные движения по регистру Остатки и приходные – по регистру РезервыТоваров, далее 
    запросом по регистру Остатки производится контроль остатков.
    Для корректной работы нескольких пользователей одновременно устанавливал перед записью движений вида расход свойство набора записей БлокироватьДляИзменения в истину.

  8. Общая схема решения будет следующей. Документ «Заказ покупателя» будет делать движения приход по регистру накопления «Резервы товаров». В документе реализация контроль будет реализован в два этапа. На первом этапе анализируются строки табличной части «Товары» в которых заполнен реквизит «Заказ покупателя». При этом сначала делаются движения по расходу в регистре накопления «Резервы товаров», а затем осуществляется контроль отрицательных остатков, т.е. контроль реализуется по новой схеме. На втором этапе анализу подвергаются строки табличной части с пустым реквизитом «Заказ покупателя», контроль осуществляется по наличию  свободного остатка, который вычисляется как разница между общим количестве на остатке и количество зарезервированного товара. В этом случае контроль остаток осуществляется по старой классической схеме, поскольку нехватка свободного количества не означает отрицательного остатка по регистру «Остатки товаров».
    Данную схему я и реализовал, создал документ «Заказ покупателя» с табличной частью «Товары», регистр накопления «Резервы товаров» с измерениями «Заказ покупателя» и «Номенклатура» и одним ресурсом «Количество». В документ «Реализация» добавил в табличную часть «Товары» реквизит «Заказ покупателя». Внес необходимые изменения в модуль проведения документа «Реализация», контроль остатков по регистру «Резервы товаров», реализовал в подписке на события «При записи», источником для которого являлся этот регистр. Контроль свободного остатка осуществлял в процедуре «Обработка проведения».
    Для корректной работы конфигурации в клиент-серверном варианте, реализовал управление блокировками, для этого пришлось разрывать тексты запросов, после считывания данных и накладывать блокировки до проверки остатков. Это проделал с помощью менеджера временных таблиц.

  9. А что за глава “Глава 3. Особенные свойства регистров” ? В списке такой нет.  Третья глава называется “Агрегаты”