оглавление   ДМ   экономическая информатика   визуальные среды - 4GL   Теория и практика обработки информации

Разработка имитационных моделей в виде приложений с интерфейсом

1. Применение текстовых объектов и потоков данных

Модель представляет собой набор операторов, содержащихся в одном объекте "Модель" и в любом количестве необязательных текстовых объектов.

Текстовые объекты с наборами операторов модели подключаются к объекту "Модель" командой INCLUDE. Формат команды:

INCLUDE         A

Операнд А - спецификация файла (полный путь доступа к файлу). Допустимые значения - String. Например:

INCLUDE         "DanDon.txt"
INCLUDE          "D:\Primer\DanZad.txt"

В первом примере путь доступа к файлу не приводится, так как предполагается, что файл с указанным именем находится в папке модели. Во втором примере указан путь доступа к файлу.

Команда INCLUDE является срочной командой. При трансляции она заменяется файлом. Поэтому располагать в модели команду INCLUDE нужно там, где должны быть операторы или команды, содержащиеся в файле.

Все дополнительно вводимые файлы нумеруются транслятором целыми числами, начиная с 0. Номер 0 присваивается объекту-модели. Нескольким вводам одного файла также присваиваются уникальные номера, т. е. каждый ввод файла приводит к созданию отличающихся наборов блоков.

Команда INCLUDE допускает пять уровней вложенности файлов модели. Нельзя помещать команду INCLUDE в Plus-процедуру.

Операторы INCLUDE можно также закреплять за функциональными клавишами. Это позволяет одним нажатием клавиши объекту "Процесс моделирования" передать набор команд и (или) Plus-операторов, содержащихся в текстовом файле.

Текстовые объекты применяются и вместе с потоками данных. Потоки данных позволяют процессу моделирования считывать из файлов и записывать данные в файлы, а также создавать файлы результатов моделирования для последующего использования.

Поток данных - это последовательность текстовых строк, используемых процессом моделирования. Существуют два типа потоков данных:

Основной элемент потока данных - текстовая строка, которая является строкой печатных символов, включая пробелы.

Для обработки потоков данных существуют пять блоков GPSS World: OPEN, CLOSE, READ, WRITE, SEEK. Три из них - READ, WRITE, SEEK - выполняют операции только с одной отдельной строкой текста.

Перейдем к рассмотрению блоков обработки потоков данных.

1.1. Блок OPEN

Блок OPEN предназначен для инициализации потока данных. Формат блока:

OPEN   A,[B],[C]

Операнд А - дескриптор потока данных. Операнд определяет тип потока данных. Он обрабатывается как строка. Если это нулевая строка, создается поток в памяти. Если это канальное имя, такое как "\pipe\mypipe", создается канальный поток. В противном случае создается поток ввода-вывода и предполагается, что операнд А является спецификацией файла.

Операнд В - номер потока данных, произвольное положительное число, задаваемое пользователем. Нумерация потоков введена с целью использования одновременно в одном процессе моделирования нескольких потоков данных. По умолчанию номер потока данных равен 1.

Операнд С - метка блока, в который направляется транзакт в случае ошибки инициализации потока данных. Коды ошибок:

OPEN   ("Plan.txt"),3,Kon1 
OPEN   ("G\Model\NorPogr.txt") 
OPEN   ("")

В первом примере открывается поток ввода-вывода, потоку присваивается номер 3 и в случае ошибки открытия активный транзакт направляется к блоку с меткой Kon1. Операндом А указан неполный путь доступа к файлу, поэтому подразумевается, что используется папка объекта "Процесс моделирования". Если файл с указанным именем не найден, то предполагается, что файл создается, и ошибка не возникает.

Во втором примере операндом А указан полный путь доступа к файлу, открываемому потоку ввода-вывода по умолчанию присваивается номер один. В случае ошибки открытия активный транзакт направляется к следующему по порядку блоку.

В третьем примере открывается поток в памяти.

Замечание.Если указанный операндом А файл найден, во время обработки блока OPEN он полностью загружается в виртуальную память. Все находившиеся в файле данные хранятся как часть объекта "Процесс моделирования" до тех пор, пока поток данных не будет закрыт. Все изменения данных отражаются в файловой системе только после того, как поток данных закрывается блоком CLOSE или библиотечной Plus-процедурой Close().

1.2. Блок CLOSE

Блок CLOSE предназначен для закрытия потока данных. Формат блока:

CLOSE A,[B],[C]

Операнд А - номер или имя параметра транзакта, в который записывается код ошибки закрытия потока данных. Если такой параметр не существует, он создается.

Операнд В - номер закрываемого потока данных, по умолчанию равен 1, т. е. если операнд В не используется, закрывается поток номер один.

Операнд С - метка блока, в который направляется транзакт в случае ошибки закрытия потока данных. Коды ошибок:

Например:

CLOSE Parm_Error,(P1+1)

В примере блок CLOSE закрывает поток данных, номер которого задан выражением в скобках. Это выражение вычисляется, округляется и используется в качестве номера потока данных (должен быть положительным целым числом).

Блок CLOSE для потоков ввода-вывода записывает данные из виртуальной памяти в дисковый файл.

1.3. Блок READ

Блок READ предназначен для считывания из потока данных текстовой строки. Формат блока:

READ   A,[B],[C]

Операнд А - номер или имя параметра транзакта, в который записывается считанная из потока ввода или потока в памяти строка, находящаяся на позиции текущей строки. После считывания позиция текущей строки увеличивается на единицу. Если такой параметр активного транзакта не существует, он создается.

Операнд В - номер потока данных, из которого производится считывание. По умолчанию равен 1, т. е. если операнд В не используется, считывание производится из потока номер один.

Операнд С - метка блока, в который направляется транзакт в случае ошибки считывания. Если операнд С не используется, код ошибки все равно сохраняется. Для его получения нужно использовать блок CLOSE. Коды ошибок:

Например:

READ   Stroka_Text,4,Kon5

В примере блок READ считывает текстовую строку из потока данных номер 4 и записывает в параметр транзакта с именем Stro-ka_Text. Если текстовая строка считывается без ошибки, а параметр активного транзакта не существует, он создается. В случае ошибки строка не считывается и активный транзакт направляется к блоку с меткой Kon5.

1.4. Блок WRITE

Блок WRITE предназначен для передачи текстовой строки потоку данных. Формат блока:

WRITE A,[B],[C],[D]

Операнд А - текстовая строка, которая должна быть передана потоку данных.

Операнд В - номер потока данных, по умолчанию равен 1.

Операнд С - метка блока, в который направляется транзакт в случае ошибки записи. Коды ошибок:

Операнд D - задает режим работы блока WRITE. Если операнд D не используется (по умолчанию) или равен ON, блок WRITE работает в режиме вставки. Если операнд D равен OFF - в режиме замены.

Режим вставки:

WRITE     "INITIAL    MX$TDon(1,1),420",5,Met3

В этом примере блок WRITE передает текстовую строку потоку данных с номером 5. Если происходит ошибка, активный транзакт переходит к блоку с меткой Met3. Иначе он переходит к следующему по порядку блоку. Если в данном случае поток данных является потоком вывода или потоком в памяти, запись производится в режиме вставки, так как операнд D не используется.

Замечание 1.Если операнды С блоков OPEN, CLOSE, READ и WRITE не используются, ошибка игнорируется. Обычно эти операнды используются для того, чтобы направить активный транзакт на блок CLOSE, который код ошибки помещает в параметр транзакта. Из параметра можно записать код ошибки в сохраняемую ячейку и завершить моделирование. Значение ячейки будет выведено в стандартном отчете.
Замечание 2.При построчном считывании данных из файла может оказаться, что на позиции текущей строки нет строки данных. Это происходит тогда, когда из файла считаны все текстовые строки. В данном случае активный транзакт входит в блок READ и далее направляется к блоку, метка которого указана операндом С. Код ошибки при этом не сохраняется.

Блок SEEK

Блок SEEK устанавливает позицию текущей строки потока данных. Формат блока:

SEEK   A,[B]

Операнд А - новая позиция текущей строки.

Операнд В - номер потока данных, по умолчанию равен 1.

Позиция текущей строки - это односвязный индекс, указывающий позицию следующей строки, которую необходимо считать или записать. Она не может быть меньше единицы. При попытке установить ее меньше единицы позиция текущей строки устанавливается равной единице.

31 - код ошибки: файл не был открыт.

Пример:

SEEK    (Stroka+P1),(Potok+3)

В этом примере, когда транзакт входит в блок SEEK, операнд А вычисляется, округляется и используется как номер потока данных. Операнд В также вычисляется, округляется и используется как номер потока данных.

2. Разработка модели в GPSS World

2.1. Постановка задачи

На склад, имеющий 10 пунктов выгрузки, прибывают транспорта с материальными средствами (МС). В транспорте могут быть автомобили различной грузоподъемности. Всего количество типов автомобилей, отличающихся грузоподъемностью, которое может быть в транспорте, распределено по нормальному закону с математическим ожиданием 6 автомобилей и стандартным отклонением 1 автомобиль. Количество автомобилей одного типа в транспорте также распределено по нормальному закону с математическим ожиданием 11 автомобилей и стандартным отклонением 2 автомобиля. Интервалы времени прибытия транспортов распределены по экспоненциальному закону со средним значением 9 часов. Время разгрузки автомобиля зависит от его типа и подчиняется экспоненциальному закону. Среднее время выгрузки МС приведено в табл. 8.1. После выгрузки из тех же автомобилей вновь формируется транспорт.

Построить модель функционирования пунктов выгрузки в течение трех суток с целью определения среднего времени выгрузки транспортов и коэффициентов загрузки пунктов выгрузки при рациональной организации работ на складе.

Таблица 8.1. Среднее время выгрузки МС из автомобилей различных типов
ХарактеристикиТип автомобиля
12345678910
Среднее время выгрузки, мин810127691151310

Для имитации транспорта в целом и одного автомобиля следует использовать транзакты. Пункты выгрузки в модели будут представлять ОКУ.

2.2. Программа модели

; Модель разгрузки транспортов
; Задание исходных данных
IntTp	EQU		720	; Средний интервал поступления транспортов
MOTip	EQU		6	; Матожидание типов автомобилей в транспорте
SOTip	EQU		1	; Стандартное отклонение типов автомобилей
MatA	EQU		11	; Матожидание автомобилей одного типа
SOtkA	EQU		2	; Стандартное отклонение автомобилей одного типа
KolPun	EQU		10	; Количество пунктов выгрузки
VrMod	EQU		1440	; Время моделирования
;	Определение функций и булевых переменных
SrVrA	FUNCTION	P3,D10	; Среднее время выгрузки
1,8/2,10/3,12/4,7/5,6/6,9/7,11/8,5/9,13/10,10
TipAvt	FUNCTION	RN64,C2	; Число типов автомобилей
0,1/1,7
; Сегмент имитации поступления и обработки сообщений
	GENERATE	(Exponential(33,0,IntTp)) ; Источник транспортов 
	SAVEVALUE	1,0	; Обнуление счетчика
	ASSIGN		5,AC1	; Абсолютное модельное время входа транспорта
	ASSIGN		2,(INT(Normal(77,MOTip,SOTip)-1))	;Число типов
	SPLIT		*2	; Транзактов - по числу типов автомобилей
	ASSIGN		2+,1	; Запомнить число типов автомобилей
	ASSIGN		4,(INT(Normal(55,MatA,SOtkA)-1));Автомобили
	SPLIT		*4	; Транзактов - по числу автомобилей
	ASSIGN		4+,1	; Запомнить число автомобилей одного типа
	TEST L		X1,KolPun,Met1 ; Есть свободные пункты выгрузки? 
	SAVEVALUE	1+,1
Met2	SELECT MIN	3,1,KolPun,,FR	; Выбор пункта с min загрузкой 
	TEST NE		P3,0,Met1	; Есть пункты с min загрузкой?
	QUEUE		P3	; Встать в очередь
	SEIZE		P3	; Занять пункт выгрузки
	DEPART		P3	; Покинуть очередь
	ADVANCE		(Exponential(73,0,FN$SrVrA))	; Выгрузка 
	RELEASE		P3	; Освободить АРМ
	UNLINK		PunSb,Met2,1	; Автомобиль на выгрузку
	ASSEMBLE	*4	; Собрать автомобили одного типа
	ASSEMBLE	*2	; Собрать автомобили всех типов
	ASSIGN		6,AC1	; Время выхода транспорта
	SAVEVALUE	VrVigS+,(P6-P5) ; Суммарное время выгрузки
VigTr	TERMINATE	; Выгруженные транспорта
Met1	LINK	PunSb,FIFO	; Автомобили, ожидающие выгрузки
; Сегмент задания времени моделирования 
	GENERATE	VrMod TEST	NE	N$VigTr,0,Met3
	SAVEVALUE	VrVig,(X$VrVigS/N$VigTr)	; Среднее время выгрузки
Met3	TERMINATE	1

Замысел построения модели заключается в следующем. Блок GENERATE имитирует поступление транзактов. Один транзакт - один транспорт. Затем случайным образом определяется количество типов автомобилей в транспорте и заносится в параметр 2 транзакта. Исходный (порождающий) транзакт - транспорт копируется блоком SPLIT и результат копирования - число автомобилей различных типов в прибывшем транспорте копируется вторым блоком SPLIT. Результат копирования - число транзактов, равное числу автомобилей в транспорте. Число автомобилей одного типа заносится в параметр 4 всех транзактов, имитирующих автомобили данного типа.

Далее первые десять транзактов-автомобилей (по числу пунктов выгрузки) поступают на блок SELECT, остальные - в список пользователя с именем PunSb. По мере освобождения пунктов выгрузки из списка пользователя выводятся транзакты и направляются на блок SELECT с меткой Met2. Результат работы блока SELECT - номер пункта выгрузки с минимальным коэффициентом загрузки заносится в параметр 3 вошедшего транзакта. Если результатом поиска блока SELECT является P3=0, т. е. номер нужного блока не найден, то транзакт блоком TEST снова отправляется в список пользователя. При успешном поиске транзакт занимает соответствующий пункт выгрузки.

Разгруженные автомобили первым блоком ASSEMBLE сначала собираются по каждому типу автомобилей отдельно, а вторым блоком ASSEMBLE - по всем типам.

При входе транзакта-транспорта в модель и выходе из нее в параметры 5 и 6 записывается соответствующее модельное время. Оно используется для расчета времени разгрузки транспорта. Суммарное время разгрузки всех транспортов накапливается в ячейке VrVigS.

Для работы с GPSS-моделью можно создать в какой-либо другой системе программирования, например, Delphi, интерфейс, который должен позволять осуществлять ввод исходных данных и вывод результатов моделирования. Например, в приведенной программе модели разгрузки транспортов вводить посредством интерфейса характеристики, для ввода которых используется команда EQU, а также среднее время выгрузки из одного автомобиля. При этом, естественно, необходимо разработать процедуры, формирующие в Delphi соответствующие строки программы GPSS-модели. Сама GPSS-программа также потребует модификации, для проведения которой нужно будет использовать команду INCLUDE и рассмотренные в п. 8.1 блоки OPEN, CLOSE, READ, WRITE для работы с текстовыми объектами и потоками данных.

3. Создание стартовой формы приложения - имитационной модели

Работа над новым проектом начинается с создания стартовой формы - окна, которое появляется при запуске приложения.

При запуске Delphi автоматически создаётся новый проект. Вид экрана после запуска Delphi показан на рис. 8.1. Можно использовать этот проект для создания нового приложения. По умолчанию этот проект имеет название Project1.

Стартовая форма создается путем изменения свойств формы Forml (см. рис. 8.1) .Свойства формы определяют ее внешний вид: размер, положение на экране, текст заголовка, вид рамки. Свойства перечислены на вкладке Properties (свойства) окна Object Inspector.В левой колонке находятся имена свойств, а в правой - их значения.

Сначала надо изменить значение свойства Caption ( Заголовок ) - заменить Forml на Модель разгрузки транспортов. Для этого щелкнуть мышью в поле Caption.В результате этого в правой колонке, где находится текущее значение свойства - текст Forml, появляется курсор (рис. 8.2.).

Используя клавишу <Backspase>, надо удалить Forml и ввести Модель разгрузки транспортов.

Аналогичным образом можно установить значения свойств Height и Width, которые определяют высоту и ширину формы. Этим свойствам надо присвоить значения 530 и 715. Размер формы и элементов управления, а также положение формы на экране и элементов управления на поверхности формы задаются в пикселях, точках экрана.

При выборе некоторых свойств, например Color (цвет), которое определяет цвет фона формы, после значения свойств выводится значок выпадающего списка. В результате щелчка на нем появляется список допустимых значений свойства, из которого можно выбрать нужное значение (рис. 8.3).

При разработке формы Form1 имитационной модели оставим свойство Color неизменным.

Вид экрана после запуска Delphi

Рис. 8.1.  Вид экрана после запуска Delphi

Установка значения свойства Caption посредством ввода

Рис. 8.2.  Установка значения свойства Caption посредством ввода

Установка значения свойства выбором из списка

Рис. 8.3.  Установка значения свойства выбором из списка

В поле значения свойства Font расположена командная кнопка с тремя точками, при нажатии на которую появляется стандартное диалоговое окно Windows выбора шрифта и его свойств (рис. 8.4). Для рассматриваемого примера выбран шрифт Times New Roman размером 10.

Большинство свойств определяют внешний вид формы. Свойство Name определяет имя формы, которое используется в программе для управления формой.

Ниже в табл. 8.2 приведены измененные свойства формы разрабатываемой имитационной модели. Остальные свойства формы оставлены без изменения и в таблице не приведены.

Пример раскрытого списка уточняющих свойств свойства Font

Рис. 8.4.  Пример раскрытого списка уточняющих свойств свойства Font

Таблица 8.2. Изменённые свойства формы имитационной модели
СвойствоОбозначениеЗначение
Имя формыNameForm1
ЗаголовокCaptionМодель разгрузки транспортов
ВысотаHeight530
ШиринаWidth715
ШрифтFont. NameTimes New Roman
Размер шрифтаFont. Size10

Таблица содержит значения вложенных свойств: Name и Size. Перед именем вложенного свойства указывается имя свойства, его вмещающего. В данном случае имя вмещающего свойства Font. После установки значений свойств, перечисленных в табл. 8.2, форма должна выглядеть так, как изображено на рис. 8.5.

Создайте папки D:\ModRTr\Интерфей с и в последней сохраните проект. Чтобы сохранить проект, надо выполнить команду File/ Save Project As. Откроется окно Save Unit As. Выберите в нем и раскройте созданную ранее папку Интерфейс. В поле Имя файла введите имя программного модуля, например, Rasgruska, и щелкните кнопку Сохранить.

После этого щелчка в диалоговом окне Save Unit As появится диалоговое окно Save Project As. В поле имя файла введите, например, Rasgr_transporta и щелкните кнопку Сохранить.

Вид формы имитационной модели после установки значений свойств

Рис. 8.5.  Вид формы имитационной модели после установки значений свойств

Добавление компонент в стартовую форму имитационной модели

Добавление полей редактирования

Программа имитационной модели должна получить от пользователя следующие исходные данные:

IntTp - средние значения интервалов поступления транспортов;

MOТip, SOTip - математическое ожидание MOТip и стандартное отклонение SOTip количества типов автомобилей в транспорте;

MatA, SOtkA - математическое ожидание MatA и стандартное отклонение SOtkA количества автомобилей одного типа в транспорте;

KolPun - количество пунктов выгрузки;

VrMod - время моделирования.

В Windows данные с клавиатуры вводятся в поля редактирования. Поэтому в данную форму надо добавить компоненты - семь полей редактирования.

В Delphi поля редактирования, командные кнопки, поля статического текста и прочие элементы управления, находящиеся в форме, называются компонентами (компоненты формы). В программе форма и компоненты рассматриваются как объекты. Этим можно объяснить то, что окно, в котором находятся свойства компонентов, называется Object Inspector.

Чтобы добавить к форме компонент, надо в палитре компонентов (рис. 8.6) щелкнуть на пиктограмме нужного компонента, и затем щелкнуть в той точке формы, где должен находиться правый верхний угол компонента. В результате в форме появляется компонент стандартного размера.

Пиктограммы стандартной палитры компонентов

Рис. 8.6.  Пиктограммы стандартной палитры компонентов

Добавить к форме компонент нужного размера, т. е. изменить его стандартный размер, можно так. После щелчка на палитре компонентов нужно поместить курсор мыши в ту точку формы, где должен находиться левый верхний угол компонента, нажать кнопку мыши и, удерживая ее нажатой, переместить курсор в точку, где должен быть правый нижний угол компонента, затем отпустить кнопку. В форме появится компонент нужного размера.

Добавьте в форму, перейдя на вкладку Standard (см. рис. 8.6), семь компонентов редактирования Edit. У компонента Edit пиктограмма .

Компонент формы, окруженный восемью маленькими квадратиками (см. на рис. 8.7 поле Edit1 ), называется выделенным (маркированным).Свойства маркированного компонента отображаются в окне Object Inspector.Ниже, в табл. 8.3, перечислены основные свойства компонента, называемого полем редактирования.

На рис. 8.7 представлен вид формы после добавления к ней семи полей редактирования Edit1 : Edit7.

Форма имитационной модели с семью полями редактирования

Рис. 8.7.  Форма имитационной модели с семью полями редактирования

Delphi позволяет легко изменить положение и размер компонента. Чтобы изменить положение компонента в форме, надо установить курсор мыши на изображение компонента, нажать левую кнопку мыши и, удерживая ее нажатой, переместить изображение границы компонента в нужную точку формы. Затем отпустить кнопку мыши.

Таблица 8.3. Основные свойства компонента поля редактирования
Свойство Обозначение
Имя поля. Используется в программе для доступа к содержимому (тексту) поляName
Текст, находящийся в поле ввода-редактированияText
Расстояние от левой границы поля до левой границы формыLeft
Расстояние от верхней границы поля до верхней границы формыTop
Высота поляHeight
Ширина поляWidth
Шрифт, используемый для отображения вводимого текстаFont
Признак наследования свойств шрифта родительской формыParentFont

Чтобы изменить размер компонента, надо его маркировать (щелкнуть на изображении компонента), установить указатель мыши на один из квадратиков, помечающих границу компонента, нажать левую кнопку мыши и, удерживая ее нажатой, изменить положение границы компонента. При выполнении указанного действия высвечиваются размеры компонента, например, 97?21. При достижении нужного размера отпустить кнопку мыши.

Свойства компонента можно так же изменить в окне Object Inspector.Чтобы свойства компонента появились в данном окне, надо маркировать нужный компонент, или выбрать его имя из раскрывающегося списка объектов, кнопка раскрытия которого находится в верхней части окна Object Inspector (рис. 8.8).

Окно Object Inspector с свойствами поля редактирования Edit1

Рис. 8.8.  Окно Object Inspector с свойствами поля редактирования Edit1

В табл. 8.4 приведены свойства полей редактирования, предназначенных для ввода IntTp, MOТip, SOTip, MatA, SOtkA, KolPun, VrMod.

Таблица 8.4. Свойства полей редактирования формы имитационной модели
Name Edit1 Edit2 Edit3 Edit4 Edit5 Edit6 Edit7
Text
Top306090306090120
Left16161635035035016
Height21212121212121
Width50505050505050

3.2. Добавление меток

Помимо полей редактирования окно формы должно содержать поясняющий текст: краткие информационные сообщения, которые должны раскрывать порядок работы с программой модели.

Текст, находящийся в форме, называется меткой. Добавляется метка к форме точно так же, как и поле редактирования. Пиктограмма метки (большая буква А) находится в палитре компонентов перед пиктограммой поля редактирования (см. рис. 8.6). После того как метка добавлена, можно, используя окно Object Inspector,изменить ее свойства.

К форме разрабатываемого приложения надо добавить восемь меток. Все метки будут представлять собой информационные сообщения. Добавьте метки и установите значения их свойств согласно табл. 8.5. Форма разрабатываемого приложения будет иметь вид, представленный на рис. 8.9.

Таблица 8.5. Свойства меток формы имитационной модели
Name Labell Label2 Label3 Label4 Label5 Label6 Label7 Label8
Caption
AutoSize false true true true true true true true
Top 0306090306090120
Left 14070707041041041070
Wordwrap true true true true true true True true
ParentFont false true true true true true true true

Вид формы имитационной модели после добавления меток

Рис. 8.9.  Вид формы имитационной модели после добавления меток

Как видно по рис. 8.9, из полей редактирования необходимо удалить их имена Edit1:Edit7. На этом же рисунке указано свойство Caption для каждой метки - информационное сообщение. Например, для Labell: Введите исходные данные и нажмите кнопку ВВОД. Для Labell: Средний интервал поступления транспортов.

Свойство ParentFont метки Labell имеет значение false, поэтому свойство Font этой метки не наследует значения свойства Font "родителя", в данном случае основной формы. Это дает возможность установить свойства шрифта метки иные, чем у формы. У меток Label2:Label8 значение свойства ParentFont оставлено без изменения. Значит, они наследуют свойства Font "родителя".

Если свойство AutoSize (автоматический подгон размера) имеет значение true, Delphi автоматически устанавливает размеры метки в зависимости от количества символов текста метки, используемого шрифта и его размера. Если надо, чтобы метка представляла собой текст из нескольких строк, то свойству AutoSize надо присвоить значение false и вручную установить значения свойств, определяющих ее размер.

У меток Label2:Label8 свойству AutoSize установлено значение true, а у метки Label1 - false.

3.3. Добавление компонент для ввода и вывода данных, представленных в виде таблиц

Среднее время разгрузки одного автомобиля различных типов представлено табл. 8.1. Компонент StringGrid ( Строковая таблица ) используется для отображения информации в виде таблицы. Таблица представляет собой набор ячеек, расположенных в строках и столбцах. Ее содержимое задается двумерным массивом.

Значок компонента StringGrid находится на дополнительной ( Additional ) странице палитры компонентов. В разрабатываемую форму имитационной модели необходимо добавить два компонента. Один компонент для ввода табл. 8.1. В данной модели результаты моделирования целесообразно вывести таблицей. Поэтому нужен второй компонент StringGrid. Добавьте два компонента. Добавляются они также, как и другие компоненты.

Добавленные компоненты StringGrid имеют стандартные свойства. Delphi предоставляет разработчику возможность изменить эти свойства после добавления компонентов в форму.

В табл. 8.6 перечислены основные свойства компонента StringGrid.

Таблица 8.6. Основные свойства компонента StringGrid
СвойствоОписание
NameИмя компонента. Используется в программе для доступа к свойствам компонента
ColCountКоличество колонок таблицы
RowCountКоличество строк таблицы
CellsСоответствующий таблице двумерный строковый массив. Если строки и столбцы нумеровать с нуля, то ячейке Cells соответствует Cells (i,j)
FixedColsКоличество зафиксированных слева столбцов таблицы. Они выделяются цветом и при горизонтальной прокрутке таблицы остаются на месте
FixedRowsКоличество зафиксированных сверху строк таблицы. Они выделяются цветом и при вертикальной прокрутке таблицы остаются на месте
OptionsСвойство используется для задания других атрибутов таблицы (табл. 8.7)
DefaultColWidthШирина столбцов таблицы
DefaultRowHeightВысота строк таблицы
GridLineWidthШирина линий, ограничивающих ячейки таблицы
LeftРасстояние от левой границы поля таблицы до левой границы формы
TopРасстояние от верхней границы поля таблицы до верхней границы формы
HeightВысота поля таблицы
WidthШирина поля таблицы
FontШрифт, используемый для отображения содержимого ячеек таблицы
ParentFontПризнак наследования характеристик шрифта формы

Из всех свойств следует обратить внимание на свойство Options. Свойство Options используется для задания многих атрибутов таблицы (компонента StringGrid ), которые описаны в табл. 8.7. На вкладке, показанной на рис. 8.10, перед свойством Options стоит знак " + ". При двойном нажатии на него появляется вкладка с вложенными свойствами свойства Options (рис. 8.10).

Таблица 8.7. Атрибуты таблицы, задаваемые свойством Options
АтрибутОписание (для значения True )
goFixedHorzLineГоризонтальные линии фиксированы
goFixedVertLineВертикальные линии фиксированы
goHorzLineГоризонтальные разделительные линии отображаются
goVertLineВертикальные разделительные линии отображаются
goRangeSelectМожно выбирать несколько ячеек
goDrawFocusSelectedТекущая ячейка помечается цветом
goRowSizingВозможно изменение размеров строк
goColSizingВозможно изменение размеров столбцов
goRowMovingВозможно перемещение строк
goColMovingВозможно перемещение столбцов
goEditingВозможно редактирование содержимого ячеек
goTabsВозможно перемещение по ячейкам клавишами Tab и Shift-Tab
goThumbTrackingСодержимое таблицы скроллируется с помощью полос прокрутки

Свойства, перечисленные в табл. 8.6 и табл. 8.7, после выделения (маркирования) соответствующей таблицы устанавливаются либо заданием какого - то числового значения, либо выбором True или False (рис. 8.10).

Для ввода данных табл. 8.1 необходимо изменить некоторые из свойств StringGrid. Например, для того, чтобы была возможность редактировать содержимое ячеек таблиц, нужно установить свойство goEditing True, а для перемещения курсора с помощью клавиш Tab и стрелок - свойство goTabs также установить True.

В табл. 8.8 приведены значения свойств обеих компонентов StringGrid, используемых моделью для ввода и вывода данных. Установите эти значения. Форма должна иметь вид, показанный на рис. 8.11. Введите также метки Label9 и Label10 (см. рис. 8.11).

Вкладка свойства Options

Рис. 8.10.  Вкладка свойства Options

Таблица 8.8. Значения свойств компонента StringGrid1
СвойствоКомпоненты
12
NameTabl1Tabl2
ColCount1111
RowCount25
FixedCols11
FixedRows11
Options.goEditingTrueTrue
Options.goTabsTrueTrue
DefaultColWidth70125
DefaultRowHeight2424
GridLineWidth11
goRowSizingTrueTrue

Вид формы после добавления компонентов StringGrid

Рис. 8.11.  Вид формы после добавления компонентов StringGrid

Первая строка и первый столбец таблиц зафиксированы (см. рис. 8.11). Они используются в качестве заголовков таблиц. В рассматриваемом примере в первой строке первой таблицы это тип автомобиля (номера 1 : 10), во второй таблице - пункты выгрузки (также номера 1 : 10). Следует отметить, что можно было бы ввести в эти ячейки и наименования вместо порядковых номеров. Как это делается, покажем на примере ввода поясняющего текста в строки таблиц. Во вторую строку первой таблицы - Cells(0, 1) - введем: Время, мин. Во вторую таблицу: Cells(0, 1) - Коэф. загр.; Cells(0, 2) - Ср. время ; Cells(0, 3) - Макс. очер.Во время создания формы имитационной модели установить значения элементов Cells таблицы нельзя, так как элементы таблицы доступны только во время работы программы. Поэтому значения элементов Cells таблицы, соответствующие первой строке и первому столбцу обеих таблиц устанавливают процедуры FormActivate1 и FormActivate2 (текст их приведен ниже) во время активизации формы. В какой процедуре обработки события производится вызов указанных процедур, укажем позже.

procedure TForm1.FormActivate1(Sender: TObject); 
var  n1:integer; 
begin
  for n1:=1 to Tabl1.ColCount do
    Tabl1.Cells[n1,0]:=IntToStr(n1);
  Tabl1.Cells[0,1]:='Время, мин'; 
end;
procedure TForm1.FormActivate2(Sender: TObject); 
var  n1:integer; 
begin
  for n1:=1 to Tabl2.ColCount do
    Tabl2.Cells[n1,0]:=IntToStr(n1);
  Tabl2.Cells[0,1]:='Коэф.исп.пункт. разгр.';
  Tabl2.Cells[0,2]:='Ср.вр.разгр.авт.,мин';
  Tabl2.Cells[0,3]:='Макс.очер.на пун.разгр.';
  Tabl2.Cells[0,4]:='Ср.вр.разгр.тран.,час'; 
end;

3.4. Добавление командных кнопок

Для управления работой имитационной модели к форме надо добавить шесть командных кнопок (рис. 8.12).

В модели предусмотрен пример. При нажатии кнопки ПРИМЕР автоматически вводятся исходные данные, курсор устанавливается на кнопке МОДЕЛИРОВАНИЕ. Нажатием этой кнопки переходят к процессу моделирования.

Стартовая форма имитационной модели

Рис. 8.12.  Стартовая форма имитационной модели

По окончании моделирования для вывода результатов нужно нажать кнопку ВЫВОД. Результаты моделирования появятся в нижней таблице.

Если производилось моделирование примера, а потом нужно выполнить моделирование с другими исходными данными, нажатием кнопки СБРОС можно удалить данные примера и ввести новые. Использование кнопки СБРОС удобно в том случае, если очередной ввод исходных данных требует большого количества изменений. После этого нажать кнопку ВВОД и нажатием кнопки МОДЕЛИРОВАНИЕ перейти к процессу моделирования, по завершении которого нажать кнопку ВЫВОД.

Нажатие на кнопку ВЫХОД ИЗ МОДЕЛИ приводит к завершению работы программы имитационной модели. Закрывается открытая форма приложения.

Кнопки добавляются в форму точно так же, как и другие компоненты. Пиктограмма командной кнопки _2U,находится на палитре стандартных компонентов (см. рис. 8.6). После добавления кнопок с помощью диалогового окна Object Inspector надо установить требуемые значения их свойств (табл. 8.9).

Таблица 8.9. Свойства кнопок стартовой формы имитационной модели
Name Button1 Button2 Button3 Button4 Button5 Button6
CaptionВводСбросМоделированиеВыход из моделиПримерВывод
Top470470470470470470
Left1769625652816424
Height252525252525
Width75751611697575

После запуска программы курсор сразу автоматически устанавливается в поле редактирования Edit1 для ввода переменной Средний интервал поступления транспортов. Поэтому в форме указано, что надо сначала ввести данные, потом нажать кнопку ВВОД и только потом кнопку МОДЕЛИРОВАНИЕ.

События и процедуры обработки событий

События

Вид созданной формы подсказывает, как работает приложение. Очевидно, что пользователь должен ввести значения в поля редактирования, нажать ВВОД и потом щелкнуть кнопку МОДЕЛИРОВАНИЕ. Щелчок на изображении командной кнопки - это пример того, что в Windows называется событием.

Событие - это то, что происходит во время работы приложения. В Delphi у каждого события есть имя, например, щелчок кнопкой мыши это событие OnClick, двойной щелчок - событие onDblClick.

В табл. 8.10 приведены некоторые события Windows.

Реакцией на событие должно быть какое-либо действие. Например, реакцией на событие OnClick, произошедшее на кнопке МОДЕЛИРОВАНИЕ,должен быть переход к запуску имитационной модели. В Delphi реакция на событие реализуется как процедура обработки события.Таким образом, задача программиста состоит в написании необходимых процедур обработки событий.

Поскольку в форму добавлены пятнадцать компонентов, то необходимо разработать для них процедуры обработки событий.

Рассмотрим методику создания процедур обработки событий.

Таблица 8.10. Перечень некоторых событий Windows
Событие Содержание
OnClickПроисходит при щелчке кнопкой мыши
OnDblClickПроисходит при двойном щелчке кнопкой мыши
OnEnterПроисходит перед тем, как элемент управления действительно получает фокус
OnErrorПроисходит, когда элемент контроля обнаруживает ошибку и не может вернуть информацию об ошибке вызывающей программе
OnExitПроисходит непосредственно перед тем, как элемент управления теряет фокус
OnKeyDownПроисходит при нажатии на клавишу. События OnKeyDown и OnKeyPress - это чередующиеся, повторяющиеся события, которые происходят до тех пор, пока не будет отпущена удерживаемая клавиша (в этот момент происходит событие OnKeyUp )
OnKeyPressПроисходит, когда пользователь нажимает клавишу, которая генерирует печатаемый символ. Может происходить также при нажатии клавиши печатаемого символа с <Ctrl>. He происходит при нажатии клавиш <Tab>, <Enter>, клавиш перемещения курсора
OnKeyUpПроисходит при отпускании нажатой клавиши
OnMouseDownПроисходит при нажатии кнопки мыши
OnMouseMoveПроисходит при перемещении мыши
OnMouseUpПроисходит при отпускании кнопки мыши

4.2. Разработка процедур обработки событий для кнопок

Сначала следует на форме приложения щелчком мыши маркировать (выделить) компонент, для которого создается процедура обработки события. В нашем случае целесообразно начать разработку с процедуры кнопки ВВОД. Выделите ее.

Затем нужно выбрать вкладку Events (события) окна Object Inspector.В результате этих действий в окне Object Inspector появится вкладка со списком событий, которые способен воспринимать маркированный компонент, в данном случае - командная кнопка (рис. 8.13).

В левой колонке вкладки перечислены имена событий, на которые может реагировать маркированный объект. Если для события определена процедура обработки события, то в правой колонке, рядом с именем события выводится ее имя.

Чтобы создать процедуру обработки события, надо сделать двойной щелчок в поле имени процедуры обработки события. В результате открывается окно редактора кода (в Delphi кодом называется текст программы) с макетом процедуры обработки события (рис. 8.14).

Вкладка Events командной кнопки ВВОД (Button1)

Рис. 8.13.  Вкладка Events командной кнопки ВВОД (Button1)

Окно редактора кода с макетом процедуры обработки события, происходящего на кнопке Button1 (ВВОД)

Рис. 8.14.  Окно редактора кода с макетом процедуры обработки события, происходящего на кнопке Button1 (ВВОД)

Delphi автоматически присваивает процедуре обработки события имя. Имя процедуры обработки события состоит из двух частей. Первая часть идентифицирует форму, которой принадлежит объект, для которого создается процедура обработки события. Вторая часть имени идентифицирует сам объект и событие. В нашем случае имя формы - Form1, Button1 - имя командной кнопки ВВОДимя события - Click.

В окне редактора кода (см. рис. 8.14) между begin и end можно печатать инструкции Object Pascal, реализующие процедуру обработки события. Введите следующий программный код:

procedure TForm1.Button1Click(Sender: TObject); 
begin
  ProvVvod1; 
  begin
    MOTip:=StrToFloat(Edit2.text);
    SOTip:=StrToFloat(Edit3.text);
    MatA:=StrToFloat(Edit4.text);
    SOtkA:=StrToFloat(Edit5.text); 
  end;
  if (SOTip*5)>MOTip then begin
    MessageDlg('Стандартное отклонение SOTip'+#13
      +'должно быть более чем в 5 раз меньше'+#13
      +'математического ожидания MOTip',
      mtWarning,[mbOk],0);
    Edit3.SetFocus; 
  end
  else if (SOtkA*)>MatA then begin
    MessageDlg('Стандартное отклонение SOtkA'+#13
      +'должно быть более чем в 5 раз меньше'+#13
      +'математического ожидания MatA',
      mtWarning,[mbOk],0);
    Edit5.SetFocus; 
  end;
  ProvVvod2; Tabl1.SetFocus;
end;

В тексте процедуры выделено то, что сформировано Delphi. Остальное вводится разработчиком.

Обработка события при щелчке кнопки ВВОД происходит так. Вначале процедурой ProvVvod1 проверяется, все ли данные введены в поля редактирования. Если все данные введены, производится их перевод в вещественный тип.

В модели используются случайные числа, распределенные по нормальному закону. Поэтому далее производится проверка с целью предотвращения случаев неправильного задания стандартного отклонения. Оно должно быть в пять раз и более меньше математического ожидания.

Далее процедурой ProvVvod2 проверяется полнота ввода данных в первую таблицу StrinGrid. Создайте процедуры ProvVvod1, ProvVvod2 в разделе implementation программного модуля (.pas ).

procedure TForm1.ProvVvod1; 
begin 
  begin 
    if (Edit1.text='') or (Edit2.text='') 
    or (Edit3.text='') or (Edit4.text='') 
    or (Edit5.text='') or (Edit6.text='') 
    or (Edit7.text='') then 
      MessageDlg('Необходимо задать все'+#13 
        +'исходные данные'+#13 
        + 'в полях редактирования', 
        mtWarning,[mbOk],0); 
  end; 
  begin 
    if Edit1.text='' then Edit1.SetFocus; 
    if Edit2.text='' then Edit2.SetFocus; 
    if Edit3.text='' then Edit3.SetFocus; 
    if Edit4.text='' then Edit4.SetFocus; 
    if Edit5.text='' then Edit5.SetFocus; 
    if Edit6.text='' then Edit6.SetFocus; 
    if Edit7.text='' then Edit7.SetFocus; 
  end; 
end; 

procedure TForm1.ProvVvod2; 
begin 
  begin 
    if (Tabl1.Cells[1,1]='') or (Tabl1.Cells[2,1]='') or (Tabl1.Cells[3,1]='') 
    or (Tabl1.Cells[4,1]='') or (Tabl1.Cells[5,1]='') or (Tabl1.Cells[6,1]='') 
    or (Tabl1.Cells[7,1]='') or (Tabl1.Cells[8,1]='') or (Tabl1.Cells[9,1]='') 
    or (Tabl1.Cells[10,1]='') 
    then 
      MessageDlg('Необходимо задать все'+#13 
        +'исходные данные в таблице', 
        mtWarning,[mbOk],0); 
  end; 
  Tabl1.SetFocus; 
end;

Объявите в интерфейсной части эти процедуры.

type TForm1 = class(TForm) 
    Edit1: TEdit; 
    : 
    procedure ProvVvod1; 
    procedure ProvVvod2; 
  private

При нажатии кнопки СБРОС все поля редактирования и ячейки Tabl1 очищаются. Создайте обработчик этого события, программный код которого приведен ниже.

procedure TForm1.Button2Click(Sender: TObject);
var n1,n2:integer;
begin
  Edit1.text:='';
  Edit2.text:='';
  Edit3.text:='';
  Edit4.text:='';
  Edit5.text:='';
  Edit6.text:='';
  Edit7.text:='';
  for n1:=1 to 10 do
    Tabl1.Cells[n1,1]:='';
  for n2:=1 to 3 do
    for n1:=1 to 10 do
      Tabl2.Cells[n1,n2]:=''; Edit1.SetFocus;
end;

Нажатием кнопки МОДЕЛИРОВАНИЕ производится переход к процессу моделирования. Создайте обработчик этого события согласно следующему программному коду.

procedure TForm1.Button3Click(Sender: TObject); begin
VivProgr;
WinExec('d:\ModRTr\GPSSW.exe',SW_RESTORE);
Button6.SetFocus;
end;

При обработке этого события вначале выполняется процедура VivProgr, состоящая в свою очередь из четырех процедур VivProgr1, VivProgr2, VivProgr3 и VivProgr4. Они формирует следующие тестовые файлы с фрагментами программы GPSS:

Создайте в разделе implementation программного модуля ( .pas ) программные коды шести процедур.

procedure TForm1.VivProgr; 
  begin 
    VivProgr1; 
    VivProgr2; 
    VivProgr3; 
    VivProgr4; 
    VivProgr5; 
  end; 

procedure TForm1.VivProgr1; 
var 
  f:TextFile; 
begin 
  AssignFile(f,'d:\ModRTr\Progr1.txt'); 
  Rewrite(f); 
  writeln(f,'IntTp EQU ',Edit1.text); 
  writeln(f,'MOTip EQU ',Edit2.text); 
  writeln(f,'SOTip EQU ',Edit3.text); 
  writeln(f,'MatA EQU ',Edit4.text); 
  writeln(f,'SOtkA EQU ',Edit5.text); 
  writeln(f,'KolPun EQU ',Edit6.text); 
  writeln(f,'VrMod EQU ',Edit7.text); 
  writeln(f,'SrVrA FUNCTION P3,D',(Tabl1.ColCount-1)); 
  writeln(f,'1,',Tabl1.Cells[1,1],'/2,',Tabl1.Cells[2,1],'/3,',Tabl1.Cells[3,1], 
    '/4,',Tabl1.Cells[4,1],'/5,',Tabl1.Cells[5,1],'/6,',Tabl1.Cells[6,1], 
    '/7,',Tabl1.Cells[7,1],'/8,',Tabl1.Cells[8,1],'/9,',Tabl1.Cells[9,1], 
    '/10,',Tabl1.Cells[10,1]); 
  CloseFile(f); 
end; 

procedure TForm1.VivProgr2; 
var 
  f:TextFile; 
begin 
  AssignFile(f,'d:\ModRTr\Progr2.txt'); 
  Rewrite(f); 
  writeln(f,'GENERATE ', StrToFloat(Edit7.text);
  CloseFile(f); 
end; 

procedure TForm1.VivProgr3; 
var 
  f:TextFile; 
  n1:integer; 
begin 
  AssignFile(f,'d:\ModRTr\Progr3.txt'); 
  Rewrite(f); 
  writeln(f,'OPEN ("DanTabl21.txt"),1,Kon1'); 
  for n1:=1 to StrToInt(Edit6.text) do 
    writeln(f,'WRITE FR',n1,',,,OFF'); 
  writeln(f,'Kon1 CLOSE Err1,1'); 
  CloseFile(f); 
end; 

procedure TForm1.VivProgr4; 
var 
  f:TextFile; 
  n1:integer; 
begin 
  AssignFile(f,'d:\ModRTr\Progr4.txt'); 
  Rewrite(f); 
  writeln(f,'OPEN ("DanTabl22.txt"),1,Kon2'); 
  for n1:=1 to StrToInt(Edit6.text) do 
    writeln(f,'WRITE FT',n1,',,,OFF'); 
  writeln(f,'Kon2 CLOSE Err1,1'); 
  CloseFile(f); 
end; 

procedure TForm1.VivProgr5; 
var 
  f:TextFile; 
  n1:integer; 
begin 
  AssignFile(f,'d:\ModRTr\Progr5.txt'); 
  Rewrite(f); 
  writeln(f,'OPEN ("DanTabl23.txt"),1,Kon3'); 
  for n1:=1 to StrToInt(Edit6.text) do 
    writeln(f,'WRITE QM',n1,',,,OFF'); 
  writeln(f,'WRITE X$VrVig',',,,OFF') 
  writeln(f,'Kon3 CLOSE Err1,1'); 
  CloseFile(f); 
end;

Объявите в интерфейсной части программного модуля эти шесть процедур.

type TForm1 = class(TForm) 
    Edit1: TEdit; 
    : 
    procedure VivProgr; 
    procedure VivProgr1; 
    procedure VivProgr2; 
    procedure VivProgr3; 
    procedure VivProgr4; 
    procedure VivProgr5; 
private

После выполнения процедуры VivProgr командой

WinExec('d:\ModRTr\GPSSW.exe',SW_RESTORE);

запускается GPSS.exe. И далее пользователем - приложение Модель разгрузки транспортов. Курсор устанавливается на кнопке ВЫВОД.

Для обработки события - щелчка кнопки ВЫВОД - используйте следующий программный код:

procedure TForm1.Button6Click(Sender: TObject);
  begin
    FormActivate2(Sender);
    VivRes1;
    VivRes2;
    VivRes3;
  end;

Обработка события начинается с выполнения процедуры FormActivate2(Sender). В результате этого вводятся заголовки в первую строку и в первый столбец второй таблицы. Затем последовательно выполняются процедуры VivRes1, VivRes2 и VivRes3, которые считывают результаты моделирования из файлов DanTabl211.txt, DanTabl212.txt и DanTabl213.txt соответственно и выводят их построчно во вторую таблицу.

Создайте обработчик события - щелчка кнопки ВЫВОД и в разделе implementation программного модуля ( .pas ) создайте процедуры FormActivate2(Sender) (см. п. 8.3.3), VivRes1, VivRes2 и VivRes3.

procedure TForm1.VivRes1; 
var
  f:TextFile;
  n1:integer;
  a:real; 
  begin
    AssignFile(f, 'd:\ModRTr\DanTabl21.txt');
    Reset(f);
    for n1:=1 to (Tabl2.ColCount-1) do begin
      read(f,a);
      a:=Trunc(a);
      a:=a/1000;
      Tabl2.Cells[n1,1]:=FloatToStr(a); 
    end; 
  end;

procedure TForm1.VivRes2; 
var
  f:TextFile; 
  n1:integer; 
  a:real; 
  begin 
    AssignFile(f, 'd:\ModRTr\DanTabl22.txt'); 
    Reset(f);
    for n1:=1 to (Tabl2.ColCount-1) do begin 
      read(f,a); 
      a:=a*1000; 
      a:=Trunc(a); 
      a:=a/1000;
      Tabl2.Cells[n1,2]:=FloatToStr(a); 
    end; 
  end;

procedure TForm1.VivRes3; 
var
  f:TextFile; 
  n1:integer; 
  a:real; 
  begin 
    AssignFile(f, 'd:\ModRTr\DanTabl23.txt'); 
    Reset(f); 
    for n1:=1 to (Tabl2.ColCount-1) do
    begin
      read(f,a);
      Tabl2.Cells[n1,3]:=FloatToStr(a); 
    end; 
  end;

Объявите в интерфейсной части только что созданные четыре процедуры.

type TForm1 = class(TForm) 
    Edit1: TEdit; 
    :
    procedure FormActivate2(Sender: TObject); 
    procedure VivRes1; 
    procedure VivRes2; 
    procedure VivRes3;
  private

Завершение работы с программой модели происходит при нажатии кнопки ВЫХОД ИЗ МОДЕЛИ. Результатом является закрытие формы приложения. Создайте обработчик этого события.

procedure TForm1.Button4Click(Sender: TObject); 
  begin
    Form1.close;
  end;

Разработка процедур обработки событий для полей редактирования

В соответствии с видом формы имитационной модели сформулируем следующие требования к программе:

Чтобы программа удовлетворяла вышеприведенным требованиям, надо для каждого поля редактирования написать процедуру обработки события OnKeyPress, которая в зависимости от того, какую клавишу нажал пользователь, будет выполнять нужное действие.

Заготовка процедуры OnKeyPress для Edit1, генерируемая Delphi, выглядит следующим образом:

Procedure Tform1.Edit1KeyPress(Sender:Tobject; var Key:Char); 
  begin
  end;

Заголовок процедуры Edit1KeyPress показывает, что процедура в качестве параметра получает символьную переменную Key. Эта переменная содержит символ, соответствующий нажатой клавише. Следует обратить внимание на то, что параметр принимается по ссылке (перед именем переменной стоит слово var ), поэтому процедура может изменить значение переменной. Символ, соответствующий нажатой клавише, появляется в поле редактирования после выполнения процедуры обработки события OnKeyPress, поэтому процедура обработки может заменить введенный символ или присвоением переменной Key значения Chr(0) запретить его появление в поле редактирования.

Ниже приведен программный код процедуры обработки события OnKeyPress в поле редактирования.

рrocedure TForm1.Edit1KeyPress(Sender:Tobject; var Key:Char); 
  begin
    case Key of
      '0'..'9',Chr(8):;
      '-':Key:=Chr(0);
      ',':if pos(',',Edit1.text)<> then Key:=Chr(0);
      Chr(13):Edit2.SetFocus
      '.': begin
          MessageDlg('Для отделения дробной части' +'числа'+#13
+'от целой используйте запятую', mtInformation, [mbOk],0); 
          Key:=Chr(0); 
        end;
      else Key:=Chr(0); 
    end;
  end;

Процедура TForm1.Edit1KeyPress проверяет, какая клавиша нажата при вводе исходных данных в поле редактирования Edit1. Если нажата клавиша BackSprace, то процедура завершает свою работу и символ появляется в поле редактирования или стирается последний введённый символ. Если нажата запятая, то процедура проверяет, есть ли уже запятая в поле редактирования. Если есть, то ввод второй запятой блокируется. Если нажата клавиша "-", то ввод её тоже блокируется. Если нажата клавиша Enter, то применением метода SetFocus к полю редактирования Edit2 курсор перемещается в это поле.

Процедуры обработки события OnKeyPress полей редактирования отличаются только способом обработки нажатия клавиши Enter (в поле Edit1 Edit2.SetFocus, в поле Edit2 Edit3.SetFocus и т.д., а в поле Edit7

then 
  begin
    FormActivate1(Sender);
    Tabl1.SetFocus; 
  end;

В остальном эти процедуры идентичны. Поэтому вместо написания процедур обработки события OnKeyPress для каждого поля редактирования можно написать одну общую процедуру, которая при нажатии Enter будет выбирать нужное действие в зависимости от того, в каком поле произошло событие. Получить информацию об источнике события можно проверкой значения параметра Sender.

Создайте в разделе implementation программный код процедур EditKeyPress и FormActivate1 (см. п. 8.3.3).

procedure TForm1.EditKeyPress(Sender: TObject; var Key: Char);
var
  nak:string[20];
  begin
  if Sender=Edit1 then 
    nak:=Edit1.text 
  else if Sender=Edit2 then 
    nak:=Edit2.text 
  else if Sender=Edit3 then 
    nak:=Edit3.text 
  else if Sender=Edit4 then 
    nak:=Edit4.text 
  else if Sender=Edit5 then 
    nak:=Edit5.text 
  else if Sender=Edit6 then 
    nak:=Edit6.text 
  else nak:=Edit7.text; 
  case Key of 
    '0'..'9',Chr(8):; 
    '-':Key:=Chr(0); 
    ',':if pos(',',nak) <>0 then Key:=Chr(0); 
    Chr(13):if Sender=Edit1 
        then Edit2.SetFocus 
        else if Sender=Edit2 
        then Edit3.SetFocus 
        else if Sender=Edit3 
        then Edit4.SetFocus 
        else if Sender=Edit4 
        then Edit5.SetFocus 
        else if Sender=Edit5 
        then Edit6.SetFocus 
        else if Sender=Edit6 
        then Edit7.SetFocus 
        else if Sender=Edit7 
        then 
          begin 
FormActivate1(Sender); 
Tabl1.SetFocus; 
          end; 
    '.':begin 
        MessageDlg('Для отделения дробной' 
          +'части от целой'+#13 
          +'используйте запятую', 
          mtInformation,[mbOk],0); 
        Key:=Chr(0); 
      end; 
    else Key:=Chr(0)
  end; 
end;

Объявите в интерфейсной части:

type TForm1 = class(TForm) 
  Edit1: TEdit;
  :
  procedure FormActivate1(Sender: TObject);
private

Теперь выделите компонент Edit2 и на вкладке Events раскройте список. Из списка для onKeyPress щелчком установите EditKeyPress. Проделайте тоже для компонентов Edit3 : Edit7.

4.4. Модификация программы имитационной модели

Интерфейс приложения разработан. Согласно интерфейсу внесем изменения в исходную GPSS-модель (см. п. 8.2.2). Заменим строки программы с командой EQU и строки

SrVrA	FUNCTION	P3,D10	; Среднее время выгрузки
1,26/2,20/3,30/4,25/5,15/6,18/7,28/8,32/9,23/10,30

командой

INCLUDE          "Progr1.txt"        ; Подключение файла

Модифицируем также сегмент задания времени моделирования.

;Сегмент задания времени моделирования
	INCLUDE		"Progr2.txt" ; Подключение файла
	TEST E		TG1,1,Met3 ; При TG1=1 - расчет результатов моделирования
;	TEST NE		N$VigTr,0,Met3
	SAVEVALUE	VrVig,((X$VrVigS/N$VigTr)/60) ; Среднее время выгрузки, час
	INCLUDE		"Progr3.txt" ; Подключение файла
	INCLUDE		"Progr4.txt" ; Подключение файла
	INCLUDE		"Progr5.txt" ; Подключение файла
Met3	TERMINATE     1

Разработка имитационной модели в виде приложения с интерфейсом завершена.

Отладьте приложение и перейдите к работе с ним.

5. Работа с приложением

Поместите в папку D:\ModRTr файл GPSS.exe и GPSS-модель ModRasgTr.gps. Нахождение файла Rasg_transporta.exe в этой же папке необязательно. Запустите Rasg_transporta.exe.

Нажмите кнопку ПРИМЕР. Автоматически будут введены данные, показанные на рис. 8.15.

Убедитесь, правильно ли выявляются ошибки, нахождение которых предусмотрено программным путем.

Проверьте, выполняется ли условие ввода характеристик нормального закона распределения случайных чисел. Измените в сторону увеличения любое из стандартных отклонений: введите в соответствующее поле редактирования, например, 4.2. Появится сообщение об ошибке (рис. 8.16): для отделения целой части от дробной нужно использовать запятую.

Нажмите OK. Повторите ввод числа с отделением его целой части от дробной части запятой в это же поле редактирования. Нажмите кнопку ВВОД. Появится предупреждение о другой ошибке (рис. 8.17). Нажмите OK и исправьте ошибку.

Форма приложения с данными примера

Рис. 8.15.  Форма приложения с данными примера

Сообщение об ошибке при вводе числа

Рис. 8.16.  Сообщение об ошибке при вводе числа

Сообщение об ошибке при вводе стандартного отклонения

Рис. 8.17.  Сообщение об ошибке при вводе стандартного отклонения

Далее удалите, например, количество пунктов разгрузки из поля редактирования и щелкните ВВОД. Появится предупреждение о том, что необходимо задать все исходные данные в полях редактирования (рис. 8.18). Щелкните OK и исправьте ошибку.

Теперь удалите, например, среднее время разгрузки автомобиля второго типа из первой таблицы и щелкните ВВОД. Появится предупреждение о том, что необходимо задать все исходные данные в полях редактирования (рис. 8.19). Щелкните OK, исправьте ошибку и нажмите ВВОД.

Предупреждение о необходимости ввода всех данных в поля редактирования

Рис. 8.18.  Предупреждение о необходимости ввода всех данных в поля редактирования

Предупреждение о необходимости ввода всех данных в первую таблицу

Рис. 8.19.  Предупреждение о необходимости ввода всех данных в первую таблицу

Теперь ошибок ввода исходных данных нет. Щелкните кнопку МОДЕЛИРОВАНИЕ.

Выполните необходимые действия с GPSS-моделью. Закройте GPSS-exe и нажмите активную кнопку ВЫВОД. Во второй таблице появятся результаты моделирования (рис. 8.20):

Форма приложения с данными и результатами моделирования

Рис. 8.20.  Форма приложения с данными и результатами моделирования

Вопросы для самоконтроля

  1. Какова цель предназначения текстовых объектов и потоков данных?
  2. Какой командой подключаются текстовые объекты к объе-ту GPSS World "Модель"? Формат этой команды.
  3. Назначение и формат блока OPEN.
  4. Назначение и формат блока CLOSE.
  5. Назначение и формат блока READ.
  6. Назначение и формат блока WRITE.
  7. Назовите режимы работы блока WRITE и дайте им характеристику.
  8. Назначение и формат блока SEEK.
  9. Назначение и формат блока SELECT.

Ссылки

Боев В.Д., Сыпченко Р.П. Компьютерное моделирование

оглавление   ДМ   экономическая информатика   визуальные среды - 4GL   Теория и практика обработки информации

Знаете ли Вы, что априорное решение в стохастических двухэтапных моделях - это вектор оптимальных значений переменных, характеризующих плановые задания, требующие выполнения до поступления информации о случайных событиях, влияющих на ожидаемые хозяйственные результаты.

НОВОСТИ ФОРУМА

Форум Рыцари теории эфира


Рыцари теории эфира
 10.11.2021 - 12:37: ПЕРСОНАЛИИ - Personalias -> WHO IS WHO - КТО ЕСТЬ КТО - Карим_Хайдаров.
10.11.2021 - 12:36: СОВЕСТЬ - Conscience -> РАСЧЕЛОВЕЧИВАНИЕ ЧЕЛОВЕКА. КОМУ ЭТО НАДО? - Карим_Хайдаров.
10.11.2021 - 12:36: ВОСПИТАНИЕ, ПРОСВЕЩЕНИЕ, ОБРАЗОВАНИЕ - Upbringing, Inlightening, Education -> Просвещение от д.м.н. Александра Алексеевича Редько - Карим_Хайдаров.
10.11.2021 - 12:35: ЭКОЛОГИЯ - Ecology -> Биологическая безопасность населения - Карим_Хайдаров.
10.11.2021 - 12:34: ВОЙНА, ПОЛИТИКА И НАУКА - War, Politics and Science -> Проблема государственного терроризма - Карим_Хайдаров.
10.11.2021 - 12:34: ВОЙНА, ПОЛИТИКА И НАУКА - War, Politics and Science -> ПРАВОСУДИЯ.НЕТ - Карим_Хайдаров.
10.11.2021 - 12:34: ВОСПИТАНИЕ, ПРОСВЕЩЕНИЕ, ОБРАЗОВАНИЕ - Upbringing, Inlightening, Education -> Просвещение от Вадима Глогера, США - Карим_Хайдаров.
10.11.2021 - 09:18: НОВЫЕ ТЕХНОЛОГИИ - New Technologies -> Волновая генетика Петра Гаряева, 5G-контроль и управление - Карим_Хайдаров.
10.11.2021 - 09:18: ЭКОЛОГИЯ - Ecology -> ЭКОЛОГИЯ ДЛЯ ВСЕХ - Карим_Хайдаров.
10.11.2021 - 09:16: ЭКОЛОГИЯ - Ecology -> ПРОБЛЕМЫ МЕДИЦИНЫ - Карим_Хайдаров.
10.11.2021 - 09:15: ВОСПИТАНИЕ, ПРОСВЕЩЕНИЕ, ОБРАЗОВАНИЕ - Upbringing, Inlightening, Education -> Просвещение от Екатерины Коваленко - Карим_Хайдаров.
10.11.2021 - 09:13: ВОСПИТАНИЕ, ПРОСВЕЩЕНИЕ, ОБРАЗОВАНИЕ - Upbringing, Inlightening, Education -> Просвещение от Вильгельма Варкентина - Карим_Хайдаров.
Bourabai Research - Технологии XXI века Bourabai Research Institution