2009-07-13 131 views
23

tôi sao chép một đoạn mã VBA từ MSDN cho thấy tôi làm thế nào để lấy kết quả từ một truy vấn SQL vào excel sheet (Excel 2007):Cơ sở dữ liệu Truy cập SQL trong Excel VBA

Sub GetDataFromADO() 

    'Declare variables' 
     Set objMyConn = New ADODB.Connection 
     Set objMyCmd = New ADODB.Command 
     Set objMyRecordset = New ADODB.Recordset 

    'Open Connection' 
     objMyConn.ConnectionString = "Provider=SQLOLEDB;Data Source=localhost;User ID=abc;Password=abc;" 
     objMyConn.Open 

    'Set and Excecute SQL Command' 
     Set objMyCmd.ActiveConnection = objMyConn 
     objMyCmd.CommandText = "select * from myTable" 
     objMyCmd.CommandType = adCmdText 
     objMyCmd.Execute 

    'Open Recordset' 
     Set objMyRecordset.ActiveConnection = objMyConn 
     objMyRecordset.Open objMyCmd 

    'Copy Data to Excel' 
     ActiveSheet.Range("A1").CopyFromRecordset (objMyRecordset) 

End Sub 

tôi đã thêm Microsoft Đối tượng dữ liệu ActiveX 2.1 Thư viện dưới dạng tham chiếu. Và cơ sở dữ liệu này có thể truy cập được.

Bây giờ, khi tôi chạy chương trình con này, nó có một lỗi:

Run-time error 3704: Hoạt động không được phép khi đối tượng được đóng lại.

Trên tuyên bố:

ActiveSheet.Range("A1").CopyFromRecordset (objMyRecordset) 

Bất cứ ý tưởng tại sao?

Cảm ơn.

+0

Help! Tôi gặp lỗi tương tự, nhưng các giải pháp dưới đây không giúp được: http://stackoverflow.com/questions/1682717/vba-adodb-run-time-error-3704 – Steven

Trả lời

20

Tôi đã thêm Danh mục ban đầu vào chuỗi kết nối của mình. Tôi cũng đã bỏ qua cú pháp ADODB.Command có lợi cho việc đơn giản tạo câu lệnh SQL của riêng tôi và mở recordset trên biến đó.

Hy vọng điều này sẽ hữu ích.

Sub GetDataFromADO() 
    'Declare variables' 
     Set objMyConn = New ADODB.Connection 
     Set objMyRecordset = New ADODB.Recordset 
     Dim strSQL As String 

    'Open Connection' 
     objMyConn.ConnectionString = "Provider=SQLOLEDB;Data Source=localhost;Initial Catalog=MyDatabase;User ID=abc;Password=abc;" 
     objMyConn.Open 

    'Set and Excecute SQL Command' 
     strSQL = "select * from myTable" 

    'Open Recordset' 
     Set objMyRecordset.ActiveConnection = objMyConn 
     objMyRecordset.Open strSQL    

    'Copy Data to Excel' 
     ActiveSheet.Range("A1").CopyFromRecordset (objMyRecordset) 

End Sub 
+2

Nó làm việc cho tôi, cảm ơn, hãy nhớ thêm tham chiếu đến Microsoft ActiveX Data Objects 2.1, tôi đã thêm phiên bản 2.6 mặc dù. Ngoài ra, bạn không cần phải đóng kết nối ở cuối? như objMyRecordset.Close? –

0

Đó có phải là chuỗi kết nối thích hợp không?
Phiên bản SQL Server ở đâu?

Bạn sẽ cần xác minh rằng bạn có thể kết nối với SQL Server bằng chuỗi kết nối, bạn đã chỉ định ở trên.

EDIT: Nhìn vào thuộc tính Nhà nước của bộ bản ghi để xem nó có đang mở không?
Ngoài ra, hãy thay đổi thuộc tính CursorLocation thành adUseClient trước khi mở recordset.

1

Tôi đang ngồi ở một máy tính không có các bit phần mềm liên quan, nhưng từ bộ nhớ mã trông sai. Bạn đang thực hiện lệnh nhưng hủy bỏ số RecordSet mà trả lại là objMyCommand.Execute.

tôi muốn làm:

Set objMyRecordset = objMyCommand.Execute 

... và sau đó mất "mở recordset" phần.

15

thay đổi được đề xuất:

  • Đừng gọi Bộ Tư lệnh Execute của đối tượng phương pháp;
  • Đặt thuộc tính Nguồn của đối tượng Recordset làm đối tượng Lệnh của bạn;
  • Gọi phương thức Open của đối tượng Recordset không có tham số;
  • Xóa các dấu ngoặc đơn xung quanh đối tượng Recordset trong cuộc gọi đến CopyFromRecordset;
  • Trên thực tế tuyên bố các biến của bạn :)

đang Revised:

Sub GetDataFromADO() 

    'Declare variables' 
     Dim objMyConn As ADODB.Connection 
     Dim objMyCmd As ADODB.Command 
     Dim objMyRecordset As ADODB.Recordset 

     Set objMyConn = New ADODB.Connection 
     Set objMyCmd = New ADODB.Command 
     Set objMyRecordset = New ADODB.Recordset 

    'Open Connection' 
     objMyConn.ConnectionString = "Provider=SQLOLEDB;Data Source=localhost;User ID=abc;Password=abc;"  
     objMyConn.Open 

    'Set and Excecute SQL Command' 
     Set objMyCmd.ActiveConnection = objMyConn 
     objMyCmd.CommandText = "select * from mytable" 
     objMyCmd.CommandType = adCmdText 

    'Open Recordset' 
     Set objMyRecordset.Source = objMyCmd 
     objMyRecordset.Open 

    'Copy Data to Excel' 
     ActiveSheet.Range("A1").CopyFromRecordset objMyRecordset 

End Sub 
+0

+1 để xóa dấu ngoặc đơn. Các dấu ngoặc đơn không cần thiết kết hợp với các tham chiếu đối tượng dường như gây ra các lỗi VBA lạ – barrowc

+0

Ví dụ này làm việc cho tôi, cảm ơn! – nekomatic

+0

Tôi nhận ra đây là một chủ đề cũ - nhưng đã tự hỏi nếu có một cách để sửa đổi mã trên để lấy các tiêu đề bảng là tốt? – firedrawndagger

0

Thêm set nocount on để đầu proc lưu trữ (nếu bạn đang ở trên SQL Server). Tôi chỉ giải quyết vấn đề này trong công việc của riêng tôi và nó được gây ra bởi kết quả trung gian, chẳng hạn như "1203 Rows Affected", được tải vào Recordset Tôi đã cố gắng sử dụng.

0

@firedrawndagger: liệt kê tên trường/tiêu đề cột lặp qua các recordset Fields việc thu thập và chèn tên:

Dim myRS as ADODB.Recordset 
Dim fld as Field 
Dim strFieldName as String 

For Each fld in myRS.Fields 
    Activesheet.Selection = fld.Name 
    [Some code that moves to next column] 
Next 
Các vấn đề liên quan