ADO select dữ liệu - columns thay đổi theo yêu cầu người dùng. (1 người xem)

Liên hệ QC

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

tan.ngohoangquoc

Thành viên hoạt động
Tham gia
10/7/14
Bài viết
100
Được thích
41
Nghề nghiệp
M&A Specialist - RM Assistant
Hi mọi người,

Em viết đoạn code dưới để lấy dữ liệu từ nhiều file đóng và có một số thắc mắc
1. Em muốn lấy dữ liệu từ sheet đầu tiên của mỗi file (tên sheet không cố định) (thật sự là mỗi file chỉ có 1 sheet)
Search trên mạng có bài dùng ADOX.Catelog và ADOX.Table để lấy thông tin sheet. không biết là em áp dụng đúng không.

2. SELECT *, em muốn thay * bằng tên khác (một loạt tên thay đổi theo yêu cầu người dùng) nên em dùng hàm JOIN để tạo ra một string dạng [Col 1],[Col 2] - Ngoài cách này còn cách nào khác không?

Thanks mọi người (Không chuyên viết code nên hơi gúm mọi người ném đá nhẹ:P)

Mã:
Private Sub GetData(objFile As Object)
    Dim cn As New ADODB.Connection
    Dim rst As New ADODB.Recordset
    Dim objCat As ADOX.Catalog
    Dim tbl As ADOX.Table
    Dim sSheet As String
    Dim Arr() As Variant
    Dim col As String
    
    Arr = Sheet1.[A3:D3].Value
    col = Join(Application.Transpose(Application.Transpose(Arr)), "],[")
    col = "[" & col & "]"

    cn.Open ("Driver={Microsoft Excel Driver (*.xls, *.xlsx, *.xlsm, *.xlsb)};dbq=" & objFile & ";")
    
    Set objCat = New ADOX.Catalog
    Set objCat.ActiveConnection = cn
    
    For Each tbl In objCat.Tables
        sSheet = tbl.Name
    Next tbl
    
    rst.Open ("select " & col & "from [" & sSheet & "]"), cn
    
    Sheet1.[A4].CopyFromRecordset rst
End Sub
 
Hi mọi người,

Em viết đoạn code dưới để lấy dữ liệu từ nhiều file đóng và có một số thắc mắc
1. Em muốn lấy dữ liệu từ sheet đầu tiên của mỗi file (tên sheet không cố định) (thật sự là mỗi file chỉ có 1 sheet)
Search trên mạng có bài dùng ADOX.Catelog và ADOX.Table để lấy thông tin sheet. không biết là em áp dụng đúng không.

2. SELECT *, em muốn thay * bằng tên khác (một loạt tên thay đổi theo yêu cầu người dùng) nên em dùng hàm JOIN để tạo ra một string dạng [Col 1],[Col 2] - Ngoài cách này còn cách nào khác không?

Thanks mọi người (Không chuyên viết code nên hơi gúm mọi người ném đá nhẹ:P)

Mã:
Private Sub GetData(objFile As Object)
    Dim cn As New ADODB.Connection
    Dim rst As New ADODB.Recordset
    Dim objCat As ADOX.Catalog
    Dim tbl As ADOX.Table
    Dim sSheet As String
    Dim Arr() As Variant
    Dim col As String
    
    Arr = Sheet1.[A3:D3].Value
    col = Join(Application.Transpose(Application.Transpose(Arr)), "],[")
    col = "[" & col & "]"

    cn.Open ("Driver={Microsoft Excel Driver (*.xls, *.xlsx, *.xlsm, *.xlsb)};dbq=" & objFile & ";")
    
    Set objCat = New ADOX.Catalog
    Set objCat.ActiveConnection = cn
    
    For Each tbl In objCat.Tables
        sSheet = tbl.Name
    Next tbl
    
    rst.Open ("select " & col & "from [" & sSheet & "]"), cn
    
    Sheet1.[A4].CopyFromRecordset rst
End Sub
Nếu muốn lấy sheet đầu tiên thì bạn thử bỏ tên sheet ra, chỉ để range thôi. Muốn thực hư thế nào bạn gửi ví dụ xem thử nhé.
 
Upvote 0
Hi mọi người,

Em viết đoạn code dưới để lấy dữ liệu từ nhiều file đóng và có một số thắc mắc
1. Em muốn lấy dữ liệu từ sheet đầu tiên của mỗi file (tên sheet không cố định) (thật sự là mỗi file chỉ có 1 sheet)
Search trên mạng có bài dùng ADOX.Catelog và ADOX.Table để lấy thông tin sheet. không biết là em áp dụng đúng không.

2. SELECT *, em muốn thay * bằng tên khác (một loạt tên thay đổi theo yêu cầu người dùng) nên em dùng hàm JOIN để tạo ra một string dạng [Col 1],[Col 2] - Ngoài cách này còn cách nào khác không?

Thanks mọi người (Không chuyên viết code nên hơi gúm mọi người ném đá nhẹ:P)

Mã:
Private Sub GetData(objFile As Object)
    Dim cn As New ADODB.Connection
    Dim rst As New ADODB.Recordset
    Dim objCat As ADOX.Catalog
    Dim tbl As ADOX.Table
    Dim sSheet As String
    Dim Arr() As Variant
    Dim col As String
    
    Arr = Sheet1.[A3:D3].Value
    col = Join(Application.Transpose(Application.Transpose(Arr)), "],[")
    col = "[" & col & "]"

    cn.Open ("Driver={Microsoft Excel Driver (*.xls, *.xlsx, *.xlsm, *.xlsb)};dbq=" & objFile & ";")
    
    Set objCat = New ADOX.Catalog
    Set objCat.ActiveConnection = cn
    
    For Each tbl In objCat.Tables
        sSheet = tbl.Name
    Next tbl
    
    rst.Open ("select " & col & "from [" & sSheet & "]"), cn
    
    Sheet1.[A4].CopyFromRecordset rst
End Sub

Bạn đã chạy thử code mình viết chưa, ? kết quả có đúng ý của bạn không /
 
Upvote 0
rst.Open ("select " & col & "from [" & sSheet & "]"), cn
Nếu là lấy bảng đầu tiên thì chỉ thế này cũng được
Mã:
    rst.Open ("select " & col & "from [" & objCat.Tables(0).Name & "]"), cn
Còn columns như thế coi bộ cũng khái quát mà, tôi thấy thế là ok (lỡ lai căng tý). Viết được như bạn là siêu rồi, ít nhất là cũng biết khái quát. Làm được thế thì code ít sửa mà người dùng thì chả cần đụng tới code cũng tùy chỉnh được một số chỗ.
 
Lần chỉnh sửa cuối:
Upvote 0
Nếu là lấy bảng đầu tiên thì chỉ thế này cũng được
Mã:
    rst.Open ("select " & col & "from [" & objCat.Tables(0).Name & "]"), cn
Còn columns như thế coi bộ cũng khái quát mà, tôi thấy thế là ok (lỡ lai căng tý) rồi.
Có thể không dùng DAO để lấy mà.
 
Upvote 0
Bạn đã chạy thử code mình viết chưa, ? kết quả có đúng ý của bạn không /

Code chạy được rùi mình chỉ muốn hỏi còn cách nào khác không thui :)


Nếu muốn lấy sheet đầu tiên thì bạn thử bỏ tên sheet ra, chỉ để range thôi. Muốn thực hư thế nào bạn gửi ví dụ xem thử nhé.

Thanks anh :) Em làm theo hướng dẫn này là chạy dc rồi :) Nhưng vì các file chứ dữ liệu khác nhau số dòng nên trong câu lệnh query em phải thêm WHERE vì em chọn vùng $A1:IV65536

Mã:
Private Sub GetData(objFile As Object)    Dim cn As New ADODB.Connection
    Dim rst As New ADODB.Recordset
    Dim Arr() As Variant
    Dim col As String, LastRow As Long
    
    Arr = Sheet1.Range(Cells(3, 1), Cells(3, Cells(3, 1).End(xlToRight).Column)).Value
    col = Join(Application.Transpose(Application.Transpose(Arr)), "],[")
    col = "[" & col & "]"
    cn.Open ("Driver={Microsoft Excel Driver (*.xls, *.xlsx, *.xlsm, *.xlsb)};dbq=" & objFile & ";")
    
    rst.Open ("select " & col & "from [$A1:IV65536] WHERE [Worklog Id] IS NOT NULL"), cn
    
    LastRow = Cells(Rows.Count, 1).End(xlUp).Row
    Sheet1.Cells(LastRow + 1, 1).CopyFromRecordset rst
    
    cn.Close
    Erase Arr
    Set cn = Nothing
    Set rst = Nothing


End Sub
 

File đính kèm

Upvote 0
Code chạy được rùi mình chỉ muốn hỏi còn cách nào khác không thui :)




Thanks anh :) Em làm theo hướng dẫn này là chạy dc rồi :) Nhưng vì các file chứ dữ liệu khác nhau số dòng nên trong câu lệnh query em phải thêm WHERE vì em chọn vùng $A1:IV65536

Mã:
Private Sub GetData(objFile As Object)    Dim cn As New ADODB.Connection
    Dim rst As New ADODB.Recordset
    Dim Arr() As Variant
    Dim col As String, LastRow As Long
    
    Arr = Sheet1.Range(Cells(3, 1), Cells(3, Cells(3, 1).End(xlToRight).Column)).Value
    col = Join(Application.Transpose(Application.Transpose(Arr)), "],[")
    col = "[" & col & "]"
    cn.Open ("Driver={Microsoft Excel Driver (*.xls, *.xlsx, *.xlsm, *.xlsb)};dbq=" & objFile & ";")
    
    rst.Open ("select " & col & "from [$A1:IV65536] WHERE [Worklog Id] IS NOT NULL"), cn
    
    LastRow = Cells(Rows.Count, 1).End(xlUp).Row
    Sheet1.Cells(LastRow + 1, 1).CopyFromRecordset rst
    
    cn.Close
    Erase Arr
    Set cn = Nothing
    Set rst = Nothing


End Sub
Tôi thấy bạn làm như vậy ok rồi mà.
 
Upvote 0
Code chạy được rùi mình chỉ muốn hỏi còn cách nào khác không thui :)




Thanks anh :) Em làm theo hướng dẫn này là chạy dc rồi :) Nhưng vì các file chứ dữ liệu khác nhau số dòng nên trong câu lệnh query em phải thêm WHERE vì em chọn vùng $A1:IV65536

Mã:
Private Sub GetData(objFile As Object)    Dim cn As New ADODB.Connection
    Dim rst As New ADODB.Recordset
    Dim Arr() As Variant
    Dim col As String, LastRow As Long
    
    Arr = Sheet1.Range(Cells(3, 1), Cells(3, Cells(3, 1).End(xlToRight).Column)).Value
    col = Join(Application.Transpose(Application.Transpose(Arr)), "],[")
    col = "[" & col & "]"
    cn.Open ("Driver={Microsoft Excel Driver (*.xls, *.xlsx, *.xlsm, *.xlsb)};dbq=" & objFile & ";")
    
    rst.Open ("select " & col & "from [$A1:IV65536] WHERE [Worklog Id] IS NOT NULL"), cn
    
    LastRow = Cells(Rows.Count, 1).End(xlUp).Row
    Sheet1.Cells(LastRow + 1, 1).CopyFromRecordset rst
    
    cn.Close
    Erase Arr
    Set cn = Nothing
    Set rst = Nothing


End Sub


Thông thường những dạng bài kiểu này, ta nên tạo hẳn 1 Form cho người dung chọn file, sheets và SQL
Kiểu như file đính kèm :
 

File đính kèm

Upvote 0

File đính kèm

Upvote 0
Thông thường những dạng bài kiểu này, ta nên tạo hẳn 1 Form cho người dung chọn file, sheets và SQL
Kiểu như file đính kèm :

Mình đang thử xem cách lấy dữ liệu trước, sẽ build một file kiểu này :P
Làm quen với ADO đã :D
 
Upvote 0
Thông thường những dạng bài kiểu này, ta nên tạo hẳn 1 Form cho người dung chọn file, sheets và SQL
Kiểu như file đính kèm :
Nếu muốn làm form thì phải làm cho tới luôn bạn. Có nghĩa là chọn file nguồn, sẽ lấy tên cột của file nguồn, liệt kê hết vào listbox (Set Listbox có chức năng chọn nhiều dòng = checkbox), như vậy sẽ ok hơn.

xin phép em mượn tạm món quà "Happy birdthday ado class" của anh cho bạn ý tham khảo.

Tham khảo file này và tùy biến bạn nhé :

Tôi xin đính chính: Cái này không phải do tôi viết nhé, đó là món quà của 1 người bạn của HMT tặng cho HMT nhân dịp sinh nhật.
 
Lần chỉnh sửa cuối:
Upvote 0
tan.ngohoangquoc à!
Tôi thấy đoạn code đầu tiên khá là hay rồi đấy. Chỉ có điều cách tìm sheet như thế thật ra là tìm ra sheet cuối cùng.
--=0

Bạn không thấy là code đó rất sáng à? Code nào càng khái quát cao thì nhìn lại càng sáng. Còn cái cần điều chỉnh để khái quát nốt là cái này:
Mã:
    Arr = Sheet1.[[COLOR=#ff0000]A3:D3[/COLOR]].Value
Đây là 4 cột, mà bạn muốn 5, 6... cột tùy theo liệt kê chẳng hạn. Sau đây là cái mà tôi làm ra từ recorded mác cờ rô.
Mã:
Range("a3:" & Range("a3").End(xlToRight).Address).Address
Dù sao thì đây là lần đầu tiên được thưởng thức hượng vị X (ý là adoX đó) nên thú lắm --=0.
 
Lần chỉnh sửa cuối:
Upvote 0
tan.ngohoangquoc à!
Tôi thấy đoạn code đầu tiên khá là hay rồi đấy. Chỉ có điều cách tìm sheet như thế thật ra là tìm ra sheet cuối cùng.
--=0

Bạn không thấy là code đó rất sáng à? Code nào càng khái quát cao thì nhìn lại càng sáng. Còn cái cần điều chỉnh để khái quát nốt là cái này:
Mã:
    Arr = Sheet1.[[COLOR=#ff0000]A3:D3[/COLOR]].Value
Đây là 4 cột, mà bạn muốn 5, 6... cột tùy theo liệt kê chẳng hạn. Sau đây là cái mà tôi làm ra từ recorded mác cờ rô.
Mã:
Range("a3:" & Range("a3").End(xlToRight).Address).Address
Dù sao thì đây là lần đầu tiên được thưởng thức hượng vị X (ý là adoX đó) nên thú lắm --=0.

:) Tại vì file chỉ có 1 sheet nên mình nghĩ áp dụng range luôn thì nhanh hơn :) đoán vậy á :P
ADOX mình cũng có biết gì đâu :P Lên mạng search thấy người ta chỉ vậy nên viết vậy :D
 
Upvote 0

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

Back
Top Bottom