Sử dụng OnEntry để đánh dấu sự thay đổi trên Sheet (1 người xem)

Liên hệ QC

Người dùng đang xem chủ đề này

nghiaphuc

Thành viên gạo cội
Thành viên danh dự
Tham gia
25/9/09
Bài viết
5,729
Được thích
8,858
Giới tính
Nam
Nghề nghiệp
Giáo viên
Chào cả nhà!
Em có bài toán thế này: Trong Workbook có 1 name Flag với giá trị ban đầu là FALSE. Em cần viết code để khi có bất kỳ sự thay đổi nào về giá trị trên Sheet1 thì name Flag sẽ được đổi thành TRUE (mục đích là để đánh dấu sự thay đổi trên sheet).
Em đã sử dụng code như sau:
[GPECODE=vb]Private Sub Auto_Open()
Dim Nm As Name
For Each Nm In ThisWorkbook.Names
Nm.Delete
Next
ThisWorkbook.Names.Add "Flag", RefersTo:=False
Sheet1.OnEntry = "Main"
End Sub
'-------------------------------------------
Sub Main()
ThisWorkbook.Names("Flag").RefersTo = True
End Sub
'-------------------------------------------
Private Sub Auto_Close()
Sheet1.OnEntry = ""
End Sub[/GPECODE]
Tuy nhiên khi chạy thì code gặp vấn đề như sau: Code chỉ hoạt động đúng yêu cầu khi nhập giá trị trực tiếp từ bàn phím, còn các trường hợp khác (xóa giá trị, chọn giá trị từ Validation, copy từ nơi khác dán vào) thì code không có tác dụng.

Câu hỏi đặt ra là: Phải sửa code như thế nào để đáp ứng được yêu cầu? Rất mong nhận được sự giúp đỡ của mọi người. Xin cảm ơn!
 

File đính kèm

Chào cả nhà!
Em có bài toán thế này: Trong Workbook có 1 name Flag với giá trị ban đầu là FALSE. Em cần viết code để khi có bất kỳ sự thay đổi nào về giá trị trên Sheet1 thì name Flag sẽ được đổi thành TRUE (mục đích là để đánh dấu sự thay đổi trên sheet).
Em đã sử dụng code như sau:
[GPECODE=vb]Private Sub Auto_Open()
Dim Nm As Name
For Each Nm In ThisWorkbook.Names
Nm.Delete
Next
ThisWorkbook.Names.Add "Flag", RefersTo:=False
Sheet1.OnEntry = "Main"
End Sub
'-------------------------------------------
Sub Main()
ThisWorkbook.Names("Flag").RefersTo = True
End Sub
'-------------------------------------------
Private Sub Auto_Close()
Sheet1.OnEntry = ""
End Sub[/GPECODE]
Tuy nhiên khi chạy thì code gặp vấn đề như sau: Code chỉ hoạt động đúng yêu cầu khi nhập giá trị trực tiếp từ bàn phím, còn các trường hợp khác (xóa giá trị, chọn giá trị từ Validation, copy từ nơi khác dán vào) thì code không có tác dụng.

Câu hỏi đặt ra là: Phải sửa code như thế nào để đáp ứng được yêu cầu? Rất mong nhận được sự giúp đỡ của mọi người. Xin cảm ơn!

OnEntry vốn nó thế. Khi bạn nhấn Delete để xóa cell rồi Enter (hoặc click cell khác) để kết thúc hoặc Ctrl + V để dán vào cell rồi Enter (hoặc click cell khác) để kết thúc thì không sẩy ra OnEntry. Bạn có viết code nào chăng nữa thì cũng không có OnEntry. Thế thôi.
Sao bạn không dùng Worksheet_Change? OnEntry nó có "chiêu" gì tởm chăng?
 
Upvote 0
OnEntry vốn nó thế. Khi bạn nhấn Delete để xóa cell rồi Enter (hoặc click cell khác) để kết thúc hoặc Ctrl + V để dán vào cell rồi Enter (hoặc click cell khác) để kết thúc thì không sẩy ra OnEntry. Bạn có viết code nào chăng nữa thì cũng không có OnEntry. Thế thôi.
Sao bạn không dùng Worksheet_Change? OnEntry nó có "chiêu" gì tởm chăng?
Thực ra thì cái món OnEntry này em cũng mới biết đây thôi và nó có tác dụng giống như Worksheet_Change. Em chưa so sánh được giữa 2 cái này cái nào "lợi hại" hơn nhưng mà Worksheet_Change thì code phải đi kèm với Sheet, còn OnEntry thì code nằm trong module nên có vẻ như nó tiện lợi hơn trong việc lưu trữ và phục hồi code nếu gặp sự cố ai đó dùng Antivirus xóa mất Macro đó mà.
Mong các anh chị và các bạn giúp đỡ code cho vấn đề này. Dùng cách nào không quan trọng, miễn là đạt được yêu cầu: Khi có bất kỳ sự thay đổi nào về giá trị trên sheet thì đánh dấu lại (có thể vào biến, vào name hay vào cái gì đó để nhận biết được).
 
Upvote 0
Mong các anh chị và các bạn giúp đỡ code cho vấn đề này. Dùng cách nào không quan trọng, miễn là đạt được yêu cầu: Khi có bất kỳ sự thay đổi nào về giá trị trên sheet thì đánh dấu lại (có thể vào biến, vào name hay vào cái gì đó để nhận biết được).

Đánh dấu vào đâu còn tùy vào việc sử dụng. Nếu là tôi thì:
- Sẽ đánh dấu bằng cách dùng SaveSettings (đưa giá trị vào Registy) nếu như file chỉ dùng trên máy tôi
- Sẽ đánh dấu vào 1 cell hoặc 1 name nếu như file dùng cho nhiều máy
-------------
Phần code thì tôi không nghĩ rằng Phúc không làm được. Worksheet_Change hoặc Worksheet_Calculate có vấn đề gì chứ?
Nếu không thích code đặt trong sheet, có thể dùng Class (để tiện cho việc Save AddIn)
 
Lần chỉnh sửa cuối:
Upvote 0
Thử đưa cho bạn một "tối kiến". Ví dụ:
Mã:
Private Sub Worksheet_Change(ByVal Target As Range)
    ThisWorkbook.Comments = ThisWorkbook.Comments & ";" & Target.Address(0, 0)
End Sub
 
Upvote 0
Đánh dấu vào đâu còn tùy vào việc sử dụng. Nếu là tôi thì:
- Sẽ đánh dấu bằng cách dùng SaveSettings (đưa giá trị vào Registy) nếu như file chỉ dùng trên máy tôi
- Sẽ đánh dấu vào 1 cell hoặc 1 name nếu như file dùng cho nhiều máy
-------------
Phần code thì tôi không nghĩ rằng Phúc không làm được. Worksheet_Change có vấn đề gì chứ?
Nếu không thích code đặt trong sheet, có thể dùng Class (để tiện cho việc Save AddIn)
Em mô tả rõ hơn một chút để dễ hình dung: Em đang làm một chương trình quản lý điểm cho trường, file này sẽ đặt ở 1 máy và share ra mạng LAN cho nhiều giáo viên cùng nhập dữ liệu (điểm, hạnh kiểm, số ngày nghỉ, phân công chuyên môn,...) từ nhiều máy khác nhau. Mỗi khi giáo viên cần nhập dữ liệu (các loại như trên) thì sẽ trích xuất dữ liệu tương ứng trong Database ra để họ nhập, sửa. Khi giáo viên nhập dữ liệu thì em cần biết rằng có sự thay đổi giá trị trên sheet để thông báo cho họ quyết định việc có lưu sự thay đổi vào Database không.

Em chọn đánh dấu vào name vì thấy có vẻ như "chuyên nghiệp" hơn (có thể ẩn name này đi).
Tối qua em cũng đã thử với Worksheet_Change nhưng có vẻ chưa ổn, vừa thử lại thì thấy được. Mặc dù không thích Worksheet_Change lắm (vì code phải đi kèm với sheet) nhưng có lẽ cũng dùng cái này vậy:
Mã:
Private Sub Worksheet_Change(ByVal Target As Range)
    ThisWorkbook.Names("Flag").RefersTo = True
End Sub
Còn đặt code trong Class thì thực sự là em chưa dùng bao giờ nên mù tịt.
Thử đưa cho bạn một "tối kiến". Ví dụ:
Mã:
Private Sub Worksheet_Change(ByVal Target As Range)
    ThisWorkbook.Comments = ThisWorkbook.Comments & ";" & Target.Address(0, 0)
End Sub
Em chỉ cần đánh dấu có sự thay đổi thôi, không cần địa chỉ của ô có thay đổi anh ạ.
 
Lần chỉnh sửa cuối:
Upvote 0
Còn đặt code trong Class thì thực sự là em chưa dùng bao giờ nên mù tịt.

.

Dễ ồm!
1> Chèn 1 class và đặt tên cho nó (clsEvents chẳng hạn)
Code trong class:
Mã:
Public WithEvents ExlApp As Application
Private Sub Class_Initialize()
  Set ExlApp = Application
End Sub
Private Sub Class_Terminate()
  Set ExlApp = Nothing
End Sub
Private Sub ExlApp_SheetChange(ByVal Sh As Object, ByVal Target As Range)
  On Error Resume Next
  '[COLOR=#ff0000]Code ĐÁNH DẤU gì tùy ý[/COLOR]
End Sub
2> Code trong Module
Mã:
Dim ExlObj As New clsEvents
Sub Event_Start()
  If ExlObj Is Nothing Then Set ExlObj = New clsEvents
End Sub
Sub Event_Stop()
  Set ExlObj = Nothing
End Sub
Chạy Sub Event_Start để khởi động sự kiện (có thể đổi tên Sub thành Auto_Open) và chạy Sub Event_Stop để tắt sự kiện (có thể đổi tên Sub thành Auto_Close)
Đât biệt dạng code này có thể Save thành 1 AddIn để dùng sự kiện Change cho mọi file Excel
 
Lần chỉnh sửa cuối:
Upvote 0

Bài viết mới nhất

Back
Top Bottom