- •Министерство образования и науки Российской федерации
- •Предисловие
- •Часть I
- •Описание предметной области
- •2. Моделирование данных
- •3. Представление данных
- •Часть II
- •4. Предварительные замечания
- •5. Постановка задачи
- •6. Структура проекта
- •7. Создание меню
- •8. Пользовательские модули
- •9. Работа с файлами
- •10. Ввод и редактирование данных
- •11. Работа с существующим файлом
- •12. Сортировка данных
- •13. Задачи, решаемые в информационной системе
- •Часть III
- •14. Общие требования
- •15. Технические задания к проектам
- •Часть I. Проектирование информационной системы 4
- •Часть II. Реализация информационной системы «Студенты» 13
- •Часть III. Проекты для самостоятельной разработки 80
11. Работа с существующим файлом
11.1. Открытие файла
Для открытия файла необходимо выполнить команду «Файл Открыть». Ей соответствует процедура обработки события, приведенная ниже.
Private Sub mnuFileOpenItem_Click(ByVal sender As _
System.Object, ByVal e As System.EventArgs) _
Handles mnuFileOpenItem.Click
Dim R As TStud = New TStud()
Dim Sp As TSpec = New TSpec()
Dim i As Integer
Decl.Path = PathUntitled
' запрос имени файла базы данных
With OpenFileDialog1
.FileName = ""
.Filter = "Все файлы (*.*)|*.*|" + _
"текстовые файлы(*.txt)|*.txt|" + _
"файлы исх. данных(*.dan)|*.dan|" + _
"файлы результата (*.rez)|*.rez"
.FilterIndex = 3
.ShowDialog()
Decl.Path = .FileName
If Decl.Path <> "" Then
PathSpec = Mid(Decl.Path, 1, Len(Decl.Path) - 4) + _
".spe"
End If
End With
' если имя файла не пусто
If Decl.Path <> "" Then
' файл открывается
f1 = New FileStream(Decl.Path, FileMode.Open)
' определяется количество записей базы данных
N = f1.Length \ R.len
' аналогично открываем файл справочник для
' специальности
F1_sp = New FileStream(PathSpec, FileMode.Open)
NSpec = F1_sp.Length \ Sp.len
Pos = 1
frmInputEdit.Text = "Файл: " + Decl.Path
' все пункты меню становятся активными
mnuView.Enabled = True
mnuSort.Enabled = True
mnuSearch.Enabled = True
mnuQuery.Enabled = True
mnuFileSaveItem.Enabled = True
mnuFileSaveAsItem.Enabled = True
mnuFileCloseItem.Enabled = True
mnuFileDeleteItem.Enabled = True
End If
' инициализация индексного массива Ind, который будет
' использоваться для сортировки данных, и массива Del
' для пометки удаляемых записей
For i = 1 To Nmax
Ind(i) = i
Del(i) = 0
Next i
End Sub
При выборе пункта меню «Файл Открыть» появится диалоговое окно, в котором пользователь может выбрать файл, который нужно открыть. Полное имя файла будет записано в переменную Path модуля Declar и в том случае, если путь существует, производится чтение из выбранного файла. Файл-справочник для специальности имеет то же самое имя, что и основной файл. Отличие состоит только в расширениях этих файлов. Кроме этого, все пункты пользовательского меню становятся доступными. Для того чтобы просмотреть содержимое файла базы данных, нужно в строке меню выбрать пункт меню «Просмотр» и в нем один из возможных вариантов просмотра.
11.2. Просмотр файла базы данных
Файл базы данных можно просмотреть, используя форму frmInputEdit. Для этого необходимо написать еще одну пользовательскую процедуру для данной формы (не забудьте для этого перейти в окно кода формы frmInputEdit). Это процедура с именем View_Form, которая должна загрузить данные и вывести первую запись в уже известном нам виде на форме frmInputEdit. Ниже приведен код этой процедуры.
Public Sub view_form()
Dim R As TStud = New TStud()
' загрузка формы frmInputEdit
frmMenu.Enabled = False
Me.Enabled = True
Me.Show()
' загрузка Файла-справочника по специальности, выполнение
' пользовательской процедуры
Call LoadSprav()
' определение количества записей в основном файле базы
N = f1.Length \ R.len
' если записей нет, то вызов процедуры для заполнения
' новой записи
If N = 0 Then
Call ShowNewZap()
cmdAdd.Enabled = True
Else
' иначе производится загрузка и вывод первой записи
Pos = 1
vscrZap.Value = Pos
Call ShowZap(Pos)
' кнопки перемещения по записям становятся активными
cmdTop.Enabled = True
cmdBottom.Enabled = True
cmdForward.Enabled = True
cmdBackUp.Enabled = True
' кнопки «Изменить» и «Обновить» становятся активными
cmdEdit.Enabled = True
cmdPack.Enabled = True
' кнопка «Добавить» становится неактивной
cmdAdd.Enabled = False
' фокус передается на кнопку «Выход»
cmdExit.Focus()
End If
End Sub
В данной процедуре открытый файл проверяется на пустоту и если он пуст (т.е. файл существует, но в нем нет ни одной записи данных), то вызывается процедура создания нового файла-базы данных (процедура ShowNewZap). Если файл не является пустым, то вызывается процедура ShowZap для вывода в форму первой записи, а так же делаются активными кнопки, позволяющие перемещаться по записям базы данных.
Для просмотра файла базы данных с использованием формы frmInputEdit необходимо в форме frmMenu написать процедуру обработки события выбора команды меню «Просмотр Форма», которая содержит вызов пользовательской процедуры View_Form, принадлежащей форме frmInputEdit:
Private Sub mnuViewFormItem_Click(ByVal sender As _
System.Object, ByVal e As System.EventArgs) _
Handles mnuViewFormItem.Click
‘ вызов процедуры загрузки формы
frmInputEdit.View_Form
End Sub
При просмотре данных в виде формы экранная форма содержит данные одной записи файла базы данных. Но иногда необходимо иметь возможность просмотреть данные файла в виде таблицы, в столбцах которой выводятся значения полей записей файла.
Для вывода данных в виде таблицы добавим в проект еще одну форму, дадим этой форме имя frmTableReadOnly и поместим на нее элемент для отображения данных в виде таблицы (DataGridView), переименуем этот элемент, задав его имя, GridView1.
Процедура обработки события выбора пункта меню «Просмотр Таблица» имеет вид:
Private Sub mnuViewTableItem_Click(ByVal sender As _
System.Object, ByVal e As System.EventArgs) _
Handles mnuViewTableItem.Click
Dim i As Integer
Dim j As Integer
Dim R As TStud = New TStud()
Dim sp As TSpec = New TSpec()
With frmTableReadOnly.GridView1
' установка количества строк таблицы и ширины столбцов
.ColumnCount = 12
' запись названий столбцов в таблицу
.Columns(0).Name = "Номер"
.Columns(1).Name = "Курс"
.Columns(2).Name = "Группа"
.Columns(3).Name = "Специальность"
.Columns(4).Name = "ФИО"
.Columns(5).Name = "Пол"
.Columns(6).Name = "Кол-во оценок"
For j = 1 To 5
.Columns(j + 6).Name = "Оц.№ " + CStr(j)
Next j
' чтение очередной записи и загрузка ее полей
' в таблицу
For i = 1 To N
R.ReadFromFile(f1, Ind(i))
' чтение специальности по ее коду
j = frmInputEdit.FindSpecIndex(R.Spec)
sp.ReadFromFile(F1_sp, j)
' загрузка новой строки в таблицу
Dim row As String() = New String() _
{CStr(i), R.Kurs, R.Group, _
Trim(sp.Number) + " - " + Trim(sp.Name), Trim(R.FIO), _
R.Pol, R.Kol, R.M(0), R.M(1), R.M(2), R.M(3), R.M(4)}
.Rows.Add(row)
Next i
End With
' изменение заголовка формы
frmTableReadOnly.Text = "Просмотр файла: " + Decl.Path
' загрузка формы frmTableReadOnly
frmTableReadOnly.Show()
End Sub
На этом месте рекомендуется протестировать создаваемый проект. Особое внимание следует уделить корректности чтения записей из файла и вывода их в таблицу и элементы формы.
11.3. Изменение и удаление записей в файле базы данных
Эти действия предусмотрены в форме для ввода и редактирования (форма frmInputEdit) и для их выполнения используются кнопки «Изменить» (cmdEdit) и «Обновить» (cmdPack).
Для корректировки содержимого полей текущей записи используется кнопка «Изменить». Отредактировав нужные поля некоторой записи, нажимаем кнопку «Изменить» и все изменения для текущей записи вносятся в базу данных. Обработка события нажатия на кнопку «Изменить»:
Private Sub cmdEdit_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles cmdEdit.Click
Dim R As TStud = New TStud()
' производится заполнение всех полей записи,
' включая измененные
R.FIO = txtFIO.Text
R.Kurs = CByte(txtKurs.Text)
R.Group = CByte(txtGroup.Text)
R.Kol = CByte(txtKol.Text)
R.Pol = ComPol.SelectedIndex
R.Spec = FindSpecCode(ComSpec.SelectedIndex)
R.DataR = txtDR.Value
R.M(0) = CByte(txtM1.Text)
R.M(1) = CByte(txtM2.Text)
If R.Kol > 2 Then
If txtM3.Text <> "" Then
R.M(2) = CByte(txtM3.Text)
Else
MsgBox("Оценка №3 должна являться цифрой!", vbOKOnly + _
vbExclamation, "Ошибка")
Exit Sub
End If
End If
If R.Kol > 3 Then
If txtM4.Text <> "" Then
R.M(3) = CByte(txtM4.Text)
Else
MsgBox("Оценка №4 должна являться цифрой!", vbOKOnly + _
vbExclamation, "Ошибка")
Exit Sub
End If
End If
If R.Kol > 4 Then
If txtM5.Text <> "" Then
R.M(4) = CByte(txtM5.Text)
Else
MsgBox("Оценка №5 должна являться цифрой!", vbOKOnly + _
vbExclamation, "Ошибка")
Exit Sub
End If
End If
' запись вносится в файл на то место,
' на котором находилась старая запись
R.writeToFile(f1, Pos)
MsgBox("Изменение выполнено успешно!")
End Sub
С файлом исходных данных связан массив Del, который по умолчанию заполнен нулями. Удаляемым записям соответствует значение, равное единице. Для того чтобы удалить некоторые записи, необходимо отметить их на форме frmInputEdit, используя флажок-переключатель Check1, затем нажать на кнопку «Обновить». Для элемента Check1 и кнопки «Обновить» процедуры обработки события Click – щелчка левой кнопки мыши на этих объектах имеют вид:
Private Sub Check1_CheckedChanged(ByVal sender As _
System.Object, ByVal e As System.EventArgs) _
Handles Check1.CheckedChanged
' отмечается на удаление запись с номером Pos
If Check1.Checked Then
Del(Ind(Pos)) = 1
Else
Del(Ind(Pos)) = 0
End If
End Sub
Private Sub cmdPack_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles cmdPack.Click
Dim i As Integer
Dim j As Integer = 1
Dim R As TStud = New TStud()
' открывается вспомогательный файл
F2 = New FileStream(PathTemp, FileMode.Create)
' из основного файла во вспомогательный переписываются
' записи, которые не нужно удалять
For i = 1 To N
R.ReadFromFile(f1, i)
If Del(i) = 0 Then
R.writeToFile(F2, j)
j = j + 1
End If
Next i
' закрываются файлы, и происходит сохранение
' вспомогательного файла под именем основного
' файла базы данных
f1.Close()
F2.Close()
Kill(Decl.Path)
Rename(PathTemp, Decl.Path)
' открывается новый основной (рабочий файл) базы
f1 = New FileStream(Decl.Path, FileMode.Open)
N = f1.Length \ R.len
' возвращение исходных значений массивам Ind и Del
For i = 1 To Nmax
Ind(i) = i
Del(i) = 0
Next i
' вывод первой записи данных
Pos = 1
If N = 0 Then
Call ShowNewZap()
Else
Call ShowZap(Pos)
End If
MsgBox("Обновление выполнено успешно!")
End Sub
Таким образом, для удаления записей используется временный файл, куда переносятся все те записи, которые не должны быть удалены (для них значение Del(i) равно нулю), затем исходный файл удаляется, а временный файл переименовывается.
Новый этап тестирования проекта с целью проверки его работоспособности при добавленных возможностях.
11.4. Сохранение и удаление файлов
Мы описали возможности ввода, просмотра и редактирования данных. Добавим несколько процедур, обрабатывающие события выбора следующих пунктов меню: «Файл Сохранить как», «Файл Закрыть» и «Файл Удалить».
При выборе данного пункта меню «Файл Сохранить как» основной файл базы (файл с данными) должен быть сохранен под новым именем, а затем, должно быть открыто это новое сохранение.
Private Sub mnuFileSaveAsItem_Click(ByVal sender As _
System.Object, ByVal e As System.EventArgs) _
Handles mnuFileSaveAsItem.Click
Dim R As TStud = New TStud()
Dim Sp As TSpec = New TSpec()
Dim PathOld As String
Dim PathOldSpec As String
' запоминаются имена основного файла базы данных и
' Файла-справочника
PathOld = Decl.Path
PathSpec = Mid(Decl.Path, 1, Len(Decl.Path) - 4) + ".spe"
PathOldSpec = PathSpec
' запрос имени нового файла базы
With Me.SaveFileDialog1
.FileName = ""
.Filter = "Все файлы (*.*)|*.*|" + _
"Текстовые файлы. (*.txt)|*.txt|" + _
"Файлы исходных данных (*.dan)|*.dan|" + _
"Файлы результатов (*.rez)|*.rez"
.FilterIndex = 3
.ShowDialog()
Decl.Path = .FileName
If Decl.Path <> "" Then
PathSpec = Mid(Decl.Path, 1, Len(Decl.Path) - 4) + _
".spe"
End If
End With
' если имя нового основного файла пусто, то рабочие файлы
' остаются прежними и производится выход из процедуры
If Decl.Path = "" Then
Decl.Path = PathOld
PathSpec = PathOldSpec
Exit Sub
End If
' иначе файлы закрывается и производится копирование
' рабочих файлов
Close()
If Not (Dir(Decl.Path) = "") Then
Kill(Decl.Path)
Kill(PathSpec)
End If
FileCopy(PathOld, Decl.Path)
FileCopy(PathOldSpec, PathSpec)
' после копирования открываются новые файлы
f1 = New FileStream(Decl.Path, FileMode.Open)
F1_sp = New FileStream(PathSpec, FileMode.Open)
frmInputEdit.Text = "Файл: " + Decl.Path
End Sub
При выборе пункта меню «Файл Закрыть» все открытые файлы должны быть закрыты и все пункты меню, недоступные в начале работы снова должны снова стать недоступными.
Private Sub mnuFileCloseItem_Click(ByVal sender As _
System.Object, ByVal e As System.EventArgs) _
Handles mnuFileCloseItem.Click
' закрываются все файлы, открытые в процессе работы
CloseAllFiles()
' пункты меню, которые были неактивными в начале
' работы программы, снова становятся неактивными
mnuFileSaveItem.Enabled = False
mnuFileSaveAsItem.Enabled = False
mnuFileCloseItem.Enabled = False
mnuFileDeleteItem.Enabled = False
mnuView.Enabled = False
mnuSort.Enabled = False
mnuQuery.Enabled = False
mnuSearch.Enabled = False
End Sub
При выборе пункта меню «Файл Удалить» основной файл базы (файл с данными) должен быть удален, и все пункты меню, недоступные в начале работы снова должны снова стать недоступными.
Private Sub mnuFileDeleteItem_Click(ByVal sender As _
System.Object, ByVal e As System.EventArgs) _
Handles mnuFileDeleteItem.Click
Dim Button As Integer
' запрос подтверждения на удаление
Button = MsgBox("Действительно удалить?", vbYesNo + _
vbQuestion, "Удаление файла")
' в случае подтверждения вызывается процедура закрытия
' и удаляется основной файл базы данных
If Button = vbYes Then
Call mnuFileCloseItem_Click(sender, e)
Kill(Decl.Path)
Kill(PathSpec)
End If
End Sub
На этом месте снова необходимо протестировать проект на работоспособность и корректность работы. Особое внимание следует уделить взаимодействию различных компонентов приложения.