-
Xử lý trùng khóa chính
tranthanhan1962 > 03-06-22, 04:54 PM
Mình tạo một danh sách khách hàng cho bẫy lỗi trùng khóa chính (Eror 3022). Khi nhập Tên khách và số điện thoai thì sẽ tao Mã khách = Tên khách & số điện thoại. Mã khach là primary key. Mấy cái này đã làm trên mdb chạy OK. Nhưng khi chuyển qua accdb thì lại im re không hoạt đông. kiểm tra thì không thấy sai chổ nào nhưng lại không chạy. thêm Me.Refresh thì báo lỗi. Nhờ ongke0711, maidinhdan và các bạn xem giúp mình còn thiếu hay sai chỗ nào.
Private Sub Form_Error(DataErr As Integer, Response As Integer)
Response = acDataErrContinue
Select Case DataErr
Case 3022
MsgBox "trùng khách hàng, vui long nhap lai", vbOKOnly, "Chu y!"
End Select
End Sub
Tập tin demo
DSKH -
RE: Xử lý trùng khóa chính
DooHoaangPhuuc > 03-06-22, 11:35 PM
Cháu đã download về vẫn thấy chương trình hoạt động bình thường.
Máy tính cháu sử dụng win 10 bản quyền -
RE: Xử lý trùng khóa chính
tranthanhan1962 > 03-06-22, 11:58 PM
Máy của mình window 11 bản quyền office 2021. Không hiểu sao nó không hoạt động -
RE: Xử lý trùng khóa chính
ongke0711 > 04-06-22, 11:54 AM
(03-06-22, 11:58 PM)tranthanhan1962 Đã viết: Máy của mình window 11 bản quyền office 2021. Không hiểu sao nó không hoạt động
Nguyên nhân không phải do phiên bản Office đâu anh Ân.
Em test như thế này:
- Nhập liệu trùng -> bấm các nút tiến lùi, tạo mới thì sự kiện Form _Error nó không chạy để bắt lỗi.
- Khi đóng Form nó mới bắt lỗi 3022.
Nguyên nhân là do anh có code cho các nút lệnh tiến lùi riêng, không dùng bộ nút Navigation mặc định của Form. Anh thử thêm Navigation Buttons=Yes xem, khi nhập trùng và di chuyển record, Form_Error sẽ bắt lỗi ngay.
Do anh đã code riêng cho nút tiến lùi nên phải bẫy lỗi 3022 luôn trong code của bộ nút này hoặc thêm sự kiện Form_BeforeUpdate (thường người ta hay dùng sự kiện này). -
RE: Xử lý trùng khóa chính
tranthanhan1962 > 04-06-22, 04:07 PM
Thank ongke0711 và DooHoaangPhuuc. Thực tệ mình đã chủ quan. Đúng là thiếu bẫy lỗi ở các nút Navigation và close form. Chỉ cần thêm bẫy lỗi và gọi call Form_Error mà không nhớ. Đúng là càng già càng tệ -
RE: Xử lý trùng khóa chính
tranthanhan1962 > 04-06-22, 05:31 PM
Hì! nghĩ đơn giản nhưng không phải vậy. Đúng như ongke0711 nói. Bẫy lỗi 3022 chỉ chạy với Navigation mặc định của Còn với nút tự tạo thì không chạy đã thử nhiều cách, nhiều code vẫn thua. một số code chạy Ok với access 2003 nhưng đem accbd thì đơ như cây cơ. Mình lên mạng tìm được một số code thì cũng viết cho mdb thôi -
RE: Xử lý trùng khóa chính
ongke0711 > 04-06-22, 05:45 PM
(04-06-22, 05:31 PM)tranthanhan1962 Đã viết: Hì! nghĩ đơn giản nhưng không phải vậy. Đúng như ongke0711 nói. Bẫy lỗi 3022 chỉ chạy với Navigation mặc định của Còn với nút tự tạo thì không chạy đã thử nhiều cách, nhiều code vẫn thua. một số code chạy Ok với access 2003 nhưng đem accbd thì đơ như cây cơ. Mình lên mạng tìm được một số code thì cũng viết cho mdb thôi
Nói chung là viết code riêng, chiếm quyền điều khiển riêng của nó thì anh không thể làm biếng mượn cái lỗi 3022 của Form _Error để bắt lỗi được rồi.
Nó không trả về lỗi 3022 do đó anh chỉ có cách là bẫy trùng khóa bằng các code kiểm tra trùng truyền thống như: Dcount() thôi.
Anh có thể bẫy lỗi 3022 như sau: Mỗi khi di chuyển, tạo mới record, phải ép Access lưu dữ liệu xuống Table, khi đó nó mới hiện lỗi 3022.
Mã PHP:Private Sub AddRecord_Click()
On Error GoTo EH
If Me.Dirty Then Me.Dirty = False
DoCmd.GoToRecord , , acNewRec
Exit Sub
EH:
Select Case Err.Number
Case 3022
MsgBox "Trung khoa"
End Select
Exit Sub
End Sub
Có một cách khác chưa test thử đó là anh tách bộ nút tiến lùi ra thành 1 subform, khi đó thì khi di chuyển record, có thể Form_Error có thể bắt được lỗi 3022. Để làm thử xong up lên mọi người tham khảo. -
RE: Xử lý trùng khóa chính
tranthanhan1962 > 04-06-22, 11:02 PM
Mình mới làm được xong. Không cần đến bộ Navigation hệ thống của form access nhưng thấy nó quá rườm rà có lẽ do PRIMARY KEY của mình đươc tạo từ 2 trường:
Đầu tiên mình test thử nút AddRecord với Embedded Macro tạo bằng wizard, nó vẫn không bắt lỗi 3022. mình thử tạo macro goto record New thì nó băt lỗi được nhưng bị vấn đề phải bấm thêm nút Stop All Macro Convert Macro sang code:
Function mcrNew()
On Error GoTo mcrNew_Err
DoCmd.GoToRecord acForm, "DanhSachKhachHang", acNewRec
mcrNew_Exit:
Exit Function
mcrNew_Err:
'MsgBox Error$
Form.Undo
Resume mcrNew_Exit
End Function
Thì bị lỗi chỗ Resume mcrNew_Exit
Bỏ dòng lệnh này thì OK. Nhưng nó chỉ xóa giá trị trường cuối cùng được gỏ vào. Các trường khác vẫn con nguyên dữ liệu
Sau khi chỉnh sửa một hồi thì đoạn code này tương đối OK
Private Sub AddRecord_Click()
On Error GoTo AddRecord_Click_Err
DoCmd.GoToRecord acForm, "DanhSachKhachHang", acNewRec
AddRecord_Click_Exit:
Exit Sub
AddRecord_Click_Err:
'MsgBox Error$
MsgBoxW "Khách hàng mà b" & ChrW(7841) & "n nh" & ChrW(7853) & "p " & ChrW(273) & "ă có. Hăy xem l" & ChrW(7841) & "i.", vbExclamation + vbOKOnly, "L" & ChrW(7895) & "i"
Form_DanhSachKhachHang.MAKHACH = ""
Form_DanhSachKhachHang.Diachi = ""
Form_DanhSachKhachHang.TENKHACH = ""
Form_DanhSachKhachHang.Dienthoai = ""
Forms!DanhSachKhachHang!TENKHACH.SetFocus
End Sub
Nhưng Form bị mất Focus, mặc dù đã chèn lệnh SetFocus vào đồng thời thêm một record với các field có giá trị "". Buột phải thêm lệnh vào event close:
Private Sub Form_Close()
DoCmd.SetWarnings False
DoCmd.RunSQL "DELETE DanhSachKhachHang.MAKHACH FROM DanhSachKhachHang WHERE (((DanhSachKhachHang.MAKHACH)=''));"
DoCmd.SetWarnings True
End Sub
Thực là quá rườm rà. Đồng thời mất Focus form buột phải chọn lại form nếu muốn nhập dữ liệu tiếp tục. ongke0711 nghiên cứu xem có cách nào hay hơn không còn trường hợp nếu không bấm nút New mà close luôn mình chưa test vì đuối quá để nghiên cứu sau? Mình nhớ vơii tập tim mdb đâu có mệt mỏi như thế này -
RE: Xử lý trùng khóa chính
ongke0711 > 05-06-22, 12:04 AM
(04-06-22, 11:02 PM)tranthanhan1962 Đã viết: ...
Thực là quá rườm rà. Đồng thời mất Focus form buột phải chọn lại form nếu muốn nhập dữ liệu tiếp tục. ongke0711 nghiên cứu xem có cách nào hay hơn không còn trường hợp nếu không bấm nút New mà close luôn mình chưa test vì đuối quá để nghiên cứu sau? Mình nhớ vơii tập tim mdb đâu có mệt mỏi như thế này
Các phiên bản Access sau này có nhiều thay đổi, cải tiến nên chắc chắn sẽ có nhiều tính năng bị loại bỏ, thay đổi. Do đó nếu anh đã quen viết trên nền Access 2003 thì phải cập nhật lại rồi.
Em đã sửa lại file của anh với cách làm khác cho đỡ rườm rà bẫy lỗi các kiểu.
Anh xem bài này và tải file: https://thuthuataccess.com/forum/post-51...l#pid51232