1С:Предприятие 8.2 /
Разработчикам /
Практикум
Практикум 8. Оптимизация процедуры проведения
Оптимизация процедуры проведения документа ОказаниеУслуги
Особенности использования ссылочных данных
Оптимизация документа ОказаниеУслуги
Оптимизация процедуры проведения документа ОказаниеУслуги
Теперь, когда вы уже достаточно хорошо знакомы с языком запросов, мы наконец-то можем приступить к одной из самых важных тем → к оптимизации документа ОказаниеУслуги, и, в частности, к полному изменению его обработчика событияОбработкаПроведения.
Зачем это нужно?
Во-первых, предположим, что руководство фирмы решило, наконец-то, завершить «эксперименты» по ручному вводу стоимости расходуемых материалов и перейти на автоматический расчет стоимости расходуемых материалов «по среднему».
Во-вторых, в обработчике события ОбработкаПроведения мы используем обращение к реквизиту ВидНоменклатуры справочника Номенклатура «через точку». Такое обращение может сильно замедлить скорость выполнения процедуры при больших объемах табличной части документа.
Поэтому, изменения, вносимые нами в документ ОказаниеУслуги, будут преследовать две цели:
- определение стоимости расходуемых материалов при проведении документа ;
- повышение скорости выполнения процедуры.
Особенности использования ссылочных данных
Термином ссылочные данные мы будем обозначать данные, хранящиеся в базе данных, доступ к которым возможен при помощи объектов встроенного языка вида Ссылка:СправочникСсылка.<имя>, ДокументСсылка. <имя> и т.д.
Для того чтобы дальнейшее изложение было понятнее, построим объяснение на примере получения ссылки на вид номенклатуры при проведении документа ОказаниеУслуги.
Не все данные, хранящиеся в базе данных, являются ссылочными. Это связано с тем, что в модели данных 1С:Предприятие 8.1 существует деление на данные, представляющие объектные сущности (справочники, планы счетов , документы и т.д.), и данные, представляющие необъектные сущности ( регистры сведений, регистры накопления и т.д.).
С точки зрения системы некоторая совокупность объектных данных определяется не только значениями своих полей, но и самим фактом своего существования. Другими словами, удалив из базы некоторую совокупность объектных данных, мы не сможем вернуть систему в то же состояние, которое было до удаления. Даже если мы заново создадим ту же самую совокупность объектных данных с теми же самыми значениями полей, с точки зрения системы это будет ДРУГАЯ совокупность объектных данных. Каждую такую совокупность объектных данных, уникальную с точки зрения системы, называют объектом базы данных. Для того чтобы система могла отличать один объект базы данных от другого, каждый объект базы данных (совокупность объектных данных) имеет внутренний идентификатор. Различные объекты базы данных всегда будут иметь разные внутренние идентификаторы. Этот идентификатор хранится вместе с остальными данными объекта в специальном поле Ссылка.
Необъектные данные хранятся в виде записей и с точки зрения системы определяются исключительно значениями своих полей. Таким образом, удалив некоторую запись и записав после этого новую, с точно такими же значениями всех полей, мы получим то же самое состояние базы данных, которое было до удаления.
Таким образом, поскольку мы можем однозначно указать на каждый объект базы данных, у нас появляется возможность хранить такой указатель в полях других таблиц базы данных, выбирать его в поле ввода, указывать в параметрах запроса при поиске по ссылке и т.д. Во всех этих случаях как раз и будет использоваться объект встроенного языка вида Ссылка. Фактически этот объект хранит только внутренний идентификатор, находящийся в поле Ссылка.
Например, если взять наш документ ОказаниеУслуги, то в поле, хранящем реквизит табличной части Номенклатура, на самом деле находится внутренний идентификатор, указывающий на элемент справочника Номенклатура.
Когда в обработчике события ОбработкаПроведения документа ОказаниеУслуги мы присваиваем значение реквизита Номенклатура табличной части какой-либо переменной, мы имеем дело с объектом ДокументОбъект.ОказаниеУслуги. Этот объект содержит в себе значения всех реквизитов документа и реквизитов его табличных частей. Поэтому обращение
приводит к тому, что мы просто читаем данные, хранящиеся в оперативной памяти:
Однако, когда мы обращаемся к виду номенклатуры как к реквизиту того элемента справочника, ссылка на который указана в табличной части документа
происходит следующее:
Поскольку в объекте ДокументОбъект.ОказаниеУслуги есть только ссылка на элемент справочника Номенклатура и больше никаких данных об этом элементе нет, система возьмет эту ссылку и обратится по ней в кэш объектов в надежде найти там данные того объекта, ссылка на который у нее есть. Если кэш объектов не будет иметь нужных данных, он обратится к базе данных с тем, чтобы прочитать все данные объекта, ссылкой на который он обладает. После того, как все данные, хранящиеся в реквизитах нужного элемента справочника и в реквизитах его табличных частей, будут считаны в кэш объектов, кэш объектов вернет запрашиваемую ссылку, хранящуюся в реквизите ВидНоменклатуры справочника Номенклатура.
Как несложно догадаться, подобное обращение к базе данных требует большего количества времени, нежели простое чтение из оперативной памяти. При интерактивном заполнении документа подобные задержки ничтожно малы, по сравнению со скоростью работы пользователя . Однако при выполнении большого количества расчетов (например, при проведении больших документов, содержащих несколько тысяч строк), разница во времени может быть довольно ощутимой.
Из всего выше сказанного можно сделать следующий вывод: если алгоритм проведения документа использует только те данные, которые присутствуют в реквизитах документа (и его табличных частей), вполне достаточно использовать конструктор движений документа (как это было у нас в случае с документом ПриходнаяНакладная). Если же в алгоритме проведения требуется анализировать дополнительные реквизиты объектов, ссылки на которые содержатся в документе, а также использовать результаты расчета итогов регистров, следует использовать запросы для более быстрой выборки данных из базы данных.
То же самое справедливо в отношении выполнения любых участков программы, критичных по производительности. Механизм запросов лучше «читает» информационную базу и может за один раз выбрать все необходимые данные, поэтому, например, в типовых решениях вы практически не увидите использования объекта СправочникВыборка.<имя>.
Оптимизация документа ОказаниеУслуги
1. Первое, что мы сделаем для оптимизации документа ОказаниеУслуги, - удалим реквизит табличной части Стоимость, который нам не понадобится в дальнейшем.
2. Также следует удалить соответствующую колонку из табличного поля, расположенного в форме .
3. После этого можно полностью удалить содержимое обработчика события ОбработкаПроведения в модуле документа и создать в нем заготовку процедуры проведения. Текст запроса, выполняемого в режиме оперативного проведения, будет отличаться от запроса, выполняемого при неоперативном проведении . Поэтому формирование текста запроса мы включим в условие Если …¦ Иначе …¦ КонецЕсли:
4. Сначала составим запрос, который будет выполняться при оперативном проведении документа. Установим курсор перед точкой с запятой, из контекстного меню вызовем конструктор запроса,
на вопрос «Создать новый запрос?» согласимся, раскроем таблицу ПереченьНоменклатуры табличной части документа ОказаниеУслуги и выберем из нее поля:
- Номенклатура;
- Количество;
- Номенклатура.ВидНоменклатуры;
- Сумма.
Эти поля будут нужны нам для задания значений измерений регистров и их ресурсов. Кроме того, поле ВидНоменклатуры понадобится нам для анализа того, чем является номенклатура , указанная в документе: материалом или услугой.
5. Для указания значений ресурса Стоимость регистров СтоимостьМатериалов и Продажи нам понадобится рассчитать текущую стоимость номенклатуры как частное стоимости остатка этого материала и его оставшегося количества.
Поэтому добавим к списку выбранных таблиц еще две:
- РегистНакопления.СтоимостьМатериалов.Остатки;
- РегистНакопления.ОстаткиМатериалов.Остатки.
6. Для этих виртуальных таблиц нам нужно будет задать одинаковые параметры. Они будут включать в себя момент времени, на который должны быть получены остатки этих регистров, и условие получения данных.
Условие получения данных указывает, что остатки должны быть получены только по тем позициям номенклатуры, которые содержатся в проводимом документе (перед выполнением запроса мы передадим в параметр СписокНоменклатурыДокумента список всех позиций номенклатуры, содержащихся в проводимом документе).
7. После того как будут заданы параметры обеих виртуальных таблиц регистров накопления, выберем из них поля СтоимостьОстаток и КоличествоОстаток:
8. Теперь вспомним о том, что документы ОказаниеУслуги могут быть проведены как в оперативном, так и в неоперативном режиме.
Поскольку в оперативном режиме нам понадобится контролировать остатки спмсываемой номенклатуры на складе, выберем еще раз виртуальную таблицу регистра накопленияОстаткиМатериаловОстатки и переименуем ее в ОстаткиМатериаловОстаткиНаСкладе.
9. Для этой виртуальной таблицы мы также укажем параметр МоментВремени, а в условии напишем, что материал должен находиться в списке номенклатуры и склад должен быть равен складу, указанному в документе:
10. Теперь из этой виртуальной таблицы мы выберем поле КоличествоОстаток:
11. На этом формирование списка выбранных полей закончено, и мы можем перейти к заданию условий связи между выбранными таблицами.
12. Каждую из виртуальных таблиц необходимо связать с таблицей документа таким образом, что для всех записей таблицы документа должны подбираться имеющиеся записи виртуальной таблицы, причем номенклатура в таблице документа должна быть равна материалу из виртуальной таблицы:
Выбранные таблицы
Условия связи между таблицами
13. Теперь перейдем на закладку Дополнительно и установим флаг Для изменения. Предложение ДЛЯ ИЗМЕНЕНИЯ позволяет заблаговременно заблокировать чтение указанных данных (которые могут читаться транзакцией другого соединения) уже при считывании, чтобы исключить взаимные блокировки при записи. Это предложение дает возможность указать в запросе те таблицы, считываемые данные которых предполагается изменить.
14. Поскольку мы планируем выполнить запись регистров накопления ОстаткиМатериалов, укажем таблицы этих регистров в качестве таблиц для изменения:
15. Перейдем на закладку Условия и зададим условия отбора из таблицы документа только строк проводимого документа (ссылка на него будет передана в параметр запроса Ссылка):
16. Перейдем на закладку Псевдонимы и зададим следующие псевдонимы полей:
- НоменклатураВидНоменклатуры → ВидНоменклатуры;
- КоличествоОстаток1 → КоличествоНаСкладе.
17. Нажмем ОК и посмотрим, какой текст запроса сформировал конструктор:
В этом запросе нет ничего сложного, за исключением, быть может, трех левых соединений с таблицей табличной части документа и использования ключевого предложения ДЛЯ ИЗМЕНЕНИЯ, значение которого было уже объяснено.
18. Текст запроса для случая неоперативного проведения документа будет практически таким же, за исключением того, что в нем будет отсутствовать третье левое соединение и, соответственно, поле КоличествоОстатокНаСкладе, т.к. проверку остатков в этом случае мы выполнять не будем:
19. Теперь добавим в текст обработчика задание параметров запроса:
Обратите внимание, что для формирования списка номенклатуры документа мы используем метод ВыгрузитьКолонку() объекта ДокументТабличнаяЧасть.Оказание Услуги.ПереченьНоменклатуры.
20. После этого добавим получение результата запроса и цикл его обхода:
21. Теперь, прежде чем начать формирование движений по регистрам , нам нужно проверить наличие на складе достаточного количества номенклатуры в цикле обхода результата запроса:
22. И в заключение, после проверки остатков на складе, перед самым концом цикла, добавим формирование движений по регистрам накопления:
23. А сразу после цикла добавим запись движений регистров:
24. Запустим 1С:Предприятие в режиме отладки и проверим работу нового обработчика события ОбработкаПроведения, перепроведя все документы ОказаниеУслуги.
Другие материалы по теме:
остаткиматериалов, оказаниеуслуги, условие, процедуры, движения, накопления, ссылка, условия, регистр., номенклатуры, остатки, номенклатура, объект, элемент, изменения, справочника, результат, количество, реквизит, справочник., документы, данные, справочник, документа, документ
Материалы из раздела: 1С:Предприятие 8.2 / Разработчикам / Практикум
Другие материалы по теме:
Источники данных для расчетов бюджетирования
Общие механизмы товарных документов
Основные элементы подсистемы. Горизонт и периодичность планирования
Нас находят: оптимизация проведения документа оказание услуги 1с, 18919, оптимизация перепроведения документов в 1с 8 3ds, 1с оптимизация времени проведения документа, 1с 8 3 оптимизация процедуры проведения документа в управляемой форме, jgnbvbpfwbz ghjdtltybz ljrevtynf 1c, для чего нужна оптимизация ghjdtltbz ljrevtynf 1с, теперь добавим в текст обработчика задания параметров запроса, что такое оптимизация проведения документа в 1С, практикум Определение оптимизации транспортного процесса
Мы на Facebook