Access
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Access

Xử lý lỗi cấp độ sau đại học

Tôi thích trò chơi ghép hình tốt như anh chàng tiếp theo. Có điều gì đó khiến bạn hài lòng khi bắt đầu với một đống mảnh ghép có vẻ ngẫu nhiên và xem bức tranh dần dần trở nên sống động khi bạn khôi phục lại trật tự cho sự hỗn loạn.

Tuy nhiên, tôi đã ngừng chơi trò chơi ghép hình. Có lẽ đã 13 năm rồi. Hãy để tôi làm phép toán. Tôi có bốn đứa con; Đứa lớn nhất 15 tuổi. Đúng vậy, hai tuổi đúng vào khoảng thời gian mà nó đủ lớn để đi lang thang với một câu đố chưa hoàn thành, bỏ đi với một trong những mảnh đó, và cho chó ăn hoặc máy đo nhiệt độ hoặc nhà vệ sinh.

Và cảm giác thỏa mãn khi đặt mảnh ghép cuối cùng vào một trò chơi ghép hình, việc đặt mảnh áp chót vào trò chơi và nhận ra mảnh ghép cuối cùng bị thiếu.

Đó là cách tôi từng cảm nhận về mã xử lý lỗi của mình.

vbWatchdog's Variables Kiểm tra

Nếu bạn sử dụng vbWatchdog để xử lý lỗi của mình (bạn nên làm như vậy), thì bạn nên làm quen với một trong những tính năng mạnh mẽ nhất của nó:Trình kiểm tra biến. Đối tượng này cung cấp quyền truy cập vào mọi biến trong phạm vi ở mỗi cấp của ngăn xếp cuộc gọi. Mức độ chi tiết đó là vàng kỹ thuật số khi cần khắc phục lỗi.

Trong nhiều năm, tôi đã phát triển một mô-đun xử lý lỗi nâng cao ghi lại tất cả thông tin này. Khi tôi tinh chỉnh việc xử lý lỗi của mình, một nhược điểm bắt đầu nổi lên. Mặc dù tôi có thể trích xuất các giá trị của hầu hết các biến của mình, nhưng tất cả những gì tôi có thể lấy ra từ các biến đối tượng là 'Không có gì' hoặc '{Đối tượng}'.

Đây không phải là tiếng gõ trên vbWatchdog. Một đối tượng có thể là bất cứ thứ gì. Nó có thể hiển thị giá trị nào khác? Tuy nhiên, mảnh ghép còn thiếu này đã gặm nhấm tôi. Tôi có thể cảm thấy cả vũ trụ đang cười nhạo tôi khi tôi đang khắc phục một số lỗi và chìa khóa để phân loại nó được ẩn sau một từ khó nghe đến khó tin, '{Object}'.

Giá như tôi có cách nào đó để biết một hoặc hai thuộc tính nhận dạng của đối tượng đó, tôi có thể tìm ra chính xác điều gì đang xảy ra.

Lần thử đầu tiên

Nỗ lực đầu tiên của tôi trong việc giải quyết vấn đề là công cụ sử dụng của mọi lập trình viên thất vọng:brute force. Trong trình xử lý lỗi chung của mình, tôi đã thêm một Chọn ... Trường hợp xung quanh .TypeDesc .

Ví dụ:tôi có một lớp trình tạo SQL mà tôi gọi là clsSQL . Một trong những thuộc tính trong lớp đó là .LastSQL . Thuộc tính đó chứa câu lệnh SQL cuối cùng mà lớp đã xây dựng hoặc thực thi. Nó có thể là một câu lệnh SELECT hoặc một câu lệnh INSERT / UPDATE / DELETE / etc. ( Tôi đã mượn ý tưởng từ đối tượng DAL của web2py. )

Đây là một phần của trình xử lý lỗi chung của tôi:

Select Case .TypeDesc
Case "clsSQL"
    If Not .Value Is Nothing Then
        ThisVar = .Name & ".LastSQL = " & .Value.LastSQL
    End If

Theo thời gian, tôi đã bắt đầu thêm các loại đối tượng tùy chỉnh bổ sung vào danh sách này. Với mỗi loại tùy chỉnh, tôi sẽ cần tìm nạp một thuộc tính tùy chỉnh khác nhau.

Tôi đã có mảnh ghép cuối cùng cho câu đố. Vấn đề là tôi thấy nó nổi trong bát nước của con chó, tất cả đều bị nhai hết ở một bên. Tôi đoán bạn có thể nói câu đố của tôi đã hoàn thành, nhưng đó là một chiến thắng của người Pyrrhic.

Một phương pháp chữa bệnh có hại nhiều hơn lợi

Tôi nhanh chóng nhận ra rằng giải pháp này sẽ không mở rộng quy mô. Có rất nhiều vấn đề. Đầu tiên, mã xử lý lỗi toàn cầu của tôi sẽ bị phình ra. Tôi giữ mã xử lý lỗi của mình trong một mô-đun tiêu chuẩn duy nhất trong thư viện mã của tôi. Điều đó có nghĩa là bất cứ khi nào tôi muốn thêm hỗ trợ cho một mô-đun lớp, mã đó sẽ được thêm vào mọi dự án của tôi. Điều đó đúng ngay cả khi mô-đun lớp chỉ được sử dụng trong một dự án duy nhất.

Vấn đề tiếp theo là tôi đã đưa các phần phụ thuộc bên ngoài vào mã xử lý lỗi của mình. Điều gì sẽ xảy ra nếu tôi thay đổi clsSQL của mình lớp vào một ngày nào đó và đổi tên hoặc xóa .LastSQL phương pháp? Cơ hội nào để tôi nhận ra rằng sự phụ thuộc như vậy tồn tại khi tôi đang làm việc trong clsSQL của mình lớp? Cách tiếp cận này sẽ nhanh chóng sụp đổ dưới sức nặng của chính nó trừ khi tôi tìm ra giải pháp thay thế.

Tìm kiếm giải pháp trong Python

Tôi nhận ra rằng những gì tôi thực sự muốn là một số cách để xác định một đại diện chính tắc của một đối tượng từ bên trong đối tượng đó . Tôi muốn có thể triển khai biểu diễn này đơn giản hoặc phức tạp nếu cần. Tôi muốn có một cách để đảm bảo rằng nó sẽ không nổ tung trong thời gian chạy. Tôi muốn nó hoàn toàn là tùy chọn cho mọi mô-đun lớp.

Đây có vẻ như là một danh sách mong muốn dài, nhưng tôi đã có thể đáp ứng mọi mục trên đó với giải pháp mà tôi tìm thấy.

Một lần nữa, tôi mượn một ý tưởng từ Python. Tất cả các đối tượng Python đều có một thuộc tính đặc biệt được gọi là ._repr . Thuộc tính này là biểu diễn chuỗi của đối tượng. Theo mặc định, nó sẽ trả về tên kiểu và địa chỉ bộ nhớ của cá thể đối tượng. Tuy nhiên, các lập trình viên Python có thể xác định một .__repr__ để ghi đè hành vi mặc định. Đây là phần hấp dẫn mà tôi muốn cho các lớp VBA của mình.

Cuối cùng tôi đã tìm ra giải pháp lý tưởng của mình. Thật không may, tôi đã tìm thấy nó ở một ngôn ngữ khác, nơi giải pháp thực sự là một tính năng của chính ngôn ngữ đó . Điều đó sẽ giúp tôi như thế nào trong VBA? Hóa ra ý tưởng là một phần quan trọng; Tôi chỉ cần có một chút sáng tạo trong việc triển khai.

Các giao diện để giải cứu

Để chuyển khái niệm Python này vào VBA, tôi đã chuyển sang một tính năng hiếm khi được sử dụng của ngôn ngữ:giao diện và toán tử TypeOf. Đây là cách nó hoạt động.

Tôi đã tạo một mô-đun lớp mà tôi đặt tên là iRepresentation . Theo quy ước, các giao diện trong hầu hết các ngôn ngữ đều được đặt tên bằng chữ "i". Tất nhiên, bạn có thể đặt tên cho các mô-đun của mình bất cứ thứ gì bạn thích. Đây là mã đầy đủ cho iRepresentation của tôi lớp học.

iRepresentation.cls

`--== iRepresentation ==-- class module
Option Compare Database
Option Explicit

Public Property Get Repr() As String
End Property

Tôi nên chỉ ra rằng không có gì đặc biệt về một mô-đun lớp đóng vai trò như một giao diện trong VBA. Điều đó, ý tôi là không có từ khóa cấp mô-đun hoặc thuộc tính ẩn nào mà chúng ta cần đặt. Chúng tôi thậm chí có thể khởi tạo một đối tượng mới bằng cách sử dụng kiểu này, mặc dù sẽ không có nhiều điểm (một ngoại lệ là thử nghiệm, nhưng đó là một chủ đề cho một ngày khác). Ví dụ:mã sau sẽ là mã hợp lệ:

Dim Representation As iRepresentation
Set Representation = New iRepresentation

Debug.Print Representation.Repr

Bây giờ, giả sử tôi có một mô-đun lớp tùy chỉnh có tên oJigsawPuzzle . Mô-đun lớp có một số thuộc tính và phương thức, nhưng chúng tôi muốn một mô-đun sẽ giúp chúng tôi xác định đối tượng JigsawPuzzle mà chúng tôi đang xử lý khi có lỗi. Một ứng cử viên rõ ràng cho một công việc như vậy là SKU, nó xác định duy nhất câu đố là một sản phẩm trên các kệ hàng. Tất nhiên, tùy thuộc vào tình hình của chúng tôi, chúng tôi cũng có thể muốn đưa thông tin khác vào bản trình bày của mình.

oJigsawPuzzle.cls

'--== oJigsawPuzzle ==-- class module
Option Compare Database
Option Explicit

Implements iRepresentation   ' <-- We need this line...

Private mSKU As String
Private mPieceCount As Long
Private mDesigner As String
Private mTitle As String
Private mHeightInInches As Double
Private mWidthInInches As Double

'... and these three lines
Private Property Get iRepresentation_Repr() As String
    iRepresentation_Repr = mSKU
End Property

Đây là nơi điều kỳ diệu đến. Khi chúng ta đang làm việc theo cách của mình thông qua đối tượng Variables Inspector, bây giờ chúng ta có thể kiểm tra từng biến đối tượng để xem liệu nó có triển khai giao diện này hay không. Và, nếu có, chúng tôi có thể lấy giá trị đó và ghi lại giá trị đó cùng với phần còn lại của các giá trị biến của chúng tôi.

Đoạn trích của trình xử lý lỗi

' --== Global Error Handler excerpt ==--

'Include Repr property value for classes that 
'        implement the iRepresentation interface
If TypeOf .Value Is iRepresentation Then
    Dim ObjWithRepr As iRepresentation
    Set ObjWithRepr = .Value
    ThisVar = .Name & ".Repr = " & ObjWithRepr.Repr
End If

Và với điều đó, câu đố xử lý lỗi của tôi đã hoàn thành. Tất cả các phần được tính. Không có vết cắn. Không có mảnh nào bị bong ra. Không có không gian trống.

Cuối cùng tôi đã khôi phục lại trật tự cho sự hỗn loạn.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Làm thế nào để chuyển đổi một truy vấn thông thường thành một truy vấn bảng chéo trong Access

  2. Thực tiễn Kém trong Thiết kế Cơ sở dữ liệu

  3. Cách làm nổi bật các bản ghi hoặc giá trị trong báo cáo Microsoft Access bằng cách sử dụng định dạng có điều kiện

  4. Quyền truy cập ODBC từ Windows Server Core

  5. Lớp cơ sở và các biến thể đối tượng có nguồn gốc