PDA

View Full Version : مبتدی: راهنمایی در نوشتن مسیج باکس



datmas
شنبه 20 مهر 1398, 21:27 عصر
با سلام خدمت بزرگواران عزیز
دوستان راهنمایی میخوام در قسمت مسیج باکس
البته بصورت دست و پا شکسته از مطالب همین سایت یه کارایی کردم ولی ناقصه.

توضیحات: فیلد Id فیلد کلیدی و غیر تکراری و فیلد نام هم Reqired آن Yes گذاشتم .



الان مسیج باکس من پیغام نمیده که در صورت تکراری بودن ((فیلد Id تکراری وارد شده است اصلاح کن)) یا در صورت پر نکردن فیلد نام سوال کنه ((فیلد نام خالی هست پر نمایید ))

با تشکر از عنایت دوستان

datmas
یک شنبه 21 مهر 1398, 16:20 عصر
دوستان محترم نمونه من تکراری نیست من خیلی گشتم تو سایت ها بتونم حل کنم و مزاحم شما نشم ولی نشد. خواهشا راهنمایی کنید. ممنون

mazoolagh
دوشنبه 22 مهر 1398, 10:36 صبح
خب روشی که استفاده کردین نشون نمیده کدوم کنترل باعث ایجاد خطا شده - بنابراین نمیتونین ببینین این id هست که مقدار نداره یا nam؟

برای
form validation یک جستجو بکنین تو تالار - میدونم چند تاپیک هست در این مورد
اول اونها رو بخونین اگر هنوز مشکل داشتین دوباره همینجا مطرح کنین

datmas
سه شنبه 23 مهر 1398, 00:50 صبح
سلام استاد ببخشید دیگه مرتب مزاحم شما میشم.
من تاپیک ها رو پیدا کردم ولی مطابق خواسته من نبود.
فرمایشتون درسته (نشون نمیده کدوم کنترل باعث ایجاد خطا شده) ولی اونقدر تسلط ندارم اصلاحش کنم.

datmas
چهارشنبه 24 مهر 1398, 21:02 عصر
سلام آقا من امیدم به شماست

shahraieni13
شنبه 27 مهر 1398, 18:03 عصر
سلام دوست عزیز .من هم چند وقت پیش با همچین مشکلی دست به گریبان بودم .
تا اینکه برحسب اتفاق یک سایت عالی پیدا کردم به اسم softpluse دقیقا همین موضوع را کامل تشریح کرده هم در مورد خود مسیج باکس و هم در مورد اینکه اگه یک تکس باکس خالی بود پیغام مناسب بده توی گوگل اسم سایت رو سرچ کنید حتما پیداش می کنید

datmas
دوشنبه 29 مهر 1398, 01:16 صبح
سلام ممنون از آدرس سایت.مشکل اولم فیلد تکراری حل شد .

ولی مشکل دومم : فیلد نام در صورت خالی بودن هنگام بستن پنجره فرم پبغام بده رو نتونستم.
البته این کد رو نوشتم هنگام بستن پنجره پیغام هم میده ولی بمحض زدن ok پنجره بسته میشه . میخوام پنجره نبنده و اجازه اصلاح بده

'Response = False
'Select Case DataErr
'Case Is = 3314
'MsgBox "!فیلد نام خالی است", vbRetryCancel + vbExclamation + vbMsgBoxRight, "اکسس"
'End Select
'Response = True

datmas
دوشنبه 29 مهر 1398, 22:14 عصر
دوستان لطفا راهنمایی کنید.:متفکر:

datmas
چهارشنبه 01 آبان 1398, 01:25 صبح
دوستان فقط این قسمت سوالم ( میخوام پنجره نبنده و اجازه اصلاح بده) درخواست دارم راهنمایی کنید.

mazoolagh
چهارشنبه 01 آبان 1398, 11:20 صبح
1- اگر همون form validation رو که قبلا گفته بودم جستجو میکردین اولین پست به معرفی همین سایت میرسیدین و زودتر نتیجه میگرفتین!

2- برای مورد زیر:

ولی مشکل دومم : فیلد نام در صورت خالی بودن هنگام بستن پنجره فرم پبغام بده رو نتونستم.
برنامه جدیدتون رو پیوست کنین

datmas
سه شنبه 07 آبان 1398, 02:49 صبح
با سلام.
سرم شلوغ بود نتونستم فایل رو ضمیمه کنم .
اینم فایل که یک باتن به نام ذخیره و بستن هم اضافه کردم و کدهایی که تو سایت پیدا کردم هم پشت باتن گذاشتم اما بی فایده بود
ضمنا فیلد ID پیغام فارسی مبنی بر تکراری میده ولی در ادامش پیغام سیستم میاد.
فیلد نشان هم کدی که نوشتم عمل نمیکنه
با تشکر از لطف و محبتتون

mazoolagh
چهارشنبه 08 آبان 1398, 11:15 صبح
برنامه تون رو دیدم
اینکه تغییرات را با زدن کلید ذخیره کنین مربوط به فرم unbound هست - شما از فرم bound استفاده میکنین.

در فرم bound روش کلا فرق میکنه و معمولا از form before update استفاده میکنیم.
این رو هم در نظر داشته باشین که یک نسخه واحد برای form validation نمیشه پیچید و بسته به نوع محدودیت های اعمال شده روی فیلد و تعریف اونها در سطح جدول و فرم رفتار رخدادها هم متفاوت هست و برای هر سناریو راهکار ممکنه تغییرات جزئی یا اساسی داشته باشه.
ولی در کل validation در فرمهای unbound خیلی ساده تر و سرراست تر هست.

اینه که نگران نباشین اگر نتیجه نگرفتین و باعث دلسردی نشه چون واقعا کار ظریف و دقیقی هست و تسلط به اون نیاز به تجربه و تمرین و خرابکاری! زیاد داره.

سعی میکنم یک نمونه کاربردی براتون پیوست کنم ولی ممکنه چند روز زمان ببره، در این مدت روی رخدادهای before update (فرم و کنترل) ، form unload , form error , validation rule (در سطح فرم و جدول) و تفاوت فرم های bound و unbound مطالعه کنین.

datmas
چهارشنبه 08 آبان 1398, 14:07 عصر
سلام.ممنون از راهنماییتون.چشم حتما مطالعه میکنم.شما به بزرگواریتون ببخشید که بدون شناخت کامل اصول مقدماتی اکسس پروژه رو شروع کردم.راستش در اکثر سایتهای بصورت کلی آموزش میدن و تا همینجا هم از این سایت و از دوستانی چون شما مقداری یاد گرفتم.

mazoolagh
یک شنبه 12 آبان 1398, 11:49 صبح
آقا من امروز برای شما یک نمونه آماده کردم که همینجا پیوست میکنم

توضیحات رو باید سر فرصت آماده کنم و احتمالا در یک تاپیک جدید بگذارم.

فعلا توضیح مختصر میدم:

جدول زیر رو داریم

150899



NCode
Primary Key

5 رقم، مقدار مجاز از 10001 تا 99990



FirstName
Required

حداقل 3 حرف، تک حرف مجاز نیست



LastName

Required


حداقل 3 حرف، تک حرف مجاز نیست



Sex

Required


value list 0;Male;1;Female



BirthDate

Required





HireDate


حداقل 20 سال بعد از تاریخ تولد


Mobile


سرشماره های مجاز 0910 تا 0919 یا 0990 تا 0992

mazoolagh
یک شنبه 12 آبان 1398, 11:53 صبح
در نظر داشته باشین که رفرنس های زیر برای اجرای کدها نیاز هست:
150900

mazoolagh
یک شنبه 12 آبان 1398, 12:01 عصر
کدهای validation مقادیر رو در فرم قرار نمیدیم بلکه در یک ماژول جدا میریزیم.
اینجوری در فرم فقط به منطق کار میپردازیم و از طرفی اگر در فرمهای دیگه هم نیاز باشه از کدنویسی تکراری پرهیز کردیم


Option Compare Database
Option Explicit
Public v
Public Const OK As String = "OK"


Public Function ValidNcode(NCode As Variant) As String
ValidNcode = OK
NCode = Nz(NCode, "")
If NCode = "" Then
ValidNcode = "National Code is required"
Exit Function
End If
Dim RX As New RegExp
RX.Global = True
RX.Pattern = "\D"
If RX.Test(NCode) Then
ValidNcode = "National Code is all numeric"
Exit Function
End If
If NCode < 10001 Or NCode > 99990 Then
ValidNcode = "National Code should should be in range of 10001 to 99990"
End If
End Function


Public Function ValidName(x As Variant) As String
x = Nz(x, "")
Dim RX As New RegExp
RX.Global = True
RX.Pattern = "[^a-zA-Z ]"
If RX.Test(x) Then
ValidName = "should contain only letters(a-z/A-Z) and spaces"
Exit Function
End If
RX.Pattern = "(\b\w\b)"
If RX.Test(x) Then
ValidName = "can not contain any single letter!"
Exit Function
End If
Select Case Len(x)
Case 0
ValidName = "is required"
Case 1 To 2
ValidName = "should have atleast 3 characters"
Case Else
ValidName = OK
End Select
End Function


Public Function ValidMobile(x As Variant) As String
ValidMobile = OK
x = Nz(x, "")
If x = "" Then Exit Function
Dim RX As New RegExp
RX.Global = True
RX.Pattern = "\D"
If RX.Test(x) Then
ValidMobile = "Mobile number is all numeric!"
Exit Function
End If
RX.Pattern = "09(1[0-9]|9[0-2])\d{7}"
If Not RX.Test(x) Then
ValidMobile = "Mobile number is invalid!"
End If
End Function


Public Function ValidHireDate(BirthDate As Variant, HireDate As Variant) As String
ValidHireDate = OK
If IsNull(HireDate) Then Exit Function
If IsNull(BirthDate) Then
ValidHireDate = "First fill the Birth Date!"
Else
If DateDiff("yyyy", BirthDate, HireDate) < 20 Then
ValidHireDate = "Hire Date should be atleat 20 years after Birth Date!"
End If
End If
End Function


Public Function FullTrim(x As Variant) As Variant
x = Trim(Nz(x, ""))
Dim RX As New RegExp
RX.Global = True
RX.Pattern = "\s+"
FullTrim = RX.Replace(x, " ")
End Function

mazoolagh
یک شنبه 12 آبان 1398, 12:03 عصر
کدهای فرم:


Option Compare Database
Option Explicit
Dim FormStatus As String
Dim Error2169 As Boolean


Private Sub Form_Load()
Error2169 = False
End Sub


Private Sub Form_Unload(Cancel As Integer)
If Error2169 Then
If MsgBox("All data changes droped," & vbCrLf & "Close form?" & vbCrLf & "OK: Close form" & vbCrLf & "CANCEL: Continue editing", vbQuestion + vbOKCancel, "") = vbCancel Then
Cancel = True
Error2169 = False
Else
Cancel = False
End If
End If
End Sub


Private Sub Form_BeforeUpdate(Cancel As Integer)
ValidateForm
If FormStatus <> "OK" Then
v = MsgBox("Correct the following items:" & vbCrLf & vbCrLf & FormStatus, vbExclamation, "Form Validation")
Cancel = True
End If
End Sub


Private Sub Form_Error(DataErr As Integer, Response As Integer)
Select Case DataErr
Case 3022
Dim FullName As String
FullName = DLookup("FirstName & ' ' & LastName", "Persons", "NCode='" & Me.NCode & "'")
v = MsgBox("National Code " & Me.NCode & vbCrLf & "already registered to :" & FullName, vbExclamation, "Duplicate National Code")
Response = acDataErrContinue
Case 3314
v = MsgBox(Me.ActiveControl.Properties("DatasheetCaption"), vbExclamation, "Required Field Is Empty")
Response = acDataErrContinue
Case 2279
v = MsgBox(Me.ActiveControl.Properties("DatasheetCaption"), vbExclamation, "Input Mask Is Incomplete")
Response = acDataErrContinue
Case 2169
Error2169 = True
Response = acDataErrContinue
Case Else
Response = acDataErrDisplay
End Select
End Sub


Sub ValidateForm()
Dim D As New Dictionary
Dim x As String
Error2169 = False
x = ValidNcode(Me.NCode)
If x <> OK Then
D.Add x, D.Count
End If
x = ValidName(Me.FirstName)
If x <> OK Then
D.Add "First Name " & x, D.Count
End If
x = ValidName(Me.LastName)
If x <> OK Then
D.Add "Last Name " & x, D.Count
End If
If IsNull(Me.BirthDate) Then
D.Add "Birth Date is required", D.Count
End If
x = ValidHireDate(Me.BirthDate, Me.HireDate)
If x <> OK Then
D.Add x, D.Count
End If
x = ValidMobile(Me.Mobile)
If x <> OK Then
D.Add x, D.Count
End If
If D.Count = 0 Then
FormStatus = "OK"
Else
FormStatus = Join(D.Keys, vbCrLf)
End If
End Sub


Private Sub FirstName_AfterUpdate()
Me.FirstName = FullTrim(Me.FirstName)
End Sub
Private Sub LastName_AfterUpdate()
Me.LastName = FullTrim(Me.LastName)
End Sub


Private Sub Sex_NotInList(NewData As String, Response As Integer)
Me.Sex = 0
Response = acDataErrContinue
End Sub

mazoolagh
یک شنبه 12 آبان 1398, 12:06 عصر
این هم خود برنامه

من همه کدها رو چک نکردم ، ممکنه اشکال داشته باشه یا موردی از دست دررفته باشه.
حالت های مختلف رو چک کنین و اگر موردی بود خبر بدین
همینجور اگر پرسشی داشتین همینجا مطرح کنین

datmas
یک شنبه 12 آبان 1398, 12:39 عصر
سلام.خیلی عزیزی این همه وقت گذاشتید.واقعا قابل توصیف نیست لطفتون.

برا تغییر محدودیت 3حرف در قسمت name چکار باید کرد؟
یا قسمت code میشه عدد بازه رو تغییر داد مثلا شماره نامه ای وارد کرد: 22-8656/1

کلا محدودیت هارو میشه برداشت ؟

mazoolagh
دوشنبه 13 آبان 1398, 11:02 صبح
برای validation هر فیلد یک تابع جدا داریم (به جز firstname و lastname که در این نمونه فرمول بررسی یکسان دارن) که با Valid شروع میشه و بعد اسم فیلد
​شما میتونین برای تغییر شرایط هر فیلد سراغ تابع مربوط به خودش برین؛ برای firstname/lastname تابع ValidName رو ویرایش کنین، بعنوان مثال بلوک Select Case Len(x) تعداد کارآکترها رو بررسی میکنه



​اگر یک فیلد اصلا نیاز به بررسی نداره بلوک مربوط به اون رو از تابع ValidateForm بردارین
اگر فیلد جدیدی دارین که باید validate بشه براش یک تابع جدید بنویسین و یک بلوک هم در ValidateForm براش اضافه کنین
در برنامه پیوست فرمولی که Validation فیلد NCode استفاده شده صرفا یک مثال هست؛ میتونین هر فرمول یا در صورت نیاز Input Mask که خواستین براش تعریف کنین.
اگر شماره نامه شکل و شرایط مشخصی داره دقیق بنویسین تا راهنمایی کنم چگونه تابع مربوطه رو تغییر بدین

datmas
دوشنبه 13 آبان 1398, 20:43 عصر
سلام.
سر شماره متفاوت هست -853 یا -2555 یا -1252/2 :مثلا 22-8858/1 که عدد 22 متغیر هست.
ضمنا در صورت خالی گذاشتن یک فیلد هنگام بستن فرم پیغام ok و cancel میاد ، با زدن کنسل جهت ادامه کار برا پر کردن فیلد باقیمانده ، ولی کلا رکورد پاک میکنه و از اول باید نوشت.

mazoolagh
سه شنبه 14 آبان 1398, 14:41 عصر
در صورت خالی گذاشتن یک فیلد هنگام بستن فرم پیغام ok و cancel میاد ، با زدن کنسل جهت ادامه کار برا پر کردن فیلد باقیمانده ، ولی کلا رکورد پاک میکنه و از اول باید نوشت.

این رفتار خود اکسس هست!
وقتی در یک فرم bound وسط ادیت یا اضافه کردن رکوردی که قابل save کردن نیست (یک دلیلش همینکه رکورد valid نیست) سعی میکنین فرم (یا دیتابیس) رو ببندین خطای 2169 پیش میاد و خود اکسس همه تغییرات رو برمیگردونه. دست شما نیست.

یک کاری که میشه کرد این هست که خودتون یک دکمه close بسازین و دکمه close خود فرم رو disable کنین. ما اینجا اینکار رو نکردیم چون هنوز دکمه close خود اکسس هست. مایل هستین میتونم براتون یک نمونه با همین روش بگذارم.
کلا زیاد به کاربر گیر ندین و رو اعصابش نرین! وقتی میخواد فرم رو ببنده حتما از ذخیره تغییرات منصرف شده.

یک راه دیگه این هست که در before update همه مقادیر رکورد رو ذخیره کنین و در form unload وقتی کاربر از بستن فرم انصراف داد مقادیر رو برگردونین (مطمئن نیستم بشه - باید چک کنم)

راه دیگه این هست که فرم unbound استفاده کنین در مقابل باید برای save رکورد خودتون کد بنویسین

mazoolagh
سه شنبه 14 آبان 1398, 14:49 عصر
سر شماره متفاوت هست -853 یا -2555 یا -1252/2 :مثلا 22-8858/1 که عدد 22 متغیر هست

یعنی سرشماره ها فقط همین چند تا هست که نوشتین؟
یا اینکه اینها مثال هست؟

طول معینی داره عدد اول ؟ مثلا 3 تا 5 رقم
وضعیت - و / ؟ همیشه هستن؟ ممکنه بیشتر از یک بار ظاهر بشن؟

هر چه دقیقتر مشخص کنین بهتر میتونین جلوی ورود داده نادرست رو بگیرین ولی فعلا کد زیر کمکتون میکنه:

Public Function ValidLetterNumber(LetterNumber As Variant) As String
ValidLetterNumber = OK
LetterNumber = Nz(LetterNumber, "")
If LetterNumber = "" Then
ValidLetterNumber = "Letter Number is required"
Exit Function
End If
Dim RX As New RegExp
RX.Global = True
RX.Pattern = "[^0-9\-/]"
If RX.Test(LetterNumber) Then
ValidLetterNumber = "Invalid Character in Letter Number"
End If
End Function

datmas
شنبه 18 آبان 1398, 08:28 صبح
سلام ببخشید دسترسی به سیستم نداشتم الان جوابتونو دیدم.
من کد فانکشن در ماژول گذاشتم اما جواب نداد؟ البته در ماژول ValidLetterNumber نداریم ولی ValidNcode هست جابجا هم اسمهارو کردم بازم نشد.
خیلی خیلی به زحمت افتادید شرمنده.

mazoolagh
یک شنبه 19 آبان 1398, 11:32 صبح
اول اینکه این نمونه فقط یک نمونه است!
فقط به شما ایده میده برای چگونگی کار - البته با حفظ همین ساختار و انجام تغییرات جزئی طبق نیازهاتون میتونین در هر برنامه ای ازش استفاده کنین.

در کد بالا فرض بر این هست که شما فیلدی به نام LetterNumber (همون شماره نامه) از نوع string دارین، دیگه Ncode رو کاری باهاش نداریم.
هم در طراحی جدول باید این فیلد باشه، هم در فرم.
اون تابع ValidLetterNumber هم کنار بقیه توابع مشابه قرار میگیره.

در تابع ValidateForm این بلوک رو قبل از بقیه بلوک ها اضافه میکنین:
x = ValidLetterNumber(Me.LetterNumber)
If x <> OK Then
D.Add x, D.Count
End If

mazoolagh
یک شنبه 19 آبان 1398, 11:34 صبح
باید کاملا وقت بگذارین و کدها رو دقیق بخونین.

ابتدای هر روتین یک breakpoint بگذارین و حالت های مختلف رو در فرم امتحان و کدها رو خط به خط trace کنین.

اینجوری منطق پشت کدها و بخصوص توالی رخدادها دستتون میاد.

datmas
یک شنبه 19 آبان 1398, 21:19 عصر
خیلی خیلی ممنون استاد .حتما از راهنماییتون استفاده میکنم