20-bo‘lim
Amaliy loyiha - xarajatlar daftari
O'rganilgan hamma narsani birlashtirib, xarajatlarni yozadigan, saralaydigan, hisobot beradigan va JSON ga saqlaydigan to'liq konsol dasturini yozamiz.
Ushbu bo‘lim mundarijasi
Endi barcha bo'limlarni birlashtiramiz. Yozadigan dasturimiz - xarajatlar daftari: u xarajatlarni yozadi, toifalar bo'yicha hisobot beradi va ma'lumotni faylga saqlaydi.
Dasturni bosqichma-bosqich quramiz va har bir bosqichni ishga tushirib ko'ramiz.
1-bosqich: toifalar va model #
Avval ma'lumot shaklini belgilaymiz. Bu ta'riflar butun bob davomida ishlatiladi:
Public Enum Toifa
Oziq
Transport
Kommunal
Kiyim
Boshqa
End Enum
Public Class Xarajat
Public Property Tavsif As String
Public Property Summa As Decimal
Public Property Toifasi As Toifa
Public Property Sana As Date
Public Sub New()
End Sub
Public Sub New(tavsif As String, summa As Decimal,
toifasi As Toifa, sana As Date)
Me.Tavsif = tavsif
Me.Summa = summa
Me.Toifasi = toifasi
Me.Sana = sana
End Sub
Public Overrides Function ToString() As String
Return $"{Sana:yyyy-MM-dd} {Tavsif.PadRight(18)}" &
$"{Toifasi.ToString().PadRight(11)}{Summa,12:N0}"
End Function
End Class
Sinab ko'ramiz:
Module Dastur
Sub Main()
Dim x As New Xarajat("Non va sut", 45000D, Toifa.Oziq,
New Date(2026, 9, 1))
Console.WriteLine(x)
End Sub
End Module
2026-09-01 Non va sut Oziq 45,000
Diqqat qiling:
Public Sub New()- parametrsiz konstruktor JSON uchun kerak.{Summa,12:N0}- o'ngga tekislab, minglik ajratgich bilan.Toifasi.ToString()- 13-bo'limdagi qoida:Enumnomi uchunToStringshart.
2-bosqich: daftar sinfi #
Endi xarajatlarni saqlaydigan va qoidalarni tekshiradigan sinf kerak. U ham keyingi misollarda ishlatiladi:
Public Class NotogriSummaException
Inherits Exception
Public Sub New(summa As Decimal)
MyBase.New($"Summa musbat bo'lishi kerak, berilgani: {summa}")
End Sub
End Class
Public Class Daftar
Private ReadOnly _xarajatlar As New List(Of Xarajat)
Public ReadOnly Property Soni As Integer
Get
Return _xarajatlar.Count
End Get
End Property
Public Sub Qoshish(x As Xarajat)
If x Is Nothing Then
Throw New ArgumentNullException(NameOf(x))
End If
If x.Summa <= 0 Then
Throw New NotogriSummaException(x.Summa)
End If
_xarajatlar.Add(x)
End Sub
Public Function Hammasi() As List(Of Xarajat)
Return New List(Of Xarajat)(_xarajatlar)
End Function
Public Function Jami() As Decimal
Return _xarajatlar.Sum(Function(x) x.Summa)
End Function
Public Function ToifaBoyicha(t As Toifa) As List(Of Xarajat)
Return (From x In _xarajatlar
Where x.Toifasi = t
Order By x.Sana
Select x).ToList()
End Function
End Class
Endi uni sinab ko'ramiz:
Module Dastur
Sub Main()
Dim d As New Daftar()
d.Qoshish(New Xarajat("Non va sut", 45000D, Toifa.Oziq,
New Date(2026, 9, 1)))
d.Qoshish(New Xarajat("Metro", 8000D, Toifa.Transport,
New Date(2026, 9, 2)))
d.Qoshish(New Xarajat("Go'sht", 120000D, Toifa.Oziq,
New Date(2026, 9, 3)))
Console.WriteLine($"Yozuvlar: {d.Soni}")
Console.WriteLine($"Jami: {d.Jami():N0} so'm")
Try
d.Qoshish(New Xarajat("Xato", -500D, Toifa.Boshqa, Date.Today))
Catch ex As NotogriSummaException
Console.WriteLine($"Rad etildi: {ex.Message}")
End Try
End Sub
End Module
Yozuvlar: 3
Jami: 173,000 so'm
Rad etildi: Summa musbat bo'lishi kerak, berilgani: -500
Hammasi() ichki ro'yxatning nusxasini qaytaradi. Aks holda
tashqaridan d.Hammasi().Clear() deb yozib, daftarni buzib
qo'yish mumkin edi.
3-bosqich: hisobot #
Module Hisobotlar
Public Function ToifalarHisoboti(d As Daftar) As String
Dim jami As Decimal = d.Jami()
If jami = 0 Then
Return "Ma'lumot yo'q"
End If
Dim qatorlar = From x In d.Hammasi()
Group x By Kalit = x.Toifasi Into Guruh = Group
Select Toifasi = Kalit,
Summa = Guruh.Sum(Function(y) y.Summa),
Soni = Guruh.Count()
Order By Summa Descending
Dim quruvchi As New System.Text.StringBuilder()
quruvchi.AppendLine("TOIFA SONI SUMMA ULUSH")
quruvchi.AppendLine(New String("-"c, 44))
For Each q In qatorlar
Dim ulush As Decimal = q.Summa / jami
quruvchi.AppendLine(
$"{q.Toifasi.ToString().PadRight(13)}{q.Soni,5}" &
$"{q.Summa,13:N0}{ulush,8:P0}")
Next
quruvchi.AppendLine(New String("-"c, 44))
quruvchi.Append($"{"JAMI".PadRight(13)}{d.Soni,5}{jami,13:N0}")
Return quruvchi.ToString()
End Function
End Module
Module Dastur
Sub Main()
Dim d As New Daftar()
d.Qoshish(New Xarajat("Non va sut", 45000D, Toifa.Oziq,
New Date(2026, 9, 1)))
d.Qoshish(New Xarajat("Metro", 8000D, Toifa.Transport,
New Date(2026, 9, 2)))
d.Qoshish(New Xarajat("Go'sht", 120000D, Toifa.Oziq,
New Date(2026, 9, 3)))
d.Qoshish(New Xarajat("Svet puli", 90000D, Toifa.Kommunal,
New Date(2026, 9, 5)))
Console.WriteLine(ToifalarHisoboti(d))
End Sub
End Module
TOIFA SONI SUMMA ULUSH
--------------------------------------------
Oziq 2 165,000 63%
Kommunal 1 90,000 34%
Transport 1 8,000 3%
--------------------------------------------
JAMI 4 263,000
Bu yerda Group By, Order By, Sum, Count, StringBuilder va
format qoidalari birgalikda ishladi.
4-bosqich: faylga saqlash #
Imports System.IO
Imports System.Text.Json
Module Saqlagich
Private ReadOnly Sozlama As New JsonSerializerOptions With {
.WriteIndented = True
}
Public Sub Saqlash(d As Daftar, yol As String)
File.WriteAllText(yol, JsonSerializer.Serialize(d.Hammasi(), Sozlama))
End Sub
Public Function Yuklash(yol As String) As Daftar
Dim d As New Daftar()
If Not File.Exists(yol) Then
Return d
End If
Try
Dim royxat = JsonSerializer.Deserialize(Of List(Of Xarajat))(
File.ReadAllText(yol))
For Each x As Xarajat In If(royxat, New List(Of Xarajat))
d.Qoshish(x)
Next
Catch ex As JsonException
Console.WriteLine("Fayl buzilgan, bo'sh daftar ochildi")
End Try
Return d
End Function
End Module
Module Dastur
Sub Main()
Dim yol As String = "xarajatlar.json"
Dim d As New Daftar()
d.Qoshish(New Xarajat("Non va sut", 45000D, Toifa.Oziq,
New Date(2026, 9, 1)))
d.Qoshish(New Xarajat("Metro", 8000D, Toifa.Transport,
New Date(2026, 9, 2)))
Saqlash(d, yol)
Console.WriteLine($"Saqlandi: {d.Soni} ta yozuv")
Dim qayta As Daftar = Yuklash(yol)
Console.WriteLine($"Yuklandi: {qayta.Soni} ta yozuv")
Console.WriteLine($"Jami: {qayta.Jami():N0}")
File.WriteAllText(yol, "bu JSON emas")
Dim buzuq As Daftar = Yuklash(yol)
Console.WriteLine($"Buzuq fayldan keyin: {buzuq.Soni} ta yozuv")
File.Delete(yol)
End Sub
End Module
Saqlandi: 2 ta yozuv
Yuklandi: 2 ta yozuv
Jami: 53,000
Fayl buzilgan, bo'sh daftar ochildi
Buzuq fayldan keyin: 0 ta yozuv
Diqqat: buzuq fayl dasturni to'xtatmadi. Bu yaxshi dasturning belgisi - kutilmagan ma'lumot kelsa ham, u ishlashda davom etadi.
5-bosqich: qidiruv va filtr #
Module Dastur
Sub Main()
Dim d As New Daftar()
d.Qoshish(New Xarajat("Non va sut", 45000D, Toifa.Oziq,
New Date(2026, 9, 1)))
d.Qoshish(New Xarajat("Metro", 8000D, Toifa.Transport,
New Date(2026, 9, 2)))
d.Qoshish(New Xarajat("Go'sht", 120000D, Toifa.Oziq,
New Date(2026, 9, 3)))
d.Qoshish(New Xarajat("Taksi", 35000D, Toifa.Transport,
New Date(2026, 9, 4)))
Console.WriteLine("-- Oziq toifasi --")
For Each x As Xarajat In d.ToifaBoyicha(Toifa.Oziq)
Console.WriteLine(x)
Next
Console.WriteLine("-- 30 mingdan qimmat --")
Dim qimmat = d.Hammasi().
Where(Function(x) x.Summa > 30000D).
OrderByDescending(Function(x) x.Summa)
For Each x As Xarajat In qimmat
Console.WriteLine($"{x.Tavsif}: {x.Summa:N0}")
Next
Console.WriteLine("-- Eng qimmati --")
Dim eng = d.Hammasi().OrderByDescending(Function(x) x.Summa).First()
Console.WriteLine($"{eng.Tavsif} - {eng.Summa:N0}")
End Sub
End Module
-- Oziq toifasi --
2026-09-01 Non va sut Oziq 45,000
2026-09-03 Go'sht Oziq 120,000
-- 30 mingdan qimmat --
Go'sht: 120,000
Non va sut: 45,000
Taksi: 35,000
-- Eng qimmati --
Go'sht - 120,000
Interaktiv menyu #
Haqiqiy dasturda foydalanuvchidan ma'lumot olinadi. Bu darslikda misollar avtomatik tekshirilgani uchun menyuni ishga tushira olmaymiz, lekin uning shakli quyidagicha:
Module Dastur
Sub Main()
Dim yol As String = "xarajatlar.json"
Dim d As Daftar = Yuklash(yol)
Do
Console.WriteLine()
Console.WriteLine("1 - Xarajat qo'shish")
Console.WriteLine("2 - Hammasini ko'rish")
Console.WriteLine("3 - Hisobot")
Console.WriteLine("0 - Chiqish")
Console.Write("Tanlang: ")
Dim tanlov As String = Console.ReadLine()
Select Case tanlov
Case "1"
QoshishMenyusi(d)
Case "2"
For Each x As Xarajat In d.Hammasi()
Console.WriteLine(x)
Next
Case "3"
Console.WriteLine(ToifalarHisoboti(d))
Case "0"
Saqlash(d, yol)
Console.WriteLine("Saqlandi. Xayr!")
Exit Do
Case Else
Console.WriteLine("Noto'g'ri tanlov")
End Select
Loop
End Sub
Sub QoshishMenyusi(d As Daftar)
Console.Write("Tavsif: ")
Dim tavsif As String = Console.ReadLine()
Console.Write("Summa: ")
Dim summa As Decimal
If Not Decimal.TryParse(Console.ReadLine(), summa) Then
Console.WriteLine("Summa noto'g'ri kiritildi")
Exit Sub
End If
Try
d.Qoshish(New Xarajat(tavsif, summa, Toifa.Boshqa, Date.Today))
Console.WriteLine("Qo'shildi")
Catch ex As NotogriSummaException
Console.WriteLine(ex.Message)
End Try
End Sub
End Module
Yuqoridagi menyuda Decimal.TryParse ishlatilgani bejiz emas.
Foydalanuvchi "salom" deb yozsa, CDec dasturni to'xtatadi.
TryParse esa xato bermaydi - shunchaki False qaytaradi va siz
xushmuomala xabar chiqara olasiz.
Qoida: klaviaturadan yoki fayldan kelgan har qanday ma'lumotga ishonmang.
Dastur tuzilishi #
Qaysi bo'lim qayerda ishlatildi #
| Bo'lim | Loyihada |
|---|---|
| 3 - Turlar | Decimal summa uchun, Date sana uchun |
| 5 - Satrlar | PadRight, N0, P0 formatlari |
| 6 - Shartlar | Select Case menyuda |
| 7 - Sikllar | For Each ro'yxatlar bo'ylab |
| 9 - Kolleksiyalar | List(Of Xarajat) |
| 10 - Protseduralar | Qoshish, Jami, Hisobot |
| 11 - Sinflar | Xarajat, Daftar |
| 13 - Enum/Module | Toifa, Saqlagich, Hisobotlar |
| 14 - Xatoliklar | NotogriSummaException, Try/Catch |
| 15 - Fayl/JSON | Saqlash, Yuklash |
| 16 - LINQ | Group By, Where, OrderBy |
| 18 - Nothing | If(royxat, New List...) |
- Loyihani o'z kompyuteringizda yig'ib, ishga tushiring.
Toifaga yangi qiymat qo'shing va hisobotni tekshiring.- Sana bo'yicha filtrlaydigan metod yozing.
- Oylik o'rtacha xarajatni hisoblang.
- Eng ko'p pul ketgan toifani topadigan funksiya yozing.
- Xarajatni o'chirish imkonini qo'shing.
- Tavsif bo'yicha qidiruv qo'shing (katta-kichik harfga qarasin).
- Hisobotni matn fayliga saqlaydigan metod yozing.
- Summa 0 bo'lganda nima bo'lishini tekshiring va xabarni yaxshilang.
- Dasturga oylik byudjet chegarasini qo'shing: chegaradan oshsa ogohlantirsin.
Xulosa #
- Katta dastur kichik qismlardan quriladi: ma'lumot (
Xarajat), qoidalar (Daftar), hisobot, saqlash - har biri alohida. - Ichki ro'yxatni tashqariga berayotganda nusxa qaytaring.
- JSON uchun sinfda parametrsiz konstruktor va
Public Propertybo'lishi shart. - Buzuq fayl yoki noto'g'ri kiritish dasturni to'xtatmasligi kerak.
Group By+Sum+Order By- hisobotning asosiy uchligi.- Foydalanuvchidan kelgan ma'lumot har doim
TryParsebilan o'qiladi.
Darslik yakuni #
Tabriklaymiz - siz Visual Basic ning asoslarini o'rgandingiz:
- O'zgaruvchilar, turlar va operatorlar
- Shartlar, sikllar, massiv va kolleksiyalar
- Protseduralar, sinflar, vorislik va interfeyslar
- Xatoliklar, fayllar, JSON va LINQ
- Delegatlar, generiklar va asinxron dasturlash
Keyingi qadamlar uchun uchta yo'nalish bor:
- Windows dasturlari -
Windows Formsbilan oyna interfeysi yasash. VB shu sohada eng qulay tillardan biri. - Veb -
ASP.NET Coreorqali sayt va API yozish. - C# - VB bilan bir platformada ishlaydi va bugun faolroq rivojlanmoqda. O'rgangan tushunchalaringizning deyarli hammasi o'sha yerda ham ishlaydi, faqat yozuv shakli boshqacha.
Eng muhimi - yozishni to'xtatmang. Har kuni kichik dastur yozish bir oyda katta farq qiladi.
O‘qish tarixini saqlamoqchimisiz?
Tizimga kirsangiz, tugatgan bo‘limlaringiz saqlanadi va qoldirgan joyingizdan davom etasiz.
Xatolik topdingizmi?
Imlo xatosi, ishlamaydigan kod yoki noto‘g‘ri ma‘lumotni ko‘rsangiz - bizga xabar bering. Har bir xabar administrator tomonidan ko‘rib chiqiladi.