Đố vui về ADO, DAO - T3/15 (1 người xem)

Liên hệ QC

Người dùng đang xem chủ đề này

Hai Lúa Miền Tây

❆❆❆❆❆❆❆❆
Thành viên BQT
Administrator
Tham gia
18/3/08
Bài viết
8,311
Được thích
15,874
Giới tính
Nam
Nghề nghiệp
Làm ruộng.
Lâu quá không khởi động chủ đề này, hôm nay xin đưa ra câu đố như sau:

Làm thế nào ta có thể liệt kê tất cả tên sheet, name, vùng in... mà không dùng vòng lặp?
 
cho góp vui cách của dân mù VBA :D
Mã:
Sub getnames()


Dim cnn As New ADODB.Connection
Dim XLName As String
Dim rs As New ADODB.Recordset
Dim Arr As Variant
Dim cArr As Variant
Dim rsArr As Variant
Dim lc As String
Dim destRG As String


XLName = "D:\\myfile.xlsx"


Application.ScreenUpdating = False
With cnn
    .Provider = "Microsoft.ACE.OLEDB.12.0"
    .ConnectionString = "Data Source='" & XLName & "';" & _
           "Extended Properties=""Excel 12.0;"""
    .Open
End With
Set rs = cnn.OpenSchema(adSchemaTables)
Arr = rs.GetRows
lc = Split(Cells(1, UBound(Arr, 2) + 1).Address(True, False), "$")(0)
destRG = "A1:" & lc & (UBound(Arr) + 1)
Sheet1.Range(destRG).Value = Arr
cArr = Sheet1.Range(destRG).Value
Sheet1.Range(destRG).ClearContents
rsArr = WorksheetFunction.Index(cArr, 3)


Sheet1.Range("A1:A" & UBound(rsArr)).Value = WorksheetFunction.Transpose(rsArr)
Sheet1.Range("A1:A" & UBound(rsArr)).Replace "$", ""
rs.Close
cnn.Close


Application.ScreenUpdating = True


End Sub
 
cho góp vui cách của dân mù VBA :D
Mã:
Sub getnames()


Dim cnn As New ADODB.Connection
Dim XLName As String
Dim rs As New ADODB.Recordset
Dim Arr As Variant
Dim cArr As Variant
Dim rsArr As Variant
Dim lc As String
Dim destRG As String


XLName = "D:\\myfile.xlsx"


Application.ScreenUpdating = False
With cnn
    .Provider = "Microsoft.ACE.OLEDB.12.0"
    .ConnectionString = "Data Source='" & XLName & "';" & _
           "Extended Properties=""Excel 12.0;"""
    .Open
End With
Set rs = cnn.OpenSchema(adSchemaTables)
Arr = rs.GetRows
lc = Split(Cells(1, UBound(Arr, 2) + 1).Address(True, False), "$")(0)
destRG = "A1:" & lc & (UBound(Arr) + 1)
Sheet1.Range(destRG).Value = Arr
cArr = Sheet1.Range(destRG).Value
Sheet1.Range(destRG).ClearContents
rsArr = WorksheetFunction.Index(cArr, 3)


Sheet1.Range("A1:A" & UBound(rsArr)).Value = WorksheetFunction.Transpose(rsArr)
Sheet1.Range("A1:A" & UBound(rsArr)).Replace "$", ""
rs.Close
cnn.Close


Application.ScreenUpdating = True


End Sub

Bạn đã đi đúng hướng, tuy nhiên:
1. Code hơi dài, có thể rút gọn lại hơn nữa?
2. Code bỏ qua vùng có AutoFilter?
 
Lần chỉnh sửa cuối:
anh nói thế thì em như "vịt nghe sấm " :D . Nhờ anh chỉ giáo vậy .
 
anh nói thế thì em như "vịt nghe sấm " :D . Nhờ anh chỉ giáo vậy .

Có gì đâu bạn, ý mình có 2 ý như sau:
1. Code bạn dài, có thể rút ngắn lại cho gọn, nên bỏ qua những công đoạn không cần thiết.
2. Code của bạn không lấy tên vùng mà trên sheet có autofilter.
 
Lần chỉnh sửa cuối:
hai anh cho hỏi chút
sao chép đoạn code bài #2 về nó báo lổi
"User defined type not defined"
ở dòng
Dim cnn As New ADODB.Connection

phải làm sao xóa lổi này ạ

cám ơn
===========
à, đã kiếm được lời giải, nhờ anh hai lúa xóa giúp

cám ơn

============
HLMT: Xóa làm chi, để cho mọi người học luôn.
 
Chỉnh sửa lần cuối bởi điều hành viên:
dân mù VBA mà anh . có những cái em ko tự giải thích đc . thí dụ như
đối với file excel nhẹ : truy vấn luôn tìm đc vùng có filter
đối với file excel nặng , như file công ty em 15mb : truy vấn này không thể tìm đc vùng có filter , nhưng nếu truy vấn khi file đó đang mở bằng cửa sổ application thì truy vấn lại tìm ra +-+-+-+

đâu là sự khác nhau giữa chúng ? mong anh giải đáp giúp
 
dân mù VBA mà anh . có những cái em ko tự giải thích đc . thí dụ như
đối với file excel nhẹ : truy vấn luôn tìm đc vùng có filter
đối với file excel nặng , như file công ty em 15mb : truy vấn này không thể tìm đc vùng có filter , nhưng nếu truy vấn khi file đó đang mở bằng cửa sổ application thì truy vấn lại tìm ra +-+-+-+

đâu là sự khác nhau giữa chúng ? mong anh giải đáp giúp

Vậy phải xem code của bạn như thế nào, code của tôi chạy trên file đến 3 triệu dòng với dung lượng là hơn 58MB nhưng vẫn lấy tốt.
 
Lâu quá không thấy ai trả lời nữa, thôi thì tôi xin gửi đáp án vậy:

PHP:
Sub TableName()
    Dim Cn As Object, rsTables As Object, Arr() As Variant
    Set Cn = CreateObject("ADODB.Connection")
    Cn.Open ("Provider=Microsoft.Jet.OLEDB.4.0;" & _
             "Data Source=" & ThisWorkbook.FullName & _
             ";Extended Properties=""Excel 8.0"";")
    Set rsTables = Cn.OpenSchema(20)
    Arr = rsTables.GetRows(, , "TABLE_NAME")
    ActiveCell.Resize(UBound(Arr, 2) - LBound(Arr, 2) + 1, 1).Value = Application.Transpose(Arr)

End Sub
 
Lâu quá không thấy ai trả lời nữa, thôi thì tôi xin gửi đáp án vậy:

PHP:
Sub TableName()
    Dim Cn As Object, rsTables As Object, Arr() As Variant
    Set Cn = CreateObject("ADODB.Connection")
    Cn.Open ("Provider=Microsoft.Jet.OLEDB.4.0;" & _
             "Data Source=" & ThisWorkbook.FullName & _
             ";Extended Properties=""Excel 8.0"";")
    Set rsTables = Cn.OpenSchema(20)
    Arr = rsTables.GetRows(, , "TABLE_NAME")
    ActiveCell.Resize(UBound(Arr, 2) - LBound(Arr, 2) + 1, 1).Value = Application.Transpose(Arr)

End Sub
Em nghĩ chắc tại các thành viên trên GPE ít người biết về ADO nên không có câu trả lời ạ!
Anh có thể cho 1 vài bài tập dễ không ạ?
 
Lâu quá không thấy ai trả lời nữa, thôi thì tôi xin gửi đáp án vậy:

Bài này dễ ồm... nếu tui có học qua Access, SQL, ADO...
Hổng học, biết chết liền!
Ẹc... Ẹc... --=0
---------------------------
Phát hiện 1 chiện: Code chỉ đúng với file đã lưu, có tên đàng hoàng. Còn với file mới tinh vừa tạo chưa lưu thì.. trật lất!
 
Lần chỉnh sửa cuối:
Bài này dễ ồm... nếu tui có học qua Access, SQL, ADO...
Hổng học, biết chết liền!
Ẹc... Ẹc... --=0
---------------------------
Phát hiện 1 chiện: Code chỉ đúng với file đã lưu, có tên đàng hoàng. Còn với file mới tinh vừa tạo chưa lưu thì.. trật lất!
Hihi, ADO nó chỉ làm việc với dữ liệu rõ ràng, mà rõ ràng là dữ liệu phải được tồn tại trong đĩa cứng. Nếu file chưa lưu hoặc file mới sẽ bị vấn đề.
 
Em nghĩ chắc tại các thành viên trên GPE ít người biết về ADO nên không có câu trả lời ạ!
không phải là người ta không biết đâu bạn, mà ADO đối với excel không mạnh bằng các ngôn ngữ khác chẳng hạn SQL, ACCESS, oracle, ..., ADO chẳng qua nó là công cụ giúp bạn thao tác trên các bảng với dữ liệu thông qua các phép kết.
học cái này chơi thì được chứ muốn làm việc đàng hoàng thì phải phải biết thiết kế CSLD
như thế nào? biết thiết kế vật lý các bảng như thế nào, các phép kết gì, cái nào là khóa chính cái nào là khóa ngoại, sau đó tạo giao diện truy vấn như thế nào? và cuối cùng là cài đặt chương trình?
cài đặt chương trình này chẳng có gì khó nếu bạn hiểu các quy trình làm việc của ứng dụng, quanh đi quẩn lại cũng có mấy câu kết nối và vài câu truy vấn dữ liệu
(đó là theo hiểu biết của tôi)
 
không phải là người ta không biết đâu bạn, mà ADO đối với excel không mạnh bằng các ngôn ngữ khác chẳng hạn SQL, ACCESS, oracle, ..., ADO chẳng qua nó là công cụ giúp bạn thao tác trên các bảng với dữ liệu thông qua các phép kết.
học cái này chơi thì được chứ muốn làm việc đàng hoàng thì phải phải biết thiết kế CSLD
như thế nào? biết thiết kế vật lý các bảng như thế nào, các phép kết gì, cái nào là khóa chính cái nào là khóa ngoại, sau đó tạo giao diện truy vấn như thế nào? và cuối cùng là cài đặt chương trình?
cài đặt chương trình này chẳng có gì khó nếu bạn hiểu các quy trình làm việc của ứng dụng, quanh đi quẩn lại cũng có mấy câu kết nối và vài câu truy vấn dữ liệu
(đó là theo hiểu biết của tôi)

Nói thì nói vậy thôi chứ theo mình nghĩ: "Biết" là một chuyện. Từ cái chỗ "biết" ấy, để đạt đến mức độ "tung hoành ngang dọc" tùy ý như Hai Lúa vẫn còn quảng đường dài (thậm chí là quá dài)
 
không phải là người ta không biết đâu bạn, mà ADO đối với excel không mạnh bằng các ngôn ngữ khác chẳng hạn SQL, ACCESS, oracle, ..., ADO chẳng qua nó là công cụ giúp bạn thao tác trên các bảng với dữ liệu thông qua các phép kết.
học cái này chơi thì được chứ muốn làm việc đàng hoàng thì phải phải biết thiết kế CSLD
như thế nào? biết thiết kế vật lý các bảng như thế nào, các phép kết gì, cái nào là khóa chính cái nào là khóa ngoại, sau đó tạo giao diện truy vấn như thế nào? và cuối cùng là cài đặt chương trình?
cài đặt chương trình này chẳng có gì khó nếu bạn hiểu các quy trình làm việc của ứng dụng, quanh đi quẩn lại cũng có mấy câu kết nối và vài câu truy vấn dữ liệu
(đó là theo hiểu biết của tôi)

Lý thuyết là thế, lý thuyết để hướng cho mình cách nhìn toàn cục và định hướng cho mình, còn việc vận dụng và phát triển thì phải tự thân vận động bạn à.
Chổ màu đỏ bạn nhận xét hơi chủ quan tí. Công nghệ càng phát triển thì cách thức thay đổi đó là điều hẳn nhiên. Nếu như ta không chạy theo thì ta bị lạc hậu. Hiện nay có nhiều công cụ hỗ trợ mà không cần viết các câu truy vấn phức tạp như thế, tôi đưa ví dụ là LINQ to SQL là ví dụ điển hình.

Em nghĩ chắc tại các thành viên trên GPE ít người biết về ADO nên không có câu trả lời ạ!
Anh có thể cho 1 vài bài tập dễ không ạ?

Không phải thế đâu bạn, có thể đề tài này bị "chìm" nên mọi người chưa tiếp cận được.
Những bài tập dễ thì bạn có thể qua Bài tập về ADO căn bản. để tham khảo nhé.
 
Lần chỉnh sửa cuối:
Nếu như ta không chạy theo thì ta bị lạc hậu. Hiện nay có nhiều công cụ hỗ trợ mà không cần viết các câu truy vấn phức tạp như thế, tôi đưa ví dụ là LINQ to SQL là ví dụ điển hình.
Đúng là như anh nói, với công nghệ kéo thả hiện nay có thể giúp chúng ta viết các câu truy vấn phức tạp(nhưng không phải là tât cả), giúp chúng ta làm được những việc mà chúng ta cần mặc dù chúng ta không hiểu nguyên lý tại sao ra như vậy? nhưng học như vậy muốn phát triển thêm thì hơi bị khó đó
ví dụ điển hình rõ nhất là các đối tượng,
chẳng hạn trong VBA đi, chúng ta biết Range là 1 đối tượng có rất nhiều thuộc tính, phương thức nhưng chúng ta đâu biết nó được tạo ra như thế nào và cấu trúc ra làm sao, chúng ta chỉ cần biết ứng dụng là được. lỡ sau này chúng ta muốn tạo thêm 1 đối tượng nào đó thì chúng ta thiết kế như thế nào định nghĩa ra làm sao?
có khi nào anh nghĩ mình có thể tạo ra một đối tượng truy vấn cho riêng mình không?
ví dụ như quản lý học sinh
một đối tượng học sinh có những thuộc tính gì? có những hành động gì ..., những cái này thì không có cái nào giúp mình, chỉ có thể tự thân vận động code thôi
(em nói như vậy là để biết các ngôn ngữ hiện đại chỉ giúp chúng ta giải quyết được phần ngọn thôi)
 
Đúng là như anh nói, với công nghệ kéo thả hiện nay có thể giúp chúng ta viết các câu truy vấn phức tạp(nhưng không phải là tât cả), giúp chúng ta làm được những việc mà chúng ta cần mặc dù chúng ta không hiểu nguyên lý tại sao ra như vậy? nhưng học như vậy muốn phát triển thêm thì hơi bị khó đó
ví dụ điển hình rõ nhất là các đối tượng,
chẳng hạn trong VBA đi, chúng ta biết Range là 1 đối tượng có rất nhiều thuộc tính, phương thức nhưng chúng ta đâu biết nó được tạo ra như thế nào và cấu trúc ra làm sao, chúng ta chỉ cần biết ứng dụng là được. lỡ sau này chúng ta muốn tạo thêm 1 đối tượng nào đó thì chúng ta thiết kế như thế nào định nghĩa ra làm sao?
có khi nào anh nghĩ mình có thể tạo ra một đối tượng truy vấn cho riêng mình không?
ví dụ như quản lý học sinh
một đối tượng học sinh có những thuộc tính gì? có những hành động gì ..., những cái này thì không có cái nào giúp mình, chỉ có thể tự thân vận động code thôi
(em nói như vậy là để biết các ngôn ngữ hiện đại chỉ giúp chúng ta giải quyết được phần ngọn thôi)

Hoàn toàn khác với suy nghĩ bài 16, ý tôi muốn diễn đạt là cái suy nghĩ của bạn trong bài 16 là chỉ vài kiểu truy vấn và kết nối thì vẫn là vài kiểu truy vấn và kết nối, không khác và không phát triển hơn được. Còn chuyện tự tạo cho mình những controls thì đó là chuyện khác.
Chổ màu đỏ cũng không hẳn đúng. Mỗi một kết quả có nhiều phương thức và cách làm khác nhau. Tội gì ta không áp dụng những cái mới, những cái mà ta cho là tiện ích hơn cái trước đó.
Ví dụ bây giờ ít ai dùng pascal cho việc lập trình ứng dụng, và nhiều thứ khác... Thôi tôi xin dừng tranh luận vấn đề này ở đây, kẻo làm loãn đề tài.
 
Lần chỉnh sửa cuối:
Lấy danh sách tên cột của 1 bảng.

Để tiếp tục tôi xin đưa ra câu đố tiếp theo: Làm thế nào để lấy danh sách tên cột của 1 bảng mà không dùng vòng lặp?
 
Cũng có thể mọi người chưa quan tâm lắm, hoặc có thể chưa nhìn thấy đề tài này. Xin phép được làm mới lại.
Mong các bạn tham gia thảo luận để còn tiếp những đề tài mới thú vị hơn.
 
Để tiếp tục tôi xin đưa ra câu đố tiếp theo: Làm thế nào để lấy danh sách tên cột của 1 bảng mà không dùng vòng lặp?
Em xin đưa đáp án đầu tiên, anh góp ý nhé
Mã:
Sub FieldName()
    Dim Cn As Object, Rst As Object, LsSql As String, Arr() As Variant
    Set Cn = CreateObject("ADODB.Connection")
    Set Rst = CreateObject("ADODB.recordset")
    Cn.Open ("Provider=Microsoft.Jet.OLEDB.4.0;" & _
             "Data Source=" & ThisWorkbook.FullName & _
             ";Extended Properties=""Excel 8.0;HDR=No;IMEX=1"";")
    LsSql = "Select * from [Table]"
    Rst.Open LsSql, Cn, 3, 1
    Arr = Rst.getrows
    ActiveCell.Resize(UBound(Arr, 1) + 1, 1) = Arr
End Sub
 
Em xin đưa đáp án đầu tiên, anh góp ý nhé
Mã:
Sub FieldName()
    Dim Cn As Object, Rst As Object, LsSql As String, Arr() As Variant
    Set Cn = CreateObject("ADODB.Connection")
    Set Rst = CreateObject("ADODB.recordset")
    Cn.Open ("Provider=Microsoft.Jet.OLEDB.4.0;" & _
             "Data Source=" & ThisWorkbook.FullName & _
             ";Extended Properties=""Excel 8.0;HDR=No;IMEX=1"";")
    LsSql = "Select * from [Table]"
    Rst.Open LsSql, Cn, 3, 1
    Arr = Rst.getrows
    ActiveCell.Resize(UBound(Arr, 1) + 1, 1) = Arr
End Sub

Cách lấy kiểu "ăn gian" như trên có thể lấy như sau:

Mã:
Sub ColumName()
    Dim Cn As Object, Rst As Object
    Set Cn = CreateObject("ADODB.Connection")
    Cn.Open ("Provider=Microsoft.Jet.OLEDB.4.0;" & _
             "Data Source=" & ThisWorkbook.FullName & _
             ";Extended Properties=""Excel 8.0;HDR=No;IMEX=1"";")
    Set Rst = Cn.Execute("Select top 1 * from [Table]")
    ActiveCell.CopyFromRecordset Rst
    
End Sub
Tuy nhiên tên cột thì bắt buộc phải có, không trùng... cách trên nếu dòng trên cùng là trống thì vẫn là trống, không có tên cột...
 
Mình bắt chước làm thử xem sao, chỉ để cổ vũ là chính vì không hiểu về mấy object này lắm. Sub chỉ chạy chính xác khi table nằm ở sheet có name đầu tiên trong các name xếp theo vần abc (do các ADO tự sắp xếp các sheet theo abc, sheet không có table chỉ có 1 phần tử là F1). Tốt nhất là table ở sheet1.
Mã:
Sub Test()
    Dim cnn As ADODB.Connection, rst As ADODB.Recordset, s$, arr
    s = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & ThisWorkbook.FullName & _
        ";Extended Properties=""Excel 12.0;HDR=YES"";"
    
    Set cnn = New ADODB.Connection
    cnn.Open s
      
    Set rst = cnn.OpenSchema(4)
    arr = rst.GetRows(, , 3)
    ActiveCell.Resize(UBound(arr, 2) + 2 - Sheets.Count, 1) = Application.Transpose(arr)
    rst.Close
    Set rst = Nothing
    cnn.Close
    Set cnn = Nothing
End Sub
 
Mình bắt chước làm thử xem sao, chỉ để cổ vũ là chính vì không hiểu về mấy object này lắm. Sub chỉ chạy chính xác khi table nằm ở sheet có name đầu tiên trong các name xếp theo vần abc (do các ADO tự sắp xếp các sheet theo abc, sheet không có table chỉ có 1 phần tử là F1). Tốt nhất là table ở sheet1.
Mã:
Sub Test()
    Dim cnn As ADODB.Connection, rst As ADODB.Recordset, s$, arr
    s = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & ThisWorkbook.FullName & _
        ";Extended Properties=""Excel 12.0;HDR=YES"";"
    
    Set cnn = New ADODB.Connection
    cnn.Open s
      
    Set rst = cnn.OpenSchema(4)
    arr = rst.GetRows(, , 3)
    ActiveCell.Resize(UBound(arr, 2) + 2 - Sheets.Count, 1) = Application.Transpose(arr)
    rst.Close
    Set rst = Nothing
    cnn.Close
    Set cnn = Nothing
End Sub
Gần được rồi đó, ráng chút nữa đi. Quy định lấy bảng nào trong file chứ không mặc định là bảng đầu tiên.
 
Thôi mình ghi đáp án luôn.

Mã:
Sub ColumnName()
  Dim cn As Object, ColumnsSchema As Object, arr
  Set cn = CreateObject("ADODB.Connection")
  Set ColumnsSchema = CreateObject("ADODB.Recordset")
  cn.Open ("Provider=Microsoft.Jet.OLEDB.4.0;" & _
             "Data Source=" & ThisWorkbook.FullName & _
             ";Extended Properties=""Excel 8.0;HDR=Yes;IMEX=1"";")
  Set ColumnsSchema = cn.OpenSchema(4, Array(Null, Null, "'TenSheet$'"))
  arr = ColumnsSchema.GetRows(, , "COLUMN_NAME")
  ActiveCell.Resize(UBound(arr, 2) - LBound(arr, 2) + 1, _
        1).Value = Application.Transpose(arr)

End Sub
 
Tạo số TT

Xin tiếp tục câu đố dể hơn.

Làm thế nào mình tạo cột số STT trong đoạn truy vấn.

1.jpg
 

File đính kèm

Xin tiếp tục câu đố dể hơn.

Làm thế nào mình tạo cột số STT trong đoạn truy vấn.
Nếu như ví dụ trong đề bài, cột mã là duy nhất và đã sort thì có thể truy vấn:
Mã:
Sub STT()
  Dim cn As Connection, rst As Recordset, s$
  Set cn = New Connection
  s = "Provider=Microsoft.Jet.OLEDB.4.0;" & _
             "Data Source=" & ThisWorkbook.FullName & _
             ";Extended Properties=""Excel 8.0;HDR=Yes;IMEX=1"";"
  cn.Open s
  
  Set rst = New Recordset
  s = "select (select count(b.ma) from data b where b.ma<=a.ma) as STT,a.* from data a"
  rst.Open s, cn
  
  Range("G2").CopyFromRecordset rst
  rst.Close
  Set rst = Nothing
  cn.Close
  Set cn = Nothing
End Sub
 

File đính kèm

Lần chỉnh sửa cuối:
Nếu như ví dụ trong đề bài, cột mã là duy nhất và đã sort thì có thể truy vấn:
Vậy trường hợp cột mã không còn là duy nhất (có các mã giống nhau) HOẶC chưa sort thì kết quả không còn được gọi là đánh số thứ tự nữa.
Em chú ý thì trong yêu cầu #29 của anh Hai Lúa có để hình kết quả với cột Ma đang bị đảo từ dưới lên trên (sort ngược) ==> câu lệnh trên vẫn chưa phải là lời giải.
Có cách nào sửa câu lệnh SQL để chỉ cần nó lấy được bản ghi nào thì nó sẽ đánh số tự động tăng dần từ 1 đến n. Kể cả khi mình lấy ORDER BY của các cột khác (tùy biến) ??
 
Lần chỉnh sửa cuối:
Nếu sort ngược lại thì thay dấu >= thành <=.
Nếu duy nhất và chưa sort thì dùng thêm order by nhưng thứ tự bảng không còn như lúc đầu.
Nếu mã không duy nhất thì sql mình bó tay.
 
...
Nếu mã không duy nhất thì sql mình bó tay.

Theo lý thuyết CSDL Liên Hệ, vị trí của dòng nằm trong bảng là việc không liên hệ. Vì vậy SQL tiêu chuẩn không có lệnh để định vị trí dòng.
Tuy nhiên, vì nhu cầu khách hàng cho nên hầu hết các phiên bản SQL trên thị truonwgf đều có hàm để đánh số dòng.

Riêng MS Access thì lại không có hàm đánh số thứ tự (ít nhất là phiên bản hiện nay). ADO dùng cổ mày Access để thực hiện truy vấn SQL trên bảng tính Excel cho nên phải chịu vậy.

Nếu kết nối với CSDL khác (mySSQL, MS SQL Server,...) thì có thể dùng hàm hoặc lệnh để làm việc này.
 
Nghĩa là việc đánh số thứ tự khi mã không là duy nhất bằng câu lệnh SQL là không thể.
Vậy chắc nếu làm thì phải viết một đoạn code khác để đánh số thứ tự khi đã truy vấn được dữ liệu. Cũng phức tạp quá !$@!!
 
Lọc dữ liệu duy nhất.

Xin chào các bạn, câu hỏi lần này là "Tôi viết câu query như thế nào để lọc duy nhất dữ liệu mà không dùng Group By và select distinct?"
 

File đính kèm

Xin chào các bạn, câu hỏi lần này là "Tôi viết câu query như thế nào để lọc duy nhất dữ liệu mà không dùng Group By và select distinct?"

Em không biết chơi kiểu gì làm đại kiểu UNION :)
Mã:
Sub TestExcel()
 
    Dim cn As New ADODB.Connection
    Dim rst As New ADODB.Recordset
    
    cn.Open ("Driver={Microsoft Excel Driver (*.xls, *.xlsx, *.xlsm, *.xlsb)};dbq=" & ThisWorkbook.FullName & ";")
    rst.Open ("select SUPPLIERS from [Data$] union select SUPPLIERS from [Data$]"), cn
    
    Sheet2.[C2].CopyFromRecordset rst


End Sub
 

Bài viết mới nhất

Back
Top Bottom