Механизм запросов
Механизм запросов — это один из способов доступа к данным, которые поддерживает платформа. Используя этот механизм, разработчик может читать и обрабатывать данные, хранящиеся в информационной базе; изменение данных с помощью запросов невозможно. Это объясняется тем, что запросы специально предназначены для быстрого получения и обработки некоторой выборки из больших массивов данных, которые могут храниться в базе данных.
Табличный способ доступа к данным
Запросы реализуют табличный способ доступа к данным, которые хранятся в базе данных. Это означает, что все данные представляются в виде совокупности связанных между собой таблиц, к которым можно обращаться как по-отдельности, так и к нескольким таблицам во взаимосвязи:

Такой способ работы с данными позволяет получать сложные выборки данных, сгруппированные и отсортированные определенным образом. Для этих выборок могут быть рассчитаны общие и промежуточные итоги, наложены ограничения на количество или состав записей и пр.
Язык запросов
Для того чтобы разработчик имел возможность использовать запросы для реализации собственных алгоритмов, в платформе реализован язык запросов. Этот язык основан на SQL, но при этом содержит значительное количество расширений, ориентированных на отражение специфики финансово-экономических задач и на максимальное сокращение усилий по разработке прикладных решений. Можно перечислить наиболее существенные возможности, реализуемые языком запросов:
Обращение к полям через точку (».»)
Если поля какой-либо таблицы имеют ссылочный тип (хранят ссылки на объекты другой таблицы), разработчик может в тексте запроса ссылаться на них через «.», при этом количество уровней вложенности таких ссылок система не ограничивает.

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

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

Автоматическое упорядочивание
Для выбора наиболее правильного («естественного») порядка вывода информации на экран или в отчет разработчику в большинстве случаев достаточно задать режим автоматического упорядочивания.

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

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

Стандартные SQL операции
В языке запросов поддерживаются стандартные для SQL операции, такие, как объединение (Union), соединение (Join) и т. д.

Временные таблицы
Язык запросов позволяет использовать в запросах временные таблицы. С их помощью можно повысить производительность запросов, в некоторых случаях снизить количество блокировок и сделать текст запроса более легким для восприятия.
Предположим, нужно получить данные из двух регистров накопления. Данные из одного регистра поместим во временную таблицу:

Запрос, использующий временную таблицу, будет иметь вид:

Пакетные запросы
Для более удобной работы с временными таблицами в языке запросов поддерживается работа с пакетными запросами — таким образом, создание временной таблицы и ее использование помещаются в один запрос. Пакетный запрос представляет собой последовательность запросов, разделенных символом «;». Запросы исполняются один за другим. Результатом выполнения пакетного запроса в зависимости от используемого метода будет являться либо результат, возвращаемый последним запросом пакета, либо массив результатов всех запросов пакета в той последовательности, в которой следуют запросы в пакете.

Конструкторы запроса
- Конструктор запроса позволяет составить только текст запроса. Подробнее…
- Конструктор запроса с обработкой результата помимо текста запроса формирует фрагмент программного кода, который исполняет запрос и выводит результаты в табличный документ или диаграмму. Подробнее…
Консоль запросов
Инструмент «Консоль запросов» позволяет разработчикам конфигураций и специалистам по внедрению отлаживать запросы и просматривать результаты их выполнения в режиме «1С:Предприятие 8». Подробнее…
В каких случаях использовать ссылку, запрос, выборку и объект
1С:Предприятие 8 содержит несколько способов получения одних и тех же данных. Для объектных сущностей (Справочников, Документов и т.д.) данные могут считываться с помощью ссылки, запроса, выборки и объекта. Подробно отличия ссылки, выборки и объекта описаны в разделе «Особенности использования типов данных, предназначенных для манипулирования объектами базы данных». В этом разделе мы дадим некоторые рекомендации, когда следует использовать какой способ доступа.
В общем случае, наиболее эффективным способом считывания данных является Запрос. В нем непосредственно указывается, как отбирать записи, и какие поля должны быть считаны. Соответственно, при выполнении запроса из базы данных будет выбрана только необходимая записи информация и передана на клиентский компьютер. Использование запроса позволяет избежать считывания полей и табличных частей, которые не нужны в конкретном случае.
Еще одним преимуществом запроса является возможность однократного считывания всей требуемой информации из нескольких связанных таблиц. То есть если нужно считать данные нескольких объектов или получить данные из других таблиц, связанных с объектами, то использование запроса будет эффективнее, чем несколько отдельных обращений к различным данным. Здесь важно заметить, что, с точки зрения производительности, существенным является не только объем считываемой информации, но и количество обращений к базе данных, так как каждое обращение влечет дополнительные «накладные» расходы.
Однако запрос будет выполнять считывание из базы данных при каждом вызове. Соответственно, при многократном обращении к одним и тем же данным будет выполняться многократное считывание. Этого можно избежать, обращаясь к свойствам ссылки. В этом случае используется кэширование объектов и в определенном интервале времени при повторном обращении к данным объекта не будет выполняться повторное считывание. Но следует учитывать, что обращение к любому полю через ссылку приведет к полному считыванию объекта (включая все поля и все табличные части). Соответственно, ссылку можно использовать для многократного обращения, если считывание объекта целиком не может его существенно замедлить. Например, получение признака «Проведен» у документа через ссылку приведет к считыванию в том числе и его табличной части. Если у документа табличная часть может иметь несколько сотен строк, то лучше воспользоваться запросом.
Разумеется, если необходимо многократно обращаться к одному и тому же полю в пределах одного и того же алгоритма, то эффективнее считать данные, запомнить их в переменную и обращаться к уже считанным данным. Но получение данных через ссылку может выдавать ранее считанные данные, даже если они были считаны в другом вызове встроенного языка, так как кэширование выполняется в рамках всей клиентской сессии.
Отдельно следует отметить возможность использования кэширования представлений. Если, например, необходимо получить представление элемента справочника, то эффективнее не обращаться через ссылку к наименованию, а преобразовать ссылку к строке. В этом случае будет использоваться специальный механизм получения представлений (так же с кэшированием) и если представления объекта еще нет в кэше, то объект не будет считываться целиком, а будут считываться только поля, необходимые для получения представления.
Если необходимо получить перечень объектов для отображения их на экране или вывода на печать, то эффективнее получать представления с помощью объекта «Запрос», а не ориентироваться на автоматическое получение представления при преобразовании ссылки к строке. Например, при выводе отчета о продажах в табличный документ достаточно легко допустить серьезную ошибку с точки зрения производительности, если выводить в табличный документ ссылки на товары. Отчет будет построен правильно, так как система автоматически преобразует ссылки к строке. Однако это преобразование при сотнях и тысячах строк может замедлить формирование отчета в несколько раз. Более правильным будет получение представлений непосредственно в запросе и вывод в табличный документ уже полученного представления в виде строки.
Аналогичным примером может являться отображение результатов запроса в форме путем выгрузки в таблицу значений или дерево значений. Если в ячейках табличного поля выводятся колонки, содержащие ссылки, то просмотр таблицы значений может существенно замедляться при многопользовательской работе. Это будет негативно сказываться и на работе конкретного пользователя, и на работе всей системы в целом. Можно рекомендовать также получать и ссылки, и их представления с помощью запроса и организовывать отображение информации в табличном поле таким образом, чтобы текст ячеек брался бы из колонок, содержащих только примитивные типы.
Однако следует учитывать, что обращение к представлениям ссылок при просмотре таблицы значений пользователем будет выполняться по мере отображения строк, а при получении представлений запросом они будут получаться по всем строкам сразу. В то же время, если будет выполняться поиск по таблице значений, то будут выбираться представления для всех строк (но по отдельности) и это будет существенно менее эффективно, чем единовременное получение представлений запросом.
При обработке информации (например, проведении документа) также можно рекомендовать использовать запросы для получения полей объектов, а не обращаться к большому количеству объектов через ссылки. Например, если нужно получить некоторый реквизит по всем товарам табличной части документа, то эффективнее выполнить запрос по табличной части с получением по каждому товару этого реквизита, чем обходить табличную часть и получать реквизит каждого товара через ссылку.
При использовании запроса вся считанная информация передается на клиентский компьютер и размещается в оперативной памяти. Если требуется обработать очень большие объемы информации, то можно рекомендовать использовать выборку. Выборка не предоставляет широких возможностей по отбору и упорядочиванию информации и считывает все поля и табличные части объектов, но зато она выполняет считывание порциями и, соответственно, может использоваться для обработки любых объемов данных без помещения их в оперативную память.
При получении объектов из выборки их повторное считывание не производится. Поэтому для массовой модификации объектов выборка может быть эффективней, чем считывание ссылок запросом и получение объектов по каждой ссылке.
С точки зрения поиска объектов (ссылок на объекты) по простым условиям (по коду, по наименованию и т.д.) использование запроса и методов менеджеров объектов ( НайтиПоКоду() и др.) не имеют существенных отличий по реализации с точки зрения платформы. Методы менеджеров имеет смысл использовать, если выполняются именно одиночные операции поиска. Основным преимуществом методов менеджеров является краткость записи в модуле. Если необходимы сложные условия или поиск нескольких объектов, то необходимо использовать запрос.
Информационные системы / Курсовая_6_семестр / Учебники / Радченко М.Г. 1С- Предприятие 8.3. Практическое пособие разработчика. Примеры и типовые приемы (2013) (1)
перечень номенклатуры документа; во второй части рассчитывается стоимость номенклатуры и формируются движения в регистрах накопления; и в третьей части производится контроль остатков номенклатуры при оперативном проведении документа.
Выделим эти три области в тексте процедуры, используя инструкции препроцессору #Область <имя области> и #КонецОбласти
Листинг 14.42. Процедура «ОбработкаПроведения()»
Процедура ОбработкаПроведения(Отказ, Режим)
Движения.ОстаткиМатериалов.Записывать = Истина; Движения.СтоимостьМатериалов.Записывать = Истина; Движения.Продажи.Записывать = Истина;
// Создать менеджер временных таблиц МенеджерВТ = Новый МенеджерВременныхТаблиц;
Запрос = Новый Запрос;
// Укажем, какой менеджер временных таблиц использует этот запрос Запрос.МенеджерВременныхТаблиц = МенеджерВТ;
Запрос.Текст p1294 ft12″> | ОказаниеУслугиПереченьНоменклатуры.Номенклатура,
СУММА(ОказаниеУслугиПереченьНоменклатуры.Сумма) КАК СуммаВДокументе
|ПОМЕСТИТЬ НоменклатураДокумента |ИЗ
Запрос2 = Новый Запрос; Запрос2.МенеджерВременныхТаблиц = МенеджерВТ;
462 1С:Предприятие 8.3. Практическое пособие разработчика
ЕСТЬNULL(СтоимостьМатериаловОстатки.СтоимостьОстаток, 0) КАК Стоимость,
ЕСТЬNULL(ОстаткиМатериаловОстатки.КоличествоОстаток, 0) КАК Количество
НоменклатураДокумента КАК НоменклатураДокумента
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.СтоимостьМатериалов.Остатки(
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ОстаткиМатериалов.Остатки(
// Установим необходимость блокировки данных в регистрах СтоимостьМатериалов
Движения.СтоимостьМатериалов.БлокироватьДляИзменения = Истина; Движения.ОстаткиМатериалов.БлокироватьДляИзменения = Истина;
// Запишем пустые наборы записей, чтобы читать остатки без учета данных в документе Движения.СтоимостьМатериалов.Записать(); Движения.ОстаткиМатериалов.Записать();
Пока ВыборкаДетальныеЗаписи.Следующий() Цикл Если ВыборкаДетальныеЗаписи.Количество = 0 Тогда
СтоимостьМатериала = 0; Иначе
СтоимостьМатериала = ВыборкаДетальныеЗаписи.Стоимость / ВыборкаДетальныеЗаписи.Количество;
Если ВыборкаДетальныеЗаписи.ВидНоменклатуры = Перечисления.ВидыНоменклатуры.Материал Тогда
Занятие 14 46 3
// Регистр ОстаткиМатериалов Расход Движение = Движения.ОстаткиМатериалов.Добавить();
Движение.ВидДвижения = ВидДвиженияНакопления.Расход; Движение.Период = Дата; Движение.Материал = ВыборкаДетальныеЗаписи.Номенклатура; Движение.Склад = Склад;
// Регистр СтоимостьМатериалов Расход Движение = Движения.СтоимостьМатериалов.Добавить();
Движение.ВидДвижения = ВидДвиженияНакопления.Расход; Движение.Период = Дата; Движение.Материал = ВыборкаДетальныеЗаписи.Номенклатура;
Движение.Стоимость = ВыборкаДетальныеЗаписи.КоличествоВДокументе * СтоимостьМатериала;
// Регистр Продажи Движение = Движения.Продажи.Добавить(); Движение.Период = Дата;
Движение.Номенклатура = ВыборкаДетальныеЗаписи.Номенклатура; Движение.Клиент = Клиент; Движение.Мастер = Мастер;
Движение.Количество = ВыборкаДетальныеЗаписи.КоличествоВДокументе; Движение.Выручка = ВыборкаДетальныеЗаписи.СуммаВДокументе; Движение.Стоимость = СтоимостьМатериала *
Если Режим = РежимПроведенияДокумента.Оперативный Тогда // Проверить отрицательные остатки Запрос3 = Новый Запрос;
И Склад = &Склад) КАК ОстаткиМатериаловОстатки
464 1С:Предприятие 8.3. Практическое пособие разработчика
РезультатЗапроса = Запрос3.Выполнить(); ВыборкаДетальныеЗаписи = РезультатЗапроса.Выбрать();
Пока ВыборкаДетальныеЗаписи.Следующий() Цикл Сообщение = Новый СообщениеПользователю(); Сообщение.Текст = «Не хватает » + Строка(-
ВыборкаДетальныеЗаписи.КоличествоОстаток) + » единиц материала «»» + ВыборкаДетальныеЗаписи.Материал + «»»;
Отказ = Истина; КонецЦикла;
В результате мы можем свернуть выделенные программные области в тексте процедуры (рис. 14.32).
Рис. 14.32. Выделение произвольных областей в модуле
Затем можно развернуть только нужную область модуля и работать с ней. Текст процедуры станет более компактным и читаемым.
В нашем примере мы разбили одну процедуру модуля на три логические части. Но чаще наоборот: когда модуль содержит много различных процедур, сходные по назначению процедуры можно объединить в группы. Например, в модуле формы можно выделить
такие области, как ПрограммныйИнтерфейс , ОбработчикиСобытий ,
СлужебныеПроцедурыИФункции . Название этих областей задается самим разработчиком и говорит само за себя.
Занятие 14 46 5
Области могут быть вложены друг в друга или в другие группируемые конструкции языка. При расстановке областей в модуле нужно следить за тем, чтобы области не пересекались между собой и с другими группируемыми конструкциями. Потому что группировка по таким областям работать не будет.
В режиме «1С:Предприятие»
Запустим «1С:Предприятие» в режиме отладки и проверим работу нового обработчика события ОбработкаПроведения , перепроведя все документы Оказание услуги .
В результате все работает точно так же, с точки зрения пользователя, но проведение документов организовано методически правильно и более эффективно с точки зрения доступа к данным.
Теория: устройство кеша
В разделе «Теория: особенности использования ссылочных данных» на стр. 413 мы упомянули о том, что в платформе есть некий кеш, который хранит в себе данные объектов, читаемых из базы данных. Теперь расскажем о работе этого механизма подробнее.
Система «1С:Предприятие» использует механизм кеширования данных объектов, считанных из базы данных при использовании объектной техники.
Таким образом, для получения реквизитов какого-либо объекта через ссылку выполняется обращение к кешу объектов, расположенному в оперативной памяти.
Кеш объектов состоит из двух частей: транзакционного кеша и обычного кеша. В зависимости от того, происходит ли обращение в рамках транзакции или нет, в действие вступает тот или иной кеш
Все данные, находящиеся в кеше, предназначены только для чтения ( ReadOnly ). Таким образом, чтение любых данных, получаемых через ссылку, выполняется только через кеш объектов, а запись – механизмами самих программных объектов.
466 1С:Предприятие 8.3. Практическое пособие разработчика
Рис. 14.33. Кеш объектов
Если при обращении к обычному кешу требуемых данных в нем нет, то выполняется чтение данных объекта из базы данных и сохранение их в кеше. Уникальным идентификатором для кеша в данном случае будет являться ссылка на объект базы данных. Поэтому данные каждого считанного объекта могут существовать в кеше в одном из двух видов: либо все данные объекта, либо представление объекта.
Таким образом, если мы обратимся к кешу для получения представления объекта и в кеше есть информация для нашей ссылки, данные будут взяты из кеша (если в кеше весь объект, нужное представление будет получено из данных объекта).
Если в кеше нет информации для нашей ссылки, из базы данных в кеш будут считаны только поля, необходимые для формирования представления объекта.
Если мы обратимся к кешу для получения реквизита объекта и в кеше есть информация для нашей ссылки, дальнейшие действия будут зависеть от того, что находится в кеше.
Если в кеше весь объект, значение реквизита будет получено из кеша. Если в кеше представление объекта, оно будет удалено из кеша,
Занятие 14 46 7
и в кеш будут считаны все данные объекта. Если же при получении реквизита объекта в кеше нет информации для нашей ссылки, из базы данных будут считаны все поля объекта.
Считанные данные будут находиться в кеше до тех пор, пока не наступит одно из следующих событий:
считанные данные будут вытеснены из кеша другими считанными данными других объектов (переполнение кеша);
при очередном обращении к кешу окажется, что считанные данные были изменены в базе данных;
закончится интервал времени в 20 минут.
Все считанные данные помещаются в последовательную очередь, и, поскольку объем кеша ограничен, наиболее старые данные будут вытесняться из кеша последними считанными.
При повторном обращении к кешу за данными уже считанного объекта будет анализироваться интервал времени, прошедший с момента появления данных в кеше.
Если обращение происходит в пределах 20 секунд после поступления данных в кеш, данные считаются верными (валидными). Если интервал превысил 20 секунд, будет выполняться проверка на соответствие версии данных, хранящихся в кеше, версии данных, находящихся в базе данных.
Если окажется, что версии данных не совпадают (т. е. произошло изменение данных в базе данных), данные, находящиеся в кеше, будут удалены из него, и будет выполнено повторное считывание данных из базы данных. Начиная с этого момента, идет отсчет следующего 20-секундного интервала валидности этих данных.
Кроме всех вышеперечисленных событий считанные данные будут удалены из кеша по истечении 20 минут после их последнего считывания из базы данных.
Таким образом, при последовательном выполнении двух операторов (листинг 14.43), где Номенклатура – это ссылка на объект справочника, на выполнение второго оператора будет тратиться гораздо меньше времени, поскольку в первом случае будет выполняться обращение к базе данных, а во втором – чтение из оперативной памяти (кеша объектов).
468 1С:Предприятие 8.3. Практическое пособие разработчика
Листинг 14.43. Последовательность операторов
А = Номенклатура.Наименование; В = Номенклатура.ВидНоменклатуры;
Если обращение к данным происходит в рамках транзакции, то оно переадресуется транзакционному кешу. В рамках транзакции в «1С:Предприятии» выполняются все операции, приводящие к изменению данных в базе данных. Например, в рамках транзакции выполняется обработка проведения документа.
Транзакция – это неделимая последовательность манипулирования данными, переводящая базу данных из одного целостного состояния в другое. Если по каким-то причинам одно из действий транзакции невыполнимо, база данных возвращается в то состояние, которое было до начала транзакции (происходит откат транзакции – Rollback ).
Транзакционный кеш по сути представляет собой ту же последовательную очередь, что и обычный кеш. Разница заключается в том, что все данные, находящиеся в транзакционном кеше, являются валидными (гарантированно актуальными).
При считывании данных в транзакционный кеш устанавливается блокировка на данные в базе данных, поэтому они гарантированно не могут быть изменены до окончания транзакции.
Транзакционный кеш хранит считанные данные до тех пор, пока они не будут вытеснены более поздними или пока не закончится транзакция. По окончании транзакции кеш очищается, однако действия, выполняемые при этом, зависят от состояния завершения транзакции.
Если транзакция завершена успешно ( Commit ), данные всех объектов, содержащиеся в транзакционном кеше, переносятся в обычный кеш, а транзакционный кеш очищается (рис. 14.34).
Если был выполнен отказ от изменений ( Rollback ), то просто очищается транзакционный кеш (рис. 14.35).
Занятие 14 46 9
Рис. 14.34. Транзакция завершена успешно
Рис. 14.35. Очистка транзакционного кеша при отказе от изменений
470 1С:Предприятие 8.3. Практическое пособие разработчика
; ; Как система «1С:Предприятие» выполняет обращение к ссылочным данным?
; ; Как используется кеш объектов?
; ; Почему для доступа к массивам данных информационной базы предпочтительнее использовать запросы?
; ; Что такое момент времени?
; ; Чем отличается оперативное проведение документов от неоперативного?
; ; Что такое оперативная отметка времени?
; ; Как запросом получить остатки регистра накопления?
; ; На что следует обращать внимание при указании параметров виртуальных таблиц запросов?
; ; Почему при неоперативном проведении документов не нужно контролировать остатки?
; ; Что такое временные таблицы, и зачем их использовать? ; ; Что такое менеджер временных таблиц?
; ; Как и зачем можно использовать временные таблицы в параметрах виртуальных таблиц?
Как система 1с предприятие выполняет обращение к ссылочным данным
В каких случаях использовать ссылку, запрос, выборку и объект
1С:Предприятие 8 содержит несколько способов получения одних и тех же данных. Для объектных сущностей (Справочников, Документов и т.д.) данные могут считываться с помощью ссылки, запроса, выборки и объекта. Подробно отличия ссылки, выборки и объекта описаны в разделе «Особенности использования типов данных, предназначенных для манипулирования объектами базы данных». В этом разделе мы дадим некоторые рекомендации, когда следует использовать какой способ доступа.
В общем случае, наиболее эффективным способом считывания данных является Запрос. В нем непосредственно указывается, как отбирать записи, и какие поля должны быть считаны. Соответственно, при выполнении запроса из базы данных будет выбрана только необходимая записи информация и передана на клиентский компьютер. Использование запроса позволяет избежать считывания полей и табличных частей, которые не нужны в конкретном случае.
Еще одним преимуществом запроса является возможность однократного считывания всей требуемой информации из нескольких связанных таблиц. То есть если нужно считать данные нескольких объектов или получить данные из других таблиц, связанных с объектами, то использование запроса будет эффективнее, чем несколько отдельных обращений к различным данным. Здесь важно заметить, что, с точки зрения производительности, существенным является не только объем считываемой информации, но и количество обращений к базе данных, так как каждое обращение влечет дополнительные «накладные» расходы.
Однако запрос будет выполнять считывание из базы данных при каждом вызове. Соответственно, при многократном обращении к одним и тем же данным будет выполняться многократное считывание. Этого можно избежать, обращаясь к свойствам ссылки. В этом случае используется кэширование объектов и в определенном интервале времени при повторном обращении к данным объекта не будет выполняться повторное считывание. Но следует учитывать, что обращение к любому полю через ссылку приведет к полному считыванию объекта (включая все поля и все табличные части). Соответственно, ссылку можно использовать для многократного обращения, если считывание объекта целиком не может его существенно замедлить. Например, получение признака «Проведен» у документа через ссылку приведет к считыванию в том числе и его табличной части. Если у документа табличная часть может иметь несколько сотен строк, то лучше воспользоваться запросом.
Разумеется, если необходимо многократно обращаться к одному и тому же полю в пределах одного и того же алгоритма, то эффективнее считать данные, запомнить их в переменную и обращаться к уже считанным данным. Но получение данных через ссылку может выдавать ранее считанные данные, даже если они были считаны в другом вызове встроенного языка, так как кэширование выполняется в рамках всей клиентской сессии.
Отдельно следует отметить возможность использования кэширования представлений. Если, например, необходимо получить представление элемента справочника, то эффективнее не обращаться через ссылку к наименованию, а преобразовать ссылку к строке. В этом случае будет использоваться специальный механизм получения представлений (так же с кэшированием) и если представления объекта еще нет в кэше, то объект не будет считываться целиком, а будут считываться только поля, необходимые для получения представления.
Если необходимо получить перечень объектов для отображения их на экране или вывода на печать, то эффективнее получать представления с помощью объекта «Запрос», а не ориентироваться на автоматическое получение представления при преобразовании ссылки к строке. Например, при выводе отчета о продажах в табличный документ достаточно легко допустить серьезную ошибку с точки зрения производительности, если выводить в табличный документ ссылки на товары. Отчет будет построен правильно, так как система автоматически преобразует ссылки к строке. Однако это преобразование при сотнях и тысячах строк может замедлить формирование отчета в несколько раз. Более правильным будет получение представлений непосредственно в запросе и вывод в табличный документ уже полученного представления в виде строки.
Аналогичным примером может являться отображение результатов запроса в форме путем выгрузки в таблицу значений или дерево значений. Если в ячейках табличного поля выводятся колонки, содержащие ссылки, то просмотр таблицы значений может существенно замедляться при многопользовательской работе. Это будет негативно сказываться и на работе конкретного пользователя, и на работе всей системы в целом. Можно рекомендовать также получать и ссылки, и их представления с помощью запроса и организовывать отображение информации в табличном поле таким образом, чтобы текст ячеек брался бы из колонок, содержащих только примитивные типы.
Однако следует учитывать, что обращение к представлениям ссылок при просмотре таблицы значений пользователем будет выполняться по мере отображения строк, а при получении представлений запросом они будут получаться по всем строкам сразу. В то же время, если будет выполняться поиск по таблице значений, то будут выбираться представления для всех строк (но по отдельности) и это будет существенно менее эффективно, чем единовременное получение представлений запросом.
При обработке информации (например, проведении документа) также можно рекомендовать использовать запросы для получения полей объектов, а не обращаться к большому количеству объектов через ссылки. Например, если нужно получить некоторый реквизит по всем товарам табличной части документа, то эффективнее выполнить запрос по табличной части с получением по каждому товару этого реквизита, чем обходить табличную часть и получать реквизит каждого товара через ссылку.
При использовании запроса вся считанная информация передается на клиентский компьютер и размещается в оперативной памяти. Если требуется обработать очень большие объемы информации, то можно рекомендовать использовать выборку. Выборка не предоставляет широких возможностей по отбору и упорядочиванию информации и считывает все поля и табличные части объектов, но зато она выполняет считывание порциями и, соответственно, может использоваться для обработки любых объемов данных без помещения их в оперативную память.
При получении объектов из выборки их повторное считывание не производится. Поэтому для массовой модификации объектов выборка может быть эффективней, чем считывание ссылок запросом и получение объектов по каждой ссылке.
С точки зрения поиска объектов (ссылок на объекты) по простым условиям (по коду, по наименованию и т.д.) использование запроса и методов менеджеров объектов ( НайтиПоКоду() и др.) не имеют существенных отличий по реализации с точки зрения платформы. Методы менеджеров имеет смысл использовать, если выполняются именно одиночные операции поиска. Основным преимуществом методов менеджеров является краткость записи в модуле. Если необходимы сложные условия или поиск нескольких объектов, то необходимо использовать запрос.
Механизм запросов
Механизм запросов — это один из способов доступа к данным, которые поддерживает платформа. Используя этот механизм, разработчик может читать и обрабатывать данные, хранящиеся в информационной базе; изменение данных с помощью запросов невозможно. Это объясняется тем, что запросы специально предназначены для быстрого получения и обработки некоторой выборки из больших массивов данных, которые могут храниться в базе данных.
Табличный способ доступа к данным
Запросы реализуют табличный способ доступа к данным, которые хранятся в базе данных. Это означает, что все данные представляются в виде совокупности связанных между собой таблиц, к которым можно обращаться как по-отдельности, так и к нескольким таблицам во взаимосвязи:

Такой способ работы с данными позволяет получать сложные выборки данных, сгруппированные и отсортированные определенным образом. Для этих выборок могут быть рассчитаны общие и промежуточные итоги, наложены ограничения на количество или состав записей и пр.
Язык запросов
Для того чтобы разработчик имел возможность использовать запросы для реализации собственных алгоритмов, в платформе реализован язык запросов. Этот язык основан на SQL, но при этом содержит значительное количество расширений, ориентированных на отражение специфики финансово-экономических задач и на максимальное сокращение усилий по разработке прикладных решений. Можно перечислить наиболее существенные возможности, реализуемые языком запросов:
Обращение к полям через точку (».»)
Если поля какой-либо таблицы имеют ссылочный тип (хранят ссылки на объекты другой таблицы), разработчик может в тексте запроса ссылаться на них через «.», при этом количество уровней вложенности таких ссылок система не ограничивает.

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

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

Автоматическое упорядочивание
Для выбора наиболее правильного («естественного») порядка вывода информации на экран или в отчет разработчику в большинстве случаев достаточно задать режим автоматического упорядочивания.

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

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

Стандартные SQL операции
В языке запросов поддерживаются стандартные для SQL операции, такие, как объединение (Union), соединение (Join) и т. д.

Временные таблицы
Язык запросов позволяет использовать в запросах временные таблицы. С их помощью можно повысить производительность запросов, в некоторых случаях снизить количество блокировок и сделать текст запроса более легким для восприятия.
Предположим, нужно получить данные из двух регистров накопления. Данные из одного регистра поместим во временную таблицу:

Запрос, использующий временную таблицу, будет иметь вид:

Пакетные запросы
Для более удобной работы с временными таблицами в языке запросов поддерживается работа с пакетными запросами — таким образом, создание временной таблицы и ее использование помещаются в один запрос. Пакетный запрос представляет собой последовательность запросов, разделенных символом «;». Запросы исполняются один за другим. Результатом выполнения пакетного запроса в зависимости от используемого метода будет являться либо результат, возвращаемый последним запросом пакета, либо массив результатов всех запросов пакета в той последовательности, в которой следуют запросы в пакете.

Конструкторы запроса
- Конструктор запроса позволяет составить только текст запроса. Подробнее…
- Конструктор запроса с обработкой результата помимо текста запроса формирует фрагмент программного кода, который исполняет запрос и выводит результаты в табличный документ или диаграмму. Подробнее…
Консоль запросов
Инструмент «Консоль запросов» позволяет разработчикам конфигураций и специалистам по внедрению отлаживать запросы и просматривать результаты их выполнения в режиме «1С:Предприятие 8». Подробнее…
Информационные системы / Курсовая_6_семестр / Учебники / Радченко М.Г. 1С- Предприятие 8.3. Практическое пособие разработчика. Примеры и типовые приемы (2013) (1)
перечень номенклатуры документа; во второй части рассчитывается стоимость номенклатуры и формируются движения в регистрах накопления; и в третьей части производится контроль остатков номенклатуры при оперативном проведении документа.
Выделим эти три области в тексте процедуры, используя инструкции препроцессору #Область <имя области> и #КонецОбласти
Листинг 14.42. Процедура «ОбработкаПроведения()»
Процедура ОбработкаПроведения(Отказ, Режим)
Движения.ОстаткиМатериалов.Записывать = Истина; Движения.СтоимостьМатериалов.Записывать = Истина; Движения.Продажи.Записывать = Истина;
// Создать менеджер временных таблиц МенеджерВТ = Новый МенеджерВременныхТаблиц;
Запрос = Новый Запрос;
// Укажем, какой менеджер временных таблиц использует этот запрос Запрос.МенеджерВременныхТаблиц = МенеджерВТ;
Запрос.Текст p1294 ft12″> | ОказаниеУслугиПереченьНоменклатуры.Номенклатура,
СУММА(ОказаниеУслугиПереченьНоменклатуры.Сумма) КАК СуммаВДокументе
|ПОМЕСТИТЬ НоменклатураДокумента |ИЗ
Запрос2 = Новый Запрос; Запрос2.МенеджерВременныхТаблиц = МенеджерВТ;
462 1С:Предприятие 8.3. Практическое пособие разработчика
ЕСТЬNULL(СтоимостьМатериаловОстатки.СтоимостьОстаток, 0) КАК Стоимость,
ЕСТЬNULL(ОстаткиМатериаловОстатки.КоличествоОстаток, 0) КАК Количество
НоменклатураДокумента КАК НоменклатураДокумента
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.СтоимостьМатериалов.Остатки(
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ОстаткиМатериалов.Остатки(
// Установим необходимость блокировки данных в регистрах СтоимостьМатериалов
Движения.СтоимостьМатериалов.БлокироватьДляИзменения = Истина; Движения.ОстаткиМатериалов.БлокироватьДляИзменения = Истина;
// Запишем пустые наборы записей, чтобы читать остатки без учета данных в документе Движения.СтоимостьМатериалов.Записать(); Движения.ОстаткиМатериалов.Записать();
Пока ВыборкаДетальныеЗаписи.Следующий() Цикл Если ВыборкаДетальныеЗаписи.Количество = 0 Тогда
СтоимостьМатериала = 0; Иначе
СтоимостьМатериала = ВыборкаДетальныеЗаписи.Стоимость / ВыборкаДетальныеЗаписи.Количество;
Если ВыборкаДетальныеЗаписи.ВидНоменклатуры = Перечисления.ВидыНоменклатуры.Материал Тогда
Занятие 14 46 3
// Регистр ОстаткиМатериалов Расход Движение = Движения.ОстаткиМатериалов.Добавить();
Движение.ВидДвижения = ВидДвиженияНакопления.Расход; Движение.Период = Дата; Движение.Материал = ВыборкаДетальныеЗаписи.Номенклатура; Движение.Склад = Склад;
// Регистр СтоимостьМатериалов Расход Движение = Движения.СтоимостьМатериалов.Добавить();
Движение.ВидДвижения = ВидДвиженияНакопления.Расход; Движение.Период = Дата; Движение.Материал = ВыборкаДетальныеЗаписи.Номенклатура;
Движение.Стоимость = ВыборкаДетальныеЗаписи.КоличествоВДокументе * СтоимостьМатериала;
// Регистр Продажи Движение = Движения.Продажи.Добавить(); Движение.Период = Дата;
Движение.Номенклатура = ВыборкаДетальныеЗаписи.Номенклатура; Движение.Клиент = Клиент; Движение.Мастер = Мастер;
Движение.Количество = ВыборкаДетальныеЗаписи.КоличествоВДокументе; Движение.Выручка = ВыборкаДетальныеЗаписи.СуммаВДокументе; Движение.Стоимость = СтоимостьМатериала *
Если Режим = РежимПроведенияДокумента.Оперативный Тогда // Проверить отрицательные остатки Запрос3 = Новый Запрос;
И Склад = &Склад) КАК ОстаткиМатериаловОстатки
464 1С:Предприятие 8.3. Практическое пособие разработчика
РезультатЗапроса = Запрос3.Выполнить(); ВыборкаДетальныеЗаписи = РезультатЗапроса.Выбрать();
Пока ВыборкаДетальныеЗаписи.Следующий() Цикл Сообщение = Новый СообщениеПользователю(); Сообщение.Текст = «Не хватает » + Строка(-
ВыборкаДетальныеЗаписи.КоличествоОстаток) + » единиц материала «»» + ВыборкаДетальныеЗаписи.Материал + «»»;
Отказ = Истина; КонецЦикла;
В результате мы можем свернуть выделенные программные области в тексте процедуры (рис. 14.32).
Рис. 14.32. Выделение произвольных областей в модуле
Затем можно развернуть только нужную область модуля и работать с ней. Текст процедуры станет более компактным и читаемым.
В нашем примере мы разбили одну процедуру модуля на три логические части. Но чаще наоборот: когда модуль содержит много различных процедур, сходные по назначению процедуры можно объединить в группы. Например, в модуле формы можно выделить
такие области, как ПрограммныйИнтерфейс , ОбработчикиСобытий ,
СлужебныеПроцедурыИФункции . Название этих областей задается самим разработчиком и говорит само за себя.
Занятие 14 46 5
Области могут быть вложены друг в друга или в другие группируемые конструкции языка. При расстановке областей в модуле нужно следить за тем, чтобы области не пересекались между собой и с другими группируемыми конструкциями. Потому что группировка по таким областям работать не будет.
В режиме «1С:Предприятие»
Запустим «1С:Предприятие» в режиме отладки и проверим работу нового обработчика события ОбработкаПроведения , перепроведя все документы Оказание услуги .
В результате все работает точно так же, с точки зрения пользователя, но проведение документов организовано методически правильно и более эффективно с точки зрения доступа к данным.
Теория: устройство кеша
В разделе «Теория: особенности использования ссылочных данных» на стр. 413 мы упомянули о том, что в платформе есть некий кеш, который хранит в себе данные объектов, читаемых из базы данных. Теперь расскажем о работе этого механизма подробнее.
Система «1С:Предприятие» использует механизм кеширования данных объектов, считанных из базы данных при использовании объектной техники.
Таким образом, для получения реквизитов какого-либо объекта через ссылку выполняется обращение к кешу объектов, расположенному в оперативной памяти.
Кеш объектов состоит из двух частей: транзакционного кеша и обычного кеша. В зависимости от того, происходит ли обращение в рамках транзакции или нет, в действие вступает тот или иной кеш
Все данные, находящиеся в кеше, предназначены только для чтения ( ReadOnly ). Таким образом, чтение любых данных, получаемых через ссылку, выполняется только через кеш объектов, а запись – механизмами самих программных объектов.
466 1С:Предприятие 8.3. Практическое пособие разработчика
Рис. 14.33. Кеш объектов
Если при обращении к обычному кешу требуемых данных в нем нет, то выполняется чтение данных объекта из базы данных и сохранение их в кеше. Уникальным идентификатором для кеша в данном случае будет являться ссылка на объект базы данных. Поэтому данные каждого считанного объекта могут существовать в кеше в одном из двух видов: либо все данные объекта, либо представление объекта.
Таким образом, если мы обратимся к кешу для получения представления объекта и в кеше есть информация для нашей ссылки, данные будут взяты из кеша (если в кеше весь объект, нужное представление будет получено из данных объекта).
Если в кеше нет информации для нашей ссылки, из базы данных в кеш будут считаны только поля, необходимые для формирования представления объекта.
Если мы обратимся к кешу для получения реквизита объекта и в кеше есть информация для нашей ссылки, дальнейшие действия будут зависеть от того, что находится в кеше.
Если в кеше весь объект, значение реквизита будет получено из кеша. Если в кеше представление объекта, оно будет удалено из кеша,
Занятие 14 46 7
и в кеш будут считаны все данные объекта. Если же при получении реквизита объекта в кеше нет информации для нашей ссылки, из базы данных будут считаны все поля объекта.
Считанные данные будут находиться в кеше до тех пор, пока не наступит одно из следующих событий:
считанные данные будут вытеснены из кеша другими считанными данными других объектов (переполнение кеша);
при очередном обращении к кешу окажется, что считанные данные были изменены в базе данных;
закончится интервал времени в 20 минут.
Все считанные данные помещаются в последовательную очередь, и, поскольку объем кеша ограничен, наиболее старые данные будут вытесняться из кеша последними считанными.
При повторном обращении к кешу за данными уже считанного объекта будет анализироваться интервал времени, прошедший с момента появления данных в кеше.
Если обращение происходит в пределах 20 секунд после поступления данных в кеш, данные считаются верными (валидными). Если интервал превысил 20 секунд, будет выполняться проверка на соответствие версии данных, хранящихся в кеше, версии данных, находящихся в базе данных.
Если окажется, что версии данных не совпадают (т. е. произошло изменение данных в базе данных), данные, находящиеся в кеше, будут удалены из него, и будет выполнено повторное считывание данных из базы данных. Начиная с этого момента, идет отсчет следующего 20-секундного интервала валидности этих данных.
Кроме всех вышеперечисленных событий считанные данные будут удалены из кеша по истечении 20 минут после их последнего считывания из базы данных.
Таким образом, при последовательном выполнении двух операторов (листинг 14.43), где Номенклатура – это ссылка на объект справочника, на выполнение второго оператора будет тратиться гораздо меньше времени, поскольку в первом случае будет выполняться обращение к базе данных, а во втором – чтение из оперативной памяти (кеша объектов).
468 1С:Предприятие 8.3. Практическое пособие разработчика
Листинг 14.43. Последовательность операторов
А = Номенклатура.Наименование; В = Номенклатура.ВидНоменклатуры;
Если обращение к данным происходит в рамках транзакции, то оно переадресуется транзакционному кешу. В рамках транзакции в «1С:Предприятии» выполняются все операции, приводящие к изменению данных в базе данных. Например, в рамках транзакции выполняется обработка проведения документа.
Транзакция – это неделимая последовательность манипулирования данными, переводящая базу данных из одного целостного состояния в другое. Если по каким-то причинам одно из действий транзакции невыполнимо, база данных возвращается в то состояние, которое было до начала транзакции (происходит откат транзакции – Rollback ).
Транзакционный кеш по сути представляет собой ту же последовательную очередь, что и обычный кеш. Разница заключается в том, что все данные, находящиеся в транзакционном кеше, являются валидными (гарантированно актуальными).
При считывании данных в транзакционный кеш устанавливается блокировка на данные в базе данных, поэтому они гарантированно не могут быть изменены до окончания транзакции.
Транзакционный кеш хранит считанные данные до тех пор, пока они не будут вытеснены более поздними или пока не закончится транзакция. По окончании транзакции кеш очищается, однако действия, выполняемые при этом, зависят от состояния завершения транзакции.
Если транзакция завершена успешно ( Commit ), данные всех объектов, содержащиеся в транзакционном кеше, переносятся в обычный кеш, а транзакционный кеш очищается (рис. 14.34).
Если был выполнен отказ от изменений ( Rollback ), то просто очищается транзакционный кеш (рис. 14.35).
Занятие 14 46 9
Рис. 14.34. Транзакция завершена успешно
Рис. 14.35. Очистка транзакционного кеша при отказе от изменений
470 1С:Предприятие 8.3. Практическое пособие разработчика
; ; Как система «1С:Предприятие» выполняет обращение к ссылочным данным?
; ; Как используется кеш объектов?
; ; Почему для доступа к массивам данных информационной базы предпочтительнее использовать запросы?
; ; Что такое момент времени?
; ; Чем отличается оперативное проведение документов от неоперативного?
; ; Что такое оперативная отметка времени?
; ; Как запросом получить остатки регистра накопления?
; ; На что следует обращать внимание при указании параметров виртуальных таблиц запросов?
; ; Почему при неоперативном проведении документов не нужно контролировать остатки?
; ; Что такое временные таблицы, и зачем их использовать? ; ; Что такое менеджер временных таблиц?
; ; Как и зачем можно использовать временные таблицы в параметрах виртуальных таблиц?
Как получить объект по ссылке?
Приветствую, коллеги! В данной статье будет рассмотрена работа с объектами и ссылками в 1С 8.3, в том числе я расскажу о том, как получать объект по ссылке и наоборот – ссылку из объекта.
Ни для кого не секрет, что в системе 1С очень многое держится на привязке различных типов данных, так как главной задачей языка 1С является обработка данных, которые были получены при помощи запроса.
Чаще всего в 1С данные представляются в виде объектов, хотя бывают случаи, когда данные выступают в роли таблицы. Например, рассмотрим объект «Справочник.ИмяСправочника»: он регулирует работу с определённым справочником, но и у самого объекта есть в наличии свойства (в данном случае – это поля с данными), а также присутствуют методы.
Объект в системе 1С создаётся при помощи специального оператора «Новый», после чего используется соответствующий конструктор для создания объектов. Если у типа объекта может существовать несколько конструкторов, то конструктор для создания объекта будет избран при помощи параметров, как показано в строке программного кода ниже:

Рис. 1 Выбор конструктора объектов для создания объектов
2. Менеджеры получения объектов системы 1С
Если необходимо создать объект 1С, который будет иметь связь с базой данных, то используются особые менеджеры, а не оператор «Новый».
Для всех видов метаданных есть соответствующий менеджер объектов 1С, который осуществляет получение значения из базы с данными, опираясь на признак, либо создание новой базы. Пример кода с созданием объекта через менеджер указан ниже:

Рис. 2 Создание объекта менеджером в 1С
3. Ссылки и объекты в 1С 8.3
Работа с объектами системы 1С:Предприятие может производится при помощи ссылки на данные, либо при помощи самого объекта.
Ссылки в языке 1С – это особые данные, которые можно только считывать. А объект в языке 1С – это данные, которые можно и считывать, и менять, и записывать.
Работа с ссылками выполняется гораздо быстрее, нежели с объектами.
Чтобы получить ссылку на объект, в 1С можно воспользоваться функцией, которая имеет следующий вид:

Рис. 3 Функция, чтобы получить ссылку на объект в 1С
Чтобы получить объект по ссылке, нужно воспользоваться функцией следующего вида:

Рис. 4 Функция, чтобы получить объект по ссылке
Также его можно создать с нуля при помощи следующей функции:

Рис. 5 Вариант функции получения объекта по ссылке
4. Как получить объект по ссылке?
Пускай некоторая переменная «СсылкаНаОбъект» принадлежит какому-то типу ссылки. Это может быть справочник, документ, план по счетам и так далее. Опираясь на это, мы используем специальную функция для того, чтобы получить объект по ссылке в 1С. Выглядит она следующим образом:

Рис. 6 Использование переменной СсылкаНаОбъект
5. Получение ссылки по объекту в 1С 8.3
Рассмотрим обратную процедуру, а именно: получение ссылки из объекта. Пусть есть некоторая переменная «Объект», которая является каким-то из объектных типов, тогда функция для получения ссылки из объекта будет выглядеть так:

Рис. 7 Переменная СсылкаНаОбъект для получения ссылки по объекту
Следует отметить, что реквизит «Ссылка» в 1С может быть заполнен только во время записи самого объекта. В случае, если объект не был прописан, то и соответствующей ссылки существовать не будет.