Цель лекции: научиться создавать распределенные информационные системы, используя механизмы
Наша организация расширяется. У нее появился дополнительный офис, который занимается закупками материалов. Но материалы может покупать и центральный офис организации. Руководством было принято решение о том, что учет поступления материалов в дополнительном офисе должен вестись с использованием того же ПО, что и в главном офисе. Учетные данные головного и дополнительного офисов нужно синхронизировать не реже одного раза в день для того, чтобы сотрудники и того и другого офиса имели бы правильное представление об остатках материалов в организации.
Основным инструментом учета поступления материалов в нашей конфигурации является документ ПоступлениеМатериалов. При его заполнении используется множество справочников, он формирует движения в регистре накопления ОстаткиМатериалов и в
Для решения этой задачи можно воспользоваться механизмом распределенных информационных баз. Он позволяет организовывать обмен данными между несколькими информационными базами, синхронизировать как изменения в данных, которые внесены в базу в пользовательском режиме, так и изменения в конфигурации.
Еще и другие возможности, в частности – организация удаленного доступа к информационной базе. Такой доступ может быть организован различными средствами, так, например, это организация WEB-доступа к базе данных, объединение территориально удаленных сетей одной и той же организации в единую сеть с использованием технологий VPN и организация сетевого доступа к базе.
Описываемая методика построения распределенной информационной системы актуальна именно для случая, когда подразделение (или подразделения), в котором нужно организовать учет, не только территориально удалено, но и не имеет возможности наладить постоянную сетевую связь с головной организацией.
Прежде чем начинать реализацию механизма, подумаем о том, все ли в нашей конфигурации готово для того, чтобы он смог нормально работать. Предположим, у нас имеются две базы данных – одну назовем Главная база (ГБ), вторую – База филиала (ФБ). После того, как база ФБ создана, в ней и в базе ГБ есть один документ ПоступлениеМатериалов с номером 00001. В базах ГБ и ФБ, каждая из которых автономно используется до того момента, когда придет время обмениваться данными, создают по одному документу ПоступлениеМатериалов. Он, в соответствии со стандартными правилами нумерации, приобретает номер 00002. И в той и в другой базе содержатся разные документы, имеющие один и тот же номер. При синхронизации данных возникнет конфликтная ситуация. Для того чтобы подобной ситуации не допустить, нам нужно предусмотреть собственные правила нумерации объектов для баз ГБ и ФБ. Обычно подобная задача решается с помощью использования
Доработаем конфигурацию таким образом, чтобы те объекты, данными которых мы будем обмениваться, предусматривали использование различной системы нумерации в разных базах.
По предварительной оценке, произведенной выше, нас интересует, во-первых, документ ПоступлениеМатериалов, во-вторых – все справочники, используемые в системе. То есть, нам нужно создать механизм формирования номеров (для документа) и кодов (для элементов справочников), который использовал бы префиксы для разделения нумерации элементов различных баз.
В нашей конфигурации уже имеется константа ПрефиксНомера – строка длиной два символа, которую мы и планируем использовать для хранения
Добавим в модули справочников (рис 7.1), данные которых нам нужно синхронизировать, такие обработчики:
Процедура ПриУстановкеНовогоКода(СтандартнаяОбработка, Префикс) Префикс=Константы.ПрефиксНомера.Получить(); КонецПроцедуры
Присваивание значения константы ПрефиксНомера параметру Префикс, приводит к тому, что код элемента справочника, присваиваемый ему при создании, начинается с заданного в константе префикса. Делая это, нужно учитывать, что количество значимых цифр кода уменьшится – для того, чтобы справиться с этой проблемой, можно увеличить длину кода справочника.
(рис 7.1) Задание префикса номера в модуле справочника
В модуль документа ПоступлениеМатериалов нам нужно внести похожее изменение, однако, здесь идет речь о номерах объекта, в итоге, получается следующий код:
Процедура ПриУстановкеНовогоНомера(СтандартнаяОбработка, Префикс) Префикс=Константы.ПрефиксНомера.Получить(); КонецПроцедуры
Подготовительный этап выполнен, теперь приступим к созданию основного объекта, на котором основана
Планы обменов используются при реализации механизмов обмена данными. В частности,
При обмене данными в рамках
Создадим новый
(рис 7.2) Создание нового плана обмена
Включим
Теперь нам нужно настроить состав объектов, которые будут участвовать в обмене. Для этого перейдем на вкладку ):
(рис 7.3) Настройка состава плана обмена
После того, как состав
(рис 7.4) План обмена в режиме 1С:Предприятие
Здесь есть один предопределенный элемент, узел, который представляет собой главную информационную базу. Откроем его для редактирования, заполним поля следующим образом:
Код: ГБ Наименование: Главная ИБ
Создадим еще один узел, заполним его параметры так (рис 7.5):
Код: ФБ Наименование: ИБ филиала
(рис 7.5) Создание нового узла распределенной базы данных
Обратите внимание на то, что в форме элемента ИБ филиала, а так же – в форме списка
Кнопка ) и нажмем Создать начальный образ.
(рис 7.6) Создание начального образа распределенной базы данных
Когда процесс создания начального образа завершится, появится сообщение, предлагающее открыть или сохранить полученный файл. Нажмем на кнопку Сохранить, укажем место для сохранения файла.
В папке, которая указана при сохранении начального образа,будет расположена обычная база данных 1С:Предприятие 8, готовая к работе. Подключим базу в стартовом окне программы (кнопка . Изменения конфигурации распространяются от главной базы к подчиненной, но не наоборот.
(рис 7.7) Информационная база филиала, открытая в конфигураторе
Можно заметить, что в базе присутствуют не только те объекты, которые указаны при настройке
Еще одна особенность – в базе филиала отсутствует список пользователей, определенный в основной базе – этот список не является частью конфигурации, к тому же, вполне логично настроить новый набор пользователей в новой информационной базе.
В сущности, в подобной базе данных конфигуратор нужен лишь для целей администрирования базы, списка пользователей, однако, он выполняет еще одну важную функцию. Если в главной базе, в одном из объектов было замечено изменение метаданных (например, добавлен новый реквизит), или был создан новый объект – для автоматического обновления информационной базы будет вызван Конфигуратор.
Откроем базу филиала в режиме 1С:Предприятие, и первым действием, которое мы выполним, будет установка константы Префикс номера. Откроем форму констант и введем в качестве префикса . В основной базе установим эту константу в значение ГБ.
(рис 7.8) Настройка префикса номера и текста сообщения в базе филиала
Если вы откроете в базе филиала форму констант, то, независимо от состояния констант в основной базе, их значения будут пустыми. Константы не отмечены в составе
Теперь попробуем выполнить некоторые действия в базе филиала. А именно, создадим новый документ ). Сразу же можно отметить, что номер этого документа начинается с ФБ. Так же, если мы будем создавать в базе филиала новые элементы справочника Номенклатура, Контрагенты и других (что, учитывая специфику задачи, вполне естественно) – их коды так же будут начинаться с ФБ.
(рис 7.9) Нумерация объектов в базе филиала
Для заполнения этого документа мы, в основном, пользовались элементами справочников, которые "достались" базе филиала от основной базы, а один из элементов – "Туалетная вода", был создан уже в базе филиала. Так же обратите внимание на состав списка документов Поступление материалов в базе филиала.
Теперь добавим новый документ показано состояние списка документов этого вида в основной базе.
(рис 7.10) Новый документ в основной базе
После того, как в базы внесены изменения, займемся их синхронизацией.
Откроем в основной базе
(рис 7.11) Запись сообщений с изменениями
Нажатие на кнопку Записать и сохранить в файл приводит к записи файла изменений и выдаче окна с предложением открыть или сохранить файл. Нажмем на кнопку Сохранить, укажем папку для сохранения файла
По умолчанию имя файла выглядит как Message_Главная ИБ_ИБ Филиала.zip (то есть, нечто вроде "Сообщение от главной базы базе филиала). Файл сообщения, на самом деле, является XML-файлом, но благодаря установке параметра Сжимать сообщение он сразу же упаковывается в ZIP-архив.
Произведем аналогичное действие в базе филиала, но теперь в списке
Предположим, некий курьер в конце дня привозит на флэш-диске файл Message_Главная ИБ_ИБ Филиала.zip в филиал из центрального офиса, и забирает оттуда файл Message_ИБ Филиала_Главная ИБ.zip. Эти файлы можно передать любым удобным способом, например, на переносном носителе информации, по электронной почте.
После получения файла в форме списка
(рис 7.12) Чтение сообщения с изменениями
После получения сообщения о том, что чтение данных успешно завершено, мы можем взглянуть на список документов ПоступлениеМатериалов – там появится новый документ из Главной ИБ.
Проделав аналогичную операцию в Главной ИБ, мы получим там новый документ из ИБ филиала и новый, созданный там же, элемент справочника. Естественно, изменения будут внесены и в регистры, по которым проводится документ из базы филиала.
Выше мы говорили о том, что
Рассмотрим пример. Добавим в узле Главная ИБ с помощью конфигуратора новую константу, назовем ее КонстантаДляРИБ. Откроем Главную ИБ в режиме 1С:Предприятие, добавим в справочник Номенклатура новый элемент – Лак для ногтей в группу Прочие материалы.
Запишем сообщение из .
(рис 7.13) Из главной базы поступили изменения конфигурации
Нажмем ОК, закроем окно программы, откроем базу в Конфигураторе и нажмем на кнопку Обновить конфигурацию базы данных. После этого изменения в конфигурации вступят в силу, то есть, мы получим возможность обращаться к новой константе в пользовательском режиме.
После того, как база обновлена, следует еще раз произвести чтение сообщения – для того, чтобы из него были прочитаны изменения данных объектов.
Если после обновления конфигурации не прочесть сообщение повторно – данные в базах не будут синхронизированы. В нашем случае это будет означать, что новый элемент справочника Номенклатура не будет добавлен в ИБ филиала.
Базы данных 1С:Предприятие обычно содержат огромное количество информации. Логично было бы предположить, что для того, чтобы ориентироваться в этой информации, неплохо было бы иметь механизм поиска. Такой механизм уже присутствует в базе по умолчанию. Он позволяет задавать поисковые запросы на естественном языке, использовать поисковые операторы (И, ИЛИ, НЕ, РЯДОМ и другие), искать информацию даже в том случае, если нам известна лишь часть искомого текста.
В частности, при создании новых объектов и их реквизитов, свойство Полнотекстовый поиск устанавливается в значение Использовать
Если в режиме 1С:Предприятие выполнить команду .
(рис 7.14) Управление полнотекстовым поиском
Кнопка Обновить индекс служит для обновления поискового индекса.
Кнопка Очистить индекс позволяет очищать индекс.
Кнопка Настройка вызывает окно, которое содержит лишь один параметр – разрешающий или запрещающий использование полнотекстового поиска. По умолчанию поиск разрешен.
Ранее мы не пользовались полнотекстовым поиском, соответственно, поискового индекса у нас пока нет (параметр .
(рис 7.15) Обновление индекса
Механизм полнотекстового поиска в нашей базе присутствует, но нет поискового интерфейса, который позволял бы пользователю производить такой поиск. Создадим его.
В Конфигураторе добавим в систему новый отчет. Назовем его ПоискВБазеДанных, создадим основную форму отчета, включим его в состав подсистемы Администрирование. Создадим следующие реквизиты и команды формы:
Реквизит ПоисковыйЗапрос, Тип: Строка, длина 100
В этом реквизите мы будем хранить поисковый запрос, который будет вводить пользователь. Разместим его на форме.
Команда ВыполнитьПоиск, наименование Искать!
Разместим команду на форме, она примет вид кнопки – нажатие на эту кнопку будет запускать новый поиск.
Реквизит СведенияОПоиске, Тип: Строка, длина 100, разместим реквизит на форме, зададим вид для элемента формы Поле надписи. Сюда мы будем выводить служебные сведения о поиске.
Реквизит РезультатыПоиска, оставим тип в значении по умолчанию, перетащим на форму и в свойстве элемента формы Вид укажем Поле HTML-документа В это поле будут выводиться результаты поиска, полученные в виде HTML.
Команда Назад, перетащим ее на форму
Команда Вперед, перетащим ее на форму
Эти команды будут использоваться для перехода к предыдущей, и, соответственно, следующей порции поиска.
Добавим реквизит НачальнаяПозиция, числового типа – на форму перетаскивать его не будем, он будет применяться для хранения начальной позиции поиска, в том случае, если мы нажимаем на кнопки Назад или Вперед, порция найденных данных, попадающая в поле вывода, будет зависеть от переменной НачальнаяПозиция.
Добавим реквизит СписокРезультатов, тип – СписокЗначений, не будем перетаскивать его на форму, мы будем пользоваться им в программном коде. Роль этого реквизита – хранение найденных данных для того, чтобы при щелчке мышью в поле HTML-документа по ссылке, ведущей к тому или иному объекту, открывалось бы окно этого объекта.
Добавим реквизит ПорогНечеткости, числового типа с параметрами по умолчанию. Перетащим его на форму, в окне настройки свойств элемента формы установим следующие параметры:
Заголовок: Порог нечеткости: 0 Вид: Поле полосы регулирования Минимальное значение: 0 Максимальное значение: 100
Благодаря таким настройкам значение параметра ПорогНечеткости, который мы будем использовать для настройки поиска, можно будет менять, перетаскивая бегунок полосы прокрутки. Порог нечеткости изменяется от 0% до 100%, от него зависит то, насколько результат поиска будет совпадать с поисковым запросом.
Добавим реквизит РазмерПорции, числового типа, с параметрами по умолчанию. Перетащим на форму, в окне настройки свойств элемента установим следующие параметры
Заголовок: Размер порции: 5 Вид: Поле полосы регулирования Минимальное значение: 5 Максимальное значение: 50
Итоговый внешний вид формы представлен на рис 7.16.
(рис 7.16) Внешний вид формы
Это окно будущей формы мы получили, нажав на кнопку Проверить в панели инструментов группы Элементы в редакторе форм.
Ниже приведен код модуля формы, который реализует поиск.
НаКлиенте
Процедура ВыполнитьПоиск(Команда)
//Начинаем новый поиск
НачатьПоиск("Новый поиск");
КонецПроцедуры
НаКлиенте
Процедура Назад(Команда)
//Переходим к предыдущей порции поиска
НачатьПоиск ("Назад");
КонецПроцедуры
НаКлиенте
Процедура Вперед(Команда)
//Переходим к следующей порции поиска
НачатьПоиск("Вперед");
КонецПроцедуры
НаКлиенте
Процедура НачатьПоиск(НаправлениеПоиска)
//Проверяем строку поиска
Если Не ПустаяСтрока(ПоисковыйЗапрос) Тогда
ВыполнитьПоискСервер(НаправлениеПоиска);
Иначе
Предупреждение("Строка поиска не задана");
КонецЕсли;
КонецПроцедуры
НаСервере
Процедура ВыполнитьПоискСервер(НаправлениеПоиска)
//Создаем новый список поиска
СпПоиска = ПолнотекстовыйПоиск.СоздатьСписок();
//Задаем параметры поиска
СпПоиска.СтрокаПоиска = ПоисковыйЗапрос;
СпПоиска.РазмерПорции=РазмерПорции;
СпПоиска.ПорогНечеткости=ПорогНечеткости;
//проверяем направление поиска
//в зависимости от них либо выполняем поиск
//с выдачей его первой части, либо показываем
//предыдущую или следующую порции поиска
Если НаправлениеПоиска = "Новый поиск" Тогда
СпПоиска.ПерваяЧасть();
ИначеЕсли НаправлениеПоиска = "Назад" Тогда
СпПоиска.ПредыдущаяЧасть(НачальнаяПозиция);
ИначеЕсли НаправлениеПоиска = "Вперед" Тогда
СпПоиска.СледующаяЧасть(НачальнаяПозиция);
КонецЕсли;
//НачальнаяПозиция будет использоваться не только в дальнейших вычислениях
//но и как ориентир при получении следующей или предыдущей порции поиска
НачальнаяПозиция = СпПоиска.НачальнаяПозиция();
//Выводим сообщение в поле сведений о поиске и настраиваем доступность
//кнопок Вперед и Назад
Если СпПоиска.Количество() <> 0 Тогда
СведенияОПоиске = "Результаты поиска" + Строка(НачальнаяПозиция + 1)
+ "-" + Строка(НачальнаяПозиция + СпПоиска.Количество())
+ "из" + Строка(СпПоиска.ПолноеКоличество());
Элементы.Вперед.Доступность
= (СпПоиска.ПолноеКоличество() - НачальнаяПозиция) > СпПоиска.Количество();
Элементы.Назад.Доступность = (НачальнаяПозиция > 0);
Иначе
СведенияОПоиске = "Поиск не дал результатов";
Элементы.Вперед.Доступность = Ложь;
Элементы.Назад.Доступность = Ложь;
КонецЕсли;
//Выводим результат поиска в поле HTML-документа
РезультатыПоиска = СпПоиска.ПолучитьОтображение
(ВидОтображенияПолнотекстовогоПоиска.HTMLТекст);
//Заполняем список СписокРезультатов
СписокРезультатов.Очистить();
Для Каждого Результат Из СпПоиска Цикл
СписокРезультатов.Добавить(Результат.Значение);
КонецЦикла;
КонецПроцедуры
НаКлиенте
Процедура РезультатыПоискаПриНажатии
(Элемент, ДанныеСобытия, СтандартнаяОбработка)
//Получаем элемент HTML
ЭлементHTML = ДанныеСобытия.Event.srcElement;
//Если это - элемент полнотекстового поиска
Если (ЭлементHTML.id = "FullTextSearchListItem") Тогда
//Отключаем стандартную обработку события
СтандартнаяОбработка = Ложь;
// Получим номер строки (nameProp) найденной строки
НомерЭлемента = Число(ЭлементHTML.sel_num);
// Откроем форму найденного элемента
ОткрытьЗначение(СписокРезультатов[НомерЭлемента].Значение);
КонецЕсли;
КонецПроцедуры
НаКлиенте
Процедура РазмерПорцииПриИзменении(Элемент)
//Выводим информацию о текущем размере порции поиска
Элементы.РазмерПорции.Заголовок="Размер порции: "+РазмерПорции;
КонецПроцедуры
НаКлиенте
Процедура ПорогНечеткостиПриИзменении(Элемент)
//Выводим информацию о текущем пороге нечеткости
Элементы.ПорогНечеткости.Заголовок = "Порог нечеткости: " + ПорогНечеткости;
КонецПроцедуры
НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
//Задаем размер порции поиска и порог нечеткости
РазмерПорции=5;
ПорогНечеткости=0;
//Блокируем кнопки Вперед и Назад
Элементы.Вперед.Доступность=Ложь;
Элементы.Назад.Доступность=Ложь;
КонецПроцедуры
В процедуре ПриСозданииНаСервере() мы, при создании нашей формы на сервере, во-первых, инициализируем реквизиты РазмерПорции и ПорогНечеткости, во-вторых – скрываем кнопки Назад и Вперед.
После ввода поискового запроса и нажатия на кнопку ВыполнитьПоиск, выполняется клиентская процедура ВыполнитьПоиск(), которая вызывает клиентскую же процедуру НачатьПоиск(). В процедуре НачатьПоиск мы проверяем, заполнена ли строка поиска, после чего вызываем серверную процедуру ВыполнитьПоискСервер(). При вызове мы передаем параметр НаправлениеПоиска – он содержит строку, в зависимости от ее содержимого мы либо выдаем исходные результаты поиска ("Новый поиск"), либо получаем следующую порцию найденных данных ("Вперед"), либо – предыдущую ("Назад"). Фактически, нажимая кнопки ВыполнитьПоиск, Вперед или Назад мы вызываем одинаковую процедуру поиска, выполняем новый поиск, но при выдаче результатов поиска ориентируемся на значение реквизита НачальнаяПозиция, в итоге – выдаем различные результаты при нажатии на различные кнопки.
При входе в серверную процедуру ВыполнитьПоискСервер(), мы инициализируем переменную СпПоиска – она будет содержать список полнотекстового поиска, настраиваем параметры поиска, устанавливая строку поискового запроса, порог нечеткости, размер порции, выполняем поиск, записываем реквизит НачальнаяПозиция, выводим сообщение о результатах поиска и устанавливаем доступность кнопок, после чего выводим найденные данные в виде HTML-кода в поле РезультатыПоиска и заполняем реквизит СписокРезультатов.
При щелчке по одной из ссылок в поле РезультатыПоиска, срабатывает обработчик РезультатыПоискаПриНажатии(). Здесь мы определяем номер элемента, по которому щелкнул мышью пользователь и открываем форму для объекта, хранящегося в соответствующем элементе списка значений СписокРезультатов.
При перемещении бегунков, связанных с реквизитами ПорогНечеткости и РазмерПорции, вызываются их обработчики ПриИзменении, роль которых – проинформировать пользователя о текущем состоянии данных показателей.
На рис 7.17 вы можете видеть работу с окном поиска. При текущем установленном пороге нечеткости (34 в данном случае) по запросу "Петров" система находит, кроме слова "Петров" еще и "Петр" и "Петрович".
(рис 7.17) Результаты поиска
В информационных базах 1С:Предприятие 8 существует немало регулярно повторяемых последовательностей действий, которые вполне можно было бы доверить автоматике. Например, это обмен данными с другими информационными системами, резервное копирование информации, обновление поисковых индексов и так далее. Для реализации выполнения подобных работ в 1С:Предприятие предусмотрен механизм
(рис 7.18) Новое регламентное задание
В качестве метода, который будет выполняться регламентным заданием, может выступать процедура неглобального общего модуля, которая может быть исполнена на сервере. Для задания такой процедуры создадим новый общий модуль (.
(рис 7.19) Новый модуль для процедуры, реализующей регламентное задание
Откроем код модуля и введем туда следующий код:
Процедура ПроверкаЗадания() Экспорт
Сообщить("Задание работает, сейчас "+ТекущаяДата());
КонецПроцедуры
Теперь укажем данную процедуру в настройках задания, в поле Имя метода, и перейдем к редактированию расписания. Расписание запуска настраивается с помощью нескольких вкладок окна Расписание, итоговый результат отображается в нижней части окна. На вкладке Общее установим в поле Повторять каждые – значение .
(рис 7.20) Окно настройки расписания, вкладка Общее
На вкладке Дневное мы можем настроить дневное расписание выполнения задания. Установим параметр Повторять через в значение .
(рис 7.21) Окно настройки расписания, вкладка Дневное
На вкладке Недельное можно задать расписание запуска по неделям, на вкладке Месячное – расписание по месяцам.
Ограничимся в настройках расписания вышеприведенными изменениями, закроем окно нажатием на кнопку ОК.
Мы работаем с информационной базой в файловом режиме. Если бы мы работали с серверным вариантом, то, для того, чтобы задание было запущено и выполнялось в соответствии с расписанием, нам нужно было бы лишь установить флажок Предопределенное в форме свойств задания. Для файлового варианта нам понадобятся некоторые дополнительные усилия (флажок Предопределенное мы так же установим).
А именно, создадим обработку с именем ОбработкаЗаданий. Включим ее в подсистему Администрирование. Создадим форму обработки, добавим на нее надпись "Обработка заданий. Закрыть для завершения", а в модуль обработки добавим следующий код:
НаКлиенте
Процедура ПриОткрытии(Отказ)
ПодключитьОбработчикОжидания("ОбработкаЗаданий", 5);
КонецПроцедуры
НаКлиенте
Процедура ОбработкаЗаданий()
ВыполнитьОбработкуЗаданий();
КонецПроцедуры
В этом коде мы подключаем обработчик ожидания формы при открытии формы. Он использует указанную при его вызове процедуру в качестве обработчика ожидания. Эта процедура будет вызываться каждый раз по истечению указанного при подключении интервала времени (в секундах).
В процедуре . вы можете видеть окно программы с открытой формой обработки, ответственной за выполнение заданий. Как можно судить из окна служебных сообщений, наше 30 секунд.
(рис 7.22) Форма обработки, ответственной за вызов метода ОбработкаЗаданий()
Для того, чтобы обеспечить обработку
Функциональные опции – это одна из новых возможностей платформы 1С:Предприятие 8.2. Смысл их использования заключается в том, что они позволяют настраивать пользовательский интерфейс в соответствии с настройками функциональных опций, задавать видимость реквизитов в формах. Кроме того, разработчик имеет возможность реализовывать программный код, выполнение которого зависит от состояния функциональной опции.
Создадим функциональную опцию, которая позволяет включать и отключать ведение расчета заработной платы в конфигурации. С ее помощью мы сможем быстро скрывать те части интерфейса, которые относятся к решению расчетных задач. Функциональная опция сама по себе не хранит какого-либо значения, которое позволяет ее включать и отключать. Обычно для хранения состояния функциональной опции используют константу, хотя она может быть привязана и к другому объекту, например – к реквизиту какого-либо объекта.
Создадим новую константу, назовем ее УчетЗарплаты, тип – Булево. Включим константу в подсистему Администрирование и в форму констант для того, чтобы мы могли редактировать ее. Кроме того, в форме констант зададим обработчик ПослеЗаписи следующего вида:
НаКлиенте Процедура ПослеЗаписи(ПараметрыЗаписи) ОбновитьИнтерфейс(); КонецПроцедуры
Смысл использования команды ОбновитьИнтерфейс() заключается в том, чтобы после вступления в силу изменения константы, связанной с функциональной опцией, обновить, перерисовать интерфейс. Иначе для того, чтобы изменения вступили в силу, придется перезапускать конфигурацию.
Создадим новую функциональную опцию, назовем ее . Включим функциональную опцию в подсистему Администрирование.
(рис 7.23) Настройка параметров функциональной опции
Теперь перейдем на закладку окна настройки функциональной опции ), что относится к расчету заработной платы. Если какие-либо объекты, например, справочники, относятся к различным частям конфигурации, не будем их отмечать, иначе при выключении функциональной опции они "исчезнут" из интерфейса.
(рис 7.24) Настройка состава функциональной опции
Выбор подсистемы РасчетЗаработнойПлаты в данном случае не ведет к автоматическому выбору всех объектов, включенных в подсистему. При выборе мы лишь подразумеваем скрытие или отображение раздела командного интерфейса РасчетЗаработнойПлаты.
Запустив систему в пользовательском режиме, мы сможем включать и отключать видимость объектов, относящихся к зарплатной подсистеме нашей конфигурации, просто устанавливая или снимая флаг у константы УчетЗарплаты.
Более сложный вариант использования функциональных опций заключается в настройке видимости отдельных элементов форм в том случае, если значение функциональной опции хранится в реквизите какого-либо объекта.
Внесем изменения в конфигурацию, в частности, в справочник ФизическиеЛица добавим реквизит логического типа ИмеетОпытКадровойСлужбы и разместим его на форме элемента справочника.
Если это свойство включено, то после выбора соответствующего физического лица в форме элемента справочника Сотрудники реквизит справочника Сотрудники Расчетчик должен отображаться, если свойство ИмеетОпытКадровойСлужбы имеет значение Ложь, то реквизит Расчетчик должен быть скрыт.
Добавим новую функциональную опцию, назовем ее РаботаСРасчетчиками, включим в подсистему Администрирование, на закладке Основные установим реквизит Хранение в значение .
(рис 7.25) Настройка параметров функциональной опции
Перейдем на закладку окна настройки функциональной опции .
(рис 7.26) Настройка состава функциональной опции
Функциональную опцию в данном случае нужно дополнить параметром функциональной опции. Создадим новый параметр функциональной опции, назовем его Расчетчик, в свойстве Использование выберем .
(рис 7.27) Настройка параметра функциональной опции
Теперь нам нужно задать параметр функциональной опции для каждого конкретного экземпляра формы справочника Сотрудники для того, чтобы, в зависимости от состояния реквизита справочника ФизическиеЛица мы могли бы настроить внешний вид формы справочника Сотрудники – скрыть или отобразить реквизит Расчетчик.
Перейдем в форму элемента справочника Сотрудники, создадим обработчик ПриСозданииНаСервере, разместим в нем следующий код:
НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
ПараметрыФункциональныхОпций
= Новый Структура("Расчетчик", Объект.ФизическоеЛицо);
УстановитьПараметрыФункциональныхОпцийФормы(ПараметрыФункциональныхОпций);
КонецПроцедуры
Здесь мы создаем новую структуру, которая содержит, в ключе – наименование параметра функциональной опции, в значении – ссылку на объект, из которого следует брать значение функциональной опции.
С помощью команды УстановитьПараметрыФункциональныхОпцийФормы, которой мы передаем сформированную структуру, мы настраиваем функциональную опцию, которая, в свою очередь, повлияет на внешний вид формы.
Кроме того, предусмотрим ситуацию, в которой пользователь выбирает различные физические лица, у некоторых из которых интересующий нас признак ИмеетОпытКадровойСлужбы установлен, у некоторых нет – то есть – состав реквизитов, отображаемых на форме нужно пересматривать и, при необходимости, обновлять, после выбора нового физического лица. Для этого добавим в обработчик события изменения поля ФизическоеЛицо формы элемента справочника Сотрудники код, аналогичный вышеприведенному, в итоге этот обработчик будет выглядеть так:
НаКлиенте
Процедура ФизическоеЛицоПриИзменении(Элемент)
ПараметрыФункциональныхОпций
= Новый Структура("Расчетчик", Объект.ФизическоеЛицо);
УстановитьПараметрыФункциональныхОпцийФормы(ПараметрыФункциональныхОпций);
СформироватьНаименование();
КонецПроцедуры
Команда СформироватьНаименование() относится к уже существующим в форме механизмам.
Опробуем созданный механизм на практике. Установим флаг .
(рис 7.28) Воздействие функциональной опции на реквизиты формы
Если функциональная опция используется для управления реквизитами, которые, например, влияют на добавление каких-либо данных в регистры, на расчет каких-либо показателей (скажем, включение и отключение складского учета), скрытие или отображение реквизита (например, реквизита документа Склад или "отключение" измерения регистра Склад) само по себе не влияет на программные механизмы работы системы. Это означает, что программный код, который должен выполняться при том или ином состоянии функциональной опции, разработчик должен писать самостоятельно, разветвляя, при необходимости, его выполнение в зависимости от состояния функциональной опции.
Продемонстрируем это на примере. Основываясь на состоянии функциональной опции РаботаСРасчетчиками, будем выводить различные сообщения при закрытии формы элемента справочника Сотрудники. Создадим в модуле формы элемента справочника обработчик ПриЗакрытии, приведем его к следующему виду:
НаКлиенте
Процедура ПриЗакрытии()
Если ПолучитьФункциональнуюОпциюФормы("РаботаСРасчетчиками") Тогда
Предупреждение("Этот сотрудник может быть расчетчиком");
Иначе
Предупреждение("Этот сотрудник не может быть расчетчиком");
КонецЕсли;
КонецПроцедуры
Здесь мы пользуемся функцией ПолучитьФункциональнуюОпциюФормы(), которая принимает на входе строковое имя функциональной опции. Если функция возвратит значение Истина – пользователь увидит сообщение "Этот сотрудник может быть расчетчиком" - в нашем случае подобное сообщение будет выведено для сотрудника Расчетчиков. В противном случае выводится сообщение "Этот сотрудник не может быть расчетчиком". Аналогично, анализируя состояние функциональных опций формы, можно управлять исполнением кода.
пользователем реализованы программно.
В этой лекции мы рассмотрели работу с механизмом распределенных баз данных, создали систему полнотекстового поиска в базе данных, научились пользоваться функциональными опциями, параметрами функциональных опций и регламентными заданиями.
Для данной лекции подготовлен видеоурок.
Цель лекции: научиться создавать распределенные информационные системы, используя механизмы
Наша организация расширяется. У нее появился дополнительный офис, который занимается закупками материалов. Но материалы может покупать и центральный офис организации. Руководством было принято решение о том, что учет поступления материалов в дополнительном офисе должен вестись с использованием того же ПО, что и в главном офисе. Учетные данные головного и дополнительного офисов нужно синхронизировать не реже одного раза в день для того, чтобы сотрудники и того и другого офиса имели бы правильное представление об остатках материалов в организации.
Основным инструментом учета поступления материалов в нашей конфигурации является документ ПоступлениеМатериалов. При его заполнении используется множество справочников, он формирует движения в регистре накопления ОстаткиМатериалов и в
Для решения этой задачи можно воспользоваться механизмом распределенных информационных баз. Он позволяет организовывать обмен данными между несколькими информационными базами, синхронизировать как изменения в данных, которые внесены в базу в пользовательском режиме, так и изменения в конфигурации.
Еще и другие возможности, в частности – организация удаленного доступа к информационной базе. Такой доступ может быть организован различными средствами, так, например, это организация WEB-доступа к базе данных, объединение территориально удаленных сетей одной и той же организации в единую сеть с использованием технологий VPN и организация сетевого доступа к базе.
Описываемая методика построения распределенной информационной системы актуальна именно для случая, когда подразделение (или подразделения), в котором нужно организовать учет, не только территориально удалено, но и не имеет возможности наладить постоянную сетевую связь с головной организацией.
Прежде чем начинать реализацию механизма, подумаем о том, все ли в нашей конфигурации готово для того, чтобы он смог нормально работать. Предположим, у нас имеются две базы данных – одну назовем Главная база (ГБ), вторую – База филиала (ФБ). После того, как база ФБ создана, в ней и в базе ГБ есть один документ ПоступлениеМатериалов с номером 00001. В базах ГБ и ФБ, каждая из которых автономно используется до того момента, когда придет время обмениваться данными, создают по одному документу ПоступлениеМатериалов. Он, в соответствии со стандартными правилами нумерации, приобретает номер 00002. И в той и в другой базе содержатся разные документы, имеющие один и тот же номер. При синхронизации данных возникнет конфликтная ситуация. Для того чтобы подобной ситуации не допустить, нам нужно предусмотреть собственные правила нумерации объектов для баз ГБ и ФБ. Обычно подобная задача решается с помощью использования
Доработаем конфигурацию таким образом, чтобы те объекты, данными которых мы будем обмениваться, предусматривали использование различной системы нумерации в разных базах.
По предварительной оценке, произведенной выше, нас интересует, во-первых, документ ПоступлениеМатериалов, во-вторых – все справочники, используемые в системе. То есть, нам нужно создать механизм формирования номеров (для документа) и кодов (для элементов справочников), который использовал бы префиксы для разделения нумерации элементов различных баз.
В нашей конфигурации уже имеется константа ПрефиксНомера – строка длиной два символа, которую мы и планируем использовать для хранения
Добавим в модули справочников (рис 7.1), данные которых нам нужно синхронизировать, такие обработчики:
Процедура ПриУстановкеНовогоКода(СтандартнаяОбработка, Префикс) Префикс=Константы.ПрефиксНомера.Получить(); КонецПроцедуры
Присваивание значения константы ПрефиксНомера параметру Префикс, приводит к тому, что код элемента справочника, присваиваемый ему при создании, начинается с заданного в константе префикса. Делая это, нужно учитывать, что количество значимых цифр кода уменьшится – для того, чтобы справиться с этой проблемой, можно увеличить длину кода справочника.
(рис 7.1) Задание префикса номера в модуле справочника
В модуль документа ПоступлениеМатериалов нам нужно внести похожее изменение, однако, здесь идет речь о номерах объекта, в итоге, получается следующий код:
Процедура ПриУстановкеНовогоНомера(СтандартнаяОбработка, Префикс) Префикс=Константы.ПрефиксНомера.Получить(); КонецПроцедуры
Подготовительный этап выполнен, теперь приступим к созданию основного объекта, на котором основана
Планы обменов используются при реализации механизмов обмена данными. В частности,
При обмене данными в рамках
Создадим новый
(рис 7.2) Создание нового плана обмена
Включим
Теперь нам нужно настроить состав объектов, которые будут участвовать в обмене. Для этого перейдем на вкладку ):
(рис 7.3) Настройка состава плана обмена
После того, как состав
(рис 7.4) План обмена в режиме 1С:Предприятие
Здесь есть один предопределенный элемент, узел, который представляет собой главную информационную базу. Откроем его для редактирования, заполним поля следующим образом:
Код: ГБ Наименование: Главная ИБ
Создадим еще один узел, заполним его параметры так (рис 7.5):
Код: ФБ Наименование: ИБ филиала
(рис 7.5) Создание нового узла распределенной базы данных
Обратите внимание на то, что в форме элемента ИБ филиала, а так же – в форме списка
Кнопка ) и нажмем Создать начальный образ.
(рис 7.6) Создание начального образа распределенной базы данных
Когда процесс создания начального образа завершится, появится сообщение, предлагающее открыть или сохранить полученный файл. Нажмем на кнопку Сохранить, укажем место для сохранения файла.
В папке, которая указана при сохранении начального образа,будет расположена обычная база данных 1С:Предприятие 8, готовая к работе. Подключим базу в стартовом окне программы (кнопка . Изменения конфигурации распространяются от главной базы к подчиненной, но не наоборот.
(рис 7.7) Информационная база филиала, открытая в конфигураторе
Можно заметить, что в базе присутствуют не только те объекты, которые указаны при настройке
Еще одна особенность – в базе филиала отсутствует список пользователей, определенный в основной базе – этот список не является частью конфигурации, к тому же, вполне логично настроить новый набор пользователей в новой информационной базе.
В сущности, в подобной базе данных конфигуратор нужен лишь для целей администрирования базы, списка пользователей, однако, он выполняет еще одну важную функцию. Если в главной базе, в одном из объектов было замечено изменение метаданных (например, добавлен новый реквизит), или был создан новый объект – для автоматического обновления информационной базы будет вызван Конфигуратор.
Откроем базу филиала в режиме 1С:Предприятие, и первым действием, которое мы выполним, будет установка константы Префикс номера. Откроем форму констант и введем в качестве префикса . В основной базе установим эту константу в значение ГБ.
(рис 7.8) Настройка префикса номера и текста сообщения в базе филиала
Если вы откроете в базе филиала форму констант, то, независимо от состояния констант в основной базе, их значения будут пустыми. Константы не отмечены в составе
Теперь попробуем выполнить некоторые действия в базе филиала. А именно, создадим новый документ ). Сразу же можно отметить, что номер этого документа начинается с ФБ. Так же, если мы будем создавать в базе филиала новые элементы справочника Номенклатура, Контрагенты и других (что, учитывая специфику задачи, вполне естественно) – их коды так же будут начинаться с ФБ.
(рис 7.9) Нумерация объектов в базе филиала
Для заполнения этого документа мы, в основном, пользовались элементами справочников, которые "достались" базе филиала от основной базы, а один из элементов – "Туалетная вода", был создан уже в базе филиала. Так же обратите внимание на состав списка документов Поступление материалов в базе филиала.
Теперь добавим новый документ показано состояние списка документов этого вида в основной базе.
(рис 7.10) Новый документ в основной базе
После того, как в базы внесены изменения, займемся их синхронизацией.
Откроем в основной базе
(рис 7.11) Запись сообщений с изменениями
Нажатие на кнопку Записать и сохранить в файл приводит к записи файла изменений и выдаче окна с предложением открыть или сохранить файл. Нажмем на кнопку Сохранить, укажем папку для сохранения файла
По умолчанию имя файла выглядит как Message_Главная ИБ_ИБ Филиала.zip (то есть, нечто вроде "Сообщение от главной базы базе филиала). Файл сообщения, на самом деле, является XML-файлом, но благодаря установке параметра Сжимать сообщение он сразу же упаковывается в ZIP-архив.
Произведем аналогичное действие в базе филиала, но теперь в списке
Предположим, некий курьер в конце дня привозит на флэш-диске файл Message_Главная ИБ_ИБ Филиала.zip в филиал из центрального офиса, и забирает оттуда файл Message_ИБ Филиала_Главная ИБ.zip. Эти файлы можно передать любым удобным способом, например, на переносном носителе информации, по электронной почте.
После получения файла в форме списка
(рис 7.12) Чтение сообщения с изменениями
После получения сообщения о том, что чтение данных успешно завершено, мы можем взглянуть на список документов ПоступлениеМатериалов – там появится новый документ из Главной ИБ.
Проделав аналогичную операцию в Главной ИБ, мы получим там новый документ из ИБ филиала и новый, созданный там же, элемент справочника. Естественно, изменения будут внесены и в регистры, по которым проводится документ из базы филиала.
Выше мы говорили о том, что
Рассмотрим пример. Добавим в узле Главная ИБ с помощью конфигуратора новую константу, назовем ее КонстантаДляРИБ. Откроем Главную ИБ в режиме 1С:Предприятие, добавим в справочник Номенклатура новый элемент – Лак для ногтей в группу Прочие материалы.
Запишем сообщение из .
(рис 7.13) Из главной базы поступили изменения конфигурации
Нажмем ОК, закроем окно программы, откроем базу в Конфигураторе и нажмем на кнопку Обновить конфигурацию базы данных. После этого изменения в конфигурации вступят в силу, то есть, мы получим возможность обращаться к новой константе в пользовательском режиме.
После того, как база обновлена, следует еще раз произвести чтение сообщения – для того, чтобы из него были прочитаны изменения данных объектов.
Если после обновления конфигурации не прочесть сообщение повторно – данные в базах не будут синхронизированы. В нашем случае это будет означать, что новый элемент справочника Номенклатура не будет добавлен в ИБ филиала.
Базы данных 1С:Предприятие обычно содержат огромное количество информации. Логично было бы предположить, что для того, чтобы ориентироваться в этой информации, неплохо было бы иметь механизм поиска. Такой механизм уже присутствует в базе по умолчанию. Он позволяет задавать поисковые запросы на естественном языке, использовать поисковые операторы (И, ИЛИ, НЕ, РЯДОМ и другие), искать информацию даже в том случае, если нам известна лишь часть искомого текста.
В частности, при создании новых объектов и их реквизитов, свойство Полнотекстовый поиск устанавливается в значение Использовать
Если в режиме 1С:Предприятие выполнить команду .
(рис 7.14) Управление полнотекстовым поиском
Кнопка Обновить индекс служит для обновления поискового индекса.
Кнопка Очистить индекс позволяет очищать индекс.
Кнопка Настройка вызывает окно, которое содержит лишь один параметр – разрешающий или запрещающий использование полнотекстового поиска. По умолчанию поиск разрешен.
Ранее мы не пользовались полнотекстовым поиском, соответственно, поискового индекса у нас пока нет (параметр .
(рис 7.15) Обновление индекса
Механизм полнотекстового поиска в нашей базе присутствует, но нет поискового интерфейса, который позволял бы пользователю производить такой поиск. Создадим его.
В Конфигураторе добавим в систему новый отчет. Назовем его ПоискВБазеДанных, создадим основную форму отчета, включим его в состав подсистемы Администрирование. Создадим следующие реквизиты и команды формы:
Реквизит ПоисковыйЗапрос, Тип: Строка, длина 100
В этом реквизите мы будем хранить поисковый запрос, который будет вводить пользователь. Разместим его на форме.
Команда ВыполнитьПоиск, наименование Искать!
Разместим команду на форме, она примет вид кнопки – нажатие на эту кнопку будет запускать новый поиск.
Реквизит СведенияОПоиске, Тип: Строка, длина 100, разместим реквизит на форме, зададим вид для элемента формы Поле надписи. Сюда мы будем выводить служебные сведения о поиске.
Реквизит РезультатыПоиска, оставим тип в значении по умолчанию, перетащим на форму и в свойстве элемента формы Вид укажем Поле HTML-документа В это поле будут выводиться результаты поиска, полученные в виде HTML.
Команда Назад, перетащим ее на форму
Команда Вперед, перетащим ее на форму
Эти команды будут использоваться для перехода к предыдущей, и, соответственно, следующей порции поиска.
Добавим реквизит НачальнаяПозиция, числового типа – на форму перетаскивать его не будем, он будет применяться для хранения начальной позиции поиска, в том случае, если мы нажимаем на кнопки Назад или Вперед, порция найденных данных, попадающая в поле вывода, будет зависеть от переменной НачальнаяПозиция.
Добавим реквизит СписокРезультатов, тип – СписокЗначений, не будем перетаскивать его на форму, мы будем пользоваться им в программном коде. Роль этого реквизита – хранение найденных данных для того, чтобы при щелчке мышью в поле HTML-документа по ссылке, ведущей к тому или иному объекту, открывалось бы окно этого объекта.
Добавим реквизит ПорогНечеткости, числового типа с параметрами по умолчанию. Перетащим его на форму, в окне настройки свойств элемента формы установим следующие параметры:
Заголовок: Порог нечеткости: 0 Вид: Поле полосы регулирования Минимальное значение: 0 Максимальное значение: 100
Благодаря таким настройкам значение параметра ПорогНечеткости, который мы будем использовать для настройки поиска, можно будет менять, перетаскивая бегунок полосы прокрутки. Порог нечеткости изменяется от 0% до 100%, от него зависит то, насколько результат поиска будет совпадать с поисковым запросом.
Добавим реквизит РазмерПорции, числового типа, с параметрами по умолчанию. Перетащим на форму, в окне настройки свойств элемента установим следующие параметры
Заголовок: Размер порции: 5 Вид: Поле полосы регулирования Минимальное значение: 5 Максимальное значение: 50
Итоговый внешний вид формы представлен на рис 7.16.
(рис 7.16) Внешний вид формы
Это окно будущей формы мы получили, нажав на кнопку Проверить в панели инструментов группы Элементы в редакторе форм.
Ниже приведен код модуля формы, который реализует поиск.
НаКлиенте
Процедура ВыполнитьПоиск(Команда)
//Начинаем новый поиск
НачатьПоиск("Новый поиск");
КонецПроцедуры
НаКлиенте
Процедура Назад(Команда)
//Переходим к предыдущей порции поиска
НачатьПоиск ("Назад");
КонецПроцедуры
НаКлиенте
Процедура Вперед(Команда)
//Переходим к следующей порции поиска
НачатьПоиск("Вперед");
КонецПроцедуры
НаКлиенте
Процедура НачатьПоиск(НаправлениеПоиска)
//Проверяем строку поиска
Если Не ПустаяСтрока(ПоисковыйЗапрос) Тогда
ВыполнитьПоискСервер(НаправлениеПоиска);
Иначе
Предупреждение("Строка поиска не задана");
КонецЕсли;
КонецПроцедуры
НаСервере
Процедура ВыполнитьПоискСервер(НаправлениеПоиска)
//Создаем новый список поиска
СпПоиска = ПолнотекстовыйПоиск.СоздатьСписок();
//Задаем параметры поиска
СпПоиска.СтрокаПоиска = ПоисковыйЗапрос;
СпПоиска.РазмерПорции=РазмерПорции;
СпПоиска.ПорогНечеткости=ПорогНечеткости;
//проверяем направление поиска
//в зависимости от них либо выполняем поиск
//с выдачей его первой части, либо показываем
//предыдущую или следующую порции поиска
Если НаправлениеПоиска = "Новый поиск" Тогда
СпПоиска.ПерваяЧасть();
ИначеЕсли НаправлениеПоиска = "Назад" Тогда
СпПоиска.ПредыдущаяЧасть(НачальнаяПозиция);
ИначеЕсли НаправлениеПоиска = "Вперед" Тогда
СпПоиска.СледующаяЧасть(НачальнаяПозиция);
КонецЕсли;
//НачальнаяПозиция будет использоваться не только в дальнейших вычислениях
//но и как ориентир при получении следующей или предыдущей порции поиска
НачальнаяПозиция = СпПоиска.НачальнаяПозиция();
//Выводим сообщение в поле сведений о поиске и настраиваем доступность
//кнопок Вперед и Назад
Если СпПоиска.Количество() <> 0 Тогда
СведенияОПоиске = "Результаты поиска" + Строка(НачальнаяПозиция + 1)
+ "-" + Строка(НачальнаяПозиция + СпПоиска.Количество())
+ "из" + Строка(СпПоиска.ПолноеКоличество());
Элементы.Вперед.Доступность
= (СпПоиска.ПолноеКоличество() - НачальнаяПозиция) > СпПоиска.Количество();
Элементы.Назад.Доступность = (НачальнаяПозиция > 0);
Иначе
СведенияОПоиске = "Поиск не дал результатов";
Элементы.Вперед.Доступность = Ложь;
Элементы.Назад.Доступность = Ложь;
КонецЕсли;
//Выводим результат поиска в поле HTML-документа
РезультатыПоиска = СпПоиска.ПолучитьОтображение
(ВидОтображенияПолнотекстовогоПоиска.HTMLТекст);
//Заполняем список СписокРезультатов
СписокРезультатов.Очистить();
Для Каждого Результат Из СпПоиска Цикл
СписокРезультатов.Добавить(Результат.Значение);
КонецЦикла;
КонецПроцедуры
НаКлиенте
Процедура РезультатыПоискаПриНажатии
(Элемент, ДанныеСобытия, СтандартнаяОбработка)
//Получаем элемент HTML
ЭлементHTML = ДанныеСобытия.Event.srcElement;
//Если это - элемент полнотекстового поиска
Если (ЭлементHTML.id = "FullTextSearchListItem") Тогда
//Отключаем стандартную обработку события
СтандартнаяОбработка = Ложь;
// Получим номер строки (nameProp) найденной строки
НомерЭлемента = Число(ЭлементHTML.sel_num);
// Откроем форму найденного элемента
ОткрытьЗначение(СписокРезультатов[НомерЭлемента].Значение);
КонецЕсли;
КонецПроцедуры
НаКлиенте
Процедура РазмерПорцииПриИзменении(Элемент)
//Выводим информацию о текущем размере порции поиска
Элементы.РазмерПорции.Заголовок="Размер порции: "+РазмерПорции;
КонецПроцедуры
НаКлиенте
Процедура ПорогНечеткостиПриИзменении(Элемент)
//Выводим информацию о текущем пороге нечеткости
Элементы.ПорогНечеткости.Заголовок = "Порог нечеткости: " + ПорогНечеткости;
КонецПроцедуры
НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
//Задаем размер порции поиска и порог нечеткости
РазмерПорции=5;
ПорогНечеткости=0;
//Блокируем кнопки Вперед и Назад
Элементы.Вперед.Доступность=Ложь;
Элементы.Назад.Доступность=Ложь;
КонецПроцедуры
В процедуре ПриСозданииНаСервере() мы, при создании нашей формы на сервере, во-первых, инициализируем реквизиты РазмерПорции и ПорогНечеткости, во-вторых – скрываем кнопки Назад и Вперед.
После ввода поискового запроса и нажатия на кнопку ВыполнитьПоиск, выполняется клиентская процедура ВыполнитьПоиск(), которая вызывает клиентскую же процедуру НачатьПоиск(). В процедуре НачатьПоиск мы проверяем, заполнена ли строка поиска, после чего вызываем серверную процедуру ВыполнитьПоискСервер(). При вызове мы передаем параметр НаправлениеПоиска – он содержит строку, в зависимости от ее содержимого мы либо выдаем исходные результаты поиска ("Новый поиск"), либо получаем следующую порцию найденных данных ("Вперед"), либо – предыдущую ("Назад"). Фактически, нажимая кнопки ВыполнитьПоиск, Вперед или Назад мы вызываем одинаковую процедуру поиска, выполняем новый поиск, но при выдаче результатов поиска ориентируемся на значение реквизита НачальнаяПозиция, в итоге – выдаем различные результаты при нажатии на различные кнопки.
При входе в серверную процедуру ВыполнитьПоискСервер(), мы инициализируем переменную СпПоиска – она будет содержать список полнотекстового поиска, настраиваем параметры поиска, устанавливая строку поискового запроса, порог нечеткости, размер порции, выполняем поиск, записываем реквизит НачальнаяПозиция, выводим сообщение о результатах поиска и устанавливаем доступность кнопок, после чего выводим найденные данные в виде HTML-кода в поле РезультатыПоиска и заполняем реквизит СписокРезультатов.
При щелчке по одной из ссылок в поле РезультатыПоиска, срабатывает обработчик РезультатыПоискаПриНажатии(). Здесь мы определяем номер элемента, по которому щелкнул мышью пользователь и открываем форму для объекта, хранящегося в соответствующем элементе списка значений СписокРезультатов.
При перемещении бегунков, связанных с реквизитами ПорогНечеткости и РазмерПорции, вызываются их обработчики ПриИзменении, роль которых – проинформировать пользователя о текущем состоянии данных показателей.
На рис 7.17 вы можете видеть работу с окном поиска. При текущем установленном пороге нечеткости (34 в данном случае) по запросу "Петров" система находит, кроме слова "Петров" еще и "Петр" и "Петрович".
(рис 7.17) Результаты поиска
В информационных базах 1С:Предприятие 8 существует немало регулярно повторяемых последовательностей действий, которые вполне можно было бы доверить автоматике. Например, это обмен данными с другими информационными системами, резервное копирование информации, обновление поисковых индексов и так далее. Для реализации выполнения подобных работ в 1С:Предприятие предусмотрен механизм
(рис 7.18) Новое регламентное задание
В качестве метода, который будет выполняться регламентным заданием, может выступать процедура неглобального общего модуля, которая может быть исполнена на сервере. Для задания такой процедуры создадим новый общий модуль (.
(рис 7.19) Новый модуль для процедуры, реализующей регламентное задание
Откроем код модуля и введем туда следующий код:
Процедура ПроверкаЗадания() Экспорт
Сообщить("Задание работает, сейчас "+ТекущаяДата());
КонецПроцедуры
Теперь укажем данную процедуру в настройках задания, в поле Имя метода, и перейдем к редактированию расписания. Расписание запуска настраивается с помощью нескольких вкладок окна Расписание, итоговый результат отображается в нижней части окна. На вкладке Общее установим в поле Повторять каждые – значение .
(рис 7.20) Окно настройки расписания, вкладка Общее
На вкладке Дневное мы можем настроить дневное расписание выполнения задания. Установим параметр Повторять через в значение .
(рис 7.21) Окно настройки расписания, вкладка Дневное
На вкладке Недельное можно задать расписание запуска по неделям, на вкладке Месячное – расписание по месяцам.
Ограничимся в настройках расписания вышеприведенными изменениями, закроем окно нажатием на кнопку ОК.
Мы работаем с информационной базой в файловом режиме. Если бы мы работали с серверным вариантом, то, для того, чтобы задание было запущено и выполнялось в соответствии с расписанием, нам нужно было бы лишь установить флажок Предопределенное в форме свойств задания. Для файлового варианта нам понадобятся некоторые дополнительные усилия (флажок Предопределенное мы так же установим).
А именно, создадим обработку с именем ОбработкаЗаданий. Включим ее в подсистему Администрирование. Создадим форму обработки, добавим на нее надпись "Обработка заданий. Закрыть для завершения", а в модуль обработки добавим следующий код:
НаКлиенте
Процедура ПриОткрытии(Отказ)
ПодключитьОбработчикОжидания("ОбработкаЗаданий", 5);
КонецПроцедуры
НаКлиенте
Процедура ОбработкаЗаданий()
ВыполнитьОбработкуЗаданий();
КонецПроцедуры
В этом коде мы подключаем обработчик ожидания формы при открытии формы. Он использует указанную при его вызове процедуру в качестве обработчика ожидания. Эта процедура будет вызываться каждый раз по истечению указанного при подключении интервала времени (в секундах).
В процедуре . вы можете видеть окно программы с открытой формой обработки, ответственной за выполнение заданий. Как можно судить из окна служебных сообщений, наше 30 секунд.
(рис 7.22) Форма обработки, ответственной за вызов метода ОбработкаЗаданий()
Для того, чтобы обеспечить обработку
Функциональные опции – это одна из новых возможностей платформы 1С:Предприятие 8.2. Смысл их использования заключается в том, что они позволяют настраивать пользовательский интерфейс в соответствии с настройками функциональных опций, задавать видимость реквизитов в формах. Кроме того, разработчик имеет возможность реализовывать программный код, выполнение которого зависит от состояния функциональной опции.
Создадим функциональную опцию, которая позволяет включать и отключать ведение расчета заработной платы в конфигурации. С ее помощью мы сможем быстро скрывать те части интерфейса, которые относятся к решению расчетных задач. Функциональная опция сама по себе не хранит какого-либо значения, которое позволяет ее включать и отключать. Обычно для хранения состояния функциональной опции используют константу, хотя она может быть привязана и к другому объекту, например – к реквизиту какого-либо объекта.
Создадим новую константу, назовем ее УчетЗарплаты, тип – Булево. Включим константу в подсистему Администрирование и в форму констант для того, чтобы мы могли редактировать ее. Кроме того, в форме констант зададим обработчик ПослеЗаписи следующего вида:
НаКлиенте Процедура ПослеЗаписи(ПараметрыЗаписи) ОбновитьИнтерфейс(); КонецПроцедуры
Смысл использования команды ОбновитьИнтерфейс() заключается в том, чтобы после вступления в силу изменения константы, связанной с функциональной опцией, обновить, перерисовать интерфейс. Иначе для того, чтобы изменения вступили в силу, придется перезапускать конфигурацию.
Создадим новую функциональную опцию, назовем ее . Включим функциональную опцию в подсистему Администрирование.
(рис 7.23) Настройка параметров функциональной опции
Теперь перейдем на закладку окна настройки функциональной опции ), что относится к расчету заработной платы. Если какие-либо объекты, например, справочники, относятся к различным частям конфигурации, не будем их отмечать, иначе при выключении функциональной опции они "исчезнут" из интерфейса.
(рис 7.24) Настройка состава функциональной опции
Выбор подсистемы РасчетЗаработнойПлаты в данном случае не ведет к автоматическому выбору всех объектов, включенных в подсистему. При выборе мы лишь подразумеваем скрытие или отображение раздела командного интерфейса РасчетЗаработнойПлаты.
Запустив систему в пользовательском режиме, мы сможем включать и отключать видимость объектов, относящихся к зарплатной подсистеме нашей конфигурации, просто устанавливая или снимая флаг у константы УчетЗарплаты.
Более сложный вариант использования функциональных опций заключается в настройке видимости отдельных элементов форм в том случае, если значение функциональной опции хранится в реквизите какого-либо объекта.
Внесем изменения в конфигурацию, в частности, в справочник ФизическиеЛица добавим реквизит логического типа ИмеетОпытКадровойСлужбы и разместим его на форме элемента справочника.
Если это свойство включено, то после выбора соответствующего физического лица в форме элемента справочника Сотрудники реквизит справочника Сотрудники Расчетчик должен отображаться, если свойство ИмеетОпытКадровойСлужбы имеет значение Ложь, то реквизит Расчетчик должен быть скрыт.
Добавим новую функциональную опцию, назовем ее РаботаСРасчетчиками, включим в подсистему Администрирование, на закладке Основные установим реквизит Хранение в значение .
(рис 7.25) Настройка параметров функциональной опции
Перейдем на закладку окна настройки функциональной опции .
(рис 7.26) Настройка состава функциональной опции
Функциональную опцию в данном случае нужно дополнить параметром функциональной опции. Создадим новый параметр функциональной опции, назовем его Расчетчик, в свойстве Использование выберем .
(рис 7.27) Настройка параметра функциональной опции
Теперь нам нужно задать параметр функциональной опции для каждого конкретного экземпляра формы справочника Сотрудники для того, чтобы, в зависимости от состояния реквизита справочника ФизическиеЛица мы могли бы настроить внешний вид формы справочника Сотрудники – скрыть или отобразить реквизит Расчетчик.
Перейдем в форму элемента справочника Сотрудники, создадим обработчик ПриСозданииНаСервере, разместим в нем следующий код:
НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
ПараметрыФункциональныхОпций
= Новый Структура("Расчетчик", Объект.ФизическоеЛицо);
УстановитьПараметрыФункциональныхОпцийФормы(ПараметрыФункциональныхОпций);
КонецПроцедуры
Здесь мы создаем новую структуру, которая содержит, в ключе – наименование параметра функциональной опции, в значении – ссылку на объект, из которого следует брать значение функциональной опции.
С помощью команды УстановитьПараметрыФункциональныхОпцийФормы, которой мы передаем сформированную структуру, мы настраиваем функциональную опцию, которая, в свою очередь, повлияет на внешний вид формы.
Кроме того, предусмотрим ситуацию, в которой пользователь выбирает различные физические лица, у некоторых из которых интересующий нас признак ИмеетОпытКадровойСлужбы установлен, у некоторых нет – то есть – состав реквизитов, отображаемых на форме нужно пересматривать и, при необходимости, обновлять, после выбора нового физического лица. Для этого добавим в обработчик события изменения поля ФизическоеЛицо формы элемента справочника Сотрудники код, аналогичный вышеприведенному, в итоге этот обработчик будет выглядеть так:
НаКлиенте
Процедура ФизическоеЛицоПриИзменении(Элемент)
ПараметрыФункциональныхОпций
= Новый Структура("Расчетчик", Объект.ФизическоеЛицо);
УстановитьПараметрыФункциональныхОпцийФормы(ПараметрыФункциональныхОпций);
СформироватьНаименование();
КонецПроцедуры
Команда СформироватьНаименование() относится к уже существующим в форме механизмам.
Опробуем созданный механизм на практике. Установим флаг .
(рис 7.28) Воздействие функциональной опции на реквизиты формы
Если функциональная опция используется для управления реквизитами, которые, например, влияют на добавление каких-либо данных в регистры, на расчет каких-либо показателей (скажем, включение и отключение складского учета), скрытие или отображение реквизита (например, реквизита документа Склад или "отключение" измерения регистра Склад) само по себе не влияет на программные механизмы работы системы. Это означает, что программный код, который должен выполняться при том или ином состоянии функциональной опции, разработчик должен писать самостоятельно, разветвляя, при необходимости, его выполнение в зависимости от состояния функциональной опции.
Продемонстрируем это на примере. Основываясь на состоянии функциональной опции РаботаСРасчетчиками, будем выводить различные сообщения при закрытии формы элемента справочника Сотрудники. Создадим в модуле формы элемента справочника обработчик ПриЗакрытии, приведем его к следующему виду:
НаКлиенте
Процедура ПриЗакрытии()
Если ПолучитьФункциональнуюОпциюФормы("РаботаСРасчетчиками") Тогда
Предупреждение("Этот сотрудник может быть расчетчиком");
Иначе
Предупреждение("Этот сотрудник не может быть расчетчиком");
КонецЕсли;
КонецПроцедуры
Здесь мы пользуемся функцией ПолучитьФункциональнуюОпциюФормы(), которая принимает на входе строковое имя функциональной опции. Если функция возвратит значение Истина – пользователь увидит сообщение "Этот сотрудник может быть расчетчиком" - в нашем случае подобное сообщение будет выведено для сотрудника Расчетчиков. В противном случае выводится сообщение "Этот сотрудник не может быть расчетчиком". Аналогично, анализируя состояние функциональных опций формы, можно управлять исполнением кода.
пользователем реализованы программно.
В этой лекции мы рассмотрели работу с механизмом распределенных баз данных, создали систему полнотекстового поиска в базе данных, научились пользоваться функциональными опциями, параметрами функциональных опций и регламентными заданиями.
Для данной лекции подготовлен видеоурок.
Для получения официальных документов о завершении программы дополнительного профессионального образования (удостоверения о повышении квалификации, дипломов о профессиональной переподготовке и MBA) необходимо предоставить:
Внимание! Вы можете не заказывать доставку бумажной версии официального документы, а скачать его в электронном виде и распечатать самостоятельно. Информация о выданном документе в течение 1 месяца загружается в Федеральную информационную систему «Федеральный реестр сведений о документах об образовании и (или) о квалификации, документах об обучении» - ФИС ФРДО.
Доступ на новый сайт осуществляется с использованием адреса электронной почты, который был указан вами при регистрации на "старом". Мы постарались перенести все ваши данные с прежнего ресурса, однако не исключена вероятность потери части информации.
При возникновении проблемы со входом, воспользуйтесь функцией сброса пароля
Если вы обнаружите несоответствия, пожалуйста, сообщите нам.