584 документа
← К списку

В 1C:EDT

страница

В 1C:EDT

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

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

Все данные, связанные с номенклатурой, которая содержится в табличной части документа, вы будете получать с помощью запроса к базе данных. А данные, связанные с самим документом (например, дата документа, склад), вы по-прежнему будете получать из документа. Такой подход позволит вам читать только нужные данные и за счет этого максимально ускорить проведение документа.

Итак, запросом вы будете получать:

  • номенклатуру,
  • вид номенклатуры,
  • количество.

Из документа вы возьмете следующие данные:

  • дата,
  • клиент,
  • мастер,
  • склад.

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

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

В процедуре обработки проведения установите курсор перед циклом обхода табличной части документа и в контекстном меню нажмите Конструктор запроса с обработкой результата (рис. 12.4).

Рис. 12.4. Вызов конструктора запроса

В конструкторе запросов перейдите на закладку Таблицы и поля и выберите таблицу ОказаниеУслугиПереченьНоменклатуры – это табличная часть документа ОказаниеУслуги.

Из этой таблицы выберите поля Номенклатура, Номенклатура.ВидНоменклатуры, Количество(рис. 12.5).

Рис. 12.5. Выбранные поля

Но вам нужны не все записи этой таблицы, а только те, которые относятся к вашему документу.

Поэтому на закладке Условия задайте условие отбора из таблицы документа только строк проводимого документа.

Для этого перетащите поле Ссылка в список условий запроса (листинг 12.4).

**Листинг 1****2.**4. Условие отбора из таблицы документа

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

Ссылку на этот документ вы передадите в параметр запроса Ссылка (рис. 12.6).

Рис. 12.6. Условие отбора из таблицы документа

Также следует учесть, что в табличной части документа одна и та же номенклатура может встречаться несколько раз.

Поэтому на закладке Группировка перетащите поля Номенклатура и Номенклатура.ВидНоменклатуры в список Поле группировки, а поле Количество – в список Суммируемое поле.

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

Рис. 12.7. Группировка строк таблицы документа

На закладке Объединения/Псевдонимы задайте псевдонимы для полей Количество – КоличествоВДокументе, а для поля Номенклатура.ВидНоменклатуры задайте псевдоним ВидНоменклатуры просто для облегчения чтения запроса (рис. 12.8).

Рис. 12.8. Псевдонимы полей

Нажмите ОК. В результате конструктор поместит следующий фрагмент в процедуру обработки проведения документа (листинг 12.5).

Листинг 1****2.5. Текст запроса с обходом результата

// {{КОНСТРУКТОР_ЗАПРОСА_С_ОБРАБОТКОЙ_РЕЗУЛЬТАТА

// Данный фрагмент построен конструктором.

// При повторном использовании конструктора внесенные вручную изменения будут утеряны!

 

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

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

"ВЫБРАТЬ

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

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

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

|ИЗ

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

|ГДЕ

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

|СГРУППИРОВАТЬ ПО

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

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

 

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

 

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

 

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

 

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

// Вставить обработку выборки ВыборкаДетальныеЗаписи

КонецЦикла;

 

//}}КОНСТРУКТОР_ЗАПРОСА_С_ОБРАБОТКОЙ_РЕЗУЛЬТАТА

Комментарии конструктора запроса в начале и конце фрагмента можно удалить.

Поскольку для построения запроса вы использовали Конструктор запроса с обработкой результата, конструктор написал за вас код для выполнения и обхода записей запроса.

После создания запроса в переменной Запрос сначала устанавливается собственно текст запроса, а затем устанавливается значение параметра запроса &Ссылка как ссылка на тот документ, в модуле которого вы сейчас находитесь (листинг 12.6).

Листинг 1****2.6. Установка параметра запроса

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

В результате выполнения запроса в переменную ВыборкаДетальныеЗаписи помещается выборка записей из результата запроса.

Далее, используя метод выборки Следующий() (ВыборкаДетальныеЗаписи.Следующий()), вы будете в цикле обходить выборку записей запроса.

Чтобы в цикле получить значение какого-либо поля выборки из результата запроса, вы будете обращаться к полям запроса через точку от переменной ВыборкаДетальныеЗаписи, которая содержит текущую строку выборки запроса. Например, так: ВыборкаДетальныеЗаписи.Номенклатура.

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

Теперь вам осталось перенести существовавшие ранее в процедуре проведения документа строки, описывающие движения регистра ОстаткиМатериалов, внутрь цикла обхода результата запроса вместо комментария «// Вставить обработку выборки ВыборкаДетальныеЗаписи» (листинг 12.7).

Листинг 1****2.7. Цикл обхода записей запроса

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

 

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

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

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

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

Движение.Материал = ТекСтрокаПереченьНоменклатуры.Номенклатура;

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

Движение.Количество = ТекСтрокаПереченьНоменклатуры.Количество;

 

КонецЦикла;

Поскольку вы находитесь теперь не в цикле обхода записей табличной части документа, а в цикле обхода результата запроса, вам нужно заменить обращение ТекСтрокаПереченьНоменклатуры на ВыборкаДетальныеЗаписи (листинг 12.8).

Листинг 1****2.8. Формирование движений регистра

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

 

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

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

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

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

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

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

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

 

КонецЦикла;

ПРИМЕЧАНИЕ

Для упрощения восприятия новый текст в листингах выделен жирным шрифтом.

Не забудьте, что для поля Количество вы задали псевдоним в запросе, поэтому замените его на КоличествоВДокументе (листинг 12.9).

Листинг 1****2.9. Формирование движений регистра

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

 

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

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

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

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

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

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

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

 

КонецЦикла;

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

Листинг 1****2.10. Формирование движений регистра только для материалов

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

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

 

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

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

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

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

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

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

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

 

КонецЕсли**;**

 

КонецЦикла;

Используя обращение ВыборкаДетальныеЗаписи.ВидНоменклатуры, вы можете проанализировать значение реквизита ВидНоменклатуры для номенклатуры, содержащейся в текущей записи результата запроса.

Полученное значение вы сравниваете со значением Материал перечисления ВидыНоменклатуры (Перечисления.ВидыНоменклатуры.Материал).

Если значения совпадают, операторы цикла выполняются. Если нет, исполнение кода переходит к следующей итерации цикла.

Оставшийся цикл обхода табличной части можно удалить (листинг 12.11).

Листинг 1****2.11. Ненужные строки

Для Каждого ТекСтрокаПереченьНоменклатуры Из ПереченьНоменклатуры Цикл

 

КонецЦикла;

В результате процедура проведения примет следующий вид (листинг 12.12).

Листинг 1****2.12. Процедура «ОбработкаПроведения()»

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

 

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

 

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

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

"ВЫБРАТЬ

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

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

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

|ИЗ

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

|ГДЕ

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

|СГРУППИРОВАТЬ ПО

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

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

 

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

 

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

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

 

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

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

 

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

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

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

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

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

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

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

 

КонецЕсли;

 

КонецЦикла;

 

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