2013-04-26 55 views
7

Tôi làm việc trên một Access DB và tôi phải sử dụng một kết nối Datasource đến một Máy chủ SQL.Cách điền một ListBox với ADODB.Recordset (Lỗi 91) Để Thực hiện Tự động hoàn thành trong Access

Để làm được điều mà tôi sử dụng các đối tượng ADODB với:

-ADODB.Connection

-ADODB.Recordset

Mã Up-to-date, sau một quan sát của Ian Kenney

Dim cnn As ADODB.Connection 
    Set cnn = New ADODB.Connection 
    Dim rs As ADODB.Recordset 

    cnn.ConnectionString = "driver={SQL Server};provider=SQLOLEDB;server=10.****;uid=****readonly;pwd=****readonly;database=****" 
    cnn.Open 

    Set rs = cnn.Execute("SELECT [MATRI], [NOMPRE] FROM SCHEME_DB.TABLE WHERE NOMPRE LIKE '*" & Me.Textbox_recherche.Text & "*'") 



    Me.Liste_choix.RowSourceType = "Table/List" 
    Me.Liste_choix.Recordset = rs 

    rs.Close 
    cnn.Close 

(Mã này (một phần của mã) là một cách để thực hiện Tự động hoàn thành trong Access với một TextBox và một ListBox)

Và tôi gặp lỗi 91 khi tôi chạy mã này: "Lỗi 91: Biến đối tượng hoặc Với biến khối không được đặt ".

Tôi không hiểu cách giải quyết vấn đề này.

Xin cảm ơn trước.

Trả lời

5

Bạn đã nói với chúng tôi rằng mã ném Lỗi 91, "Biến đối tượng hoặc Với biến khối không được đặt". Thật không may, bạn không cho biết dòng nào gây ra lỗi. Điều đó buộc chúng ta phải đoán được vấn đề nằm ở đâu.

Một vấn đề là ở đây:

Me.Liste_choix.Recordset = rs 

Đó nỗ lực chuyển nhượng của một đối tượng khác. Các ký hiệu = là đủ cho các bài tập với các kiểu dữ liệu đơn giản ... tức là MyVariable = 2. Tuy nhiên, bạn phải bao gồm từ khóa Set với các nhiệm vụ đối tượng.

Set Me.Liste_choix.Recordset = rs 

Mặc dù bạn nên thực hiện thay đổi đó, tôi không chắc chắn đó là nguyên nhân gây ra lỗi 91; Tôi đã đoán Access sẽ khiếu nại "Sử dụng thuộc tính không hợp lệ" thay thế.

Tuyên bố SELECT là một vấn đề khác, nhưng một lần nữa tôi không chắc liệu nó có góp phần vào lỗi bạn báo cáo hay không. Mệnh đề WHERE sử dụng so sánh Like với mẫu có * làm ký tự đại diện. Truy vấn đó có thể trả về những gì bạn mong đợi khi bạn chạy nó từ DAO. Nhưng bạn đang sử dụng ADO xử lý * chỉ là một ký tự dấu hoa thị mà không có bất kỳ ý nghĩa đặc biệt nào. Vì vậy, truy vấn đó có thể trả về không có hàng khi bạn chạy nó từ ADO. Thay thế * bằng %.

Là lời khuyên chung, nếu mô-đun mã của bạn chưa bao gồm Option Explicit trong phần Tuyên bố, hãy thêm nó. Sau đó chạy Debug-> Compile từ trình đơn chính của VB Editor. Khắc phục mọi thứ mà trình biên dịch phàn nàn. Đảm bảo bạn đã thực hiện những điều đó trước khi khắc phục sự cố thêm.

+0

Cảm ơn bạn, tôi cung cấp cho bạn tiền thưởng nhưng tôi nghĩ rằng một vấn đề quan trọng là cách khai báo đối tượng ADODB.Connection. Chúng ta phải khai báo đối tượng này với .Properties (không biết chính xác tại sao ...) như trong câu trả lời của tôi ... –

4

Bạn đã đóng recordset và kết nối trước khi bạn sử dụng nó

rs đóng ở đây

rs.Close 

và kết nối được đóng ở đây

cnn.Close 

Me.Liste_choix.RowSourceType = "Table/List" 

rs sử dụng ở đây

Me.Liste_choix.Recordset = rs 

Cập nhật Từ docs:

Sử dụng phương thức Close để đóng một đối tượng Connection cũng đóng bất kỳ đối tượng Recordset hoạt động liên quan đến việc kết nối. Một đối tượng Command được kết hợp với đối tượng Connection mà bạn đang đóng sẽ vẫn tồn tại, nhưng nó sẽ không còn được liên kết với một đối tượng Connection; nghĩa là thuộc tính ActiveConnection của nó sẽ được đặt thành Không có gì. Ngoài ra, bộ sưu tập Tham số của đối tượng Lệnh sẽ bị xóa bất kỳ thông số nào do nhà cung cấp xác định .

Sử dụng phương pháp Đóng để đóng đối tượng Recordset, Record hoặc Stream giải phóng dữ liệu được liên kết và bất kỳ quyền truy cập độc quyền nào mà bạn có thể có vào dữ liệu thông qua đối tượng cụ thể này. Sau đó, bạn có thể gọi phương thức mở để mở lại đối tượng có thuộc tính giống nhau hoặc được sửa đổi, . Trong khi đối tượng Recordset bị đóng, hãy gọi bất kỳ phương thức nào yêu cầu một con trỏ trực tiếp tạo ra lỗi.

SQL INJECTION Ngoài ra còn có một sql injection rủi ro bằng cách xây dựng sql trực tiếp từ người dùng nhập vào.
Câu hỏi này (MS Access prepared statements) cho biết cách sử dụng truy vấn được tham số hóa - có thể đáng xem.

+0

Đây không phải là nguyên nhân của lỗi này, khi tôi di chuyển rs.Close và cnn.Close dưới Me.Liste_choix.Recordset = rs, tôi đã có những lỗi. –

+0

bạn đã thử di chuyển rs.close/cnn.close sau khi bạn sử dụng recordset? –

+0

Có ... Me.Liste_choix.RowSourceType = "Bảng/List" Me.Liste_choix.Recordset = rs rs.Close cnn.Close –

7

Tôi đã giải quyết được sự cố (Lỗi 91), Đã xảy ra ba sự cố: tạo ADODB.Connection, * trong phần Chọn (Cảm ơn HansUp) và Đặt cho listbox.recordset (Cảm ơn HansUp) một lần nữa)

tôi đã giải quyết được lỗi:

 Private Sub Textbox_recherche_Change() 

       Dim cnn As ADODB.Connection 
       Set cnn = New ADODB.Connection 
       Dim rs As ADODB.Recordset 

'A important point to solve the Error 91 is to declare your ADODB.Connection with .Properties like that : (I don't use Windows NT authentification but the SQL Server authentification) 


       With cnn 
        .Provider = "Microsoft.Access.OLEDB.10.0" 
        .Properties("Data Provider").Value = "SQLOLEDB" 
        .Properties("Data Source").Value = "10.******" 
        .Properties("User ID").Value = "*****readonly" 
        .Properties("Password").Value = "*****readonly" 
        .Open 
       End With 

    'The second point is to replace the * in the search for the autocompletion by the % 

       Set rs = cnn.Execute("SELECT [NOMPRE] FROM ****.***** WHERE NOMPRE LIKE '%" & Me.Textbox_recherche.Text & "%'") 

    'You have to declare the RowSourceType of your listbox to "Table/Query" 

      Me.Liste_choix.RowSourceType = "Table/Query" 

    'And Finally to SET your recordset like that: 

      Set Me.Liste_choix.Recordset = rs 

       rs.Close 
       cnn.Close 

       Set cnn = Nothing 
       Set rs = Nothing    

      End Sub 
Các vấn đề liên quan