Bài tập về ADO căn bản. (1 người xem)

Liên hệ QC

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

Bạn có thể nói rõ hơn về vấn đề này không?
Bạn thử gõ tên trường bằng Tiếng Việt có dấu trong cửa sổ VBAProject rồi truy vấn thử nhé. Chắc chắn là sẽ không được. Do vậy cái tên trường đó bạn phải gõ 1 nơi nào đó bên ngoài sheet rồi nối chuổi nó vào.
VB: Ở Sheet1 cell A1 bạn gõ Tên Cột Có Tiêu Đề TV
Thì trong chuổi truy vấn bạn nối như sau: "Select " & Sheet1.[A1] & " From Bang"
 
Bạn thử gõ tên trường bằng Tiếng Việt có dấu trong cửa sổ VBAProject rồi truy vấn thử nhé. Chắc chắn là sẽ không được. Do vậy cái tên trường đó bạn phải gõ 1 nơi nào đó bên ngoài sheet rồi nối chuổi nó vào.
VB: Ở Sheet1 cell A1 bạn gõ Tên Cột Có Tiêu Đề TV
Thì trong chuổi truy vấn bạn nối như sau: "Select " & Sheet1.[A1] & " From Bang"
À cái này thì mình biết rồi. aha
 
Dear A. Tuân & all. Cho em hỏi có thể truy vấn giữ liêu dạng cột mới c = cột a/b không?. Trong đó cột c là cột mới, cột a, b là hai cột có trong bảng data
 
SELECT COT1, COT2, COT1+COT2 AS B, B*COT3
Dear A.Tuân & các a/c trong GPE
VD:
SELECT Tensanpham, count([Soluong] điều kiện đếm là soluong<50) as soluongnho, count([Soluong] điều kiện đếm là soluong>50) as soluonglon
FROM [bangA$]
GROUP BY Tensanpham

? có các nào đếm có điều kiện như vậy không a ?
 
Có, nhưng bỏ ba cái từ đía điếc kia đi rồi tôi mới tiếp chuyện.
 
Nhờ các anh/chị giúp đỡ như mô tả dưới bằng ADO ạ:
- khi nhập “A” ở cột D file Book1 thì dữ liệu cột A và C tự động update vào File HT1 (cái nào nhập “A” trước thì update trước), đồng thời cột C của file HT1 điền “HT1”

- khi nhập “B” ở cột D file Book1 thì dữ liệu cột A và C tự động update vào File HT2 (cái nào nhập “B” trước thì update trước), đồng thời cột C của file HT2 điền “HT2”
 

File đính kèm

Nhờ các anh/chị giúp đỡ như mô tả dưới bằng ADO ạ:
- khi nhập “A” ở cột D file Book1 thì dữ liệu cột A và C tự động update vào File HT1 (cái nào nhập “A” trước thì update trước), đồng thời cột C của file HT1 điền “HT1”

- khi nhập “B” ở cột D file Book1 thì dữ liệu cột A và C tự động update vào File HT2 (cái nào nhập “B” trước thì update trước), đồng thời cột C của file HT2 điền “HT2”
http://www.giaiphapexcel.com/diendan/threads/cập-nhật-dữ-liệu-bằng-ado.128215/#post-803612
 
Chào Các Anh
Nhờ các Anh Chỉ dẫn cách sử dụng hàm CASE hoặc IF
Vi dụ File DATA có 3 cột Maso,Tenchitiet,Soluong
Cú pháp Case
Mã:
CASE expression
    WHEN condition1 THEN result1
    WHEN condition2 THEN result2
   ...
    WHEN conditionN THEN resultN
    ELSE result
END
Mình viết thử nhưng không được nhờ các anh hướng dẫn
Mã:
Set lrs = Cnn.Execute("SELECT Maso,Tenchitiet,soluong," & _
                        CASE
                        when soluong >360 THEN 'A'" & _
                        when soluong =360 THEN 'B'" & _
                             Else 'C'" & _
                             END" & _
                      "FROM [DATA$]")
 
Lần chỉnh sửa cuối:
Chào Các Anh
Nhờ các Anh Chỉ dẫn cách sử dụng hàm CASE hoặc IF
Vi dụ File DATA có 3 cột Maso,Tenchitiet,Soluong
Cú pháp Case
Mã:
CASE expression
    WHEN condition1 THEN result1
    WHEN condition2 THEN result2
   ...
    WHEN conditionN THEN resultN
    ELSE result
END
Mình viết thử nhưng không được nhờ các anh hướng dẫn
Mã:
Set lrs = Cnn.Execute("SELECT Maso,Tenchitiet,soluong," & _
                        CASE
                        when soluong >360 THEN 'A'" & _
                        when soluong =360 THEN 'B'" & _
                             Else 'C'" & _
                             END" & _
                      "FROM [DATA$]")

Bạn dùng hàm IIF thay cho cấu trúc CASE WHEN với CSDL là Excel, Access

Cách làm như sau:
Mã:
Set lrs = Cnn.Execute("SELECT Maso,Tenchitiet,soluong," & _
                        IIF(soluong >360, 'A', IIF(soluong =360,  'B', 'C' )) " & _
                      "FROM [DATA$]")
 
Bạn dùng hàm IIF thay cho cấu trúc CASE WHEN với CSDL là Excel, Access

Cách làm như sau:
Mã:
Set lrs = Cnn.Execute("SELECT Maso,Tenchitiet,soluong," & _
                        IIF(soluong >360, 'A', IIF(soluong =360,  'B', 'C' )) " & _
                      "FROM [DATA$]")

anh đưa đoạn này cho bạn kia cọp pi về chạy sẽ lại rớt tiền nữa, rồi sẽ quay lại đây hỏi tiếp. !$@!!
 
Bạn dùng hàm IIF thay cho cấu trúc CASE WHEN với CSDL là Excel, Access

Cách làm như sau:
Mã:
Set lrs = Cnn.Execute("SELECT Maso,Tenchitiet,soluong," & _
                        IIF(soluong >360, 'A', IIF(soluong =360,  'B', 'C' )) " & _
                      "FROM [DATA$]")
Dùng hàm IIF này thì em làm được nhưng em muốn biết Case..When này có áp dụng được trong Excel không thôi.
Em gửi file không được nên gửi file theo đường link sau
http://www.fshare.vn/file/P6GGORJ2HWUA
Cám ơn anh rất nhiều
 

File đính kèm

Lần chỉnh sửa cuối:
em cũng hổng biết sao dán cái anh đưa ở trên vào cửa sổ VBA thấy đỏ lòm à. hic
Chắc VBA đến ngày... :P . Vậy có thể do ghép chuỗi SQL thiếu ". Em dò lại đầu và cuối một chuỗi phải bao bởi ". Em kiểm tra lại code này:

Mã:
Set lrs = Cnn.Execute("SELECT Maso,Tenchitiet,soluong," & _
                        "IIF(soluong >360, 'A', IIF(soluong =360,  'B', 'C' )) " & _
                      "FROM [DATA$]")
 
Chắc VBA đến ngày... :p . Vậy có thể do ghép chuỗi SQL thiếu ". Em dò lại đầu và cuối một chuỗi phải bao bởi ". Em kiểm tra lại code này:

Mã:
Set lrs = Cnn.Execute("SELECT Maso,Tenchitiet,soluong," & _
                        "IIF(soluong >360, 'A', IIF(soluong =360,  'B', 'C' )) " & _
                      "FROM [DATA$]")

À vâng, cám ơn anh. Thì ra đầu và cuối chuỗi phải có dấu nháy kép. Giờ hết đỏ rồi ạ. %#^#$
 
Cái câu hỏi ở bài #415 vừa sai, vừa mập mờ. Quý vị giải được cũng đáng phục nghề kiên nhẫn.
Từ lúc hỏi ở thớt bên kia, tôi đã bảo chủ thớt ghi lại câu cú cho rõ ràng rồi hãy xét tiếp - trước mắt là câu đó bị thiếu dấu cách. Đó là cách debug lỗi thuật ngữ code (xét lỗi chính tả).
Sau khi biết đúng câu rồi thì mới thảy thẳng câu ấy vào hệ thống CSDL mà thử. Đó là cách debug code nếu đã đúng thuật ngữ (xét xem có đúng dữ liệu truy vấn)

Chỉ có cái kỹ thuật debug mà chủ thớt cũng còn chập choạng thì còn đòi thử Access với SQL Server làm chi cho mất thì giờ.
 
em cũng hổng biết sao dán cái anh đưa ở trên vào cửa sổ VBA thấy đỏ lòm à. hic
 
em cũng hổng biết sao dán cái anh đưa ở trên vào cửa sổ VBA thấy đỏ lòm à. hic

Đỏ là do đến ngày ;). Ở những đoạn ngắt dòng, em chỉnh lại bằng cách, xóa dấu _ hiện nay đi và làm lại: Nhấn phím SPACE sau đó SHIFT + _ rôi ENTER nhé.
 
Dạ em chào cả nhà,
Hiện tại em đang muốn làm cái insert VBA excel vào sqlserver 2008r2. em thử chạy trực tiếp trên máy cài sql thì ok. Nhưng sang máy khác thì lỗi
dbnetlib connectionopen (connect()). sql server does not exist or access denied
em thử nhiều cách mà vẫn chưa được mong các bác giúp đỡ.
 
Dạ em chào cả nhà,
Hiện tại em đang muốn làm cái insert VBA excel vào sqlserver 2008r2. em thử chạy trực tiếp trên máy cài sql thì ok. Nhưng sang máy khác thì lỗi
dbnetlib connectionopen (connect()). sql server does not exist or access denied
em thử nhiều cách mà vẫn chưa được mong các bác giúp đỡ.
Bạn đã cấu hình SQL Server cho phép kết nối hay chưa?
 
Bài 1:
Nhằm mục đích luyện tập và nâng cao kiến thức về ADO tôi xin mở topic này. Topic này chỉ dành cho những người mới học, bắt đầu học ADO như tôi tham gia.

Tôi có 2 Workbooks (A.xls và B.xls chung 1 folder): Wb A.xls có 1 sheet là sheet data dùng để chứa dữ liệu, wb B.xls là wb rỗng, trong đó có sheet1.

Xin hỏi là dùng ADO từ WB A.xls để copy toàn bộ dữ liệu của sheet data sang WB B.xls với sheet chứa dữ liệu là data
Anh ơi cho em hỏi. Sao bài 1 Em làm bị lỗi nó báo thế này vậy anh.
upload_2017-12-2_13-21-44.png
 

File đính kèm

Kiểm tra lại file B.xls coi có cột STT không nhé
Cám ơn anh. Đọc qua giúp đỡ của anh và Microft em đã cơ bản hiểu được chỗ này. Đây là câu lệnh thêm vào bảng. Vì vậy trong Sheet1 của File B.xls phải có columns heading giống bảng bên này. Sau khi thêm tên cột em đã INSERT thành công. Cám ơn anh HLMT nhiều. Ai bị lỗi giống em có thể tham khảo thêm tại https://support.microsoft.com/EN-US/help/295646
 
ở bài trên tôi code như vậy

Mã:
Sub TEST() ' KHONG CO TIEU DE
Dim Cn As Object
Dim Rst As Object
Dim i As Long
Set Cn = CreateObject("ADODB.connection")
Set Rst = CreateObject("ADODB.recordset")
    Sheet4.Range("a2:Z10000").Clear
    Cn.Provider = "Microsoft.ACE.OLEDB.12.0"
    Cn.Properties("Data Source") = ThisWorkbook.FullName
    Cn.Properties("Extended Properties") = "Excel 12.0;HDR=yes;IMEX=1"
    Cn.Open
    Rst.Open ("select MaKho, TenKho, count(SoPhieu), Sum(SoLuong) as So_Luong,Sum(SoLuong*gia) as SoTien from [data$] where Makho<>'' group by MaKho, TenKho"), Cn
    Sheet4.Range("a2").CopyFromRecordset Rst
    Rst.Close
    Cn.Close
End Sub
kết quả ra tất cả đều đúng nhưng tổng số phiếu không hợp lý
Tôi muốn tổng số phiếu là đếm những phiếu riêng biệt chứ không phải trùng
ví dụ như mã TL0010 số phiếu lá 23 chứ không phải là 156 . Xin được giúp đỡ xin cảm ơn
Bạn thử đổi câu lệnh truy vấn này xem sao
Rst.Open ("select Makho, TenKho, count(sophieu), sum(so_Luong),sum(So_Tien) from(select DISTINCT maKho, TenKho , SoPhieu, Sum(SoLuong) as So_Luong,Sum(SoLuong*gia) as So_Tien from [data$] where Makho<>'' group by MaKho, TenKho, sophieu) group by makho, tenkho"), Cn
 

File đính kèm

Nếu là SQL Server thì có thể Count(Distinct SoPhieu)
Nhưng hình như Access không hổ trợ dạng này.
Theo tôi nghĩ có lẽ bạn phải group 2 lần.
select MaKho, TenKho, count(*), Sum(SL) as So_Luong, Sum(ST) as SoTien from
(select MaKho, TenKho, Sum(SoLuong) as SL, Sum(SoLuong*gia) as ST from [data$] where Makho<>'' group by MaKho, TenKho, SoPhieu) As A group by MaKho, TenKho
 
Chào Các Anh
Mình muốn sữa đổi điều kiện trong đoạn code sau:
Thay thế điều kiện
[" & ThisWorkbook.FullName & "].[DK$A1:A4]
Thành điều kiện sau để khi cần bổ sung thêm điều kiện không cần sữa code.
With Sheet2
.Range("A1", .[A1].End(xlDown)).Value
End With

Mã:
Private Sub CommandButton1_Click()
Dim v As String, Cnn As Object, lrs As Object
Application.ScreenUpdating = False
    Set Cnn = CreateObject("ADODB.Connection")
    v = Application.Version
    With Sheet3
     .Range("A2:D5000").ClearContents
    Cnn.Open ("Provider=Microsoft." & IIf(v <> "8.0", "ACE.OLEDB.12.0", "Jet.OLEDB.4.0") & _
    ";Data Source=" & ThisWorkbook.FullName & ";Extended Properties=Excel " & IIf(v <> "8.0", "12.0", "8.0"))
'---------------------------------------------------------------------------------------------------------------
    Set lrs = Cnn.Execute("SELECT STT, TEN, sum(SoLuong), GhiChu " & _
                      "FROM [Data$] " & _
                          " WHERE STT IN (SELECT STT FROM [" & ThisWorkbook.FullName & "].[DK$A1:A4]) " & _
                          "GROUP BY STT,TEN,GhiChu ")
'---------------------------------------------------------------------------------------------------------------
    .Range("A2").CopyFromRecordset lrs
    End With
'---------------------------------------------------------------------------------------------------------------
lrs.Close: Set lrs = Nothing
Cnn.Close: Set Cnn = Nothing
Application.ScreenUpdating = True
End Sub
 

File đính kèm

Em chào cả nhà.
Em nhờ cả nhà hướng dẫn giúp em đoạn code ADO để ghi dữ liệu vào file đóng với cấu trúc file như em đã đính kèm. Em cũng thử sử dụng INNER JOIN và UPDATE như bác Hai Lúa Miền Tây đã viết trước đây nhưng lại bị vướng chỗ SUM và cột update dữ liệu. Em muốn sum dữ liệu từ SHEET MAIN sang SHEET DATA ạ. Làm theo hướng workbook.open thì em làm được rồi nhưng em muốn tìm hiểu xem code Ado thì viết ntn.
Em cám ơn mọi người.
 

File đính kèm

Các anh chị cho dhn46 hỏi về lấy dữ liệu file csv:
dhn46 có file 1.csv tại D:\, có file để chứa kết quả Result.Xlsm cùng thư mục D:\
Tại sheet1 file Result, [A1:A10] chứa điều kiện cần lọc tương ứng với cột thứ 1 file 1.csv
Vậy xin hỏi code sử dụng SQL để lấy dữ liệu từ file D:\1.csv tới file D:\Result.xlsm với điều kiện tại D:\Result.xlsm_Sheet1.[A1:A10]
Xin cảm ơn GPE
 
Các anh chị cho dhn46 hỏi về lấy dữ liệu file csv:
dhn46 có file 1.csv tại D:\, có file để chứa kết quả Result.Xlsm cùng thư mục D:\
Tại sheet1 file Result, [A1:A10] chứa điều kiện cần lọc tương ứng với cột thứ 1 file 1.csv
Vậy xin hỏi code sử dụng SQL để lấy dữ liệu từ file D:\1.csv tới file D:\Result.xlsm với điều kiện tại D:\Result.xlsm_Sheet1.[A1:A10]
Xin cảm ơn GPE

Ủa cái này có vấn đề gì khó hả bạn ? mình thấy hình như bạn cũng đâu có yếu khoản SQL ta :)
 
Ủa cái này có vấn đề gì khó hả bạn ? mình thấy hình như bạn cũng đâu có yếu khoản SQL ta :)
Không ai có thể biết hết mọi thứ, không biết thì hỏi có sao đâu bạn.
Các anh chị cho dhn46 hỏi về lấy dữ liệu file csv:
dhn46 có file 1.csv tại D:\, có file để chứa kết quả Result.Xlsm cùng thư mục D:\
Tại sheet1 file Result, [A1:A10] chứa điều kiện cần lọc tương ứng với cột thứ 1 file 1.csv
Vậy xin hỏi code sử dụng SQL để lấy dữ liệu từ file D:\1.csv tới file D:\Result.xlsm với điều kiện tại D:\Result.xlsm_Sheet1.[A1:A10]
Xin cảm ơn GPE
Bạn có thể dùng Inner Join để lấy dữ liệu theo ý nhé.

Mã:
Sub GetValue_CSV()
    With CreateObject("ADODB.Connection")
        .Open "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & ThisWorkbook.FullName & ";Extended Properties=Excel 12.0"
        Sheet2.Range("A2").CopyFromRecordset .Execute("SELECT * FROM [Text;Database=" & ThisWorkbook.Path & ";HDR=YES;FMT=Delimited].[1.csv] a " & _
                                                        "INNER JOIN [Sheet1$A1:A10] b on a.[ID]=b.[ID] ")
    End With
End Sub
 

File đính kèm

Không ai có thể biết hết mọi thứ, không biết thì hỏi có sao đâu bạn.

Bạn có thể dùng Inner Join để lấy dữ liệu theo ý nhé.

Mã:
Sub GetValue_CSV()
    With CreateObject("ADODB.Connection")
        .Open "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & ThisWorkbook.FullName & ";Extended Properties=Excel 12.0"
        Sheet2.Range("A2").CopyFromRecordset .Execute("SELECT * FROM [Text;Database=" & ThisWorkbook.Path & ";HDR=YES;FMT=Delimited].[1.csv] a " & _
                                                        "INNER JOIN [Sheet1$A1:A10] b on a.[ID]=b.[ID] ")
    End With
End Sub

Đây là dạng kết nối dữ liệu từ 2 database khác nhau, cách viết cũng gần giống như kết nối 2 file excel khác nhau.
Mình thấy bạn đó tham gia nhiều chủ đề ADO chắc có biết kỹ thuật này chứ. Vui thôi mà.
 
Đây là dạng kết nối dữ liệu từ 2 database khác nhau, cách viết cũng gần giống như kết nối 2 file excel khác nhau.
Mình thấy bạn đó tham gia nhiều chủ đề ADO chắc có biết kỹ thuật này chứ. Vui thôi mà.
Việc kết nối dữ liệu với nhiều kiểu dữ liệu nguồn khác nhau cũng ít gặp trên diễn đàn này. Nên người ta chưa biết thì người ta hỏi. Nếu mình biết và thích trả lời thì mình trả lời giúp họ, đừng nên vặn vẹo chi nhé.
 
Việc kết nối dữ liệu với nhiều kiểu dữ liệu nguồn khác nhau cũng ít gặp trên diễn đàn này. Nên người ta chưa biết thì người ta hỏi. Nếu mình biết và thích trả lời thì mình trả lời giúp họ, đừng nên vặn vẹo chi nhé.
Cảm ơn anh HLMT và bạn AutoReply nhiều.

Dhn46 cũng đã thử nhưng chưa làm được ^^.

Với lượng dữ liệu nhiều thì kết nối ADO tới file csv này nhanh hơn việc mở file nên dhn46 muốn thử cho trường hợp này (đã test với "Select * from 1.csv")

Không biết còn phương pháp nào mà tốc độ lấy dữ liệu cao hơn không với file *.csv lên tới hàng GB? Nếu có nhờ các anh chị chỉ giúp (không xét các trường hợp sử dụng Server)
 
Cảm ơn anh HLMT và bạn AutoReply nhiều.

Dhn46 cũng đã thử nhưng chưa làm được ^^.

Với lượng dữ liệu nhiều thì kết nối ADO tới file csv này nhanh hơn việc mở file nên dhn46 muốn thử cho trường hợp này (đã test với "Select * from 1.csv")

Không biết còn phương pháp nào mà tốc độ lấy dữ liệu cao hơn không với file *.csv lên tới hàng GB? Nếu có nhờ các anh chị chỉ giúp (không xét các trường hợp sử dụng Server)
Chưa làm được là do dữ liệu nhiều hay là do chỗ nào vậy bạn?
 
Chưa làm được là do dữ liệu nhiều hay là do chỗ nào vậy bạn?
Đây là sub lấy toàn bộ dữ liệu của em
Mã:
Sub Test1()
    Set cnn = CreateObject("ADODB.Connection")
    Set rcst = CreateObject("ADODB.Recordset")
    pathFolder = ThisWorkbook.Path
    cnn.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & pathFolder & _
                           ";Mode=Read;Extended Properties=""Text;HDR=NO;FMT=Delimited(,)"";"
    cnn.Open
            strQuery = "Select * from 1.csv"
            rcst.Open strQuery, cnn
    Range("A1").CopyFromRecordset rcst
End Sub
Đây là hướng em lấy 1 phần dữ liệu.
Anh xem giúp em hướng này sai tại đâu nhé
Cảm ơn anh!
Mã:
Sub Test()
    Set cnn = CreateObject("ADODB.Connection")
    Set rcst = CreateObject("ADODB.Recordset")
    pathFolder = ThisWorkbook.Path
    cnn.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & pathFolder & _
                           ";Mode=Read;Extended Properties=""Text;HDR=NO;FMT=Delimited(,)"";"
    cnn.Open
            strQuery = "Select * from 1.csv where F1 in [excel 8.0;database=" & ThisWorkbook.FullName & ";HDR=No].[Sheet1$A1:A10].F1"
            rcst.Open strQuery, cnn
    Range("A1").CopyFromRecordset rcst
End Sub
 
Đây là sub lấy toàn bộ dữ liệu của em
Mã:
Sub Test1()
    Set cnn = CreateObject("ADODB.Connection")
    Set rcst = CreateObject("ADODB.Recordset")
    pathFolder = ThisWorkbook.Path
    cnn.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & pathFolder & _
                           ";Mode=Read;Extended Properties=""Text;HDR=NO;FMT=Delimited(,)"";"
    cnn.Open
            strQuery = "Select * from 1.csv"
            rcst.Open strQuery, cnn
    Range("A1").CopyFromRecordset rcst
End Sub
Đây là hướng em lấy 1 phần dữ liệu.
Anh xem giúp em hướng này sai tại đâu nhé
Cảm ơn anh!
Mã:
Sub Test()
    Set cnn = CreateObject("ADODB.Connection")
    Set rcst = CreateObject("ADODB.Recordset")
    pathFolder = ThisWorkbook.Path
    cnn.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & pathFolder & _
                           ";Mode=Read;Extended Properties=""Text;HDR=NO;FMT=Delimited(,)"";"
    cnn.Open
            strQuery = "Select * from 1.csv where F1 in [excel 8.0;database=" & ThisWorkbook.FullName & ";HDR=No].[Sheet1$A1:A10].F1"
            rcst.Open strQuery, cnn
    Range("A1").CopyFromRecordset rcst
End Sub
Đổi lại code như bài của tôi thử nhé.
 
Đây là sub lấy toàn bộ dữ liệu của em
Mã:
Sub Test1()
    Set cnn = CreateObject("ADODB.Connection")
    Set rcst = CreateObject("ADODB.Recordset")
    pathFolder = ThisWorkbook.Path
    cnn.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & pathFolder & _
                           ";Mode=Read;Extended Properties=""Text;HDR=NO;FMT=Delimited(,)"";"
    cnn.Open
            strQuery = "Select * from 1.csv"
            rcst.Open strQuery, cnn
    Range("A1").CopyFromRecordset rcst
End Sub
Đây là hướng em lấy 1 phần dữ liệu.
Anh xem giúp em hướng này sai tại đâu nhé
Cảm ơn anh!
Mã:
Sub Test()
    Set cnn = CreateObject("ADODB.Connection")
    Set rcst = CreateObject("ADODB.Recordset")
    pathFolder = ThisWorkbook.Path
    cnn.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & pathFolder & _
                           ";Mode=Read;Extended Properties=""Text;HDR=NO;FMT=Delimited(,)"";"
    cnn.Open
            strQuery = "Select * from 1.csv where F1 in [excel 8.0;database=" & ThisWorkbook.FullName & ";HDR=No].[Sheet1$A1:A10].F1"
            rcst.Open strQuery, cnn
    Range("A1").CopyFromRecordset rcst
End Sub

Không thấy bạn nói thêm gì, thôi thì tôi chỉnh lại theo miêu tả của bạn bên dưới.
Mã:
Sub GetValue_CSV()
    With CreateObject("ADODB.Connection")
        .Open "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & ThisWorkbook.FullName & ";Extended Properties=""Excel 12.0;HDR=No"""
        Sheet2.Range("A2").CopyFromRecordset .Execute("SELECT a.* FROM [Text;Database=" & ThisWorkbook.Path & ";HDR=NO;FMT=Delimited].[1.csv] a " & _
                                                        "INNER JOIN [Sheet1$A1:A10] b on a.[F1]=b.[F1] ")
    End With
End Sub
 
Đổi lại code như bài của tôi thử nhé.
Cảm ơn anh HLMT, em đã áp dụng hướng dẫn của anh và sử dụng được cho công việc của mình.
có 1 vấn đề phát sinh là tên File có dấu chấm thì Code báo lỗi.
Vậy có cách nào khắc phục vấn đề này không anh?
Nhờ anh và các anh chị tư vấn và cho giải pháp.
Mã:
Sub CsvToExcel(FilterSN As Boolean, cTarget As Range)
Dim LinkFile As String, LinkFolder As String, FileName As String, strSQL As String
Dim Cnn, Rst
Set Cnn = CreateObject("ADODB.Connection")
Set Rst = CreateObject("ADODB.Recordset")
With Application.FileDialog(msoFileDialogFilePicker)
    If .Show = -1 Then
        .AllowMultiSelect = False
        LinkFile = .SelectedItems(1)
        LinkFolder = Left(LinkFile, InStrRev(LinkFile, "\"))
        FileName = Right(LinkFile, Len(LinkFile) - InStrRev(LinkFile, "\"))
    End If
If .SelectedItems.Count > 0 Then
Cnn.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & LinkFolder & _
                           ";Mode=Read;Extended Properties=""Text;HDR=No;FMT=Delimited(,)"";"
                           
If FilterSN = True Then
    strSQL = "SELECT * FROM [Text;Database=" & ThisWorkbook.Path & ";HDR=No;FMT=Delimited].[" & FileName & "] a " & _
                                                        "INNER JOIN [FilterSN$B4:B1000] b on a.[ID]=b.[ID] "
Else
    strSQL = "SELECT * FROM [Text;Database=" & LinkFolder & ";HDR=No;FMT=Delimited].[" & FileName & "] a"
End If
Cnn.Open "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & ThisWorkbook.FullName & ";Extended Properties=Excel 12.0"
Rst.Open strSQL, Cnn, 1, 3
cTarget.CopyFromRecordset Rst
 
Tôi đã đọc loạt bài viết về ADO của mọi người trong chuyên đề này, tôi đã viết 1 đoạn code test thử cho mục đích tổng hợp bảng chấm công như trong file đính kèm. kết quả là dữ liệu tập hợp bị thiếu rất nhiều kể cả trên 1 dòng hay trên nhiều cột, thiếu cả dữ liệu dạng text, cả dữ liệu dạng số, cả dữ liệu là time....
File dữ liệu nguồn là bảng chấm công cũng đã test tiêu đề cột dạng text, dạng Number đủ cả, vùng dữ liệu cũng test các kiểu: cả bảng tính hoặc chỉ vùng chấm công ... đều không được. kết quả khi mở file nguồn và khi đóng file nguồn là khác nhau...
Tôi đưa file đính kèm hy vọng mọi người vào xem và giải quyết giúp vấn đề.
Trân trọng
 

File đính kèm

Tôi đã đọc loạt bài viết về ADO của mọi người trong chuyên đề này, tôi đã viết 1 đoạn code test thử cho mục đích tổng hợp bảng chấm công như trong file đính kèm. kết quả là dữ liệu tập hợp bị thiếu rất nhiều kể cả trên 1 dòng hay trên nhiều cột, thiếu cả dữ liệu dạng text, cả dữ liệu dạng số, cả dữ liệu là time....
File dữ liệu nguồn là bảng chấm công cũng đã test tiêu đề cột dạng text, dạng Number đủ cả, vùng dữ liệu cũng test các kiểu: cả bảng tính hoặc chỉ vùng chấm công ... đều không được. kết quả khi mở file nguồn và khi đóng file nguồn là khác nhau...
Tôi đưa file đính kèm hy vọng mọi người vào xem và giải quyết giúp vấn đề.
Trân trọng

Bạn giải thích giùm câu lệnh SQL mà bạn muốn lấy dữ liệu nhé: thực sự tôi cũng chưa hiểu lắm

Mã:
"SELECT *,'ChamcongGioLamViecTo1.xlsm' as [From File] ,(SELECT *  FROM [T1$D6:D6]) FROM [T1$B12:EM] WHERE F1 is not Null"

ADO rất khó tính trong việc đọc dữ liệu, bạn cứ thử nếu tiêu đề dạng Text thì dữ liệu bên dứoi bạn cũng đổi về text đối chiếu xem ADO nó convert đúng không.
 
Lần chỉnh sửa cuối:
Bạn giải thích giùm câu lệnh SQL mà bạn muốn lấy dữ liệu nhé: thực sự tôi cũng chưa hiểu lắm

Mã:
"SELECT *,'ChamcongGioLamViecTo1.xlsm' as [From File] ,(SELECT *  FROM [T1$D6:D6]) FROM [T1$B12:EM] WHERE F1 is not Null"
Trong câu lệnh trên ngoài việc lấy dữ liệu tất cả các cột của vùng B12:EM của sheet T1 thì chèn thêm cột tên file lấy từ tên file nguồn, cột tháng lấy từ D6 của sheet T1, loại bỏ tất cả các dòng rỗng của cột B trong dữ liệu nguồn. Đại ý là như vậy bạn nhé.
 
Nhìn trong file bạn tôi thấy nó không thiết dữ liệu mà chỉ không hiển thị dữ liệu là: 12:00:00 AM. Hình như cái kiểu này của Excel, phải chọn "Show a zero in cells that have zero value" nó mới hiển thị.
 
Lần chỉnh sửa cuối:
Nhìn trong file bạn tôi thấy nó không thiết dữ liệu mà chỉ không hiển thị dữ liệu là: 12:00:00 AM. Hình như cái kiểu này của Excel, phải chọn "Show a zero in cells that have zero value" nó mới hiển thị.
Phần định dạng mình có thể đưa code xử lý, không cần bàn nội dung này. Vấn đề là code hiện tại sửa thế nào để có thể lấy đủ dữ liệu từ file nguồn theo mong muốn của mình. Ở đây vấn đề đáng nói là dữ liệu kiểu text cũng thiếu, kiểu number cũng thiếu, kiểu time cũng thiếu, file nguồn nếu mở cho kết quả khác, nếu đóng cho kết quả khác. Anh ADO này khó nhằn thật.
 
Tôi đã đọc loạt bài viết về ADO của mọi người trong chuyên đề này, tôi đã viết 1 đoạn code test thử cho mục đích tổng hợp bảng chấm công như trong file đính kèm. kết quả là dữ liệu tập hợp bị thiếu rất nhiều kể cả trên 1 dòng hay trên nhiều cột, thiếu cả dữ liệu dạng text, cả dữ liệu dạng số, cả dữ liệu là time....
File dữ liệu nguồn là bảng chấm công cũng đã test tiêu đề cột dạng text, dạng Number đủ cả, vùng dữ liệu cũng test các kiểu: cả bảng tính hoặc chỉ vùng chấm công ... đều không được. kết quả khi mở file nguồn và khi đóng file nguồn là khác nhau...
Tôi đưa file đính kèm hy vọng mọi người vào xem và giải quyết giúp vấn đề.
Trân trọng
Tôi vẫn ngóng kết quả. hy vọng có bạn giúp giải quyết vấn đề
 
Phần định dạng mình có thể đưa code xử lý, không cần bàn nội dung này. Vấn đề là code hiện tại sửa thế nào để có thể lấy đủ dữ liệu từ file nguồn theo mong muốn của mình. Ở đây vấn đề đáng nói là dữ liệu kiểu text cũng thiếu, kiểu number cũng thiếu, kiểu time cũng thiếu, file nguồn nếu mở cho kết quả khác, nếu đóng cho kết quả khác. Anh ADO này khó nhằn thật.
Không khó nhằn đâu, vì dữ liệu gốc của bạn nó bị lộ cộ tiêu đề tùm lum nên thế
Thử thay thành $B11:EM (thay vì cũ $B12:EM) xem có khá hơn chút không
Nhưng giải phải trị gốc là cơ sở dữ liệu raw (gốc) phải có tiêu đề rõ ràng
 
Không khó nhằn đâu, vì dữ liệu gốc của bạn nó bị lộ cộ tiêu đề tùm lum nên thế
Thử thay thành $B11:EM (thay vì cũ $B12:EM) xem có khá hơn chút không
Nhưng giải phải trị gốc là cơ sở dữ liệu raw (gốc) phải có tiêu đề rõ ràng
Toàn bộ dòng 1 đến dòng 11 mình đã bỏ qua không duyệt đến nó vì đúng như bạn nêu, từ dòng 12 là vùng dữ liệu mình quan tâm, coi như nó là dòng tiêu đề, dòng này có cột dạng text, cột dạng number.
vấn đề cùng dạng number nhưng có cột lấy được dữ liệu, có cột mất.... thực sự là nguyên nhân ở chỗ nào mình đang muốn biết. tìm đọc không thấy. Test các vùng khác nhau nhiều rồi ko có kết quả đúng trừ khi file nguồn được mở
 
Toàn bộ dòng 1 đến dòng 11 mình đã bỏ qua không duyệt đến nó vì đúng như bạn nêu, từ dòng 12 là vùng dữ liệu mình quan tâm, coi như nó là dòng tiêu đề, dòng này có cột dạng text, cột dạng number.
vấn đề cùng dạng number nhưng có cột lấy được dữ liệu, có cột mất.... thực sự là nguyên nhân ở chỗ nào mình đang muốn biết. tìm đọc không thấy. Test các vùng khác nhau nhiều rồi ko có kết quả đúng trừ khi file nguồn được mở
Nguyên nhân là ADO là ứng với kiểu xử lý database thường ưa thích là database chuẩn có tiêu đề, dữ liệu cùng 1 cột phải cùng kiểu dữ liệu
Trường hợp vấn đề ở đây là chương trình sẽ dò tìm 8 dòng đầu để dịnh kiểu (datatype) cho field (column) tương ứng, vì dữ liệu trống nên nó sẽ CÓ THỂ định kiểu sai, dẫn đến hiểu lầm dữ liệu time sau... nên bỏ qua

Nếu dữ liệu vẫn lộ cộ thế, thì bạn nên thử đọc và xét sâu vấn đề
Rst.Open strSQL, Cnn, 1, 3
---> tham số 1 , 3 đằng sau cho hợp lý

giá trị IMEX trong chuỗi connectstring cũng ảnh hưởng việc định kiểu,
Thử thay đổi chúng nó xem sao
 
Nguyên nhân là ADO là ứng với kiểu xử lý database thường ưa thích là database chuẩn có tiêu đề, dữ liệu cùng 1 cột phải cùng kiểu dữ liệu
Trường hợp vấn đề ở đây là chương trình sẽ dò tìm 8 dòng đầu để dịnh kiểu (datatype) cho field (column) tương ứng, vì dữ liệu trống nên nó sẽ CÓ THỂ định kiểu sai, dẫn đến hiểu lầm dữ liệu time sau... nên bỏ qua

Nếu dữ liệu vẫn lộ cộ thế, thì bạn nên thử đọc và xét sâu vấn đề
Rst.Open strSQL, Cnn, 1, 3
---> tham số 1 , 3 đằng sau cho hợp lý

giá trị IMEX trong chuỗi connectstring cũng ảnh hưởng việc định kiểu,
Thử thay đổi chúng nó xem sao
Sau một hồi Test và KQ = Không đạt.
Bạn có thể sửa trực tiếp vào File hộ mình được không ???
 
Hic. Nhiều dữ liệu quá... chỉ là bảng chấm công.
Nhiều là số liệu lộ cộ, chồng chéo, cái có cái không, nên khó kiểm soát nếu không phải chủ nhân của nó - nên tôi không kiểm soát là đã đủ dữ liệu lấy như bạn mong muộn, do vậy không test tốt được.
 
Nguyên nhân là ADO là ứng với kiểu xử lý database thường ưa thích là database chuẩn có tiêu đề, dữ liệu cùng 1 cột phải cùng kiểu dữ liệu
Trường hợp vấn đề ở đây là chương trình sẽ dò tìm 8 dòng đầu để dịnh kiểu datatype) cho field (column) tương ứng, vì dữ liệu trống nên nó sẽ CÓ THỂ định kiểu sai, dẫn đến hiểu lầm dữ liệu time sau... nên bỏ qua
...

Đã lỡ chỉ đến đây rồi thì chỉ luôn cách vượt qua vấn đề này luôn đi.
 
Ở đây vấn đề đáng nói là dữ liệu kiểu text cũng thiếu, kiểu number cũng thiếu, kiểu time cũng thiếu, file nguồn nếu mở cho kết quả khác, nếu đóng cho kết quả khác. Anh ADO này khó nhằn thật.
Nếu đã chấp nhận dùng ADO thì phải chấp nhận việc xây dựng CSDL đúng chuẩn. Còn nếu dữ liệu không đúng chuẩn thì ta không nên dùng nó. Bởi vì ta sẽ không chắc chắn rằng khi sử dụng sẽ không gặp phải vấn đề.
 
Nếu đã chấp nhận dùng ADO thì phải chấp nhận việc xây dựng CSDL đúng chuẩn. Còn nếu dữ liệu không đúng chuẩn thì ta không nên dùng nó. Bởi vì ta sẽ không chắc chắn rằng khi sử dụng sẽ không gặp phải vấn đề.
Đây là dữ liệu chấm công nên trong 1 trường nó có đầy đủ các loại dữ liệu text, time, number, không thể khác. Nếu theo như anh nói ở trên có nghĩa không áp dụng ADO cho bài toán này. Vậy ta giải thích sao khi dữ liệu nguồn mở thì kết quả lại đúng. Khi đóng dữ liệu nguồn thì kết quả lại sai.
Và với bài toán này khi vùng dữ liệu nguồn ta chọn có dòng đầu tiên là text ở tất cả các trường dữ liệu thì kết quả ok(Dựa trên góp ý của Nguyễn Duy Tuân). Phương án em lựa chọn là thiết kế lại dòng đầu tiên của vùng dữ liệu nguồn và tạm hài lòng kết quả.
 
Đây là dữ liệu chấm công nên trong 1 trường nó có đầy đủ các loại dữ liệu text, time, number, không thể khác. Nếu theo như anh nói ở trên có nghĩa không áp dụng ADO cho bài toán này. Vậy ta giải thích sao khi dữ liệu nguồn mở thì kết quả lại đúng. Khi đóng dữ liệu nguồn thì kết quả lại sai.
Và với bài toán này khi vùng dữ liệu nguồn ta chọn có dòng đầu tiên là text ở tất cả các trường dữ liệu thì kết quả ok(Dựa trên góp ý của Nguyễn Duy Tuân). Phương án em lựa chọn là thiết kế lại dòng đầu tiên của vùng dữ liệu nguồn và tạm hài lòng kết quả.

Có mấy vấn đề về bài toán của bạn cần phải xem lại.
- Chắc bạn chưa hiểu CSDL đúng chuẩn như bác HLMT đã nói nên mới đem ra so sánh với cái file dữ liệu chấm công Excel của bạn. CSDL chuẩn cơ bản là: (nói riêng cho file excel)
+ "Kiểu dữ liệu" cột nào ra cột đó. Cột này có thể "Text", cột kia "Date", cột khác dạng "Number"... nhưng bắt buộc không có kiểu trộn lẫn các loại dữ liệu vô cùng 1 cột.
+ Tiêu đề cột phải đầy đủ cho các cột nếu dùng "HDR=Yes".
- File chấm công của bạn không phải là CSDL chuẩn vì vi phạm nguyên tắc trên. Một cột dạng DateTime mà có thêm Text.
- File chấm công của bạn không phải là file dữ liệu gốc (thô) mà là dữ liệu đã qua xử lý để báo cáo (thêm các ký hiệu chấm công) nên để dùng ADO đọc dữ liệu thì kết quả trả về không tin tưởng được. Lập trình code, xử lý, đúng là đúng, sai là sai, không thể tạm hài lòng vì hên kết quả lần này ra đúng.
Cách nên làm là xử lý từ file dữ liệu thô của máy chấm công (máy có thể xuất dạng Excel, text cũng được). Thêm dữ liệu nghỉ phép, dùng công thức tính toán giờ vào ra v.v.. để xử lý bài toán chấm công.
Còn việc ADO đọc dữ liệu Excel khi file đóng hay mở cho kết quả khác nhau đó là một cái lỗi mà chính Microsoft đã thông báo rồi. "Việc Query một file Excel đang mở bằng ADO trong VBA có thể gây rò rỉ bộ nhớ (memory leak), các tham chiếu trong bộ nhớ không được giải phóng nên có thể làm kết quả sai".
 
Có mấy vấn đề về bài toán của bạn cần phải xem lại.
- Chắc bạn chưa hiểu CSDL đúng chuẩn như bác HLMT đã nói nên mới đem ra so sánh với cái file dữ liệu chấm công Excel của bạn. CSDL chuẩn cơ bản là: (nói riêng cho file excel)
+ "Kiểu dữ liệu" cột nào ra cột đó. Cột này có thể "Text", cột kia "Date", cột khác dạng "Number"... nhưng bắt buộc không có kiểu trộn lẫn các loại dữ liệu vô cùng 1 cột.
+ Tiêu đề cột phải đầy đủ cho các cột nếu dùng "HDR=Yes".
- File chấm công của bạn không phải là CSDL chuẩn vì vi phạm nguyên tắc trên. Một cột dạng DateTime mà có thêm Text.
- File chấm công của bạn không phải là file dữ liệu gốc (thô) mà là dữ liệu đã qua xử lý để báo cáo (thêm các ký hiệu chấm công) nên để dùng ADO đọc dữ liệu thì kết quả trả về không tin tưởng được. Lập trình code, xử lý, đúng là đúng, sai là sai, không thể tạm hài lòng vì hên kết quả lần này ra đúng.
Cách nên làm là xử lý từ file dữ liệu thô của máy chấm công (máy có thể xuất dạng Excel, text cũng được). Thêm dữ liệu nghỉ phép, dùng công thức tính toán giờ vào ra v.v.. để xử lý bài toán chấm công.
Còn việc ADO đọc dữ liệu Excel khi file đóng hay mở cho kết quả khác nhau đó là một cái lỗi mà chính Microsoft đã thông báo rồi. "Việc Query một file Excel đang mở bằng ADO trong VBA có thể gây rò rỉ bộ nhớ (memory leak), các tham chiếu trong bộ nhớ không được giải phóng nên có thể làm kết quả sai".
Cám ơn ý kiến của bạn. Hiểu thêm chút kiến thức.
 
Nếu đã chấp nhận dùng ADO thì phải chấp nhận việc xây dựng CSDL đúng chuẩn. Còn nếu dữ liệu không đúng chuẩn thì ta không nên dùng nó. Bởi vì ta sẽ không chắc chắn rằng khi sử dụng sẽ không gặp phải vấn đề.
Anh ơi cho em hỏi là.Bây giờ mình muốn lấy dữ liệu ở file đóng dùng ADO.Nhưng lấy vào mảng và chỉ lấy dòng dữ liệu cuối cùng thì làm thế nào vậy anh.
 

File đính kèm

Anh ơi cho em hỏi là.Bây giờ mình muốn lấy dữ liệu ở file đóng dùng ADO.Nhưng lấy vào mảng và chỉ lấy dòng dữ liệu cuối cùng thì làm thế nào vậy anh.
File đóng, là sao? có nghĩa là còn file nữa, vậy post lên (lưu ý không bao giờ lấy dữ liệu từ file đóng được, mà khi đó chỉ nói là không mở ở excel và kết nối lấy dữ liệu qua ADO)
Và bạn chỉ nhờ riêng, nên thôi đợi người nhờ vậy
 
Chắc từ nay hông keo lấy Dữ Liệu File đóng nữa mà keo là: Sử dụng ADO lấy dữ liệu file Excel khác hay lấy dữ Liệu Database.accdb ..........he -0-0-0-===\.
Còn keo cô next hay Cnn khó nhớ thấy bà ....
 
...Nhưng lấy vào mảng và chỉ lấy dòng dữ liệu cuối cùng thì làm thế nào vậy anh.
1. Hàm GetRows() của RecordSet lấy dữ liệu vào mảng. Nếu không có tham số thì nó đổ cả RecordSet vào 1 mảng 2 chiều. Từ đó, mò đến dòng cuối cùng của mảng.
2. Hàm MoveLast đi đến dòng cuối của RecordSet. Hàm GetRows(1, 0) đọc dòng này
Thực ra thì GetRows(1, 2) cũng đọc được dòng cuối của RecordSet mà không cần MoveLast.
 
Chắc từ nay hông keo lấy Dữ Liệu File đóng nữa mà keo là: Sử dụng ADO lấy dữ liệu file Excel khác hay lấy dữ Liệu Database.accdb ..........he -0-0-0-===\.
Còn keo cô next hay Cnn khó nhớ thấy bà ....
Túm lại: là file không thể đóng, khi có nhu cầu lấy dữ liệu, nếu ai viết hay nói vậy, là chỉ đúng 1 nửa
 
Em xin chào cả nhà
Em có 2 File "Input" và "Output" :

-File "Input" : Sheet"Input" Chứa dữ liệu nhập
-File "Output" Sheet"Output" Chứa tiêu đề giống với "Input"
=>Em muốn thiết kế 2 nút bấm "GetData" và "Update"

1/ Nút "GetData" => Sẽ lấy tất dữ liệu (trừ dòng tiêu đề) từ Sheet "Input" sang "Output" với điều kiện Sheet "Output" đang đóng/mở đều sẽ thao tác được & Nếu đã "GetData" được tất cả dữ liệu từ "Input" rồi thì khi Click "GetData" lần n+1 dữ liệu sẽ không đổ thêm vào nữa tránh bị Double, hoặc khi Click "GetData" các dòng dữ liệu tại Sheet"Ouuput được xóa đi và ghi lại (Theo hướng sử dụng ADODB)

2/ Nút "Update" => Sẽ cập nhật dữ liệu được sửa đổi từ Sheet"Input" sang "Output" với điều kiện dữ liệu "SoTicket" on "Input" = "SoTicket" on "Output" (Ví dụ: chỉ Update được khi TM41055001 ở "Input" = TM41055001 ở "Output")

*Note : Có thể Bonus giúp em thêm kết hợp ADO và ARRAY
*Note 2: Cả nhà nếu có phương án hoặc giải pháp nào tốt hơn thì em cũng rất mong được tư vấn ạ

Mong cả nhà giúp đỡ em, em vừa gia nhập VBA không được bao lâu và thật sự rất tâm đắc với các nghiên cứu của các bậc tiền bối, nhưng vì kiến thức ADO và VBA còn có giới hạn nên chỉ có thể Edit và tùy biến theo mô hình làm việc của riêng mình. Rất cám ơn cả nhà
 

File đính kèm

Em sorry anh , anh download file đính kèm về xem giúp em, em đã sửa lại Tiếng Việt . Vì tên file em đặt là tiếng anh nên có vẻ hơm rườm rà một chút => Mong cả nhà hỗ trợ
Em có 2 File "Input" và "Output" :

-File "Input" : Sheet"Input" Chứa dữ liệu nhập
-File "Output" Sheet"Output" Chứa tiêu đề giống với "Input"
=>Em muốn thiết kế 2 nút bấm "GetData" và "Update"

1/ Nút "Gửi dữ liệu (Insert)" => Sẽ lấy tất dữ liệu (trừ dòng tiêu đề) từ Sheet "Input" sang "Output" với điều kiện Sheet "Output" đang đóng/mở đều sẽ thao tác được & Nếu đã "Gửi dữ liệu (Insert)" được tất cả dữ liệu từ "Input" rồi thì khi Click "Gửi dữ liệu (Insert)" lần n+1 dữ liệu sẽ không đổ thêm vào nữa tránh bị trùng và sinh ra nhiều dòng hàng giống nhau, hoặc khi bấm "Gửi dữ liệu (Insert)" các dòng dữ liệu tại Sheet"Output" được xóa đi và ghi lại (Theo hướng sử dụng ADODB)

2/ Nút "Cập nhật (Update)" => Sẽ cập nhật dữ liệu được sửa đổi từ Sheet"Input" sang "Output" với điều kiện dữ liệu "SoTicket" trong file "Input" = "SoTicket" trong file "Output" (Ví dụ: chỉ Cập nhật (Update) được khi TM41055001 ở "Input" = TM41055001 ở "Output")

*Note : Có thể theme giúp em kết hợp ADO và ARRAY
*Note 2: Cả nhà nếu có phương án hoặc giải pháp nào tốt hơn thì em cũng rất mong được tư vấn ạ

Mong cả nhà giúp đỡ em, em vừa gia nhập VBA không được bao lâu và thật sự rất tâm đắc với các nghiên cứu của các bậc tiền bối, nhưng vì kiến thức ADO và VBA còn có giới hạn nên chỉ có thể Edit và tùy biến theo mô hình làm việc của riêng mình. Rất cám ơn cả nhà
 

File đính kèm

Em sorry anh , anh download file đính kèm về xem giúp em, em đã sửa lại Tiếng Việt . Vì tên file em đặt là tiếng anh nên có vẻ hơm rườm rà một
..

*Note : Có thể theme giúp em kết hợp ADO và ARRAY
*Note 2: Cả nhà nếu có phương án hoặc giải pháp nào tốt hơn thì em cũng rất mong được tư vấn ạ

Ý là diễn giải yêu cầu bằng tiếng Việt đừng chen tiếng Anh vô. Ở môi trường cty bạn, bạn có thể nói chuyện chen Anh VIệt gì đó thì tùy nhưng ở các diễn đàn, môi trường công cộng nên dùng thuần Việt giao tiếp thì hay hơn. :)
 
... ở các diễn đàn, môi trường công cộng nên dùng thuần Việt giao tiếp thì hay hơn. :)
Việc tôi không thích dùng tiếng Anh Việt lẫn lộn là vì lý do cá nhân. Giản dị hơn là tôi không muốn con tôi "Hai Đét" mỗi sáng gặp mặt.

Ở diễn đàn, tiếng Anh Việt lẫn lộn gây khó hiểu. Điển hình là từ "theme" ở trên. Nó là tiếng Anh hay tiếng Việt gõ sai? "Note" ở trên là "yêu cầu" hay "phụ chú"?

Ở môi trường công cộng, tiếng Anh Việt lẫn lộn còn liên quan đến vấn đề ngữ cảnh. Có nhiều lúc nghe thấy giọng mỉa mai châm biếm nhưng lại không biết người dùng cố tình hay do dốt tiếng Anh mà còn ráng rặn.

Vì vậy tôi có nói, "muốn dùng tiếng Anh thì dùng luôn cả bài". Khi ấy mình biết rõ chủ đích người viết.
 
em thì lại thích các bạn dùng tiếng Anh lẫn tiếng Việt luôn , vì nó cũng là 1 cách học mà ^^

(Em sorry anh , anh download file đính kèm về xem giúp em, em đã sửa lại Tiếng Việt)
như câu này thì bạn này hơi lười , hàm lượng đầu tư cho tiếng Anh chưa cao nên cũng ko học đc gì nhiều từ bạn

nếu bạn ghi theo cú pháp !

Em xin lỗi anh , anh tải tập tin đính kèm về xem giúp em, em đã sửa lại tiếng Việt
(i'm sorry , please download the attached file and help me to check it, i already revise Vietnamese)

thì mình nghĩ là có đóng góp cho cộng đồng hơn ^^
 
em thì lại thích các bạn dùng tiếng Anh lẫn tiếng Việt luôn , vì nó cũng là 1 cách học mà ^^
...
Bạn muốn học theo cách gì thì cũng là quyền tự do cá nhân. Nhưng tôi khuyến cáo cho các bạn khác còn phân vân:
- Dùng 2 thứ tiếng lẫn lộn là cách học không tốt. Tiếng Anh khó nhất không phải là từ vựng, mà nó khó ở câu cú - nhất là thành ngữ. Vì vậy, lúc học tiếng Anh, đầu óc phải hoàn toàn suy nghĩ theo văn hoá Anh.

Điển hình, một bạn nọ viết:
"Sau một time tìm hiểu về..."
time ở đây là cái gì? Tiếng Anh từ time có hai nghĩa, "thời gian" và "lượt". Cả hai nghĩa ấy đưa vào câu trên đều có thể dịch được, tuy rằng ra hai nghĩa khác nhau hoàn toàn.
 
Các anh cho em hỏi là em viết code lấy dữ liệu vào mảng bằng ADO nhưng nó chỉ lấy được 255 ký tự vào mảng.Có cách nào lấy được toàn bộ dữ liệu không nhỉ.
Mã:
Sub tonghop()
     Application.ScreenUpdating = False
     Application.AskToUpdateLinks = False
     Application.DisplayAlerts = False
     Dim cn As Object, sqlStr As String, i As Long, lr As Long, k, rst As Object, Pro As String, ext As String, arr(1 To 1000, 1 To 14), a As Long
     Dim sarr, j As Long, b As Long
     Set cn = CreateObject("ADODB.Connection")
     Set rst = CreateObject("ADODB.recordset")
     With Application.FileDialog(msoFileDialogFilePicker)
         .AllowMultiSelect = True
    If Not .Show = -1 Then Exit Sub
    For Each k In .SelectedItems
       Pro = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source="
       ext = ";Extended Properties=""Excel 12.0;HDR=yes;IMEX= 1"";"
       cn.Open (Pro & k & ext)
       sqlStr = "Select * From [sheet1$a1:e30]"
       sarr = cn.Execute(sqlStr).GetRows
       a = a + 1
       b = Len(sarr(1, 24))
       arr(a, 1) = a
       arr(a, 2) = sarr(1, 3)
       arr(a, 3) = sarr(1, 0)
       arr(a, 4) = sarr(1, 2)
       arr(a, 5) = sarr(1, 1)
       arr(a, 9) = sarr(4, 7)
       arr(a, 10) = sarr(4, 8)
       arr(a, 11) = sarr(4, 9)
       arr(a, 12) = sarr(4, 10)
       arr(a, 13) = sarr(4, 11)
       arr(a, 14) = sarr(1, 24)
       For j = 25 To 28
          If sarr(1, j) <> Empty Then arr(a, 14) = arr(a, 14) & Chr(10) & sarr(1, j)
       Next j
       cn.Close
    Next
    End With
    With Sheets("sheet1")
         lr = .Range("A" & Rows.Count).End(xlUp).Row
         If lr > 12 Then .Range("A13:N" & lr).ClearContents
         If a Then .Range("A13:N13").Resize(a).Value = arr
     End With
End Sub
 
Có 2 cách:
1. vào Registry chỉnh TypeGuessRows từ 8 thành 0 (Excel sẽ không dùng 8 rows đầu để đoán)
2. chèn thêm 1 dòng giả, với số ký tự cỡ 1000.
 
Mở file.
Copy dữ liệu sang sheet khác.
Insert Row đầu tiên. Vào cột cần làm, gõ 1000 ký tự. Save.

Cách gõ 1000 ký tự:
Mở word hoặc Notepad.
Lựa một trang web nào đó có các câu cú dài dài (ví dụ https:// libguides.navitas.com/literature-review/examples)
Chọn một đoạn (pargraph) dài dài và không có chứa gì đặc biệt (như link...)
Gõ Enter 3 lần (lần thứ nhất là chọn vị trí, lần thứ nhì bôi đen từ, lần thứ ba bôi đen cả đoạn)
Ctrl+C, đem qua văn bản Word hay Notepad Ctrl+V vài lần là sẽ đủ 1000 ký tự.
Ctrl+A, Ctrl+C
Trong clipboard sẽ có 1000 ký tự.
 
thấy mô tả thế chạy mất dép ... vào Registry mà sửa cho nó nhanh -0-0-0-
ado.JPG
 
thấy mô tả thế chạy mất dép ... vào Registry mà sửa cho nó nhanh -0-0-0-
View attachment 223944
Trước hết em xin cám ơn các anh chị, em xin giải thích là code này bác Snow25 làm giúp em ạ, Khổ cái máy công ty không cho chỉnh sửa Redistry, còn cách của bác Vietmini em làm theo nhưng chắc vẫn sai ở đâu đó nên không được.
 
Lần chỉnh sửa cuối:
thấy mô tả thế chạy mất dép ... vào Registry mà sửa cho nó nhanh -0-0-0-
...
1. Không phải máy nào cũng được phép sửa registry.
2. Có lẽ quý vị quá quen với hai từ "tự động" cho nên nghĩ là chêm dòng là công việc rắc rối. Thực ra rất nhiều người già dặn kinh nghiệm về CSDL sử dụng cách chêm dòng khi cần import dữ liệu Excel vào các CSDL khác.

Trước hết em xin cám ơn các anh chị, em xin giải thích là code này bác Snow25 làm giúp em ạ, Khổ cái máy công ty không cho chỉnh sửa Redistry, còn cách của bác Vietmini em làm theo nhưng chắc vẫn sai ở đâu đó nên không được.
Thử chêm 10 dòng?
 
Các anh cho em hỏi là em viết code lấy dữ liệu vào mảng bằng ADO nhưng nó chỉ lấy được 255 ký tự vào mảng.Có cách nào lấy được toàn bộ dữ liệu không nhỉ.
Mã:
Sub tonghop()
     Application.ScreenUpdating = False
     Application.AskToUpdateLinks = False
     Application.DisplayAlerts = False
     Dim cn As Object, sqlStr As String, i As Long, lr As Long, k, rst As Object, Pro As String, ext As String, arr(1 To 1000, 1 To 14), a As Long
     Dim sarr, j As Long, b As Long
     Set cn = CreateObject("ADODB.Connection")
     Set rst = CreateObject("ADODB.recordset")
     With Application.FileDialog(msoFileDialogFilePicker)
         .AllowMultiSelect = True
    If Not .Show = -1 Then Exit Sub
    For Each k In .SelectedItems
       Pro = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source="
       ext = ";Extended Properties=""Excel 12.0;HDR=yes;IMEX= 1"";"
       cn.Open (Pro & k & ext)
       sqlStr = "Select * From [sheet1$a1:e30]"
       sarr = cn.Execute(sqlStr).GetRows
       a = a + 1
       b = Len(sarr(1, 24))
       arr(a, 1) = a
       arr(a, 2) = sarr(1, 3)
       arr(a, 3) = sarr(1, 0)
       arr(a, 4) = sarr(1, 2)
       arr(a, 5) = sarr(1, 1)
       arr(a, 9) = sarr(4, 7)
       arr(a, 10) = sarr(4, 8)
       arr(a, 11) = sarr(4, 9)
       arr(a, 12) = sarr(4, 10)
       arr(a, 13) = sarr(4, 11)
       arr(a, 14) = sarr(1, 24)
       For j = 25 To 28
          If sarr(1, j) <> Empty Then arr(a, 14) = arr(a, 14) & Chr(10) & sarr(1, j)
       Next j
       cn.Close
    Next
    End With
    With Sheets("sheet1")
         lr = .Range("A" & Rows.Count).End(xlUp).Row
         If lr > 12 Then .Range("A13:N" & lr).ClearContents
         If a Then .Range("A13:N13").Resize(a).Value = arr
     End With
End Sub
anh thử kiểm tra chuỗi nào = 255 thì cắt tới 255 rồi nối chuỗi "&" 256 trở đi thử xem được không
 
1. Không phải máy nào cũng được phép sửa registry.
2. Có lẽ quý vị quá quen với hai từ "tự động" cho nên nghĩ là chêm dòng là công việc rắc rối. Thực ra rất nhiều người già dặn kinh nghiệm về CSDL sử dụng cách chêm dòng khi cần import dữ liệu Excel vào các CSDL khác.


Thử chêm 10 dòng?
Dạ đúng rồi bác, máy công ty nên không chỉnh được redistry ạ, nhờ bác qua thead này xem giúp em với ạ, em cám ơn!
www.giaiphapexcel.com/diendan/threads/xin-giúp-đỡ-code-tổng-hợp-dữ-liệu-từ-nhiều-file-excel-vào-1-file.142213/
 
Insert Row đầu tiên. Vào cột cần làm, gõ 1000 ký tự. Save.
Lựa một trang web nào đó có các câu cú dài dài (ví dụ https:// libguides.navitas.com/literature-review/examples)

Vụ vượt qua lỗi chỉ lấy 255 ký tự vào mảng, anh Vetmini hướng dẫn vụ này chính xác đó bạn.
Cái này là do lỗi của Jet OLEDB Provider của ADO chứ không phải do mảng. Nó sẽ tham chiếu 8 dòng đầu trong Excel spreadsheet để xác định kiểu dữ liệu, nếu số ký tự nhỏ hơn 255 thì nó cho là Text nên sẽ giới hạn ký tự. Giải pháp đơn giản là như anh Vietmini có nói là: chèn thêm 1 dòng giả với số ký tự lớn hơn 255. Bạn cứ thử chèn (vào 1 trong 8 dòng đầu của Range mà ADO truy xuất) một đoạn text dài 2.000 ký tự xem, nó cũng trả kết quả như yêu cầu.

Tôi thì hay vô trang: https://www.lipsum.com/ để lấy các đoạn text mẫu với số lượng ký tự mong muốn.

Còn việc tuỳ chỉnh Registry thì chẳng lẻ copy ứng dụng qua máy khác lại phải yêu cầu người dùng thiết lập lại? chưa kể là không được phân quyền như LYSM đã nói.
 
Vụ vượt qua lỗi chỉ lấy 255 ký tự vào mảng, anh Vetmini hướng dẫn vụ này chính xác đó bạn.
Cái này là do lỗi của Jet OLEDB Provider của ADO chứ không phải do mảng. Nó sẽ tham chiếu 8 dòng đầu trong Excel spreadsheet để xác định kiểu dữ liệu, nếu số ký tự nhỏ hơn 255 thì nó cho là Text nên sẽ giới hạn ký tự. Giải pháp đơn giản là như anh Vietmini có nói là: chèn thêm 1 dòng giả với số ký tự lớn hơn 255. Bạn cứ thử chèn (vào 1 trong 8 dòng đầu của Range mà ADO truy xuất) một đoạn text dài 2.000 ký tự xem, nó cũng trả kết quả như yêu cầu.

Tôi thì hay vô trang: https://www.lipsum.com/ để lấy các đoạn text mẫu với số lượng ký tự mong muốn.

Còn việc tuỳ chỉnh Registry thì chẳng lẻ copy ứng dụng qua máy khác lại phải yêu cầu người dùng thiết lập lại? chưa kể là không được phân quyền như LYSM đã nói.
Vâng, bác giải thích dễ hiểu quá, nhưng em hỏi chút tại sao phải làm nhiều bước như bác VetMini hướng dẫn ạ? Em đánh toàn dấu Space vào dòng đầu tiên và cũng ra kết quả như ý? Có cách nào không phải “lừa” hệ thống như vậy không ạ? Chẳng hạn như 1 Sub phụ để xác định kiểu dữ liệu cho nó luôn không?
 
Vâng, bác giải thích dễ hiểu quá, nhưng em hỏi chút tại sao phải làm nhiều bước như bác VetMini hướng dẫn ạ? Em đánh toàn dấu Space vào dòng đầu tiên và cũng ra kết quả như ý? Có cách nào không phải “lừa” hệ thống như vậy không ạ? Chẳng hạn như 1 Sub phụ để xác định kiểu dữ liệu cho nó luôn không?

Uh. Tôi cũng quên nói bạn là dùng space cũng được.
vd: text = Space(256)

Còn đoạn mà anh Vetmini hướng dẫn là hình như dùng để copy đoạn văn bản trong trang web của link đính kèm thôi.
Chủ yếu là cái dòng này:
Insert Row đầu tiên. Vào cột cần làm, gõ 1000 ký tự. Save


Còn về Sub phụ để gán kiểu dữ liệu cho Field trong Excel thì có một cách khác đó là tự tạo Table ảo ADO Recordset trên bộ nhớ rồi gán trị từng dòng của Table đó từ mảng. Cách này thì bạn muốn tạo Field kiểu dữ liệu gì cũng được. ADO có kiểu "adLongVarChar" tương đương kiểu Memo (Long Text) trong Access - hình như chứa được 64.000 ký tự.

Bạn đọc bài của bác HLMT có ví dụ vè việc tạo in-memorry ADO Recordset đó.
Link: https://www.giaiphapexcel.com/diendan/threads/cách-truy-vấn-dữ-liệu-trên-cùng-file-không-mở-kết-nối-adodb-connection.141551/

À nhưng mà cách tạo Table ảo ADO thì lại không phù hợp với trường hợp xử lý dữ liệu của bạn vì là truy cập File excel khác thì lấy đâu ra mảng mà gán vào Table :) .
 
Lần chỉnh sửa cuối:
Uh. Tôi cũng quên nói bạn là dùng space cũng được.
vd: text = Space(256)

Còn đoạn mà anh Vetmini hướng dẫn là hình như dùng để copy đoạn văn bản trong trang web của link đính kèm thôi.
Chủ yếu là cái dòng này:



Còn về Sub phụ để gán kiểu dữ liệu cho Field trong Excel thì có một cách khác đó là tự tạo Table ảo ADO Recordset trên bộ nhớ rồi gán trị từng dòng của Table đó từ mảng. Cách này thì bạn muốn tạo Field kiểu dữ liệu gì cũng được. ADO có kiểu "adLongVarChar" tương đương kiểu Memo (Long Text) trong Access - hình như chứa được 64.000 ký tự.

Bạn đọc bài của bác HLMT có ví dụ vè việc tạo in-memorry ADO Recordset đó.
Link: https://www.giaiphapexcel.com/diendan/threads/cách-truy-vấn-dữ-liệu-trên-cùng-file-không-mở-kết-nối-adodb-connection.141551/

À nhưng mà cách tạo Table ảo ADO thì lại không phù hợp với trường hợp xử lý dữ liệu của bạn vì là truy cập File excel khác thì lấy đâu ra mảng mà gán vào Table :) .
Hic, ADO em mù tịt ạ, nếu bác viết giúp em sub khắc phục được nhược điểm 255 ký tự thì tốt quá ạ.
 
Hic, ADO em mù tịt ạ, nếu bác viết giúp em sub khắc phục được nhược điểm 255 ký tự thì tốt quá ạ.

Bạn dùng code hiện tại của bạn snow25 là tối ưu hơn rồi. Dùng kiểu tạo table nó sẽ đi lòng vòng và không dùng được cho trường hợp của bạn.
 
Mình đang sử dụng code sau để lấy dữ liệu từ File *.CSV lên Excel mà nó lỗi ...
1/ Tiêu đề và Lỗi Font Tiếng việt
2/ xử lý ngay trong ADO khi lấy lên cột ( Format Number ): số tiền nạp ... để cộng ,trừ nhân chia ngay trên Excel ok
3/ Mình có Chỉnh HDR=Yes Or No rồi mà nó lấy lên báo lỗi font tiếng việt và thiếu

( File SIM BANKING!.csv là file xuất ra từ Web của người ta và họ cũng làm khó chút là thêm cái ký tự ! vào tên File)


Xin cảm ơn
Mã:
Rem ==========
Function GetShortName(ByVal FileName_Path As String)
    With CreateObject("Scripting.FileSystemObject")
        If .FileExists(FileName_Path) Then
            GetShortName = .GetFile(FileName_Path).ShortName
        End If
    End With
End Function
Rem ==========
Sub Import_CSV()
    Dim Conn As ADODB.Connection
    Dim Rst As ADODB.Recordset
    Dim FileName As String
    Dim sPath As String
    Dim rSQL As String
    Rem ======
    sPath = ThisWorkbook.Path & "\"
    FileName = GetShortName(sPath & "\SIM BANKING!.csv") ''Xu ly loi ADO ko lay duoc Filename ky tu dac biet!
    Rem ======
    Set Conn = New ADODB.Connection
    Conn = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & sPath & ";Mode=Read;Extended Properties=""Text;HDR=Yes;FMT=Delimited(,)"";"
    Conn.Open
    Rem ======
    Set Rst = Conn.Execute("SELECT * FROM " & "[" & FileName & "]")
    Cells.Clear
    Range("A2").CopyFromRecordset Rst

    Rst.Close: Set Rst = Nothing
    Conn.Close: Set Conn = Nothing
End Sub
Rem ==========
 

File đính kèm

Lần chỉnh sửa cuối:
Mình đang sử dụng code sau để lấy dữ liệu từ File *.CSV lên Excel mà nó lỗi ...
1/ Tiêu đề và Lỗi Font Tiếng việt
2/ xử lý ngay trong ADO khi lấy lên cột ( Format Number ): số tiền nạp ... để cộng ,trừ nhân chia ngay trên Excel ok
3/ Mình có Chỉnh HDR=Yes Or No rồi mà nó lấy lên báo lỗi font tiếng việt và thiếu
Tập tin CSV đang mã bằng utf-8. Tôi e rằng không dùng được utf-8 đâu. Dùng unicode thì được.
 
Mình đang sử dụng code sau để lấy dữ liệu từ File *.CSV lên Excel mà nó lỗi ...
1/ Tiêu đề và Lỗi Font Tiếng việt
2/ xử lý ngay trong ADO khi lấy lên cột ( Format Number ): số tiền nạp ... để cộng ,trừ nhân chia ngay trên Excel ok
3/ Mình có Chỉnh HDR=Yes Or No rồi mà nó lấy lên báo lỗi font tiếng việt và thiếu

( File SIM BANKING!.csv là file xuất ra từ Web của người ta và họ cũng làm khó chút là thêm cái ký tự ! vào tên File)

Như bác batman1 nói tập tin có định dạng UTF-8 (từ web) nên bạn Mạnh chỉ có thể dùng ADODB. Stream để đọc và ghi nó được thôi. ADODB Stream có thể đọc tên file có dấu chấm than (!) luôn nhé.
Ví dụ:
Mã:
sFilePath = ThisWorkbook.Path & "\SIM BANKING!.CSV"
Dim oStream As Object
   Set oStream = CreateObject("ADODB.Stream")
   With oStream
        .Open
        .Type = 1  ' adTypeBinary
        .LoadFromFile sFilePath
        .Type = 2  ' adTypeText
        .Charset = "utf-8"
        strText = .ReadText(-1)  ' adReadAll
    End With
    ...
    'Code đưa strText vào Sheet'
 
Lần chỉnh sửa cuối:
Như bác batman1 nói tập tin có định dạng UTF-8 (từ web) nên bạn Mạnh chỉ có thể dùng ADODB. Stream để đọc và ghi nó được thôi.
Ý tôi là nếu dùng ADO (code trong tập tin) thì không dùng được utf-8. Nếu muốn dùng ADO thì phải mở và lưu lại CSV với mã unicode.
 

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

Back
Top Bottom