- •Министерство образования и науки Российской федерации
- •Предисловие
- •Часть I
- •Описание предметной области
- •2. Моделирование данных
- •3. Представление данных
- •Часть II
- •4. Предварительные замечания
- •5. Постановка задачи
- •6. Структура проекта
- •7. Создание меню
- •8. Пользовательские модули
- •9. Работа с файлами
- •10. Ввод и редактирование данных
- •11. Работа с существующим файлом
- •12. Сортировка данных
- •13. Задачи, решаемые в информационной системе
- •Часть III
- •14. Общие требования
- •15. Технические задания к проектам
- •Часть I. Проектирование информационной системы 4
- •Часть II. Реализация информационной системы «Студенты» 13
- •Часть III. Проекты для самостоятельной разработки 80
13. Задачи, решаемые в информационной системе
В техническом задании запланировано решение следующих задач:
Вывод списков групп по запросам для одной группы и для всех групп.
Вычисление среднего балла для каждого студента.
Для каждой учебной группы вычисление количества студентов и среднего балла в группе.
Результаты решения задач оформляются в виде отчетов, вывод которых вызывается командами пункта меню «Отчеты» в строке меню главной формы.
Заметим, что первый пункт – это фактически два различных отчета: списки всех групп и список одной, указанной группы. Из-за этого мы при создании пунктов меню поставили в соответствие этому отчету два пункта меню: «Отчеты Списки групп Все группы» и «Отчеты Списки групп Одна группа».
Отчеты будем генерировать в виде текстовых файлов. Для их просмотра используем компонент RichTextBox.
Поместим этот элемент на форму frmMenu, задав ему следующие свойства:
-
Name = RichTextBox1
Системное имя
Font = Courier New
Шрифт
ReadOnly = True
Запрет редактирования
ScrollBars = Vertical
Вертикальная полоса прокрутки
Visible = False
Объект невидим
Кроме этого элемента поместим на форму еще и кнопку (Name = cmdSaveOtch, Visible = False), при нажатии которой будем сохранять просматриваемый отчет. Таким образом, макет формы frmMenu , доработанный для вывода результатов имеет вид, представленный на рисунке 8.
По нажатию кнопки «Сохранить отчет» текущий отчет (т.е. отчет, который просматривается в данный момент) должен быть сохранен. Таким образом, поскольку мы генерируем отчеты в текстовый файл с заранее заданным именем, то по нажатию кнопки должна быть сделана копия файла с отчетом.
Рисунок 8. Макет главной формы в режиме конструктора
Приведем код процедуры обработки события нажатия на кнопку «Сохранить отчет».
Private Sub cmdSaveOtch_Click(ByVal sender As System.Object,_
ByVal e As System.EventArgs) Handles cmdSaveOtch.Click
' запрос имени файла для сохранения
With SaveFileDialog1
.FileName = ""
.Filter = "Все файлы (*.*)|*.*|" + _
"Текстовые файлы. (*.txt)|*.txt|" + _
"Файлы исходных данных (*.dan)|*.dan|" + _
"Файлы результатов (*.rez)|*.rez"
.FilterIndex = 2
.ShowDialog()
End With
' если имя файла не пусто и не равно имени
' просматриваемого файла,
If SaveFileDialog1.FileName <> "" And _
richName <> SaveFileDialog1.FileName Then
' то производится копирование просматриваемого файла,
FileCopy(richName, SaveFileDialog1.FileName)
' его удаление
Kill(richName)
' и вывод в RichTextBox1 нового файла
richName = SaveFileDialog1.FileName
RichTextBox1.LoadFile(richName, _
RichTextBoxStreamType.PlainText)
' сообщение об успешном завершении сохранения отчета
MsgBox("Отчет сохранен", vbOKOnly + vbInformation, _
"Сохранение")
End If
End Sub
13.1. Вывод списков групп
Вывод списков групп реализован в процедуре обработки события выбора пункта меню «Отчеты Списки групп Все группы».
Прежде чем привести код этой процедуры, обсудим алгоритм, реализованный в ней. Идея алгоритма состоит в следующем: сначала файл с данными о студентах должен быть «отсортирован» по курсу, группе и фамилии; результатом чего станет индексный массив Ind, который позволит просматривать записи файла в отсортированном виде именно таким образом. Такая упорядоченность записей файла фактически представляет его разбитым на группы записей, самая внутренняя группа имеет одинаковые значения для курса и группы и упорядочена в алфавитном порядке фамилий. Поэтому в самом внешнем цикле перебираются курсы, во вложенном в него цикле перебираются номера групп, и в следующем по уровню вложенности цикле (для одинаковых значений курса и группы во всех записях) выбираются и выводятся в текстовый файл фамилии студентов. Код процедуры снабжен подробными комментариями.
Private Sub mnuQueryListAllItem_Click(ByVal sender As _
System.Object, ByVal e As System.EventArgs) _
Handles mnuQueryListAllItem.Click
Dim i As Integer
Dim Ind(Nmax) As Integer
Dim NK As Byte
Dim NG As Byte
Dim NPP As Integer
Dim KeyK(Nmax) As Single
Dim KeyG(Nmax) As Single
Dim KeyFIO(Nmax) As String
Dim R As TStud = New TStud()
' открывается временный вспомогательный файл otch.ist,
' находящийся в той же папке, что и работающий проект
Path2 = CurDir() + "\otch.txt"
F4 = FreeFile()
FileOpen(F4, Path2, OpenMode.Output)
' подготовка данных для сортировки по курсу, группе и ФИО
For i = 1 To N
R.ReadFromFile(f1, i)
KeyK(i) = R.Kurs
KeyG(i) = R.Group
KeyFIO(i) = R.FIO
Ind(i) = i
Next i
' сортировка данных
Call SortStr(KeyFIO, N, Ind)
Call Sort(KeyG, N, Ind)
Call Sort(KeyK, N, Ind)
' чтение первой записи в отсортированном списке
i = 1
R.ReadFromFile(f1, Ind(i))
Do While i <= N
' фиксирование и запись в файл номера текущего курса
NK = R.Kurs
PrintLine(F4, "Курс " + CStr(NK))
Do While NK = R.Kurs And i <= N
' фиксирование и запись в файл номера
' текущей группы
NG = R.Group
PrintLine(F4, vbTab + "Группа " + CStr(NG))
' порядковый номер студентов в группе
' начинается с единицы
NPP = 1
Do While NK = R.Kurs And NG = R.Group
' запись в файл ФИО студента
PrintLine(F4, vbTab + vbTab + CStr(NPP) + "." + _
vbTab + R.FIO)
NPP = NPP + 1
i = i + 1
' если еще есть записи, то считываем
' следующую, иначе выходим из цикла
If i <= N Then
R.ReadFromFile(f1, Ind(i))
Else
Exit Do
End If
Loop
' пропуск строки между списками различных групп
PrintLine(F4, "")
Loop
Loop
' файла отчета закрывается
FileClose(F4)
' загрузка только что созданного файла в RichTextBox1
RichTextBox1.LoadFile(Path2, _
RichTextBoxStreamType.PlainText)
richName = Path2
' показ элемента RichTextBox1 и кнопки «Сохранить отчет»
RichTextBox1.Visible = True
cmdSaveOtch.Visible = True
End Sub
Вывод списка одной группы реализован в процедуре обработки события выбора пункта меню «Отчеты Списки групп Одна группа»
В этой задаче у пользователя сначала запрашиваются значения для курса и группы, и проверяется корректность введенных значений. Затем файл исходных данных упорядочивается по полю «Фамилия» в алфавитном порядке; после чего он просматривается, из него выбираются и выводятся в текстовый файл записи, в которых значения курса и группы совпадают со значениями, введенными пользователем.
Private Sub mnuQueryListOneItem_Click(ByVal sender As _
System.Object, ByVal e As System.EventArgs) _
Handles mnuQueryListOneItem.Click
Dim i As Integer
Dim Ind(Nmax) As Integer
Dim NK As Byte
Dim NG As Byte
Dim NPP As Integer
Dim TempStr As String
Dim KeyFIO(Nmax) As String
Dim R As TStud = New TStud()
' открывается файл otch.ist, находящийся в той же папке,
' что и работающий проект
Path2 = CurDir() + "\otch.ist"
F4 = FreeFile()
FileOpen(F4, Path2, OpenMode.Output)
' запрос у пользователя интересующего его курса
TempStr = InputBox("Введите курс", "Ввод курса")
Do While Not IsNumeric(TempStr)
'если введенный курс не является числом,
' но является пустым значением
If (TempStr = "") Then
' то файл закрывается и осуществляется выход
' из процедуры
FileClose(F4)
Exit Sub
End If
' если введенный курс не является числом,
' то еще раз производится запрос номера курса
MsgBox("Курс - число", vbOKOnly + vbExclamation, _
"Ошибка")
TempStr = InputBox("Введите курс", "Ввод курса")
Loop
' перевод введенного курса в числовое значение
NK = CByte(TempStr)
' запрос у пользователя интересующей его группы
TempStr = InputBox("Введите группу", "Ввод группы")
Do While Not IsNumeric(TempStr)
'если введенная группа не является числом,
' но является пустым значением
If (TempStr = "") Then
' то файл закрывается и осуществляется выход
' из процедуры
FileClose(F4)
Exit Sub
End If
' если введенная группа не является числом,
' то еще раз производится запрос номера группы
MsgBox("Группа-число", vbOKOnly + vbExclamation, _
"Ошибка")
TempStr = InputBox("Введите группу", "Ввод группы")
Loop
' перевод введенной группы в числовое значение
NG = CByte(TempStr)
' подготовка данных для сортировки по полю ФИО
For i = 1 To N
R.ReadFromFile(f1, i)
KeyFIO(i) = R.FIO
Ind(i) = i
Next i
' сортировка данных
Call SortStr(KeyFIO, N, Ind)
' запись в файл информации о курсе и группы
PrintLine(F4, "Курс " + CStr(NK) + ", Группа " + CStr(NG))
' порядковый номер студентов в группе
' начинается с единицы
NPP = 1
For i = 1 To N
' считывание следующей записи и если курс и группа
' соответствуют, то производится вывод в файл отчета
R.ReadFromFile(f1, Ind(i))
If R.Kurs = NK And R.Group = NG Then
PrintLine(F4, vbTab + CStr(NPP) + "." + vbTab + R.FIO)
NPP = NPP + 1
End If
Next i
' файл отчета закрывается
FileClose(F4)
' загрузка только что созданного файла в RichTextBox1
RichTextBox1.LoadFile(Path2, _
RichTextBoxStreamType.PlainText)
richName = Path2
' показ элемента RichTextBox1 и кнопки «Сохранить отчет»
RichTextBox1.Visible = True
cmdSaveOtch.Visible = True
End Sub
13.2. Количество студентов и средний балл в группах
Во второй и третьей задаче из числа запланированных задач необходимо для каждого студента вычислить средний балл. Вынесем вычисление среднего балла каждого студента в отдельную пользовательскую процедуру, которая будет принадлежать форме frmMenu. В этой процедуре создается вспомогательный файл прямого доступа с записями пользовательского типа Tball, содержащий столько же записей, сколько находится в файле исходных данных. Пользовательский тип Tball содержит поле для вычисления среднего балла. Код процедуры приведен ниже.
Private Sub AverageBallCreate()
Dim i As Integer
Dim j As Integer
Dim KeyK(Nmax) As Single
Dim KeyG(Nmax) As Single
Dim KeyFIO(Nmax) As String
Dim KeyB(Nmax) As Single
Dim R As TStud = New TStud()
Dim S As TBall = New TBall()
' открывается вспомогательный файл Ball.avg, находящийся в
' той же папке, что и работающий проект
Path1 = CurDir + "\Ball.avg"
F3 = New FileStream(Path1, FileMode.Create)
' читается следующая запись из основного файла базы данных
' вычисляется средний балл и созданная запись о среднем
' балле выводится во вспомогательный файл
For i = 1 To N
R.ReadFromFile(f1, i)
S.Sb = 0
For j = 1 To R.Kol
S.Sb = S.Sb + R.M(j - 1)
Next j
S.Sb = S.Sb / R.Kol
S.Kurs = R.Kurs
S.Group = R.Group
S.FIO = R.FIO
S.writeToFile(F3, i)
Next i
' вспомогательный файл закрывается
F3.Close()
End Sub
Вычисление количества студентов и среднего балла для каждой учебной группы реализовано в процедуре обработки события выбора команды меню «Отчеты Количество и средний балл».
В файле исходных данных содержатся только оценки, поэтому в этой процедуре, сначала формируется вспомогательный файл с данными о студентах (курс, группа, ФИО, средний балл). Затем вспомогательный файл упорядочивается по курсу и группе. После этого вычисляется количество записей в группе с одинаковыми значениями курса и группы, а также средний балл в этой же группе.
Алгоритм вычислений похож на алгоритм, используемый для вывода списков по группам. Во внешнем цикле перебираются курсы, во вложенном в него цикле перебираются номера групп, и в следующем по уровню вложенности цикле (для одинаковых значений курса и группы во всех записях) увеличиваются значения счетчика для количества студентов и суммы для накопления средних баллов. Значения счетчика и суммы обнуляются перед входом во внутренний цикл, после выхода из которого выводится количество студентов в группе и вычисляется и выводится средний балл в группе. Код процедуры снабжен подробными комментариями.
Private Sub mnuQueryKolItem_Click(ByVal sender As _
System.Object, ByVal e As System.EventArgs) _
Handles mnuQueryBallItem.Click
Dim Sum As Double
Dim k As Integer
Dim i As Integer
Dim Ind(Nmax) As Integer
Dim KeyK(Nmax) As Single
Dim KeyG(Nmax) As Single
Dim NK As Byte
Dim NG As Byte
Dim S As TBall = New TBall()
' вызов процедуры создания вспомогательного файла,
' содержащего информацию о среднем балле каждого студента
AverageBallCreate()
' открывается созданный вспомогательный файл
F3 = New FileStream(Path1, FileMode.Open)
' открывается вспомогательный файл kol.avg, находящийся в
' той же папке, что и работающий проект
Path2 = CurDir() + "\kol.avg"
F4 = FreeFile()
FileOpen(F4, Path2, OpenMode.Output)
' подготовка данных для сортировки по курсу и группе
For i = 1 To N
S.ReadFromFile(F3, i)
KeyK(i) = S.Kurs
KeyG(i) = S.Group
Ind(i) = i
Next i
' сортировка данных
Call Sort(KeyG, N, Ind)
Call Sort(KeyK, N, Ind)
' вывод заголовка таблицы отчета
PrintLine(F4, "Курс" + vbTab + "Группа" + vbTab + _
"Кол-во студ." + vbTab + "Сред-ний балл")
' чтение первой записи в отсортированном списке
i = 1
S.ReadFromFile(F3, Ind(i))
Do While i <= N
' фиксирование номера текущего курса
NK = S.Kurs
Do While NK = S.Kurs And i <= N
' фиксирование номера текущей группы
NG = S.Group
' начальные количество и сумма равны нулю
k = 0
Sum = 0
' вычисление количества студентов и суммы их
' средних баллов
Do While NK = S.Kurs And NG = S.Group
k = k + 1
Sum = Sum + S.Sb
i = i + 1
If i <= N Then
S.ReadFromFile(F3, Ind(i))
Else
Exit Do
End If
Loop
' вывод в файл номера курса, номера группы,
' количества студентов и среднего балла группы
PrintLine(F4, CStr(NK) + vbTab + CStr(NG) + vbTab _
+ vbTab + vbTab + CStr(k) + vbTab + vbTab _
+ vbTab + CStr(Format(Sum / k, "#0.00")))
Loop
Loop
' вспомогательные файлы закрываются
F3.Close()
FileClose(F4)
' загрузка только что созданного файла в RichTextBox1
RichTextBox1.LoadFile(Path2, _
RichTextBoxStreamType.PlainText)
richName = Path2
' показ элемента RichTextBox1 и кнопки «Сохранить отчет»
RichTextBox1.Visible = True
cmdSaveOtch.Visible = True
End Sub
13.3. Вычисление среднего балла для каждого студента
Вычисление среднего балла для каждого студента реализовано в процедуре обработки события выбора команды меню «Отчеты Вычисление среднего балла».
Собственно вычисление среднего балла алгоритмически не является трудной задачей, и она уже решена в пользовательской процедуре. В процедуре для данной команды меню будет использована эта процедура. Для вывода результата будем использовать таблицу (элемент DataGridView) , для этого добавим в проект еще одну форму, на которую поместим элемент DataGridView и кнопку, для того чтобы дать возможность пользователю не только просмотреть таблицу на экране, но и сохранить результаты в текстовом файле для дальнейшего использования.
Добавим в проект форму, дадим форме имя frmTableRez и поместим на нее элемент для отображения данных в виде таблицы (DataGridView), переименуем этот элемент, задав его имя, GridView1.
Также поместим на форму кнопку с системным именем cmdSaveOtch для сохранения отчета в виде текстового файла.
Процедура обработки события нажатия на кнопку «Сохранить отчет» имеет вид:
Private Sub cmdSaveOtch_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles cmdSaveOtch.Click
Dim i As Integer
Dim j As Integer
' запрос имени файла для сохранения отчета
With frmMenu.SaveFileDialog1
.FileName = ""
.Filter = "Все файлы (*.*)|*.*|" + _
"Текстовые файлы. (*.txt)|*.txt|" + _
"Файлы исходных данных (*.dan)|*.dan|" + _
"Файлы результатов (*.rez)|*.rez"
.FilterIndex = 2
.ShowDialog()
End With
' если имя файла не пусто,
If frmMenu.SaveFileDialog1.FileName <> "" Then
' то файл открывается
F4 = FreeFile()
FileOpen(f4, frmMenu.SaveFileDialog1.FileName, _
OpenMode.Output)
' и в него выводятся все ячейки таблицы
With GridView1
For i = 0 To .ColumnCount - 1
Print(F4, .Columns(i).Name + vbTab)
Next i
PrintLine(F4, "")
For j = 0 To .RowCount - 1
For i = 0 To .ColumnCount - 1
Print(F4, CStr(.Rows(j).Cells(i).Value) + vbTab)
Next i
PrintLine(F4, "")
Next j
End With
' файл отчета закрывается
FileClose(F4)
' сообщение об успешном завершении сохранения отчета
MsgBox("Отчет сохранен", vbOKOnly + vbInformation, _
"Сохранение")
End If
End Sub
А теперь приведем код процедуры обработки события, соответствующего выбору пункта меню «Отчеты Вычисление среднего балла». В этой процедуре предусмотрены две возможности вывода результатов: в виде, упорядоченном по курсу, группе и фамилиям студентов; или в виде, упорядоченном по курсу, группе и убыванию среднего балла. Код процедуры снабжен подробными комментариями.
Private Sub mnuQueryBallItem_Click(ByVal sender As _
System.Object, ByVal e As System.EventArgs) _
Handles mnuQueryKolItem.Click
Dim i As Integer
Dim Ind(Nmax) As Integer
Dim KeyK(Nmax) As Single
Dim KeyG(Nmax) As Single
Dim KeyFIO(Nmax) As String
Dim KeyB(Nmax) As Single
Dim S As TBall = New TBall()
Dim Button As Integer
' вызов процедуры создания вспомогательного файла,
' содержащего информацию о среднем балле каждого студента
AverageBallCreate()
' открывается созданный вспомогательный файл
F3 = New FileStream(Path1, FileMode.Open)
' подготовка данных для сортировок
For i = 1 To N
S.ReadFromFile(F3, i)
KeyK(i) = S.Kurs
KeyG(i) = S.Group
KeyFIO(i) = S.FIO
KeyB(i) = -S.Sb ' для сортировки по убыванию
Ind(i) = i
Next i
' запрос о порядке вывода отчета
Button = MsgBox("Вывод по убыванию среднего балла?", _
vbQuestion + vbYesNo, "Вывод результата")
' сортировка данных производится по курсу, группе и либо по
' ФИО, либо по среднему баллу, в зависимости ответа
' пользователя на запрос
If Button = vbYes Then
Call Sort(KeyB, N, Ind)
Call Sort(KeyG, N, Ind)
Call Sort(KeyK, N, Ind)
Else
Call SortStr(KeyFIO, N, Ind)
Call Sort(KeyG, N, Ind)
Call Sort(KeyK, N, Ind)
End If
' заполнение заголовка формы frmTableRez
frmTableRez.Text = "Просмотр файла: " + Path1
With frmTableRez.GridView1
.ColumnCount = 5
' запись названий столбцов в таблицу
.Columns(0).Name = "№"
.Columns(1).Name = "Курс"
.Columns(2).Name = "Группа"
.Columns(3).Name = "Фамилия И.О."
.Columns(4).Name = "Средний балл"
' чтение очередной записи и загрузка ее полей
' в таблицу
For i = 1 To N
S.ReadFromFile(F3, Ind(i))
' загрузка новой строки в таблицу
Dim row As String() = New String() _
{CStr(i), S.Kurs, S.Group, S.FIO, _
CStr(Format(S.Sb, "#0.00"))}
.Rows.Add(row)
Next i
End With
' вспомогательный файл закрывается
F3.Close()
' загрузка формы frmTableRez
frmTableRez.Show()
End Sub
Таким образом, нами были предусмотрены все средства, запланированные в техническом задании проекта, а значит, информационная система «Студенты» после прохождения комплекса разнообразных тестов на работоспособность и корректность обработки информации может быть внедрена на рабочем месте заказчика.