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

2



Министерство образования и науки Республики Казахстан

Карагандинский государственный технический университет

Кафедра





















ПОЯСНИТЕЛЬНАЯ

ЗАПИСКА

к курсовому проекту

по дисциплине "Прикладная теория систем"

Тема: "Разработка имитационной модели системы

массового обслуживания"







Руководители

Студент

(группа)







Караганда 2009


Содержание



Введение

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

Описание программного модуля

Руководство пользователя

Результаты тестирования программы

Заключение

Список использованных источников

Приложение

Листинг программы




Введение



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

В данном курсовом проекте рассматривается система массового обслуживания, применимая для магазинов.


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



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

В данном курсовом проекте рассматривается система массового обслуживания - магазин.

Описание задачи: время работы с 8 до 20. Необходимо ввести различную периодичность поступления заявок в зависимости от времени суток. Также существует приоритет поступления заявок - помимо основных клиентов существуют клиенты, обслуживаемые вне очереди, для них периодичность поступления задаётся отдельно. Также необходима возможность ввода времени обслуживания клиента. Необходимо определить оптимальное число аппаратов обслуживания.



Описание программного модуля



1. Выбор аппарата обслуживания. Если система только начала свою работу и приходит только первый клиент или же если свободны все аппараты, то он выбирается случайным образом. В обратном случае выбирается тот аппарат, очередь к которому меньше.

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

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

4. Определяется состояние клиента. Пойдёт ли он сразу на обслуживание либо будет ждать своей очереди.

5. С пункта первого по четвёртый процедура повторяется, но для клиентов с более высоким приоритетом.

Далее проверяется каждый клиент, находящийся в очереди.

6. Если клиент в данный момент обслуживается, то проверяется, не прошло ли время его обслуживания. Если прошло, то ему присваивается статус "Обслужен" и далее ищется следующий клиент для обслуживания.

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

8. Далее проверяется, не закончилось ли время работы системы. Если время закончилось, то процесс завершается и выводится отчёт о работе системы. Если же не закончилось, то процесс повторяется с первого пункта.



Руководство пользователя



Работа программы начинается с её настройки. Так как здесь имитируется работа магазина, то обязательно необходимо определить начала работы (рис.1 - 1). Промежуток работы программы от 8: 00-20: 00. от выбранного промежутка зависит периодичность появления клиентов в магазине. Далее выбирается продолжительность работы магазина (рис.1 - 2).



10Так же можно выбрать количество обслуживающих аппаратов - продавцов (рис.1 - 3).










1

2

3

5

4

7

6

8

9

10

11Рисунок 1. Программная реализация СМО



В программе также есть возможность изменения промежутков формирования заявок на обслуживание и времени самого обслуживания для разных приоритетов и в зависимости от текущего времени обслуживания, что является очень важным моментом в работе данного СМО (рис.1 - 5). Существует два типа приоритетов: первый - это клиенты, обслуживаемые вне очереди и второй - клиенты, обслуживаемые всегда в порядке очереди. Для обслуживания так же есть параметр время ожидания (рис.1 - 4). Этот параметр показывает промежуток времени, в течение которого клиент может не дождаться начала обслуживания и покинуть очередь. Для того чтобы начать процесс моделирования необходимо нажать на кнопку “начать" (рис.1 - 6). Процесс моделирования можно остановить совсем, нажав кнопку “остановить" (рис.1 - 8) или приостановить временно с помощью кнопки “приостановить” (рис.1 - 7), его можно начать, заново нажав кнопку “Начать". Во время работы программы текущие результаты отображаются в таблице (рис.1 - 10). По окончанию работы программы выводится текстовый файл с основными результатами. Результаты работы программы можно также просмотреть, нажав кнопку “Отчёт” (рис.1 - 9).




Рисунок 2. Пример отчёта



Во время работы приложения также можно следить за изменением количества клиентов на диаграмме (рис.1 - 11).

В приложении имеется меню (Файл, Сохранить). Меню “Файл" содержит следующие пункты:

“Начать" - начинает процесс моделирования (идентичен кнопке “Начать”)

“Приостановить” - временно останавливает процесс моделирования (кнопка “Приостановить”),

“Остановить" - заканчивает процесс моделирования (кнопка “Остановить”),

“Сохранить отчёт" - сохраняет отчёт о работе приложения,

“Открыть отчёт" - открывает файл отчёта,

“Выход” - заканчивает работу приложения.

Меню “Справка” содержит пункты:

“Помощь" - справочная информация о программе,

“Разработчик” - информации о разработчике приложения.


Результаты тестирования программы











Общее время работы 

Номер аппарата обслуживания

Время работы аппарата

Время простоя аппарата

Общее количество клиентов 

Количество обслуженных клиентов

Количество выбывших клиентов

1: 50: 0

1

1: 50: 0

0: 0: 0

10

9

0



2

1: 49: 0

0: 1: 0

8

7

0



3

1: 47: 0

0: 3: 0

8

7

0



4

1: 46: 0

0: 4: 0

8

7

0



5

1: 45: 0

0: 5: 0

8

7

0



6

1: 44: 0

0: 6: 0

7

7

0



7

1: 43: 0

0: 7: 0

7

6

0



8

1: 41: 0

0: 9: 0

7

6

0



9

1: 41: 0

0: 9: 0

7

6

0



10

1: 41: 0

0: 9: 0

49

19

29




Заключение



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


Список использованных источников



	Лифшиц А.Л. Статистическое моделирование СМО, М., 1978.

	Советов Б.А., Яковлев С.А. Моделирование систем, М: Высшая школа, 1985.

	Гмурман В.Е. Теория вероятностей и математическая статистика, М: Высшая школа, 2001.

	Пригодин Н.В. Системный подход в моделироании М., 1986.


Приложение



Листинг программы



void CSMODlg:: OnButton1 ()

{

UpdateData ();

if (! NTime)

{

timeS=m_StartH*60+m_StartM;

timeE=m_EndH*60+m_EndM;

timeT=timeS+timeE;

int i=timeS;

Tm=timeS;

m_Table2. SetCols (m_CountOch*4);

m_Table2. SetRows (1);

m_Table2. SetRows (4);

int j=0;

while (j< (m_CountOch*4))

{

m_Table2. SetTextMatrix (0,j,"№"); m_Table2. SetColWidth (j,350);

m_Table2. SetTextMatrix (0,j+1,"Получение"); m_Table2. SetColWidth (j+1,700);

m_Table2. SetTextMatrix (0,j+2,"Обслужен"); m_Table2. SetColWidth (j+2,700);

m_Table2. SetTextMatrix (0,j+3,"Состояние"); m_Table2. SetColWidth (j+3,800);

j+=4;

}

for (i=0; i<1000; i++)

{

OCH. o1 [i] =0; OCH. o2 [i] =0;

OCH. kol1 [i] =0; OCH. kol2 [i] =0;

OCH. Obsluzh1 [i] =1;

OCH. Vib1 [i] =1;

OCH. TP [i] =0; OCH. TW [i] =0;

stat1 [i] =0;

stat2 [i] =0;

for (int k=0; k<1000; k++)

{

Kli [i]. num1 [k] =0; Kli [i]. time1 [k] =0; Kli [i]. timeVib [k] =0;

Kli2 [i]. num1 [k] =0; Kli2 [i]. time1 [k] =0; Kli2 [i]. timeVib [k] =0;

}

}

OCH. io1=0; OCH. io2=0;

Klient=0; Klient2=0;

bol=0;

}

LTimer1=SetTimer (ID_TIMER1,100,NULL);

UpdateData (FALSE);

}

void CSMODlg:: OnTimer (UINT uTime)

{

int i,n,tp;

float hr,min,sek;

char a [255] ;

time_t t;

srand ( (unsigned) time (&t));

COleSafeArray saRet;

DWORD numElements [] = {m_CountOch, 2};

saRet. Create (VT_R8, 2, numElements);

if (Klient2<=0 && bol! =0)

{ // очередь с первым приоритетом

i=0;

tp= (atof (m_Table. GetTextMatrix (1,3)) - atof (m_Table. GetTextMatrix (1,2))) *100;

Klient2= (rand ()%tp) *0.01+atoi (m_Table. GetTextMatrix (1,2));

++OCH. kol1 [i] ; // общее количество для аппарата

++OCH. o2 [i] ; // количество с данным приоритетом

if (m_Table2. GetRows () < (OCH. kol1 [i] +3))

{

m_Table2. SetRows (m_Table2. GetRows () +1); iTabl++;

}

tp= (atof (m_Table. GetTextMatrix (1,5)) - atof (m_Table. GetTextMatrix (1,4))) *100;

Kli2 [i]. time1 [OCH. o2 [i]] =Tm+ (rand ()%tp) *0.01+atoi (m_Table. GetTextMatrix (1,4));

float prim=Kli2 [i]. time1 [OCH. o2 [i]] ;

Kli2 [i]. timeVib [OCH. o2 [i]] =Tm+rand ()% (m_Vibiv-m_DoVib) +m_DoVib;

Kli2 [i]. num1 [OCH. o2 [i]] =OCH. kol1 [i] ;

 // постановка в очередь

hr=floorf (Tm/60);

min=floorf (Tm-hr*60);

sek=floorf ( (Tm*100- (hr*60+min) *100) /60);

sprintf (a,"%2.0f:%2.0f:%2.0f",hr,min,sek);

m_Table2. SetTextMatrix (OCH. kol1 [i],1+i*4,a);

itoa (OCH. kol1 [i],a,10);

m_Table2. SetTextMatrix (OCH. kol1 [i], i*4,a);

if (stat1 [i] ==0&&stat2 [i] ==0)

{

m_Table2. SetTextMatrix (OCH. kol1 [i],3+i*4,"Выполняется");

OCH. CountObsl [i] =2;

Kli2 [i]. Stat [OCH. o2 [i]] =2;

stat2 [i] =1;

}

else

{

m_Table2. SetTextMatrix (OCH. kol1 [i],3+i*4,"Ожидает");

Kli2 [i]. Stat [OCH. o2 [i]] =1;

}

}

Klient2--;

bol=1;

if (Klient<=0)

{

 // очередь со вторым приоритетом

int k;

if (bol==0)

i=rand ()%m_CountOch;

if (m_CountOch==1)

{i=0; }

else

{i=m_CountOch;

for (k= (m_CountOch-1); k>=0; k--)

{

if ( (OCH. kol1 [k] -OCH. Obsluzh1 [k]) <= (OCH. kol1 [i] -OCH. Obsluzh1 [i]))

i=k;

else i=i;

}if (i==m_CountOch) i=i-1;

}

++OCH. kol1 [i] ; // общее количество

++OCH. o1 [i] ; // количество с данным приоритетом

if (m_Table2. GetRows () < (OCH. kol1 [i] +3))

{

m_Table2. SetRows (m_Table2. GetRows () +1);

}

if ( (Tm>=480) && (Tm<720))

{

tp= (atof (m_Table. GetTextMatrix (2,3)) - atof (m_Table. GetTextMatrix (2,2))) *100;

Klient= (rand ()%tp) *0.01+atoi (m_Table. GetTextMatrix (2,2));

tp= (atof (m_Table. GetTextMatrix (2,5)) - atof (m_Table. GetTextMatrix (2,4))) *100;

Kli [i]. time1 [OCH. o1 [i]] =Tm+ (rand ()%tp) *0.01+atoi (m_Table. GetTextMatrix (2,4));

Kli [i]. timeVib [OCH. o1 [i]] =Tm+rand ()% (m_Vibiv-m_DoVib) +m_DoVib;

}else

if ( (Tm>=720) && (Tm<900))

{

tp= (atof (m_Table. GetTextMatrix (3,3)) - atof (m_Table. GetTextMatrix (3,2))) *100;

Klient= (rand ()%tp) *0.01+atoi (m_Table. GetTextMatrix (3,2));

tp= (atof (m_Table. GetTextMatrix (3,5)) - atof (m_Table. GetTextMatrix (3,4))) *100;

Kli [i]. time1 [OCH. o1 [i]] =Tm+ (rand ()%tp) *0.01+atoi (m_Table. GetTextMatrix (3,4));

Kli [i]. timeVib [OCH. o1 [i]] =Tm+rand ()% (m_Vibiv-m_DoVib) +m_DoVib;

}else

if ( (Tm>=900) && (Tm<1200))

{

tp= (atof (m_Table. GetTextMatrix (4,3)) - atof (m_Table. GetTextMatrix (4,2))) *100;

Klient= (rand ()%tp) *0.01+atof (m_Table. GetTextMatrix (4,2));

tp= (atof (m_Table. GetTextMatrix (4,5)) - atof (m_Table. GetTextMatrix (4,4))) *100;

Kli [i]. time1 [OCH. o1 [i]] =Tm+ (rand ()%tp) *0.01+atoi (m_Table. GetTextMatrix (4,4));

Kli [i]. timeVib [OCH. o1 [i]] =Tm+rand ()% (m_Vibiv-m_DoVib) +m_DoVib;

}

Kli [i]. num1 [OCH. o1 [i]] =OCH. kol1 [i] ;

 // постановка в очередь

hr=floorf (Tm/60);

min=floorf (Tm-hr*60);

sek=floorf ( (Tm*100- (hr*60+min) *100) /60);

sprintf (a,"%2.0f:%2.0f:%2.0f",hr,min,sek);

m_Table2. SetTextMatrix (OCH. kol1 [i],1+i*4,a);

itoa (OCH. kol1 [i],a,10);

m_Table2. SetTextMatrix (OCH. kol1 [i], i*4,a);

if (stat1 [i] ==0&&stat2 [i] ==0)

{

m_Table2. SetTextMatrix (OCH. kol1 [i],3+i*4,"Выполняется");

OCH. CountObsl [i] =1;

Kli [i]. Stat [OCH. o1 [i]] =2;

stat1 [i] =1;

}

else

{

m_Table2. SetTextMatrix (OCH. kol1 [i],3+i*4,"Ожидает");

Kli [i]. Stat [OCH. o1 [i]] =1;

}

}

Klient--;

 // // // // // // // // выбывание из очереди // // // // // // // // // // // // // //  // 

int count;

for (int ki=0; ki<m_CountOch; ki++)

{

for (int j=1; j< (OCH. o1 [ki] +1); j++)

{

count=Kli [ki]. num1 [j] ;

if (strcmp (m_Table2. GetTextMatrix (count,3+ki*4),"Выполняется") ==0)

{

 // // // // // /

OCH. TW [ki] ++;

if ( (Kli [ki]. time1 [count] <=Tm) && (Kli [ki]. time1 [count] ! =0))

{

m_Table2. SetTextMatrix (count,3+ki*4,"Обслужен");

OCH. Obsluzh1 [ki] ++;

hr=Kli [ki]. time1 [count] /60;

hr=floorf (hr);

min=floorf ( (Kli [ki]. time1 [count])) - hr*60;

sek=floorf ( ( (Kli [ki]. time1 [count]) *100- (hr*60+min) *100) /60);

sprintf (a,"%2.0f:%2.0f:%2.0f",hr,min,sek);

m_Table2. SetTextMatrix (count,2+ki*4,a);

stat1 [ki] =0; break;

}else stat1 [ki] =1;

 // // // // // /

}

}

for (j=1; j< (OCH. o2 [ki] +1); j++)

{

count=Kli2 [ki]. num1 [j] ;

if (strcmp (m_Table2. GetTextMatrix (count,3+ki*4),"Выполняется") ==0)

{

OCH. TW [ki] ++;

if ( (Kli2 [ki]. time1 [count] <=Tm) && (Kli2 [ki]. time1 [count] ! =0))

{

m_Table2. SetTextMatrix (count,3+ki*4,"Обслужен");

OCH. Obsluzh1 [ki] ++;

hr= (Kli2 [ki]. time1 [count]) /60;

hr=floorf (hr);

min=floorf ( (Kli2 [ki]. time1 [count]) - hr*60);

sek=floorf ( ( (Kli2 [ki]. time1 [count]) *100- (hr*60+min) *100) /60);

sprintf (a,"%2.0f:%2.0f:%2.0f",hr,min,sek);

m_Table2. SetTextMatrix (count,2+ki*4,a);

stat2 [ki] =0; break;

}else stat2 [ki] =1;

}

}

}

 // // // // // // // // // // // // // // // // // // // // // // // // // // // // /

for (ki=0; ki<m_CountOch; ki++)

{

for (int j=1; j< (OCH. o1 [ki] +1); j++)

{

if (strcmp (m_Table2. GetTextMatrix (Kli [ki]. num1 [j],3+ki*4),"Ожидает") ==0)

{

if (stat1 [ki] ==0&&stat2 [ki] ==0)

{

stat1 [ki] =1;

m_Table2. SetTextMatrix (Kli [ki]. num1 [j],3+ki*4,"Выполняется");

goto l1;

}

if (Kli [ki]. timeVib [j] <=Tm)

{

m_Table2. SetTextMatrix (Kli [ki]. num1 [j],3+ki*4,"Выбыл");

Kli [ki]. time1 [Kli [ki]. num1 [j]] =0;

OCH. Vib1 [ki] ++;

hr=Tm/60;

hr=floorf (hr);

min=floorf (Tm-hr*60);

sek=floorf ( (Tm*100- (hr*60+min) *100) /60);

sprintf (a,"%2.0f:%2.0f:%2.0f",hr,min,sek);

m_Table2. SetTextMatrix (Kli [ki]. num1 [j],2+ki*4,a);

}

l1:; }

}

for (j=1; j< (OCH. o2 [ki] +1); j++)

{

if (strcmp (m_Table2. GetTextMatrix (Kli2 [ki]. num1 [j],3+ki*4),"Ожидает") ==0)

{

if (stat1 [ki] ==0&&stat2 [ki] ==0)

{

stat2 [ki] =1;

m_Table2. SetTextMatrix (Kli2 [ki]. num1 [j],3+ki*4,"Выполняется");

goto l2;

}

if (Kli2 [ki]. timeVib [j] <=Tm)

{

m_Table2. SetTextMatrix (Kli2 [ki]. num1 [j],3+ki*4,"Выбыл");

Kli2 [ki]. time1 [Kli2 [ki]. num1 [j]] =0;

OCH. Vib1 [ki] ++;

hr=Tm/60;

hr=floorf (hr);

min=floorf (Tm-hr*60);

sek=floorf ( (Tm*100- (hr*60+min) *100) /60);

sprintf (a,"%2.0f:%2.0f:%2.0f",hr,min,sek);

m_Table2. SetTextMatrix (Kli2 [ki]. num1 [j],2+ki*4,a);

}

l2:; }

}

}

long index [2] ;

for (index [0] =0; index [0] <m_CountOch; index [0] ++)

{

for (index [1] =0; index [1] <2; index [1] ++)

{

double val = OCH. Obsluzh1 [index [0]] -1;

saRet. PutElement (index, &val);

}

}

m_mychart. SetChartData (saRet. Detach ());

m_mychart. Refresh;

 // // // // // // // // // // // // // // // // // // // // // // // // // // // // // /

Tm++;

if (Tm>=timeT)

{

KillTimer (ID_TIMER1);

n=m_Table2. GetRows ();

m_Table2. SetRows (n+5);

for (int j=0; j<m_CountOch; j++)

{

m_Table2. SetTextMatrix (n+2,2+j*4,"вр. работы");

hr=floorf (OCH. TW [j] /60);

min=floorf (OCH. TW [j] -hr*60);

sek=floorf ( (OCH. TW [j] *100- (hr*60+min) *100) /60);

sprintf (a,"%2.0f:%2.0f:%2.0f",hr,min,sek);

m_Table2. SetTextMatrix (n+2,3+j*4,a);

OCH. TP [j] =timeE-OCH. TW [j] ;

m_Table2. SetTextMatrix (n+3,2+j*4,"вр. простоя");

hr=floorf (OCH. TP [j] /60);

min=floorf (OCH. TP [j] -hr*60);

sek=floorf ( (OCH. TP [j] *100- (hr*60+min) *100) /60);

sprintf (a,"%2.0f:%2.0f:%2.0f",hr,min,sek);

m_Table2. SetTextMatrix (n+3,3+j*4,a);

}

strcpy (str,"Общее время работы \t\t");

hr=floorf (timeE/60);

min=floorf (timeE-hr*60);

sek=floorf ( (timeE*100- (hr*60+min) *100) /60);

sprintf (a,"%2.0f:%2.0f:%2.0f\r\n",hr,min,sek);

strcat (str,a);

strcat (str,"Номер аппарата обслуживания \t");

for (j=0; j<m_CountOch; j++) {sprintf (a,"%d\t",j+1); strcat (str,a); }

strcat (str,"\r\n");

strcat (str,"Время работы аппарата\t\t");

for (j=0; j<m_CountOch; j++)

{sprintf (a,"%s\t",m_Table2. GetTextMatrix (n+2,3+4*j)); strcat (str,a); }

strcat (str,"\r\n");

strcat (str,"Время простоя аппарата\t\t");

for (j=0; j<m_CountOch; j++)

{sprintf (a,"%s\t",m_Table2. GetTextMatrix (n+3,3+4*j)); strcat (str,a); }

strcat (str,"\r\n");

strcat (str,"Общее количество клиентов \t");

for (j=0; j<m_CountOch; j++)

{sprintf (a,"%d\t",OCH. kol1 [j]); strcat (str,a); }

strcat (str,"\r\n");

strcat (str,"Количество обслуженных клиентов\t");

for (j=0; j<m_CountOch; j++)

{sprintf (a,"%d\t",OCH. Obsluzh1 [j] -1); strcat (str,a); }

strcat (str,"\r\n");

strcat (str,"Количество выбывших клиентов\t");

for (j=0; j<m_CountOch; j++)

{sprintf (a,"%d\t",OCH. Vib1 [j] -1); strcat (str,a); }

LPTSTR sizeF;

LPTSTR *sizeOf;

CStdioFile File ("отчёт. txt",CFile:: modeCreate|CFile:: modeWrite|CFile:: typeBinary);

File. WriteString ( (LPCTSTR) str);

ShellExecute (NULL,NULL,"отчёт. txt",NULL, NULL, SW_SHOWNORMAL);

NTime=FALSE;

}

}

void CSMODlg:: OnButton2 ()

{

KillTimer (ID_TIMER1);

NTime=TRUE;

}

void CSMODlg:: OnButton3 ()

{

char a [255] ;

float hr,min,sek;

strcpy (str,"Общее время работы \t\t");

hr=floorf (timeE/60);

min=floorf (timeE-hr*60);

sek=floorf ( (timeE*100- (hr*60+min) *100) /60);

sprintf (a,"%2.0f:%2.0f:%2.0f\r\n",hr,min,sek);

strcat (str,a);

strcat (str,"Номер аппарата обслуживания \t");

for (int j=0; j<m_CountOch; j++) {sprintf (a,"%d\t\t",j+1); strcat (str,a); }

strcat (str,"\r\n");

strcat (str,"Время работы аппарата\t\t");

for (j=0; j<m_CountOch; j++)

{

hr=floorf (OCH. TW [j] /60);

min=floorf (OCH. TW [j] -hr*60);

sek=floorf ( (OCH. TW [j] *100- (hr*60+min) *100) /60);

sprintf (a,"%2.0f:%2.0f:%2.0f\t\t",hr,min,sek);

strcat (str,a);

}

strcat (str,"\r\n");

strcat (str,"Время простоя аппарата\t\t");

for (j=0; j<m_CountOch; j++)

{

OCH. TP [j] =timeE-OCH. TW [j] ;

hr=floorf (OCH. TP [j] /60);

min=floorf (OCH. TP [j] -hr*60);

sek=floorf ( (OCH. TP [j] *100- (hr*60+min) *100) /60);

sprintf (a,"%2.0f:%2.0f:%2.0f\t\t",hr,min,sek);

strcat (str,a);

}

strcat (str,"\r\n");

strcat (str,"Общее количество клиентов \t");

for (j=0; j<m_CountOch; j++)

{sprintf (a,"%d\t\t",OCH. kol1 [j]); strcat (str,a); }

strcat (str,"\r\n");

strcat (str,"Количество обслуженных клиентов\t");

for (j=0; j<m_CountOch; j++)

{sprintf (a,"%d\t\t",OCH. Obsluzh1 [j] -1); strcat (str,a); }

strcat (str,"\r\n");

strcat (str,"Количество выбывших клиентов\t");

for (j=0; j<m_CountOch; j++)

{sprintf (a,"%d\t\t",OCH. Vib1 [j] -1); strcat (str,a); }

COtchDlg m_Otch;

UpdateData ();

m_Otch. m_Show=str;

UpdateData (FALSE);

KillTimer (ID_TIMER1);

NTime=FALSE;

}