Для формирования и выполнения запросов к таблицам базы данных в платформе 1С используется специальный объект языка программирования Запрос. Создается этот объект вызовом конструкции Новый Запрос. Запрос удобно использовать, когда требуется получить сложную выборку данных, сгруппированную и отсортированную необходимым образом. Классический пример применения запроса - получение сводки по состоянию регистра накопления на определенный момент времени. Так же, механизм запросов позволяет легко получать информацию в различных временных разрезах.
Текст запроса – это инструкция, в соответствии с которой должен быть выполнен запрос. В тексте запроса описывается:
таблицы информационной базы, используемые в качестве источников данных запроса;
поля таблиц, которые требуется обрабатывать в запросе;
правила группировки;
сортировки результатов;
и т. д.
Инструкция составляется на специальном языке – языке запросов и состоит из отдельных частей – секций, предложений, ключевых слов, функций, арифметических и логических операторов, комментариев, констант и параметров.
Язык запросов платформы 1С очень похож на синтаксис других SQL-языков, но имеются отличия. Основными преимуществами встроенного языка запросов являются: разыменование полей, наличие виртуальных таблиц, удобная работа с итогами, нетипизированные поля в запросах.
Рекомендации по написанию запросов к базе данных на языке запросов платформы 1С:
1) Текст запроса может содержать предопределенные данные конфигурации, такие как:
значения перечислений;
предопределенные данные:
справочников;
планов видов характеристик;
планов счетов;
планов видов расчетов;
пустые ссылки;
значения точек маршрута бизнес-процессов.
Также текст запроса может содержать значения системных перечислений, которые могут быть присвоены полям в таблицах базы данных: ВидДвиженияНакопления, ВидСчета и ВидДвиженияБухгалтерии. Обращение в запросах к предопределенным данным конфигурации и значениям системных перечислений осуществляется с помощью литерала функционального типа ЗНАЧЕНИЕ. Данный литерал позволяет повысить удобочитаемость запроса и уменьшить количество параметров запроса.
Пример использования литерала ЗНАЧЕНИЕ:
ГДЕ Город = ЗНАЧЕНИЕ(Справочник.Города.Москва)
ГДЕ Город = ЗНАЧЕНИЕ(Справочник.Города.ПустаяСсылка)
ГДЕ ТипТовара = ЗНАЧЕНИЕ(Перечисление.ВидыТоваров.Услуга)
ГДЕ ВидДвижения = ЗНАЧЕНИЕ(ВидДвиженияНакопления.Приход)
ГДЕ ТочкаМаршрута = ЗНАЧЕНИЕ(БизнесПроцесс.БизнесПроцесс1.ТочкаМаршрута.Действие1
2) Использование инструкции АВТОУПОРЯДОЧИВАНИЕ в запросе может сильно время выполнения запроса, поэтому, если сортировка не требуется, то лучше вообще ее не использовать. Во большинстве случаях лучше всего применять сортировку с помощью инструкции УПОРЯДОЧИТЬ ПО.
Автоупорядочивание работает по следующим принципам:
Если в запросе было указано предложение УПОРЯДОЧИТЬ ПО, то каждая ссылка на таблицу, находящаяся в этом предложении, будет заменена полями, по которым по умолчанию сортируется таблица (для справочников это код или наименование, для документов – дата документа). Если поле для упорядочивания ссылается на иерархический справочник, то будет применена иерархическая сортировка по этому справочнику.
Если в запросе отсутствует предложение УПОРЯДОЧИТЬ ПО, но есть предложение ИТОГИ, тогда результат запроса будет упорядочен по полям, присутствующим в предложении ИТОГИ после ключевого слова ПО, в той же последовательности и, в случае если итоги рассчитывались по полям – ссылкам, то по полям сортировки по умолчанию таблиц, на которые были ссылки.
Если в запросе отсутствуют предложения УПОРЯДОЧИТЬ ПО и ИТОГИ, но есть предложение СГРУППИРОВАТЬ ПО, тогда результат запроса будет упорядочен по полям, присутствующим в предложении, в той же последовательности и, в случае если группировка велась по полям – ссылкам, то по полям сортировки по умолчанию таблиц, на которые были ссылки.
В случае же, если в запросе отсутствуют предложения и УПОРЯДОЧИТЬ ПО, ИТОГИ и СГРУППИРОВАТЬ ПО, результат будет упорядочен по полям сортировки по умолчанию для таблиц, из которых выбираются данные, в порядке их появления в запросе.
В случае, если запрос содержит предложение ИТОГИ, каждый уровень итогов упорядочивается отдельно.
3) Что бы избежать повторного запроса к базе данных при выводе результата запроса пользователю (например, построение запроса или отображение результата запроса с помощью табличного документа) полезно использовать инструкцию ПРЕДСТАВЛЕНИЕССЫЛКИ, которая позволяет получать представление ссылочного значения. Пример:
Так же возможно использование инструкции ПРЕДСТАВЛЕНИЕ - предназначена для получения строкового представления значения произвольного типа. Отличие этих инструкций в том, что в первом случае, если инструкции передать ссылку, результатом будет строка, В остальных случаях результатом будет значение переданного параметра. Во втором случае, результатом инструкции всегда будет строка!
4) Если в запросе имеется поле с составным типом, то для таких полей возникает необходимость привести значения поля к какому-либо определенному типу с помощью инструкции ВЫРАЗИТЬ, что позволит убрать лишние таблицы из левого соединения с полем составного типа данных и ускорить выполнение запроса. Пример:
Имеется регистра накопления ОстаткиТоваров, у которого поле Регистратор имеет составной тип. В запросе выбираются Дата и Номер документов ПоступлениеТоваров, при этом при обращении к реквизитам документа через поле Регистратор не происходит множество левых соединений таблицы регистра накопления с таблицами документов-регистраторов.
Если приведение типа считается не осуществимым, то результатом приведения типа будет значение NULL.
5) Не стоит забывать про инструкцию РАЗРЕШЕННЫЕ, которая означает, что запрос выберет только те записи, на которые у текущего пользователя есть права. Если данное слово не указать, то в случае, когда запрос выберет записи, на которые у пользователя нет прав, запрос отработает с ошибкой.
6) В случае, если в запросе используется объединение, и в некоторых частях объединения присутствуют вложенные таблицы (документ с табличной частью), а в некоторых нет, возникает необходимость дополнения списка выборки полями – пустыми вложенными таблицами. Делается это при помощи ключевого слова ПУСТАЯТАБЛИЦА, после которого в скобках указываются псевдонимы полей, из которых будет состоять вложенная таблица. Пример:
7) Что бы в результат запроса не попали повторяющиеся строки, следует использовать инструкцию РАЗЛИЧНЫЕ, потому что так нагляднее и понятнее, а инструкция СГРУППИРОВАТЬ ПО применяется для группировки с помощью агрегатных функций. Ксати, при использовании агрегатных функций предложение СГРУППИРОВАТЬ ПО может быть и не указано совсем, при этом все результаты запроса будут сгруппированы в одну единственную строку. Пример:
8) Инструкция СГРУППИРОВАТЬ ПО позволяет обращаться к полям верхнего уровня, без группировки результатов по этим полям, если агрегатные функции применены к полям вложенной таблицы. Хотя в справке 1С написано, при группировке результатов запроса в списке полей выборки обязательно должны быть указаны агрегатные функции, а помимо агрегатных функций в списке полей выборки допускается указывать только поля, по которым осуществляется группировка. Пример:
9) Инструкция ЕСТЬNULL предназначена для замены значения NULL на другое значение, но не забываем, что второй параметр будет преобразован к типу первого в случае, если тип первого параметра является строкой или числом.
10) При обращении к главной таблице можно в условии обратиться к данным подчиненной таблицы. Такая возможность называется разыменование полей подчиненной таблицы.
Пример (поиск документов, содержащих в табличной части определенный товар):
Преимущество этого запроса перед запросом к подчиненной таблице Приходная.Товары в том, что если есть дубли в документах, результат запроса вернет только уникальные документы без использования ключевого слова РАЗЛИЧНЫЕ.
11) Интересный вариант оператора В - это проверка вхождения упорядоченного набора в множество таких наборов (Поле1, Поле2, ... , ПолеN) В (Поле1, Поле2, ... , ПолеN).
Пример:
12) При любой возможности используйте виртуальные таблицы запросов. При создании запроса система предоставляет в качестве источников данных некоторое количество виртуальных таблиц - это таблицы, которые так же являются результатом запроса, который система формирует в момент выполнения соответствующего участка кода.
Разработчик может самостоятельно получить те же самые данные, которые система предоставляет ему в качестве виртуальных таблиц, однако алгоритм получения этих данных не будет оптимизирован, так как:
Все виртуальные таблицы параметризованы, т. е. разработчику предоставляется возможность задать некоторые параметры, которые система будет использовать при формировании запроса создания виртуальной таблицы. В зависимости от того, какие параметры виртуальной таблицы указаны разработчиком, система может формировать РАЗЛИЧНЫЕ запросы для получения одной и той же виртуальной таблицы, причем они будут оптимизированы с точки зрения переданных параметров.
Не всегда разработчик имеет возможность получить доступ к тем данным, к которым имеет доступ система.
13) В клиент-серверном варианте работы функция ПОДСТРОКА() реализуется при помощи функции SUBSTRING() соответствующего оператора SQL, передаваемого серверу баз данных SQL Server, который вычисляет тип результата функции SUBSTRING() по сложным правилам в зависимости от типа и значений ее параметров, а так же в зависимости от контекста, в котором она используется. В большинстве случаев эти правила не оказывают влияния на выполнение запроса, но бывают случаи, когда для выполнения запроса существенна максимальная длина строки результата, вычисленная SQL Server. Важно иметь в виду, что в некоторых контекстах использования функции ПОДСТРОКА() максимальная длина ее результата может оказаться равной максимальной длине строки ограниченной длины, которая в SQL Server равна 4000 символам. Это может привести к неожиданному аварийному завершению выполнения запроса:
Microsoft OLE DB Provider for SQL Server: Warning: The query processor could not produce a query plan from the optimizer because the total length of all the columns in the GROUP BY or ORDER BY clause exceeds 8000 bytes.
HRESULT=80040E14, SQLSTATE=42000, native=8618
Чтобы избежать такой ошибки, не рекомендуют использовать функцию ПОДСТРОКА() с целью приведения строк неограниченной длины к строкам ограниченной длины. Вместо нее лучше использовать операцию приведения типа ВЫРАЗИТЬ().
14) С осторожностью используйте ИЛИ в конструкции ГДЕ, так как использование условия с ИЛИ может значительно "утяжелить" запрос. Решить проблему можно конструкцией ОБЪЕДИНИТЬ ВСЕ. Пример:
15) Условие НЕ В в конструкции ГДЕ увеличивает время исполнения запроса, так как это своего рода НЕ (ИЛИ1 ИЛИ2 ... ИЛИn), поэтому для больших таблиц старайтесь использовать ЛЕВОЕ СОЕДИНЕНИЕ с условием ЕСТЬ NULL. Пример:
16) При использовании Временных таблиц нужно индексировать поля условий и соединений в этих таблицах, НО, при использовании индексов запрос может выполняться еще медленнее. Поэтому необходимо анализировать каждый запрос с применением индекса и без, замерять скорость выполнения запроса и принимать окончательное решение.
Если вы помещаете во временную таблицу данные, которые изначально индексированы по некоторым полям, то во временной таблице индекса по этим полям уже не будет.
17) Если вы не используете Менеджер временных таблиц, то явно удалять временную таблицу не требуется, она будет удалена после завершения выполнения пакетного запроса, иначе следует удалить временную таблицу одним из способов: командой УНИЧТОЖИТЬ в запросе, вызвать метод МенеджерВременныхТаблиц.Закрыть().
Разберем, как изменялся (скорее дополнялся) синтаксис текстов запросов на простом примере: Проводится документ Расходная содержащая в табличной части Товары список продаваемых товаров и количество. При проведении такого документа необходимо обеспечить контроль отрицательных остатков хранящихся в регистре накопления остатков ОстаткиТоваров.
Структура конфигурации представлена на рисунке справа:
Сформируем запрос к табличной части документа и виртуальной таблице Остатки регистра накопления. Учтем возможные дубли строк в документе, для этого произведем группирование записей.
Естественно приведенный запрос абсолютно не оптимален. С помощью вложенных запросов оптимизируем его: Произведем группирование табличной части документа до соединения с таблицей остатков, в параметры виртуальной таблицы передадим список товаров как значение условия для расчета остатков. В итоге наш запрос примет следующий вид:
Если бы в запросе необходимо было бы получить данные из остатков разных регистров то значение фильтра, а следовательно и наш второй вложенный запрос, повторялся бы во всех параметрах виртуальных таблиц, естественно что система при каждом вложенном запросе заново обращается к базе данных для получения данных.
Временные таблицы
Не помню уже с какого релиза в запросах стало можно использовать временные таблицы. Для этого используется объект «Менеджер временных таблиц». Фактически менеджер временных таблиц описывает пространство имен временных таблиц и отвечает за их создание и уничтожение в базе данных.
Сами временные таблицы действительно физически создаются в базе, соответственно следует относиться к ним осторожно, так как дисковая подсистема на сегодняшний момент самая медленная часть техники, а скорость создания и уничтожения таблиц напрямую от нее зависит.
Перепишем запрос для использования временных таблиц. Во временные таблицы поместим сгруппированную табличную часть документа и список товаров для фильтра виртуальных таблиц:
При использовании временных таблиц в тексте запроса применяют инструкцию Поместить для создания новой временной таблицы, в этом случае в результат запроса система передает не содержимое этой таблицы (см прим 1 и прим 2 в тексте выше), а количество записей помещенных во временную таблицу, по желанию можно не принимать это значение.
Также допускается использование инструкции Уничтожить в этом случае временная таблица уничтожается, в противном случае временные таблицы уничтожаются вместе с объектом менеджер временных таблиц.
В основном нашем запросе я использовал названия временных таблиц как указание на источник получения данных (им обязательно надо назначать синоним, что мы и видим в тексте). Использовать временные таблицы как источник можно не единожды, что при умелом их применении позволит и сократить текст запроса (улучшиться читабельность сложных запросов) и увеличить скорость (при использовании данных временной таблицы в нескольких местах запроса).
Пакетные запросы
Пакетные запросы логично дополняют функционал временных таблиц и дают больше возможностей при работе с запросами.
В пакетном запросе фактически можно описать несколько запросов, как связанных между собой использованием временных таблиц, так и не связанных (можно, но не понятно зачем?). В итоге можно выполнить последовательно все запросы и принять в результате либо массив с результатами исполнения каждого запроса, либо результат последнего. Для получения массива с результатами запроса применяют метод ВыполнитьПакет() объекта запрос, а для получения результата последнего запроса ВыполнитьЗапрос().
В тексте запроса, запросы пакета разделяются символом «;» (точка с запятой). Область имен виртуальных таблиц у одного пакетного запроса одна. Использование менеджера временных таблиц не требуется, но возможно если вы хотите передать временные таблицы из одного пакетного запроса в другой.
Перепишем процедуру для использования пакетных запросов:
Фактически я убрал определение объекта запрос и использование менеджера временных таблиц, объединил тексты запросов (обратите внимание на разделитель «;» между текстами). В результате текст запроса стал читабельнее (а при использовании конструктора запросов намного увеличивается удобство чтения запроса).
После выполнения запроса в переменную МассивРезультатов у нас попадет 3 элемента. Первые два будут содержать число характеризующее количество записей помещенных во временные таблицы ДокТЧ и СписокТоваров, а третий будет содержать выборку с полями Номенклатура, Док_Количество и Рег_Количество.
В переменную РезультатЗапроса попадет только выборка.
Ну вот и все что касается пакетных запросов. Очень удобный механизм и с точки зрения написания запросов и с точки зрения чтения сложных запросов.
Данный код позволяет открыть список документов с установленным отбором, также можно открыть список элементов справочника с нужным отбором
Для того, чтобы открыть форму списка с заранее установленным отбором используйте следующие способы:
Первый способ заключается в том, что при открытии формы можно задать параметр формы Отбор, и открыть форму списка с этим параметром.
Параметр Отбор представляет собой структуру. Имена элементов соответствуют именам полей, по которым производится отбор, а значения содержат значения отбора. Это параметр расширения управляемой формы динамического списка. То есть он существует у форм, основным реквизитом которых является реквизит типа ДинамическийСписок, например у форм списка и форм выбора.
Например, в следующем примере открывается список приходных накладных с отбором по полю Номер, равному 333.
Второй способ
Можно открыть форму списка без параметров:
И затем, в обработчике события формы списка приходных накладных ПриСозданииНаСервере написать код, который создает отбор в динамическом списке, являющемся основным реквизитом формы:
Преимущества данного метода в том, что ВидСравнения у отбора можно задавать не только Равно, как в первом случае, а и Больше, Меньше и т.п.
Но у такого способа есть и очень существенный недостаток: с этим отбором форма будет открываться всегда. Откуда бы ее ни вызвали. Поэтому такую форму не следует назначать основной. А если все же она основная - то перед установкой отбора необходимо предусмотреть какой-то анализ того, откуда открывается эта форма. Например, анализируя параметры формы.
Третий способ
И наконец, условие отбора можно поместить в произвольный запрос, выбирающий данные для динамического списка.
Например, нам нужно открыть список приходных накладных, в которых присутствует номенклатура, выделенная в списке номенклатуры.
Для этого в форме списка номенклатуры создадим команду и соответствующую ей кнопку Приходные накладные.
Обработчик выполнения этой команды заполним следующим образом:
В этом обработчике мы открываем форму списка приходных накладных, передавая в параметр формы ФильтрПоТовару ссылку на текущий элемент в списке номенклатуры.
Затем создадим форму списка документов ПриходнаяНакладная и создадим параметр формы ФильтрПоТовару, который мы будем использовать для открытия формы с нужным отбором.
Теперь откроем палитру свойств основного реквизита формы Список. Установим флаг ПроизвольныйЗапрос и в строке Настройка списка нажмём Открыть.
В поле Запрос введём следующий текст запроса:
В запросе мы используем параметр Товар, в который и будет передаваться ссылка на текущую строку в списке номенклатуры, содержащуюся в параметре формы списка приходных накладных ФильтрПоТовару.
Для этого в обработчике события формы списка ПриСозданииНаСервере напишем код для установки значения параметра запроса Товар:
Здесь Список.Параметры - это список параметров запроса динамического списка для реквизита Список. Значение параметра Товар устанавливается равным значению параметра формы ФильтрПоТовару.
В результате по нажатию кнопки Приходные накладные в форме списка номенклатуры мы будем получать список только тех приходных накладных, в которых присутствует номенклатура, выделенная в данный момент в списке номенклатуры.
Не могу запустить обработку из раздела "Дополнительные обработки". Выдает "Установлен безопасный режим. Выполнение операции запрещено!"
В 1С Предприятии 8.2-8.3 появился специальный режим исполнения кода - безопасный режим. Суть безопасного режима в том что недоступно выполнение некоторых методов и конструкций встроенного языка. Если вы доверяете источнику из которого получена обработка - безопасный режим можно отключить.
Хранилище конфигурации предназначено для коллективной разработки конфигурации. В хранилище сохраняется история разрабатываемой конфигурации, а также информация о том, когда и кто вносил изменения в конфигурацию. Разработка конфигурации с использованием хранилища может вестись неограниченным числом пользователей.
Принцип работы
Хранилище конфигурации представляет собой базу данных, в которой сохраняются все изменения конфигурации, сделанные в процессе её разработки. После подключения информационной базы к хранилищу из него в информационную базу загружается последняя версия конфигурации, и все объекты метаданных конфигурации становятся недоступными для редактирования.
Гранулой редактирования - объектами разработки - являются все основные объекты метаданных (такие как справочники, документы, регистры сведений), а также формы и макеты. Объекты разработки могут редактироваться независимо друг от друга разными пользователями. Реквизиты, табличные часть и т.д. не являются отдельными объектами с логической точки зрения, поэтому они не были включены в состав объектов разработки. Данные объекты метаданных редактируются в составе своих родительских объектов, являющихся объектами разработки.
Для получения возможности редактирования объекта необходимо произвести его захват в хранилище. При выполнении захвата из хранилища будет получена (в случае наличия) новая версия объекта разработки. После внесения изменений объект необходимо поместить в хранилище, после этого обновленная версия объекта становится доступной для других пользователей, участвующих в процессе разработки конфигурации. Если же изменения не должны быть помещены в хранилище, то предусмотрена процедура отмены захвата, при которой из хранилища получается старая версия объекта разработки. Таким образом, можно выделить четыре простейшие операции работы с хранилищем: захват объекта в хранилище;
помещение объекта в хранилище;
получение объекта из хранилища;
отмена захвата в хранилище.
Для параллельной разработки конфигурации в хранилище используется стратегия пессимистической блокировки: в то время, пока объект разработки редактируется одним пользователем, другие пользователи не имеют возможности его редактировать.
Стоит обратить внимание на тот факт, что при подключении информационной базы к хранилищу конфигурации происходит полная замена текущей редактируемой конфигурации конфигурацией хранилища . Это необходимо для обеспечения полного соответствия идентификаторов объектов метаданных. Если все же имеется информационная база, часть объектов метаданных конфигурации которой необходимо перенести в конфигурацию хранилища, то необходимо: выгрузить конфигурацию из информационной базы в файл,
подключить информационную базу к хранилищу конфигурации,
выполнить захват объектов, которые необходимо заместить,
произвести объединение с требуемой конфигурацией.
Важно понимать, что предметом разработки является конфигурация, а не отдельные объекты. Хранилище ведет историю развития конфигурации. При помещении объектов разработки в хранилище создается новая версия конфигурации, для которой записываются: дата создания версии, пользователь, создавший версию, а также списки объектов разработки, которые были добавлены, изменены, удалены в процессе получения данной версии конфигурации. История объектов разработки не ведется. Несмотря на то, что имеется возможность просмотра истории объекта разработки, отдельно загрузить из хранилища объект разработки какой-либо версии конфигурации невозможно, возможна лишь загрузка из хранилища версии конфигурации целиком. Однако все же имеется возможность получения объекта определенной версии конфигурации: необходимо захватить объект и выполнить объединение с версией конфигурации, в которой данный объект имеет требуемое состояние.
При создании новой версии конфигурации хранилища имеется возможность записать комментарий к этой версии. Рекомендуется комментировать версии конфигурации, для того чтобы впоследствии можно было понять, что именно было изменено в данной версии конфигурации. Для наиболее значимых версий (например: выпуск релиза) рекомендуется также устанавливать метку - строку, кратко описывающую версию конфигурации хранилища.
В процессе разработки конфигурации с использованием хранилища рекомендуется периодически получать актуальное состояние объектов разработки. Это позволяет избежать возможных трудностей при помещении объектов в хранилище (например при удалении объектов метаданных из конфигурации).
Средства работы с хранилищем конфигурации позволяют просматривать историю версий конфигурации хранилища, сохранять конфигурацию определенной версии в файл, сравнивать с другими версиями конфигурации данного хранилища или же сравнивать с другой конфигурацией из файла.
Если по каким-либо причинам хранилище конфигурации недоступно, то имеется возможность продолжать работу с объектами разработки, захваченными ранее в хранилище. Таким образом, можно вести разработку, не имея постоянной непосредственной связи с хранилищем конфигурации.
Режимы использования
Для работы с хранилищем конфигурации предусмотрено несколько способов: с подключением информационной базы к хранилищу;
без подключения информационной базы к хранилищу.
Данные режимы отличаются друг от друга как набором функциональности, предоставляемой платформой 1С:Предприятия, так и своим предназначением.
Работа с подключением информационной базы к хранилищу
Этот режим является основным режимом работы с хранилищем. Он используется для групповой разработки конфигурации несколькими пользователями.
Работа в данном режиме начинается с процедуры подключения информационной базы к хранилищу. К одному хранилищу может быть одновременно подключена одна информационная база от имени одного пользователя. Если пользователь, у которого уже имеется информационная база, подключенная к данному хранилищу, произведет попытку подключения другой информационной базы, то ему будет выдано соответствующее предупреждение. Если же подключение все же будет осуществлено, то прежняя информационная база уже не сможет работать с данным хранилищем конфигурации без предварительного отключения от него. Аутентификация в хранилище от имени пользователя, не подключавшего данную информационную базу к хранилищу, невозможна.
При подключении информационной базы к хранилищу в нем регистрируется строка соединения с информационной базой. Если при последующих соединениях с хранилищем данная строка будет изменена (по каким-либо причинам информационная база была перемещена на другой ресурс), то платформой будет выдано соответствующе предупреждение, и, в случае подтверждения соединения, строка соединения будет обновлена. Если соединение происходило копией информационной базы, то работа оригинала с данным хранилищем будет невозможна без предварительного отключения от него.
Работа без подключения информационной базы к хранилищу
Режим обеспечивает возможность просмотра и администрирования хранилища без подключения к нему, т.е. без замены редактируемой конфигурации конфигурацией хранилища. В данном режиме пользователь может получить конфигурацию определенной версии хранилища, посмотреть историю конфигурации или отдельных объектов разработки, произвести действия по редактированию прав пользователей или изменению их состава.
Работа в данном режиме начинается с открытия хранилища конфигурации, данная процедура заключается в аутентификации пользователя в хранилище, которая будет автоматически предложена при выполнении любого первого действия с хранилищем в данной сессии работы Конфигуратора. Для открытия другого хранилища в данной сессии Конфигуратора необходимо закрыть текущее хранилище конфигурации, выполнив соответствующий пункт меню.
Предполагается, что данный режим будет использоваться для подготовки дистрибутивов конфигураций на основе файлов выгрузки информационных баз. Данная процедура может выглядеть следующим образом:
Создать новую информационную базу.
Открыть хранилище конфигурации.
Из хранилища конфигурации загрузить конфигурацию нужной версии.
Произвести заполнение информационной базы необходимыми данными.
Произвести подготовку дистрибутива конфигурации.
В процессе модернизации конфигурации хранилища для выпуска новых дистрибутивов необходимо повторить процедуру, начиная с пункта 2, и, если новых данных вводить не требуется, сразу выполнить подготовку дистрибутива.
Контроль ссылочной целостности
Стандартные механизмы контроля ссылочной целостности конфигурации обеспечивают контроль на уровне объектов метаданных: нельзя, например, удалить из конфигурации справочник, если на него ссылается реквизит документа и т.д. На уровне интерфейсов, форм и макетов такой контроль не ведется.
Пример: удаление справочника Склады из демонстрационной конфигурации ":
происходит проверка имеющихся на этот объект ссылок в других объектах:
"Справочник.Склады" использован в: Документ.ПриходнаяНакладная.Реквизит.Склад.Тип
Документ.РасходнаяНакладная.Реквизит.Склад.Тип
РегистрНакопления.УчетНоменклатуры.Измерение.Склад.Тип
после удаления обнаруженных ссылок справочник Склады успешно удаляется из конфигурации, хотя ссылка не него по-прежнему имеется в интерфейсе Основной (кнопка Склады из подменю Справочники содержит действие "Склады: Открыть справочник") и формах документов ПриходнаяНакладная, РасходнаяНакладная (поля ввода, предназначенные для редактирования реквизитов Склад по-прежнему имеют тип СправочникСсылка.Склады).
При разработке конфигурации без использования хранилища этого вполне хватает. Однако для параллельной разработки конфигурации такой контроль ссылочной целостности недостаточен.
Хранилище конфигурации обеспечивает более строгий контроль ссылочной целостности конфигурации. Производится полный контроль ссылок между объектами метаданных как на уровне самих объектов, так и на уровне содержимого их форм и макетов, а также содержимого интерфейсов.
Следствием этого факта является необходимость получения из хранилища (помещения в хранилище) объектов, так или иначе связанных с объектом, над которым непосредственно производится действие. Однако хранилище конфигурации производит анализ ссылок объекта и требует получения (помещения) дополнительных объектов только в случае необходимости.
Анализ ссылок производится рекурсивно: сначала производится анализ объекта, с которым производится действие в хранилище; затем при обнаружении необходимости выполнения операции над дополнительными объектами аналогичный анализ производится для них, и так до тех пор, пока ссылки всех требуемых объектов не будут проанализированы.
Особенности конфигурирования
Разработка конфигурации в информационной базе, подключенной к хранилищу конфигурации, имеет некоторые особенности.
Как уже говорилось ранее, для получения возможности редактирования объекта необходимо произвести его захват в хранилище конфигурации. Если необходимо внести изменения в объект метаданных, не являющийся объектом разработки (реквизиты, табличные части), то необходимо произвести захват того объекта разработки, который содержит данные объекты метаданных.
Для добавления нового объекта метаданных или же для изменения порядка следования существующих объектов необходимо произвести захват родительского объекта разработки.
Удаление объектов конфигурации
Особое внимание стоит уделить процедуре удаления объектов метаданных из конфигурации. Для удаления объекта метаданных из конфигурации необходимо захватить в хранилище сам удаляемый объект, его родительский объект, а также все подчиненные объекты удаляемого. После чего появится возможность удалить объект из конфигурации.
Однако при помещении в хранилище, если на удаленный объект имеются ссылки в других объектах, средства работы с хранилищем потребуют помещение этих объектов в хранилище с очищенными ссылками на удаленный объект.
Рекомендуется перед удалением объекта из конфигурации производить поиск ссылок на данный объект. Произвести захват в хранилище всех обнаруженных объектов и вычистить из них все ссылки на удаляемый объект. После этого необходимо удалить все ссылки на удаляемый объект из форм, интерфейсов и макетов. После чего удалить объект из конфигурации и произвести попытку помещения изменений в хранилище. Если помещение в хранилище завершится неудачей из-за обнаружения ссылок на удаленный объект, то необходимо захватить указанные объекты и произвести повторную попытку помещения изменений в хранилище.
Пример: удаление справочника Склады из демонстрационной конфигурации:
Производим поиск ссылок на удаляемый объект:
"Справочник.Склады" использован в: Документ.ПриходнаяНакладная.Реквизит.Склад.Тип
Документ.РасходнаяНакладная.Реквизит.Склад.Тип
РегистрНакопления.УчетНоменклатуры.Измерение.Склад.Тип
Захватываем данные объекты и удаляем из них реквизиты, ссылающиеся на справочник Склады.
Захватываем интерфейс "Основной" и удаляем из него кнопку Склады из подменю Справочники с действием "Склады: Открыть справочник".
Захватываем корневой объект конфигурации и справочник Склады.
Удаляем справочник Склады из конфигурации.
Производим попытку помещения корневого объекта конфигурации в хранилище
Параметры командной строки для работы с хранилищем конфигурации
Параметры командной строки режима работы с хранилищем конфигурации
/ConfigurationRepositoryF <каталог хранилища> — указание имени каталога хранилища.
/ConfigurationRepositoryN <имя> — указание имени пользователя хранилища.
/ConfigurationRepositoryDumpCfg <имя cf файла> [-v <номер версии хранилища>] — сохранить конфигурацию из хранилища в файл (пакетный режим запуска).
-v <номер версии хранилища> v — номер версии, если номер версии не указан, или равен -1, будет сохранена последняя версия.
/ConfigurationRepositoryUpdateCfg [-v <номер версии хранилища>] [-revised] — обновить конфигурацию хранилища из хранилища (пакетный режим запуска).
-v<номер версии хранилища> — номер версии, если номер версии не указан, или равен -1, будет сохранена последняя версия, если конфигурация не подключена к хранилищу, то параметр игнорируется;
-revised — получать захваченные объекты, если потребуется. Если конфигурация не подключена к хранилищу, то параметр игнорируется;
-force — если при пакетном обновлении конфигурации из хранилища должны быть получены новые объекты конфигурации или удалиться существующие, указание этого параметра свидетельствует о подтверждении пользователем описанных выше операций. Если параметр не указан — действмия выполнены не будут.
/ConfigurationRepositoryUnbindCfg [-force] — отключение конфигурации от хранилища конфигурации (у пользователя должны быть административные права в данной информационной базе). Если пользователь аутентифицируется в хранилище (интерактивно или через параметры командной строки), то отключение конфигурации от хранилища также отражается в самом хранилище конфигурации (информация о подключении удаляется), если же пользователь не аутентифицировался в хранилище, то производится только локальное отключение конфигурации от хранилища.
В случае, если в конфигурации имеются захваченные объекты, которые были изменены относительно хранилища, то будет выдано соответствующее сообщение и отключения не выполнится.
–force — ключ для форсирования отключения от хранилища (пропуск диалога аутентификации, если не указаны параметры пользователя хранилища, игнорирование наличия захваченных и измененных объектов).
/ConfigurationRepositoryReport <имя файла> [-NBegin <номер версии>] [-NEnd <номер версии>] [-GroupByObject] [-GroupByComment] — построение отчета по истории хранилища. Если параметры группировки не указаны и режим совместимости указан "Не используется", то отчет формируется с группировкой по версиям. В режимах совместимости "Версия 8.1" и "Версия 8.2.13" отчет формируется с группировкой по объектам. Если конфигурация базы данных отличается от редактируемой по свойству совместимости, при обработке командной строки учитывается значение режима совместимости конфигурации базы данных.
<имя файла> — имя файла, в который выводится отчет;
NBegin — номер сохраненной версии, от которой начинается строиться отчет;
NEnd — номер сохраненной версии, по которую строится отчет;
GroupByObject — признак формирования отчета по версиям с группировкой по объектам;
GroupByComment — признак формирования отчета по версиям с группировкой по комментарию.
Примеры: для конфигурации, не присоединенной к текущему хранилищу:
для присоединенной к хранилищу конфигурации, информация для отчетов берется из текущего хранилища:
В статье приведены полезные приемы при работе с запросами 1С v.8.2, а также сведения, которые не так хорошо известны о языке запросов. Я не стремлюсь дать полное описание языка запросов, а хочу остановиться лишь на некоторых моментах, которые для кого-то могут быть полезны.
Итак, начнем. Запрос - это специальный объект в 1С 8.2, который используется для формирования и выполнения запросов к таблицам базы данных в системе. Для выполнения запроса необходимо составить текст запроса, в котором описывается какие таблицы будут использоваться в качестве источников данных запроса, какие нужно выбрать поля, какие применить сортировки и группировки и т.д. Подробнее о запросах можно прочитать в книге "1С 8.2 Руководстве разработчика". Язык запросов 1С 8.2 очень похож синтаксисом на другие SQL языки запросов баз данных, но есть и отличия. Из основных преимуществ встроенного языка запросов стоит отметить разыменование полей, наличие виртуальных таблиц, удобная работа с итогами и нетипизированные поля в запросах. Из недостатков – в качестве выходного поля нельзя использовать запрос, нельзя использовать хранимые процедуры, нельзя преобразовать строку в число.
Приведу сведения и рекомендации по языку запросов по пунктам:
1.Для повышения читабельности запроса и уменьшения количества параметров запроса можно в запросе применять обращение к предопределенным данным конфигурации с помощью литерала ЗНАЧЕНИЕ (ПРЕДСТАВЛЕНИЕЗНАЧЕНИЯ). В качестве представления значений могут использоваться значение перечислений, предопределенные данные справочников, планов видов расчета, планов видов характеристик, планов счетов, пустые ссылки, значения точек маршрута, значения системных перечислений (например, ВидДвиженияНакопления, ВидСчета).
Примеры: ГДЕ Город = ЗНАЧЕНИЕ(Справочник.Города.Москва) ГДЕ Город = ЗНАЧЕНИЕ(Справочник.Города.ПустаяСсылка) ГДЕ ТипТовара = ЗНАЧЕНИЕ(Перечисление.ВидыТоваров.Услуга) ГДЕ ВидДвижения = ЗНАЧЕНИЕ(ВидДвиженияНакопления.Приход) ГДЕ ТочкаМаршрута = ЗНАЧЕНИЕ(БизнесПроцесс.Согласование.ТочкаМаршрута.Согласие)
Выражение в скобках всегда начинается со слова в единственном числе (Справочник, Перечисление и т.д.), которое соответствует типу предопределенного значения.
2.Автоупорядочивание в запросе может сильно тормозить процесс. Если сортировка не нужна, лучше вообще ее не использовать. Во многих случаях эффективнее записать сортировку через ключевое слово УПОРЯДОЧИТЬ ПО.
3.Нужно следить, чтобы при использовании псевдонимов не появилось неоднозначное поле. Иначе система не поймет к какому объекту надо обращаться.
Пример запроса с неоднозначным полем: ВЫБРАТЬ Номенклатура.Ссылка, ОстаткиТоваровОстатки.КоличествоОстаток ИЗ Справочник.Номенклатура КАК Номенклатура ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ОстаткиТоваров.Остатки КАК ОстаткиТоваровОстатки ПО ОстаткиТоваровОстатки.Номенклатура = Номенклатура.Ссылка
Нужно исправить псевдоним таблицы, например, так: «Справочник.Номенклатура КАК Номенклатура1», а «Номенклатура.Ссылка» соответственно исправить на «Номенклатура1.Ссылка».
4.Иногда полезно получать представление ссылочных полей с помощью ключевого слова ПРЕДСТАВЛЕНИЕ наряду со ссылкой для того, чтобы не было повторного обращения к базе данных. Это бывает полезно при выводе результата запроса в таблицу.
Пример: ВЫБРАТЬ ПРЕДСТАВЛЕНИЕ(Документ.Контрагент) КАК Получатель, ПРЕДСТАВЛЕНИЕ(Документ.Основание) ИЗ Документ.РасходнаяНакладная КАК Документ
5.Использование в запросе ВЫРАЗИТЬ(Поле КАК Тип) позволяет убрать лишние таблицы из соединения с полем составного типа данных. Тем самым ускорить выполнение запроса.
Пример (регистратор - поле с составным типом для физической таблицы регистранакопления ОстаткиТоваров, в запросе выбираются Дата и Номер документов ПоступлениеТоваров, при этом при обращении к реквизитам документа Дата и Номер через Регистратор не происходит множественного соединения таблицы регистра с таблицами документов, являющихся регистраторами для регистра ОстаткиТоваров): ВЫБРАТЬ РАЗЛИЧНЫЕ [b] ВЫРАЗИТЬ(ОстаткиТоваров.Регистратор КАК Документ.ПоступлениеТоваров).Номер КАК НОМЕРПОСТУПЛЕНИЯ,[/b] [b]ВЫРАЗИТЬ(ОстаткиТоваров.Регистратор КАК Документ.ПоступлениеТоваров).Дата КАК ДАТАПОСТУПЛЕНИЯ[/b] [b]ИЗ РегистрНакопления.ОстаткиТоваров КАК ОстаткиТоваровГДЕ (ВЫРАЗИТЬ(ОстаткиТоваров.Регистратор КАК Документ.ПоступлениеТоваров) ЕСТЬ НЕ NULL)[/b]
6.Когда в конфигурации 1С есть пользователи, у которых права ограничены на определенные объекты конфигурации, в запросе к таким объектам необходимо использовать ключевое слово РАЗРЕШЕННЫЕ, чтобы запрос выполнился без ошибки (Выбрать Разрешенные ...)
7.При объединении таблиц, содержащих вложенные таблицы (например, Документ с табличной частью) бывает полезно ключевое слово ПУСТАЯТАБЛИЦА, когда, например, в одном из документов нет табличной части.
Пример: ВЫБРАТЬ Ссылка.Номер, ПУСТАЯТАБЛИЦА.(Ном, Тов, Кол) КАК Состав ИЗ Документ.РасходнаяНакладная ОБЪЕДИНИТЬ ВСЕ ВЫБРАТЬ Ссылка.Номер, Состав.(НомерСтроки, Номенклатура, Количество) ИЗ Документ.РасходнаяНакладная
8.При работе с соединениями таблиц, содержащих по одной строке, бывает нужно склеить строки таблиц (при этом в обеих таблицах нет такого поля, по которому их можно было соединить). Этого можно добиться, применив конструкцию «ПОЛНОЕ СОЕДИНЕНИЕ Таблица По ИСТИНА». Если в таблицах больше, чем одна строка, то в результате будет количество строк, равное произведению количества строк обеих таблиц. Если в одной таблице О строк, то в результирующей таблице количество строк будет равно количеству строк второй таблицы. Также для соединения таких таблиц можно применять декартово произведение таблиц , при котором в результирующей таблице будут встречаться все комбинации строк из обеих таблиц. Надо помнить, что если в одной из таблиц 0 строк, тогда и декартово произведение будет 0, поэтому полное соединение будет лучше. Вообще вместо полного соединения ПО ИСТИНА можно использовать и любой другой тип соединения, но в таком случае тоже возможна ситуация, когда в результирующей таблице будет 0 строк, даже если в одной из таблиц будет ненулевое количество строк. В случае полного соединения такая ситуация будет только в одном случае, если количество строк в обеих таблицах равно 0. Если знать, что в таблице есть точно хотя бы одна строка, тогда можно использовать и ЛЕВОЕ СОЕДИНЕНИЕ с другой таблицей с условием ПО ИСТИНА.
Пример (правда надуманный, для Полного соединения): ВЫБРАТЬ Первые 1 Пол.Ссылка, К.Контрагент ИЗ Перечисление.Пол КАК Пол ПОЛНОЕ СОЕДИНЕНИЕ (Выбрать Первые 1 Д.Контрагент ИЗ Документ.РеализацияТоваров КАК Д Упорядочить По Д.МоментВремени ) КАК К ПО (ИСТИНА)
9. Для того чтобы получить уникальные записи по какому-то полю, правильней вместо группировки пользоваться ключевым словом РАЗЛИЧНЫЕ в запросе, потому что такая конструкция намного наглядней и ключевое слово СГРУППИРОВАТЬ ПО имеет более широкое применение и часто используется, если дополнительно надо рассчитать агрегатные функции по группировкам. В некоторых случаях необходимо вывести ограниченное количество строк. Для этого в описании запроса в описании запроса следует указать ключевое слово ПЕРВЫЕ и после него – требуемое количество строк.
Пример для ПЕРВЫЕ: Выбрать Первые 5 Справочник.Номенклатура.Наименование, Справочник.Номенклатура.ЗакупочнаяЦена Упорядочить По Справочник.Номенклатура.ЗакупочнаяЦена Убыв
Пример для РАЗЛИЧНЫЕ: Выбрать Различные Документ.Расходная.Контрагент
10.Агрегатные функции в запросе можно использовать без ключевого слова СГРУППИРОВАТЬ. В таком случае все результаты будут сгруппированы в одну строку.
Пример: Выбрать Сумма(Накладная.Сумма) Как Сумма Из Документ.РасходнаяНакладная.Состав Как Накладная
11.В запросах в полях выборки можно свободно обращаться к реквизитам полей выборки. Эта возможность называется разыменованием полей выборки. Если источник данных - вложенная таблица (табличная часть документа), то в полях выборки можно обращаться также к полям основной таблицы (например, через поле Ссылка обратиться к полю основной таблицы Контрагент)
Пример: ВЫБРАТЬ [b] ПоступлениеТоваровИУслугТовары.Номенклатура, ПоступлениеТоваровИУслугТовары.Номенклатура.Код, ПоступлениеТоваровИУслугТовары.Количество КАК Количество, ПоступлениеТоваровИУслугТовары.Ссылка.КонтрагентИЗ Документ.ПоступлениеТоваровИУслуг.Товары КАК ПоступлениеТоваровИУслугТоварыГДЕ ПоступлениеТоваровИУслугТовары.Ссылка = &Ссылка[/b]
Есть одна особенность использования разыменования полей, если в запросе есть группировки. В любых запросах с группировками в списках полей запроса можно свободно обращаться к реквизитам группировочных полей.
Пример: ВЫБРАТЬ ПоступлениеТоваровИУслугТовары.Номенклатура, ПоступлениеТоваровИУслугТовары.Номенклатура.Код, СУММА(ПоступлениеТоваровИУслугТовары.Количество) КАК Количество, ПоступлениеТоваровИУслугТовары.Ссылка.Контрагент, ПоступлениеТоваровИУслугТовары.Ссылка.Дата ИЗ Документ.ПоступлениеТоваровИУслуг.Товары КАК ПоступлениеТоваровИУслугТовары ГДЕ ПоступлениеТоваровИУслугТовары.Ссылка = &Ссылка СГРУППИРОВАТЬ ПО ПоступлениеТоваровИУслугТовары.Номенклатура, ПоступлениеТоваровИУслугТовары.Ссылка
В справке 1С написано, что при наличии группировки, в полях выборки запроса могут участвовать только группировочные поля и агрегатные функции по полям выборки. Есть один исключительный случай, когда агрегатные функции применены к полям вложенной таблицы. В этом случае в списке полей выборки возможны обращения к полям таблицы верхнего уровня, без группировки результатов по этим полям.
Пример: ВЫБРАТЬ ПоступлениеТоваровИУслуг.Товары.(СУММА(Количество),Номенклатура), ПоступлениеТоваровИУслуг.Ссылка, ПоступлениеТоваровИУслуг.Контрагент ИЗ Документ.ПоступлениеТоваровИУслуг КАК ПоступлениеТоваровИУслуг СГРУППИРОВАТЬ ПО ПоступлениеТоваровИУслуг.Товары.(Номенклатура)
12. Иногда вместо указания какого-либо поля в группировке полезно в поля выборки запроса включить параметр: ВЫБРАТЬ ДокТовары.Номенклатура, &Контрагент, &Период, СУММА(ДокТовары.Количество * ДокТовары.К) КАК Количество, СУММА(ДокТовары.Сумма) КАК СуммаИЗ Документ.Приходная.Товары КАК ДокТоварыГДЕ ДокТовары.Ссылка = &Ссылка СГРУППИРОВАТЬ ПО ДокТовары.Номенклатура
А затем установить параметр в тексте запроса: Запрос.УстановитьПараметр(«&Контрагент», ВыбКонтрагент); Запрос.УстановитьПараметр(«&Период», Дата);
13. В универсальных запросах параметры можно использовать в описании источников данных запроса, в условиях ГДЕ, в условиях соединения таблиц и параметрах виртуальных таблиц. Существует два приема для создания универсальных запросов:
А) с помощью механизма конкатенации строк, добавляя в текст запроса переменные;
Пример1: ТипУпорядочивания = ?(НЕКАЯПЕРЕМЕННАЯ,"","УБЫВ"); Запрос.Текст= "Выбрать ... Упорядочить ПО Поле1 " + ТипУпорядочивания + "...";
Пример2: Запрос.Текст = "Выбрать Поле1..."; Если НЕКАЯПЕРЕМЕННАЯ = 1 Тогда Запрос.Текст = Запрос.Текст + ",Поле2 ..."; КонецЕсли;
Б)использовать параметры в различных частях запроса (например, в секции источников данных запроса), а затем метод встроенного языка - СТРЗАМЕНИТЬ(). При проектировании универсальных запросов полезно обращение к свойству объектов МЕТАДАННЫЕ(), с помощью которого можно определить название таблицы для какой-то ссылки (например, для документа будет примерно так - Ссылка.МЕТАДАННЫЕ().ИМЯ), переданной через параметр в некую универсальную процедуру.
Пример: Выбрать ДокТЧ.Номенклатура, ... ИЗ &НекийДокТЧ КАК ДокТЧ
А затем установить параметр в тексте запроса Запрос.Текст = СтрЗаменить(Запрос.Текст, "&НекийДокТЧ", "Документ."+Ссылка.Метаданные().Имя+".Товары");
Параметры можно использовать в условиях запроса, чтобы включить опциональное условие &Параметр ИЛИ НЕ КакоеТоСвойство: Запрос.УстановитьПараметр(“&Параметр”, “Контрагент.Наименование=””Иванов”””);
С помощью литерала ИСТИНА можно убирать определенные фильтры в запросе Запрос.УстановитьПараметр(«&Параметр»,Истина);
14.Очень полезными в конструкторе запросов является команда контекстного меню таблицы - "Переименовать таблицу...", с помощью которого можно придумать некоторое обобщенное имя для источника данных. Для создания запросов к однотипным таблицам, похожим по структуре, бывает полезным для второй таблицы скопировать текст запроса первой таблицы, зайти в окно конструктора запросов и в контекстном меню таблицы выбрать пункт - Заменить таблицу... и выбрать вторую талицу.
15.При работе с созданием вложенных запросов в секциях условий или параметров виртуальных таблиц конструктора запросов используется прием выделения пробела в скобках, тогда появляется в контекстном меню пункт «Конструктор запроса», а при редактировании вложенного запроса в условии выделяют весь запрос в скобках .
Пример вложенного запроса: Товар В ( Выбрать Номенклатура ...)
16. При проектировании отчетов СКД в запросах к регистрам остатков - в качестве параметра Период удобнее и правильнее использовать выражение ДобавитьКДате(КонецПериода(Период,ДЕНЬ),СЕКУДА,1), так как остатки в виртуальных получаются на начало периода, не включая последнюю секунду. Прием +1 секунда не может быть применен с документами: по новой методике проведения документов остатки по регистру надо получать на Период, заданный объектом Граница с моментом времени документа включая (а не на дату документа +1 секунда!), а по старой методике проведения - на момент времени документа (а не на дату документа !). При анализе оборотов или данных за период удобно добавлять параметр с типом СтандартныйПериод (в этом случае не надо приводить последнюю дату интервала на конец дня). У стандартного поля «НачалоПериода» в поле «Выражение» надо прописать «&Период.ДатаНачала». А у стандартного поля «КонецПериода» в поле «Выражение» прописать «&Период.ДатаОкончания». Очень много полезной информации по языку запросов можно найти не в синтакс-помощнике, а в полной справке конфигуратора 1С 8.2 (кнопка F1)
17.Функция запроса ЕстьNull (удобнее писать англоязычный вариант IsNull) обычно используется для избавления от значений типа Null для числовых полей запроса. В ряде случаев, например полного соединения двух таблиц функция IsNull (Параметр1,Параметр2) может с успехом заменить конструкцию ВЫБОР КОГДА ... ТОГДА ..ИНАЧЕ ….КОНЕЦ, когда для какого-либо поля значения NULL могут быть как в первой таблице, так и во второй (такая конструкция позволяет получать не Null значение для поля). Но надо помнить, что в отличие от условного оператора ВЫБОР функция ЕстьNull приводит тип второго аргумента к типу первого аргумента, что нужно учитывать, если типы аргументов отличаются!
Пример: IsNull(Рег.Остаток,0) IsNull(Док.Товар,Док1.Номенклатура)
18. У условной конструкции ВЫБОР есть альтернативный синтаксис для простого случая проверки равенства определенному значению, но, правда, он недокументированный: Выбор Выражение Когда 1 Тогда «Высший» Когда 2 Тогда «Средний» Иначе «Низший» Конец
19.Оператор проверки значения на NULL Eсть Null (Можно рекомендовать использовать англоязычный вариант Is Null). Такая конструкция появилась потому, что любая операция сравнения двух величин, хотя бы одно из которых Null, всегда ложь. Написать Где Наименование = Null неправильно. Интересна также форма отрицания данного оператора Не Есть Null - неправильно, а правильно Есть Не Null или форма Не (Поле1 Есть Null) - это существенное отличие от всех операторов, использующихся совместно с оператором Не.
20. Иногда полезна форма оператора В для проверки совпадения с одним из перечисленных значений.
Пример: ...Где Товар.Наименование В ("Бытовая техника","Компьютеры")
Для справочников может быть полезна форма оператора В проверки принадлежности по иерархии.
Пример: ...Где Номенклатура В ИЕРАРХИИ (&Группа)
Оператор В часто используется для проверки вхождения значения в результат вложенного запроса.
Пример: ...Где Номенклатура.Ссылка В (Выбрать Номенклатура.Ссылка ...).
Во вложенном запросе можно обращаться к полям внешнего запроса в условии.
Пример: // Выбрать названия товаров, которые присутствовали // в расходных накладных ВЫБРАТЬ Товары.Наименование ИЗ Справочник.Номенклатура КАК Товары ГДЕ Товары.Ссылка В (ВЫБРАТЬ РасходнаяНакладнаяСостав.Номенклатура ИЗ Документ.РасходнаяНакладная.Состав КАК РасходнаяНакладнаяСостав ГДЕ РасходнаяНакладнаяСостав.Номенклатура = Товары.Ссылка)
Операция В может использоваться с массивами, списками значений, таблицами значений, вложенными запросами. При этом возможно сокращение условий
Синтаксис для вложенного запроса (выражение1, выражение2,...,выражениеN) В (Выбрать выражение1, выражение2,...,выражениеN ...)
Синтаксис для таблицы значений (выражение1, выражение2,...,выражениеN) В (&ТЗ), где в таблице значений ТЗ используются N первых колонок
20. В интернете есть шутка по поводу того, как конструктор запроса постоянно делает ЛЕВОЕ соединение таблиц (и меняет их местами), как бы мы не указывали ПРАВОЕ: 1С:Предприятие любит «налево».
21. Сложные запросы удобно отлаживать в консоли запросов. Существует их в интернете много. После отладки запроса его можно скопировать и в конструкторе запроса есть замечательная кнопка «Запрос», куда можно вставить его в том же виде и сохранить (раньше была только возможность скопировать в конфигураторе и сделать форматирование запроса посредством символа переноса строки). В окне, которое открывается при нажатии кнопки «Запрос», можно редактировать запрос и смотреть результат выполнения, что довольно удобно.
22.При проектировании отчетов СКД нужно помнить, что если нужно обеспечить фильтрацию по некоторому полю, необязательно добавлять параметр в текст запроса. У конструктора запросов есть вкладка «Компоновка данных», где можно добавлять параметры в условия. Кроме того, на уровне отчета СКД есть закладка условия, где можно добавлять произвольные условия и сохранять в быстрых настройках. В таком случае условия будут универсальными (равенство, неравенство, принадлежность, вхождение в список и т.д.).
23. При работе с документами бывает нужно добавить сортировку по виртуальному полю таблицы МОМЕНТВРЕМЕНИ, но вот незадача - во вложенных запросах сортировка по этому полю правильно не работает. Помогают танцы с бубнами: сортировка по виртуальному полю МОМЕНТВРЕМЕНИ заменяется на две сортировки: по дате и по ссылке. Также решить проблему можно через временную таблицу переносом вложенного запроса в отдельный запрос. На протяжении уже многих релизов данная фича или баг не исправлена.
Пример неправильно работающего запроса, получающего последний проведенный документ по указанному контрагенту (вернее, табличную часть документа): ВЫБРАТЬ РасходнаяТовары.Ссылка, РасходнаяТовары.НомерСтроки, РасходнаяТовары.Товар, РасходнаяТовары.Количество, РасходнаяТовары.Цена, РасходнаяТовары.Сумма ИЗ Документ.Расходная.Товары КАК РасходнаяТовары ГДЕ РасходнаяТовары.Ссылка В (ВЫБРАТЬ ПЕРВЫЕ 1 Д.Ссылка ИЗ Документ.Расходная КАК Д ГДЕ Д.Ссылка.Проведен И Д.Контрагент = &Контрагент УПОРЯДОЧИТЬ ПО Д.Ссылка.МоментВремени УБЫВ)
Возможные решения:
A) Заменить на УПОРЯДОЧИТЬ ПО на УПОРЯДОЧИТЬ ПО Д.Дата УБЫВ УПОРЯДОЧИТЬ ПО Д.Ссылка УБЫВ
Б) Можно перенести вложенный запрос во временную таблицу: ВЫБРАТЬ ПЕРВЫЕ 1 Д.Ссылка ПОМЕСТИТЬ ТЗСсылка ИЗ Документ.Расходная КАК Д ГДЕ Д.Ссылка.Проведен И Д.Контрагент = &Контрагент УПОРЯДОЧИТЬ ПО Д.Ссылка.МоментВремени УБЫВ ; //////////////////////////////////////////////////////////////////////////////// ВЫБРАТЬ РасходнаяТовары.Ссылка, РасходнаяТовары.НомерСтроки, РасходнаяТовары.Товар, РасходнаяТовары.Количество, РасходнаяТовары.Цена, РасходнаяТовары.Сумма ИЗ Документ.Расходная.Товары КАК РасходнаяТовары ГДЕ РасходнаяТовары.Ссылка В (ВЫБРАТЬ Т.Ссылка ИЗ ТЗСсылка КАК Т)
В) Можно обратиться к основной таблице документа, а уже затем к табличной части ВЫБРАТЬ ПЕРВЫЕ 1 Расходная.Ссылка, Расходная.Товары.( Ссылка, НомерСтроки, Товар, Количество, Цена, Сумма ) ИЗ Документ.Расходная КАК Расходная ГДЕ Расходная.Контрагент = &Контрагент И Расходная.Проведен УПОРЯДОЧИТЬ ПО Расходная.МоментВремени УБЫВ
24. При обращении к главной таблице документа(справочника) можно в условии обратиться к данным подчиненной таблицы (табличной части). Такая возможность называется разыменование полей табличной части. В качестве примера задачи можно привести задачу поиска документов, содержащих в табличной части определенный товар.
Пример: Выбрать Приходная.Ссылка ИЗ Документ.Приходная Где Приходная.Товары.Номенклатура = &Номенклатура.
Преимущество этого запроса перед запросом ко вложенной таблице Приходная.Товары в том, что если есть дубли в документах , результат запроса вернет только уникальные документы без использования ключевого слова РАЗЛИЧНЫЕ.
Сравните: Выбрать Различные Товары.Ссылка ИЗ Документ.Приходная.Товары как Товары Где Товары.Номенклатура = &Номенклатура.
На этом месте, пожалуй, всё. Понятно, что в языке запросов ещё много неосвещенных мной вопросов. Для написания статьи была использована информация, полученная мной после прохождения базового курса 1С 8.2 spec8.ru, а также из книги «1С 8.2 Руководство разработчика» и просторов интернета.
Всем спасибо!
Автор: fpat
Цитата из справки 1С: "По умолчанию при объединении запросов полностью одинаковые строки в результате запроса, сформированные РАЗНЫМИ запросами, заменяются одной. Если требуется, чтобы были оставлены разные строки, необходимо указать ключевое слово ВСЕ."
Конструкция ОБЪЕДИНИТЬ и ОБЪЕДИНИТЬ ВСЕ объединяет два результата запроса в один.
Пример запроса для вывода всех документов Приход и Расход:
Конструкция ОБЪЕДИНИТЬ - соединяет два результата и группирует повторяющие строки,
А конструкция ОБЪЕДИНИТЬ ВСЕ - НЕ группирует автоматически строки результата.
Подробнее:
Порядок следования определяется порядком в списке полей в предложении ВЫБРАТЬ.
Количество полей можно изменить добавлением пустого фиктивного поля:
До некоторой степени, операции объединения и соединения прямо противоположны: при соединении у источников обязательно должен быть ключ (при объединении наличие ключа абсолютно не имеет значения), при соединении количество полей может быть произвольным (при объединении количество нолей должно совпадать и поля должны следовать в одном и то же порядке), при соединении природа данных в источниках может быть различна (при объединении связываются однотипные данные).
Смысл механизма При объединении, фактически, выполняются два запроса, а потом их результаты объединяются в один общий. Конструкция ОБЪЕДИНИТЬ ВСЕ оставит в итоговом запросе только неповторяющиеся записи (то есть, результат её действия аналогичен использованию фразы РАЗЛИЧНЫЕ после выполнения объединения).
Назначение псевдонимов, упорядочивание и расчёт итогов выполняются после объединения и действуют на результирующую таблицу.
В случае если в качестве второго параметра передается значение Ложь, расходные накладные и записи регистра накопления регистрируются как измененные только в случае совпадения склада со складом, определенным в узле плана обмена. Все остальные данные регистрируются обычным образом.
УстановитьНовыйНомер(<ПрефиксНомера>) Параметры:
<ПрефиксНомера> (необязательный)
Тип: Строка.
Префикс устанавливаемого номера.
Значение по умолчанию: Пустая строка Описание:
Устанавливает новый номер документа для заданного префикса номера. Доступность:
Сервер, толстый клиент, внешнее соединение. Примечание:
Для документов с нумерацией в пределах периода, номер устанавливается в пределах периода, соответствующего установленной дате документа. Если дата - пустая, процедура установит номер в пределах периода соответствующего пустой дате. Пример:
В типовой конфигурации, как правило, установка нового номера происходит через подписку на событие "ПриУстановкеНовогоНомера...". Последовательность вызова процедур, при работе через форму документа, при этом следующая:
- МодульФормы ПередЗаписью()
- МодульОбъекта ПередЗаписью()
- МодульОбъекта ПриУстановкеНовогоНомера()
- Событие(подписка) ПриустановкеНовогоНомера() (установка префиксов и номера)
- МодульОбъекта ПриЗаписи() (префиксы и номер установлены)
- Модульформы ПриЗаписи()
- МодульФормы ПослеЗаписи()
Пакетные запросы логично дополняют функционал временных таблиц и дают больше возможностей при работе с запросами.
В пакетном запросе фактически можно описать несколько запросов, как связанных между собой использованием временных таблиц, так и не связанных (можно, но не понятно зачем?). В итоге можно выполнить последовательно все запросы и принять в результате либо массив с результатами исполнения каждого запроса, либо результат последнего. Для получения массива с результатами запроса применяют метод ВыполнитьПакет() объекта запрос, а для получения результата последнего запроса ВыполнитьЗапрос().
В тексте запроса, запросы пакета разделяются символом «;» (точка с запятой). Область имен виртуальных таблиц у одного пакетного запроса одна. Использование менеджера временных таблиц не требуется, но возможно если вы хотите передать временные таблицы из одного пакетного запроса в другой.
Фактически я убрал определение объекта запрос и использование менеджера временных таблиц, объединил тексты запросов (обратите внимание на разделитель «;» между текстами). В результате текст запроса стал читабельнее (а при использовании конструктора запросов намного увеличивается удобство чтения запроса).
После выполнения запроса в переменную МассивРезультатов у нас попадет 3 элемента. Первые два будут содержать число характеризующее количество записей помещенных во временные таблицы ДокТЧ и СписокТоваров, а третий будет содержать выборку с полями Номенклатура, Док_Количество и Рег_Количество.
В переменную РезультатЗапроса попадет только выборка.
Ну вот и все что касается пакетных запросов. Очень удобный механизм и с точки зрения написания запросов и с точки зрения чтения сложных запросов.
Не помню уже с какого релиза в запросах стало можно использовать временные таблицы. Для этого используется объект «Менеджер временных таблиц». Фактически менеджер временных таблиц описывает пространство имен временных таблиц и отвечает за их создание и уничтожение в базе данных.
Сами временные таблицы действительно физически создаются в базе, соответственно следует относиться к ним осторожно, так как дисковая подсистема на сегодняшний момент самая медленная часть техники, а скорость создания и уничтожения таблиц напрямую от нее зависит.
Перепишем запрос для использования временных таблиц. Во временные таблицы поместим сгруппированную табличную часть документа и список товаров для фильтра виртуальных таблиц:
При использовании временных таблиц в тексте запроса применяют инструкцию Поместить для создания новой временной таблицы, в этом случае в результат запроса система передает не содержимое этой таблицы (см прим 1 и прим 2 в коде выше), а количество записей помещенных во временную таблицу, по желанию можно не принимать это значение.
Также допускается использование инструкции Уничтожить в этом случае временная таблица уничтожается, в противном случае временные таблицы уничтожаются вместе с объектом менеджер временных таблиц.
В основном нашем запросе я использовал названия временных таблиц как указание на источник получения данных (им обязательно надо назначать синоним, что мы и видим в тексте). Использовать временные таблицы как источник можно не единожды, что при умелом их применении позволит и сократить текст запроса (улучшиться читабельность сложных запросов) и увеличить скорость (при использовании данных временной таблицы в нескольких местах запроса).
Автор: Павел Чистов
Если Вы работаете с одной таблицей, то Вам нет необходимости использовать объединение. Совсем другое дело, когда Вы работаете с несколькими таблицами и Вам, например, нужно получить данные, и по покупкам и по продажам товаров.
Для объединения используется предложение ОБЪЕДИНИТЬ. На самом деле происходит объединение результатов запросов, то есть каждый запрос собирает данные независимо друг от друга, а затем эти результаты объединяются в один. И только над последним запросом выполняются остальные операции, например, упорядочивание и расчет итогов.
При объединении запросов происходит "вертикальное склеивание" результатов, то есть сначала идут строки результата первого запроса, затем второго.
Перейдём к практике:
Результат этого запроса следующий:
Номенклатура Количество Сумма
Бумага А4 25 14 500
Стикеры 500л 8 4 880
Файл прозрачный 5 4 100
Набор офисный 8 8 840
В итоге мы получим две таблицы, которые будут соединены друг с другом. Трудно увидеть, где кончается документ Приходная и начинается документ Расходная. Но мы сделаем кое-что, чтобы понять это:
Как видно из текста запроса мы задали для каждого документа разные псевдонимы для количества и суммы. Также на место тех полей, где мы будем получать значения суммы и количества, поставим нули. Это нужно, чтобы пустые значения количества и суммы заменялись нулями.
Номенклатура КолПриход СумПриход КолРасход СумРасход
Бумага А4 25 14 500
Стикеры 500л 8 4 880
Файл прозрачный 5 4 100
Набор офисный 8 8 840
Набор офисный 1 1 105
Файл прозрачный 1 820
Стикеры 500л 1 610
Теперь нам нужно из результат запроса убрать дублирующиеся элементы. У нас два запроса и если мы будем сворачивать, каждый отдельно, чтобы исключить дублирующиеся элементы, то у нас ничего не получится. Поэтому мы приведём запрос к следующему виду:
Итак, мы видим, что весь наш запрос заключён в скобки и назван как ВложенныйЗапрос. Это сделано для того, чтобы мы смогли сгруппировать записи из обоих подзапросов и исключить дублирующиеся элементы. Такая конструкция называется вложенным запросом. Результат этого запроса следующий:
Номенклатура КолПриход СумПриход КолРасход СумРасход
Бумага А4 25 14 500
Стикеры 500л 8 4 880 1 610
Набор офисный 5 4 100 1 1 105
Файл прозрачный 8 8 840 1 820
В итоге получаем сгруппированную таблицу, в которой данные из вложенных подзапросов приведены к понятному виду. Количество вложенных запросов не должно превышать 255. Мы использовали здесь четыре подзапроса.
Если мы хотим оставлять в запросе только уникальные значения записей при этом, не используя группировку. Нужно писать предложение ОБЪЕДЕНИТЬ без ключевого слова ВСЕ.