PDA

View Full Version : آموزش: ساختار تقویم فارسی



hamidrezax1
شنبه 14 بهمن 1396, 18:50 عصر
سلام دوستان بارها و بارها شده که در برنامه نویسی برای اینکه کاربر یک تقویم به صورت صحیح وارد کنه از Dll ها و تقویم ها ی ساخته شده و... استفاده کردید تا تاریخ توسط کاربر نتونه به صورت نادرست وارد بشه.اما در این قسمت میخوام یه روش دیگه ای رو قرار بدم که تکست باکس مربوطه بیاد و تاریخ وارد شده توسط کاربر رو بگیره و چک کنه و تصیح کنه تا در نهایت تاریخ به درستی وارد بشهو مثلا اگر کاربر نوشت (95/1/1) تاریخ در تکس باکس و یا هر چیزی که مد نظرتون هست بشه(1395/01/01) برای این منظور من کد مربوطه رو قرار میدم تو اینجا تا هرکدوم از دوستان خواستن ازش استفاده کنن.برای همتون آرزوی موفقیت و پیروزی رو دارم(قطعا کد مربوطه دارای نقص هست و بایستی با یکسری ارور تصیح بشه اما ساختار کلی رو ارائه داده)
موفق باشید



If Me.TextBox1.Text.Length = 10 Then
Exit Sub
Else
Dim a, b, c, f As String
a = Me.TextBox1.Text.Substring(2, 1)
If a = "/" Then
Me.TextBox1.Text = "13" + Me.TextBox1.Text
If Me.TextBox1.Text.Length = 10 Then
Exit Sub
End If
End If
a = Me.TextBox1.Text.Substring(4, 1)
b = Me.TextBox1.Text.Substring(7, 1)
If b <> "/" Then




b = Me.TextBox1.Text.Substring(0, 5)
f = Me.TextBox1.Text.Length - 5
c = Me.TextBox1.Text.Substring(5, f)


Me.TextBox1.Text = b + "0" + c
If Me.TextBox1.Text.Length = 10 Then
Exit Sub
End If
End If
a = Me.TextBox1.Text.Substring(7, 1)
If a = "/" And Me.TextBox1.Text.Length <> 10 Then


b = Me.TextBox1.Text.Substring(0, 8)
f = Me.TextBox1.Text.Length - 8
c = Me.TextBox1.Text.Substring(8, f)


Me.TextBox1.Text = b + "0" + c
If Me.TextBox1.Text.Length = 10 Then
Exit Sub
End If
End If


End If

محمد آشتیانی
شنبه 14 بهمن 1396, 19:21 عصر
سلام
دست شما درد نکنه و خسته نباشید ، اما چند مسئله
کد شما صحت تاریخ رو چک نمیکنه ، مثلا 95/11/74 رو ایرادی نمیگیره بهش (ایده آل این هست که محدوده عددی که برای ماه وارد میشه رو هم چک کنه و با توجه به ماه وارد شده ، محدوده روزها رو هم چک کنید)
یا فرض کنید کاربر تایپ کرده 395/11/11 و عدد یک از دستش در رفته ، در این صورت هم خروجی اشتباه خواهد شد
همه این ها رو اگر فرصت داشتید پیاده سازی کنید ، خوبه که کل این عملیات در یک فانکشن انجام بشه و وابسته به TextBox یا کنترل دیگری نباشد ، صرفا ورودی بگیرید و بعنوان خروجی تاریخ صحیح بدید و یا خطا.

کار شما بسیار ارزشمنده و توضیحات صرفا بخاطر تکمیل زحمتی هست که کشیدید.


بدون در نظر گرفتن پیشنهاداتی که عرض کردم ، این کد دقیقا کار کد شما رو انجام میده

Public Function CheckDate(inputDate As String) As String

Dim splittedDate As List(Of String) = inputDate.Split(Convert.ToChar("/")).ToList()


If splittedDate(0).Length = 2 Then
splittedDate(0) = "13" + splittedDate(0)
End If

Return $"{splittedDate(0)}/{CInt(splittedDate(1)).ToString("D2")}/{CInt(splittedDate(2)).ToString("D2")}"


End Function



موفق باشید.

hamidrezax1
سه شنبه 17 بهمن 1396, 04:54 صبح
جناب مهندس میشه لطفا راهنمایی کنید
147584

محمد آشتیانی
سه شنبه 17 بهمن 1396, 08:18 صبح
سلام
اون خطای Character is not valid احتمالا بخاطر نسخه دات نت فریم ورک و ویژوال استودیویی که استفاده می کنید هست ، فکر میکنم برای استفاده از این قابلیت باید از فریم ورک 4.6 و بالاتر استفاده کنید
(برای مطالعه بیشتر ، اسم این قابلیت String interpolation هست ، که بسیار هم امکان خوب و جذابی هست)


اگر نمیخواهید ازش استفاده کنید ، می تونید به این شکل بنویسید

Return splittedDate(0) + "/" + CInt(splittedDate(1)).ToString("D2") + "/" + CInt(splittedDate(2)).ToString("D2")

یا

Dim sb = New StringBuilder
Return sb.AppendFormat("{0}/{1}/{2}", splittedDate(0), CInt(splittedDate(1)).ToString("D2"),CInt(splittedDate(2)).ToString("D2")).ToString()

یا هر مدل دیگری که می پسندید.

موفق باشید.

hamidrezax1
شنبه 21 بهمن 1396, 07:00 صبح
سلام استاد کد شما رو با فرمایشاتی که فرمودین تغییر دادم.ممنون میشم بررسی کنید



Public Function CheckDate(ByVal inputDate As String) As String
Dim splittedDate As List(Of String) = inputDate.Split(Convert.ToChar("/")).ToList()
If splittedDate(0).Length = 2 Then
splittedDate(0) = "13" + splittedDate(0)
End If
Try
If CInt(splittedDate(0)).ToString("D2").Length <> 4 Then
MsgBox("کاربر گرامی سال وارد شده صحیح نمی باشد", MsgBoxStyle.Information, "هشدار")
Exit Function
End If
If CInt(splittedDate(0)).ToString("D2") > 1399 Then
MsgBox("کاربر گرامی سال وارد شده صحیح نمی باشد", MsgBoxStyle.Information, "هشدار")
Exit Function
End If
If CInt(splittedDate(1)).ToString("D2") > 12 Then
MsgBox("کاربر گرامی ماه وارد شده صحیح نمی باشد", MsgBoxStyle.Information, "هشدار")
Exit Function
End If
If CInt(splittedDate(1)).ToString("D2") <= 5 And CInt(splittedDate(2)).ToString("D2") > 31 Then
MsgBox("کاربر گرامی روز وارد شده صحیح نمی باشد", MsgBoxStyle.Information, "هشدار")
Exit Function
End If
If CInt(splittedDate(1)).ToString("D2") >= 6 And CInt(splittedDate(2)).ToString("D2") > 30 Then
MsgBox("کاربر گرامی روز وارد شده صحیح نمی باشد", MsgBoxStyle.Information, "هشدار")
Exit Function
End If
Catch ex As Exception
MsgBox("کاربر گرامی اطلاعات وارد شده صحیح نمی باشد", MsgBoxStyle.Information, "هشدار")
Exit Function
End Try


Return splittedDate(0) + "/" + CInt(splittedDate(1)).ToString("D2") + "/" + CInt(splittedDate(2)).ToString("D2")


End Function

محمد آشتیانی
یک شنبه 22 بهمن 1396, 15:36 عصر
سلام
این به نظر میرسه کامل چک میکنه (شاید هم موردی رو یادم رفته باشه البته)


Public Function CheckDate(inputDate As String) As String

Dim splittedDate As List(Of String) = inputDate.Split(Convert.ToChar("/")).ToList()


Dim year As String = splittedDate(0)
Dim month As String = splittedDate(1)
Dim day As String = splittedDate(2)


If year.Trim().Length < 4 Then
Throw New Exception("Invalid year value")
End If

If month.Trim().Length = 0 Then
Throw New Exception("Invalid month value")
End If


If day.Trim().Length = 0 Then
Throw New Exception("Invalid day value")
End If


If CInt(month) < 1 Or CInt(month) > 12 Then
Throw New Exception("Invalid month value")
End If


If CInt(day) < 1 Then
Throw New Exception("Invalid day value")
End If


Dim persianCalendar As New PersianCalendar()
Dim leapYear As Boolean = persianCalendar.IsLeapYear(CInt(year))

If leapYear Then


If (CInt(month) < 7 And CInt(day) > 31) Or (CInt(month) > 6 And CInt(day) > 30) Then
Throw New Exception("Invalid day value")
End If


Else


If (CInt(month) < 7 And CInt(day) > 31) Or ((CInt(month) > 6 And CInt(month) < 12) And CInt(day) > 30) Or (CInt(month) = 12 and CInt(day) > 29) Then
Throw New Exception("Invalid day value")
End If


End If


Return year + "/" + CInt(month).ToString("D2") + "/" + CInt(day).ToString("D2")


End Function


توی فانکشن ها حتی الامکان از ارتباط با UI اجتناب کنید ، مثلا نمایش MessageBox ، فرض کنید بخوان از این تابع شما در یک برنامه کنسول استفاده کنند یا اصلا قرار باشه به عنوان یک dll در اختیار برنامه نویس دیگری قرار بگیره و اونجا بخوان جور دیگری خطا رو به کاربر نمایش بدن ، این هست که از Exception ، هنگام رخ دادن خطا استفاده شده ، موقع فراخوانی می تونید به این شکل استفاده کنید.


Try
TextBox1.Text = CheckDate(TextBox1.Text)
Catch ex As Exception
MsgBox(ex.Message, MsgBoxStyle.Information, "هشدار")
End Try

محمد آشتیانی
یک شنبه 22 بهمن 1396, 15:53 عصر
در این سبک کاربرد ها ، برای راحتی بیشتر و تمیز شدن کدتون ، میتونید از Extention Method ها نیز استفاده کنید ، به این ترتیب که یک ماژول به پروژتون اضافه می کنید و هرجا نیاز به چک کردن یک تاریخ شمسی بود ، (که طبیعتا نوعش String هست) ازش استفاده کنید.


Imports System.Globalization
Imports System.Runtime.CompilerServices


Module Extention


<Extension()>
Public Function CheckDate(inputDate As String) As String

Dim splittedDate As List(Of String) = inputDate.Split(Convert.ToChar("/")).ToList()


Dim year As String = splittedDate(0)
Dim month As String = splittedDate(1)
Dim day As String = splittedDate(2)


If year.Trim().Length < 4 Then
Throw New Exception("Invalid year value")
End If

If month.Trim().Length = 0 Then
Throw New Exception("Invalid month value")
End If


If day.Trim().Length = 0 Then
Throw New Exception("Invalid day value")
End If


If CInt(month) < 1 Or CInt(month) > 12 Then
Throw New Exception("Invalid month value")
End If


If CInt(day) < 1 Then
Throw New Exception("Invalid day value")
End If


Dim persianCalendar As New PersianCalendar()
Dim leapYear As Boolean = persianCalendar.IsLeapYear(CInt(year))

If leapYear Then


If (CInt(month) < 7 And CInt(day) > 31) Or (CInt(month) > 6 And CInt(day) > 30) Then
Throw New Exception("Invalid day value")
End If


Else


If (CInt(month) < 7 And CInt(day) > 31) Or ((CInt(month) > 6 And CInt(month) < 12) And CInt(day) > 30) Or (CInt(month) = 12 and CInt(day) > 29) Then
Throw New Exception("Invalid day value")
End If


End If


Return year + "/" + CInt(month).ToString("D2") + "/" + CInt(day).ToString("D2")


End Function


End Module


به اینصورت هم استفاده میشه

Try
TextBox1.Text = TextBox1.Text.CheckDate()
Catch ex As Exception
MsgBox(ex.Message, MsgBoxStyle.Information, "هشدار")
End Try


تو این حالت اگر انتهای نام یک متغیر String نقطه بذارید ، نام تابع CheckDate رو میتونید در لیست توابع ببینید و استفادش کنید

مثلا
Dim a As String = "1396/12/30"
a.CheckDate()

یا مثالی که بالاتر زدم



انشاالله مفید باشه

hamidrezax1
سه شنبه 24 بهمن 1396, 17:37 عصر
البته استاد بیشتر بحث من در خصوص کانورت کردن دیتا بیس و ایمپورت اطلاعات از اکسل بود که داده هاش معمولا به صورت صحیح وارد نشده بود.در واقع در زمان اجرا کوئری من نرم افزار تاریخ ها رو به صورت صحیح ایمپورت میکرد یعنی تاریخ 96/04/1 رو به 1396/04/01 تغییر میداد و ...
باز هم از راهنمایتون کمال سپاسگذاری رو دارم.سالم و پیروز باشید