Вложенные таблицы 1с. Вложенные запросы

В данной статье рассмотрено предложение ИЗ, его место и роль в языке запросов 1С:Предприятия 8.

Предложение ИЗ присутствует почти в каждом запросе 1С:Предприятия 8, так как в большинстве случаев именно в нем указываются таблицы-источники данных для запроса. Кроме того, предложение ИЗ позволяет выполнить соединение нескольких таблиц, а также указать параметры при получении виртуальной таблицы.

Ниже рассмотрены следующие темы:
- Таблицы-источники
- Примеры запросов с предложением ИЗ:
- Выборка данных из различных таблиц-источников
- Виртуальные таблицы
- Псевдонимы источников
- Вложенный запрос как источник
- Соединение таблиц
- Место предложения ИЗ в структуре запроса

Место предложения ИЗ в структуре запроса

В запросе может не быть предложения ИЗ (если поля в списке выборки полностью квалифицированы, т.е. включают имя таблицы).
- Источников в запросе может быть несколько (в этом случае, они обычно соединяются по определенному условию)
- В качестве источника может быть обычная таблица-источник, виртуальная таблица с параметрами, а также вложенный запрос
- Для источника можно назначить псевдоним с помощью ключевого слова КАК (Внимание : если источником является вложенный запрос, то псевдоним обязателен).

Таблицы-источники

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

Примеры запросов с предложением ИЗ

Выборка данных из различных таблиц-источников

Выборка элементов справочника:


ВЫБРАТЬ *, Представление ИЗ Справочник.Номенклатура

Выборка документов определенного вида:

Выборка проведенных документов, входящих в журнал СкладскиеДокументы:

Выборка активных записей регистра накопления:


ВЫБРАТЬ Номенклатура, ПодразделениеКомпании, СуммаПродажи
ИЗ РегистрНакопления.ПродажиКомпании
ГДЕ Активность = Истина

Выборка данных из табличной части документа:


//обращение к табличной части документа
ВЫБРАТЬ Номенклатура, Количество
ИЗ Документ.АвансовыйОтчет.Товары

При обращении к табличной части документа как источнику данных обычные реквизиты документа доступны через поле табличной части Ссылка, например:

Виртуальные таблицы

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

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


//обращение к виртуальной таблице регистра накопления (вызов без параметров)
ВЫБРАТЬ * ИЗ РегистрНакопления.ПродажиКомпании.Обороты

//выборка оборотов за период
ВЫБРАТЬ * ИЗ РегистрНакопления.ПродажиКомпании.Обороты(&Нач, &Кон,)

//выборка оборотов по конкретному товару
ВЫБРАТЬ * ИЗ РегистрНакопления.ПродажиКомпании.Обороты(,Номенклатура = &ВыбТовар)

//остатки товаров на определенную дату
ВЫБРАТЬ * ИЗ РегистрНакопления.ОстаткиТоваровКомпании.Остатки(&ВыбДата,)

Замечание . Виртуальная таблица "Остатки", а также "ОстаткиИОбороты" существуют только у регистра накопления типа "Остатки". Виртуальная таблица "Обороты" существует у регистра оборотов и регистра остатков.Виртуальная таблица "ОборотыДтКт" существует только у регистра бухгалтерии с поддержкой корреспонденции.

Псевдонимы источников

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


ВЫБРАТЬ Продажи.Номенклатура,
Продажи.ПодразделениеКомпании,
Продажи.СуммаПродажи
ИЗ РегистрНакопления.ПродажиКомпании КАК Продажи
ГДЕ Активность = Истина

Вложенный запрос как источник

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


ВЫБРАТЬ
Товары.Номенклатура КАК Товар,
Товары.Номенклатура.Артикул
ИЗ
ВЫБРАТЬ Номенклатура ИЗ Документ.ВнутреннийЗаказ.Товары
ОБЪЕДИНИТЬ
ВЫБРАТЬ Номенклатура ИЗ Документ.ЗаказПокупателя.Товары
) КАК Товары

Соединение таблиц

Важной возможностью языка запросов системы 1С:Предприятие 8 является обращение сразу к нескольким таблицам. При этом их можно соединять определенным образом.

Рассмотрим сначала, что произойдет, если в предложении ИЗ будет несколько источников. В этом случае будет сформировано "декартово произведение" двух множеств. Каждой записи одной таблицы будут сопоставлены все записи из другой. Например,

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

Внутреннее соединение

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


ВЫБРАТЬ ДокТовары.Номенклатура, Спр.Артикул, ДокТовары.Количество, ДокТовары.Сумма
ИЗ Справочник.Номенклатура КАК Спр
СОЕДИНЕНИЕ Документ.АвансовыйОтчет.Товары КАК ДокТовары
ПО Спр.Ссылка = ДокТовары.Номенклатура

Замечание . В данном примере того же эффекта можно добиться, если просто обращаться к имени поля через точку, что называется разыменованием ссылочных полей. При этом соединение таблиц производится неявно. Возможность разыменования полей в 1С:Предприятии 8 допускает обращение к свойствам объектов через несколько точек, например, «Номенклатура.Поставщик.Страна». Это позволяет значительно упростить написание запросов.
Если в таблице будет найдено несколько записей, удовлетворяющих условию соединения, то в результат запроса будут включены все эти записи.
Замечание. При соединениях чаще всего применяется условие на "равно", но в языке запросов есть возможность использовать все операции сравнения и логические операции И, ИЛИ, НЕ.

Левое внешнее соединение

Конструкция ЛЕВОЕ [ВНЕШНЕЕ] СОЕДИНЕНИЕ означает, что в результат запроса надо включить комбинации записей из обеих исходных таблиц, которые соответствуют указанному условию. Но, в отличие от внутреннего соединения, в результат запроса надо включить еще и записи из первого источника (указанного слева от слова СОЕДИНЕНИЕ), для которых не найдено соответствующих условию записей из второго источника.

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

Обратите внимание, что NULL-значения не являются нулем или пустой строкой. Это специальные маркеры, обозначающие неуказанные (отсутствующие) значения или значения, не имеющие смысла.

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


ИЗ Справочник.Валюты КАК Спр
ЛЕВОЕ ВНЕШНЕЕ СОЕДИНЕНИЕ РегистрСведений.КурсыВалют.СрезПоследних КАК Рег
ПО Спр.Ссылка = Рег.Валюта

Правое внешнее соединение

Конструкция ПРАВОЕ [ВНЕШНЕЕ] СОЕДИНЕНИЕ означает, что в результат запроса надо включить комбинации записей из обеих исходных таблиц, которые соответствуют указанному условию. Кроме того, в результат запроса надо включить еще и записи из второго источника (указанного справа от слова СОЕДИНЕНИЕ), для которых не найдено соответствующих условию записей из первого источника.

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


ВЫБРАТЬ Спр.Наименование КАК Валюта, Рег.Курс
ИЗ РегистрСведений.КурсыВалют.СрезПоследних() КАК Рег
ПРАВОЕ ВНЕШНЕЕ СОЕДИНЕНИЕ Справочник.Валюты КАК Спр
ПО Спр.Ссылка = Рег.Валюта

Полное внешнее соединение

Конструкция ПОЛНОЕ [ВНЕШНЕЕ] СОЕДИНЕНИЕ означает, что в результат запроса надо включить комбинации записей из обеих исходных таблиц, которые соответствуют указанному условию. Кроме того, в результат запроса надо включить также еще и те записи из обоих источников, для которых не найдено соответствий.

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

Таким образом, предложение ИЗ является одним из самых важных элементов языка запросов, поскольку позволяет указать таблицы-источники для запроса. Гибкие возможности предложения ИЗ позволяют использовать язык запросов для решения самых разнообразных задач.

Конструктор запросов в 1С 8.3 и 8.2 — мощнейший инструмент разработки. Он позволяет составить текст запроса при помощи специальной визуальной среды. Таким образом, чтобы создать запрос 1с не обязательно знать встроенный язык запросов, достаточно ориентироваться в не сложном и интуитивно понятном интерфейсе конструктора.

Конструктор запросов представляет из себя набор вкладок, каждая из которых отвечает за свою часть запроса. Так заполняя вкладку Таблицы и поля мы выбираем таблицы из которых запрос 1с будет получать данные и поля этих таблиц необходимые для решения конкретной задачи. Заполняя в кладку Условия мы накладываем условия на выбранные таблицы, для того чтобы выбрать из них только нужные нам данные и так далее.

Описание конструктора запросов на официальном сайте 1С 8: v8.1c.ru

Таблицы и поля; ; ; ; ; ; Вложенные запросы (в разработке).

Для того чтобы вызвать конструктор запросов 1с 8 в программном коде необходимо:

  • Создать новый запрос
Запрос = Новый Запрос;
  • Задать пустую строку текста запроса
Запрос.Текст = "";
  • Поставить курсор мышки между кавычками, нажать правую кнопку мыши. В открывшемся контекстном меню выбрать пункт Конструктор запроса и ответить Да на вопрос о создании нового запроса. Если текст запроса уже записан, то необходимо щелкнуть на любом месте внутри него и вызвать конструктор;

Рассмотрим на небольших примерах с возрастающей сложностью все основные вкладки конструктора запросов. Такой подход позволит начинающему программисту 1с более эффективно изучить конструктор и все его возможности. Для примеров будем использовать конфигурацию Бухгалтерия 3.0.

Урок №1. Конструктор запросов — простейший пример использования.

Задача: написать запрос к справочнику номенклатура, выбрать всю номенклатуру справочника.

Новые вкладки: Таблицы и поля.

Новые механизмы: просмотр и редактирование текста запроса при помощи кнопки «Запрос».

Для начала создания запроса создадим новый запрос и вызовем конструктор (как это делается написано несколькими абзацами выше). После этого откроется окно конструктора на вкладке Таблицы и поля.

Теоретическая часть урока №1

Вкладка Таблицы и поля состоит из трех разделов:

База данных . В данном разделе представлены все таблицы базы данных, которые можно использовать для построения запроса;

Таблицы . В данный раздел выбираются таблицы необходимые для данного запроса. Для тогда чтобы переместить их из раздела база данных нужно:

  • Либо дважды щелкнуть по таблице;
  • Либо воспользоваться кнопками «>» или «>>».

Над разделом Таблицы присутствует ряд кнопок. Про большинство из них будет подробнее рассказано в следующих уроках. А пока дам только краткие пояснения.

  • Создать вложенный запрос (красная линия). Предназначена для создания нового вложенного запроса;
  • Создать описание временной таблицы (желтая линия). Позволяет задать имя временной таблицы, которая расположена вне данного запроса, также можно использовать для передачи в запрос таблицы значений;
  • Изменить текущий элемент (зеленая линия). Позволяет перейти в выделенный вложенный запрос, временную таблицу или описание временной таблицы;
  • Удалить текущий элемент (голубая линия). Удаляет выделенную таблицу из выбранных таблиц;
  • Заменить таблицу (синяя линия). Открывает диалог замены выделенной таблицы. Полезно, если вы неверно выбрали виртуальную таблицу регистра, так как происходит позиционирование на текущей выбранной таблице в списке.
  • Параметры виртуальной таблицы (фиолетовая линия). Открывает параметры виртуальной таблицы регистра.

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

  • Либо дважды щелкнуть по полю;
  • Либо воспользоваться кнопками «>» или «>>»;
  • Также можно добавить новое поле самостоятельно, используя произвольное выражение из полей выбранных таблиц и функций языка запросов.

Над разделом Поля присутствует ряд кнопок. Про создание полей при помощи произвольных выражений будет подробнее рассказано в следующих уроках. А пока дам только краткие пояснения.

  • Добавить (зеленая линия). Предназначена для добавления нового поля при помощи редактора произвольных выражений;
  • Изменить текущий элемент (красная линия). Позволяет изменить выделенное поле при помощи редактора;
  • Удалить текущий (синяя линия). Удаляет выделенное поле из списка.

Практическая часть урока №1

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

Приступим к созданию запроса по номенклатуре:

  • Создадим новый запрос и откроем конструктор методом указанным в начале урока;
  • В разделе База данных , откроем ветку Справочники и найдем там справочник Номенклатура;
  • Выделим его и при помощи кнопки «>» перенесем в раздел Таблицы;
  • В разделе Таблицы раскроем справочник номенклатура при помощи значка «+»;
  • В раскрывшемся списке полей найдем поле Ссылка и перенесем его в раздел Поля при помощи кнопки «>»
  • Запрос по номенклатуре готов, нажимаем кнопку «ОК» в нижней части окна конструктора.

Данная статья рассчитана на читателей, которые знакомы с языком SQL.

Язык запросов в 1С, применяющийся начиная с версии 8, сегодня стал полезным инструментом для работы с базами данных, который позволяет читать из них, но не записывать. Синтаксически язык запросов очень схож с языком SQL, но на русском языке.

Ниже представлена таблица соответствия основных операторов языка запросов и SQL:

Операторы языка запросов 1С

Оператор SQL

РАЗЛИЧНЫЕ

СОЕДИНЕНИЕ

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

ОБЪЕДИНИТЬ

УПОРЯДОЧИТЬ ПО

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

Выполнение запроса 1С из программного кода осуществляется при помощи объекта встроенного языка «Запрос». Пример написания запроса к базе данных с использованием встроенного языка программирования:

Запрос = Новый Запрос; Запрос.Текст = "ВЫБРАТЬ | Синоним.Ссылка КАК Ссылка |ИЗ | Справочник.Справочник1 КАК Синоним"; Выборка = Запрос.Выполнить().Выбрать(); Пока Выборка.Следующий() Цикл // Вставить обработку выборки ВыборкаДетальныеЗаписи КонецЦикла;

Метод «Выполнить» выполняет запрос, метод «Выбрать» возвращает значение типа «ВыборкаИзРезультатаЗапроса». Также можно использовать метод «Выгрузить», который возвращает таблицу значений.

Параметры запроса хранятся в свойстве «Параметры» (в данном случае это структура, поэтому все методы структуры тут применимы – вставить, удалить и т.д.).

Пример установки параметра «Запрос.Параметры.Вставить» («Справочник», СправочникСсылка). В запросе обратиться к параметрам можно через амперсанд «&Справочник». Ниже пример запроса с использованием параметров:

Запрос = Новый Запрос; Запрос.Текст = "ВЫБРАТЬ | Пользователи.Ссылка КАК Ссылка, | Пользователи.Родитель КАК Родитель, | Пользователи.Наименование КАК Наименование |ИЗ | Справочник.Пользователи КАК Пользователи |ГДЕ | Пользователи.Ссылка = &Справочник"; Запрос.Параметры.Вставить("Справочник", СправочникСсылка); Выборка = Запрос.Выполнить().Выбрать(); Пока Выборка.Следующий() Цикл // Вставить обработку выборки ВыборкаДетальныеЗаписи КонецЦикла;

Напомним, что язык запросов предназначен только для чтения данных из базы, поэтому в нем отсутствуют аналоги таких операторов SQL, как INS ERT и UPDATE. Данные можно модифицировать только через объектную модель встроенного языка программирования 1С. Также в языке запросов 1С существуют операторы, аналогов которых нет в SQL, например:

  • В ИЕРАРХИИ
  • ПОМЕСТИТЬ
  • ИНДЕКСИРОВАТЬ ПО

В ИЕРАРХИИ – позволяет выбрать все элементы иерархического справочника, которые входят в иерархию переданной ссылки. Пример запроса с использованием В ИЕРАРХИИ :

ВЫБРАТЬ Товары.Ссылка, Товары.Артикул ИЗ Справочник.Товары КАК Товары ГДЕ Товары.Ссылка В ИЕРАРХИИ(&Цитрусовые)"

В данном случае в результат вернутся все подчиненные элементы справочника номенклатуры «Цитрусовые», неважно, сколько уровней иерархии есть у данного справочника.

Также, к примеру, стоит задача найти товар с именем «Ручка». Товар должен входить в иерархию «Канц. Товаров», то есть нам не надо искать дверную ручку. Структура номенклатуры в этом случае такова:

Канцелярия

|_ Ручки перьевые |_ Ручка красная |_ Ручка синяя |_ Ручки чернильные |_ Линейки

Фурнитура

|_ Ручки дверные |_ Ручка дверная простая |_ Ручка дверная люкс

Пишем такой запрос:

ВЫБРАТЬ Товары.Ссылка, Товары.Артикул ИЗ Справочник.Товары КАК Товары ГДЕ Товары.Наименование Подобно "Ручка%" И Товары.Ссылка В ИЕРАРХИИ(&Канцелярия)"

При использовании конструкции В ИЕРАРХИИ необходимо учитывать, что если в параметр «Канцелярия» передать пустую ссылку, выполнение запроса замедлится, так как платформа будет проверять каждый элемент на принадлежность корню.

ПОМЕСТИТЬ – Данный оператор помещает результат во временную таблицу. Пример запроса:

ВЫБРАТЬ Пользователи.Ссылка КАК Ссылка, Пользователи.Родитель КАК Родитель, Пользователи.Наименование КАК Наименование ПОМЕСТИТЬ ОтобранныеПользователи ИЗ Справочник.Пользователи КАК Пользователи ГДЕ Пользователи.Ссылка = &Справочник; ВЫБРАТЬ ОтобранныеПользователи.Ссылка КАК Ссылка, ОтобранныеПользователи.Родитель КАК Родитель, ОтобранныеПользователи.Наименование КАК Наименование ИЗ ОтобранныеПользователи КАК ОтобранныеПользователи

Данный запрос на SQL будет выполнен несколькими запросами:

  • Создание временной таблицы (платформа умеет «переиспользовать» ранее созданные временные таблицы, поэтому создание происходит не всегда);
  • Помещение данных во временную таблицу;
  • Выполнение основного запроса, а именно SEL ECT из этой временной таблицы;
  • Уничтожение/очистка временной таблицы.

Временная таблица может быть уничтожена явно, через конструкцию УНИЧТОЖИТЬ , либо неявно – при закрытии менеджера временных таблиц.

У объекта «Запрос» встроенного языка программирования есть свойство «МенеджерВременныхТаблиц», которое предназначено для работы с временными таблицами. Пример кода:

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

После выполнения запроса переменную МВТ можно использовать второй раз в другом запросе, что, несомненно, является еще одним плюсом использования временных таблиц. В данном случае временная таблица из базы будет удалена при вызове метода «Закрыть»…

МВТ.Закрыть();

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

ИНДЕКСИРОВАТЬ ПО – этот оператор применяется совместно с оператором ПОМЕСТИТЬ. При создании временной таблицы этим оператором можно проиндексировать создаваемую таблицу, что существенно ускоряет работу с ней (но только, если индекс подходит под ваш запрос).

Бесплатная консультация эксперта

Спасибо за Ваше обращение!

Специалист 1С свяжется с вами в течение 15 минут.

Особенности некоторых операторов языка запросов

ДЛЯ ИЗМЕНЕНИЯ – данный оператор предназначен для блокировки определенной таблицы запроса (или всех таблиц, которые участвуют в запросе). Блокировка осуществляется наложением U блокировки на таблицу. На SQL это реализуется через hint UPDLOCK. Данная конструкция необходима для предотвращения блокировок типа deadlock. Пример запроса с конструкцией ДЛЯ ИЗМЕНЕНИЯ:

ВЫБРАТЬ Пользователи.Ссылка КАК Ссылка, Пользователи.Родитель КАК Родитель, Пользователи.Наименование КАК Наименование ИЗ Справочник.Пользователи КАК Пользователи ЛЕВОЕ СОЕДИНЕНИЕ Справочник.РФК КАК РФК ПО Пользователи.РФК = РФК.Ссылка ДЛЯ ИЗМЕНЕНИЯ Справочник.Пользователи

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



СОЕДИНЕНИЕ – запрос поддерживает соединения ЛЕВОЕ/ПРАВОЕ, ПОЛНОЕ, ВНУТРЕННЕЕ, что соответствует соединениям в SQL – LEFT/RIGHT JOIN, OUTER JOIN, INNER JOIN.

Однако при использовании конструктора запросов вы не сможете сделать ПРАВОЕ СОЕДИНЕНИЕ. Конструктор просто будет менять местами таблицы, но оператор будет всегда левый. По этой причине в 1С никогда не встретишь применения правого соединения.

Синтаксически соединение выглядит так:

ВЫБРАТЬ Таблица1.Ссылка КАК Ссылка ИЗ Справочник.Справочник1 КАК Таблица1 ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Справочник2 КАК Таблица2 ПО Таблица1.Реквизит = Таблица2.Реквизит

В языке запросов 1С отсутствует оператор для соединения декартова произведения (CROSS JOIN). Однако отсутствие оператора не означает, что язык запросов не поддерживает такого соединения. Соединить таблицы при необходимости можно таким образом:

ВЫБРАТЬ Таблица1.Ссылка КАК Ссылка ИЗ Справочник.Справочник1 КАК Таблица1 ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Справочник2 КАК Таблица2 ПО ИСТИНА

Как видно из примера, задан ключ соединения ПО ИСТИНА , то есть каждая строка одной таблицы соответствует строке другой. Тип соединения (ЛЕВОЕ, ПРАВОЕ, ПОЛНОЕ, ВНУТРЕННЕЕ) не важен, если у вас есть строки в обеих таблицах, но если в какой-то из таблиц нет строк (пуская таблица) – результат будет отличаться. Например, при использовании ВНУТРЕННЕЕ соединение результат будет пустой. При использовании ЛЕВОЕ/ПРАВОЕ соединение в результате будет или не будет данных в зависимости от того, к какой таблице мы присоединяемся – с данными или нет. При использовании ПОЛНОГО соединения данные будут всегда (естественно, только одной таблицы, так как в другой пустота), выбор типа соединения зависит от конкретной прикладной задачи.

Небольшая визуальная подсказка, как работают различные типы соединений:



ПОДОБНО. В отличие от аналогичного оператора языка SQL – LIKE, шаблон для ПОДОБНО можно задать, используя только некоторые спец символы:

  • % (процент): последовательность, содержащая любое количество произвольных символов;
  • _ (подчеркивание): один произвольный символ;
  • / - следующий символ нужно интерпретировать как обычный символ.

ИТОГИ ПО аналогом на SQL можно назвать оператор ROLLUP. Пример использования оператора ИТОГИ:

ВЫБРАТЬ Товары.Цена КАК Цена, Товары.Товар КАК Товар ИЗ Справочник.Номенклатура КАК Товары ИТОГИ СРЕДНЕЕ(Цена) ПО Товар

Результат будет такой:

Кровать

9833,333

Утюг

Ручка

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

Работа с пакетными запросами

1С позволяет работать с пакетами запросов. В пакетном запросе тексты запросов разделяются точкой с запятой (;). Выполнение пакетного запроса 1С осуществляется последовательно. Пример текста пакетного запроса:

ВЫБРАТЬ Пользователи.Ссылка КАК Ссылка, Пользователи.Родитель КАК Родитель, Пользователи.Наименование КАК Наименование ИЗ Справочник.Пользователи КАК Пользователи;
ВЫБРАТЬ ГрафикРаботы.Пользователь КАК Пользователь, ГрафикРаботы.Дата КАК Дата, ГрафикРаботы.РабочихЧасов КАК РабочихЧасов ИЗ РегистрСведений.ГрафикРаботы КАК ГрафикРаботы

Для получения результата всех запросов, входящих в пакет, необходимо воспользоваться методом объекта запроса «ВыполнитьПакет», вместо «Выполнить». Данный метод последовательно выполняет все запросы. Результат запроса – массив результатов для каждого запроса из пакета, а последовательность расположения в массиве такая же, как последовательность запросов в тексте пакета.

Рассматривая язык запросов, стоит упомянуть о такой особенности, как виртуальные таблицы. Виртуальные таблицы отсутствуют в базе данных, это своеобразная обертка, которая выполняется на стороне СУБД как запрос с использованием подзапросов. Пример запроса 1С с использованием виртуальных таблиц:

ВЫБРАТЬ РегистрОбязательствОбороты.Обязательство КАК Обязательство ИЗ РегистрНакопления.РегистрОбязательств.Обороты() КАК РегистрОбязательствОбороты

Такой запрос на СУБД будет выглядеть так:

SEL ECT T1.Fld25931RRef FR OM (SELECT T2._Fld25931RRef AS Fld25931RRef, CAST(SUM(T2._Fld25936) AS NUMERIC(38, 8)) AS Fld25936Turnover_, CAST(SUM(T2._Fld25937) AS NUMERIC(38, 8)) AS Fld25937Turnover_ FR OM dbo._AccumRgTn25938 T2 WH ERE ((T2._Fld949 = @P1)) AND ((T2._Fld25936 @P2 OR T2._Fld25937 @P3)) GROUP BY T2._Fld25931RRef HAVING (CAST(SUM(T2._Fld25936) AS NUMERIC(38, 8))) 0.0 OR (CAST(SUM(T2._Fld25937) AS NUMERIC(38, 8))) 0.0) T1>>>>

Видно, что не похоже на SQL, поскольку есть подзапрос, группировка. Виртуальные таблицы, по большому счету – это «синтаксический сахар», то есть созданы, в общем-то, для удобства разработки запросов, чтобы запросы были компактнее и читабельнее.

Виртуальные таблицы есть только у регистров, но какие именно виртуальные таблицы доступны у регистра, можно увидеть в конструкторе запросов.



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



В тексте запроса это выглядит так:

РегистрНакопления.РегистрОбязательств.Обороты(, Операция = &Операция) КАК РегистрОбязательствОбороты

Для удобства написание запросов, то есть создания текстов запросов, в 1С существует конструктор, который можно вызвать через контекстное меню (правой кнопкой мыши):



В конструкторе запросов можно увидеть полный список поддерживаемых функций и операторов языка запросов.


Конструктор запросов является очень гибким визуальным инструментом для создания запросов любой сложности. Он доступен только в режиме конфигуратора. В режиме Предприятия есть так называемая «Консоль запросов» – это внешняя обработка, поставляемая на диске ИТС. Для управляемого приложения консоль запросов можно скачать на сайте its.1c.ru.

Описание работы в конструкторе запросов выходит за рамки тематики данной статьи, поэтому подробно рассматриваться не будет.

Причины неоптимальной работы запросов

Ниже приведен список основных причин (но не всех), которые приводят к замедлению выполнения запроса.

  • Использования соединения с подзапросами

Не рекомендуется выполнять соединение с подзапросами, подзапросы необходимо заменить временными таблицами. Соединение подзапросов может приводить к значительной потере в производительности, при этом выполнение запроса на разных СУБД может значительно разниться в скорости. Скорость выполнения таких запросов также чувствительна к статистике в СУБД. Причина такого поведения в том, что оптимизатор СУБД не всегда корректно может определить оптимальный план выполнения запросов, так как оптимизатор ничего не знает о том, какое количество строк вернет подзапрос после своего выполнения.

  • Использование виртуальных таблиц в соединениях запроса

Виртуальные таблицы на уровне СУБД выполняются как подзапросы, поэтому причины такие же, как в первом пункте.

  • Использование условий в запросе, неподходящих под существующие индексы

Если в условиях запроса (в операторе ГДЕ или в условиях виртуальной таблицы) используются поля, которые не все входят в индекс, данный запрос будет выполнен с использованием SQL конструкции table scan или index scan (полностью или частично). Это скажется не только на времени выполнения запроса, но также будет наложена избыточная S блокировка на лишние строки, что в свою очередь может привести к эскалации блокировок, то есть будет заблокирована вся таблица.

  • Использование ИЛИ в условиях запроса

Использование логического оператора ИЛИ в конструкции ГДЕ может также приводить к сканированию таблицы (table scan). Это происходит из-за того, что СУБД не может корректно использовать индекс. Вместо ИЛИ можно применить конструкцию ОБЪЕДИНИТЬ ВСЕ.

  • Получение данных через точку для полей составного типа

Не рекомендуется получать значения через точку (в конструкции ВЫБРАТЬ, ГДЕ ), поскольку если реквизит объекта окажется составным типом, соединение будет происходить с каждой таблицей, входящей в этот составной тип. В результате запрос на СУБД будет значительно усложнен, это может помешать оптимизатору в выборе корректного плана выполнения запроса.

Язык запросов является одним из основополагающих механизмов 1С 8.3 для разработчиков. При помощи запросов можно быстро получить любые данные, хранящиеся в базе. Его синтаксис очень похож на SQL, но есть и отличия.

Основные достоинства языка запросов 1С 8.3 (8.2) перед SQL:

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

Недостатки языка запросов в 1С:

  • в отличие от SQL, в 1С запросы не позволяют изменять данные;
  • отсутствие хранимых процедур;
  • невозможность преобразования строки в число.

Рассмотрим наш мини учебник по основным конструкциям языка запросов 1С.

В связи с тем, что запросы в 1С позволяют лишь получать данные, любой запрос должен начинаться со слова «ВЫБРАТЬ». После этой команды указываются поля, данные из которых нужно получить. Если указать «*», то будут выбраны все доступные поля. Место, откуда будут выбираться данные (документы, регистры, справочники и прочее) указывается после слова «ИЗ».

В рассмотренном ниже примере выбираются наименования всей номенклатуры из справочника «Номенклатура». После слова «КАК» указываются псевдонимы (имена) для таблиц и полей.

ВЫБРАТЬ
Номенклатура.Наименование КАК НаименованиеНоменклатуры
ИЗ
Справочник.Номенклатура КАК Номенклатура

Рядом с командой «ВЫБРАТЬ» можно указать ключевые слова:

  • РАЗЛИЧНЫЕ . Запрос будет отбирать только отличающиеся хотя бы по одному полю строки (без дублей).
  • ПЕРВЫЕ n , где n – количество строк с начала результата, которые необходимо отобрать. Чаще всего такая конструкция используется совместно с сортировкой (УПОРЯДОЧИТЬ ПО). Например, когда нужно отобрать определенное количество последних по дате документов.
  • РАЗРЕШЕННЫЕ . Данная конструкция позволяет выбирать из базы только те записи, которые доступны текущему пользователю. Баз использования этого ключевого слова пользователю будет выведено сообщение об ошибке при попытке обращения запроса к тем записям, доступа к которым у него нет.

Эти ключевые слова могут использоваться как все вместе, так и по отдельности.

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

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

Чаще всего предложение «ДЛЯ ИЗМЕНЕНИЯ» используется при получении остатков. Ведь при одновременной работе нескольких пользователей в программе, пока один получает остатки, другой может их изменить. В таком случае полученный остаток будет уже не верен. Если же заблокировать данные этим предложением, то пока первый сотрудник не получит корректный остаток и не совершит с ним все необходимые манипуляции, второй сотрудник будет вынужден ждать.

ВЫБРАТЬ
Взаиморасчеты.Сотрудник,
Взаиморасчеты.СуммаВзаиморасчетовОстаток
ИЗ
РегистрНакопления.ВзаиморасчетыССотрудниками.Остатки КАК Взаиморасчеты
ДЛЯ ИЗМЕНЕНИЯ

ГДЕ (WHERE)

Конструкция необходима для наложения какого-либо отбора на выгружаемые данные. В некоторых случая получения данных из регистров разумнее прописывать условия отборов в параметрах виртуальных таблиц. При использовании «ГДЕ», сначала получаются все записи, и только потом применяется отбор, что значительно замедляет выполнение запроса.

Ниже приведен пример запроса получения контактных лиц с определенной должностью. Параметр отбора имеет формат: &ИмяПараметра (имя параметра произвольное).

ВЫБОР (CASE)

Конструкция позволяет указывать условия непосредственно в теле запроса.

В приведенном ниже примере «ДополнительноеПоле» будет содержать текст в зависимости от того проведен документ или нет:

ВЫБРАТЬ
ПоступлениеТиУ.Ссылка,
ВЫБОР
КОГДА ПоступлениеТиУ.Проведен
ТОГДА «Документ проведен!»
ИНАЧЕ «Документ не проведен…»
КОНЕЦ КАК ДополнительноеПоле
ИЗ
Документ.ПоступлениеТоваровУслуг КАК ПоступлениеТиУ

СОЕДИНЕНИЕ (JOIN)

Соединения связывают две таблицы по определенному условию связи.

ЛЕВОЕ/ПРАВОЕ СОЕДИНЕНИЕ

Суть ЛЕВОГО соединения заключается в том, что полностью берется первая указанная таблица и к ней по условию связи привязывается вторая. Если записей, соответствующих первой таблице во второй не нашлось, то в качестве их значений подставляется NULL. Проще говоря, главной является первая указанная таблица и к её данным уже подставляются данные второй таблицы (если они есть).

Например, необходимо получить номенклатурные позиции из документов «Поступление товаров и услуг» и цены из регистра сведений «Цены номенклатуры». В данном случае, если цена у какой-либо позиции не найдена, вместо нее подставиться NULL. Из документа все позиции будут выбраны вне зависимости от того, есть ли на них цена или нет.

ВЫБРАТЬ
ПоступлениеТиУ.Номенклатура,
Цены.Цена
ИЗ
Документ.ПоступлениеТоваровУслуг.Товары КАК ПоступлениеТиУ
ВНУТРЕННЕЕ СОЕДИНЕНИЕ РегистрСведений.ЦеныНоменклатуры.СрезПоследних КАК Цены
ПО ПоступлениеТиУ.Номенклатура = Цены.Номенклатура

В ПРАВОМ все в точности да наоборот.

ПОЛНОЕ СОЕДИНЕНИЕ

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

При использовании в предыдущем примере полного соединения будут выбраны все позиции номенклатуры из документа «Поступление товаров и услуг» и все последние цены из регистра «Цены номенклатуры». Значения не найденных записей, как в первой, так и во второй таблице будут равняться NULL.

ВНУТРЕННЕЕ СОЕДИНЕНИЕ

Отличием ВНУТРЕННЕГО соединения от ПОЛНОГО является то, что если хотя бы в одной из таблиц не найдена запись, то запрос не выведет ее вообще. В результате будут выбраны только те номенклатурные позиции из документа «Поступление товаров и услуг», для которых в регистре сведений «Цены номенклатуры» есть записи, если в предыдущем примере заменить «ПОЛНОЕ» на «ВНУТРЕННЕЕ».

СГРУППИРОВАТЬ ПО (GROUP BY)

Группировка в запросах 1С позволяет сворачивать строки таблицы (группировочные поля) по определенному общему признаку (группируемым полям). Группировочные поля могут выводиться только с применением агрегатных функций.

Результатом следующего запроса будет список видов номенклатуры с максимальными ценами по ним.

ВЫБРАТЬ
,
МАКСИМУМ(Цены.Цена) КАК Цена
ИЗ

СГРУППИРОВАТЬ ПО
Цены.Номенклатура.ВидНоменклатуры

ИТОГИ

В отличие от группировки при использовании итогов выводятся все записи и уже к ним добавляются итоговые строки. Группировка выводит лишь обобщенные записи.

Итоги можно подводить по всей таблице целиком (с использованием ключевого слова «ОБЩИЕ»), по нескольким полям, по полям с иерархической структурой (ключевые слова «ИЕРАРХИЯ», «ТОЛЬКО ИЕРАРХИЯ»). При подведении итогов не обязательно использовать агрегатные функции.

Рассмотрим пример, аналогичный примеру выше с использованием группировки. В данном случае результат запроса вернет не только сгруппированные поля, но и детальные записи.

ВЫБРАТЬ
Цены.Номенклатура.ВидНоменклатуры КАК ВидНоменклатуры,
Цены.Цена КАК Цена
ИЗ
РегистрСведений.ЦеныНоменклатуры.СрезПоследних КАК Цены
ИТОГИ
МАКСИМУМ(Цена)
ПО
ВидНоменклатуры

ИМЕЮЩИЕ (HAVING)

Данный оператор схож с оператором «ГДЕ», но используется только для агрегатных функций. Остальные поля, кроме используемых этим оператором, должны быть сгруппированы. Оператор «ГДЕ» не применим для агрегатных функций.

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

ВЫБРАТЬ

МАКСИМУМ(Цены.Цена) КАК Цена
ИЗ
РегистрСведений.ЦеныНоменклатуры.СрезПоследних КАК Цены
СГРУППИРОВАТЬ ПО
Цены.Номенклатура.ВидНоменклатуры
ИМЕЮЩИЕ
МАКСИМУМ(Цены.Цена) > 1000

УПОРЯДОЧИТЬ ПО

Оператор «УПОРЯДОЧИТЬ ПО» сортирует результат запроса. Для того, чтобы гарантированно выводить записи в постоянном порядке, используется АВТОУПОРЯДОЧИВАНИЕ. Примитивные типы сортируются по обычным правилам. Ссылочные типы сортируются по GUID.

Пример получения списка сотрудников, отсортированного по наименованию:

ВЫБРАТЬ
Сотрудники.Наименование КАК Наименование
ИЗ
Справочник.Сотрудники КАК Сотрудники
УПОРЯДОЧИТЬ ПО
Наименование
АВТОУПОРЯДОЧИВАНИЕ

Прочие конструкции языка запросов 1С

  • ОБЪЕДИНИТЬ – результаты двух запросов в один.
  • ОБЪЕДИНИТЬ ВСЕ – аналог ОБЪЕДИНИТЬ, но без группировки одинаковых строк.
  • ПУСТАЯ ТАБЛИЦА – иногда используется при объединении запросов для указания пустой вложенной таблицы.
  • ПОМЕСТИТЬ – создает временную таблицу для оптимизации сложных запросов 1С. Такие запросы называются пакетными.

Функции языка запросов

  • ПОДСТРОКА обрезает строку с определенной позиции на указанное количество символов.
  • ГОД…СЕКУНДА позволяют получить выбранное значение числового типа. Входным параметром является дата.
  • НАЧАЛОПЕРИОДА и КОНЕЦПЕРИОДА используются при работе с датами. В качестве дополнительного параметра указывается тип периода (ДЕНЬ, МЕСЯЦ, ГОД и т. п.).
  • ДОБАВИТЬКДАТЕ позволяет прибавить или отнять от даты указанное время определенного типа (СЕКУНДА, МИНУТА, ДЕНЬ и т. п.).
  • РАЗНОСТЬДАТ определяет разницу между двумя датами с указанием типа выходного значения (ДЕНЬ, ГОД, МЕСЯЦ и т. п.).
  • ЕСТЬNULL заменяет отсутствующее значение на указанное выражение.
  • ПРЕДСТАВЛЕНИЕ и ПРЕДСТАВЛЕНИЕССЫЛКИ получают строковое представление указанного поля. Применяются для любых значений и только ссылочных соответственно.
  • ТИП, ТИПЗНАЧЕНИЯ используются для определения типа входного параметра.
  • ССЫЛКА является логическим оператором сравнения для типа значения реквизита.
  • ВЫРАЗИТЬ используется для преобразования значения к нужному типу.
  • ДАТАВРЕМЯ получает значение типа «Дата» из числовых значений (Год, Месяц, День, Час, Минута, Секунда).
  • ЗНАЧЕНИЕ в запросе 1С используется для указания предопределенных значений — справочников, перечислений, планов видов характеристик. Пример использования: «Где ЮрФизЛицо = Значение(Перечисление.ЮрФизЛица.ФизЛицо) «.

Конструктор запросов

Для создания запросов с 1С есть очень удобный встроенный механизм – конструктор запросов. Он содержит следующие основные вкладки:

  • «Таблицы и поля» — содержит поля, которые необходимо выбрать и их источники.
  • «Связи» — описывает условий для конструкции СОЕДИНЕНИЕ.
  • «Группировка» — содержит описание конструкций группировок и суммируемых полей по ним.
  • «Условия» — отвечает за отборы данных в запросе.
  • «Дополнительно» — дополнительные параметры запроса, такие как ключевые слова команды «ВЫБРАТЬ» и пр.
  • «Объединения/Псевдонимы» — указываются возможности объединения таблиц и задаются псевдонимы (конструкция «КАК»).
  • «Порядок» — отвечает за сортировку результата запросов.
  • «Итоги» — аналогична вкладке «Группировка», но применяется для конструкции «ИТОГИ».

Текст самого запроса можно просмотреть, нажав в левом нижнем углу на кнопку «Запрос». В данной форме его можно откорректировать вручную или скопировать.


Консоль запросов

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

Скачать консоль запросов можно на диске ИТС, либо по .

Из базы данных по некоему условию. Для этого в 1С 8.3 необходимо использовать вложенные запросы.

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

Пример вложенного запроса на языке запросов

Приведу пример вложенного запроса на . Допустим, нам нужно сделать выборку суммы некоторого остатка по отдельным клиентам на определенную дату:

ВЫБРАТЬ
НераспОплатыОстатки.Заказчик,
НераспОплатыОстатки.СуммаОст
ИЗ

Получите 267 видеоуроков по 1С бесплатно:

ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления. НераспОплаты.Остатки КАК НераспОплаты
ПО ВложЗапрос.СсылкаНаСпрЗаказчики = НераспОплатыОстатки.Заказчик

Когда СУБД будет выполнять такой запрос, не исключены неверные действия оптимизатора, так как трудно определиться с планом обработки запроса. Когда СУБД соединяет две таблицы, оптимизатор строит алгоритм на основе вычисления количества записей в этих таблицах.

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

Как лучше?

// Временная таблица
ВЫБРАТЬ
Заказчики.Ссылка КАК Заказчики
ПОМЕСТИТЬ табЗаказчики
ИЗ
Справочник.Заказчики КАК Заказчики
ГДЕ Заказчики.Ссылка В (&Заказчики)
;

// Основной запрос
ВЫБРАТЬ
табКлиенты.Ссылка,
НераспОплатыОстатки.СуммаОст,
ИЗ
табЗаказчики КАК табЗаказчики
ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.НераспОплаты.Остатки(
,
Заказчик В
(ВЫБРАТЬ
табЗаказчики.Заказчики
ИЗ
табЗаказчики)) КАК НераспОплатыОстатки
ПО табЗаказчики.Заказчики = НераспОплатыОстатки.Заказчики

Смотрите также видео-урок про вложенные запросы:

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

Если Вы начинаете изучать 1С программирование, рекомендуем наш бесплатный курс (не забудьте

Похожие статьи

  • Xbox не работает, зависает, не включается, тормозит, глючит, выключается

    Что делать, когда Xbox One не включается и не работает, сам отключается и зависает, тормозят игры и появляются ошибки? Наши рекомендации помогут исправить многие неисправности. × При неожиданном возникновении проблем с играми, учетной...

  • Пропал диск "Д" на компьютере: что делать, как его вернуть

    Бывают случаи, при которых нормально включившийся компьютер, после нормального процесса загрузки выдаёт на экран надпись «Операционная система не найдена «. Это может нам сказать лишь о том, что наша ОС не смогла для загрузки обнаружить...

  • Программы для создания скриншотов

    В статье будет разобрана программа для скриншотов с экрана windows 7 и не только. Для блоггера учителя надо давать наглядный и визуальный формат, особенно в моей нише. Для этого просто не обойтись без скриншотов (снимков с экрана). В...

  • Прослушивание мобильного телефона бесплатно

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

  • Таможня не пропускает телефоны Xiaomi с Алиэкспресс

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

  • Лучший вариант — торговля бинарными опционами!

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