Delphi_part2
.pdf
появиться компонент InputBox, с помощью которого вводится нужная группа, после чего во втором окне появится список соответствующих студентов отсортированный по фамилиям..
При нажатии на кнопку «Подсчитать количество имеющих более 2-х хвостов» во втором окне появится список соответствующих студентов отсортированный по результатам успеваемости,а их количество будет выведено в окне MessageBox
Рисунок 10.2 – Интерфейс проекта
10.2.2 Определение типов данных
Для реализации проекта нужно определить тип записи, тип массива для хранения исходных данных и другие типы. Эти описания должны быть доступны всем процедурам проекта, поэтому их следует сделать вне этих процедур, в начале раздела Implementation.
Тексты этих описаний для создаваемого проекта приведены ниже.
type |
|
TFio = String[20]; |
// тип для фамилии студента |
TGroup = String[5]; |
// тип для группы |
TAttRec = record |
//тип для записи |
fio : TFio ; |
|
group : TGroup; |
|
61
neud: integer; srBall : real;
end;
//Тип для массива записей
TAttArray = Array[1..30] of TAttRec;
10.2.3 Инициализация интерфейса
При запуске проекта необходимо подготовить интерфейс так, чтобы было удобно с ним работать и проводить отладку. Для этого можно использовать процедуру обработки события onCreate формы. Именно эта процедура настроит компоненты StringGrid для вывода записей проекта и обеспечит их начальное заполнение. Исходный код процедуры приводится ниже.
// Процедура підготовки до роботи
procedure TfrmRecord.FormCreate(Sender: TObject); begin
//Настраиваем таблицу с исходными данными with StringGrid1 do begin
ColCount :=4; RowCount :=5; FixedRows :=1;
//Заголовок таблицы в нулевой строке StringGrid1
Cells [0,0]:='Группа'; Cells [1,0]:='Студент'; Cells [2,0]:='Неуд.';Cells [3,0]:='Ср.балл';
//Несколько записей таблицы для ускорения отладки
Cells [0, 1] := 'КС051'; Cells [1,1]:='Чуб П.П.'; Cells [2, 1] := '0'; Cells [3,1] := '4,55';
Cells [0, 2] := 'КС051'; Cells [1,2] := 'Гай А.Л.'; Cells [2, 2] := '3'; Cells [3,2] := '1,55';
Cells [0, 3] := 'КС051'; Cells [1,3] := 'Кот А.В.'; Cells [2, 3] := '1'; Cells [3,3] := '2,45';
Cells [0, 4] := 'ЕМ051'; Cells [1,4] :=' Жир П.Р.'; Cells [2, 4] := '2'; Cells [3,4] := '2,00';
end;
//Настраиваем таблицу для обработанных данных with StringGrid2 do begin
ColCount :=4; RowCount :=2; FixedRows :=1;
62
//Заголовок таблицы в нулевой строке StringGrid2
Cells [0,0] := 'Группа'; Cells [1,0] := 'Студент'; Cells [2,0] := 'Неуд.';Cells [3,0] := 'Ср.балл';
end;
end;
10.2.4 Добавление строки в таблицу
Добавить строку в таблицу очень легко. Для этого достаточно увеличить количество строк компонента StringGrid1 на единицу. Соответствующую процедуру следует связать с кнопкой «Добавить». Код процедуры представлен ниже.
//Процедура введення додаткового рядка procedure TfrmRecord.btnAddClick(Sender: TObject); begin
StringGrid1.RowCount := StringGrid1.RowCount +1;
end;
10.2.5 Удаление строки из таблицы
Эта процедура несколько сложнее, чем добавление. Для того чтобы удалить некоторую строку следует все остальные последовательно поднять на одну выше, а затем количество строк в компоненте уменьшить на единицу, что обрежет последнюю строку.
Но для того, чтобы переносить записи из одной строки компонента в другую, целесообразно предварительно написать подпрограммы считывания записи из строки компонента StringGrid и занесения записи в строку этого компонента. Эти подпрограммы пригодятся и для решения других задач, в частности задачи считывания массива из StringGrid и задачи записи массива в
StringGrid.
Код соответствующих подпрограмм приведен ниже.
// Функція, що читає запис із рядка StrinGrid
function recordFromRowGrid(sg: TStringGrid; row: integer): TAttRec;
// Функція, що читає запис із рядка StrinGrid begin
result.group := sg.Cells [0, row]; result.fio := sg.Cells [1,row]; result.neud := strToInt(sg.Cells [2, row]);
result.srBall := strToFloat(sg.Cells [3, row]);
63
end;
// Процедура переносу запису у рядoк StrinGrid
procedure recordToRowGrid(rec: TAttRec; sg:TStringGrid; row: integer); begin
sg.Cells [0, row] := rec.group; sg.Cells [1, row] := rec.fio;
sg.Cells [2, row]:= intToStr(rec.neud); sg.Cells [3,r ow]:= floatToStr(rec.srBall);
end;
Наличие этих подпрограмм позволяет написать процедуру удаления записи из компонента StringGrid подобно тому, как удаляется элемент из массива.
Код процедуры удаления представлен ниже.
// Процедура вилучення поточного рядка із StringGrid procedure TfrmRecord.btnDelClick(Sender: TObject);
var i, k: integer; r: TAttRec; begin
k := StringGrid1.Row ; //Узнаем, какая строка активна if k = 0 then exit;
//Переписуємо наступні рядки у попередні for i := k to StringGrid1.RowCount - 2 do begin
r := recordFromRowGrid(StringGrid1, i + 1); recordToRowGrid(r, StringGrid1, i );
end;
// Обрезаем последюю строку
StringGrid1.RowCount := StringGrid1.RowCount - 1; end;
10.2.6Процедура создания массива записей по содержимому StringGrid
Эта процедура обеспечивает обмен информацией между компонентом StringGrid и массивом записей. Алгоритм процедуры заключается в циклическом вызове написанной ранее процедуры считывания записи из
64
StringGrid. Ниже приводится код этой процедуры.
// Процедура формування масиву по змісту StringGrid procedure getArrayFromGrid(var ar: TAttArray; var count: integer;
sg: TStringGrid);
var i: integer; begin
count := sg.RowCount-1; for i := 1 to count do
ar[i] := recordFromRowGrid(sg, i ); end;
10.2.7Процедура отображения массива в компоненте
StringGrid
Эта процедура, как и предыдущая, обеспечивает обмен информацией между компонентом StringGrid и массивом записей. Алгоритм процедуры заключается в циклическом вызове написанной ранее процедуры вывода записи в строку StringGrid. Ниже приводится код этой процедуры.
// Процедура відображення масиву у StrinGrid
procedure showArrayInGrid(sg: TStringGrid; const ar: TAttArray; count: integer);
var i: integer; begin
if count = 0 then exit; sg.RowCount := count+1; for I := 1 to count do
recordToRowGrid(ar[i], sg, i); end;
10.2.8Процедура сортировки массива записей по группе
ифамилии
Особенность сортировки массивов записей состоит в том, что может быть очень много вариантов сортировки. Возможны сортировки по значениям отдельных полей, а также по их комбинациям. Например, можно сортировать массив записей по количеству «хвостов», а при равенстве этого показателя по среднему баллу, кроме того, при равенстве среднего балла по фамилиям.
Алгоритм сортировки для каждого из возможных вариантов остается одним и тем же, меняется только правило сравнения записей.
65
В тех случаях, когда алгоритм сравнения записей сложный, его целесообразно представить в виде отдельной функции, которая будет возвращать результат логического типа.
Например, при необходимости сортировать массив записей по группе и фамилии, можно предварительно написать соответствующую функцию сравнения.
// Допоміжна функція для cортування за групою та прізвищем function compareGrFio(r1, r2:TAttRec):boolean;
begin
if r1.Group <> r2.Group
then result:=r1.Group <= r2.Group else result := r1.fio <= r2.fio;
end;
После этого можно написать процедуру сортировки массива записей, например, методом пузырька, которая будет отличаться от рассматриваемой ранее процедуры только тем, что для сравнения двух элементов массива вызывается написанная выше функция.
//Процедура сортування масиву записiв
//методом бульбашки за групою та прізвищем
procedure sortAttArrayGrFio (var ar:TAttArray;count:integer); var i, j: integer; r: TAttRec; ok: boolean;
begin
i := count; repeat
i:=i-1; ok:=true;
for j:=1 to i do
// Сравниваем записи с помощью функции if not compareGrFio(ar[j], ar[j+1]) then begin
r:=ar[j];
ar[j]:=ar[j+1];
ar[j+1]:=r; ok:=false;
end;
66
until ok; end;
Наличие этой процедуры позволяет нам написать процедуру, которая будет вызываться при нажатии на кнопку «Упорядочить по группе и фамилии». Код процедуры приведен ниже.
// Сортування за групою та прізвищем
procedure TfrmRecord.btnSortGrFioClick(Sender: TObject); var ar: TAttArray; count :integer;
begin
//Беремо масив із StringGrid1 getArrayFromGrid(ar, count, StringGrid1);
// Сортуємо масив за правилом, що задає функція compareGrFio sortAttArrayGrFio (ar, count);
//Передаємо впорядкований масив у StringGrid2 showArrayInGrid(StringGrid2, ar, count);
end;
10.2.9 Сортировка записей по количеству неудовлетворительных оценок и среднему баллу
Для этой сортировки можно также предварительно написать соответствующую функцию сравнения. Ниже приведена такая функция.
// Допоміжна функція для cортування за результатами атестації function compareResult(const r1, r2:TAttRec): boolean;
begin
if r1.neud <> r2.neud
then result := r1.neud < r2.neud else result := r1.srBall > r2.srBall; end;
Наличие этой функции позволяет нам написать процедуру сортировки, которая будет отличаться от рассмотренной выше только именем функции, вызываемой для сравнения. Вместо вызова compareGrFio(ar[j], ar[j+1]), в процедуре сортировки нужно будет написать compareResult(ar[j], ar[j+1]). Кроме того, у процедуры должно быть другое имя, например, sortAttArrayResult.
67
10.2.10Выборка студентов какой-нибудь группы, имеющих средний балл выше 4
Для решения этой задачи вначале напишем процедуру формирования соответствующего массива записей путем выборки нужных записей из исходного массива. Ниже приведена эта процедура.
//Допоміжна процедура відбору студентів заданої групи,
//що мають середній бал більше ніж 4
procedure createRecordArrayMoreThen4(const ar: TAttArray; count: integer; gr:TGroup; var ar4: TAttArray; var count4:integer);
var i: integer; begin
count4 := 0;
for i:=1 to count do
if (ar[i].group = gr) and (ar[i].srBall >=4) and (ar[i].neud = 0) then begin
count4 := count4 + 1; ar4[count4] := ar[i];
end;
end;
Наличие этой процедуры позволяет нам написать процедуру обработки события нажатия на кнопку «Выбрать ударников какой-то группы». Код процедуры приведен ниже.
// Процедура вибору хорошистів групи procedure TfrmRecord.btn4Click(Sender: TObject);
var ar, ar4: TAttArray; count, count4: integer; gr: TGroup; begin
//Беремо масив із StringGrid1 getArrayFromGrid(ar, count, StringGrid1);
// Запит на введення назви групи
gr := inputBox('Поиск "хорошистов"', 'Введите группу', 'КС051');
//Створюємо масив хорошистів групи createRecordArrayMoreThen4(ar, count, gr, ar4, count4);
//Сортуємо масив за правилом, що задає функція compareResult sortAttArrayResult (ar4, count4);
68
//Передаємо впорядкований масив у StringGrid2 showArrayInGrid(StringGrid2,ar4, count4);
end;
10.2.11Подсчет числа студентов, имеющих более 2-х неудовлетворительных оценок и вывод упорядоченного списка этих студентов
Для решения этой задачи вначале напишем процедуру формирования соответствующего массива записей путем выборки нужных записей из исходного массива. Ниже приведена эта процедура.
//Допоміжна процедура відбору студентів ,
//що мають кількість заборгованностей більше ніж 2 procedure createRecordArrayMoreThen2(const ar: TAttArray; count: integer; gr:TGroup; var ar2: TAttArray; var count2:integer);
var i: integer; begin
count3 := 0;;
for i:=1 to count do if ar[i].neud > 2 then begin
count2 := count2 + 1; ar2[count2] := ar[i];
end;
end;
Наличие этой процедуры позволяет нам написать процедуру обработки события нажатия на кнопку «Подсчитать количество имеющих более 3-х хвостов». Код процедуры приведен ниже.
// Процедура вибору хвостистів
procedure TfrmRecord.btn2Click(Sender: TObject);
var ar, ar2: TAttArray; count, count2: integer; gr: TGroup; begin
//Беремо масив із StringGrid1 getArrayFromGrid(ar, count, StringGrid1);
// Створюємо масив хвостистів групи createRecordArrayMoreThen2(ar, count, gr, ar2, count2);
69
// Сортуємо масив за правилом, що задає функція compareResult sortAttArrayResult (ar2, count2);
//Передаємо впорядкований масив у StringGrid2 showArrayInGrid(StringGrid2, ar2, count2);
//Виводимо кількість хвостистів у ShowMessage
ShowMessage(intToStr(count2)+' cтудентов имеют более 2-х неуд.')
end;
10.3 ЗАДАНИЕ ДЛЯ САМОСТОЯТЕЛЬНОЙ РАБОТЫ
В лабораторной работе следует создать проект, в соответствии с требованиями варианта из таблицы 10.1. Номер варианта выбирается по последней цифре номера зачетной книжки. Обработку записей следует проводить в массиве. Компоненты TStringGrid использовать только для считывания записей и вывода результатов.
Таблица 10.1 – Задания для самостоятельной работы
№ |
Содержание записей проекта и требования к обработке |
0 |
Номер комнаты в общежитии, количество компьютеров, наличие |
|
холодильника, количество жильцов. |
|
Сортировка обменом по номеру комнаты. Комплексная сортировка |
|
по количеству жильцов ↓ + по наличию холодильника ↓ + по количеству |
|
компьютеров ↓. |
|
Выборка комнат, где на каждого жильца не менее 1-го компьютера. |
|
Подсчет общего числа компьютеров и холодильников. |
1 |
Фамилия работника, оклад, надбавка в целых %, премия. |
|
Сортировка выбором по фамилии. Комплексная сортировка по |
|
суммарной выплате ↑ + по фамилиям ↓. |
|
Выборка лиц, у которых суммарная выплата выше заданного |
|
значения. |
|
Подсчет общей суммы выплат. |
2 |
Фамилия студента, дата (в виде строки символов гг-мм-дд), |
|
расходы на завтрак, обед, ужин в студенческой столовой. |
|
Комплексная сортировка вставкой по дате ↓ + по фамилии ↓. |
|
Комплексная сортировка по фамилии ↓ + по сумме расходов за день ↑ . |
|
Выборка данных о ежедневных суммарных расходах, для студента. |
|
Подсчет суммарных расходов студента за месяц. |
3 |
Фамилия студента, группа, контракт или бюджет, средний балл. |
|
Комплексная сортировка обменом по группе ↓ + по фамилии ↓. |
|
Комплексная сортировка по полю контракт или бюджет + по среднему |
|
баллу. |
|
Выборка студентов, у которых средний балл ниже заданного. |
|
Вычисление среднего балла для заданной группы. |
70
