2013-08-05 52 views
12

Tôi đang phát triển công cụ MS Excel 2013 với VBA liên quan đến việc sử dụng QueryTables. Một sự bất tiện mà tôi đang gặp phải là truy cập hiện có QueryTables trong trang tính Excel. Hiện tại, phương pháp duy nhất tôi có thể tìm thấy để truy cập vào bảng truy vấn là bằng cách lập chỉ mục số nguyên. Tôi đã đưa ra đoạn mã sau để có bằng chứng nhanh về khái niệmExcel VBA tham chiếu đến đối tượng QueryTable theo tên

Sub RefreshDataQuery() 

Dim querySheet As Worksheet 
Dim interface As Worksheet 

Set querySheet = Worksheets("QTable") 
Set interface = Worksheets("Interface") 

Dim sh As Worksheet 
Dim QT As QueryTable 

Dim startTime As Double 
Dim endTime As Double 

Set QT = querySheet.ListObjects.item(1).QueryTable 

startTime = Timer 
QT.Refresh 
endTime = Timer - startTime 

interface.Cells(1, 1).Value = "Elapsed time to run query" 
interface.Cells(1, 2).Value = endTime 
interface.Cells(1, 3).Value = "Seconds" 

End Sub 

Điều này làm việc nhưng tôi thực sự không muốn làm theo cách này. Công cụ sản phẩm cuối cùng sẽ có tối đa năm QueryTables khác nhau. Những gì tôi muốn là để chỉ một QueryTable theo tên của nó.

Điều gì sẽ là tốt đẹp là nếu tôi có thể dịch các đoạn mã sau

Set QT = querySheet.ListObjects.item(1).QueryTable 

Để một cái gì đó dọc theo dòng

Set QT = querySheet.ListObjects.items.QueryTable("My Query Table") 

Bất kỳ đề xuất sẽ được nhiều đánh giá cao.

Trả lời

6

Theo this MSDN link for ListObject không có bộ sưu tập nào của QueryTables là tài sản của ListObjects. mã đúng là:

Set QT = querySheet.ListObjects.items(1).QueryTable 

Những gì bạn có thể cần phải là để tham khảo thích hợp ListObject item như (chỉ là ví dụ code):

Dim LS as ListObject 
Set LS = querySheet.ListObjects("My LO 1") 
Set QT = LS.QueryTable 

Các thay thế khác là để tham khảo QT qua WorkSheet property theo cách này:

Set QT = Worksheet("QTable").QueryTables("My Query Table") 
+0

Đặt QT = querySheet.ListObjects.items.QueryTable không biên dịch. Tôi không thấy một mục thích hợp cho ListObjects. Đối với đề nghị thứ hai của bạn, Set QT = Worksheet ("QTable"). QueryTables ("Bảng truy vấn của tôi"), điều này không có tác dụng với tôi vì QTable đã tồn tại từ trước. –

+0

Tôi đã thay đổi thành: 'Set QT = querySheet.ListObjects.items (1) .QueryTable' tương tự như mã của bạn. –

+0

ý của bạn là 'bảng tính đã tồn tại từ trước?' ... rõ ràng là thay đổi tên QT thành cái mà bạn thực sự có. Bạn luôn có thể kiểm tra số lượng QT trong bảng theo cách này: 'Debug.Print Worksheets (" QTable "). QueryTables.Count' và tên của mỗi QT theo cách này:' có. Bạn luôn có thể kiểm tra số lượng QT trong bảng theo cách này: 'Debug.Print Worksheets (" QTable "). QueryTables (1) .Name' cho lần đầu tiên. –

8

Trong Excel 2003 và trước đó, kết nối dữ liệu ngoài sẽ tạo đối tượng QueryTable có cha mẹ là trang tính. Bạn có thể truy cập đối tượng QueryTable, đối tượng một, thông qua đối tượng collection QueryTables. Giống như hầu hết các đối tượng sưu tập, bạn có thể chuyển một số chỉ mục hoặc tên cho phương thức Item (mặc định) để lấy nó.

Sheet1.QueryTables("MyQtName") 

Khi bạn mở trang tính 2003 trong phiên bản mới, nó vẫn có đối tượng QueryTable và có thể truy cập theo cùng một cách. Ngay cả khi bạn chuyển đổi định dạng tệp, QueryTable vẫn tồn tại.

Năm 2007 và các phiên bản sau, chỉ có ba cách để tạo ra một QueryTable đó sẽ là một thành viên của Worksheet.QueryTables:

  1. qua mã
  2. dữ liệu - Từ chữ
  3. dữ liệu - Từ Web

Tất cả các kết nối dữ liệu bên ngoài UI khác trong các phiên bản mới này sẽ không kết quả trong thành viên QueryTables, nhưng trong ListObject. ListObject đó sẽ có một và chỉ một đối tượng QueryTable có thể được truy cập thông qua thuộc tính ListObject.QueryTable.

Đây là tin xấu. QueryTable có cha mẹ trong một ListObject không có một thuộc tính tên. Vâng, nó ở đó, nhưng bạn sẽ nhận được một lỗi thời gian chạy 1004 nếu bạn cố gắng truy cập nó. Tôi đoán MS đã quyết định vì chỉ có một QueryTable cho mỗi ListObject, nó không có ý nghĩa rằng nó nên có một tên.

Nếu bạn cố chuyển đổi Bảng tính.QueryTables.QueryTable thành ListObject, kết nối dữ liệu ngoài sẽ biến mất và ListObject mới không có QueryTable.

Vì QueryTables.Count của bạn trả về 0, tất cả các QueryTables của bạn nằm trong ListObject và không có tên. ListObjects có tên. Bạn có thể sử dụng

Sheet1.ListObjects("MyListName").QueryTable 

Đây là hàm có tên hoặc bảng tính và trả về QueryTable có tên hoặc con của một ListObject có tên đó.

Public Function QueryTableByName(ByVal sName As String, ByRef sh As Worksheet) As QueryTable 

    Dim qt As QueryTable 
    Dim lo As ListObject 

    On Error Resume Next 
     Set qt = sh.QueryTables(sName) 
    On Error GoTo 0 

    If qt Is Nothing Then 
     On Error Resume Next 
      Set lo = sh.ListObjects(sName) 
     On Error GoTo 0 

     If Not lo Is Nothing Then 
      On Error Resume Next 
       Set qt = lo.QueryTable 
      On Error GoTo 0 
     End If 
    End If 

    Set QueryTableByName = qt 

End Function 
+1

Tóm tắt và chức năng tuyệt vời! –

+0

Điều này rất hữu ích và mang tính mô tả. Cảm ơn! –

+0

@Dick Kusleika Đáng buồn là xuất hiện ListObjects không còn có thuộc tính tên trong năm 2013 hoặc thuộc tính QueryTable nữa. –

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