VBA Nâng cao: Phương pháp tắt và bật sự kiện Application tối ưu

Liên hệ QC

HeSanbi

Nam Nhân✨Hiếu Lễ Nghĩa Trí Tín✨
Tham gia
24/2/13
Bài viết
2,382
Được thích
3,538
Giới tính
Nam
Hôm nay tôi giới thiệu các bạn phương pháp viết mã Nâng cao đơn giản hóa việc tắt sự kiện và thay đổi cài đặt trong Application của Excel một cách tối ưu, để thuận tiện trong việc viết mã cho những ứng dụng lớn.

Tại sao tôi lại viết ra phương pháp này? Các lý do mà tôi phải viết ra phương pháp này, như dưới đây:

  1. Khi tôi viết ứng dụng lớn thì việc tắt sự kiện và thay đổi cài đặt đã lặp đi lặp lại nhiều lần, làm mã của tôi nhìn bị rối mắt. Làm cho mã của tôi dài thêm.
  2. Khi tắt sự kiện trong nhiều thủ tục lòng trong nhiều thủ tục khác, thì đã gây ra lỗi bật lại sự kiện trong thủ tục con không hợp lí.
Phương pháp dưới đây được tối ưu như sau:
  1. Tắt sự kiện và thay đổi cài đặt tùy chọn.
  2. Tắt sự kiện và thay đổi cài đặt mã gọn hơn.
  3. Tắt sự kiện và thay đổi cài đặt nhiều thủ tục trong thủ tục mà không gây ra rối. Không bật tắt sự kiện lẫn lộn nhau.
Cách sử dụng phương pháp với 2 thủ tục SpeedOn SpeedOff:
  1. SpeedOn: là thủ tục dùng để tắt sự kiện ScreenUpdating, EnableEvents, và chuyển các cài đặt khác về trạng thái ngừng tác động.
  2. SpeedOff: là thủ tục ngược lại của SpeedOn.
Với các đối số kiểu Integer nhập vào thủ tục là -1, 0, 1, 3 đại diện cho các chỉ thị như sau:
  • -1: Không làm gì cả, ví dụ: SpeedOn Events:=-1, thì sự kiện Events không bật cũng không tắt
  • 0: Tắt hoặc bật sự kiện và cài đặt, trả lại giá trị cho lần gọi lại. Hỗ trợ cho đối số nhập là biến. ví dụ: e = 0 gọi SpeedOn Events:=e, biến e sẽ nhận lại một giá trị khác nếu sự kiện đó đã được thay đổi. Và gọi SpeedOff Events:=e để hoàn lại.
  • 1: Tắt hoặc bật sự kiện và cài đặt, không trả lại giá trị. Nếu cài đặt đã đổi trước đó bởi biến số là 0, thì chỉ thị này không có đủ quyền thay đổi.
  • 3. Bắt buộc tắt hoặc bật sự kiện và cài đặt. Nếu cài đặt đã đổi trước đó bởi biến số là 0, thì chỉ thị này vượt quyền và thay đổi cài đặt.
Nếu muốn thay đổi sự kiện mong muốn các bạn có thể gõ thêm tham số đại diện: ví dụ SpeedOn Events:=1, Screen:=-1


Trong mã bên dưới các bạn sẽ thấy ví dụ mà tôi đã lòng các hàm bật tắt sự kiện vào thủ tục nằm trong thủ tục.

Các bạn có thể đọc và thực thi các ví dụ bên dưới trong Module để hiểu rõ phương pháp.

Các bạn có thể đọc thêm các bài viết của tôi tại tag
#sanbi udf


JavaScript:
Private Sub AppFaster_test()
  Dim e1%, e2%, e3%:
  Debug.Print "1";
  SpeedOn e1, e2, e3
  AppFaster_test2
  Debug.Print "1";
  SpeedOff e1, e2, e3
End Sub
Private Sub AppFaster_test2()
  Dim e1%, e2%, e3%:
  Debug.Print "2";
  SpeedOn e1, e2, e3
  AppFaster_test3
  Debug.Print "2";
  SpeedOff e1, e2, e3
End Sub
Private Sub AppFaster_test3()
  Dim e1%, e2%, e3%:
  AppFaster_test4
  Debug.Print "3";
  SpeedOn e1, e2, e3
  Debug.Print "3";
  SpeedOff e1, e2, e3
End Sub
Private Sub AppFaster_test4()
  Dim e1%, e2%, e3%:  e2 = 3
  Debug.Print "4";
  SpeedOff e1, e2, e3
End Sub

Sub SpeedOn( _
             Optional Screen% = 1, Optional Events% = 1, Optional Calcula% = -1, Optional Display% = -1, Optional CalSave% = -1, Optional cursor% = -1, Optional statusBar% = -1, Optional EnableCancelKey% = -1)
  AppFaster True, Screen, Events, Calcula, Display, CalSave
End Sub
Sub SpeedOff(Optional Screen% = 1, Optional Events% = 1, Optional Calcula% = -1, Optional Display% = -1, Optional CalSave% = -1, Optional cursor% = -1, Optional statusBar% = -1, Optional EnableCancelKey% = -1)
  AppFaster False, Screen, Events, Calcula, Display, CalSave
End Sub
Private Sub AppFaster(Optional ByVal fast As Boolean = False, _
             Optional Screen% = 1, Optional Events% = 1, Optional Calcula% = -1, Optional Display% = -1, Optional CalSave% = -1, Optional cursor% = -1, Optional statusBar% = -1, Optional EnableCancelKey% = -1)
  'Fast: 0 | 1
  'Slow: 0 | 1 | 2 | 3
  'Skip: #0 #1
  On Error Resume Next
  Static e1%, e2%, e3%, e4%, e5%, e6%, e7%, e8%, dt As Date
  Dim V1%, v2%, v3&, k%, b%, ot As Boolean, y As Boolean
  ot = dt > 0 And ((dt + TimeSerial(0, 0, 15)) < Now)
  V1 = Screen:  v2 = e1: GoSub sw:  Screen = V1: e1 = v2
  V1 = Events:  v2 = e2: GoSub sw:  Events = V1: e2 = v2
  V1 = Calcula: v2 = e3: GoSub sw: Calcula = V1: e3 = v2
  V1 = Display: v2 = e4: GoSub sw: Display = V1: e4 = v2
  V1 = CalSave: v2 = e5: GoSub sw: CalSave = V1: e5 = v2
  'V1 = CalSave: v2 = e6: GoSub sw: cursor = V1: e6 = v2
  'V1 = CalSave: v2 = e7: GoSub sw: statusBar = V1: e7 = v2
  'V1 = CalSave: v2 = e8: GoSub sw: EnableCancelKey = V1: e8 = v2
  Err.clear
 
  If y Then dt = Now
Exit Sub
sw: k = k + 1: v3 = 0: b = 0: If ot Then v2 = 0
  If fast Then GoSub fast Else GoSub slow
Return
fast:
With Application
  Select Case True
  Case V1 = 1 And v2 = 0: b = 1
  Case V1 = 0 And v2 = 0: b = 2
  Case V1 = 0 And v2 = 2: b = 3
  End Select
 
  If b Then
    Select Case k
    Case 1: v3 = .ScreenUpdating: If v3 Then .ScreenUpdating = False
    Case 2: v3 = .EnableEvents: If v3 Then .EnableEvents = False
    Case 3: Err.clear: v3 = .Calculation <> -4135: If v3 And Err = 0 Then .Calculation = -4135
    Case 4: v3 = .DisplayAlerts: If v3 Then .DisplayAlerts = False
    Case 5: Err.clear: v3 = .CalculateBeforeSave: If v3 And Err = 0 Then .CalculateBeforeSave = False
    Case 6: v3 = .cursor <> xlWait: If v3 Then .cursor = xlWait
    Case 7: v3 = .statusBar: If v3 Then .statusBar = False
    Case 8: v3 = .EnableCancelKey <> xlErrorHandler: If v3 Then .EnableCancelKey = xlErrorHandler
    End Select
    If v3 Then
      y = True
      Select Case b
      Case 1: V1 = 1: v2 = 0
      Case 2: V1 = 2: v2 = 1
      Case 3: V1 = 1: v2 = 1
      End Select
    End If
  End If
End With
Return
slow:
With Application
  Select Case True
  Case V1 = 0 And v2 = 0: b = 1
  Case V1 = 1 And v2 = 0: b = 2
  Case V1 = 2 And v2 = 1: b = 3: v2 = 0
  Case V1 = 3:            b = 4: v2 = switch(v2 = 0, 0, v2 = 1, 2, True, 2)
  End Select
  If b Then
    Select Case k
    Case 1: v3 = .ScreenUpdating: If v3 = 0 Then .ScreenUpdating = True
    Case 2: v3 = .EnableEvents: If v3 = 0 Then .EnableEvents = True
    Case 3: Err.clear: v3 = .Calculation = -4105: If v3 = 0 And Err = 0 Then .Calculation = -4105
    Case 4: v3 = .DisplayAlerts: If v3 = 0 Then .DisplayAlerts = True
    Case 5: Err.clear: v3 = .CalculateBeforeSave: If v3 = 0 And Err = 0 Then .CalculateBeforeSave = True
    Case 6: v3 = .cursor <> xlDefault: If v3 Then .cursor = xlDefault
    Case 7: v3 = .statusBar: If v3 Then .statusBar = False
    Case 8: v3 = .EnableCancelKey <> xlInterrupt: If v3 Then .EnableCancelKey = xlInterrupt
    End Select
  End If
End With
Return
End Sub
 
Lần chỉnh sửa cuối:
Web KT
Back
Top Bottom