Đánh giá chủ đề:
  • 2 Votes - 4.5 Average
  • 1
  • 2
  • 3
  • 4
  • 5
[Thủ Thuật] Lưu vết chương trình khi nhập liệu
#1
Xin chào cả nhà.
Tôi có viết một chương trình Access quản lý công việc trong phòng tại cơ quan. Tôi dùng phương pháp BackEnd và FrontEnd để chia sẻ dữ liệu trong mạng Lan, tổng số user khoảng 10 người. Chương trình chạy tốt và hiệu quả. Tuy nhiên có một vấn đề mà lâu nay tôi chưa tìm ra giải pháp tối ưu là làm sao biết được ai đã sửa dữ liệu trên form ngày giờ nào, và sửa như thế nào.
Tôi đã tìm kiếm nhiều giải pháp trên diễn đàn và đã áp dụng, tuy nhiên code rất dài, phức tạp, khó quản lý. Bởi tổng số record trong CSDL hơn 7000 records cùng với 10 users cùng làm việc hàng ngày, quản lý tốt CSDL là nhiệm vụ hàng đầu, hơn nữa trong phòng không phải ai cũng hiểu rõ vấn đề bảo vệ CSDL là quan trọng như thế nào.
Và thật không ngờ, không phải giải pháp cao siêu gì cả, rất đơn giản mà thật hiệu quả. Giờ đây, mỗi sáng tôi chỉ mở form theo dõi là có thể biết ai đã làm gì hôm qua, dữ liệu nào đã chỉnh sửa, giá trị cũ sang giá trị mới ra sao, không phải nhức đầu khi phải phân quyền cho từng user. Bây giờ ai cũng có thể chỉnh sửa dữ liệu và có trách nhiệm với việc thay đổi của mình.
Nói hơi dông dài để các bạn có thể hiểu rõ hơn vấn đề. Hôm nay tôi sẽ chia sẻ giải pháp của tôi với các bạn với mục đích là cùng nhau học hỏi. Biết đâu đây chưa phải là giải pháp tốt nhất. Rất mong sự chia sẻ từ diễn đàn.
I. MÔ TẢ CHƯƠNG TRÌNH
Khi mở chương trình sẽ có Form Đăng nhập như sau
[Hình: Dangnhap.jpg]
Sau khi đăng nhập đúng username và password, click button Đăng nhập sẽ mở ra Form Customers (lấy mẫu từ NorthWind Database của MS Office 2003)
[Hình: Customers.jpg]

Từ đây, bạn có thể sửa bất kỳ record nào, bất kỳ control nào trên form. Sau khi cập nhật dữ liệu xong, bạn đóng Form, thế thì xong.
Thế làm sao bạn có thể biết user nào đã cập nhật dữ liệu, cập nhật khi nào. Đây mới chính là vấn đề cần giải quyết. Chúng ta sẽ có một table tblLuuVetChuongTrinh ghi lại tất cả các hoạt động của user trên form này. Nào bạn hãy mở table tblLuuVetChuongTrinh, chúng ta sẽ có gì.

[Hình: LuuVetChuongTrinh.jpg]

Giờ đây ta đã biết user nào sửa control nào, giá trị cũ qua giá trị mới, ngày giờ cụ thể. Bạn chỉ cần tạo một form lọc những giá trị cần biết để quản lý tốt hơn CSDL của mình.

II. GIẢI QUYẾT VẤN ĐỀ

Trong CSDL mẫu này, bạn hãy import 1table Customers và 1 form Customers từ NorthWind Database, bỏ đi tất cả code trong AfterUpdate của từng Control và Form của Customers Form nguyên gốc.
1. Tạo table tblUsers có cấu trúc như sau:
[Hình: cautructblusers.jpg]
2. Nhập tên user và password của từng user
[Hình: dulieutbluser.jpg]
3. Tạo table tblLuuVetChuongTrinh có cấu trúc như sau:
[Hình: tblluvetchuongtrinh.jpg]

4. Tạo 5 biến toàn cục (Global) trong standard module
Option Compare Database
Public GvarUserName As String
Public varOldValue As String
Public varNewValue As String
Public varControlName As String
Public varFormName As String

Các biến toàn cục này có ý nghĩa thế nào chắc không cần giải thích các bạn nhỉ Tongue_smile

Khi form Đăng nhập mở lên, user chọn username từ combo box và gõ password, sau đó click button Đăng nhập, nếu chọn đúng tất cả sẽ mở form Customers, đồng thời sẽ gán biến toàn cục GvarUsernName = UserName.

Đây là đoạn code kiểm tra khi click vào button đăng nhập (OnClick)

Private Sub cmdDangNhap_Click()
Dim varPassword As String
' Doan code khong cho Control cbUserName trong hay rong
If IsNull(Me.cbUserName) Or Me.cbUserName = "" Then
MsgBox "Please select Username!", vbCritical, "Require Data"
Me.cbUserName.SetFocus
Exit Sub
End If
' Doan code khong cho Control txtPassword trong hay rong
If IsNull(Me.txtPassword) Or Me.txtPassword = "" Then
MsgBox "Please enter Password!", vbCritical, "Require Data"
Me.txtPassword.SetFocus
Exit Sub
End If

varPassword = DLookup("Password", "tblUser", "Username ='" & Me.cbUserName & "'")
If Me.txtPassword = varPassword Then
GvarUserName = Me.cbUserName
DoCmd.Close acForm, Me.Name
DoCmd.OpenForm "Customers"
Else
MsgBox "Incorect Password. Please contact the Administrator.", vbCritical, "Cannot access the Database"
Me.txtPassword.SetFocus
Exit Sub
End If
End Sub


Sau khi form Customers mở lên, user sửa đổi dữ liệu thì sẽ có một hàm lưu lại các thay đổi đó, đồng thời ghi các thay đổi đó vào table tblLuuVetChuongTrinh. Chúng ta đã có 5 biến toàn cục (global) đã định nghĩa ở trên, vấn đề là chúng ta sẽ gán giá trị cho các biến như thế nào. Ở đây với sự kiện AfterUpdate cho từng control trên form chúng ta sẽ gọi một Function có tên GoiHamLuuVetChuongTrinh. Đây chính là cái quan trọng nhất của chương trình, không cao siêu, không phức tạp, cực kỳ đơn giản. Function GoiHamLuuVetChuongTrinh được tôi viết như sau:

Function GoiHamLuuVetChuongTrinh()
If IsNull(Screen.ActiveControl.OldValue) Then
varOldValue = ""
Else
varOldValue = Screen.ActiveControl.OldValue
End If
If IsNull(Screen.ActiveControl.Value) Then
varNewValue = ""
Else
varNewValue = Screen.ActiveControl.Value
End If
varControlName = Screen.ActiveControl.Name
varFormName = Screen.ActiveForm.Name
Call CapNhatLuuVet(GvarUserName, varOldValue, varNewValue, varControlName, varFormName)
End Function


Hàm này sẽ gán từng giá trị cho các biến toàn cục ở trên, ngữ pháp câu lệnh đơn giản, tuy nhiên theo tôi kỹ thuật dùng Screen.ActiveControl đã biến những việc phức tạp trở nên cực kỳ đơn giản. Kỹ thuật này không cần biết Control đó tên gì, giá trị bao nhiêu mà chỉ đơn giản là Screen.ActiveControl.

Function CapNhatLuuVet sẽ add các biến toàn cục vào tblLuuVetChuongTrinh.

Function CapNhatLuuVet(fUserName, fOldValue, fNewValue, fControlName, fFormName)
Dim db As Database
Dim rst As Recordset
Set db = CurrentDb
Set rst = db.OpenRecordset("tblLuuVetChuongTrinh")
rst.AddNew
rst!TenUser = fUserName
rst!GiaTriCu = fOldValue
rst!GiatriMoi = fNewValue
rst!TenControl = fControlName
rst!TenForm = fFormName
rst!NgayCapNhat = Date
rst!GioCapNhat = Time()
rst.Update
rst.Close
Set rst = Nothing
Set db = Nothing
End Function



Sau khi đã có 2 function quan trọng trên, bạn vào từng control một trên form Customers chon sự kiện AfterUpdate và gõ (hoặc copy) chỉ một dòng lệnh sau:

Call GoiHamLuuVetChuongTrinh


Thế là xong, riêng tôi đã cất đi gánh nặng khi phải suy nghĩ về cách phân quyền cho từng user (ai được sửa cái gì, ai không được sửa cái gì, làm sao theo dõi . . .) khi áp dụng kỹ thuật này. Mỗi người đều có một phương pháp riêng để giải quyết các vấn đề trong công việc, sao cho ĐƠN GIẢN, NHANH CHÓNG, HIỆU QUẢ. Rất mong những ý kiến đóng góp của tất cả các bạn ở diễn đàn thuthuataccess.com và hy vọng các bạn có một giải pháp tốt hơn cho vấn đề này.
Chữ ký của n2kp Xin chào, mình là n2kp, Tham gia http://thuthuataccess.com/forum từ ngày 23-05 -12.
Reply
#2
Khá hay!
Mình cũng có module Để theo dõi ai làm gì trong chương trình. Thủ Thuật này mình chia sẻ khá lâu rồi (29/10/10)

http://thuthuataccess.com/forum/thread-377.html

Mong bạn cùng chia sẻ nhiều thủ thuật hay trên diễn đàn nữa!
Chúc tốt lành
Chữ ký của Noname 020
ღღღღღTài sản của Noname (View All Items) ღღღღღ
Reply
Những người đã cảm ơn uronmapu
#3
(23-05-12, 04:35 PM)Noname Đã viết: Khá hay!
Mình cũng có module Để theo dõi ai làm gì trong chương trình. Thủ Thuật này mình chia sẻ khá lâu rồi (29/10/10)

http://thuthuataccess.com/forum/thread-377.html

Mong bạn cùng chia sẻ nhiều thủ thuật hay trên diễn đàn nữa!
Chúc tốt lành

Hi Noname!
Mình cũng đã tham khảo module của bạn, tuy nhiên không giải quyết được vấn đề lưu vết cập nhật từng control trên form.
Cám ơn Noname đã chi sẻ.
Chữ ký của n2kp Xin chào, mình là n2kp, Tham gia http://thuthuataccess.com/forum từ ngày 23-05 -12.
Reply
Những người đã cảm ơn uronmapu
#4
(23-05-12, 04:41 PM)n2kp Đã viết:
(23-05-12, 04:35 PM)Noname Đã viết: Khá hay!
Mình cũng có module Để theo dõi ai làm gì trong chương trình. Thủ Thuật này mình chia sẻ khá lâu rồi (29/10/10)

http://thuthuataccess.com/forum/thread-377.html

Mong bạn cùng chia sẻ nhiều thủ thuật hay trên diễn đàn nữa!
Chúc tốt lành

Hi Noname!
Mình cũng đã tham khảo module của bạn, tuy nhiên không giải quyết được vấn đề lưu vết cập nhật từng control trên form.
Cám ơn Noname đã chi sẻ.

UH, Tùy theo nhu cầu quản lý tới đâu mà mình chế biến thêm thôi! happy
Cái Screen.ActiveControl này hay quá! love struck
Chữ ký của Noname 020
ღღღღღTài sản của Noname (View All Items) ღღღღღ
Reply
Những người đã cảm ơn uronmapu
#5
Từ file Access mẫu NorthWind này, chúng ta từ người chập chững đến các "cao thủ" đều học được rất nhiều điều từ cơ bản đến nâng cao, từ table, query, form, macro, modul....Kết hợp với Help, chúng ta sẽ sớm thành "đại cao thủ" Access
Thân mến
Chữ ký của Xuân Thanh Trăm năm trước thì ta chưa gặp
Trăm năm sau biết gặp được không?
Cuộc đời sắc sắc không không
Thì thôi ta cứ hết lòng vì nhau
ღღღღღTài sản của Xuân Thanh (View All Items) ღღღღღ
Reply
Những người đã cảm ơn Noname , dannynguyen1980 , uronmapu
#6
(23-05-12, 08:43 PM)Xuân Thanh Đã viết: Từ file Access mẫu NorthWind này, chúng ta từ người chập chững đến các "cao thủ" đều học được rất nhiều điều từ cơ bản đến nâng cao, từ table, query, form, macro, modul....Kết hợp với Help, chúng ta sẽ sớm thành "đại cao thủ" Access
Thân mến

Đúng rồi! Các bạn mới học Access sau này nên cài đủ sample để có northwind. Tham khảo cả cách thiết kế cơ sở dữ liệu của họ cũng tiết kiệm được thời gian học tập nhiều lắm!
Chữ ký của Noname 020
ღღღღღTài sản của Noname (View All Items) ღღღღღ
Reply
Những người đã cảm ơn Xuân Thanh , uronmapu
#7
Trong trường hợp mình muốn trong bảng tblLuuvetchuongtrinh có nêu rõ được cả bản ghi nào được user tác động kô ( để biết người sử dụng tác động vào record nào - Ví dụ số hóa đơn nào chẳng hạn )? Vậy phải làm như nào, mong các bạn chỉ giáo thêm, tôi thấy cái này hay và tiện lợi quá. Cám ơn rất nhiều.
Chữ ký của connguoi123 Hãy chia sẻ kinh nghiệm cùng mình trên ThuThuatAccess nhé! Chúc vui vẻ rose
Reply
Những người đã cảm ơn uronmapu
#8
(29-05-12, 05:40 PM)connguoi123 Đã viết: Trong trường hợp mình muốn trong bảng tblLuuvetchuongtrinh có nêu rõ được cả bản ghi nào được user tác động kô ( để biết người sử dụng tác động vào record nào - Ví dụ số hóa đơn nào chẳng hạn )? Vậy phải làm như nào, mong các bạn chỉ giáo thêm, tôi thấy cái này hay và tiện lợi quá. Cám ơn rất nhiều.

Chào bạn,
Bạn có thể thêm một trường (vd:IDHoadon) vào tblLuuvetchuong trình và trong Function CapNhatLuuVet bạn thêm một tham số IDhoadon, lúc đó Function CapNhatLuuVet chi tiết sẽ như thế này:
Function CapNhatLuuVet(IDhoadon, fUserName, fOldValue, fNewValue, fControlName, fFormName)
Dim db As Database
Dim rst As Recordset
Set db = CurrentDb
Set rst = db.OpenRecordset("tblLuuVetChuongTrinh")
rst.AddNew
rst!IDhoadon = IDhoadon
rst!TenUser = fUserName
rst!GiaTriCu = fOldValue
rst!GiatriMoi = fNewValue
rst!TenControl = fControlName
rst!TenForm = fFormName
rst!NgayCapNhat = Date
rst!GioCapNhat = Time()
rst.Update
rst.Close
Set rst = Nothing
Set db = Nothing
End Function

Thân chào.
Chữ ký của n2kp Xin chào, mình là n2kp, Tham gia http://thuthuataccess.com/forum từ ngày 23-05 -12.
Reply
Những người đã cảm ơn Noname , connguoi123 , uronmapu , hungle2006
#9
Thank you N2kp, nhưng bạn thử chưa, mình thử nhưng không được ?
Chữ ký của connguoi123 Hãy chia sẻ kinh nghiệm cùng mình trên ThuThuatAccess nhé! Chúc vui vẻ rose
Reply
Những người đã cảm ơn uronmapu
#10
Bạn có thể đưa file access của bạn lên đây mình xem sao?
Mình đã áp dụng và OK.

Thân chào.
Chữ ký của n2kp Xin chào, mình là n2kp, Tham gia http://thuthuataccess.com/forum từ ngày 23-05 -12.
Reply
Những người đã cảm ơn uronmapu


Có thể liên quan đến chủ đề
Chủ đề: Tác giả Trả lời: Xem: Bài mới nhất
  Tránh xung đột dữ liệu trong access quocdung9999 16 1,700 23-11-16, 11:13 AM
Bài mới nhất: quocdung9999
  [Thủ Thuật] Tạo thanh tiến trình trên Form (Progress bar) khi xử lý dữ liệu ongke0711 18 1,506 21-10-16, 10:17 PM
Bài mới nhất: ongke0711
  [Hỏi] Quá trình thực hiện một lệnh với CSDL dinh_trong_hoa 1 177 02-08-16, 04:06 PM
Bài mới nhất: ongke0711
Photo Hướng dẫn tính tôn kho từ một bảng chi tiết nhập xuất tt1212 8 399 17-06-16, 04:47 PM
Bài mới nhất: tt1212
  Sử dụng Class Module và Kết nối dữ liệu SQL SERVER trong Access VBA lehongduc 42 17,056 12-06-16, 12:28 PM
Bài mới nhất: lehongduc

Chuyển nhanh:


User(s) browsing this thread: 1 Guest(s)
Diễn Đàn Thơ Văn Thi Ẩm Lâu|Nhà Hàng Sông Thơ