ورود

View Full Version : آموزش: تشخیص و جلوگیری از ورود رکورد تکراری در فرم bound (با استفاده از رخداد before update)



mazoolagh
چهارشنبه 18 مهر 1403, 14:54 عصر
تاپیک های مرتبط:
آموزش: تشخیص و جلوگیری از ورود رکورد تکراری (با استفاده از data-macro در جدول) (barnamenevis.org) (https://barnamenevis.org/showthread.php?589743-%D8%AA%D8%B4%D8%AE%DB%8C%D8%B5-%D9%88-%D8%AC%D9%84%D9%88%DA%AF%DB%8C%D8%B1%DB%8C-%D8%A7%D8%B2-%D9%88%D8%B1%D9%88%D8%AF-%D8%B1%DA%A9%D9%88%D8%B1%D8%AF-%D8%AA%DA%A9%D8%B1%D8%A7%D8%B1%DB%8C-(%D8%A8%D8%A7-%D8%A7%D8%B3%D8%AA%D9%81%D8%A7%D8%AF%D9%87-%D8%A7%D8%B2-data-macro-%D8%AF%D8%B1-%D8%AC%D8%AF%D9%88%D9%84))
آموزش: تشخیص و جلوگیری از ورود رکورد تکراری (با استفاده از تعریف unique constraint در جدول) (barnamenevis.org) (https://barnamenevis.org/showthread.php?589739-%D8%AA%D8%B4%D8%AE%DB%8C%D8%B5-%D9%88-%D8%AC%D9%84%D9%88%DA%AF%DB%8C%D8%B1%DB%8C-%D8%A7%D8%B2-%D9%88%D8%B1%D9%88%D8%AF-%D8%B1%DA%A9%D9%88%D8%B1%D8%AF-%D8%AA%DA%A9%D8%B1%D8%A7%D8%B1%DB%8C-(%D8%A8%D8%A7-%D8%A7%D8%B3%D8%AA%D9%81%D8%A7%D8%AF%D9%87-%D8%A7%D8%B2-%D8%AA%D8%B9%D8%B1%DB%8C%D9%81-unique-constraint-%D8%AF%D8%B1-%D8%AC%D8%AF%D9%88%D9%84))
آموزش: جلوگیری از ورود داده تکراری در اکسس + نمایش پیغام خطا (barnamenevis.org) (https://barnamenevis.org/showthread.php?413205-%D8%AC%D9%84%D9%88%DA%AF%DB%8C%D8%B1%DB%8C-%D8%A7%D8%B2-%D9%88%D8%B1%D9%88%D8%AF-%D8%AF%D8%A7%D8%AF%D9%87-%D8%AA%DA%A9%D8%B1%D8%A7%D8%B1%DB%8C-%D8%AF%D8%B1-%D8%A7%DA%A9%D8%B3%D8%B3-%D9%86%D9%85%D8%A7%DB%8C%D8%B4-%D9%BE%DB%8C%D8%BA%D8%A7%D9%85-%D8%AE%D8%B7%D8%A7)


جدول نمونه زیر رو در نظر بگیرین:

156167

میخواهیم که جلوی ثبت رکورد تکراری بر اساس سه فیلد FirstName, LastName, DepartmentID رو بگیریم - به فیلدهای JobID و BirthDate کاری نداریم.

mazoolagh
چهارشنبه 18 مهر 1403, 14:55 عصر
گام اول این هست که ببینیم چنین رکوردی داریم یا نه،
و بعد با یک پیغام مناسب به کاربر خبر بدیم.


برای جستجو کافی هست از متد findfirst رکوردست استفاده کنیم که به مراتب از dlookup سریعتر هست.
ولی دامنه جستجو رو به همه رکوردها به جز رکورد فعلی محدود میکنیم.
همچنین به روال منطقی بجای رکوردست فرم از recordsetclone اون استفاده میکنیم.


Option Compare Database
Option Explicit

Const WHR = "[ID]<> @ID AND [FirstName]=""@FN"" AND LastName=""@LN"" AND [DepartmentID]=@DID"

Private Sub Form_BeforeUpdate(Cancel As Integer)
Dim Criteria As String
Criteria = Replace(WHR, "@ID", Me.ID)
Criteria = Replace(Criteria, "@FN", Me.FirstName)
Criteria = Replace(Criteria, "@LN", Me.LastName)
Criteria = Replace(Criteria, "@DID", Me.DepartmentID)

With Me.RecordsetClone
.FindFirst Criteria
If Not .NoMatch Then
Cancel = True
If MsgBox( _
Prompt:="ID=" & !ID & vbCrLf & _
"First Name=" & !FirstName & vbCrLf & _
"Last Name=" & !LastName & vbCrLf & _
"Birth Date=" & !BirthDate & vbCrLf & _
"Department=" & DLookup("Department", "Departments", "DepartmentID=" & !DepartmentID) & vbCrLf & _
"Job Title=" & DLookup("JobTitle", "JobTitles", "JobID=" & !JobID) & vbCrLf & vbCrLf & _
"Drop Changes ?", _
Buttons:=vbExclamation + vbYesNo, _
Title:="Duplicate Record") = vbYes Then
Me.Undo
End If
End If
End With
End Sub

mazoolagh
چهارشنبه 18 مهر 1403, 15:03 عصر
تست در ویرایش رکورد:

156168

تست در ثبت رکورد جدید:

156169

mazoolagh
چهارشنبه 18 مهر 1403, 15:27 عصر
1- در اینجا برای سادگی فقط کدها مورد نیاز همین بحث آمده،
در یک برنامه عملی باید form validation رو دقیق پیاده کنین - یک آموزش همراه با کد نمونه رو در تاپیک زیر میتونین ببینین (پست شماره 14 و به بعد):
مبتدی: راهنمایی در نوشتن مسیج باکس (barnamenevis.org) (https://barnamenevis.org/showthread.php?558147-%D8%B1%D8%A7%D9%87%D9%86%D9%85%D8%A7%DB%8C%DB%8C-%D8%AF%D8%B1-%D9%86%D9%88%D8%B4%D8%AA%D9%86-%D9%85%D8%B3%DB%8C%D8%AC-%D8%A8%D8%A7%DA%A9%D8%B3&p=2423742&viewfull=1#post2423742)

2- در اینجا فرض شده که رکوردست فرم همه رکوردهای جدول رو در بر میگیره،
اگر اینجور نیست باید به جای recordsetclone ، یک رکوردست دیگه روی کل جدول استفاده کنین.

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

برنامه پیوست: