So sánh 3 cách lấy dữ liệu từ 1 file đang đóng
Với Excel chúng ta thường có nhu cầu lọc lựa, lấy dữ liệu từ 1 file đang trạng thái đóng đã biết trước đường dẫn và địa chỉ tham chiếu vùng dữ liệu, nhưng lại không muốn tự tay mở nó ra để chép 1 cách thủ công qua file đang làm. Với VBA, chúng ta có 3 cách để tự động hóa khâu lấy dữ liệu này.
Cách 1: Mở trực tiếp file lên, lấy dữ liệu xong đóng lại:
Sub GetDataByOpenFile()
Dim Wb As Workbook, WbS As Workbook
Dim sFullName$, tmr#
tmr = Timer()
Application.ScreenUpdating = False
sFullName = "D:GoogleDrive2CaNhanVBAMapVN.xlsx" 'Duong dan file du lieu
Set Wb = ThisWorkbook
Set WbS = Workbooks.Open(sFullName)
WbS.Sheets("VNxy").Range("A1:D100").Copy Wb.Sheets("KQ").Range("A1")
WbS.Close False
Application.ScreenUpdating = True
Msgbox Timer() – tmr 'Thoi gian thuc hien
End Sub
– Ưu điểm của cách 1 là trực quan, ta có thể tạm ngừng lệnh, chạy từng bước để xem kết quả trung gian. Dữ liệu có thế nào chép sang thế ấy hoặc có thể tùy ý chép riêng định dạng, công thức, giá trị…
– Nhược điểm cách 1 là thời gian thực thi khá chậm, mất khoảng 1,4 giây cho việc mở file, chép dữ liệu, đóng file. (Thời gian ở đây là trong điều kiện thử nghiệm cụ thể của tác giả, chỉ để so sánh tốc độ thực hiện các cách với nhau. Thời gian đó sẽ khác đi khi dùng ở máy khác, dùng 1 file nguồn khác…)
Cách 2: Mở file bằng ADODB:
Sub GetDataByADODB()
Dim Rec As Object, rs As Object
Dim sFullName$, iCol&, tmr#
tmr = Timer()
sFullName = "D:GoogleDrive2CaNhanVBAMapVN.xlsx" 'Duong dan file du lieu
Application.ScreenUpdating = False
Set Rec = CreateObject("ADODB.Connection")
With Rec
.Provider = "Microsoft.ACE.OLEDB.12.0"
.ConnectionString = "Data Source=" & sFullName & ";" & _
"Extended Properties=""Excel 12.0 Xml;HDR=YES"";"
.Open
End With
Set rs = Rec.Execute("Select * From [VNxy$A1:D100]")
Sheets("KQ").Range("A2").CopyFromRecordset rs
For iCol = 0 To rs.Fields.Count - 1 'Chep tieu de cọt
Sheets("KQ").Cells(1, iCol + 1).Value = rs.Fields(iCol).Name
Next
Set rs = Nothing
Msgbox Timer() – tmr 'Thoi gian thuc hien
Application.ScreenUpdating = True
End Sub
– Ưu điểm của cách 2 là thực thi nhanh, chỉ mất cỡ 0,2 giây, và người dùng không nhận biết được file đóng mở.
– Nhược điểm cách 2 là:
+ Trong đa số trường hợp phải mất công khắc phục việc chạy lệnh đối với tiêu đề có dấu tiếng Việt (Có cách khác không bị ảnh hưởng bởi tiêu đề tiếng Việt. Nhưng vấn đề này sẽ được trình bày ở 1 bài khác, có sự so sánh việc sử dụng của 2 cách).
+ Những ai chưa rành cú pháp SQL và lồng các biến vào câu lệnh SQL có thể gặp trở ngại khi điều kiện truy vấn phức tạp.
+ Gặp dữ liệu có dấu phân cách thập phân với các máy đã được dịnh dạng trong Control Panel là dấu phẩy thì sẽ có rắc rối với kết quả chép ra. Thay vì đúng là 144,12 thì kết quả chép ra ở đây là 14412,00.
Để khắc phục nhược điểm này thì phải thêm mã lệnh để chuyển định dạng dấu phẩy thập phân trong Control Panel sang dấu chấm trước khi chạy truy vấn rồi chuyển lại dấu phẩy ngay sau truy vấn.
Khai báo và đặt hàm SetLocalSetting trên đầu Module:
[I]#If VBA7 Then[/I]
[I]Private Declare PtrSafe Function SetLocaleInfo _[/I]
[I]Lib "kernel32" Alias "SetLocaleInfoA" ( _[/I]
[I]ByVal Locale As LongPtr, _[/I]
[I]ByVal LCType As LongPtr, _[/I]
[I]ByVal lpLCData As String) As Boolean[/I]
[I]Private Declare PtrSafe Function GetUserDefaultLCID% Lib "kernel32" ()
#Else[/I]
[I]Private Declare Function SetLocaleInfo _[/I]
[I]Lib "kernel32" Alias "SetLocaleInfoA" ( _[/I]
[I]ByVal Locale As Long, _[/I]
[I]ByVal LCType As Long, _[/I]
[I]ByVal lpLCData As String) As Boolean[/I]
[I]Private Declare Function GetUserDefaultLCID% Lib "kernel32" ()
#End If[/I]
[I]Private Const LOCALE_SDECIMAL = &HE[/I]
[I]Private Function SetLocalSetting(LC_CONST As Long, Setting As String) As Boolean[/I]
[I]Call SetLocaleInfo(GetUserDefaultLCID(), LC_CONST, Setting)[/I]
[I]End Function[/I]
Với Sub GetDataByADODB() ở trên, thêm lệnh này trước lệnh truy vấn SQL:
Call SetLocalSetting(LOCALE_SDECIMAL, ".")
Và thêm lệnh này ngay sau khi chạy xong truy vấn SQL:
Call SetLocalSetting(LOCALE_SDECIMAL, ",")
Cách 3: Dùng Macro 4. Cách này tôi dùng code từ nguồn:
[URL='www.giaiphapexcel.com/diendan/threads/d%C3%B9ng-macro-4-%C4%91%E1%BB%83-l%E1%BA%A5y-d%E1%BB%AF-li%E1%BB%87u-t%E1%BB%AB-1-file-%C4%91ang-%C4%91%C3%B3ng.39312/']www.giaiphapexcel.com/diendan/threads/dùng-macro-4-để-lấy-dữ-liệu-từ-1-file-đang-đóng.39312/
Sub GetDataByMacro4()
Dim tmr#
tmr = Timer()
Dim sFile As String, sSheet As String, sAddr As String
sFile = "D:GoogleDrive2CaNhanVBAMapVN.xlsx"
sSheet = "VNxy"
sAddr = "A1:D100"
Sheets("KQ").Range("A1:D100") = GetData(sFile, sSheet, sAddr)
'Kích thuoc phai bang sAddr
Msgbox Timer() – tmr 'Thoi gian thuc hien
End Sub
Function GetData(sFile As String, sSheet As String, sAddr As String)
Dim pLink As String, iR As Long, iC As Long, Arr
If Len(Dir(sFile)) Then
Arr = Range(sAddr)
pLink = "'" & Replace(sFile, Dir(sFile), "[" & Dir(sFile) & "]") & sSheet & "'!"
For iR = 1 To Range(sAddr).Rows.Count
For iC = 1 To Range(sAddr).Columns.Count
Arr(iR, iC) = ExecuteExcel4Macro(pLink & Range(sAddr). _
Cells(iR, iC).Address(, , 2))
Next iC
Next iR
GetData = Arr
End If
End Function
Với cách này, dù dữ liệu nguồn sAddr = "A1:D100" nhưng khi muốn hiển thị kết quả ít hơn thì bạn giảm kích thước vùng kết quả chỗ Sheets("KQ").Range("A1:D100"). Nếu tăng kích thước vùng kết quả thì sẽ bị #N/A ở các ô thừa.
– Thực tình thì không thấy ưu điểm nào của cách này ngoài việc nó lấy đúng số liệu nguồn như cách 1. Còn nhược điểm là quá chậm, phải đến tận 5 giây (gấp hơn 3 lần cách 1) thì mới lấy được dữ liệu cùng cỡ với các cách trên. Dòng tiêu đề sẽ hiển thị là 0 với tiêu đề nào chừa trống.
P/S: Tôi đính kèm file dữ liệu mà tôi đã dùng để test tốc độ thực thi code để các bạn có cùng 1 mẫu thử.
Trong bài có chỗ nào sai, sót thì các bác "gội" rồi mới "cạo" nhẹ nhàng góp ý giúp.
www.giaiphapexcel.com/diendan/threads/so-s%C3%A1nh-3-c%C3%A1ch-l%E1%BA%A5y-d%E1%BB%AF-li%E1%BB%87u-t%E1%BB%AB-1-file-%C4%91ang-%C4%91%C3%B3ng.157352/page-4#post-1043424
Học Nhân sự Tổng hợp – Trở thành chiến binh nhân sự vững nghiệp vụ
Con người là một trong những yếu tố quan trọng của công ty, là tài sản quý giá của doanh nghiệp. Chính vì thế,...
Xem khóa học
Đọc mấy bài đầu thấy lấy trực tiếp bằng công thức và dùng macro 4 giống như link tôi dẫn trong bài #1. Để hồi rảnh tôi xem lại thử sao tốc độ lại khá hơn
Để rảnh tôi test chừng vài chục ngàn dòng xem.
Quả là Workbooks.Open nhanh hơn ADODB (4s so với 7s). Còn cách macro 4 chạy lâu quá tôi không chờ được, hic.
File 60 ngàn dòng không có công thức gì
Các bác rành về mấy cách đó test xem, chứ tôi chỉ biết mỗi VBA thôi
đồng ý là thế …. nhưng thớt này họ nói So sánh mà
Code nạp csv như hình đấy bạn, python nạp excel chậm lắm bạn nếu dữ liệu càng lớn vì file excel nó dạng dữ liệu nén, dữ liệu khoảng vài chục ngàn thì nạp excel được còn lớn hơn thì tốt nhất chuyển qua csv , đọc file thì nó cũng phụ thuộc vào cpu và tốc độ ssd bạn ạ nên máy bạn yếu nạp chậm hơn là bình thường bạn ạ
Kết quả tốc độ Open là 62 giây còn ADODB là 485 giây (lâu quá) –=0
Tiện thể: database đó có 14 cột hà!
Khoảng 30 giây bạn à. Nhanh thiệt! Như vậy có lẽ Provider Microsoft.ACE.OLEDB.12.0 thiết kế tối ưu cho Access?
Bạn muốn so sánh theo phương diện lý thuyết hay thực hành?
Lý thuyết: thực sự mỗi cách nó làm cái gì?
Thực hành: ở đây (GPE), khi nói thựck hành là người ta muốn nói tốc độ. Tôi không cùng quan niệm nên mạn phép không bàn tới.
Cây gạo là một trong những loại cây có thể sống lâu năm và lớn thành đại thụ. Vì vậy mới có thành ngữ gạo cội.
Tôi thích đọc sách cho nên biết nhiều lý thuyết thôi. Gọi đại thụ thì chưa xứng đáng.
Cách 1 dùng chính Excel để mở file, đọc lấy dữ liệu, và đóng lại khi dùng xong. Nó là cách trực tiếp và giản dị nhất.
Cách 3 là cách người ta dùng khi cần lấy dữ liệu ở chính xác một vài chỗ. Nó chính thức là sử dụng liên kết từ file Excel này đến file Excel khác. Tương tự như ở một cell nào đó bạn có công thức =[tên file]'tên sheet'!địa chỉ cell.
Nói cách khác, phương pháp này cũng dùng Excel để đọc file.
Chú: vì mã nguồn bạn đưa ra là người ta biểu diễn cách lấy một mảng dữ liệu, cho nên có ba cái mớ vòng lặp để đọc từng ô và nhét vào mảng.
Cách 2 là cách khá thú vị. ADO là tên viết tắt ActiveX Data Object. Cái tên nói lên rõ rằng nó là một đối tượng thuộc loại ActiveX (gồm COM và OLE). Và đối tượng này chuyên về đọc/xử lý dữ liệu.
Khi đọc file Excel, ADO không dùng Excel mà dùng cách riêng của nó (hỏi mấy cha viết code đối tượng mới biết nó thực sự mở file và đọc hạ tầng cơ sở dữ liệu bằng phương pháp nào). Sau khi kết nói thì ADO coi cái file Excel kia như một CSDL. Để có thể truy vấn và xử lý CSDL dạng Excel, Microsoft đã chọn Access làm cỗ máy dịch và thi hành lệnh SQL. Tất cả mọi lệnh SQL đều phải tuân theo tiêu chuẩn Access Query. Nếu thay file Excel bằng SQL Server thì phải chọn cỗ máy SQL. Và mọi lệnh SQL đều phải theo tiêu chuẩn T-SQL.
Người ta dùng ADO chủ yếu là vì tiện lợi của lệnh SQL, có thể tóm gom tổng kết dữ liệu luôn trước khi đưa ra kết quả. Điển hình là các dạng đối chiếu (join by keys), lọc (where), sắp xếp (sort), nhóm (group).
Về sau này, với Power BI thì ADO mất dần đi lợi thế của SQL. Data Model của Power BI dùng cỗ máy SQL Server (Express) cho nên hiệu quả hơn Access nhiều.
Tôi hay dùng ADO để import dữ liệu từ File đang đóng và cảm thấy giải pháp đó là vô địch.
Ngoài ra cũng tiện khi cần lấy kết quả cho mảng để làm việc khác (như nạp vào Combobox).
Ah,
Tôi cũng học từ sư phụ @NDU
Code bài #19, dùng hàm Getdata thôi
http://www.giaiphapexcel.com/diendan/threads/import-d%E1%BB%AF-li%E1%BB%87u.86477/page-1
Tôi chưa hiểu ý của bạn lắm, nhưng tôi nạp kiểu này thì bình thường, như tôi đang dùng hàm GetData:
uhm, tôi cũng dân ngoại đạo, thực sự thì ngôn ngữ ADO tôi cũng không hiểu sâu, tôi cứ nạp bằng hàm Getdata là lấy data từ File khác (đang đóng) về.
2354
Lại dở lý thuyết, dở hoài thành dở lái mất :p:
Vì với đa số ngôn ngữ lập trình, kể cả VBA, Array là loại mảng trọng cột (column major: xếp cột trước, dòng sau) cho nên hàm GetRows của ADO được viết để lấy dữ liệu theo cột. Tức là mỗi dòng mà GetRows đọc trên recordset sẽ được ghi lại vào một cột trong array.
Nếu mảng nhỏ, và dữ liệu không dài lắm thì có thể dùng hàm Transpose của worksheet để xoay mảng. Hình như giới hạn của Transpose là khoảng 400 dòng và mỗi string dưới 256 ký tự.
Nếu lấy dữ liệu trong Recordset nhiều lần thì nên tìm hiểu về cách đặt con trỏ.
Chú: ADO là một đối tượng. Recordset cũng là một đối tượng. GetRows là một phương thức của đối tượng Recordset. Mặt khác, CopyFromRecordSet là một phương thức của Range (Excel). Theo nguyên tắc lập trình hướng đối tượng thì đối tượng có thể biến hình tuỳ theo mọt vài bản chất nào đó. Muốn biết cách hoạt động của đối tượng ra sao thì phải tìm hiểu về thuộc tính và phương thức của chúng.
Chú 2 (thêm vào sau 12 phút): ở bài trước tôi quên nói thẳng rằng <quote>nhu cầu chọn lựa<endquote> theo nguyên tắc lập trình thì sẽ đặt trọng điểm trên điều kiện môi trường. Tuy quên giải thích, nhưng ở bài ấy tôi có đưa thẳng ra phương pháp chọn lựa theo ý cá nhân. Trái với đa số trên GPE, có lẽ gồm cả thớt, theo quan điểm tốc độ. Đó là một quan điểm chọn lựa "thực tế". Thực tế ở đây là sẽ đúng với hầu hết các trường hợp mà quý vị gặp. Chỉ có điều là quý vị cùng có suy nghĩ giống nhau cho nên các điều kiện môi trường và nhu cầu sẽ xếp giống nhau, các mẫu/loại dữ liệu mà quý vị test cũng giống nhau.
Khi gặp một môi trường khác, quý vị sẽ chưng hửng. Nhưng đó là chuyện của mai sau. Mai sau là lý thuyết, hiện tại mới là thực tế.
Nếu python nạp excel chậm thì cũng giống power query a nhỉ
Việc import đơn giản chỉ là lấy dữ liệu về thì ADO nhanh và tiện lợi.
Tuy nhiên nếu cần thêm việc tổng hợp, tính toán, group theo vài tiêu chí thì phải dùng Power Query.
Em cũng chưa biết python là gì, ví dụ việc tổng hợp khoảng 30 file excel (mỗi file tầm 3M) thì python có lợi thế hơn Power Query không anh?
Cái hay của Range().CopyFromRecordSet là nó đảo chiều từ hàng thành cột của một mảng từ dữ liệu được xuất ra bằng ADO. Nhưng mình rất thích xử lý trên mảng "đảo ngược" được xuất ra bằng ADO. Các anh (chị) có biết tại sao không?
Khi bạn muốn lấy lại thì bạn phải di chuyển con trỏ về dòng đầu tiên.
Ví dụ nếu bạn đã đổ recordset xuống sheet, nhưng vì lý do nào đó mà bạn muốn đổ nữa hoặc thực hiện điều gì đó thì xem ví dụ như sau:
Khi làm việc với Listbox và Combobox thì nó sẽ không cần chuyển mảng mà có thể đưa dữ liệu trực tiếp vào.
Nếu dữ liệu vượt quá số dòng chứa ở sheet đích thì code cho cách 1 và 3 sẽ như thế nào vậy bạn?
Cái vụ tìm kiếm dạng này thì tôi vẫn dùng câu lệnh SQL được nhưng phải lồng thêm một cái hàm để xử lý chuỗi tìm kiếm.
Nói chung là chỉ xử lý 1 từ, nếu nhiều từ thì phải viết thêm :). Thực ra thì tìm vẫn ra nhưng tôi không cho tìm nhiều từ để chạy cho nhanh
VD: chuong, luan, lien
2357
Nhìn vậy chứ nó cũng đơn giản. Chi viết cái hàm xử lý, dùng bảng tra các nguyên âm thôi (a,â, e, ê…y) và các biến thể với dấu thanh của nó + xử lý chuỗi. Bạn ngâm cứu chút chắc là ra thôi.
a = "a" & ChrW(224) & ChrW(225) & ChrW(227) & ChrW(7841) & ChrW(7843)
a1 = ChrW(226) & ChrW(7845) & ChrW(7847) & ChrW(7849) & ChrW(7851) & ChrW(7853)
…
Cơ bản tôi hay dùng Recordset nên thường sử dụng câu lệnh SQL để xử lý mà ADO là dùng câu lệnh SQL nên áp dụng được thôi.
Không bạn, nếu chỉ tính file excel thì việc nạp excel trong python còn chậm hơn power query nhiều, 30 file excel (mỗi file tầm 3M) thì Power query chắc hơn nửa tiếng quá, cùng dữ liệu đó nếu chuyển sang file csv chắc tầm 15 phút, còn dùng python khoảng 3 phút thôi với điều kiện là Ram đủ
Nếu connect excel tốc độ thì tôi nghĩ như nhau giữa ADO và Power query, Power query nó có thời gian chờ nên có thể chậm hơn chút không đáng kể, không tính phần transform thì tôi nghĩ Power query tiện hơn nhiều vì nó là tool mà
Bạn để mỗi file tầm 3M tức là 3 triệu dòng mỗi file, tức là 30 file 90 triệu dòng phải không? nếu 90 triệu dòng mà file excel thì không có 8p đâu bạn, nếu chỉ có 50.000 dòng mỗi file thì trung bình mỗi s nó sẽ đọc được khoảng 20.000 dòng tức là 3s một file =>30 file tầm 2 phút thôi
Ví dụ bạn dùng file Excel nguồn có 1,048,576 dòng và bạn dùng 3 cách lần lượt ở bài 1 và lấy dữ liệu đưa vào 1 file nào đó bắt đầu từ địa chỉ A3 xem sao nhé.
Phải làm rõ mục số 2 bạn muốn nói cái gì, chứ đọc vậy không hiểu rồi.
– ADODB và sqlLite là 2 cái đối tượng khác nhau hoàn toàn. Một bên là thư viện với các phương thức, thuộc tính để kết nối tới CSDL bên ngoài, còn sqlLite là một ứng dụng xây dựng, chứa CSDL nên bạn nói "khi dùng ADODB lấy thì kêu nó nhanh hơn sqlLite.." là không hiểu rồi đó!
Bài test tôi có đề cập ở trên là "dùng ADODB kết nối tới CSDL sqlLite và CSDL Access" để xem ADODB lấy dữ liệu từ hệ quản trị CSDL nào nhanh? chứ ADODB và sqlLite có cùng loại đâu mà so sánh!!!
Một khi muốn kết nối tới CSDL nào đó thì phải dùng Driver nào cho phù hợp thì đối với sqlLite tôi chỉ biết nó cung cấp ODBC Driver thông qua file "sqlliteodbc.dll". Đối với Ms Access thì mặc định đã có sẳn Driver đi kèm khi cài Office rồi khỏi mất công kiếm Driver cho nó.
– "Xài thuần ADODB và thuần SQLLite" là sao bạn? thuần sqlLite tức là dùng ứng dụng sqlLiteStudio xuất (export) table sqlLite sang Excel? Tool export của sqlLiteStudio chỉ xuất được ra CSV, HTML, JSON…, không có Excel. Vậy từ Excel làm sao kết nối tới CSDL sqlLite? Bạn đừng nói dùng cái tool của Delphi nhé vì nó đã là của ngôn ngữ lập trình Delphi rồi, không còn là VBA Excel.
– Mục 3 là bạn phải cập nhật lại thông tin đi. Khi nói về Big Data (tạm gọi dữ liệu khủng đi như dữ liệu thương mại điện tử, ngân hàng, y tế, bán lẻ v.v..), Data science thì từ Python nó nằm trên đầu đó, bên cạnh đó còn có ngôn ngữ R, phải biết SQL (không phải sqlLite nhé) để truy vấn dữ liệu, Java, C++… và còn nhiều kỹ năng mềm khác nữa. Chắc chắc ADODB, và sqlLite không có nằm trong môn khoa học dữ liệu này đâu.
– Mục 4: mấy cái tool họ so sánh là của Delphi và chạy trên ngôn ngữ lập trình Delphi. Từ Delphi dùng các thư viện trên để truy vấn khau thác dữ liệu thì cái FireDAC là tốt hơn các thư viện còn lại. dùng thư viện FireDAC có thể kết nối hầu hết các ứng dụng quản trị CSDL hiện tại như: MS Access, SQLite, MySQL, SQL Server, Oracle, PostgreSQL… Bạn dùng từ "FireDAC là thuần sqlLite" thì khó hiểu thật.
Bạn đang nói select query hay xử lý dữ liệu, nếu nói xử lý dữ liệu thì tôi biết Python top 1 nhiều năm rồi ngoài thư viện Pandas nó còn thư viện Pyspark xử lý vài trăm GB dữ liệu
http://www.upgrad.com/blog/data-science-programming-languages/
Nói về lọc dữ liệu trên ComboBox bằng array để tìm mục nào đó thì mình mới phát minh ra một kiểu lọc mà từ trước tới nay chưa một ai có thuật toán như mình, nó đảm bảo nhanh từ bằng đến gấp đôi gấp ba và nhiều hơn thế nữa nếu cứ tăng 1 ký tự! Nhưng mình đang hoàn thiện sẽ có dịp mình tặng cho mọi người cùng thưởng thức!
So sánh vẫn luôn là so sánh thôi và rất dễ bị tráo khái niệm
Nếu đã so sánh thì phải đồng (cùng ) nhiều thứ:
– Cùng File Dữ liệu
– Cùng File kết quả
– Cùng môi trường kết quả cuối cùng (file kết quả là đang mở hay là không mở ở Excel)
vv
Còn nếu chuyển qua môi trường khác như CSV, TextFile — thì phải coi đó là bước trung gian, cần kể cả thời gian chuyển tự động qua bước trung gian đó.
Tóm lại, ai quen môi trường nào thì làm ở môi trường đó, và quy mô File cấu trúc File dữ liệu gốc , cũng như kết quả sẽ quyết định nên chọn cái nào: Chân phương, hay là tắt, lắt léo, hay sử dụng công cụ (Tool) khác …
Cách này tôi làm không phải dạng "tìm kiếm ngay khi gõ" (OnChange) mà tìm sau khi gõ xong (AfterUpdate).
Bên cạnh đó thì ADO Recordset cũng đã tải và nằm trong bộ nhớ rồi, chỉ cần Filter nó ra hoăc xoá Filter để trả lại Recordset nguyên vẹn, không cần kết nối, tải lại Recordset.
Cái vụ ADO recordset Filter có trong loạt bài của bạn HLMT.
Trước giờ mình chỉ biết cách lọc trên mảng, không nghĩ là có những cách khác hay hơn, nếu làm được điều này thì sẽ tuyệt vời đối với những danh sách dài vài chục nghìn dòng mà tốc độ vẫn nhanh. ý tưởng code như vậy có nhanh không anh, tầm 1 ngày hoặc 2 ngày có xong được không anh, anh nghĩ code sẽ ngắn chứ?
Kiểu như dùng nâng cao của mảng? Có cách nào để áp dụng luôn sáng tìm trên textbox và hiện ra trên listbox để có tốc độ cực nhanh?
Lúc trước tôi cũng có viết mấy kiểu lọc dữ liệu "của comboBox". Ngoài mục tiêu giúp người dùng tìm nhanh còn có mục tiêu giảm tải lượng dữ liệu truyền tải nếu áp dụng cho các ứng dụng lấy dữ liệu qua internet (SQL Server).
Nếu ý bạn là hỏi về đoạn mà bạn trích của Hai Lúa Miền Tây thì tôi đã viết nhiều lần rồi.
Giả sử bạn có mảng 2 chiều Arr "bình thường" với nghĩa là dòng và cột của nó y hệt như dòng và cột mà bạn cần nhập vào ListBox, ComboBox. Lúc đó bạn nhập mảng đó vào ListBox, ComboBox bằng thuộc tính LIST
Nếu Arr là mảng "đảo ngược", "xoay 90 độ" so với mảng cần nhập vào ListBox, ComboBox thì bạn dùng thuộc tính COLUMN
Nhiều người không biết dùng Column nên khi có mảng Arr "xoay 90 độ" thì họ dùng vòng For để từ mảng Arr tạo ra mảng mới vd. ketqua là mảng "bình thường", rồi dùng thuộc tính List để nhập vào ListBox, ComboBox
Có gì mà ngấm.
Tạo tập tin mới có UserForm với 2 ListBox (có 2 cột). Dữ liệu như trên hình, code cũng như trong hình.
Tại sao tại (A) dùng LIST mà ở (B) lại dùng COLUMN?
Mảng Arr tại (A) có dòng cột y như cần phải có trong ListBox1 nên để load vào ListBox1 thì phải dùng LIST.
Mảng Arr tại (B) có dòng cột "xoay 90 độ" so với cần phải có trong ListBox2 nên để load vào ListBox2 thì phải dùng COLUMN.
Thường mảng Arr "xoay 90 độ" so với nhu cầu cần phải có được tạo bởi code và từng "ô" của nó được điền bằng code từ những giá trị nào đó. Khi đó những người không biết dùng COLUMN thì họ dùng
Nhưng do nhiều khi Transpose có lỗi nên để dùng LIST họ phải tạo mảng mới ketqua từ Arr rồi dùng LIST
2358
1. Tôi chưa thử với trường hợp protect workbook. Để tôi thử xem thế nào rồi thông tin lại.
2. Tôi dùng ADODB khá nhiều nhưng chưa bao giờ gặp nó mở file lên mà thấy được cả. Còn chưa hiểu cái Read Only của bạn có phải thấy được ở trạng thái ReadOnly không? Nếu đúng vậy bạn gửi tôi file nguồn và code bạn dùng để tôi xem thử mới biết được.
File Protect Workbook for structure có mật khẩu thì câu: "Extended Properties=""Excel 12.0 Xml;HDR=YES"";"
sửa thành: "Extended Properties=""Excel 12.0 Xml;HDR=YES;PWD=123"";"
(123 là mật khẩu protect)
Người hỏi có giải thích trường hợp ở bài #107: có file Excel đang mở.
Theo tôi nhớ thì do lỗi ADO bị chạm resource connection. Bug này ai chơi Resource Consumption qua mấy cái OLE đều biết. Bug này nếu Microsoft chưa khắc phục thì chịu thôi.
Với code ở bài #1 thì buộc phải thêm PWD=123 mới chạy được. Còn code kiểu này thì không cần (tôi thực hành thôi chứ không biết lý do)
P/S: sau khi đã cung cấp mật khẩu 1 lần không đóng Excel thì bỏ PWD=123 đi nó chạy được (lý do: không biết), chứ không phải do cú pháp tôi nói ở trên.
Bạn thử power query xem sao, chắc là sẽ không thất vọng đâu.
Có thể chậm nhưng chắc.
Ngoài ra PQ tổng hợp tính toán ngon lành.
Trước mắt là bạn có thể bổ sung thêm một cách import dữ liệu ngay tại topic này đó thôi.
PQ là 1 tool của excel, thử đọc tài liệu của sư phụ @ptm0412 phần cơ bản là giải quyết được nhiều thứ lắm rồi.
GPE này rất thực mà bạn.
PQ không đơn thuần là lấy dữ liệu về. PQ có thể tính toán, tổng hợp, group by, insert thêm trường… nếu dùng ADO chắc sẽ mệt lắm.
Mỗi môn đều có cái hay. Nếu có một cơ sở dữ liệu chuẩn thì dùng Power Query quá tuyệt, phân tích dữ liệu, sắp xếp tổng hợp dữ liệu lớn, thiết lập các mối quan hệ…
Còn nhiều khi với dữ liệu chưa chuẩn lắm, dùng VBA lại uyển chuyển, mà ngôn ngữ em thấy cũng dễ hiểu, cho kết quả nhanh, các báo cáo tùy biến theo nhu cầu
Nên hiện tại em vẫn kết hợp cả hai trong công việc.
{1} tôi nhường cho các bạn đã rành Power Query trả lời câu này
{2} Đó chính là câu "chạy theo dữ liệu"
Tôi nghĩ cái món Vba ở đây trên 90% tham gia gpe xem nó như kim chỉ nam rồi, nghĩ nó là nhất rồi thì đâu biết cái khác nó hay nó dở thế nào đâu. Làm cái nhỏ nhỏ thì được. Còn dữ liệu lớn thì nên tìm giải pháp khác. Tôi thấy một số thứ viết vba mướt mồ hôi còn dùng power bi, tableau, python, đại loại rất nhiều thứ xử lý rất đơn giản, nhanh gọn. Biết nhiều càng tốt nhưng đừng cuồng quá một thứ. Tôi nghĩ vậy
Tôi nghĩ cái món Vba ở đây trên 90% tham gia gpe xem nó như kim chỉ nam rồi, nghĩ nó là nhất rồi thì đâu biết cái khác nó hay nó dở thế nào đâu. Làm cái nhỏ nhỏ thì được. Còn dữ liệu lớn thì nên tìm giải pháp khác. Tôi thấy một số thứ viết vba mướt mồ hôi còn dùng power bi, tableau, python, đại loại rất nhiều thứ xử lý rất đơn giản, nhanh gọn. Biết nhiều càng tốt nhưng đừng cuồng quá một thứ. Tôi nghĩ vậy
Biết càng nhiều càng tốt, vì kiến thức không bao giờ đủ. Nhưng tôi nghĩ số người dùng dữ liệu khủng chỉ là thiểu số. Mà dù thiểu số hay đa số thì cũng có người chỉ làm việc với dữ liệu bình thường. Nếu kiến thức hiện có đủ để làm việc với dữ liệu đó thì khó khuyên họ học cái mới. Vì họ chưa phải làm việc với dữ liệu khủng, sau giờ làm việc nếu có thời gian thì họ muốn giúp vợ / chồng việc nhà, chăm sóc con, trau dồi những kỹ năng khác cấp bách hơn. Nhu cầu có rất nhiều, không đủ thời gian thì phải lựa chọn thôi. Với bạn là phải đầu tư cho cái này, người khác họ có ưu tiên khác.