Курс молодого самурая: Управляем сабформой
Как известно, каждая форма может иметь не более одного источника данных. И для того, что бы можно было вывести на экран данные сразу из двух таблиц, зачастую используют сабформу (SubForm) .
Сабформа является отдельной формой, обычно списочной, которая вызывается другой формой в процессе работы. Выбор сабформы осуществляется при помощи свойства SubFormID элемента «сабформа». А связь формы и сабформы осуществляется посредством свойства SubFormLink. Стандартным примером такой связи служит Заказ Продажи (см. Рис. 1). Заметим, что при вставке новой строки в сабфому, в рамках нашего примера, номер документа в строке присваивается автоматически именно из-за указанного свойства.
Рис. 1 Свойство сабформы, отвечающее за связь данных.
Далее рассмотрим вопрос передачи данных из формы в сабформу и наоборот. Так как эти две формы являются различными хоть и зависимыми они не имеют прямого доступа к данным друг друга. Однако, если мы дадим имя сабформе (см. часть первую: Управляем Формой), то получим доступ, как к ее параметрам, так и к функциям.
Соответственно, написав функции SetValue и GetValue на сабформе, мы сможем передавать на нее данные из формы. Таким образом, при наступлении некого события на форме мы тут же можем передать «сигнал» о нем на сабформу. Если на сабформу были переданы данные, которые должны повлиять на отображаемую информацию, то следует обновить сабформу. Для этого используется вызов:
CurrForm.MySubForm.FORM.Update.
Причем функцию Update придется сделать самостоятельно. Заметим, что не стоит путать ее с вызовом CurrForm.MySubForm.UPDATE.
Наиболее интересен случай обработки формой события на сабформе. Несмотря на то, что сейчас будет рассказано о двух способах реализации такой обработки, настоятельно рекомендуется избегать таких ситуаций!
Итак, способ первый, пожалуй, самый распространенный:
Используется свойство TimerInterval и триггер OnTimer формы (см. Часть первая: Управляем формой.). И выгляди примерно так:
Form - OnTimer() IF OldValue = GetValue THEN EXIT; //код, который запускает некую процедуру по событию на сабформе. …..
Основным минусом такого способа является трудность отладки формы с таким триггером.
Второй способ не является стандартным и работает через XML 4.0. DOM.
Суть метода заключается в том, что вызов функции XMLDoc.LoadXML запускает триггер OnreadyStateChanged вне зависимости в каких объектах они находятся. Т.е. нам надо объявить переменную на форме, а затем передать на сабформу и ждать события. Пример кода представлен ниже.
OBJECT Form 50000 MyForm { OBJECT-PROPERTIES { Date=09-11-30; Time=20:14:19; Modified=Yes; Version List=; } PROPERTIES { Width=8000; Height=4840; OnOpenForm=BEGIN CREATE(XmlDoc); CurrForm.SubForm.FORM.SetXmlDoc(XmlDoc); END;OnCloseForm=BEGIN CLEAR(XmlDoc); END; } CONTROLS { { 1000000000;TextBox;330 ;220 ;4290 ;440 ;Editable=No; SourceExpr=TextVar } { 1000000001;SubForm;220 ;880 ;7480 ;2310 ;Name=SubForm; SubFormID=Form50001 } } CODE { VAR TextVar@1000000000 : Text[50]; XmlDoc@1000000001 : Automation "{F5078F18-C551-11D3-89B9-0000F81FE221} 4.0:{88D969C0-F192-11D4-A65F-0040963251E5}:'Microsoft XML, v4.0'.DOMDocument40" WITHEVENTS; EVENT XmlDoc@1000000001::ondataavailable@198(); BEGIN END; EVENT XmlDoc@1000000001::onreadystatechange@-609(); BEGIN IF (XmlDoc.readyState = 4) THEN BEGIN //код который обрабатывает событие на сабформе END; END; BEGIN END. } } OBJECT Form 50001 MySubForm { OBJECT-PROPERTIES { Date=09-11-30; Time=20:35:51; Modified=Yes; Version List=; } PROPERTIES { Width=8030; Height=2420; } CONTROLS { { 1000000000;TextBox;220 ;220 ;4180 ;440 ;SourceExpr=TextVar1; OnAfterValidate=BEGIN Fire (); END; } { 1000000001;TextBox;220 ;770 ;4180 ;440 ;SourceExpr=TextVar2 } } CODE { VAR TextVar1@1000000000 : Text[50]; TextVar2@1000000002 : Text[50]; XmlDoc@1000000001 : Automation "{F5078F18-C551-11D3-89B9-0000F81FE221} 4.0:{88D969C0-F192-11D4-A65F-0040963251E5}:'Microsoft XML, v4.0'.DOMDocument40"; PROCEDURE SetXmlDoc@1000000000(pXmlDoc@1000000000 : Automation "{F5078F18-C551-11D3-89B9-0000F81FE221} 4.0:{88D969C0-F192-11D4-A65F-0040963251E5}:'Microsoft XML, v4.0'.DOMDocument40"); BEGIN XmlDoc := pXmlDoc; END; PROCEDURE Fire@1000000004(); BEGIN XmlDoc.loadXML('<root></root>'); END; PROCEDURE GetText@1000000001() : Text[50]; BEGIN EXIT(TextVar1); END; BEGIN END. } }
Метки: Бариев Юрий
22 Июль 2008 в 11:37
Гениально, использовать события от внешних компонент.
Интересно можно ли применить для этих целей очереди http://www.nav4u.ru/archives/49-ispolzovanie-microsoft-message-queue-dlya-obmena-informaciej-s-dynamics-nav-navision/
17 Сентябрь 2008 в 4:18
Коротко и ясно:) Сам использую эти инструменты. Надеюсь остальным пригодится)