Создаем базу анекдотов
(Vb.net + XML)
1 - 2
Программа |
18 кб |
|
База (2500+) |
310 кб |
|
База (39000+) |
4700 кб |
|
В прошлых уроках я рассказывал о работе VB с файлами XML. Для примера показывал одну программу - база анекдотов. И сейчас я о ней расскажу.
Самый сложный вопрос с анекдотами и стихами, это их хранение.
Удобней всего использовать HTML, где каждому стиху своя ссылка. Но редактировать такой документ не удобно.
Если Хранить в текстовом документе - не удобно искать.
В таблицах Экселя - не удобно читать.
Тогда и пришла идея совместить все 3 способа. Для хранения выбираем файл XML, что очень похоже на хтмл, работаем с ним, как с таблицей и выводим текст .
Если у нас имеется огромная база, то нам необходимо текстовый файл с анекдотами конвертировать в файл XML.
У каждого нового анекдота будет свой порядковый номер, начиная с единицы.
По нему и будет осуществляться поиск.
Если что то не понравилось, можно удалить.
а если есть что добавить, тогда дополняем нашу базу.
Есть возможность работать с разными базами, загружая необходимую. А также сохраняя резервную копию текущей базы.
По умолчанию программа открывает базы формата АНК, что по сути является файлом XML, с определённой структурой.
После запуска программы, загружается начальная база, если ещё нет, создаётся мини база с 3 записями. Таким образом, мы можем скачать программу отдельно без каких либо баз, а затем по мере необходимости скачать нужные базы.
Меняя значения в нумераторе мы переходим к записям с данным номером. Можно выбирать пошаговый переход, ввод конкретного числа или выбор случайного номера.
После прочтения записи мы можем оценить ещё (+5, +1, 0) или удалить ее.
При удалении данная запись заменяется на последнюю, а после удаляется последняя.
Из плюшек в данной программе часы и функция поверх всех окон.
Данная программа является демонстрацией работы с файлами XML, а также пример простой базы данных.
---
Для тех, кому интересен код данной программы читаем дальше.
В нашей программе мы будем использовать 2 формы, одна основная, а другая для добавления новой записи.
Начнем с главной формы.
Для управления Удобней всего использовать менюСтрип, в него добавим такие элементы
1. Файл
новая база - создание пустой базы шаблона(предварительно сохраняем копию текущей базы)
загрузить - загрузка файл АНК (можно и XML)
сохранить - создание копии Базы
Выход - выход из программы
2. Настройки
Удалить запись - удаляет текущую запись
добавить запись - открывает окно добавления записи
поверх всех - вкл\откл функцию Поверх всех
часы - вкл\откл часы
Txt2Ank - конвертор из Txt в Анк
Далее идет навигация по запясям
3. <==, ==>, случайное - переключение между записями - вперед, назад, случайный номер.
На форме
NumericUpDown1 - Нумератор - переключение между записями
ComboBox1 - комбобокс - изменение ранга записи
Ярлык - для вывода часов
RichTextBox - для вывода записи (а так же номера и ранга), если использовать текстбокс - то форматирование не сохранится
Кроме видимых элементов добавляем:
* StatusStrip1 - в статус мы записываем общее количество записей в базе(это число выводится также в название) и полный путь и имя базы.
* Contex1 - контекстное меню для RTB - копировать запись в буфер обмена
* OpenFileDealog и SaveFileDealog - для открытия и сохранения базы
* Timer - для часов
---
На вторую форму помещаем RTB и Кнопку.
--
А теперь переходим к коду
главная форма.
Добавляем библиотеку для работы с файлами ХМЛ
Imports System.Xml
Задаем переменные, имена баз и их местонахождение.
Public Class Form1
'переменные
'баз общая
Public fileName As String = "basefull.ank"
Public fileNameBU As String
'времянка для удаления записей
Dim fileName2 As String = "tmp2.ank"
Dim fileName3 As String = "tmp3.ank"
Dim D As Date = Now 'date Переменная для времени
'При загрузке - высчитывается количество записей в начальной базе.
'загрузка формы
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
maxIDxml(fileName)
End Sub
Для того, что бы было понятней, познакомимся с главными подпрограммами.
'===========SUB=================================
' (1) Процедура записи позиции
Private Sub addProduct(ByVal pID As String, ByVal pName As String, ByVal pPrice As String, _
ByVal writer As Xml.XmlTextWriter)
writer.WriteStartElement("anek")
' Запись открывающего тега
writer.WriteStartElement("id")
' Запись обычных тексовых данных в качестве содержимого тега
writer.WriteString(pID)
' Запись закрывающего тега
writer.WriteEndElement()
writer.WriteStartElement("text")
writer.WriteString(pName)
writer.WriteEndElement()
writer.WriteStartElement("rang")
writer.WriteString(pPrice)
writer.WriteEndElement()
writer.WriteEndElement()
End Sub
' (2) новый хмл
Sub newFile()
' проверям наличие файла
If IO.File.Exists(fileName) Then
fileNameBU = Format(D, "BU yyyy_MM_dd_HHmmssfff.bu")
IO.File.Copy(fileName, fileNameBU)
End If
' Создаем объект для записи XML-данных
Dim Writer As New Xml.XmlTextWriter("basefull.ank", System.Text.Encoding.UTF8)
' Записываем объявление версии XML
Writer.WriteStartDocument(True)
' Указываем, что XML-документ должен быть отформатирован
Writer.Formatting = Xml.Formatting.Indented
' Задаем 2 пробела для выделения вложенных данных
Writer.Indentation = 2
' Записываем открывающий тег
Writer.WriteStartElement("Table")
' Вызываем процедуру записи позиции
addProduct(1, "Родил", 0, Writer)
addProduct(2, "Колобок повесился", 0, Writer)
addProduct(3, "Бедный гаишник", 0, Writer)
' Закрываем тег
Writer.WriteEndElement()
' Заканчиваем запись (закрываем все не закрытые элементы)
Writer.WriteEndDocument()
' Закрываем файл
Writer.Close()
End Sub
' (3) получение последнего (наибольшего) номерa ID
Sub maxIDxml(files As String)
If IO.File.Exists(fileName) Then
' "Файл уже существует"
Else
newFile()
End If
Dim xdoc As XDocument = XDocument.Load(files)
Dim maxId = 0
For Each xe As XElement In xdoc.Element("Table").Elements("anek")
If xe.Element("id").Value > maxId Then
maxId += 1
End If
Next
Me.Text = Str(maxId)
ToolStripStatusLabel1.Text = fileName
ToolStripStatusLabel2.Text = maxId
End Sub
' (4) показывает текст по номеру ID (из нумератора)
Sub element1()
Dim nnn = NumericUpDown1.Value
maxIDxml(fileName)
Dim maxId_ = Val(Me.Text)
NumericUpDown1.Maximum = maxId_
Dim xdoc As XDocument = XDocument.Load(fileName)
rtxOtvet.Text = ""
For Each xe As XElement In xdoc.Element("Table").Elements("anek")
If xe.Element("id").Value = nnn Then
rtxOtvet.Text += xe.Elements("id").Value + " ) "
rtxOtvet.Text += xe.Elements("text").Value + " ранг "
rtxOtvet.Text += xe.Elements("rang").Value + vbCrLf
ComboBox1.Text = xe.Elements("rang").Value
End If
Next
End Sub
' (5-1) удаление (1)
Sub del1()
'------1
'значение из последнего записываем в удаленный.
'загрузка документа
Dim xdoc As XDocument = XDocument.Load(fileName)
'из последней сохраняем в переменные
Dim maxiZap = Val(Me.Text)
Dim nameMax = ""
Dim priceMax = ""
For Each xe As XElement In xdoc.Element("Table").Elements("anek")
If xe.Element("id").Value = maxiZap Then
nameMax = xe.Elements("text").Value
priceMax = xe.Elements("rang").Value
End If
Next
'из переменных во 2
Dim etot = NumericUpDown1.Value
For Each xe As XElement In xdoc.Element("Table").Elements("anek")
If xe.Element("id").Value = etot Then
xe.Elements("text").Value = nameMax
xe.Elements("rang").Value = priceMax
xdoc.Save(fileName2)
End If
Next
'---------
'удаление записи последней
'загрузка документа
Dim xdoc2 As XDocument = XDocument.Load(fileName2)
Dim id = maxiZap
On Error Resume Next
For Each xe As XElement In xdoc.Element("Table").Elements("anek")
If xe.Element("id").Value = id Then
xe.RemoveAll()
xdoc.Descendants("anek").Where(Function(el) el.Attribute("id").Value.Equals(Str(id))).Remove()
xdoc.Save(fileName2)
Exit Sub
End If
Next
End Sub
' (5-2) удаление (2) - подчищаем файл от записи " <anek />"
Sub delOstatok()
'-----------2
Dim mass() = IO.File.ReadAllLines(fileName2, System.Text.Encoding.Default)
Dim max = mass.Length
Dim massTMP(max)
Dim File As IO.StreamWriter
File = IO.File.CreateText(fileName3)
For i = 0 To max - 1
If mass(i) <> " <anek />" Then
massTMP(i) = mass(i)
File.WriteLine(massTMP(i))
End If
Next
File.Close()
End Sub
' (5-3) удаление (3) - удаляем все временные файлы и заменяем основной файл на измененный
Sub delTempFile()
'-----------------3
IO.File.Delete(fileName)
IO.File.Delete(fileName2)
IO.File.Copy(fileName3, fileName)
IO.File.Delete(fileName3)
End Sub
' (6) смена ранга
Sub RANG(rx As Integer)
Dim nnn = NumericUpDown1.Value
Dim xdoc As XDocument = XDocument.Load(fileName)
For Each xe As XElement In xdoc.Element("Table").Elements("anek")
If xe.Element("id").Value = nnn Then
xe.Elements("rang").Value = rx
xdoc.Save(fileName)
End If
Next
element1()
End Sub
Самая сложная и непонятная процедура - тк, перед ее использованием необходимо привести текстовый файл в необходимый вид.
(подробней в видео)
' (8) импорт - конвертер тхт а анк
Sub importFromTXT(filestxt As String, fileAnk As String)
' Dim r As New Random
Dim bk
Dim masStrFull()
Dim mString() = IO.File.ReadAllLines(filestxt, System.Text.Encoding.Default) 'Загоняем текст построчно в массив
Dim miniStr()
Dim x = 0
Dim xz = 0
Dim numbers = 1
'из тхт в хмл
' Создаем объект для записи XML-данных
Dim Writer As New Xml.XmlTextWriter(fileAnk, System.Text.Encoding.UTF8)
' Записываем объявление версии XML
Writer.WriteStartDocument(True)
' Указываем, что XML-документ должен быть отформатирован
Writer.Formatting = Xml.Formatting.Indented
' Задаем 2 пробела для выделения вложенных данных
Writer.Indentation = 2
' Записываем открывающий тег
Writer.WriteStartElement("Table")
' Вызываем процедуру записи позиции
'-----------
'-создание файла хмл из тхт
bk = mString.Length
ReDim masStrFull(bk)
ReDim miniStr(bk)
'-весь массив строк проходит проверку
'-между *** это отдельный элемент нового массива
For i = 0 To (bk - 1)
If mString(i) = " *** " Then
miniStr(xz) = mString(i)
xz += 1
End If
masStrFull(xz) += mString(i) + vbNewLine
Next i
'- теперь каждый новый элемент записываем в файл
'-(если он не равен пустой строке)
For j = 0 To (masStrFull.Length - 1)
If masStrFull(j) <> "" Then
addProduct(j, masStrFull(j), "0", Writer)
End If
Next
' Закрываем тег
Writer.WriteEndElement()
' Заканчиваем запись (закрываем все не закрытые элементы)
Writer.WriteEndDocument()
' Закрываем файл
Writer.Close()
End Sub
'=========END==SUB=================================
После описания основный процедур переходим к меню
Читать дальше ->
1 - 2
Смотреть видео
В начало
|