Вывести результат формирования СКД в таблицу значений Код 1C v 8.3 Настройки = КомпоновщикНастроек.ПолучитьНастройки();
КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
МакетКомпоновки = КомпоновщикМакета.Выполнить(СхемаКомпоновкиДанных, Настройки, , ,Тип("ГенераторМакетаКомпоновкиДанныхДляКоллекцииЗначений"));
ПроцессорКомпоновкиДанных = Новый ПроцессорКомпоновкиДанных;
ПроцессорКомпоновкиДанных.Инициализировать(МакетКомпоновки);
ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВКоллекциюЗначений;
ПроцессорВывода.УстановитьОбъект(Результат);
ПроцессорВывода.Вывести(ПроцессорКомпоновкиДанных, Истина);
Категория:
Схема Компоновки Данных Добавление дополнительных отчетов и обработок в тонком клиенте БП 3.0, ЗУП 3.0, УТ 11 Любой отчет и обработку можно подключить пользователям как дополнительные отчеты или обработки, вот например пункт в БП - Банк:
Добавление происходит через
далее Дополнительные отчеты и обработки , в списке нажмите Создать и Выберите Файл отчета/обработки:
Перед добавлением файл нужно подготовить, дописать в модуль объекта код подключения:
Для обработок код:
Код 1C v 8.3 Функция СведенияОВнешнейОбработке() Экспорт
ПараметрыРегистрации = Новый Структура;
//Вид
//Строка, вид обработки, один из возможных:
//"ДополнительнаяОбработка", "ДополнительныйОтчет", "ЗаполнениеОбъекта", "Отчет", "ПечатнаяФорма", "СозданиеСвязанныхОбъектов"
ПараметрыРегистрации.Вставить("Вид", "ДополнительнаяОбработка");
//Массив строк имен объектов метаданных в формате:
//<ИмяКлассаОбъектаМетаданного>.[ * | <ИмяОбъектаМетаданных>].
//Например, "Документ.СчетЗаказ" или "Справочник.*".
//Прим. параметр имеет смысл только для назначаемых обработок, для глобальных может не задаваться.
ПараметрыРегистрации.Вставить("Назначение", Новый СписокЗначений);
//Наименование обработки, которым будет заполнено наименование элемента справочника по умолчанию - краткая строка для идентификации обработки администратором
ПараметрыРегистрации.Вставить("Наименование", "Сравнение документов БУХ и УТ");
//Версия обработки в формате “<старший номер>.<младший номер>” используется при загрузке обработок в информационную базу. Например “.
ПараметрыРегистрации.Вставить("Версия", "1.0");
//Принимает значение Истина или Ложь, в зависимости от того, требуется ли устанавливать или отключать безопасный режим исполнения обработок. Если истина, обработка будет запущена в безопасном режиме. Более подбробно о безопасном режиме в справке к платформе 1С:Предприятие.
ПараметрыРегистрации.Вставить("БезопасныйРежим", Истина);
//Краткая информация по обработке, описание обработки.
ПараметрыРегистрации.Вставить("Информация", "");
//Команды, поставляемые обработкой. Таблица значений с колонками:
ПараметрыРегистрации.Вставить("Команды", Новый СписокЗначений);
ТаблицаКоманд = ПолучитьТаблицу_Команд();
ДобавитьКоманду(ТаблицаКоманд,
"Сравнение документов БУХ и УТ", //Представление
"Сравнение документов БУХ и УТ", //Идентификатор
"ОткрытиеФормы", //Использование
Ложь, //ПоказыватьОповещение
""); //Модификатор
ПараметрыРегистрации.Вставить("Команды", ТаблицаКоманд);
Возврат ПараметрыРегистрации;
КонецФункции
Функция ПолучитьТаблицу_Команд()
Команды = Новый ТаблицаЗначений;
//Представление – представление команды в пользовательском интерфейсе;
Команды.Колонки.Добавить("Представление", Новый ОписаниеТипов("Строка"));
//Идентификатор – идентификатор команды;
//любая строка, уникальная в пределах данной обработки (отчета).
//В случае с обработками печатных форм на основе макета табличного документа передается список макетов,
//на основе которых нужно получить печатную форму
//(см. описание параметра ИменаМакетов процедуры УправлениеПечатьюКлиент.ВыполнитьКомандуПечати в разделе Печать).
Команды.Колонки.Добавить("Идентификатор", Новый ОписаниеТипов("Строка"));
//"ОткрытиеФормы" – открыть форму обработки;
//"ВызовКлиентскогоМетода" – вызвать клиентскую экспортную процедуру из модуля формы обработки;
//"ВызовСерверногоМетода" – вызвать серверную экспортную процедуру из модуля объекта обработки.
Команды.Колонки.Добавить("Использование", Новый ОписаниеТипов("Строка"));
//ПоказыватьОповещение – если Истина, требуется показать оповещение при начале и при завершении работы обработки.
//Имеет смысл только при запуске обработки без открытия формы.
Команды.Колонки.Добавить("ПоказыватьОповещение", Новый ОписаниеТипов("Булево"));
//Модификатор – дополнительный модификатор команды.
//Используется для дополнительных обработок печатных форм на основе табличных макетов,
//для таких команд должен содержать строку ПечатьMXL (см. пример в демонстрационной конфигурации).
Команды.Колонки.Добавить("Модификатор", Новый ОписаниеТипов("Строка"));
Возврат Команды;
КонецФункции
Процедура ДобавитьКоманду(ТаблицаКоманд, Представление, Идентификатор, Использование, ПоказыватьОповещение = Ложь, Модификатор = "")
НоваяКоманда = ТаблицаКоманд.Добавить();
НоваяКоманда.Представление = Представление;
НоваяКоманда.Идентификатор = Идентификатор;
НоваяКоманда.Использование = Использование;
НоваяКоманда.ПоказыватьОповещение = ПоказыватьОповещение;
НоваяКоманда.Модификатор = Модификатор;
КонецПроцедуры
Для отчетов и печатных форм меняйте параметр Вид :
Код 1C v 8.3 //"ДополнительнаяОбработка", "ДополнительныйОтчет", "ЗаполнениеОбъекта", "Отчет", "ПечатнаяФорма", "СозданиеСвязанныхОбъектов"
ПараметрыРегистрации.Вставить("Вид", "ДополнительнаяОбработка");
Возможные значения этого поля приведу в виде таблицы
Значение поля "Вид" Расположение команды Расширение
файла
ПечатнаяФорма В меню "Печать" на форме объекта или списка epf ЗаполнениеОбъекта В меню "Заполнить" на форме объекта или списка epf СозданиеСвязанныхОбъектов В меню "Создать на основании" - "Создание связанных объектов.." на форме объекта или списка epf Отчет В меню "Отчеты" на форме объекта или списка erf ДополнительнаяОбработка В списке соответствующих подсистем в меню "Сервис" - "Дополнительные обработки" epf ДополнительныйОтчет В списке соответствующих подсистем в меню "Сервис" - "Дополнительные отчеты" erf
Это поле может принимать одно из значений, возвращаемых функциями в типовых конфигурациях:
ДополнительныеОтчетыИОбработкиКлиентСервер.ВидОбработки<Вид>(). Например, для вида "ПечатнаяФорма" есть функция ВидОбработкиПечатнаяФорма().
Категория:
Внешние печатные формы, отчеты и обработк… Вывод результата запроса на форму УП в таблицу значений (аналог СоздатьКолонки() для УП) при разработке на обычных формах было удобно выводить результат запроса используя метод СоздатьКолоки():
Код 1C v 8.х Процедура ПоискНажатие(Элемент)
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ДокументоОборот.Этап,
| ДокументоОборот.Отдел,
| ДокументоОборот.ФИО,
| ДокументоОборот.ДатаВремя КАК Дата_Время,
| ДокументоОборот.Документы,
| ДокументоОборот.Примечание,
| ДокументоОборот.Доставка
|ИЗ
| РегистрСведений.ДокументоОборот КАК ДокументоОборот
|ГДЕ
| ДокументоОборот.Документы ПОДОБНОДокументы
| И ДокументоОборот.Доставка.Дата МЕЖДУДатаН ИДатаК
|
|УПОРЯДОЧИТЬ ПО
| ДокументоОборот.ДатаВремя";
Запрос.УстановитьПараметр("Документы", "%"+СокрЛП(Строка(СтрокаПоиска))+"%");
Запрос.УстановитьПараметр("ДатаК", КонПериода);
Запрос.УстановитьПараметр("ДатаН", НачПериода);
Рез=Запрос.Выполнить();
НайденДок = рез.Выгрузить();
ЭлементыФормы.НайденДок.СоздатьКолонки();
В управляемом приложении метод СоздатьКолоки() не доступен, ниже представлена процедура, которая отображает на управляемой форме содержимое таблицы значений переданное ей в качестве параметра:
Пример формы:
Код вывода результата запроса на управляемую форму :
Код 1C v 8.2 УП &НаСервере
Процедура СоздатьТаблицуФормы(Знач ИмяПоляТаблицыФормы, Знач ИмяРеквизитаДанныеФормыКоллекция, Знач ТаблицаЗначений)
// Если руками не создали эелемент формы Таблица, то создается программно
Если Элементы.Найти(ИмяПоляТаблицыФормы) = Неопределено Тогда
ЭлементРеквизита = Элементы.Добавить(ИмяПоляТаблицыФормы, Тип("ТаблицаФормы"),);
ЭлементРеквизита.ПутьКДанным = ИмяРеквизитаДанныеФормыКоллекция;
КонецЕсли;
УдаляемыеРеквизиты = Новый Массив;
РеквизитыДляУдаления = ПолучитьРеквизиты(ИмяРеквизитаДанныеФормыКоллекция);
Для Каждого РеквизитУдаления Из РеквизитыДляУдаления Цикл
УдаляемыеРеквизиты.Добавить(ИмяРеквизитаДанныеФормыКоллекция+"."+РеквизитУдаления.Имя);
// Удаляем элементы формы
Элементы.Удалить(Элементы[ИмяПоляТаблицыФормы+РеквизитУдаления.Имя]);
КонецЦикла;
// Добавление реквизитов в таблицу формы
ДобавляемыеРеквизиты = Новый Массив;
Для каждого Колонка Из ТаблицаЗначений.Колонки Цикл
ДобавляемыеРеквизиты.Добавить(Новый РеквизитФормы(Колонка.Имя, Колонка.ТипЗначения, ИмяРеквизитаДанныеФормыКоллекция, Колонка.Заголовок));
КонецЦикла;
ИзменитьРеквизиты(ДобавляемыеРеквизиты,УдаляемыеРеквизиты);
// Добавление элементов форму
Для каждого Колонка Из ТаблицаЗначений.Колонки Цикл
ЭлементРеквизита = Элементы.Добавить(ИмяПоляТаблицыФормы + Колонка.Имя, Тип("ПолеФормы"), Элементы[ИмяПоляТаблицыФормы]);
ЭлементРеквизита.ПутьКДанным = ИмяРеквизитаДанныеФормыКоллекция + "." + Колонка.Имя;
ЭлементРеквизита.Вид = ВидПоляФормы.ПолеВвода;
КонецЦикла;
ЗначениеВРеквизитФормы(ТаблицаЗначений, ИмяРеквизитаДанныеФормыКоллекция);
КонецПроцедуры
&НаСервере
Процедура ВПоискНаСервере()
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| РеализацияТоваровУслугСерии.Серия КАК Серия,
| РеализацияТоваровУслугСерии.Ссылка КАК Реализация,
| РеализацияТоваровУслугСерии.Ссылка.ЗаказКлиента КАК ЗаказКлиента,
| РеализацияТоваровУслугСерии.Ссылка.Контрагент КАК Контрагент,
| РеализацияТоваровУслугСерии.Ссылка.Договор КАК Договор
|ИЗ
| Документ.РеализацияТоваровУслуг.Серии КАК РеализацияТоваровУслугСерии
|ГДЕ
| РеализацияТоваровУслугСерии.Серия В
| (ВЫБРАТЬ
| СерииНоменклатуры.Ссылка КАК Ссылка
| ИЗ
| Справочник.СерииНоменклатуры КАК СерииНоменклатуры
| ГДЕ
| СерииНоменклатуры.Наименование ПОДОБНОНаименование)
|
|УПОРЯДОЧИТЬ ПО
| Серия
|АВТОУПОРЯДОЧИВАНИЕ";
Запрос.УстановитьПараметр("Наименование", "%"+НомерФН+"%");
РезультатЗапроса = Запрос.Выполнить();
ТаблицаЗапроса = Запрос.Выполнить().Выгрузить();
СоздатьТаблицуФормы("ТЗ","ТЗ",ТаблицаЗапроса);
КонецПроцедуры
&НаКлиенте
Процедура ВПоиск(Команда)
ВПоискНаСервере();
КонецПроцедуры
Категория:
Управляемое приложение, Тонкий клиент Добавление дополнительных отчетов и обработок в управляемом приложении Для добавления отчета или обработки нужно в модуле добавить Функцию СведенияОВнешнейОбработке()
Код 1C v 8.2 УП Функция СведенияОВнешнейОбработке() Экспорт
// Объявим переменную, в которой мы сохраним и вернем "наружу" необходимые данные
ПараметрыРегистрации = Новый Структура;
// Объявим еще одну переменную, которая нам потребуется ниже
МассивНазначений = Новый Массив;
// Первый параметр, который мы должны указать - это какой вид обработки системе должна зарегистрировать.
// Допустимые типы: ДополнительнаяОбработка, ДополнительныйОтчет, ЗаполнениеОбъекта, Отчет, ПечатнаяФорма, СозданиеСвязанныхОбъектов
ПараметрыРегистрации.Вставить("Вид", "ДополнительнаяОбработка");
ПараметрыРегистрации.Вставить("Назначение", МассивНазначений);
// Теперь зададим имя, под которым ВПФ будет зарегистрирована в справочнике внешних обработок
ПараметрыРегистрации.Вставить("Наименование", "Выгрузка проводок в БП 2.0");
// Зададим право обработке на использование безопасного режима. Более подробно можно узнать в справке к платформе (метод УстановитьБезопасныйРежим)
ПараметрыРегистрации.Вставить("БезопасныйРежим", Истина);
// Следующие два параметра играют больше информационную роль, т.е. это то, что будет видеть пользователь в информации к обработке
ПараметрыРегистрации.Вставить("Версия", "1.0");
ПараметрыРегистрации.Вставить("Информация", "Обработка 'Выгрузка проводок в БП 2.0'");
// Создадим таблицу команд (подробнее смотрим ниже)
ТаблицаКоманд = ПолучитьТаблицуКоманд();
ДобавитьКоманду(ТаблицаКоманд,
"Выгрузка проводок в БП 2.0",
"ВыгрузкапроводоквБП20",
"ОткрытиеФормы", //Использование. Варианты: "ОткрытиеФормы", "ВызовКлиентскогоМетода", "ВызовСерверногоМетода"
Ложь,//Показывать оповещение. Варианты Истина, Ложь
"");//Модификатор
ПараметрыРегистрации.Вставить("Команды", ТаблицаКоманд);
Возврат ПараметрыРегистрации;
КонецФункции
Функция ПолучитьТаблицуКоманд()
Команды = Новый ТаблицаЗначений;
Команды.Колонки.Добавить("Представление", Новый ОписаниеТипов("Строка"));
Команды.Колонки.Добавить("Идентификатор", Новый ОписаниеТипов("Строка"));
Команды.Колонки.Добавить("Использование", Новый ОписаниеТипов("Строка"));
Команды.Колонки.Добавить("ПоказыватьОповещение", Новый ОписаниеТипов("Булево"));
Команды.Колонки.Добавить("Модификатор", Новый ОписаниеТипов("Строка"));
Возврат Команды;
КонецФункции
Процедура ДобавитьКоманду(ТаблицаКоманд, Представление, Идентификатор, Использование, ПоказыватьОповещение = Ложь, Модификатор = "")
НоваяКоманда = ТаблицаКоманд.Добавить();
НоваяКоманда.Представление = Представление;
НоваяКоманда.Идентификатор = Идентификатор;
НоваяКоманда.Использование = Использование;
НоваяКоманда.ПоказыватьОповещение = ПоказыватьОповещение;
НоваяКоманда.Модификатор = Модификатор;
КонецПроцедуры
После сохранения приступим к добавлению в программу:
Ставим галку Дополнительные отчеты и обработки
Открываем дополнительные отчеты и обработки и жмем создать, появляется окно выбора файла, после выбора:
Укажите Размещение (в каком разделе отображать данный отчет/обработку) и в списке в колонке Быстрый доступ выберите пользователей, которым будет доступен данный отчет/обработка.
Если при добавлении вы получаете ошибку:
{ОбщийМодуль.ДополнительныеОтчетыИОбработки.Модуль(2621)}: Поле объекта не обнаружено (ХранилищеВариантов)
Если ВнешнийОбъектМетаданные.ХранилищеВариантов <> Неопределено Тогда
То нужно заменить в модуле объекта, в ф ункции СведенияОВнешнейОбработке() :
Код 1C v 8.2 УП РегистрационныеДанные.Вставить("Вид", "ДополнительнаяОтчет"); //расширение erf
на:
РегистрационныеДанные.Вставить("Вид", "ДополнительнаяОбработка"); //расширение epf
Категория:
Внешние печатные формы, отчеты и обработк… 17 правил для составления оптимального ЗАПРОСа к данным базы 1С Для формирования и выполнения запросов к таблицам базы данных в платформе 1С используется специальный объект языка программирования Запрос . Создается этот объект вызовом конструкции Новый Запрос . Запрос удобно использовать, когда требуется получить сложную выборку данных, сгруппированную и отсортированную необходимым образом. Классический пример применения запроса - получение сводки по состоянию регистра накопления на определенный момент времени. Так же, механизм запросов позволяет легко получать информацию в различных временных разрезах.
Текст запроса – это инструкция, в соответствии с которой должен быть выполнен запрос. В тексте запроса описывается:
таблицы информационной базы, используемые в качестве источников данных запроса; поля таблиц, которые требуется обрабатывать в запросе; правила группировки; сортировки результатов; и т. д. Инструкция составляется на специальном языке – языке запросов и состоит из отдельных частей – секций, предложений, ключевых слов, функций, арифметических и логических операторов, комментариев, констант и параметров.
Язык запросов платформы 1С очень похож на синтаксис других SQL-языков, но имеются отличия. Основными преимуществами встроенного языка запросов являются: разыменование полей, наличие виртуальных таблиц, удобная работа с итогами, нетипизированные поля в запросах.
Рекомендации по написанию запросов к базе данных на языке запросов платформы 1С: 1) Текст запроса может содержать предопределенные данные конфигурации, такие как:
значения перечислений; предопределенные данные: справочников; планов видов характеристик; планов счетов; планов видов расчетов; пустые ссылки; значения точек маршрута бизнес-процессов. Также текст запроса может содержать значения системных перечислений, которые могут быть присвоены полям в таблицах базы данных: ВидДвиженияНакопления, ВидСчета и ВидДвиженияБухгалтерии. Обращение в запросах к предопределенным данным конфигурации и значениям системных перечислений осуществляется с помощью литерала функционального типа ЗНАЧЕНИЕ. Данный литерал позволяет повысить удобочитаемость запроса и уменьшить количество параметров запроса.
Пример использования литерала ЗНАЧЕНИЕ :
ГДЕ Город = ЗНАЧЕНИЕ(Справочник.Города.Москва) ГДЕ Город = ЗНАЧЕНИЕ(Справочник.Города.ПустаяСсылка) ГДЕ ТипТовара = ЗНАЧЕНИЕ(Перечисление.ВидыТоваров.Услуга) ГДЕ ВидДвижения = ЗНАЧЕНИЕ(ВидДвиженияНакопления.Приход) ГДЕ ТочкаМаршрута = ЗНАЧЕНИЕ(БизнесПроцесс.БизнесПроцесс1.ТочкаМаршрута.Действие1 2) Использование инструкции АВТОУПОРЯДОЧИВАНИЕ в запросе может сильно время выполнения запроса, поэтому, если сортировка не требуется, то лучше вообще ее не использовать. Во большинстве случаях лучше всего применять сортировку с помощью инструкции УПОРЯДОЧИТЬ ПО .
Автоупорядочивание работает по следующим принципам:
Если в запросе было указано предложение УПОРЯДОЧИТЬ ПО, то каждая ссылка на таблицу, находящаяся в этом предложении, будет заменена полями, по которым по умолчанию сортируется таблица (для справочников это код или наименование, для документов – дата документа). Если поле для упорядочивания ссылается на иерархический справочник, то будет применена иерархическая сортировка по этому справочнику. Если в запросе отсутствует предложение УПОРЯДОЧИТЬ ПО, но есть предложение ИТОГИ, тогда результат запроса будет упорядочен по полям, присутствующим в предложении ИТОГИ после ключевого слова ПО, в той же последовательности и, в случае если итоги рассчитывались по полям – ссылкам, то по полям сортировки по умолчанию таблиц, на которые были ссылки. Если в запросе отсутствуют предложения УПОРЯДОЧИТЬ ПО и ИТОГИ, но есть предложение СГРУППИРОВАТЬ ПО, тогда результат запроса будет упорядочен по полям, присутствующим в предложении, в той же последовательности и, в случае если группировка велась по полям – ссылкам, то по полям сортировки по умолчанию таблиц, на которые были ссылки. В случае же, если в запросе отсутствуют предложения и УПОРЯДОЧИТЬ ПО, ИТОГИ и СГРУППИРОВАТЬ ПО, результат будет упорядочен по полям сортировки по умолчанию для таблиц, из которых выбираются данные, в порядке их появления в запросе. В случае, если запрос содержит предложение ИТОГИ, каждый уровень итогов упорядочивается отдельно. 3) Что бы избежать повторного запроса к базе данных при выводе результата запроса пользователю (например, построение запроса или отображение результата запроса с помощью табличного документа) полезно использовать инструкцию ПРЕДСТАВЛЕНИЕССЫЛКИ , которая позволяет получать представление ссылочного значения. Пример:
Код 1C v 8.х ВЫБРАТЬ
ПРЕДСТАВЛЕНИЕССЫЛКИ(РасходнаяНакладнаяСостав.Номенклатура) КАК НоменклатураПредставление<br>
Так же возможно использование инструкции ПРЕДСТАВЛЕНИЕ - предназначена для получения строкового представления значения произвольного типа. Отличие этих инструкций в том, что в первом случае, если инструкции передать ссылку, результатом будет строка, В остальных случаях результатом будет значение переданного параметра. Во втором случае, результатом инструкции всегда будет строка!
4) Если в запросе имеется поле с составным типом, то для таких полей возникает необходимость привести значения поля к какому-либо определенному типу с помощью инструкции ВЫРАЗИТЬ , что позволит убрать лишние таблицы из левого соединения с полем составного типа данных и ускорить выполнение запроса. Пример:
Имеется регистра накопления ОстаткиТоваров, у которого поле Регистратор имеет составной тип. В запросе выбираются Дата и Номер документов ПоступлениеТоваров, при этом при обращении к реквизитам документа через поле Регистратор не происходит множество левых соединений таблицы регистра накопления с таблицами документов-регистраторов.
Код 1C v 8.х ВЫБРАТЬ
ВЫРАЗИТЬ(ОстаткиТоваров.Регистратор КАК Документ.ПоступлениеТоваров).Номер КАК НомерПоступления,
ВЫРАЗИТЬ(ОстаткиТоваров.Регистратор КАК Документ.ПоступлениеТоваров).Дата КАК ДатаПоступления
ИЗ
РегистрНакопления.ОстаткиТоваров КАК ОстаткиТоваров<br>
Если приведение типа считается не осуществимым, то результатом приведения типа будет значение NULL .
5) Не стоит забывать про инструкцию РАЗРЕШЕННЫЕ , которая означает, что запрос выберет только те записи, на которые у текущего пользователя есть права. Если данное слово не указать, то в случае, когда запрос выберет записи, на которые у пользователя нет прав, запрос отработает с ошибкой.
6) В случае, если в запросе используется объединение, и в некоторых частях объединения присутствуют вложенные таблицы (документ с табличной частью), а в некоторых нет, возникает необходимость дополнения списка выборки полями – пустыми вложенными таблицами. Делается это при помощи ключевого слова ПУСТАЯТАБЛИЦА , после которого в скобках указываются псевдонимы полей, из которых будет состоять вложенная таблица. Пример:
Код 1C v 8.х // Выбрать поля Номер и Состав
// из виртуальной таблицы Документ.РасхНакл
ВЫБРАТЬ Ссылка.Номер, ПУСТАЯТАБЛИЦА.(Ном, Тов, Кол) КАК Состав
ИЗ Документ.РасхНакл
ОБЪЕДИНИТЬ ВСЕ
ВЫБРАТЬ Ссылка.Номер, Состав.(НомерСтроки, Товар, Количество)
ИЗ Документ.РасхНакл Документ.РасходнаяНакладная.Состав.*<br>
7) Что бы в результат запроса не попали повторяющиеся строки, следует использовать инструкцию РАЗЛИЧНЫЕ , потому что так нагляднее и понятнее, а инструкция СГРУППИРОВАТЬ ПО применяется для группировки с помощью агрегатных функций. Ксати, при использовании агрегатных функций предложение СГРУППИРОВАТЬ ПО может быть и не указано совсем, при этом все результаты запроса будут сгруппированы в одну единственную строку. Пример:
Код 1C v 8.х // Необходимо узнать, каким вообще контрагентам
// отгружался товар за период.
Выбрать Различные
Документ.РасходнаяНакладная.Контрагент<br>
8) Инструкция СГРУППИРОВАТЬ ПО позволяет обращаться к полям верхнего уровня, без группировки результатов по этим полям, если агрегатные функции применены к полям вложенной таблицы. Хотя в справке 1С написано, при группировке результатов запроса в списке полей выборки обязательно должны быть указаны агрегатные функции, а помимо агрегатных функций в списке полей выборки допускается указывать только поля, по которым осуществляется группировка. Пример:
Код 1C v 8.х ВЫБРАТЬ
ПоступлениеТоваровИУслуг.Товары.(СУММА(Количество),Номенклатура),
ПоступлениеТоваровИУслуг.Ссылка,
ПоступлениеТоваровИУслуг.Контрагент
ИЗ
Документ.ПоступлениеТоваровИУслуг КАК ПоступлениеТоваровИУслуг
СГРУППИРОВАТЬ ПО
ПоступлениеТоваровИУслуг.Товары.(Номенклатура)<br>
9) Инструкция ЕСТЬNULL предназначена для замены значения NULL на другое значение, но не забываем, что второй параметр будет преобразован к типу первого в случае, если тип первого параметра является строкой или числом.
10) При обращении к главной таблице можно в условии обратиться к данным подчиненной таблицы. Такая возможность называется разыменование полей подчиненной таблицы.
Пример (поиск документов, содержащих в табличной части определенный товар):
Код 1C v 8.х ВЫБРАТЬ
Приходная.Ссылка
ИЗ
Документ.Приходная Где Приходная.Товары.Номенклатура =Номенклатура.<br>
Преимущество этого запроса перед запросом к подчиненной таблице Приходная.Товары в том, что если есть дубли в документах, результат запроса вернет только уникальные документы без использования ключевого слова РАЗЛИЧНЫЕ.
11) Интересный вариант оператора В - это проверка вхождения упорядоченного набора в множество таких наборов (Поле1, Поле2, ... , ПолеN) В (Поле1, Поле2, ... , ПолеN).
Пример:
Код 1C v 8.х ВЫБРАТЬ
Контрагенты.Ссылка
ГДЕ
(Контрагенты.Ссылка, Товары.Ссылка) В
(ВЫБРАТЬ Продажи.Покупатель, Продажи.Товар
ИЗ РегистрНакопления.Продажи КАК Продажи)
ИЗ
Справочник.Контрагенты,
Справочник.Товары<br>
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) С осторожностью используйте ИЛИ в конструкции ГДЕ , так как использование условия с ИЛИ может значительно "утяжелить" запрос. Решить проблему можно конструкцией ОБЪЕДИНИТЬ ВСЕ . Пример:
Код 1C v 8.х ВЫБРАТЬ
_ДемоКонтрагенты.НаименованиеПолное
ИЗ
Справочник._ДемоКонтрагенты КАК _ДемоКонтрагенты
ГДЕ
_ДемоКонтрагенты.Ссылка =Ссылка1
ОБЪЕДИНИТЬ ВСЕ
ВЫБРАТЬ
_ДемоКонтрагенты.НаименованиеПолное
ИЗ
Справочник._ДемоКонтрагенты КАК _ДемоКонтрагенты
ГДЕ
_ДемоКонтрагенты.Ссылка =Ссылка2<br>
15) Условие НЕ В в конструкции ГДЕ увеличивает время исполнения запроса, так как это своего рода НЕ (ИЛИ1 ИЛИ2 ... ИЛИn) , поэтому для больших таблиц старайтесь использовать ЛЕВОЕ СОЕДИНЕНИЕ с условием ЕСТЬ NULL . Пример:
Код 1C v 8.х ВЫБРАТЬ
_ДемоКонтрагенты.Ссылка
ИЗ
Справочник._ДемоКонтрагенты КАК _ДемоКонтрагенты
ЛЕВОЕ СОЕДИНЕНИЕ Документ._ДемоЗаказПокупателя КАК _ДемоЗаказПокупателя
ПО _ДемоКонтрагенты.Ссылка = _ДемоЗаказПокупателя.Контрагент
ГДЕ
_ДемоЗаказПокупателя.Контрагент ЕСТЬ NULL<br>
16) При использовании Временных таблиц нужно индексировать поля условий и соединений в этих таблицах, НО, при использовании индексов запрос может выполняться еще медленнее. Поэтому необходимо анализировать каждый запрос с применением индекса и без, замерять скорость выполнения запроса и принимать окончательное решение.
Если вы помещаете во временную таблицу данные, которые изначально индексированы по некоторым полям, то во временной таблице индекса по этим полям уже не будет.
17) Если вы не используете Менеджер временных таблиц , то явно удалять временную таблицу не требуется, она будет удалена после завершения выполнения пакетного запроса, иначе следует удалить временную таблицу одним из способов: командой УНИЧТОЖИТЬ в запросе, вызвать метод МенеджерВременныхТаблиц.Закрыть() .
Источник
И в дополнении видео от Евгения Гилева : Типовые ошибки при написании запросов на 1С:
VIDEO Категория:
Запросы Функции сохранения таблицы значений в файл и чтения из файла В данном примере хочу привести несколько универсальных функций по выгрузке таблицы значений в файл и дальнейшего чтения из файла:
П орядок программных действий при выгрузке в файл выглядит так:
Подготавливаем таблицу значений (выгружаем из табличной части, выбираем колонки); Конвертируем таблицу значений в табличный документ; Сохраняем табличный документ в MXL. При загрузке таблицы порядок действий такой:
Читаем из файла табличный документ; Конвертируем табличный документ в таблицу значений; Используем эту таблицу значений в своих целях (загружаем в табличную часть). Соответственно файл для хранения данных таблицы имеет расширение *.mxl.
Основные функции для реализации поставленной задачи следующие:
ПреобразоватьТДвТЗ – Функция преобразования табличного документа в таблицу значений.
ПреобразоватьТЗвТД – Функция обратного преобразования таблицы значений в табличный документ.
ПрочитатьТЗИзMXL – Читает из файла данные, определяет колонки таблицы и преобразует эти данные в таблицу значений.
ЗаписатьТЗВMXL – Преобразует таблицу значений в табличный документ и записывает его в файл.
Код 1C v 8.3 // Преобразовать табличный документ в таблицу значений.
//
// Параметры:
// ТабДок - <ТабличныйДокумент> - Исходный табличный документ;
// СтруктураКолонок - <Структура>, <ТаблицаЗначений> - Структура колонок;
// НачалоСтрока - <Число> - Строка начала области;
// НачалоСтолбец - <Число> - Столбец начала области;
// КонецСтрока - <Число> - Строка конца области;
// КонецСтолбец - <Число> - Столбец конца области.
//
// Возвращаемое значение:
// <ТаблицаЗначений> - Полученная таблица значений.
//
Функция ПреобразоватьТДвТЗ(ТабДок, СтруктураКолонок, Знач НачалоСтрока = Неопределено, Знач НачалоСтолбец = Неопределено, Знач КонецСтрока = Неопределено, Знач КонецСтолбец = Неопределено) Экспорт
// Определение габаритов таблицы
Если НачалоСтрока = Неопределено И НачалоСтолбец = Неопределено Тогда
НачалоСтрока = 1;
НачалоСтолбец = 1;
КонецЕсли;
Если НачалоСтрока = Неопределено Тогда
НачалоСтрока = 1;
Пока НЕ ТабДок.Область(НачалоСтрока, НачалоСтолбец).СодержитЗначение
И НачалоСтрока < ТабДок.ВысотаТаблицы
Цикл
НачалоСтрока = НачалоСтрока + 1;
КонецЦикла;
ИначеЕсли НачалоСтолбец = Неопределено Тогда
НачалоСтолбец = 1;
Пока НЕ ТабДок.Область(НачалоСтрока, НачалоСтолбец).СодержитЗначение
И НачалоСтолбец < ТабДок.ШиринаТаблицы
Цикл
НачалоСтолбец = НачалоСтолбец + 1;
КонецЦикла;
КонецЕсли;
КонецСтрока = ?(КонецСтрока = Неопределено, ТабДок.ВысотаТаблицы, КонецСтрока);
КонецСтолбец = ?(КонецСтолбец = Неопределено, ТабДок.ШиринаТаблицы, КонецСтолбец);
// Преобразование
ЭтоТаблица = (ТипЗнч(СтруктураКолонок) = Тип("ТаблицаЗначений"));
ТабЗначений = ПолучитьТаблицуВывода(СтруктураКолонок);
Для ИндексСтроки = НачалоСтрока По КонецСтрока Цикл
СтрокаТЗ = ТабЗначений.Добавить();
ИндексКолонки = НачалоСтолбец;
Для Каждого Колонка Из СтруктураКолонок Цикл
НаименованиеКолонки = ?(ЭтоТаблица, Колонка.Наименование, Колонка.Ключ);
пИндексКолонки = ?(ЭтоТаблица, Колонка.СтолбецОтчёт, ИндексКолонки);
Если ТабДок.Область(ИндексСтроки, пИндексКолонки).СодержитЗначение Тогда
СтрокаТЗ[НаименованиеКолонки] = ТабДок.Область(ИндексСтроки, пИндексКолонки).Значение;
Иначе
СтрокаТЗ[НаименованиеКолонки] = ТабДок.Область(ИндексСтроки, пИндексКолонки).Текст;
КонецЕсли;
ИндексКолонки = ИндексКолонки + 1;
КонецЦикла;
КонецЦикла;
Возврат ТабЗначений;
КонецФункции;
// Преобразовать таблицу значений в табличный документ.
//
// Параметры:
// ТабЗначений - <ТаблицаЗначений> - Исходная таблица значений;
// ТабДок - <ТабличныйДокумент> - Полученный табличный документ. Если параметр не задан,
// то документ создаётся заново и возвращается функцией;
// НачалоСтрока - <Число> - Строка начала области;
// НачалоСтолбец - <Число> - Столбец начала области;
// ВыводитьЗаголовки - <Булево> - Определяет выводить ли имена колонок или нет.
//
// Возвращаемое значение:
// <ТабличныйДокумент> - Полученный табличный документ (возвращает параметр "ТабДок").
//
Функция ПреобразоватьТЗвТД(ТабЗначений, ТабДок = Неопределено, Знач НачалоСтрока = Неопределено, Знач НачалоСтолбец = Неопределено, ВыводитьЗаголовки = Ложь) Экспорт
Если ТабДок = Неопределено Тогда
ТабДок = Новый ТабличныйДокумент;
КонецЕсли;
// Определение габаритов таблицы
НачалоСтрока = ?(НачалоСтрока = Неопределено, 1, НачалоСтрока);
НачалоСтолбец = ?(НачалоСтолбец = Неопределено, 1, НачалоСтолбец);
// Преобразование
ИндексСтроки = НачалоСтрока;
Если ВыводитьЗаголовки Тогда
ИндексКолонки = НачалоСтолбец;
Для Каждого Колонка Из ТабЗначений.Колонки Цикл
ТабДок.Область(ИндексСтроки, ИндексКолонки).Текст = ?(ПустаяСтрока(Колонка.Заголовок), Колонка.Имя, Колонка.Заголовок);
ИндексКолонки = ИндексКолонки + 1;
КонецЦикла;
ИндексСтроки = ИндексСтроки + 1;
КонецЕсли;
Для Каждого Элемент Из ТабЗначений Цикл
ИндексКолонки = НачалоСтолбец;
Для Каждого Колонка Из ТабЗначений.Колонки Цикл
ТабДок.Область(ИндексСтроки, ИндексКолонки).СодержитЗначение = Истина;
ТабДок.Область(ИндексСтроки, ИндексКолонки).ТипЗначения = Новый ОписаниеТипов(Колонка.ТипЗначения);
ТабДок.Область(ИндексСтроки, ИндексКолонки).Значение = Элемент[Колонка.Имя];
ИндексКолонки = ИндексКолонки + 1;
КонецЦикла;
ИндексСтроки = ИндексСтроки + 1;
КонецЦикла;
Возврат ТабДок;
КонецФункции;
// Читает табличный документ из файла MXL и преобразует его в таблицу значений.
//
// Параметры:
// ИмяФайла - <Строка> - Путь к файлу MXL;
// СтруктураКолонок - <Структура>, <ТаблицаЗначений> - Структура колонок. Если этот параметр
// не задан, то структура колонок формируется из самого табличного документа;
// ЕстьЗаголовок - <Булево> - Есть ли первая строка с заголовками или нет.
//
// Возвращаемое значение:
// <ТаблицаЗначений> - Полученная таблица значений.
//
Функция ПрочитатьТЗИзMXL(ИмяФайла, СтруктураКолонок = Неопределено, ЕстьЗаголовок = Истина) Экспорт
ТабДок = Новый ТабличныйДокумент;
ТабДок.Прочитать(ИмяФайла);
Если СтруктураКолонок = Неопределено И ЕстьЗаголовок Тогда
СтруктураКолонок = Новый Структура;
Для ИндексКолонки = 1 По ТабДок.ШиринаТаблицы Цикл
Обл1 = ТабДок.Область(1, ИндексКолонки);
Обл2 = ТабДок.Область(2, ИндексКолонки);
ИмяКолонки = СокрЛП(Обл1.Текст);
ИмяКолонки = ?(Найти(ИмяКолонки, " ") > 0, СтрЗаменить(ТРег(ИмяКолонки), " ", ""), ИмяКолонки);
СтруктураКолонок.Вставить(ИмяКолонки, ?(Обл2.СодержитЗначение, Обл2.ТипЗначения, Новый ОписаниеТипов));
КонецЦикла;
ИначеЕсли СтруктураКолонок = Неопределено И НЕ ЕстьЗаголовок Тогда
СтруктураКолонок = Новый Структура;
Для ИндексКолонки = 1 По ТабДок.ШиринаТаблицы Цикл
Обл2 = ТабДок.Область(1, ИндексКолонки);
ИмяКолонки = "К" + Формат(ИндексКолонки, "ЧДЦ=0; ЧН=0; ЧГ=0");
СтруктураКолонок.Вставить(ИмяКолонки, ?(Обл2.СодержитЗначение, Обл2.ТипЗначения, Новый ОписаниеТипов));
КонецЦикла;
КонецЕсли;
Таблица = ПреобразоватьТДвТЗ(ТабДок, СтруктураКолонок, ?(ЕстьЗаголовок, 2, 1), 1);
Возврат Таблица;
КонецФункции;
// Сохраняет таблицу значений в файле в виде табличного документа.
//
// Параметры:
// ИмяФайла - <Строка> - Путь к файлу MXL;
// ТабЗначений - <ТаблицаЗначений> - Сохраняемая таблица значений;
// ЕстьЗаголовок - <Булево> - Есть ли первая строка с заголовками или нет.
//
Процедура ЗаписатьТЗВMXL(ИмяФайла, ТабЗначений, ЕстьЗаголовок = Истина) Экспорт
ТабДок = ПреобразоватьТЗвТД(ТабЗначений, Неопределено, 1, 1, ЕстьЗаголовок);
ТабДок.Записать(ИмяФайла, ТипФайлаТабличногоДокумента.MXL);
КонецПроцедуры;
Еще небольшой набор функций для вывода таблицы значений в табличный документ. После формирования табличного документа, - сохраняем его в файл mxl.
Табличный документ можно сохранить a файлы следующих типов:
ANSITXT - Текстовый документ DOCX - документ MS Word HTML HTML3 HTML4 HTML5 MXL MXL7 ODS - Файл Open Office PDF - файл Acrobat Readr TXT - Текстовый документ XLS - файл Excel XLS95 - файл Excel95 XLS97 - файл Excel97 XLSX - файл Excel2010 Код 1C v 8.3 // Получаем таблицу значения из файла.
Функция ЗагрузитьТЗизФайла(ИмяФайла)
Путь = КаталогВременныхФайлов() + ИмяФайла;
Текст = Новый ЧтениеТекста(Путь, КодировкаТекста.UTF8);
стрТЗ = Текст.Прочитать();
Текст.Закрыть();
// получим таблицу значений из строки
ТЗ = ЗначениеИзСтрокиВнутр(стрТЗ);
Возврат ТЗ;
КонецФункции
// Заполнить ячейки в строке значениями
//
Функция ЗаписьТЗ2ТабДок(записьТЗ,НомерСтроки,ТабличныйДокумент)
НомерКолонки = 1;
Символ160 = Символ(160);
// цикл по колонкам таблицы
// РезультатЗапроса.Колонки.Количество() // - количество колонок
Для каждого полеТЗ из ЗаписьТЗ цикл
// значения ячейки в Excel
типПоляТЗ = ТипЗнч(полеТЗ);
если типПоляТЗ = Тип("Число") тогда
полеТЗ=Строка(полеТЗ);
полеТЗ=СтрЗаменить(полеТЗ,Символ160,"");
полеТЗ=СтрЗаменить(полеТЗ,",",".");
иначеесли типПоляТЗ = Тип("Строка") тогда
иначе
полеТЗ = строка(полеТЗ);
КонецЕсли;
имяОбласти = "R" + номерСтроки + "C" + НомерКолонки;
имяОбласти = СтрЗаменить(имяОбласти,Символ(160),"");
Ячейка = ТабличныйДокумент.Область(имяОбласти);
Ячейка.Текст = полеТЗ;
НомерКолонки = НомерКолонки + 1;
КонецЦикла;
КонецФункции
// Заполнить наименованиями колонок таблицу
Функция НаимКолонок2Mxl(ТаблицаЗначений,ТабличныйДокумент)
// массКолонки = новый массив();
номерСтроки=1;
номКолонки=1;
ТабличныйДокумент = новый ТабличныйДокумент;
// цикл по коллекции колонок
Для НомКол=0 по ТаблицаЗначений.Колонки.Количество() - 1 Цикл
//Сообщить(Колонка.Имя + "(" + Колонка.ТипЗначения + ")" );
имяКолонки=ТаблицаЗначений.Колонки[НомКол].Имя;
//ТабличныйДокумент.Область(
имяОбласти = "R" + номерСтроки + "C" + номКолонки;
имяОбласти = СтрЗаменить(имяОбласти,Символ(160),"");
Ячейка = ТабличныйДокумент.Область(имяОбласти);
//значениеЯчейки = СтрЗаменить(имяОбласти,Символ(160),"");
Ячейка.Текст = имяКолонки;
// на основе текущего шрифта сделаем Жирный
ЖирныйШрифт = ?(ЖирныйШрифт = Неопределено,Новый Шрифт(Ячейка.Шрифт,,,Истина),ЖирныйШрифт);
Ячейка.Шрифт = ЖирныйШрифт;
номКолонки = номКолонки + 1;
КонецЦикла;
КонецФункции
// Заполнить построчно табличный документ
Функция Таблица2Mxl(ТаблицаЗначений,ТабличныйДокумент)
//Выборка = РезультатЗапроса.Выбрать();
НомСтр=1; // заполняем данными начиная со 2-й строки
// цикл по строкам таблицы
Для каждого записьТЗ из ТаблицаЗначений Цикл
НомСтр = НомСтр + 1;
// цикл по колонкам таблицы
ЗаписьТЗ2ТабДок(записьТЗ,НомСтр,ТабличныйДокумент);
КонецЦикла;
КонецФункции
// Таблица значений в табличный документ
Функция ТаблицаЗначений2Mxl(ТаблицаЗначений,ФайлMxl)
ТабличныйДокумент = новый ТабличныйДокумент;
// вывести колонки
НаимКолонок2Mxl(ТаблицаЗначений,ТабличныйДокумент);
// вывести содержимое таблицы
Таблица2Mxl(ТаблицаЗначений,ТабличныйДокумент);
ТабличныйДокумент.Записать(ФайлMxl,ТипФайлаТабличногоДокумента.MXL);
ТабличныйДокумент.Показать(ФайлMxl,ФайлMxl);
Возврат 0;
КонецФункции
Функция Тест_ВыгрузитьТЗвMxl();
файл_мТЗИсходныеДанные = "мТЗИсходныеДанные.dat";
ТЗ = ЗагрузитьТЗизФайла(файл_мТЗИсходныеДанные);
ФайлMxl = КаталогВременныхФайлов() + СтрЗаменить(файл_мТЗИсходныеДанные,".dat",".mxl");
ТаблицаЗначений2Mxl(ТЗ,ФайлMxl);
КонецФункции
Тест_ВыгрузитьТЗвMxl();
Пример выгруженной таблицы значений в файл:
Категория:
Работа с Таблицей Значений Фоновые задания 1С, примеры работы и параллельного запуска В рамках выполнения проекта столкнулся с интересной задачей ускорения загрузки данных из других информационных баз. Задача загрузки данных предполагала выполнение к внешней базе несвязанных между собой запросов, результаты которых помещаются в одну таблицу значений. Когда на оптимизацию запроса рука уже не поднималась, приступил к ускорению загрузки с помощью распараллеливания процессов. Отмечу, что элементы кода в данном посте приведены для клиент-серверного варианта и укрупнено для общего понимания подхода.
Что у нас в 1с Предприятии 8.2 имеется для распараллеливания & это фоновые задачи . Метод, который будет вызываться в фоновой задаче, должен быть прописан в серверном общем модуле и быть экспортным. Естественно нам понадобиться в фоновую задачу передавать и забирать значения.
В моем случае передача значений в фоновую задачу происходила через параметры. Метод ЗагрузитьИзВИБ имеет два параметра это ВходнойПараметр и АдресВХранилище. ВходнойПараметр это структура, в которую сгружаются все данные, необходимые для проведения загрузки. АдресВХранилище это адрес во временном хранилище, по которому будет передан результат загрузки. Сам код метода фонового задания выглядит так:
Код 1C v 8.х Процедура ЗагрузитьИзВИБ(ВходнойПараметр,АдресВХранилище) Экспорт
//Из структуры перегоняем данные в переменные
ТаблицаДляЗаполнения = ВходнойПараметр.ТаблицаДляЗаполнения;
ДанныеОбъекта = ВходнойПараметр.ДанныеОбъекта;
//Тут идет собственно загрузка данных
ВыполнитьЗагрузку(ТаблицаДляЗаполнения,ДанныеОбъекта);
//Возвращаем данные из фоновой задачи в хранилище
ПоместитьВоВременноеХранилище(ТаблицаДляЗаполнения, АдресВХранилище);
КонецПроцедуры
Зачем нам в фоновую задачу передавать адрес во временном хранилище. Наша фоновая задача должна куда-то положить результат, причем так чтобы мы знали где его потом взять.
Для того чтобы запустить фоновые задачи выполняется следующий код:
Код 1C v 8.х МассивАдресовВХранилище = Новый Массив;
МассивЗапущенныхЗаданий = Новый Массив;
Сч = 1;
Пока Сч <= КоличествоПотоков Цикл
Ключ = Новый УникальныйИдентификатор;
ВходнойПараметр = Новый Структура;
ВходнойПараметр.Вставить("ТаблицаДляЗаполнения",ТаблицаДляЗаполнения);
ВходнойПараметр.Вставить("ДанныеОбъекта",ДанныеОбъекта);
//Подготовим адрес в хранилище
АдресВХранилище = ПоместитьВоВременноеХранилище(Неопределено);
МассивПараметров = Новый Массив;
МассивПараметров.Добавить(ВходнойПараметр);
МассивПараметров.Добавить(АдресВХранилище);
МассивАдресовВХранилище.Добавить(АдресВХранилище);
МассивЗапущенныхЗаданий.Добавить(ФоновыеЗадания.Выполнить("ОбщийМодульСервер.ЗагрузитьИзВИБ",МассивПараметров, Ключ, "Загрузка"));
Сч = Сч + 1;
КонецЦикла;
Перед запуском фоновой задачи через ФоновыеЗадания.Выполнить() мы формируем массив параметров. Значения из массива параметров переходят в метод фонового задания в качестве параметров. В МассивЗапущенныхЗаданий хранятся все фоновые задачи, которые мы запустили. Теперь надо подождать их ожидания.
ФоновыеЗадания.ОжидатьЗавершения(МассивЗапущенныхЗаданий);
После того как все задачи были завершены, можем приступить к получению из них данных. Для этого мы проходим по всем адресам в хранилище, которые хранятся в массиве МассивАдресовВХранилище . После получения результата фонового задания перегоняем его в общую таблицу.
Код 1C v 8.х Для Каждого ТекАдресВХранилище Из МассивАдресовВХранилище Цикл
ТекТаблица = ПолучитьИзВременногоХранилища(ТекАдресВХранилище);
Для Каждого ТекСтрокаДанные Из ТекТаблица Цикл
НоваяСтрока = НашаОбщаяТаблица.Добавить();
ЗаполнитьЗначенияСвойств(НоваяСтрока,ТекСтрокаДанные);
КонецЦикла;
КонецЦикла;
Вопрос определения оптимального количества потоков выходит за рамки данного поста. А после получения некоторых результатов на рабочих данных пока что выходит и за рамки моего сознания . Но если у вас есть идеи как посчитать нужное количество потоков, пишите в комментариях, с радостью почитаю.
Источник
Категория:
Регламентные задания, Фоновые задания 1С 7.x : Как получить курсы валют с сайта НБУ http://www.bank.gov.ua/ за любую дату ? Код 1C v 7.x
Функция ПолучитьТаблицуКурсовНБУ(ДатаКурса, Ежедневно = 1) // если в качестве второго параметра указать число отличное от 1 - получем валюты, которые котируются на ежемесячной основе
Перем Reader, Url, Точки, HtmlTab, Строк, Р, НомСтроки, НомЯчейки, Док, ТекстВЯчейке, ТабКурсов;
Url = "http://www.bank.gov.ua/control/uk/curmetal/currency/search?formType=searchFormDate&time_step=" + ?(Ежедневно = 1, "daily", "monthly") +
"&date=" + Формат(ДатаКурса, "ДДДММГГГГ") + "&outer=table&execute=run&time=" + _GetPerformanceCounter();
Сообщить(Url);
Reader = СоздатьОбъект("MSXML2.XMLHTTP");
Reader.Open("Get", Url, 0);
Reader.Send();
Пока Reader.ReadyState <> 4 Цикл
Состояние("Чтение данных за <" + ДатаКурса + "> ");
КонецЦикла;
Док = СоздатьОбъект("HtmlFile");
Док.open("text/html");
Док.write(Reader.ResponseText);
Док.close();
HtmlTab = Док.getElementsByTagName("table").item(5);
ТабКурсов = СоздатьОбъект("ТаблицаЗначений");
ТабКурсов.НоваяКолонка("ЦифрКод" , "Строка", 3, , "Цифр. код");
ТабКурсов.НоваяКолонка("БуквКод" , "Строка", 3, , "Букв. код");
ТабКурсов.НоваяКолонка("Название" , "Строка");
ТабКурсов.НоваяКолонка("Курс" , "Число" ,14, 4);
ТабКурсов.НоваяКолонка("Кратность" , "Число" , 9, 0);
Строк = HtmlTab.rows.length;
Для НомСтроки = 1 По Строк Цикл
Р = HtmlTab.rows(НомСтроки - 1);
Если (НомСтроки = 1) Или (Р.cells.length <> 5) Тогда // 1 - я заголовок, остальные не с данными
Продолжить;
КонецЕсли;
ТабКурсов.НоваяСтрока();
ТабКурсов.ЦифрКод = СокрЛП(Р.cells(0).innerText);
ТабКурсов.БуквКод = СокрЛП(Р.cells(1).innerText);
ТабКурсов.Название = СокрЛП(Р.cells(3).innerText);
ТабКурсов.Курс = 0 + СтрЗаменить(СокрЛП(Р.cells(4).innerText), " ", "");
ТабКурсов.Кратность = 0 + СтрЗаменить(СокрЛП(Р.cells(2).innerText), " ", "");
КонецЦикла;
Reader = 0;
ТабКурсов.ВыбратьСтроку(, "Курсы за " + ДатаКурса);
Возврат ТабКурсов;
КонецФункции
Категория:
HTML, JS, VML Как получить курсы валют с сайта http://finance.ua/ за любую дату ? Код 1C v 7.x
Функция ПолучитьТаблицуКурсов(ДатаКурса)
Перем Reader, Url, Точки, HtmlTab, Строк, Р, НомСтроки, НомЯчейки, Док, ТекстВЯчейке, ТабКурсов;
Reader = СоздатьОбъект("MSXML2.XMLHTTP");
Url = "http://tables.finance.ua/ru/currency/official/-/1/" + ДатаГод(ДатаКурса) + "/" + ДатаМесяц(ДатаКурса) + "/" + ДатаЧисло(ДатаКурса) + "?time=" + _GetPerformanceCounter();
Сообщить(Url);
Reader.Open("Get", Url, 0);
Reader.Send();
Пока Reader.ReadyState <> 4 Цикл
Состояние("Чтение данных за <" + ДатаКурса + "> ");
КонецЦикла;
Док = СоздатьОбъект("HtmlFile");
Док.open("text/html");
Док.write(Reader.ResponseText);
Док.close();
HtmlTab = Док.getElementByID("currency-official-table");
Строк = HtmlTab.rows.length;
ТабКурсов = СоздатьОбъект("ТаблицаЗначений");
ТабКурсов.НоваяКолонка("ЦифрКод" , "Строка", 3, , "Цифр. код");
ТабКурсов.НоваяКолонка("БуквКод" , "Строка", 3, , "Букв. код");
ТабКурсов.НоваяКолонка("Название" , "Строка");
ТабКурсов.НоваяКолонка("Курс" , "Число" ,14, 4);
ТабКурсов.НоваяКолонка("Кратность" , "Число" , 9, 0);
Для НомСтроки = 1 По Строк Цикл
Р = HtmlTab.rows(НомСтроки - 1);
Если (НомСтроки = 1) Или (Р.cells.length <> 7) Тогда // 1 - я заголовок, остальные не с данными
Продолжить;
КонецЕсли;
ТабКурсов.НоваяСтрока();
ТабКурсов.ЦифрКод = СокрЛП(Р.cells(0).innerText);
ТабКурсов.БуквКод = СокрЛП(Р.cells(1).innerText);
ТабКурсов.Название = СокрЛП(Р.cells(3).innerText);
ТабКурсов.Курс = 0 + СтрЗаменить(СокрЛП(Р.cells(4).innerText), " ", "");
ТабКурсов.Кратность = 0 + СтрЗаменить(СокрЛП(Р.cells(2).innerText), " ", "");
КонецЦикла;
Reader = 0;
ТабКурсов.ВыбратьСтроку(, "Курсы за " + ДатаКурса);
Возврат ТабКурсов;
КонецФункции
Категория:
HTML, JS, VML Пример создания внешней печатной формы для управляемого приложения Пример создания внешней печатной формы АКТа для Бухгалтерии 3.0
1. В конфигураторе 1C Предприятия 8 создаем внешнюю обработку (Файл->Новый->Внешняя обработка), задаем имя.
2. В модуле обработки пишем код. Постараюсь его максимально комментировать. Главное должно быть:
функция ПечатьВнешнейПечатнойФормы табличного документа - которая выведет данные в макет функция Печать - вызывается из конфигурации! в нее передается массив печатаемых объектов и функция СведенияОВнешнейОбработке(). Она необходима для регистрации печатной формы в справочнике ДополнительныеОтчетыИОбработки, в ней собирается структура с данными для подключения формы. Эта функция, а также ряд сопутствующих ей, практически одинаковы для всех печатных форм, поэтому их можно просто копировать в новую печатную форму ничего не меняя. Код 1C v 8.3 // Функция формирует табличный документ с Внешней печатной формой
//
// Возвращаемое значение:
// Табличный документ - печатная форма акта
Функция ПечатьВнешнейПечатнойФормы(МассивОбъектов, ОбъектыПечати, Подписант) Экспорт
ТабДок = новый ТабличныйДокумент;
Макет = ПолучитьМакет("Макет");
ОбластьШапки = Макет.ПолучитьОбласть("Шапка");
ОбластьДанные = Макет.ПолучитьОбласть("Данные");
ОбластьПодвал = Макет.ПолучитьОбласть("Подвал");
Запрос = новый запрос;
Запрос.УстановитьПараметр("МассивОбъектов",МассивОбъектов);
Запрос.Текст = "ВЫБРАТЬ
| РеализацияТоваровУслугТовары.Номенклатура,
| РеализацияТоваровУслугТовары.Сумма,
| РеализацияТоваровУслугТовары.Количество,
| РеализацияТоваровУслугТовары.Цена,
| РеализацияТоваровУслугТовары.Ссылка КАК Ссылка
|ИЗ
| Документ.РеализацияТоваровУслуг.Товары КАК РеализацияТоваровУслугТовары
|ГДЕ
| РеализацияТоваровУслугТовары.Ссылка В(&МассивОбъектов)
|
|ОБЪЕДИНИТЬ ВСЕ
|
|ВЫБРАТЬ
| РеализацияТоваровУслугУслуги.Номенклатура,
| РеализацияТоваровУслугУслуги.Сумма,
| РеализацияТоваровУслугУслуги.Количество,
| РеализацияТоваровУслугУслуги.Цена,
| РеализацияТоваровУслугУслуги.Ссылка
|ИЗ
| Документ.РеализацияТоваровУслуг.Услуги КАК РеализацияТоваровУслугУслуги
|ГДЕ
| РеализацияТоваровУслугУслуги.Ссылка В(&МассивОбъектов)
|
|УПОРЯДОЧИТЬ ПО
| Ссылка";
ОбщаяВыборка = Запрос.Выполнить().Выгрузить();
Для Каждого СсылкаНаОбъект из МассивОбъектов Цикл
ОбластьШапки.Параметры.ТекстЗаголовка = "Акт № "+СсылкаНаОбъект.Номер;
ОбластьШапки.Параметры.Организация = СсылкаНаОбъект.Организация;
ТабДок.Вывести(ОбластьШапки);
Отбор = Новый Структура;
Отбор.Вставить("Ссылка",СсылкаНаОбъект);
Выборка = ОбщаяВыборка.НайтиСтроки(Отбор);
ИтогоСумма = 0;
ИтогоКоличество = 0;
Для Каждого Стр из Выборка Цикл
ЗаполнитьЗначенияСвойств(ОбластьДанные.Параметры,Стр);
ИтогоСумма = ИтогоСумма + Стр.Сумма;
ИтогоКоличество = ИтогоКоличество + Стр.Количество;
ТабДок.Вывести(ОбластьДанные);
КонецЦикла;
ОбластьПодвал.Параметры.ИтогоСумма = ИтогоСумма;
ОбластьПодвал.Параметры.Подписант = Подписант;
ТабДок.Вывести(ОбластьПодвал);
ТабДок.ВывестиГоризонтальныйРазделительСтраниц();
КонецЦикла;
Возврат ТабДок;
КонецФункции
// Экспортная процедура печати, вызываемая из основной программы
//
// Параметры:
// ВХОДЯЩИЕ:
// МассивОбъектовНазначения - Массив - список объектов ссылочного типа для печати документа
// Как правило, содержит один элемент с ссылкой на вызвавший форму объект (документ, справочник)
//
// ИСХОДЯЩИЕ:
// КоллекцияПечатныхФорм - ТаблицаЗначений - таблица сформированных табличных документов.
// Как правило, содержит одну строку с именем текущей печатной формы
// ОбъектыПечати - СписокЗначений - список объектов печати.
// ПараметрыВывода - Структура - Параметры сформированных табличных документов. Содержит поля:
// ДоступнаПечатьПоКомплектно - булево - по умолчанию Ложь
// ПолучательЭлектронногоПисьма
// ОтправительЭлектронногоПисьма
//
Процедура Печать(МассивОбъектовНазначения, КоллекцияПечатныхФорм, ОбъектыПечати, ПараметрыВывода) Экспорт
Если УправлениеПечатью.НужноПечататьМакет(КоллекцияПечатныхФорм, "АКТПечатьВнешняя") Тогда
ТабличныйДокумент = ПечатьВнешнейПечатнойФормы(МассивОбъектовНазначения, ОбъектыПечати, "");
УправлениеПечатью.ВывестиТабличныйДокументВКоллекцию(КоллекцияПечатныхФорм, "АКТПечатьВнешняя", "АКТ (внешний)", ТабличныйДокумент);
ИначеЕсли УправлениеПечатью.НужноПечататьМакет(КоллекцияПечатныхФорм, "АКТПечатьВнешняяИван") Тогда
ТабличныйДокумент = ПечатьВнешнейПечатнойФормы(МассивОбъектовНазначения, ОбъектыПечати, "Иванов А.Ю.");
УправлениеПечатью.ВывестиТабличныйДокументВКоллекцию(КоллекцияПечатныхФорм, "АКТПечатьВнешняяИван", "АКТ (внешний) Иванов", ТабличныйДокумент);
ИначеЕсли УправлениеПечатью.НужноПечататьМакет(КоллекцияПечатныхФорм, "АКТПечатьВнешняяПетр") Тогда
ТабличныйДокумент = ПечатьВнешнейПечатнойФормы(МассивОбъектовНазначения, ОбъектыПечати, "Петров В.С.");
УправлениеПечатью.ВывестиТабличныйДокументВКоллекцию(КоллекцияПечатныхФорм, "АКТПечатьВнешняяПетр", "АКТ (внешний) Петров", ТабличныйДокумент);
КонецЕсли;
КонецПроцедуры
#Область СведенияОВнешнейОбработке
// Сервисная экспортная функция. Вызывается в основной программе при регистрации обработки в информационной базе
// Возвращает структуру с параметрами регистрации
//
// Возвращаемое значение:
// Структура с полями:
// Вид - строка, вид обработки, один из возможных: "ДополнительнаяОбработка", "ДополнительныйОтчет",
// "ЗаполнениеОбъекта", "Отчет", "ПечатнаяФорма", "СозданиеСвязанныхОбъектов"
// Назначение - Массив строк имен объектов метаданных в формате:
// <ИмяКлассаОбъектаМетаданного>.[ * | <ИмяОбъектаМетаданных>].
// Например, "Документ.СчетЗаказ" или "Справочник.*". Параметр имеет смысл только для назначаемых обработок, для глобальных может не задаваться.
// Наименование - строка - Наименование обработки, которым будет заполнено наименование элемента справочника по умолчанию.
// Информация - строка - Краткая информация или описание по обработке.
// Версия - строка - Версия обработки в формате “<старший номер>.<младший номер>” используется при загрузке обработок в информационную базу.
// БезопасныйРежим - булево - Принимает значение Истина или Ложь, в зависимости от того, требуется ли устанавливать или отключать безопасный режим
// исполнения обработок. Если истина, обработка будет запущена в безопасном режиме.
//
Функция СведенияОВнешнейОбработке() Экспорт
//Инициализируем структуру с параметрами регистрации
ПараметрыРегистрации = Новый Структура;
// Первый параметр, который мы должны указать - это какой вид обработки системе должна зарегистрировать.
// Допустимые типы: ДополнительнаяОбработка, ДополнительныйОтчет, ЗаполнениеОбъекта, Отчет, ПечатнаяФорма, СозданиеСвязанныхОбъектов
ПараметрыРегистрации.Вставить("Вид", "ПечатнаяФорма"); //может быть - ПечатнаяФорма, ЗаполнениеОбъекта, ДополнительныйОтчет, СозданиеСвязанныхОбъектов...
МассивНазначений = Новый Массив;
// Теперь нам необходимо передать в виде массива имен, к чему будет подключена наша ВПФ
// Имейте ввиду, что можно задать имя в таком виде: Документ.* - в этом случае обработка будет подключена ко всем документам в системе,
// которые поддерживают механизм ВПФ
МассивНазначений.Добавить("Документ.РеализацияТоваровУслуг"); //Указываем документ к которому делаем внешнюю печ. форму
ПараметрыРегистрации.Вставить("Назначение", МассивНазначений);
ПараметрыРегистрации.Вставить("Наименование", "АКТ (Внешний)"); //имя под которым обработка будет зарегестрирована в справочнике внешних обработок
ПараметрыРегистрации.Вставить("БезопасныйРежим", ЛОЖЬ); // Зададим право обработке на использование безопасного режима. Более подробно можно узнать в справке к платформе (метод УстановитьБезопасныйРежим)
ПараметрыРегистрации.Вставить("Версия", "1.0"); // эти два параметра играют больше информационную роль,
ПараметрыРегистрации.Вставить("Информация", "Дополнительная печатная форма"); // т.е. это то, что будет видеть пользователь в информации к обработке
// Создадим таблицу команд (подробнее смотрим ниже)
ТаблицаКоманд = ПолучитьТаблицуКоманд();
ДобавитьКоманду(ТаблицаКоманд, "Внешний: АКТ", "АКТПечатьВнешняя", "ВызовСерверногоМетода", Истина, "ПечатьMXL");
ДобавитьКоманду(ТаблицаКоманд, "Внешний: АКТ (Иванов)", "АКТПечатьВнешняяИван", "ВызовСерверногоМетода", Истина, "ПечатьMXL");
ДобавитьКоманду(ТаблицаКоманд, "Внешний: АКТ (Петров)", "АКТПечатьВнешняяПетр", "ВызовСерверногоМетода", Истина, "ПечатьMXL");
ПараметрыРегистрации.Вставить("Команды", ТаблицаКоманд);
Возврат ПараметрыРегистрации;
КонецФункции
#КонецОбласти
#Область Вспомогательное
// ВСПОМОГАТЕЛЬНЫЕ ПРОЦЕДУРЫ И ФУНКЦИИ РЕГИСТРАЦИИ ОБРАБОТКИ
// Формирует структуру с параметрами регистрации регистрации обработки в информационной базе
//
// Параметры:
// ОбъектыНазначенияФормы - Массив - Массив строк имен объектов метаданных в формате:
// <ИмяКлассаОбъектаМетаданного>.[ * | <ИмяОбъектаМетаданных>].
// или строка с именем объекта метаданных
// НаименованиеОбработки - строка - Наименование обработки, которым будет заполнено наименование элемента справочника по умолчанию.
// Необязательно, по умолчанию синоним или представление объекта
// Информация - строка - Краткая информация или описание обработки.
// Необязательно, по умолчанию комментарий объекта
// Версия - строка - Версия обработки в формате “<старший номер>.<младший номер>” используется при загрузке обработок в информационную базу.
//
//
// Возвращаемое значение:
// Структура
//
Функция ПолучитьПараметрыРегистрации(ОбъектыНазначенияФормы = Неопределено, НаименованиеОбработки = "", Информация = "", Версия = "1.0")
Если ТипЗнч(ОбъектыНазначенияФормы) = Тип("Строка") Тогда
ОбъектНазначенияФормы = ОбъектыНазначенияФормы;
ОбъектыНазначенияФормы = Новый Массив;
ОбъектыНазначенияФормы.Добавить(ОбъектНазначенияФормы);
КонецЕсли;
ПараметрыРегистрации = Новый Структура;
ПараметрыРегистрации.Вставить("Вид", "ПечатнаяФорма");
ПараметрыРегистрации.Вставить("БезопасныйРежим", Истина);
ПараметрыРегистрации.Вставить("Назначение", ОбъектыНазначенияФормы);
Если Не ЗначениеЗаполнено(НаименованиеОбработки) Тогда
НаименованиеОбработки = ЭтотОбъект.Метаданные().Представление();
КонецЕсли;
ПараметрыРегистрации.Вставить("Наименование", НаименованиеОбработки);
Если Не ЗначениеЗаполнено(Информация) Тогда
Информация = ЭтотОбъект.Метаданные().Комментарий;
КонецЕсли;
ПараметрыРегистрации.Вставить("Информация", Информация);
ПараметрыРегистрации.Вставить("Версия", Версия);
Возврат ПараметрыРегистрации;
КонецФункции
// Формирует таблицу значений с командами печати
//
// Возвращаемое значение:
// ТаблицаЗначений
//
Функция ПолучитьТаблицуКоманд()
Команды = Новый ТаблицаЗначений;
//Представление команды в пользовательском интерфейсе
Команды.Колонки.Добавить("Представление", Новый ОписаниеТипов("Строка"));
//Уникальный идентификатор команды или имя макета печати
Команды.Колонки.Добавить("Идентификатор", Новый ОписаниеТипов("Строка"));
//Способ вызова команды: "ОткрытиеФормы", "ВызовКлиентскогоМетода", "ВызовСерверногоМетода"
// "ОткрытиеФормы" - применяется только для отчетов и дополнительных отчетов
// "ВызовКлиентскогоМетода" - вызов процедуры Печать(), определённой в модуле формы обработки
// "ВызовСерверногоМетода" - вызов процедуры Печать(), определённой в модуле объекта обработки
Команды.Колонки.Добавить("Использование", Новый ОписаниеТипов("Строка"));
//Показывать оповещение.
//Если Истина, требуется показать оповещение при начале и при завершении работы обработки.
//Имеет смысл только при запуске обработки без открытия формы
Команды.Колонки.Добавить("ПоказыватьОповещение", Новый ОписаниеТипов("Булево"));
//Дополнительный модификатор команды.
//Используется для дополнительных обработок печатных форм на основе табличных макетов.
//Для таких команд должен содержать строку ПечатьMXL
Команды.Колонки.Добавить("Модификатор", Новый ОписаниеТипов("Строка"));
Возврат Команды;
КонецФункции
// Вспомогательная процедура.
//
Процедура ДобавитьКоманду(ТаблицаКоманд, Представление, Идентификатор, Использование = "ВызовСерверногоМетода", ПоказыватьОповещение = Ложь, Модификатор = "ПечатьMXL")
НоваяКоманда = ТаблицаКоманд.Добавить();
НоваяКоманда.Представление = Представление;
НоваяКоманда.Идентификатор = Идентификатор;
НоваяКоманда.Использование = Использование;
НоваяКоманда.ПоказыватьОповещение = ПоказыватьОповещение;
НоваяКоманда.Модификатор = Модификатор;
КонецПроцедуры
#КонецОбласти
3. Добавляем макет вывода печатной формы:
4. Сохраняем и добавляем в конфигурацию:
Подключается через Администрирование - Печатные формы, отчеты и обработки:
Создаете новую обработку, записывайте и при открытии документа Реализация, нажав на Печать - появляются доступные печатные формы с разными подписывающими.
Скачать Шаблон внешней печатной формы для управляемого приложения
Категория:
Внешние печатные формы, отчеты и обработк… Отправка почты 1с 7.7 CDO.Configuration. Відправлення почти 1с 7.7 CDO.Configuration [c7]
Процедура глОтправитьПочту(АдресПолучателя = "",ТемаПисьма = "",ТелоПисьма = "",ТзЕмейл = "") Экспорт
iConf = CreateObject("CDO.Configuration");
iMsg = CreateObject("CDO.Message");
iMsg.Configuration = iConf;
iMsg.From = "Программист 1с"""" <primer@mail.ru>";
iMsg.To = АдресПолучателя;
iMsg.Subject = ТемаПисьма;
iMsg.textBody = ТелоПисьма;
iMsg.BodyPart.Charset = "windows-1251";
//В таблицу значений передаю файлы вложения
ТзЕмейл.ВыбратьСтроки();
Пока ТзЕмейл.ПолучитьСтроку() = 1 Цикл
iMsg.AddAttachment(СокрЛП(ТзЕмейл.ПутьКФайлу));
//iMsg.AddAttachment("D:\1.txt");
КонецЦикла;
iConf.Fields.Item("
Категория:
Работа с Интернет, Почтой (Mail), FTP Как мы писали парсер сайта с ценами для 1С Недавно, мой постоянный клиент решил проводить маркетинговые исследования по изменению цен на товары у конкурентов... и эти данные захотел использовать в 1С в связке с его прайс-листом + куча отчетов с графиками и процентным отклонением от цен основного конкурента
В результате этого, была написана обработка собирающая данные со страниц разных сайтов. Из целей конфиденциальности - сайты раскрывать не буду...
Вид обработки загрузки данных с сайта в 1С
Ниже код загрузки данных со страницы сайта , смысл такой :
в функция передается адрес страницы сайта полученный текст страницы обрабатывается, удаляются теги из полученного текста формируется ТЗ с данными По названию ищется поставщик из вспомогательного справочника Справочники.Pr_Поставщики.НайтиПоНаименованию(, если нет - создается на выходе ТЗ с данными Код 1C v 8.х Функция ПолучитьТаблицуДанных(Строка)
тзДанных = Новый ТаблицаЗначений;
Сервер = "site.ru";
Соединение = Новый HTTPСоединение(Сервер);
Заголовки = Новый Соответствие;
Заголовки.Вставить("host", Сервер);
ТекАдрес = СтрЗаменить(Строка.Наименование.УРЛСтраницы,"http://","");
ТекАдрес = СтрЗаменить(ТекАдрес,Сервер,"");
Запрос = Новый HTTPЗапрос(ТекАдрес, Заголовки);
Ответ =Соединение.Получить(Запрос);
Если Ответ.КодСостояния = 200 Тогда // Данные получены, обрабатываем их
Содержимое= Ответ.ПолучитьТелоКакСтроку();
//Выведем тест полученной страницы
НачалоБлока = "<table id=" + """" + "table-price" + """" + " cellspacing=" + """" + "0" + """" + " border=" + """" + "1" + """" + " bordercolor=" + """" + "#dedede" + """" + " class=" + """" + "tablesorter" + """" + " >";
//НачалоБлока = "<div class=" + """" + "w100fl" + """" + " id=" + """" + "kurs" + """" + ">";
КонецБлока = "</table>";
ТекстБлока = Сред(Содержимое, Найти(Содержимое, НачалоБлока) + СтрДлина(НачалоБлока), Найти(Содержимое, КонецБлока) - Найти(Содержимое, НачалоБлока) - СтрДлина(НачалоБлока));
//Обработаем тест
обрТекст = СтрЗаменить(ТекстБлока,"<tr>","");
обрТекст = СтрЗаменить(обрТекст,"</tr>",Символы.ПС);
обрТекст = СтрЗаменить(обрТекст," >", ">");
обрТекст = СтрЗаменить(обрТекст,"</th> <th>", " | ");
обрТекст = СтрЗаменить(обрТекст,"</td> <td>", " | ");
обрТекст = СтрЗаменить(обрТекст,"</th> <th class=" + """" + "sortable_header" + """" + ">", " | ");
обрТекст = СтрЗаменить(обрТекст,"</th> <th >", " | ");
обрТекст = СтрЗаменить(обрТекст,"</th><th>", " | ");
обрТекст = СтрЗаменить(обрТекст,"</td><td>", " | ");
обрТекст = СтрЗаменить(обрТекст," >", ">");
RegExp = Новый COMОбъект("VBScript.RegExp");
RegExp.IgnoreCase = Ложь;
RegExp.Global = Истина;
RegExp.MultiLine = Истина;
RegExp.Pattern = "<[^>]*>"; //Ищем теги HTML
обрТекст=RegExp.Replace(обрТекст, "");
//Сообщить(обрТекст);
Если СокрЛП(обрТекст) = "Ни одной позиции не найдено." Тогда
Сообщить(Строка(Строка.Наименование)+ " = Ни одной позиции не найдено! Строка " + Строка.Наименование);
Возврат тзДанных;
КонецЕсли;
Если Найти(обрТекст, "Страница не найдена") > 0 Тогда
Сообщить(Строка(ТекАдрес)+" = Страница не найдена, строка " + Строка.Наименование);
Возврат тзДанных;
КонецЕсли;
//Преобразуем полученный текст в таблицу
Для н=1 По СтрЧислоСтрок(обрТекст)Цикл
СтрТекста=СтрПолучитьСтроку(обрТекст,н);
Если Найти(СтрТекста, "Длина Цена") > 0 Тогда
СтрТекста = СтрЗаменить(СтрТекста, "Длина Цена", "Длина | Цена");
КонецЕсли;
Если Найти(СтрТекста, "Марка стали Цена") > 0 Тогда
СтрТекста = СтрЗаменить(СтрТекста, "Марка стали Цена", "Марка стали | Цена");
КонецЕсли;
Если Найти(СтрТекста, ", Поставщик") > 0 Тогда
СтрТекста = СтрЗаменить(СтрТекста, ", Поставщик", " | Поставщик");
КонецЕсли;
//Выводим текст страницы построчно
мсДанных = ПолучитьМассивИзСтрокиСРазделителем(СтрТекста, "|", Истина);
Если н=1 Тогда
Для Каждого ткЗнач из мсДанных Цикл
СтрЗапрещСимволов = " .,<>""\/-";
ИмяКолонки = ткЗнач;
Для сч33 = 1 по СтрДлина(СтрЗапрещСимволов) Цикл
ЗапрещСимв = Сред(СтрЗапрещСимволов, сч33, 1);
ИмяКолонки = СтрЗаменить(ИмяКолонки, ЗапрещСимв, "_");
КонецЦикла;
// добавим нужное количество колонок- если перед колонкой Поставщик не хватает
// бывает, что в шапке определяется меньше колонок, чем реально в таблице
Если НРег(ИмяКолонки) = "поставщик" Тогда
Для Сч_дк = (Строка.Наименование.Родитель.Поставшик - 2) по тзДанных.Колонки.Количество() Цикл
тзДанных.Колонки.Добавить("Колонка_" + (тзДанных.Колонки.Количество() + 1));
КонецЦикла;
КонецЕсли;
тзДанных.Колонки.Добавить(ИмяКолонки);
КонецЦикла;
тзДанных.Колонки.Добавить("ном", , , 7);
Иначе
НовСтр = тзДанных.Добавить(); нмас=0;
Для Каждого ткЗнач из мсДанных Цикл
НовСтр[нмас] = ткЗнач;
нмас=нмас+1;
КонецЦикла;
НовСтр.ном = н;
КонецЕсли;
//Сообщить(стр);
КонецЦикла;
тзДанных.Колонки.Добавить("ЕстьСоответствие", Новый ОписаниеТипов("Булево"));
тзДанных.Колонки.Добавить("СпрPr_Поставщики", Новый ОписаниеТипов("СправочникСсылка.Pr_Поставщики"));
Для каждого стр из тзДанных Цикл
текПоставщик = Справочники.Pr_Поставщики.НайтиПоНаименованию(стр[Строка.Наименование.родитель.Поставшик-1]);
Если текПоставщик = Справочники.Pr_Поставщики.ПустаяСсылка() Тогда
НовЭлем = Справочники.Pr_Поставщики.СоздатьЭлемент();
НовЭлем.Наименование = СокрЛП(стр[Строка.Наименование.родитель.Поставшик-1]);
НовЭлем.Записать();
текПоставщик = НовЭлем.Ссылка;
КонецЕсли;
стр.СпрPr_Поставщики = текПоставщик;
КонецЦикла;
Иначе
тзДанных.Колонки.Добавить("ЕстьСоответствие", Новый ОписаниеТипов("Булево"));
тзДанных.Колонки.Добавить("СпрPr_Поставщики", Новый ОписаниеТипов("СправочникСсылка.Pr_Поставщики"));
Сообщить("Ошибка получения данных для строки " + Строка.Наименование);
КонецЕсли;
Возврат тзДанных;
КонецФункции
В коде используется вспомогательная функция ПолучитьМассивИзСтрокиСРазделителем
Код 1C v 8.2 УП // Функция разбивает строку разделителем.
//
// Параметры:
// пСтрока - Строка - которую разбиваем;
// *пРазделитель - Строка, "." - символ-разделитель;
// *ОбрезатьНепечатныеСимволы - Булево, *Ложь.
//
// Возвращаемое значение:
// Массив - фрагментов.
//
Функция ПолучитьМассивИзСтрокиСРазделителем(Знач Стр, Разделитель = ".", ОбрезатьНепечатныеСимволы = Ложь) Экспорт
МассивСтрок = Новый Массив;
Если Разделитель = " " Тогда
Стр = СокрЛП(Стр);
Пока 1=1 Цикл
Поз = Найти(Стр,Разделитель);
Если Поз=0 Тогда
МассивСтрок.Добавить(Стр);
Возврат МассивСтрок;
КонецЕсли;
МассивСтрок.Добавить(Лев(Стр,Поз-1));
Стр = СокрЛ(Сред(Стр,Поз));
КонецЦикла;
Иначе
ДлинаРазделителя = СтрДлина(Разделитель);
Пока 1=1 Цикл
Поз = Найти(Стр,Разделитель);
Если Поз=0 Тогда
Фрагмент = Стр;
Если ОбрезатьНепечатныеСимволы Тогда
Фрагмент = СокрЛП(Фрагмент);
КонецЕсли;
МассивСтрок.Добавить(Фрагмент);
Возврат МассивСтрок;
КонецЕсли;
Фрагмент = Лев(Стр,Поз-1);
Если ОбрезатьНепечатныеСимволы Тогда
Фрагмент = СокрЛП(Фрагмент);
КонецЕсли;
МассивСтрок.Добавить(Фрагмент);
Стр = Сред(Стр,Поз+ДлинаРазделителя);
КонецЦикла;
КонецЕсли;
Возврат МассивСтрок;
КонецФункции // ПолучитьМассивИзСтрокиСРазделителем()
Конечно, перед тем как мы начали это делать - прошерстили интернет и нашли несколько решений , вот они:
Код 1C v 8.х Соединение = ПолучитьCOMОбъект("","Microsoft.XMLHTTP");
ИмяВременногоФайла=ПолучитьИмяВременногоФайла("htm");
Соединение.open("GET", "http://mamba.ru/my", 0);
Соединение.send();
//status: //404 - Not Found //200 - Ok
ТаймАут = 200;
Начало=ТекущаяДата();
Пока Соединение.readyState <> 4 И (ТаймАут=0 ИЛИ ТекущаяДата()-Начало<ТаймАут) Цикл
бфДиалоги.ксОбработкаПрерыванияПользователя();
КонецЦикла;
//Сохраняем во временный файл
обСохранитьДвоичныйБуферВФайл(Соединение.responseBody, ИмяВременногоФайла);
Соединение.open("POST", "http://mamba.ru/my");
Соединение.send("login=xxx&password=&&&");
Функция обСохранитьДвоичныйБуферВФайл(Буфер, ИмяФайла) Экспорт
Поток = Новый COMОбъект("ADODB.Stream");
Поток.Type = 1; //Бинарный
Поток.Mode = 3;
Поток.Open();
Поток.Write(Буфер);
Поток.SaveToFile(ИмяФайла);
Поток.Close();
КонецФункции
Код 1C v 8.х НТТР = ПолучитьCOMОбъект("","Microsoft.XMLHTTP");
ИмяФайлаОтвета = КаталогВременныхФайлов() + "filename.tmp";
НТТР.open("GET", "www.google.com",0,,);
НТТР.send();
StreamTypeEnum = Новый Структура("adTypeBinary, adTypeText", 1, 2);
ConnectModeEnum = Новый Структура(
"adModeRead, adModeReadWrite, adModeRecursive, adModeShareDenyNone,
|adModeShareDenyRead, adModeShareDenyWrite, adModeShareExclusive,
|adModeUnknown, adModeWrite", 1, 3, 4194304, 16, 4, 8, 12, 0, 2);
SaveOptionsEnum = Новый Структура("adSaveCreateNotExist, adSaveCreateOverWrite", 1, 2);
StreamOut = Новый COMОбъект("ADODB.Stream");
StreamOut.Type = StreamTypeEnum.adTypeBinary;
StreamOut.Mode = ConnectModeEnum.adModeReadWrite; //Нужны и чтение и запись
StreamOut.Open(); //Открыли на чтение и запись
StreamOut.Write(НТТР.responseBody);
StreamOut.SaveToFile(ИмяФайлаОтвета, SaveOptionsEnum.adSaveCreateOverWrite); //"2" - перезапись файла
StreamOut.Close();
И даже не этом сайте есть статья : Парсер сайта связного на 1С
Нужен парсер сайта в 1С!? - Обращайтесь, контакты в
профиле Категория:
Работа с Интернет, Почтой (Mail), FTP СКД Внешний источник данных, грузим из ТЗ и далее получаем остатки на каждый документ Очень часто бывают ситуации, когда необходимо сделать отчет СКД на сложном запросе, который используюет в себе вложенные запросы и объединения внутренние и полные и т.д. - в результате в консоли этот запрос формируется верно, а в скд половина полей пустые! Связано это с особенностью СКД в объединении внутренних данных, а так же не стоит забывать что в СКД наборы данных связываются как левое соединение...
Решения возможны следующие:
Изменить запрос в СКД Сформировать запрос обычным способом и подставить эти данные в СКД как внешние Рассмотрим последний вариант:
Внешний источник данных, грузим из ТЗ Для вывода отчета я использую шаблон All4CF.ru_Template_SKD_v4.1 в нем уже реализованы почти все необходимые функции и работает в Обычных и УП формах.
В модуле объекта уже есть функция
Код 1C v 8.2 УП Функция ПолучитьТаблицуВнешнегоНабораДанных()
Возврат Новый ТаблицаЗначений;
КонецФункции // ПолучитьТаблицуВнешнегоНабораДанных()
установим в ней наш запрос, получается примерно так:
Код 1C v 8.2 УП // В данной функции можно сформировать таблицу внешнего набора данных для СКД
//
// Функция должна возвращать таблицу данных (например таблицу значений)
//
Функция ПолучитьТаблицуВнешнегоНабораДанных()
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ РАЗРЕШЕННЫЕ РАЗЛИЧНЫЕ
| ВложенныйЗапрос.Регистратор КАК ДокРеал,
| ВложенныйЗапрос.Регистратор.Доставка КАК ДокДоставка
|ПОМЕСТИТЬ ОплаченнаяРеализация
|ИЗ
| (ВЫБРАТЬ
| ВзаиморасчетыСКонтрагентамиПоДокументамРасчетовОбороты.Регистратор КАК Регистратор
/////// Огромный запрос .......
| СГРУППИРОВАТЬ ПО
| ДоставкаПромежуточнаяНакладная.Ссылка,
| ДоставкаПромежуточнаяНакладная.Ссылка.Счет,
| ДоставкаПромежуточнаяНакладная.Ссылка.ВыставленоКлиенту,
| ИздержкиРаспределенныеНеНаОП.РаспределеннаяИздержка,
| ДоставкаПромежуточнаяНакладная.Ссылка.СтоимостьПрайс + ДоставкаПромежуточнаяНакладная.Ссылка.ЗатратыПриДоставке) КАК ДанныеПоДоставкам
| ПО ДанныеПоРеализации.ДокументПродажи.Доставка = ДанныеПоДоставкам.ДокДоставка";
Запрос.УстановитьПараметр("КонецПериода", НастройкаПериода.ДатаОкончания);
Запрос.УстановитьПараметр("НачалоПериода", НастройкаПериода.ДатаНачала);
Запрос.УстановитьПараметр("НачалоПериодаМинусГод", НастройкаПериода.ДатаНачала-(86400*365));
Результат = Запрос.Выполнить();
Выборка = Результат.Выгрузить();
Возврат Выборка;
КонецФункции // ПолучитьТаблицуВнешнегоНабораДанных()
Ниже в коде происходит установка внешних данных из нашей ТЗ с именем ТаблицаВнешнегоНабораДанных
Код 1C v 8.2 УП // при необходимости вставим внешние наборы данных в СКД
ВнешниеНаборыДанных = Новый Структура;
ТаблицаВнешнегоНабораДанных = ПолучитьТаблицуВнешнегоНабораДанных();
ВнешниеНаборыДанных.Вставить("ТаблицаВнешнегоНабораДанных",ТаблицаВнешнегоНабораДанных);
ПроцессорКомпоновкиДанных.Инициализировать(МакетКомпоновкиДанных,ВнешниеНаборыДанных,ДанныеРасшифровки);
ВывестиРезультатКомпоновкиСАвтофиксациейСтрок(ТабличныйДокумент, ПроцессорКомпоновкиДанных, ДанныеРасшифровки.Элементы,,,КоличествоФиксируемыхСтолбцов);
В самой компоновке добавляем набор Объект с именем ТаблицаВнешнегоНабораДанных и перечисляем поля, которые будут использоваться в отчете:
Как я уже говорил выше, далее нам необходимо получить остатки взаиморасчетов на дату документа:
Получение остатков на документ в СКД Набор данных Запрос - назвали его Остатки:
Теперь установим связи Запроса и Объекта
Остатки нужно получать на дату документа и по контрагенту
Далее, если нужно, задайте вычисляемые поля, ресурсы, параметры и Настройте Список вывода...
Пример результата отчета:
Категория:
Схема Компоновки Данных Как сформировать диаграмму с типом График В этом примере построим диаграмму с типом График , вида:
Вот код ее формирования:
Код 1C v 8.х Процедура ГрафикКолВоДоставок()
//Создаем таблицу данных
ТабД = Новый ТаблицаЗначений;
ТабД.Колонки.Добавить("ДатаК");
ТабД.Колонки.Добавить("Всего");
кп = КонПериодаЛ;
нп = кп-(86400);
Пока кп>НачПериодаЛ Цикл
Состояние("Кол-во Доставок на: "+ Строка(кп));
КоличествоДоставок = 0; Тоннаж = 0;
Привилегированный.ПолучитьКоличествоДоставок(кп, КоличествоДоставок, Тоннаж);
Нстр = ТабД.Добавить();
Нстр.ДатаК=кп;
Нстр.Всего = КоличествоДоставок;
кп = нп;
нп = кп-(86400);
КонецЦикла;
ДиаграммаВП = ЭлементыФормы.ДиаграммаКолВоДоставок;
ДиаграммаВП.КоличествоТочек=0;
ТабД.Сортировать("ДатаК Возр");
Для Каждого СтрТраб из ТабД Цикл
Точка=ДиаграммаВП.Точки.Добавить(Формат(СтрТраб.Получить(0),"ДФ=dd.MM"));
Индекс=0;
//Для Каждого Серия из ДиаграммаВП.Серии Цикл
Попытка
ДиаграммаВП.УстановитьЗначение(Точка,ДиаграммаВП.Серии[0],?(СтрТраб.Получить(1)=Неопределено,0,СтрТраб.Получить(1)));
Исключение
КонецПопытки;
КонецЦикла;
КонецПроцедуры
Категория:
Диаграмма Объектная модель схемы запроса Периодически во встроенном языке возникает необходимость изменения текста запроса в зависимости от разных алгоритмических условий. Раньше подобная задача решалась путём непосредственного формирования нужного текста запроса в виде строки. А это не всегда удобно и зачастую очень громоздко.
Теперь во встроенном языке мы реализовали объектную модель схемы запроса. Вы можете создать пустую схему запроса конструктором и загрузить в неё имеющийся текст запроса. После этого отдельные элементы текста запроса будут доступны вам как свойства объектной модели.
На рисунке ниже стрелки показывают, в каких объектах встроенного языка будут доступны те или иные элементы простого запроса, загруженного в схему:
Редактирование текста запроса с помощью объектной модели позволяет вам проще и понятнее модифицировать имеющиеся запросы. Или даже создавать их во встроенном языке «с нуля». А затем просто получать готовый текст запроса из схемы методом ПолучитьТекстЗапроса() .
Пример использования Схемы запроса Код 1C v 8.3 //Создание схемы запроса
СхемаЗапроса = Новый СхемаЗапроса;
ЗапросВыбораИзИБ = СхемаЗапроса.ПакетЗапросов[0];
//Установка свойств запроса
ЗапросВыбораИзИБ.ТаблицаДляПомещения = "ТаблицаОбороты";
ЗапросВыбораИзИБ.ВыбиратьРазрешенные = Истина;
//Добавляем операторы выбора первого запроса пакета
ОператорВыбораЗакупок = ЗапросВыбораИзИБ.Операторы[0];
ИсточникНоменклатура = ОператорВыбораЗакупок.Источники.Добавить("Справочник.Номенклатура","Товары");
//Добавляем запрос выбора из регистра закупок
ИсточникЗакупки = ОператорВыбораЗакупок.Источники.Добавить("РегистрНакопления.Закупки.Обороты","Закупки");
ИсточникЗакупки.Источник.Параметры[0].Выражение = Новый ВыражениеСхемыЗапроса("&Начало") ;
ИсточникЗакупки.Источник.Параметры[1].Выражение = Новый ВыражениеСхемыЗапроса("&Окончание") ;
ИсточникЗакупки.Источник.Параметры[2].Выражение = Новый ВыражениеСхемыЗапроса("Месяц") ;
//Меняем тип соединения
ИсточникЗакупки.Соединения[0].ТипСоединения = ТипСоединенияСхемыЗапроса.ПравоеВнешнее;
//Указываем выбираемые поля
ОператорВыбораЗакупок.ВыбираемыеПоля.Добавить("Товары.Ссылка");
ОператорВыбораЗакупок.ВыбираемыеПоля.Добавить("Закупки.Период");
ОператорВыбораЗакупок.ВыбираемыеПоля.Добавить("ЕСТЬNULL(Закупки.СуммаОборот, 0)");
ОператорВыбораЗакупок.ВыбираемыеПоля.Добавить("0");
//Указываем спевдонимы для выбранных полей
ЗапросВыбораИзИБ.Колонки[0].Псевдоним = "Номенклатура";
ЗапросВыбораИзИБ.Колонки[1].Псевдоним = "Период";
ЗапросВыбораИзИБ.Колонки[2].Псевдоним = "СуммаЗакупок";
ЗапросВыбораИзИБ.Колонки[3].Псевдоним = "СуммаПродаж";
//Добавляем отбор
ОператорВыбораЗакупок.Отбор.Добавить("НЕ Товары.ЭтоГруппа");
///////////////////////
//Выбираем данные о продажах
ОператорВыбораПродаж = ЗапросВыбораИзИБ.Операторы.Добавить();
ИсточникНоменклатура = ОператорВыбораПродаж.Источники.Добавить("Справочник.Номенклатура","Товары");
ОператорВыбораПродаж.ВыбираемыеПоля.Добавить("Товары.Ссылка");
//Добавляем источник РН и устанавливаем параметры
ИсточникПродажи =ОператорВыбораПродаж.Источники.Добавить("РегистрНакопления.Продажи.Обороты","Продажи");
ИсточникПродажи.Источник.Параметры[0].Выражение = Новый ВыражениеСхемыЗапроса("&Начало") ;
ИсточникПродажи.Источник.Параметры[1].Выражение = Новый ВыражениеСхемыЗапроса("&Окончание") ;
ИсточникПродажи.Источник.Параметры[2].Выражение = Новый ВыражениеСхемыЗапроса("Месяц") ;
ИсточникПродажи.Соединения[0].ТипСоединения = ТипСоединенияСхемыЗапроса.ПравоеВнешнее;
//Указываем отбираемые поля и устанавливаем для числовых полей соответствие с полями первого запроса
ОператорВыбораПродаж.ВыбираемыеПоля.Добавить("Продажи.Период");
ВыражениеЗакупки = ОператорВыбораПродаж.ВыбираемыеПоля.Добавить("0");
ВыражениеПродажи = ОператорВыбораПродаж.ВыбираемыеПоля.Добавить("ЕСТЬNULL(Продажи.СуммаОборот, 0)");
ЗапросВыбораИзИБ.Колонки[2].Поля.Установить(1,ВыражениеЗакупки);
ЗапросВыбораИзИБ.Колонки[3].Поля.Установить(1,ВыражениеПродажи);
//Добавляем отбор
ОператорВыбораПродаж.Отбор.Добавить("НЕ Товары.ЭтоГруппа");
//Индексируем данные
ЗапросВыбораИзИБ.Индекс.Добавить(ЗапросВыбораИзИБ.Колонки[0]);
ЗапросВыбораИзИБ.Индекс.Добавить(ЗапросВыбораИзИБ.Колонки[1]);
//Устанавливаем параметры выбора данных
ОператорВыбораПродаж.ВыбиратьРазличные = Истина;
ОператорВыбораПродаж.КоличествоПолучаемыхЗаписей = 100;
////////////////
//Второй пакет запроса
ЗапросВыбораИзВТ = СхемаЗапроса.ПакетЗапросов.Добавить();
ОператорВыбрать = ЗапросВыбораИзВТ.Операторы[0];
//Устанавливаем сформированную в прошлом запросе временную таблицу как источник
Источник = ОператорВыбрать.Источники.Добавить("ТаблицаОбороты","ТаблицаОбороты");
ОператорВыбрать.ВыбираемыеПоля.Добавить("ТаблицаОбороты.Номенклатура");
ОператорВыбрать.ВыбираемыеПоля.Добавить("ТаблицаОбороты.Период");
ОператорВыбрать.ВыбираемыеПоля.Добавить("СУММА(ТаблицаОбороты.СуммаЗакупок)");
ОператорВыбрать.ВыбираемыеПоля.Добавить("СУММА(ТаблицаОбороты.СуммаПродаж)");
//Условие отбора
ОператорВыбрать.Отбор.Добавить("СУММА(ТаблицаОбороты.СуммаЗакупок) > 0");
//Устанавливаем псевдонимы колонок
ЗапросВыбораИзВТ.Колонки[0].Псевдоним = "Номенклатура";
ЗапросВыбораИзВТ.Колонки[1].Псевдоним = "Период";
ЗапросВыбораИзВТ.Колонки[2].Псевдоним = "СуммаЗакупок";
ЗапросВыбораИзВТ.Колонки[3].Псевдоним = "СуммаПродаж";
//Порядок сортировки данных
ЗапросВыбораИзВТ.Порядок.Добавить(ЗапросВыбораИзВТ.Операторы[0].Источники[0].Источник.ДоступныеПоля[0].Поля[6]);
ЗапросВыбораИзВТ.Порядок.Добавить(ЗапросВыбораИзВТ.Колонки[1]);
//Итоги запроса
ИтогНоменклатура = ЗапросВыбораИзВТ.КонтрольныеТочкиИтогов.Добавить(ЗапросВыбораИзВТ.Колонки[0]);
ИтогНоменклатура.ТипКонтрольнойТочки = ТипКонтрольнойТочкиСхемыЗапроса.ТолькоИерархия;
ЗапросВыбораИзВТ.ОбщиеИтоги =Истина;
ЗапросВыбораИзВТ.ВыраженияИтогов.Добавить(ЗапросВыбораИзВТ.Колонки[2]);
ЗапросВыбораИзВТ.ВыраженияИтогов.Добавить(ЗапросВыбораИзВТ.Колонки[3]);
////////////////
//Последний запрос пакета - удаление временной таблицы
ЗапросУничтоженияВТ = СхемаЗапроса.ПакетЗапросов.Добавить(Тип("ЗапросУничтоженияТаблицыСхемыЗапроса"));
ЗапросУничтоженияВТ.ИмяТаблицы = "ТаблицаОбороты";
// ДАЛЕЕ ЕСЛИнам необходимо этот запрос модифицировать дальше в зависимости от настроек.
// Рассмотрим несколько примеров модификация нашего пакета из 3х запросов:
// Пример 1. Допустим, у нас есть переменные "Организация" и "Склад". И в случае, если они заполнены, нам необходимо добавить в отбор данных условия на эти переменные.
Если ЗначениеЗаполнено(Организация) Тогда
ОператорВыбораЗакупок.Отбор.Добавить("Закупки.Организация = &Организация");
ОператорВыбораПродаж.Отбор.Добавить("Продажи.Организация = &Организация");
КонецЕсли;
Если ЗначениеЗаполнено(Склад) Тогда
ОператорВыбораЗакупок.Отбор.Добавить("Закупки.Склад = &Склад");
ОператорВыбораПродаж.Отбор.Добавить("Продажи.Склад = &Склад");
КонецЕсли;
// Пример 2. Нам нужно отобрать товары, для которых последняя цена выше 1000руб. Т.е. необходимо
// 1. Добавить в текст запроса выбор во временную таблицу из регистра цен номенклатуры, по которой цены выше 1000руб.
// 2. Добавить при выборе данных условия по этой временной таблице в оба запроса выбора данных (закупки и продажи).
// Как вклиниваться в текстовый запрос для выполнения этих действий, вы пожете представить самостоятельно.
// Программно мы просто добавляем строки кода:
//Добавляем временную таблицу
ЗапросИзРегистраЦен = СхемаЗапроса.ПакетЗапросов.Добавить();
//Настраиваем временную таблицу
ЗапросИзРегистраЦен.ТаблицаДляПомещения = "ВТ_ЦеныНоменклатуры";
ОператорВыбрать = ЗапросИзРегистраЦен.Операторы[0];
Источник = ОператорВыбрать.Источники.Добавить("РегистрСведений.ЦеныНоменклатуры.СрезПоследних","ЦеныНоменклатурыСрезПоследних");
ОператорВыбрать.ВыбираемыеПоля.Добавить("ЦеныНоменклатурыСрезПоследних.Номенклатура");
ОператорВыбрать.Отбор.Добавить("ЦеныНоменклатурыСрезПоследних.Цена > &Цена");
//Сдвигаем новую табличку перед запросами выбора данных
СхемаЗапроса.ПакетЗапросов.Сдвинуть(СхемаЗапроса.ПакетЗапросов.Индекс(ЗапросИзРегистраЦен),0);
//Добавляем условия в исходные запросы
ОператорВыбораЗакупок.Отбор.Добавить("Закупки.Номенклатура В (ВЫБРАТЬ ВТ_ЦеныНоменклатуры.Номенклатура ИЗ ВТ_ЦеныНоменклатуры КАК ВТ_ЦеныНоменклатуры)");
ОператорВыбораПродаж.Отбор.Добавить("Продажи.Номенклатура В (ВЫБРАТЬ ВТ_ЦеныНоменклатуры.Номенклатура ИЗ ВТ_ЦеныНоменклатуры КАК ВТ_ЦеныНоменклатуры)");
// Еще один небольшой пример использования схемы запроса. Формирование запроса, выполняющего поиск задвоенных значений предопределенных данных.
// Без обращения к метаданным формирует один общий запрос ко всем справочникам, планам счетов, ПВХ, ПВР вцелом по конфигурации.
СхемаЗапроса = Новый СхемаЗапроса;
КоллекцияОператоры = СхемаЗапроса.ПакетЗапросов[0].Операторы;
Для каждого ГруппаТаблиц Из СхемаЗапроса.ПакетЗапросов[0].ДоступныеТаблицы Цикл
Если ГруппаТаблиц.Представление = "Справочники"
ИЛИ ГруппаТаблиц.Представление = "ПланыСчетов"
ИЛИ ГруппаТаблиц.Представление = "ПланыВидовРасчета"
ИЛИ ГруппаТаблиц.Представление = "ПланыВидовХарактеристик" Тогда
Для каждого Таблица Из ГруппаТаблиц.Состав Цикл
Для каждого ПолеТаблицы Из Таблица.Поля Цикл
Если ПолеТаблицы.Имя = "ИмяПредопределенныхДанных" Тогда
НовыйОператор = КоллекцияОператоры.Добавить();
НовыйИсточник = НовыйОператор.Источники.Добавить(Таблица,"СправочникИмя");
НовыйОператор.ВыбираемыеПоля.Добавить(""""+Таблица.Имя+"""");
НовыйОператор.ВыбираемыеПоля.Добавить("КОЛИЧЕСТВО(РАЗЛИЧНЫЕ СправочникИмя.ИмяПредопределенныхДанных)" );
НовыйОператор.Группировка.Добавить("СправочникИмя.ИмяПредопределенныхДанных");
НовыйОператор.Отбор.Добавить("СправочникИмя.Предопределенный");
НовыйОператор.Отбор.Добавить("КОЛИЧЕСТВО(РАЗЛИЧНЫЕ СправочникИмя.Ссылка) > 1");
Продолжить;
КонецЕсли;
КонецЦикла;
КонецЦикла;
КонецЕсли;
КонецЦикла;
Категория:
Запросы