Это четвертая статья из цикла, посвященного основам работы на ISBL. В этой статье будут рассмотрены основы работы с объектами в ISBL.
Ранее уже рассказывалось, что представляет собой ISBL и основы его синтаксиса, а также были рассмотрены типовые варианты использования функций ISBL.
Объектом в ISBL считается любой элемент системы, с которым прикладной разработчик так или иначе может взаимодействовать – электронный документ, задача, справочник и т.д. У каждого объекта есть методы для выполнения каких-либо действий (например, сохранение электронного документа) и свойства, содержащие данные об объекте.
Объектная модель IS-Builder – иерархия типов объектов платформы IS-Builder.
Объект можно получить следующими способами:
- С помощью специальных системных функций, например, CreateStringList(), предназначенной для создания списка строк.
- С помощью других объектов, например объектов-фабрик, работа с которыми будет рассмотрена позже в этой статье.
Свойство объекта - это способ доступа к данным об объекте. Свойствами объекта, например IEDocument, являются наименование, автор и т.п.
Метод объекта - это операция над объектом. Например, старт задачи, экспорт документа с блокировкой и т.п.
Для обращения к свойствам и методам объектов используется следующий синтаксис:
<переменная-объект>.<имя свойства>([<параметры свойства>])
<переменная-объект>.<имя метода>([<параметры метода>])
Здесь [] указывают на то, что различные методы или свойства могут вызываться как с параметрами, так и без них.
// Получение объекта через системную функцию // Создадим объект список строк (IStringList) StringList = CreateStringList() // Установим значение свойства Delimiter(Разделитель) // Строки в списке будут разделяться указанным разделителем StringList.Delimiter = ';' // Добавим строки и выведем текст на экран StringList.Add(‘Пример работы с объектами’) StringList.Add(‘Эта строка будет после “;”.’) // Выведем текст на экран EditText(StringList.DelimitedText)
Начиная с DIRECTUM 5.1 функционал редактора вычислений расширен. Для упрощения разработки на ISBL добавлены подсказки по объектной модели:
В следующем примере мы получим объект IEDocument, изменим его имя и сохраним:
// Получение объекта через объект-фабрику // ИД документа EDocID = '35123' // С помощью метода GetObjectByID получим объект EDocument = EDocuments.GetObjectByID(EDocID) // Изменим наименование документа EDocument.Requisites('ISBEDocName').Value = ‘Новое наименование’ // Вызовем метод Save - сохранение документа EDocument.Save()
ISBL поддерживает работу как с внутренними объектами - объектная модель IS-Builder, так и с внешними, например, объектная модель Microsoft Office.
Наследование - это механизм, реализующий возможность использования объектом-наследником функциональности, методов и свойств родительского объекта.
Рассмотрим примеры работы наследования для объекта ITask. Общая схема для объекта типа ITask выглядит так:
IObject <- IEdmsObject <- ICustomWork <- ITask, где "<-" указывает на родительский объект.
Используя механизм наследования, для объекта ITask есть возможность вызвать любые методы или обратиться к любым свойства родительского объекта. Например, можно вызвать метод Save(), определенный для родительского объекта типа IObject, который сохранит изменения набора данных.
Вызываемые родительские методы или свойства, работают в контексте объекта-наследника. Метод GetObjectByID фабрики задач возвращает задачу, объект ITask,а при вызове GetObjectByIDу фабрики папок, IFolderFactory, мы получим папку, объект IFolder.
Метод GetObjectByID фабрики задач и фабрики папок наследуется от объекта IFactory. Из справки можно узнать, что IFactory.GetObjectByID возвращает объект IObject, это означает, что наследники объекта IFactory вернут объекты-наследники IObject.
Объекты-фабрики для создания, удаления и получения других объектов(документов, задач, задачний и т.п.). Получить объект-фабрику можно :
Фабрики позволяют выполнять:
- Создание и удаление объектов.
- Получение доступа к объектам.
- Выполнение характерных для данного типа объекта действий и т.д. Например «создать из файла» для фабрики документов или «очистить время напоминания» для фабрики задач.
// Создать новую задачу Task = Tasks.CreateNew() // Установить тему задачи Task.Subject = 'Тестовая задача.' // Получим имя текущего пользователя AuthorName = Application.Connection.UserName // Получим объект IUser по имени текущего пользователя Author = ServiceFactory.GetUserByName(AuthorName) // Установим автора задачи Task.Author = Author.Code // Создадим задание (этап маршрута) самому себе RouteStep = Tasks.CreateRouteStep(1; Author; jkJob; Today(); ""; "") // Добавить задание в маршрут Task.Route.Add(RouteStep) // Старт задачи Task.Start()
В приведенном выше примере предопределенная переменная Tasks - хранит фабрику задач ITaskFactory, ServiceFactory - фабрику служебных объектов IServiceFactory.
Метод CreateRouteStep используется для создания этапа маршрута, поэтому использовать его имеет смысл только при работе с объектами ITask – для добавления нового этапа.
IEDocument - объект, который предназначен для работы с электронными документами.
Рассмотрим пример, в котором запросим у пользователя ID документа, установим стадию жизненного цикла документа в "Устаревший":
// Диалог запроса ID документа EDocumentID = InputDialog('ИД'; ''; 'Число'; 'Введите ИД документа: ') // Получить объект по заданному ИД EDocument = EDocuments.GetObjectByID(EDocumentID) // Установить стадию жизненного цикла в "Устаревший" EDocument.SetLifeCycleStageByName("Obsolete")
И схожий пример, чтобы заблокировать документ:
// Диалог запроса ID документа EDocumentID = InputDialog('ИД'; ''; 'Число'; 'Введите ИД документа: ') // Получить объект по заданному ИД EDocument = EDocuments.GetObjectByID(EDocumentID) MBResult = MessageBox(INFORMATION_CAPTION; 'Заблокировать документ?'; 'Да|Нет'; 'Нет'; 'Нет') if MBResult == 'Да' // Заблокировать документ EDocument.Lock // Сообщение о блокировке ShowMessage("Документ " & EDocument.Name & " заблокирован.") endif
Следующий пример выводит список имен и значений всех реквизитов объекта:
// Получим документ EDoc = EDocuments.GetObjectByID(EDocID) // Список строк, в который будем записывать информацию о реквизитах RequisiteList= CreateStringList() // Разделитель между строками – знак переноса строки, CR RequisiteList.Delimiter = CR Index = 0 // Пройдемся по всем реквизитам while Index < EDoc.RequisiteCount RequisiteList.Add(EDoc.RequisiteByIndex(Index).Name) RequisiteList.Add(EDoc.RequisiteByIndex(Index).AsString) RequisiteList.Add("----------") Index = Index + 1 endwhile EditText(RequisiteList.DelimitedText)
В этом примере, было использовано свойство RequisiteCount объекта IObject - оно содержит количество реквизитов объекта, а метод IObject.RequisiteByIndex() - по заданному индексу возвращает объект реквизит IRequisite. Этот способ получения объекта-реквизита IRequisite удобен, если мы хотим получить различную информацию о всех реквизитах объекта, но на практике чаще встречается задача получить информацию о реквизите по имени реквизита:
// Получим значение реквизита и выведем в сообщении // Value, свойство объекта IRequisite, хранит значение реквизита ShowMessage(EDoc.Requisites('ISBEDocName').Value) ShowMessage(EDoc.ИД)
Для этого используется свойство IObject.Requisites(<Имя реквизита>), которое возвращает объект IRequisite по его имени.
В вычислениях на ISBL есть возможность обратиться напрямую к значению реквизита указав его имя после точки, например EDoc.ИД– вернет ИД документа. Запись EDoc.ИД эквивалентна EDoc.Requisites(“ИД”).Value
Также при работе с реквизитами, используйте свойство IObject.RequisiteValues - список типа IList, который содержит набор пар <имя реквизита> и <значение реквизита>.
Детальные разделы- это объекты типа IDataSet, набор данных, представляющий собой совокупность записей (по аналогии со справочником, который является схожим типом объекта). Таким образом, детальные разделы - это "таблицы внутри записей".
У большинства объектов, например у IEDocument или ITask, в системе есть детальные разделы. Для получения детального раздела нужно вызвать метод DetailDataSet() объекта IObject. Детальные разделы нумеруются с 1 по 6. Чтобы проверить, существует ли детальный раздел у объекта, нужно вызвать метод DetailExists() объекта IObject и передать ему номер раздела в качестве параметра.
Рассмотрим пример работы с детальным разделом:
// Диалог запроса ID документа DialogResult = InputDialog('ИД|Пользователь'; ''; 'Число|Аналитика:ПОЛ'; 'Введите ИД документа и выберите пользователя: ') // Получить результаты выполнения диалога EDocumentID = SubString(DialogResult; "|"; 1) UserCode = SubString(DialogResult; "|"; 2) User = ServiceFactory.GetUserByCode(UserCode) EDocument = EDocuments.GetObjectById(EDocumentID) // Получить детальный раздел 1 для документа, // который содержит информацию о правах доступа на электронный документ. // Более подробное описание можно найти в справочной системе, в книге // «Объектная модель DIRECTUM», в разделе «Реквизиты объектов DIRECTUM». EDocumentDDS = EDocument.DetailDataSet(1) AccessData = CreateStringList() AccessData.Delimiter = CR // Определить, есть ли ИД указанного пользователя в детальном разделе if EDocumentDDS.Locate('ISBEDocAccountID'; User.ID) ShowMessage('У пользователя ' & User.FullName & ' вид доступа "' & EDocumentDDS.Requisites('ISBEDocAccessType').Value & '" для указанного документа!') endif AccessData.Add("Список ИД пользователей или групп, имеющих права на изменение документа:") // Перейти на первую запись EDocumentDDS.First() // Пока запись не последняя while not EDocumentDDS.EOF if EDocumentDDS.Requisites('ISBEDocAccessType').Value == 'Изменение' AccessData.Add(EDocumentDDS.Requisites('ISBEDocAccountID').Value) endif // Перейти к следующей записи EDocumentDDS.Next() endwhile EditText(AccessData.DelimitedText)
Как уже упоминалось ранее, IDataSet - это объект, представляющий собой набор данных, а также методы и свойства для работы с ним. Работа с IReference, наследником IComponent, похожа на работу с IDataSet.
Набор данных IReference - это список записей. У каждой записи есть набор реквизитов, которые устанавливаются в разделе "Карточка" справочника. При работе с IReference нужно учитывать, что одна запись всегда является текущей. Рассмотрим работу с IReference более подробно:
// Получим объект IReference WorkerRef = References.ReferenceFactory('РАБ').GetComponent // Открыть набор данных справочника WorkerRef.Open() // Перейти к первой записи WorkerRef.First() // Выполнять, пока не конец справочника while not WorkerRef.EOF if WorkerRef.Requisites(“Дополнение”).Value == ‘Иванов Иван Иванович’ // Открыть запись WorkerRef.OpenRecord() // Установить табельный номер WorkerRef.Requisites('Дополнение3').Value = "123" // Сохранить изменения WorkerRef.Save() // Закрыть запись WorkerRef.CloseRecord() // Если запись нашли, перейдем к последней записи // и выйдем из цикла WorkerRef.Last() endif endwhile // Закрыть набор данных справочника WorkerRef.Close()
Каждая запись может иметь несколько детальных разделов ("табличная часть" карточки справочника), которые имеют тип IDataSet. Записи детальных разделов, однако, не могу иметь своих детальных разделов.
Рассмотрим пример работы с детальным разделом объектом IReference – добавим новую запись в справочник «Журналы регистрации»:
// Получить объект IReference для указанного справочника Reference = References.ReferenceFactory('ГДЛ').GetComponent // Открыть набор данных Reference.Open // Добавить запись Reference.Append // Открыть запись Reference.OpenRecord // Заполним реквизиты Reference.Requisites("Содержание").Value = "Тестовый журнал." Reference.Requisites("МестоРег").Value = "1" // Получим объект IDataSet детального раздела ReferenceDDS = Reference.DetailDataSet(1) // Добавим запись в детальный раздел ReferenceDDS.Append // Изменим реквизит детального раздела ReferenceDDS.Requisites('СтрокаТ').Value = "123" MBSaveResult = MessageBox(ATTENTION_CAPTION; 'Сохранить?'; 'Да|Нет'; 'Нет'; 'Нет') if MBSaveResult == 'Да' // Сохранить изменения Reference.Save else // Отменить изменения Reference.Cancel endif Reference.CloseRecord Reference.Close
Скажите, пожалуйста, как сделать реквизит в детальном разделе readonly?
Двойной клик на таблице в редакторе формы и потом:
Извините за некорректный вопрос, как программно закрыть поля для редактирования при наступлении некоторого события, например:если поле "Признак" принимает значение "Да", то поле "Дата" закрыто для редактирования.(оба реквизита таблицы 1. )
Функция для настройки доступности реквизитов на форме
Авторизуйтесь, чтобы написать комментарий