-
cách bắt sự kiện trùng khóa
http2 > 13-08-19, 12:14 PM
hiện tại em có cái form nhiều người dùng . khi em nhập liệu xong sẽ sử dụng nút add new để thêm data vào table .
VD : nhân viên 1 và 2 cùng mở form nhập liệu
ID khi form cấp đều là số 1 . khi nhấn add new thì người nào nhấn trước sẽ thực hiện thành công . và người nhấn sau sẽ báo lõi trùng khóa . vậy em muốn bắt sự kiện đó để khi báo trùng khóa em nhất yes thì tự động cái text ID đó sẽ lấy max số của cái ID +1 gán vào text ID.
Em muốn bắt được sự kiện nút Yes để em có thể gán cho cái textID.value = max (ID)+1 -
RE: cách bắt sự kiện trùng khóa
ongke0711 > 13-08-19, 01:39 PM
- Nếu nhiều người dùng cùng lúc thì bạn không nên gán ID ngay khi mở form mà chi khi [Lưu] thì mới lấy số ID.
- Để đề phòng có khi 2 người bấm nút Lưu cùng lúc hoặc cách nhau thời gian quá ngắn, dữ liệu chưa kịp cập nhật thì dùng cái cách câu giờ trước khi lưu như code trong bài post này.
Link: https://thuthuataccess.com/forum/post-35...l#pid35777 -
RE: cách bắt sự kiện trùng khóa
http2 > 13-08-19, 04:35 PM
Sao lại phải phức tạp quá vậy anh . chỉ cần bẩy cái lỗi đó và rest lại cái table là có số mới rồi mà . nhanh và tiện lợi . tạo thêm table với query thì phúc tạp quá . cứ người sau add trùng thì cứ làm mới rồi lấy số max +1 là xong mà . làm cách anh giới thịu phúc tạp vô đối ^^
để em tìm cách bẩy cái lỗi ^^ -
RE: cách bắt sự kiện trùng khóa
tranthanhan1962 > 13-08-19, 06:22 PM
Cái này đơn giản mà Sử dụng primary key = ID+User người dùng hoặc User người dùng + ID sẽ không bị lỗi trùng khóa mà có thể biết được record đó do ai nhập, sau đó muốn tách ID cũng dễ mà, những số ID trùng nhau chứng tỏ các user tạo record cùng lúc. còn sắp xếp thì vào query xử lý, Đánh số thứ tự thì xử lý trong report, Cái ID autonumber của access khi đi một mình chẳng giúp đỡ gì cho ai cả, ngoài việc cho biết record nào tạo ra trước, record nào tạo ra sau record nào bị xóa. Mà việc này lại càng không có ý nghĩa khi có những record phát sinh trước do nhập thiếu bị nhập sau những record phát sinh sau. -
RE: cách bắt sự kiện trùng khóa
ongke0711 > 13-08-19, 09:37 PM
(13-08-19, 04:35 PM)http2 Đã viết: Sao lại phải phức tạp quá vậy anh . chỉ cần bẩy cái lỗi đó và rest lại cái table là có số mới rồi mà . nhanh và tiện lợi . tạo thêm table với query thì phúc tạp quá . cứ người sau add trùng thì cứ làm mới rồi lấy số max +1 là xong mà . làm cách anh giới thịu phúc tạp vô đối ^^
để em tìm cách bẩy cái lỗi ^^
Giải thuật cốt lõi cho việc chống trùng là giống nhau như bạn nói: lấy số Max + 1. Nhưng các thủ thuật phụ thêm để xử lý nó mới đáng để nói.
- Trong demo trên của tôi là có thêm hàm Reset số thứ tự khi qua ngày, tháng hoặc năm. Có rất nhiều trường hợp, nhiều bạn yêu cầu cần cái hàm này trong việc thiết lập mã phiếu nhập/xuất, nghiêp vụ, giao dịch v.v.. Bạn bây giờ chưa cần tới thì bỏ cái hàm ResetSTT đó ra.
- Trong môi trường đa người dùng bạn phải lường trước các trường hợp.
Ví dụ: có 3 người nhập liệu (A, B, C) cùng bấm nút Lưu. Nếu theo cách bạn làm: truy cập table lấy ID max + 1 rồi cấp phát cho ngừoi dùng
--> khi đó Access sẽ cấp cùng 1 số ID mới đó cho 3 người dùng vì họ bấm cùng lúc. Có thể bấm chênh lệch 50 - 100 ms nhưng Access chưa kịp lưu lại mã ID mới cấp cho người nhập liệu A nên vẫn mã ID cũ mà cấp cho B, C.
--> Sau đó 3 người dùng bấm lưu tiếp.
-->nếu hên sẽ có 1 người lưu được, 2 người không và báo trùng mã cho 2 người kia. Nếu xui (cũng rất khó xảy ra) là lại báo trùng mã cả 3. Lại phải thao tác lại từ đầu và sẽ có trường hợp mã ID sẽ bị nhảy số.
--> Access lại cấp số mới cho một lúc 2 người -> lại đụng lỗi trùng mã lại kiểm tra và cấp số mới ....
Nói túm lại cách của bạn là cấp cùng 1 mã cho nhiều người dùng nếu họ truy cập cùng lúc hoặc trong khoảng thời gian mà Access chưa kịp lưu mã ID mới vừa cấp.
Còn cách của tôi thì khác hoàn toàn: nó giống như xếp hàng đợi. Khi có sự truy cập để lấy STT mới, Access chỉ cấp cho 1 người và nó khoá table ngay khi có 1 người truy cập trước. Giống như đưa vé rồi mới được bước vô cửa vậy. Khi đó ai đến sau sẽ đợi trong khoảng milisecond và Access lại cấp số mới cho một người kế tiếp và cứ như vậy. Sẽ không có lỗi trùng dữ liệu mà chỉ có lỗi không truy cập được table để lấy Số ID mới --> khi đó bẫy lỗi cho chờ như tôi đã đề cập trong bài.
Tôi phải dùng kiểu này vì có nhiều ứng dụng có nhiều người nhập liệu cùng lúc và nhập rất nhanh như tôi đã làm qua là nhập số lô tô các đài. 8 - 10 người nhập cùng lúc trong 15 phút và thao tác nhập cực nhanh, khi đó cái khoá ID sẽ bị đụng tùm lum.
Đối với ứng dụng của bạn, nếu ít giao dịch, ít người dùng nhâp liệu cùng lúc thì cứ dùng cách đơn giản thôi, xui lắm thì bị đụng và tốc độ bị ảnh hưởng đôi chút vì phải cấp phát mã lại nhiều lần vậy thôi. -
RE: cách bắt sự kiện trùng khóa
http2 > 14-08-19, 11:36 AM
Dạ Cám ơn anh . em đã hiểu rồi ạ . em đang test thủ công . đúng là form bên em nhập liệu không nhanh lắm . nên ít sảy ra lỗi như anh nói . chỉ là khi A mở form nhập rồi một lúc khi A chưa lưu thì B lại mở form nhập thì cái "ID" sẽ cấp phát cho A và B là gióng nhau "ví dụ là số 2" . khi A lưu thì là số 2 còn B lưu thì bị báo trùng mã . Nên giờ em thêm 1 txtIDMax vào form và cho value của nó là = Max([ID]) . viết code vào CmdSave là :
Mã PHP:Me.Refresh
If txtIDmax = Null then
ID = 1
Else
ID = txtIDMax + 1
End If
Me.Refresh
vậy là khi A nhấn Save thì nó sẽ làm tươi mới lại data và khi add vào ID rồi thì lại làm mới lại . Khi B nhấn save thì nó cũng làm mới lại rồi mới lấy Max([ID]) để gán cho txtIDMax +1 .
lý thuyết thì là như vậy . không biết chạy thì sao . chưa test .