Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Оптимизация процедуры проведения документа Оказ...doc
Скачиваний:
1
Добавлен:
09.11.2019
Размер:
838.14 Кб
Скачать

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

Иначе

Запрос.Текст =

"ВЫБРАТЬ

| ОказаниеУслугиПереченьНоменклатуры.Номенклатура,

| ОказаниеУслугиПереченьНоменклатуры.Количество,

| ОказаниеУслугиПереченьНоменклатуры.Номенклатура.ВидНоменклатуры КАК ВидНоменклатуры,

| ОказаниеУслугиПереченьНоменклатуры.Сумма,

| ОстаткиМатериаловОстатки.КоличествоОстаток,

| СтоимостьМатериаловОстатки.СтоимостьОстаток

|ИЗ

| Документ.ОказаниеУслуги.ПереченьНоменклатуры КАК ОказаниеУслугиПереченьНоменклатуры

| ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ОстаткиМатериалов.Остатки(&МоментВремени, Материал В (&СписокНоменклатурыДокумента)) КАК ОстаткиМатериаловОстатки

| ПО ОказаниеУслугиПереченьНоменклатуры.Номенклатура = ОстаткиМатериаловОстатки.Материал

| ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.СтоимостьМатериалов.Остатки(&МоментВремени, Материал В (&СписокНоменклатурыДокумента)) КАК СтоимостьМатериаловОстатки

| ПО ОказаниеУслугиПереченьНоменклатуры.Номенклатура = СтоимостьМатериаловОстатки.Материал

|ГДЕ

| ОказаниеУслугиПереченьНоменклатуры.Ссылка = &Ссылка

|

|ДЛЯ ИЗМЕНЕНИЯ

| РегистрНакопления.ОстаткиМатериалов.Остатки,

| РегистрНакопления.СтоимостьМатериалов.Остатки" ;

КонецЕсли;

Запрос.УстановитьПараметр("МоментВремени", МоментВремени());

Запрос.УстановитьПараметр("СписокНоменклатурыДокумента", ПереченьНоменклатуры.ВыгрузитьКолонку("Номенклатура"));

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

Обратите внимание, что для формирования списка номенклатуры документа мы используем метод ВыгрузитьКолонку() объекта ДокументТабличнаяЧасть.ОказаниеУслуги.ПереченьНоменклатуры.

После этого добавим получение результата запроса и цикл его обхода (листинг 7).

Листинг 7. Получение результата запроса и цикл его обхода

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

Пока ВыборкаРезультатаЗапроса.Следующий() Цикл

КонецЦикла;

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

Теперь, прежде чем начать формирование движений по регистрам, нам нужно проверить наличие на складе достаточного количества номенклатуры в цикле обхода результата запроса (листинг 8).

Листинг 8. Проверка на складе достаточного количества номенклатуры

Пока ВыборкаРезультатаЗапроса.Следующий() Цикл

// Проверить остаток при оперативном проведении.

Если Режим = РежимПроведенияДокумента.Оперативный Тогда

Если ВыборкаРезультатаЗапроса.ВидНоменклатуры = Перечисления.ВидыНоменклатуры.Материал Тогда

Остаток = ?(ВыборкаРезультатаЗапроса.КоличествоОстатокНаСкладе = Null, 0, ВыборкаРезультатаЗапроса.КоличествоОстатокНаСкладе);

Если Остаток < ВыборкаРезультатаЗапроса.Количество Тогда

Сообщить("Материала" + СокрЛП(ВыборкаРезультатаЗапроса.Номенклатура) + "имеется только" + Остаток);

Отказ = Истина;

Возврат;

КонецЕсли;

КонецЕсли;

КонецЕсли;

И в заключение, после проверки остатков на складе, перед самым концом цикла, добавим формирование движений по регистрам накопления (листинг 9).

Листинг 9. Формирование движений по регистрам накопления

// Сформировать движения.

Если ВыборкаРезультатаЗапроса.ВидНоменклатуры = Перечисления.ВидыНоменклатуры.Материал Тогда

// Регистр ОстаткиМатериалов Расход

Движение = Движения.ОстаткиМатериалов.Добавить();

Движение.ВидДвижения = ВидДвиженияНакопления.Расход;

Движение.Период = Дата;

Движение.Материал = ВыборкаРезультатаЗапроса.Номенклатура;

Движение.Склад = Склад;

Движение.Количество = ВыборкаРезультатаЗапроса.Количество;

// Регистр СтоимостьМатериалов Расход.

Движение = Движения.СтоимостьМатериалов.Добавить();

Движение.ВидДвижения = ВидДвиженияНакопления.Расход;

Движение.Период = Дата;

Движение.Материал = ВыборкаРезультатаЗапроса.Номенклатура;

// Рассчитать стоимость материала.

СтоимостьМатериала = ?(ВыборкаРезультатаЗапроса.КоличествоОстаток = Null, 0,

ВыборкаРезультатаЗапроса.СтоимостьОстаток / ВыборкаРезультатаЗапроса.КоличествоОстаток);

Движение.Стоимость = СтоимостьМатериала * ВыборкаРезультатаЗапроса.Количество;

КонецЕсли;

// Регистр Продажи

Движение = Движения.Продажи.Добавить();

Движение.Период = Дата;

Движение.Номенклатура = ВыборкаРезультатаЗапроса.Номенклатура;

Движение.Клиент = Клиент;

Движение.Мастер = Мастер;

Движение.Количество = ВыборкаРезультатаЗапроса.Количество;

Движение.Выручка = ВыборкаРезультатаЗапроса.Сумма;

Если ВыборкаРезультатаЗапроса.ВидНоменклатуры = Перечисления.ВидыНоменклатуры.Материал Тогда

Движение.Стоимость = СтоимостьМатериала * ВыборкаРезультатаЗапроса.Количество;

Иначе

Движение.Стоимость = 0;

КонецЕсли;

А сразу после цикла добавим запись движений регистров (листинг 10).

Листинг 6.10. Запись движений регистров

КонецЦикла;

// Записать движения регистров

Движения.ОстаткиМатериалов.Записать();

Движения.СтоимостьМатериалов.Записать();

Движения.Продажи.Записать();

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

Запустим 1С:Предприятие в режиме отладки и проверим работу нового обработчика события ОбработкаПроведения, перепроведя все документы Оказание услуги.

В заключение следует сделать небольшое отступление, которое касается задания параметров виртуальных таблиц, использовавшихся в наших запросах.

Как в первом, так и во втором запросах мы использовали условие, что материал должен находиться в списке значений, задаваемом одним из параметров запроса (листинг 11).

Листинг 11. Условие, накладываемое на материал

ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.СтоимостьМатериалов.Остатки(&МоментВремени, Материал В (&СписокНоменклатурыДокумента))

Однако при большом количестве строк табличной части документа, из которой формируется список номенклатуры документа, возможно, более эффективным будет не передача номенклатуры документа в списке значений, а выполнение вложенного запроса к временной таблице (листинг 12).

Листинг 12. Запрос во временной таблице

ВЫБРАТЬ * ИЗ НоменклатураДокумента

При этом временная таблица должна формироваться следующим образом (листинг 13):

Листинг 13. Формирование временной таблицы

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

Запрос = Новый Запрос;

Запрос.МенеджерВременныхТаблиц = МенеджерВременныхТаблиц;

Запрос.Текст =

"ВЫБРАТЬ РАЗЛИЧНЫЕ

| Номенклатура

|

|ПОМЕСТИТЬ

| НоменклатураДокумента

|

|ИЗ

| Документ.ОказаниеУслуги.ПереченьНоменклатуры КАК

| ОказаниеУслугиПереченьНоменклатуры

|

|ГДЕ

| ОказаниеУслугиПереченьНоменклатуры.Ссылка = &Ссылка";

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

Запрос.Выполнить();

Выбор решения требует сравнительных тестов и зависит от конкретной информационной базы, размеров документа, количества одновременно работающих пользователей, производительности компьютеров и т. д.