Простые запросы Разберем, как изменялся (скорее дополнялся) синтаксис текстов запросов на простом примере: Проводится документ Расходная содержащая в табличной части Товары список продаваемых товаров и количество. При проведении такого документа необходимо обеспечить контроль отрицательных остатков хранящихся в регистре накопления остатков ОстаткиТоваров .
Структура конфигурации представлена на рисунке справа:
Сформируем запрос к табличной части документа и виртуальной таблице Остатки регистра накопления. Учтем возможные дубли строк в документе, для этого произведем группирование записей.
Код 1C v 8.х Процедура ОбработкаПроведения(Отказ, РежимПроведения)
Запрос = Новый Запрос;
Запрос. Текст = "
|ВЫБРАТЬ
| Док.Номенклатура,
| СУММА(Док.Количество) КАК Док_Количество,
| МИНИМУМ(ЕСТЬNULL(Рег.КоличествоОстаток,0)) КАК Рег_Количество
|
|ИЗ
| Документ.Расходная.Товары КАК Док
| ЛЕВОЕ СОЕДИНЕНИЕ
| РегистрНакопления.ОстаткиТоваров.Остатки() КАК Рег
| ПО
| Док.Номенклатура = Рег.Номенклатура
|
|ГДЕ
| Ссылка =Ссылка
|СГРУППИРОВАТЬ ПО Док.Номенклатура" ;
Запрос. УстановитьПараметр( "Ссылка" , Ссылка) ;
РезультатЗапроса = Запрос. Выполнить( ) ;
Выборка = РезультатЗапроса. Выбрать( ) ;
Пока Выборка. Следующий( ) Цикл
КонецЦикла ;
КонецПроцедуры
Естественно приведенный запрос абсолютно не оптимален. С помощью вложенных запросов оптимизируем его: Произведем группирование табличной части документа до соединения с таблицей остатков, в параметры виртуальной таблицы передадим список товаров как значение условия для расчета остатков. В итоге наш запрос примет следующий вид:
Код 1C v 8.х |ВЫБРАТЬ
| Док.Номенклатура,
| Док.Количество КАК Док_Количество,
| ЕСТЬNULL(Рег.КоличествоОстаток,0) КАК Рег_Количество
|
|ИЗ
| (ВЫБРАТЬ
| Номенклатура, СУММА(Количество) КАК Количество
| ИЗ
| Документ.Расходная.Товары
| ГДЕ
| Ссылка =Ссылка
| СГРУППИРОВАТЬ ПО Номенклатура) КАК Док
|
| ЛЕВОЕ СОЕДИНЕНИЕ
| РегистрНакопления.ОстаткиТоваров.Остатки( , Номенклатура В
| (ВЫБРАТЬ РАЗЛИЧНЫЕ
| Номенклатура
| ИЗ
| Документ.Расходная.Товары
| ГДЕ
| Ссылка =Ссылка)) КАК Рег
| ПО
| Док.Номенклатура = Рег.Номенклатура";
Если бы в запросе необходимо было бы получить данные из остатков разных регистров то значение фильтра, а следовательно и наш второй вложенный запрос, повторялся бы во всех параметрах виртуальных таблиц, естественно что система при каждом вложенном запросе заново обращается к базе данных для получения данных.
Временные таблицы Не помню уже с какого релиза в запросах стало можно использовать временные таблицы. Для этого используется объект «Менеджер временных таблиц». Фактически менеджер временных таблиц описывает пространство имен временных таблиц и отвечает за их создание и уничтожение в базе данных.
Сами временные таблицы действительно физически создаются в базе, соответственно следует относиться к ним осторожно, так как дисковая подсистема на сегодняшний момент самая медленная часть техники, а скорость создания и уничтожения таблиц напрямую от нее зависит.
Перепишем запрос для использования временных таблиц. Во временные таблицы поместим сгруппированную табличную часть документа и список товаров для фильтра виртуальных таблиц:
Код 1C v 8.х Процедура ОбработкаПроведения(Отказ, РежимПроведения)
МВТ = Новый МенеджерВременныхТаблиц;
Запрос = Новый Запрос;
Запрос. МенеджерВременныхТаблиц = МВТ;
Запрос. Текст = "
|ВЫБРАТЬ
| Номенклатура, СУММА(Количество) КАК Количество
|ПОМЕСТИТЬ ДокТЧ
|ИЗ
| Документ.Расходная.Товары
|ГДЕ
| Ссылка =Ссылка
|СГРУППИРОВАТЬ ПО Номенклатура" ;
Запрос. УстановитьПараметр( "Ссылка" , Ссылка) ;
РезультатЗапроса = Запрос. Выполнить( ) ;
Запрос = Новый Запрос;
Запрос. МенеджерВременныхТаблиц = МВТ;
Запрос. Текст = "ВЫБРАТЬ РАЗЛИЧНЫЕ
| Номенклатура
|ПОМЕСТИТЬ СписокТоваров
|ИЗ
| Документ.Расходная.Товары
|ГДЕ
| Ссылка =Ссылка" ;
Запрос. УстановитьПараметр( "Ссылка" , Ссылка) ;
РезультатЗапроса = Запрос. Выполнить( ) ;
Запрос = Новый Запрос;
Запрос. МенеджерВременныхТаблиц = МВТ;
Запрос. Текст = "
|ВЫБРАТЬ
| Док.Номенклатура,
| Док.Количество КАК Док_Количество,
| ЕСТЬNULL(Рег.КоличествоОстаток,0) КАК Рег_Количество
|ИЗ
| ДокТЧ КАК Док
| ЛЕВОЕ СОЕДИНЕНИЕ
| РегистрНакопления.ОстаткиТоваров.Остатки(,
| Номенклатура В(ВЫБРАТЬ РАЗЛИЧНЫЕ
| Номенклатура
| ИЗ
| СписокТоваров КАК СписокТоваров)) КАК Рег
| ПО
| Док.Номенклатура = Рег.Номенклатура" ;
РезультатЗапроса = Запрос. Выполнить( ) ;
Выборка = РезультатЗапроса. Выбрать( ) ;
Пока Выборка. Следующий( ) Цикл
КонецЦикла ;
КонецПроцедуры
При использовании временных таблиц в тексте запроса применяют инструкцию Поместить для создания новой временной таблицы, в этом случае в результат запроса система передает не содержимое этой таблицы (см прим 1 и прим 2 в тексте выше), а количество записей помещенных во временную таблицу, по желанию можно не принимать это значение.
Также допускается использование инструкции Уничтожить в этом случае временная таблица уничтожается, в противном случае временные таблицы уничтожаются вместе с объектом менеджер временных таблиц.
В основном нашем запросе я использовал названия временных таблиц как указание на источник получения данных (им обязательно надо назначать синоним, что мы и видим в тексте). Использовать временные таблицы как источник можно не единожды, что при умелом их применении позволит и сократить текст запроса (улучшиться читабельность сложных запросов) и увеличить скорость (при использовании данных временной таблицы в нескольких местах запроса).
Пакетные запросы Пакетные запросы логично дополняют функционал временных таблиц и дают больше возможностей при работе с запросами.
В пакетном запросе фактически можно описать несколько запросов, как связанных между собой использованием временных таблиц, так и не связанных (можно, но не понятно зачем?). В итоге можно выполнить последовательно все запросы и принять в результате либо массив с результатами исполнения каждого запроса, либо результат последнего. Для получения массива с результатами запроса применяют метод ВыполнитьПакет() объекта запрос, а для получения результата последнего запроса ВыполнитьЗапрос().
В тексте запроса, запросы пакета разделяются символом «;» (точка с запятой). Область имен виртуальных таблиц у одного пакетного запроса одна. Использование менеджера временных таблиц не требуется, но возможно если вы хотите передать временные таблицы из одного пакетного запроса в другой.
Перепишем процедуру для использования пакетных запросов:
Код 1C v 8.х Процедура ОбработкаПроведения(Отказ, РежимПроведения)
Запрос = Новый Запрос;
Запрос. Текст = "
|ВЫБРАТЬ
| Номенклатура, СУММА(Количество) КАК Количество
|ПОМЕСТИТЬ ДокТЧ
|ИЗ
| Документ.Расходная.Товары
|ГДЕ
| Ссылка =Ссылка
|СГРУППИРОВАТЬ ПО Номенклатура
|;
|
|ВЫБРАТЬ РАЗЛИЧНЫЕ
| Номенклатура
|ПОМЕСТИТЬ СписокТоваров
|ИЗ
| Документ.Расходная.Товары
|ГДЕ
| Ссылка =Ссылка
|;
|
|ВЫБРАТЬ
| Док.Номенклатура,
| Док.Количество КАК Док_Количество,
| ЕСТЬNULL(Рег.КоличествоОстаток,0) КАК Рег_Количество
|ИЗ
| ДокТЧ КАК Док
| ЛЕВОЕ СОЕДИНЕНИЕ
| РегистрНакопления.ОстаткиТоваров.Остатки(,
| Номенклатура В(ВЫБРАТЬ РАЗЛИЧНЫЕ
| Номенклатура
| ИЗ
| СписокТоваров КАК СписокТоваров)) КАК Рег
| ПО
| Док.Номенклатура = Рег.Номенклатура" ;
Запрос. УстановитьПараметр( "Ссылка" , Ссылка) ;
МассивРезультаттов = Запрос. ВыполнитьПакет( ) ;
РезультатЗапроса = Запрос. Выполнить( ) ;
Выборка = РезультатЗапроса. Выбрать( ) ;
Пока Выборка. Следующий( ) Цикл
КонецЦикла ;
КонецПроцедуры
Фактически я убрал определение объекта запрос и использование менеджера временных таблиц, объединил тексты запросов (обратите внимание на разделитель «;» между текстами). В результате текст запроса стал читабельнее (а при использовании конструктора запросов намного увеличивается удобство чтения запроса).
После выполнения запроса в переменную МассивРезультатов у нас попадет 3 элемента. Первые два будут содержать число характеризующее количество записей помещенных во временные таблицы ДокТЧ и СписокТоваров , а третий будет содержать выборку с полями Номенклатура, Док_Количество и Рег_Количество .
В переменную РезультатЗапроса попадет только выборка.
Ну вот и все что касается пакетных запросов. Очень удобный механизм и с точки зрения написания запросов и с точки зрения чтения сложных запросов.
Автор: Павел Чистов
Обработка демонстрирует возможности интеграции 1С с картографическими сервисами, в ней поддерживается работа трех поставщиков услуг / карт — Яндекс, Google. Рамблер.
Автор: Діма Головаченко - http://smaylukk.com.ua
но так вот сама обработка + еще 2 :
Скачивать файлы может только зарегистрированный пользователь!
Код Модуля Обработки:
Код 1C v 8.х Перем СтруктураПоставщиковКарт Экспорт ;
Перем СтруктураЧисел;
Функция СформироватьСтрокуJSONИзМассива(Объект)
СтрокаJSON = "[" ;
Для каждого Элемент Из Объект Цикл
СтрокаJSON = СтрокаJSON + СформироватьСтрокуJSON( Элемент) + "," ;
КонецЦикла ;
Если Прав( СтрокаJSON, 1 ) = "," Тогда
СтрокаJSON = Лев( СтрокаJSON, СтрДлина( СтрокаJSON) - 1 ) ;
КонецЕсли ;
Возврат СтрокаJSON + "]" ;
КонецФункции
Функция СформироватьСтрокуJSONИзСтруктуры(Объект)
СтрокаJSON = "{" ;
Для каждого Элемент Из Объект Цикл
Если Элемент. Значение = "" Тогда
Продолжить;
КонецЕсли ;
СтрокаJSON = СтрокаJSON + """ " + Элемент. Ключ + """ " + ":" ;
Если ТипЗнч( Элемент. Значение) = Тип( "Строка" ) Тогда
СтрокаJSON = СтрокаJSON + """ " + URLEncode( Элемент. Значение) + """ " ;
ИначеЕсли ТипЗнч( Элемент. Значение) = Тип( "Число" ) Тогда
СтрокаJSON = СтрокаJSON + СтрЗаменить( Строка( Элемент. Значение) , Символы. НПП, "" ) ;
ИначеЕсли ТипЗнч( Элемент. Значение) = Тип( "Булево" ) Тогда
СтрокаJSON = СтрокаJSON + Формат( Элемент. Значение, "БЛ=false; БИ=true" ) ;
ИначеЕсли ТипЗнч( Элемент. Значение) = Тип( "Дата" ) Тогда
СтрокаJSON = СтрокаJSON + Формат( ТекущаяДата( ) - Дата( 1970 , 1 , 1 , 1 , 0 , 0 ) , "ЧГ=0" ) ;
ИначеЕсли ТипЗнч( Элемент. Значение) = Тип( "Массив" ) Тогда
СтрокаJSON = СтрокаJSON + СформироватьСтрокуJSON( Элемент. Значение) ;
ИначеЕсли ТипЗнч( Элемент. Значение) = Тип( "Структура" ) Тогда
СтрокаJSON = СтрокаJSON + СформироватьСтрокуJSON( Элемент. Значение) ;
ИначеЕсли ТипЗнч( Элемент. Значение) = Тип( "ТаблицаЗначений" ) Тогда
СтрокаJSON = СтрокаJSON + СформироватьСтрокуJSON( Элемент. Значение) ;
Иначе
СтрокаJSON = СтрокаJSON + """ " + URLEncode( Строка( Элемент. Значение) ) + """ " ;
КонецЕсли ;
СтрокаJSON = СтрокаJSON + "," ;
КонецЦикла ;
Если Прав( СтрокаJSON, 1 ) = "," Тогда
СтрокаJSON = Лев( СтрокаJSON, СтрДлина( СтрокаJSON) - 1 ) ;
КонецЕсли ;
Возврат СтрокаJSON + "}" ;
КонецФункции
Функция СформироватьСтрокуJSON(Объект) Экспорт
СтрокаJSON = "" ;
Если ТипЗнч( Объект) = Тип( "Массив" ) Тогда
СтрокаJSON = СформироватьСтрокуJSONИзМассива( Объект) ;
ИначеЕсли ТипЗнч( Объект) = Тип( "Структура" ) Тогда
СтрокаJSON = СформироватьСтрокуJSONИзСтруктуры( Объект) ;
ИначеЕсли ТипЗнч( Объект) = Тип( "ТаблицаЗначений" ) Тогда
СоставСтруктуры = "" ;
Для каждого Колонка Из Объект. Колонки Цикл
СоставСтруктуры = СоставСтруктуры + ? ( ЗначениеЗаполнено( СоставСтруктуры) , "," , "" ) + Колонка. Имя;
КонецЦикла ;
МассивСтрок = Новый Массив;
Для каждого Строка Из Объект Цикл
СтруктураКолонок = Новый Структура( СоставСтруктуры) ;
ЗаполнитьЗначенияСвойств( СтруктураКолонок, Строка) ;
МассивСтрок. Добавить( СтруктураКолонок) ;
КонецЦикла ;
СтрокаJSON = СформироватьСтрокуJSONИзМассива( МассивСтрок) ;
КонецЕсли ;
Возврат СтрокаJSON;
КонецФункции
Процедура ЗаполнитьДанныеИзОтветаJSON(Результат, ТекстJSON, ТипДанных)
ТекстJSON = СокрЛП( Сред( ТекстJSON, 2 ) ) ;
НомерЗначения = 0 ;
Пока ТекстJSON < > "" Цикл
ПервыйСимвол = Лев( ТекстJSON, 1 ) ;
Если ПервыйСимвол = "{" Тогда
Значение = Новый Структура;
ЗаполнитьДанныеИзОтветаJSON( Значение, ТекстJSON, "Структура" ) ;
Если ТипДанных = "Структура" Тогда
Результат. Вставить( "Значение" + ? ( НомерЗначения = 0 , "" , НомерЗначения) , Значение) ;
НомерЗначения = НомерЗначения + 1 ;
ИначеЕсли ТипДанных = "Массив" Тогда
Результат. Добавить( Значение) ;
КонецЕсли ;
ИначеЕсли ПервыйСимвол = "[" Тогда
Значение = Новый Массив;
ЗаполнитьДанныеИзОтветаJSON( Значение, ТекстJSON, "Массив" ) ;
Если ТипДанных = "Структура" Тогда
Результат. Вставить( "Значение" + ? ( НомерЗначения = 0 , "" , НомерЗначения) , Значение) ;
НомерЗначения = НомерЗначения + 1 ;
Иначе
Результат. Добавить( Значение) ;
КонецЕсли ;
ИначеЕсли ПервыйСимвол = "}" И ТипДанных = "Структура" Тогда
ТекстJSON = СокрЛП( Сред( ТекстJSON, 2 ) ) ;
Если Лев( ТекстJSON, 1 ) = "," Тогда
ТекстJSON = СокрЛП( Сред( ТекстJSON, 2 ) ) ;
КонецЕсли ;
Возврат ;
ИначеЕсли ПервыйСимвол = "]" И ТипДанных = "Массив" Тогда
ТекстJSON = СокрЛП( Сред( ТекстJSON, 2 ) ) ;
Если Лев( ТекстJSON, 1 ) = "," Тогда
ТекстJSON = СокрЛП( Сред( ТекстJSON, 2 ) ) ;
КонецЕсли ;
Возврат ;
Иначе
Если ТипДанных = "Структура" Тогда
Поз = Найти( ТекстJSON, ":" ) ;
Если Поз = 0 Тогда
Прервать ;
КонецЕсли ;
ИмяЗначения = СокрЛП( Лев( ТекстJSON, Поз - 1 ) ) ;
ИмяЗначения = СтрЗаменить( ИмяЗначения, """ " , "" ) ;
ТекстJSON = СокрЛП( Сред( ТекстJSON, Поз+ 1 ) ) ;
Если Лев( ТекстJSON, 1 ) = "{" Тогда
Значение = Новый Структура;
ЗаполнитьДанныеИзОтветаJSON( Значение, ТекстJSON, "Структура" ) ;
ИначеЕсли Лев( ТекстJSON, 1 ) = "[" Тогда
Значение = Новый Массив;
ЗаполнитьДанныеИзОтветаJSON( Значение, ТекстJSON, "Массив" ) ;
Иначе
ПервыйКавычка = Ложь ;
ПредпоследнийКавычка = Ложь ;
Поз = 0 ;
Для Сч = 1 По СтрДлина( ТекстJSON) Цикл
Символ = Сред( ТекстJSON, Сч, 1 ) ;
Если Символ = """ " Тогда
Если ПервыйКавычка Тогда
ПредпоследнийКавычка = Истина ;
Иначе
ПервыйКавычка = Истина ;
КонецЕсли ;
КонецЕсли ;
Если ( Символ = "," И ( ( ПервыйКавычка И ПредпоследнийКавычка) Или ( Не ПервыйКавычка И Не ПредпоследнийКавычка) ) ) ИЛИ Символ = "]" ИЛИ Символ = "}" Тогда
Поз = Сч;
Прервать ;
КонецЕсли ;
КонецЦикла ;
Если Поз = 0 Тогда
Значение = ТекстJSON;
ТекстJSON = "" ;
Иначе
Значение = Лев( ТекстJSON, Поз - 1 ) ;
Значение = СтрЗаменить( Значение, """ " , "" ) ;
ТекстJSON = СокрЛП( Сред( ТекстJSON, Поз + ? ( Сред( ТекстJSON, Поз, 1 ) = "," , 1 , 0 ) ) ) ;
КонецЕсли ;
Значение = СокрЛП( Значение) ;
КонецЕсли ;
Результат. Вставить( ИмяЗначения, Значение) ;
ИначеЕсли ТипДанных = "Массив" Тогда
Поз = 0 ;
Для Сч = 1 По СтрДлина( ТекстJSON) Цикл
Символ = Сред( ТекстJSON, Сч, 1 ) ;
Если Символ = "," ИЛИ Символ = "]" ИЛИ Символ = "}" Тогда
Поз = Сч;
Прервать ;
КонецЕсли ;
КонецЦикла ;
Если Поз = 0 Тогда
Значение = ТекстJSON;
ТекстJSON = "" ;
Иначе
Значение = Лев( ТекстJSON, Поз - 1 ) ;
Значение = СтрЗаменить( Значение, """ " , "" ) ;
ТекстJSON = СокрЛП( Сред( ТекстJSON, Поз + ? ( Сред( ТекстJSON, Поз, 1 ) = "," , 1 , 0 ) ) ) ;
КонецЕсли ;
Значение = СокрЛП( Значение) ;
Результат. Добавить( Значение) ;
КонецЕсли ;
КонецЕсли ;
КонецЦикла ;
КонецПроцедуры
Функция ЗаполнитьСтруктуруИзОтветаJSON(Знач ТекстJSON) Экспорт
Результат = Новый Структура;
ТекстJSON = СтрЗаменить( ТекстJSON, "\"" " , """ " ) ;
Если Лев( ТекстJSON, 1 ) = "{" Тогда
ЗаполнитьДанныеИзОтветаJSON( Результат, ТекстJSON, "Структура" ) ;
ИначеЕсли Лев( ТекстJSON, 1 ) = "[" Тогда
МассивДанных = Новый Массив;
ЗаполнитьДанныеИзОтветаJSON( МассивДанных, ТекстJSON, "Массив" ) ;
Результат. Вставить( "Значение" , МассивДанных) ;
КонецЕсли ;
Возврат Результат;
КонецФункции
Функция КодСимволаASCII(Символ)
КодUNICODE = КодСимвола( Символ) ;
Если ( ( КодUNICODE > 1039 ) И ( КодUNICODE < 1104 ) ) Тогда
Возврат ( КодUNICODE - 848 ) ;
ИначеЕсли КодUNICODE = 8470 Тогда
Возврат 185 ;
ИначеЕсли КодUNICODE = 1105 Тогда
Возврат 184 ;
ИначеЕсли КодUNICODE = 1025 Тогда
Возврат 168 ;
Иначе
Возврат КодUNICODE;
КонецЕсли ;
КонецФункции
Функция URLEncode(value)
table = "%00%01%02%03%04%05%06%07%08%09%0A%0B%0C%0D%0E%0F%10%11%12%13%14" +
"%15%16%17%18%19%1A%1B%1C%1D%1E%1F%20%21%22%23%24%25%26%27%28" +
"%29%2A%2B%2C%2D%2E%2F%30%31%32%33%34%35%36%37%38%39%3A%3B%3C" +
"%3D%3E%3F%40%41%42%43%44%45%46%47%48%49%4A%4B%4C%4D%4E%4F%50" +
"%51%52%53%54%55%56%57%58%59%5A%5B%5C%5D%5E%5F%60%61%62%63%64" +
"%65%66%67%68%69%6A%6B%6C%6D%6E%6F%70%71%72%73%74%75%76%77%78" +
"%79%7A%7B%7C%7D%7E%7F%80%81%82%83%84%85%86%87%88%89%8A%8B%8C" +
"%8D%8E%8F%90%91%92%93%94%95%96%97%98%99%9A%9B%9C%9D%9E%9F%A0" +
"%A1%A2%A3%A4%A5%A6%A7%A8%A9%AA%AB%AC%AD%AE%AF%B0%B1%B2%B3%B4" +
"%B5%B6%B7%B8%B9%BA%BB%BC%BD%BE%BF%C0%C1%C2%C3%C4%C5%C6%C7%C8" +
"%C9%CA%CB%CC%CD%CE%CF%D0%D1%D2%D3%D4%D5%D6%D7%D8%D9%DA%DB%DC" +
"%DD%DE%DF%E0%E1%E2%E3%E4%E5%E6%E7%E8%E9%EA%EB%EC%ED%EE%EF%F0" +
"%F1%F2%F3%F4%F5%F6%F7%F8%F9%FA%FB%FC%FD%FE%FF" ;
result = "" ;
length = СтрДлина( value ) ;
Для i = 1 По length Цикл
symbol = Сред( value, i, 1 ) ;
code = КодСимволаASCII( symbol ) ;
result = result + Сред( table, code* 3 + 1 , 3 ) ;
КонецЦикла ;
Возврат result;
КонецФункции
Функция UnicodeEncode(Строка) Экспорт
Результат = Истина ;
Попытка
Рег = Новый COMОбъект( "VBScript.RegExp" ) ;
Рег. IgnoreCase = Истина ;
Рег. Global = Истина ;
Рег. Multiline = Ложь ;
Рег. Pattern = "u[0-9a-f]+" ;
Колекция = Рег. Execute( Строка) ;
Для Каждого Элемент Из Колекция Цикл
Если СтрДЛина( Элемент. value) = 1 Тогда
Продолжить;
КонецЕсли ;
КодСимвола = ПереводЧислаИз16 в10 ( Сред( ВРег( Элемент. value) , 2 ) ) ;
Символ = Символ( КодСимвола) ;
Строка = СтрЗаменить( Строка, "\" + Элемент. value, Символ) ;
КонецЦикла ;
Исключение
Результат = Ложь ;
Сообщить( "Ошибка преобразования из Unicode" , СтатусСообщения. Информация) ;
КонецПопытки ;
Возврат Результат;
КонецФункции
Функция ПереводЧислаИз16в10(Знач Значение)
Результат = 0 ;
Если ТипЗнч( Значение) < > Тип( "Строка" ) Тогда
Значение = СокрЛП( Строка( Значение) ) ;
КонецЕсли ;
МаксРазрядЦелых = 0 ;
МаксРазрядЦелых = СтрДлина( Значение) - 1 ;
н = МаксРазрядЦелых;
Ин = 1 ;
Пока н > = 0 Цикл
ТекЗначение = СтруктураЧисел. Получить( Сред( Значение, Ин, 1 ) ) * Pow( 16 , н) ;
Результат = Результат + ТекЗначение;
н = н - 1 ;
Ин = Ин + 1 ;
КонецЦикла ;
Возврат Результат;
КонецФункции
СтруктураПоставщиковКарт = Новый Соответствие;
СтруктураПоставщиковКарт. Вставить( 0 , "Яндекс" ) ;
СтруктураПоставщиковКарт. Вставить( 1 , "Гугл" ) ;
СтруктураПоставщиковКарт. Вставить( 2 , "2ГИС" ) ;
СтруктураПоставщиковКарт. Вставить( 3 , "Рамблер" ) ;
СтруктураЧисел = Новый Соответствие;
СтруктураЧисел. Вставить( "0" , 0 ) ;
СтруктураЧисел. Вставить( "1" , 1 ) ;
СтруктураЧисел. Вставить( "2" , 2 ) ;
СтруктураЧисел. Вставить( "3" , 3 ) ;
СтруктураЧисел. Вставить( "4" , 4 ) ;
СтруктураЧисел. Вставить( "5" , 5 ) ;
СтруктураЧисел. Вставить( "6" , 6 ) ;
СтруктураЧисел. Вставить( "7" , 7 ) ;
СтруктураЧисел. Вставить( "8" , 8 ) ;
СтруктураЧисел. Вставить( "9" , 9 ) ;
СтруктураЧисел. Вставить( "A" , 10 ) ;
СтруктураЧисел. Вставить( "B" , 11 ) ;
СтруктураЧисел. Вставить( "C" , 12 ) ;
СтруктураЧисел. Вставить( "D" , 13 ) ;
СтруктураЧисел. Вставить( "E" , 14 ) ;
СтруктураЧисел. Вставить( "F" , 15 ) ;
Код Формы Управляемой:
Код 1C v 8.2 УП
&НаКлиенте
Процедура НайтиАдрес(Команда)
НайтиАдресНаКарте(ТекАдрес);
КонецПроцедуры
&НаКлиенте
Процедура ИнициализацияКарты(Команда)
ИнициализироватьКарту();
КонецПроцедуры
&НаКлиенте
Процедура СправочнаяИнформация(Команда)
Элементы.ГруппаСправка.Видимость = Не Элементы.ГруппаСправка.Видимость;
КонецПроцедуры
&НаКлиенте
Процедура Разработчик(Команда)
ЗапуститьПриложение("http://smaylukk.com.ua/?lang=Ru");
КонецПроцедуры
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
Объект.ТипКарты = Параметры.ТипКарты;
ТекОбъект = РеквизитФормыВЗначение("Объект");
Поставщик = ТекОбъект.СтруктураПоставщиковКарт.Получить(Объект.ТипКарты);
Макет = ТекОбъект.ПолучитьМакет("Справка");
ТекстСправки = Макет.ПолучитьОбласть("Справка" + Поставщик).Область().Текст;
Справка = ТекстСправки;
КонецПроцедуры
&НаКлиенте
Процедура ПриОткрытии(Отказ)
Элементы.ГруппаСправка.Видимость = Ложь;
Заголовок = "Работа с картами. Поставщик - " + Поставщик;
ИнициализироватьКарту();
КонецПроцедуры
&НаКлиенте
Процедура ПриЗакрытии()
//удаление временных файлов
Для Каждого ТекЭлемент Из МассивВременныхФайлов Цикл
УдалитьФайлы(ТекЭлемент.Значение);
КонецЦикла;
КонецПроцедуры
&НаКлиенте
//Процедура составляет имя процедуры поставщика
// и запускает ее на исполнение
//Параметры:
// НачалоИмени - Строка
Процедура ВыполнитьПроцедуруПоставщика(ИмяПроцедуры)
Выполнить ИмяПроцедуры;
КонецПроцедуры
&НаКлиенте
//процедура инициализирует карту постащика из макета
Процедура ИнициализироватьКарту()
Текст = ПолучитьТекстМакета("Макет" + Поставщик);
Эксплорер = Текст;
КонецПроцедуры
&НаСервере
Функция ПолучитьТекстМакета(ИмяМакета)
Макет = РеквизитФормыВЗначение("Объект").ПолучитьМакет(ИмяМакета);
Результат = Макет.ПолучитьТекст();
Возврат Результат;
КонецФункции
&НаКлиенте
Процедура ОчисткаКарты()
Элементы.Эксплорер.document.getElementById("WebClientOperation").value = "Reset()";
Элементы.Эксплорер.document.getElementById("WebClient").click();
КонецПроцедуры
///////////////////////////////////////////////////////////////////////
///////////////////ГЕОКОДИРОВАНИЕ И ПОИСК АДРЕСА///////////////////////
///////////////////////////////////////////////////////////////////////
&НаКлиенте
Процедура НайтиАдресНаКарте(Адрес = "")
//поиск адреса
Если Адрес = "" Тогда
Адрес = "Москва";
КонецЕсли;
// дальше пробуем с помощью геокодинга вывести данные поиска в таблицу
ТаблицаАдресов.Очистить();
ПоискАдреса(Адрес);
Если Поставщик = "Яндекс" Тогда
ПроизвестиГеокодинг_Яндекс();
ИначеЕсли Поставщик = "Гугл" Тогда
ПроизвестиГеокодинг_Гугл();
ИначеЕсли Поставщик = "Рамблер" Тогда
ПроизвестиГеокодинг_Рамблер();
КонецЕсли;
КонецПроцедуры
&НаКлиенте
Процедура ПоискАдреса(Адрес)
Элементы.Эксплорер.document.getElementById("WebClientOperation").value = "FindAdres(""" + Адрес + """);";
Элементы.Эксплорер.document.getElementById("WebClient").click();
КонецПроцедуры
&НаСервере
//Процедура выводит в таблицу данные геокдинга Яндекса
//
//Параметры:
// ТекАдрес - Строка
Процедура ПроизвестиГеокодинг_Яндекс()
Яндекс = Новый HTTPСоединение("geocode-maps.yandex.ru");
ВременныйФайл = КаталогВременныхФайлов() + "Yandex_geocode_" + СокрЛП(Новый УникальныйИдентификатор);
Попытка
Яндекс.Получить("/1.x/?geocode=" + ТекАдрес + "&results=10", ВременныйФайл);
Исключение
Сообщить("Ошибка при попытке геокодировать по яндексу адрес: " + ТекАдрес);
Сообщить(ОписаниеОшибки());
Возврат;
КонецПопытки;
ЧтениеXML = Новый ЧтениеXML;
ЧтениеXML.ОткрытьФайл(ВременныйФайл);
ПостроительDOM = Новый ПостроительDOM;
ДокументДОМ = ПостроительDOM.Прочитать(ЧтениеXML);
СписокText = ДокументДОМ.ПолучитьЭлементыПоИмени("text");
СписокPos = ДокументДОМ.ПолучитьЭлементыПоИмени("pos");
Если (СписокText.Количество() = 0) ИЛИ (СписокPos.Количество() = 0) Тогда
Возврат;
КонецЕсли;
Для ъ = 0 по СписокText.Количество()-1 Цикл
Координаты = СписокPos[Ъ].ТекстовоеСодержимое;
Разделитель = Найти(Координаты," ");
Широта = Число(Сред(Координаты, Разделитель + 1));
Долгота = Число(Лев(Координаты, Разделитель - 1));
Если Широта = 0 ИЛИ Долгота = 0 Тогда
Продолжить;
КонецЕсли;
стрАдрес = ТаблицаАдресов.Добавить();
Если СписокText.Количество() > ъ Тогда
стрАдрес.Адрес = СписокText[Ъ].ТекстовоеСодержимое;
стрАдрес.Широта = Широта;
стрАдрес.Долгота = Долгота;
КонецЕсли;
КонецЦикла;
МассивВременныхФайлов.Добавить(ВременныйФайл);
КонецПроцедуры
&НаСервере
//Процедура выводит в таблицу данные геокдинга Гугл
//
//Параметры:
// ТекАдрес - Строка
Процедура ПроизвестиГеокодинг_Гугл()
Гугл = Новый HTTPСоединение("maps.googleapis.com");
ВременныйФайл = КаталогВременныхФайлов() + "Google_geocode_" + СокрЛП(Новый УникальныйИдентификатор);
Попытка
Гугл.Получить("/maps/api/geocode/xml?address=" + ТекАдрес + "&language=ru&sensor=false", ВременныйФайл);
Исключение
Сообщить("Ошибка при попытке геокодировать по Google адрес: " + ТекАдрес);
Сообщить(ОписаниеОшибки());
Возврат;
КонецПопытки;
ЧтениеXML = Новый ЧтениеXML;
ЧтениеXML.ОткрытьФайл(ВременныйФайл);
ПостроительDOM = Новый ПостроительDOM;
ДокументДОМ = ПостроительDOM.Прочитать(ЧтениеXML);
ТаблицаРезультатов = ДокументДОМ.ПолучитьЭлементыПоИмени("result");
Если ДокументДОМ.ПолучитьЭлементыПоИмени("status")[0].ТекстовоеСодержимое <> "OK" ИЛИ ТаблицаРезультатов.Количество() = 0 Тогда
Возврат;
КонецЕсли;
Для ТекРезультат = 0 по ТаблицаРезультатов.Количество() -1 Цикл
СписокText = ТаблицаРезультатов[ТекРезультат].ПолучитьЭлементыПоИмени("formatted_address");
ЭлементыШиротаДолгота = ТаблицаРезультатов[ТекРезультат].ПолучитьЭлементыПоИмени("location");
Широта = ЭлементыШиротаДолгота[0].ПолучитьЭлементыПоИмени("lat")[0].ТекстовоеСодержимое;
Долгота = ЭлементыШиротаДолгота[0].ПолучитьЭлементыПоИмени("lng")[0].ТекстовоеСодержимое;
Если Широта = 0 ИЛИ Долгота = 0 Тогда
Продолжить;
КонецЕсли;
стрАдрес = ТаблицаАдресов.Добавить();
стрАдрес.Широта = Широта;
стрАдрес.Долгота = Долгота;
стрАдрес.Адрес = СписокText[0].ТекстовоеСодержимое;
КонецЦикла;
МассивВременныхФайлов.Добавить(ВременныйФайл);
КонецПроцедуры
&НаСервере
//Процедура выводит в таблицу данные геокдинга Рамблер
//
//Параметры:
// ТекАдрес - Строка
Процедура ПроизвестиГеокодинг_Рамблер()
ТемпАдрес = СтрЗаменить(ТекАдрес, " ", "+");
Рамблер = Новый HTTPСоединение("maps.rambler.ru");
ВременныйФайл = КаталогВременныхФайлов() + "Рамблер_geocode_" + СокрЛП(Новый УникальныйИдентификатор);
Попытка
Рамблер.Получить("/search/?&a=search&q=" + ТемпАдрес + "&n=10", ВременныйФайл);
Исключение
Сообщить("Ошибка при попытке геокодировать по Рамблер адрес: " + ТекАдрес);
Сообщить(ОписаниеОшибки());
Возврат;
КонецПопытки;
а = 1;
Т = Новый ТекстовыйДокумент;
Т.Прочитать(ВременныйФайл);
СтрокаОтвет = Т.ПолучитьТекст();
Результат = РеквизитФормыВЗначение("Объект").UnicodeEncode(СтрокаОтвет);
Если Результат Тогда
СтруктураJSON = РеквизитФормыВЗначение("Объект").ЗаполнитьСтруктуруИзОтветаJSON(СтрокаОтвет);
КонецЕсли;
МассивРезультатов = СтруктураJSON.res;
//обрабатываем элементы массива - только адреса. POI можно обработать отдельно пожеланию
Для Каждого Результат Из МассивРезультатов Цикл
Для Каждого ТекРезультат Из Результат.matches Цикл
стрАдрес = ТаблицаАдресов.Добавить();
стрАдрес.Долгота = Число(ТекРезультат.x);
стрАдрес.Широта = Число(ТекРезультат.y);
Если Результат.type = "addr" Тогда //Результат.type = "poi" - содержит в себе список точек интереса
стрАдрес.Адрес = ТекРезультат.addr;
Иначе
стрАдрес.Адрес = ТекРезультат.name + " - " + ТекРезультат.addr;
КонецЕсли;
КонецЦикла;
КонецЦикла;
МассивВременныхФайлов.Добавить(ВременныйФайл);
КонецПроцедуры
&НаКлиенте
Процедура ОбратнПоискАдреса(Широта, Долгота, Адрес)
Элементы.Эксплорер.document.getElementById("WebClientOperation").value = "ReverseSearchAdres(" + Широта + "," + Долгота + ", """ + Адрес + """);";
Элементы.Эксплорер.document.getElementById("WebClient").click();
КонецПроцедуры
&НаКлиенте
Процедура ТаблицаАдресовВыбор(Элемент, ВыбраннаяСтрока, Поле, СтандартнаяОбработка)
Если ЗначениеЗаполнено(ТаблицаАдресов[ВыбраннаяСтрока].Широта) И ЗначениеЗаполнено(ТаблицаАдресов[ВыбраннаяСтрока].Долгота) Тогда
СтандартнаяОбработка = Ложь;
КонецЕсли;
Широта = Формат(ТаблицаАдресов[ВыбраннаяСтрока].Широта, "ЧЦ=10; ЧДЦ=7; ЧРД=.; ЧРГ=");
Долгота = Формат(ТаблицаАдресов[ВыбраннаяСтрока].Долгота, "ЧЦ=10; ЧДЦ=7; ЧРД=.; ЧРГ=");
ОбратнПоискАдреса(Широта, Долгота, ТаблицаАдресов[ВыбраннаяСтрока].Адрес);
КонецПроцедуры
&НаКлиенте
Процедура ТекАдресПриИзменении(Элемент)
НайтиАдресНаКарте(ТекАдрес);
КонецПроцедуры
///////////////////////////////////////////////////////////////////////
///////////////////МАРШРУТИЗАЦИЯ, КЛАСТЕРА И ПОЛИГОН///////////////////////////////////////
///////////////////////////////////////////////////////////////////////
&НаКлиенте
Процедура ЭксплорерПриНажатии(Элемент, ДанныеСобытия, СтандартнаяОбработка)
ПолучитьКоординаты();
КонецПроцедуры
&НаКлиенте
Процедура ПостроитьМаршрут(Команда)
Если ТаблицаТочек.Количество() <= 1 Тогда
Предупреждение("Недостаточно точек для построение маршрута!");
Возврат;
КонецЕсли;
Если Поставщик = "Яндекс" Тогда
ПостроитьМаршрут_Яндекс();
ИначеЕсли Поставщик = "Гугл" Тогда
ПостроитьМаршрут_Гугл();
ИначеЕсли Поставщик = "Рамблер" Тогда
ПостроитьМаршрут_Рамблер();
КонецЕсли;
КонецПроцедуры
&НаКлиенте
//Процедура выстраивает маршрут для Яндекса
//
//Параметры:
//
Процедура ПостроитьМаршрут_Яндекс()
ПараметрыМаршрута = ПолучитьПараметрыМаршрутаЯндекс();
ОчисткаКарты();
Элементы.Эксплорер.document.getElementById("WebClientOperation").value = "calcRoute(" + ПараметрыМаршрута + ")";
Элементы.Эксплорер.document.getElementById("WebClient").click();
КонецПроцедуры
&НаКлиенте
//Функция получает массив точек, для передачи параметров в Яндекс
//
//Параметры:
//
//Возвращаемое значение:
// Строка
Функция ПолучитьПараметрыМаршрутаЯндекс()
Результат = "";
Результат = Результат + "[[" + СтрЗаменить(Строка(ТаблицаТочек[0].Широта), ",", ".") + "," + СтрЗаменить(Строка(ТаблицаТочек[0].Долгота), ",", ".") + "],";
Для Ин = 1 По ТаблицаТочек.Количество() - 2 Цикл
Результат = Результат + "[" + СтрЗаменить(Строка(ТаблицаТочек[ин].Широта), ",", ".") + "," + СтрЗаменить(Строка(ТаблицаТочек[ин].Долгота), ",", ".") + "],";
КонецЦикла;
Результат = Результат + "[" + СтрЗаменить(Строка(ТаблицаТочек[ТаблицаТочек.Количество() - 1].Широта), ",", ".") + "," + СтрЗаменить(Строка(ТаблицаТочек[ТаблицаТочек.Количество() - 1].Долгота), ",", ".") + "]]";
Возврат Результат;
КонецФункции
&НаКлиенте
//Процедура выстраивает маршрут для Гугл
//
//Параметры:
//
Процедура ПостроитьМаршрут_Гугл()
ПараметрыМаршрута = ПолучитьПараметрыМаршрутаГугл();
ОчисткаКарты();
Элементы.Эксплорер.document.getElementById("WebClientOperation").value = "calcRoute(" + ПараметрыМаршрута + ")";
Элементы.Эксплорер.document.getElementById("WebClient").click();
КонецПроцедуры
&НаКлиенте
//Функция получает массив точек, для передачи параметров в Гугл
//
//Параметры:
//
//Возвращаемое значение:
// Строка
Функция ПолучитьПараметрыМаршрутаГугл()
Результат = "";
ВнутрМассив = "";
Результат = Результат + "[[" + СтрЗаменить(Строка(ТаблицаТочек[0].Широта), ",", ".") + "," + СтрЗаменить(Строка(ТаблицаТочек[0].Долгота), ",", ".") + "],";
Если ТаблицаТочек.Количество() = 2 Тогда
Результат = Результат + "[],";
Иначе
Для Ин = 1 По ТаблицаТочек.Количество() - 2 Цикл
ВнутрМассив = ВнутрМассив + "[" + СтрЗаменить(Строка(ТаблицаТочек[ин].Широта), ",", ".") + "," + СтрЗаменить(Строка(ТаблицаТочек[ин].Долгота), ",", ".") + "],";
КонецЦикла;
Результат = Результат + "[" + Сред(ВнутрМассив, 1, СтрДлина(ВнутрМассив) - 1) + "],";
КонецЕсли;
Результат = Результат + "[" + СтрЗаменить(Строка(ТаблицаТочек[ТаблицаТочек.Количество() - 1].Широта), ",", ".") + "," + СтрЗаменить(Строка(ТаблицаТочек[ТаблицаТочек.Количество() - 1].Долгота), ",", ".") + "]]";
Возврат Результат;
КонецФункции
&НаКлиенте
//Процедура выстраивает маршрут для Рамблера
//
//Параметры:
//
Процедура ПостроитьМаршрут_Рамблер()
ПараметрыМаршрута = ПолучитьПараметрыМаршрутаРамблер();
ОчисткаКарты();
Элементы.Эксплорер.document.getElementById("WebClientOperation").value = "calcRoute(" + ПараметрыМаршрута + ")";
Элементы.Эксплорер.document.getElementById("WebClient").click();
КонецПроцедуры
&НаКлиенте
//Функция получает массив точек, для передачи параметров в Рамблер
//
//Параметры:
//
//Возвращаемое значение:
// Строка
Функция ПолучитьПараметрыМаршрутаРамблер()
Результат = "";
Результат = Результат + "[[" + СтрЗаменить(Строка(ТаблицаТочек[0].Широта), ",", ".") + "," + СтрЗаменить(Строка(ТаблицаТочек[0].Долгота), ",", ".") + "],";
Для Ин = 1 По ТаблицаТочек.Количество() - 2 Цикл
Результат = Результат + "[" + СтрЗаменить(Строка(ТаблицаТочек[ин].Широта), ",", ".") + "," + СтрЗаменить(Строка(ТаблицаТочек[ин].Долгота), ",", ".") + "],";
КонецЦикла;
Результат = Результат + "[" + СтрЗаменить(Строка(ТаблицаТочек[ТаблицаТочек.Количество() - 1].Широта), ",", ".") + "," + СтрЗаменить(Строка(ТаблицаТочек[ТаблицаТочек.Количество() - 1].Долгота), ",", ".") + "]]";
Возврат Результат;
КонецФункции
&НаКлиенте
Процедура СоздатьКластер(Команда)
Если ТаблицаТочек.Количество() <= 1 Тогда
Предупреждение("Недостаточно точек для построение кластера!");
Возврат;
КонецЕсли;
ОчисткаКарты();
ПостроитьКластера();
КонецПроцедуры
&НаКлиенте
Процедура ПостроитьКластера()
Кол = ТаблицаТочек.Количество();
Индекс = 1;
Для Каждого ТекСтрока Из ТаблицаТочек Цикл
Широта = формат(ТекСтрока.Широта, "ЧРД=.");
Долгота = формат(ТекСтрока.Долгота, "ЧРД=.");
СодержимоеТочки = "Содерижмое точки"; //опять же можно вставить свое название
Элементы.Эксплорер.document.getElementById("WebClientOperation").value = "addToPointArray(" + Широта + "," + Долгота + ", '" + ТекСтрока.Точка + "', """ + СодержимоеТочки + """);";
Элементы.Эксплорер.document.getElementById("WebClient").click();
Состояние("Обработан " + Индекс + " из " + кол);
Индекс = Индекс + 1;
КонецЦикла;
Элементы.Эксплорер.document.getElementById("WebClientOperation").value = "drawCluster();";
Элементы.Эксплорер.document.getElementById("WebClient").click();
КонецПроцедуры
&НаКлиенте
Процедура ОчиститьВсе(Команда)
ОчисткаКарты();
ТаблицаТочек.Очистить();
КонецПроцедуры
&НаКлиенте
Процедура ОчиститьКарту(Команда)
ОчисткаКарты();
КонецПроцедуры
&НаКлиенте
Процедура ОчиститьТаблицу(Команда)
ТаблицаТочек.Очистить();
КонецПроцедуры
&НаКлиенте
//Процедура получает координаты установленной точки
Процедура ПолучитьКоординаты()
Попытка
ЧислоТип = Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(15, 12));
КоординатаX = Элементы.Эксплорер.document.getElementById("CoordX").value;
КоординатаX = ЧислоТип.ПривестиЗначение(КоординатаX);
КоординатаY = Элементы.Эксплорер.document.getElementById("CoordY").value;
КоординатаY = ЧислоТип.ПривестиЗначение(КоординатаY);
Кол = ТаблицаТочек.Количество();
Если КоординатаX > 0 И КоординатаY > 0 И (Кол = 0 Или КоординатаX <> ТаблицаТочек[Кол - 1].Широта И КоординатаY <> ТаблицаТочек[Кол - 1].Долгота) Тогда
НоваяСтрока = ТаблицаТочек.Добавить();
НоваяСтрока.Точка = "Точка" + ТаблицаТочек.Количество();
НоваяСтрока.Широта = КоординатаX;
НоваяСтрока.Долгота = КоординатаY;
КонецЕсли;
Исключение
КонецПопытки;
КонецПроцедуры
&НаКлиенте
Процедура ПострениеПолигона(Команда)
Если ТаблицаТочек.Количество() <= 1 Тогда
Предупреждение("Недостаточно точек для построение полигона!");
Возврат;
КонецЕсли;
ОчисткаКарты();
ПостроитьПолигон();
КонецПроцедуры
&НаКлиенте
//Процедура выстраивает маршрут для Рамблера
//
//Параметры:
//
Процедура ПостроитьПолигон()
МассивТочек = "[";
Для Каждого ТекТочка Из ТаблицаТочек Цикл
Широта = формат(ТекТочка.Широта, "ЧРД=.");
Долгота = формат(ТекТочка.Долгота, "ЧРД=.");
МассивТочек = МассивТочек + "[" + Широта + "," + Долгота + "],";
КонецЦикла;
МассивТочек = Сред(МассивТочек, 1, СтрДлина(МассивТочек) - 1) + "]";
Цвет16 = Получить16Цвет();
Название = "Полигон";//вставить свое
Элементы.Эксплорер.document.getElementById("WebClientOperation").value = "createPolygon(" + МассивТочек + ", '" + Название + "', '" + Цвет16 + "');";
Элементы.Эксплорер.document.getElementById("WebClient").click();
КонецПроцедуры
&НаСервере
//Функция возвращает значение случайного цвета в 16-ричном формате
//
//Параметры:
// нет
//Возвращаемое значение:
// Строка
Функция Получить16Цвет()
Результат = "";
Строка16 = "0123456789ABCDEF";
ГСЧ = Новый ГенераторСлучайныхЧисел;
Результат = "#";
Для н = 1 По 6 Цикл
м = ГСЧ.СлучайноеЧисло(1, 16);
Результат = Результат + Сред(Строка16, м, 1);
КонецЦикла;
Возврат Результат;
КонецФункции
Пакетные запросы логично дополняют функционал временных таблиц и дают больше возможностей при работе с запросами.
В пакетном запросе фактически можно описать несколько запросов, как связанных между собой использованием временных таблиц, так и не связанных (можно, но не понятно зачем?). В итоге можно выполнить последовательно все запросы и принять в результате либо массив с результатами исполнения каждого запроса, либо результат последнего. Для получения массива с результатами запроса применяют метод
ВыполнитьПакет() объекта запрос, а для получения результата последнего запроса
ВыполнитьЗапрос() .
В тексте запроса, запросы пакета разделяются символом «;» (точка с запятой). Область имен виртуальных таблиц у одного пакетного запроса одна. Использование менеджера временных таблиц не требуется, но возможно если вы хотите передать временные таблицы из одного пакетного запроса в другой.
Код 1C v 8.х Процедура ОбработкаПроведения(Отказ, РежимПроведения)
Запрос = Новый Запрос;
Запрос. Текст = "
|ВЫБРАТЬ
| Номенклатура, СУММА(Количество) КАК Количество
|ПОМЕСТИТЬ ДокТЧ
|ИЗ
| Документ.Расходная.Товары
|ГДЕ
| Ссылка = &Ссылка
|СГРУППИРОВАТЬ ПО Номенклатура
|;
|
|ВЫБРАТЬ РАЗЛИЧНЫЕ
| Номенклатура
|ПОМЕСТИТЬ СписокТоваров
|ИЗ
| Документ.Расходная.Товары
|ГДЕ
| Ссылка = &Ссылка
|;
|
|ВЫБРАТЬ
| Док.Номенклатура,
| Док.Количество КАК Док_Количество,
| ЕСТЬNULL(Рег.КоличествоОстаток,0) КАК Рег_Количество
|ИЗ
| ДокТЧ КАК Док
| ЛЕВОЕ СОЕДИНЕНИЕ
| РегистрНакопления.ОстаткиТоваров.Остатки(,
| Номенклатура В(ВЫБРАТЬ РАЗЛИЧНЫЕ
| Номенклатура
| ИЗ
| СписокТоваров КАК СписокТоваров)) КАК Рег
| ПО
| Док.Номенклатура = Рег.Номенклатура" ;
Запрос. УстановитьПараметр( "Ссылка" , Ссылка) ;
МассивРезультаттов = Запрос. ВыполнитьПакет( ) ;
РезультатЗапроса = Запрос. Выполнить( ) ;
Выборка = РезультатЗапроса. Выбрать( ) ;
Пока Выборка. Следующий( ) Цикл
КонецЦикла ;
КонецПроцедуры
Фактически я убрал определение объекта запрос и использование менеджера временных таблиц, объединил тексты запросов (обратите внимание на разделитель «;» между текстами). В результате текст запроса стал читабельнее (а при использовании конструктора запросов намного увеличивается удобство чтения запроса).
После выполнения запроса в переменную
МассивРезультатов у нас попадет 3 элемента. Первые два будут содержать число характеризующее количество записей помещенных во временные таблицы ДокТЧ и СписокТоваров, а третий будет содержать выборку с полями Номенклатура, Док_Количество и Рег_Количество.
В переменную
РезультатЗапроса попадет только выборка.
Ну вот и все что касается пакетных запросов. Очень удобный механизм и с точки зрения написания запросов и с точки зрения чтения сложных запросов.
Автор:
Павел Чистов