Фреймворк представляет собой управляемую форму с набором элементов, процедур и функций, которые облегчают процесс разработки.
Задачи могут быть:
- простыми — состоять из одного шага;
- составными — состоять из нескольких шагов.
Для добавления простой задачи загрузки данных необходимо в области Инициализация в процедуру Инициализировать добавить вызов функции ДобавитьЗадачуЗагрузкиДанных. Например, для создания задачи загрузки справочника Товары мы добавим строку:
#Область Инициализация
&НаСервере
Процедура Инициализировать()
ДобавитьЗадачуЗагрузкиДанных("Товары", "Загрузка товаров");
КонецПроцедуры
#КонецОбласти
Функция ДобавитьЗадачуЗагрузкиДанных принимает 2 параметра:
- ИмяЗадачи — обязательный параметр, будет использоваться в коде.
- Синоним задачи — необязательный параметр для представления названия задачи в списке задач. Если синоним не указан, система сформирует представление из имени задачи, заменив все "_" на пробелы.
Провило замены "_" на " " работает для синонимов задач, шагов, параметров, колонок и таблиц.
Если в модуле нет процедуры Инициализировать, то система автоматически создаст задачу загрузки, взяв имя объекта обработки в качестве имени задачи. Это удобно, когда надо сделать обработку с одной задачей загрузки.
Задача загрузки данных предполагает обращение к файлу, а также наличие запроса (к табличному документу и данным базы) и процедуру записи данных.
Кроме простых задач загрузки можно добавлять простые задачи обработки данных. Такие задачи не обращаются к файлам. Пример создания:
Функция ДобавитьЗадачуОбработкиДанных(ИмяЗадачи)
Также можно добавлять составные задачи, которые состоят из нескольких шагов. Это полезно, когда между шагами требуются действия пользователя: например, выбор объектов к записи:
ОписаниеЗадачи = "Имя задачи, Синоним";
ОписаниеЭтапов = "
|Имя этапа, Синоним, Название кнопки, Запрос + Процедура, Стоп сообщение";
ЗадачиИЭтапы_ДобавитьЗадачуСЭтапами(ОписаниеЗадачи, ОписаниеЭтапов);
Автор рекомендует код каждой задачи оформлять в виде области. При этом названия методов, которые относятся к одной задаче, следует начинать с имени задачи:
#Область Товары
&НаСервере
Процедура Товары_ПриВыбореЗадачи()
…
КонецПроцедуры
&НаСервере
Функция Товары_ТекстЗапроса()
…
КонецФункции
&НаСервере
Процедура Товары()
…
КонецПроцедуры
#КонецОбласти
Процедура ИмяЗадачи_ПриВыбореЗадачи не является обязательной. Система будет пытаться ее вызвать, когда задача выбрана. Это может быть полезано для добавления параметров задачи. Например:
&НаСервере
Процедура Товары_ПриВыбореЗадачи()
ТипыПараметра = Новый Массив;
ТипыПараметра.Добавить(Тип("СправочникСсылка.Товары"));
ОписаниеТиповПараметра = Новый ОписаниеТипов(ТипыПараметра);
ДобавитьПараметрЗадачи("Группа", ОписаниеТиповПараметра, , , Истина);
КонецПроцедуры
Добавит параметр:
Мы использовали ДобавитьПараметрЗадачи для добавления параметра. Вот ее объявление:
&НаСервере
Процедура ДобавитьПараметрЗадачи(Имя, Тип, Заголовок = Неопределено, Невидимый = Ложь, ВыборГруппы = Ложь)
Для получения значения параметра, установленного пользователем, используйте функцию ПолучитьЗначениеПараметраПользователя:
ГруппаТоваров = ПолучитьЗначениеПараметраПользователя("Группа");
Параметры хранятся в хранилище общих настроек. Вы всегда можете изменить это поведение, изменив функцию.
Обязательная функция ИмяЗадачи_ТекстЗапроса отвечает за формирование текста запроса. Данные табличного документа доступны через обращение к временной таблице ДанныеТабличногоДокумента. В общем случае запрос должен состоять из трех частей:
- Обращение к табличному документу
- Оработка данных (получение ссылок, расчеты)
- Описание выводимых таблиц
В случае с загрузкой справочника товаров функция может выглядеть следующим образом:
&НаСервере
Функция Товары_ТекстЗапроса()
Результат = "";
//ОписаниеКолонок = "
// | ИмяПоляЗапроса (будет доступно как поле запроса),
// НомерКолонкиТабличногоДокумента или ПсевдонимПоляВводаНомера,
// Тип (Число, Дата, Булево, Если не указано -- Строка);";
ОписаниеКолонок = "
|Код, 1
|Наименование, 2
|ПометкаУдаления, 3, Булево
|ПоставщикКод, 4
|Описание, 5
|";
// Запрос к табличному документу
Результат = Запрос_ТекстОбращенияКТабличномуДокументу(ОписаниеКолонок);
// Разделитель таблиц
Результат = Результат + Запрос_РазделительТаблиц();
// Запрос обработки данных
//Результат = Результат + "ВЫБРАТЬ ... " -- текст запросов пакета: получение ссылочных данных, расчеты, группировки, сортировки.
Результат = Результат + "ВЫБРАТЬ
| ДанныеТабличногоДокумента.Код КАК Код,
| ДанныеТабличногоДокумента.Наименование КАК Наименование,
| ДанныеТабличногоДокумента.ПометкаУдаления КАК ПометкаУдаления,
| ДанныеТабличногоДокумента.ПоставщикКод КАК ПоставщикКод,
| ДанныеТабличногоДокумента.Описание КАК Описание
|ПОМЕСТИТЬ ВТ_ДанныеТабличногоДокумента
|ИЗ
| ДанныеТабличногоДокумента КАК ДанныеТабличногоДокумента
|ГДЕ
| (ДанныеТабличногоДокумента.Код <> """")
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
| Товары.Ссылка,
| ВТ_ДанныеТабличногоДокумента.Код,
| ВТ_ДанныеТабличногоДокумента.Наименование,
| ВТ_ДанныеТабличногоДокумента.ПометкаУдаления,
| ВТ_ДанныеТабличногоДокумента.ПоставщикКод,
| Контрагенты.Ссылка КАК Поставщик,
| ВТ_ДанныеТабличногоДокумента.Описание
|ИЗ
| ВТ_ДанныеТабличногоДокумента КАК ВТ_ДанныеТабличногоДокумента
| ВНУТРЕННЕЕ СОЕДИНЕНИЕ Справочник.Товары КАК Товары
| ПО ВТ_ДанныеТабличногоДокумента.Код = Товары.Код
| И (&Искать_только_по_коду
| ИЛИ ВТ_ДанныеТабличногоДокумента.Наименование = Товары.Наименование)
| ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Контрагенты КАК Контрагенты
| ПО ВТ_ДанныеТабличногоДокумента.ПоставщикКод = Контрагенты.Код
|";
// Разделитель таблиц
Результат = Результат + Запрос_РазделительТаблиц();
//ОписаниеВыводимыхТаблиц = "
// |ИмяТаблицы (будет доступна, как реквизит формы ЭтотОбъект.ПолученныеДанные_ИмяТаблица),
// НомерРезультатаВПакете (если < 0, то считать с конца), Синоним (название страницы)
ОписаниеВыводимыхТаблиц = "
|Товары, -1
|";
// Выводимые таблицы
Результат = Результат + Запрос_ТекстСхемыВывода(ОписаниеВыводимыхТаблиц);
Возврат Результат;
КонецФункции
Функция Запрос_ТекстОбращенияКТабличномуДокументу формирует текст запроса обращения к табличному документу. В качестве параметра она принимает текст описания колонок табличного документа, из которых необходимо получить данные. Каждая строка описания отвечает за одну колонку и содержит через запятую: ИмяПоляЗапроса (будет доступно как поле запроса), НомерКолонкиТабличногоДокумента или ПсевдонимПоляВводаНомера и тип, к которому система будет пытаться приводить значения колонки.
ОписаниеКолонок = "
|Код, 1
|Наименование, 2
|ПометкаУдаления, 3, Булево
|";
Скажет системе, что данные надо брать из 1, 2 и 3 колонок при этом назначить полям временной таблицы имена соответственно: Код, Наименование, ПометкаУдаления. Данные третьей колонки система будет конвертировать в тип Булево, так же доступны: Число, Дата.
Если формат табличного документа не гарантирует последовательность колонок, можно указать системе, чтобы она запрашивала номера колонок у пользователя. Например:
ОписаниеКолонок = "
|Код, Код_товара
|Наименование, ?2
|ПометкаУдаления, , Булево
|";
укажет системе, что на форме необходимо разместить таблицу для ввода номеров колонок:
Знак "?" обозначает, что скорее всего данные находятся в конкретной колонке, но необходимо пользователю дать возможность редактировать ее номер.
При изменении номера колонок сохраняются в хранилище общих настроек.
Часть обращения к данным -- текст запросов пакета: получение ссылочных данных, расчеты, группировки, сортировки. Например:
Результат = Результат + "ВЫБРАТЬ
| ДанныеТабличногоДокумента.Код КАК Код,
| ДанныеТабличногоДокумента.Наименование КАК Наименование,
| ДанныеТабличногоДокумента.ПометкаУдаления КАК ПометкаУдаления,
| ДанныеТабличногоДокумента.ПоставщикКод КАК ПоставщикКод
|ПОМЕСТИТЬ ВТ_ДанныеТабличногоДокумента
|ИЗ
| ДанныеТабличногоДокумента КАК ДанныеТабличногоДокумента
|ГДЕ
| (ДанныеТабличногоДокумента.Код <> """"
| И ДанныеТабличногоДокумента.Наименование <> """")
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
| Товары.Ссылка,
| ВТ_ДанныеТабличногоДокумента.Код,
| ВТ_ДанныеТабличногоДокумента.Наименование,
| ВТ_ДанныеТабличногоДокумента.ПометкаУдаления,
| ВТ_ДанныеТабличногоДокумента.ПоставщикКод,
| Контрагенты.Ссылка КАК Поставщик
|ИЗ
| ВТ_ДанныеТабличногоДокумента КАК ВТ_ДанныеТабличногоДокумента
| ВНУТРЕННЕЕ СОЕДИНЕНИЕ Справочник.Товары КАК Товары
| ПО ВТ_ДанныеТабличногоДокумента.Код = Товары.Код
| И (&Искать_только_по_коду
| ИЛИ ВТ_ДанныеТабличногоДокумента.Наименование = Товары.Наименование)
| ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Контрагенты КАК Контрагенты
| ПО ВТ_ДанныеТабличногоДокумента.ПоставщикКод = Контрагенты.Код
|";
При этом для параметров запроса система выведет поля для указания значений. Например, в запросе выше мы используем параметр Искать_только_по_коду. Система сделает для него поле ввода:
Значения параметров шагов также хранятся в хранилище общих настроек.
Часть с описанием выводимых таблиц говорит системе какие таблицы запроса мы будем использовать в дальнейшем. Здесь нам помогает функция Запрос_ТекстСхемыВывода. Например:
ОписаниеВыводимыхТаблиц = "
|Товары, -1
|";
// Выводимые таблицы
Результат = Результат + Запрос_ТекстСхемыВывода(ОписаниеВыводимыхТаблиц);
Скажет, что нам нужны данные первого с конца запроса пакета. После выполнения запроса система для него сделает таблицу формы:
Для простой задачи загрузки необходимо наличие процедура ИмяЗадачи. Она нужна для реализации записи данных. Например:
&НаСервере
Процедура Товары()
// Полученные данные
Товары = ПолученныеДанные("Товары");
// Получение параметров
ГруппаТоваров = ПолучитьЗначениеПараметраПользователя("Группа");
// Запись данных
Для Каждого ТекСтрокаТоваров Из Товары Цикл
ТекТоварСсылка = ТекСтрокаТоваров.Ссылка;
Если ЗначениеЗаполнено(ТекТоварСсылка) Тогда
ТекТоварОбъект = ТекТоварСсылка.ПолучитьОбъект();
Иначе
ТекТоварОбъект = Справочники.Товары.СоздатьЭлемент();
КонецЕсли;
ЗаполнитьЗначенияСвойств(ТекТоварОбъект, ТекСтрокаТоваров);
ТекТоварОбъект.Родитель = ГруппаТоваров;
ТекТоварОбъект.Записать();
ТекСтрокаТоваров.Ссылка = ТекТоварОбъект.Ссылка;
Сообщения_Добавить("Товар записан", , ТекСтрокаТоваров.Ссылка);
КонецЦикла;
КонецПроцедуры
Вот собственно и все, что надо для реализации простой загрузки
Пример добавления составной задачи допишем код в процедуру Инициализировать:
#Область Инициализация
&НаСервере
Процедура Инициализировать()
//Добавление простой задачи
ДобавитьЗадачуЗагрузкиДанных("Товары", "Загрузка товаров");
//Добавление составной задачи
ОписаниеЗадачи = "Приходы_товаров, , , Файл";
ОписаниеЭтапов = "
|Получить_данные, , , Запрос, Выберите документы для записи
|Записать, , , Процедура,
|";
ЗадачиИЭтапы_ДобавитьЗадачуСЭтапами(ОписаниеЗадачи, ОписаниеЭтапов);
КонецПроцедуры
#КонецОбласти
При этом система добавит кнопку выполнения шага (этапа) и поле выбора текущего шага (этапа):
Названия методов шагов составных задач должны начинаться с ИмяЗадачи_ИмяШага_. Например:
Функция Приходы_товаров_Получить_данные_ТекстЗапроса()
Процедура Приходы_товаров_Записать()
После выполнения шага, у которого есть стоп-сообщение, система выведет стоп-собщение и приостановит выполнение задачи:
При нажатии кнопки шага система выполнит один шаг.
Для дальнейшего выполнения можно использовать как кнопку задачи, так и кнопку шага:
Теперь у нас есть обработка, которая умеет выполнять как простую, так сложную задачи загрузки данных из табличного документа.
Проверено на следующих конфигурациях и релизах:
- 1С:Библиотека стандартных подсистем, редакция 3.1, релизы 3.1.2.264