Lấy dữ liệu từ nhiều vào 1 sheet ? (1 người xem)

Liên hệ QC

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

Xin chào ndu96081631,
Cảm ơn bạn đã giúp đỡ, hiện giờ với kiến thức abc của tôi thì để nhìn nhận thấy vấn đề chưa hợp lý theo ý của bạn là không thể.
Giá như bạn có thể góp ý chi tiết như bạn VetMini trong chủ đề này:
http://www.giaiphapexcel.com/forum/showthread.php?121612-Lọc-duy-nhất&p=770666#post770666

thì sẽ dễ dàng cho cả tôi và befaint rất nhiều.

Được thôi (chỉ sợ ít người thích nghe)
1> Thứ nhất: Ngay từ đầu đọc code là tôi đã thấy khá lằng nhằng về cách đặt tên biến khiến tôi biết đường nào mà lần
Tên biến cũng có quy định ngầm thế này: tiền tố đầu (từ 1 đến 3 ký tự) mô tả kiểu biến và luôn luôn viết thường, các ký tự sau đó mô tả công dụng của biến với ký tự đầu (hoặc vài ký tự sau đó) được viết hoa. Ví dụ:
wksMain ---> Biết ngay biến này là kiểu worksheet, có tên là Main hoặc có công dụng như một sheet chính
lR hoặc lRow ---> Biến kiểu long, mô tả về chỉ số dòng
aSource hoặc arrSource ---> biến Array mô tả vùng dữ liệu nguồn
vân vân....
2> Thứ hai: Nói về phép so sánh chuỗi: If NS <> TEN0 đây là phép so sánh rất chủ quan, bởi nếu đổi tên sheet thành TONGHOP thì phát biểu IF kia sẽ cho kết quả FALSE mà ta chưa chắc biết lý do tại sao. Cách an toàn là dùng UCase hoặc LCase
Mã:
Const TEN0 = "TONGHOP"
.......
If UCase(NS) <> TEN0 then
Ngoài ra, để chắc ăn cho người chạy code với bất cứ sự thay đổi tên sheet nào, ta nên vẽ 1 button lên sheet tổng hợp, chạy code thông qua button thì sẽ khỏi chạy đâu sai cả (vân vân.. và nhiều cách khác)
3> Thứ ba: kMax = UBound(tmp, 2) trong khi tmp = ws.Range("E10:AW" & z).Value2 là vùng cố định từ cột E đến AW ---> Suy ra kMax này ta luôn luôn biết trước là bao nhiêu cột rồi, vậy tại sao lại đưa vào vòng lập để tính toán?
----------------------------------
Vài góp ý nhỏ. Nhìn chung là code ổn nhưng tôi vẫn không thích tí nào về cách đặt tên biến của code này (chóng mặt, khó dò tìm...). Và cũng bởi chóng mặt, khó tìm nên nếu ai đó muốn sửa code thì chắc người ta thà viết lại từ đâu cho khỏe
 
Upvote 0
Có lẽ do thói quen đặt tên biến của mỗi người, ai đặt nấy hiểu, nấy nhớ. Ví dụ biến T, biến z ...
Cũng tương tự hoạt động của code trên, nhưng nếu đặt tên biến kiểu khác có lẽ dễ "đọc" hơn một chút:
I, J, K là các biến "chạy".
Rws, hay R có thể nghĩ đến "dòng"
sArr : mảng nguồn, dArr: Mảng đích (kết quả)
FileName: Tên File......
PHP:
Public Sub GPE()Const TONGHOP As String = "Tonghop"Dim Ws As Worksheet, sArr(), dArr(1 To 50000, 1 To 50)Dim Rws As Long, I As Long, J As Long, K As Long, R As LongDim FileName As String, ShName As String, MaSheet As String, TenSheet As StringFileName = Left(ThisWorkbook.Name, InStr(ThisWorkbook.Name, ".") - 1)For Each Ws In ThisWorkbook.Worksheets    If Ws.Name <> TONGHOP Then        With Ws            R = .Range("I1000000").End(xlUp).Row            If R > 9 Then                ShName = .Name:   MaSheet = .Range("K6").Value:   TenSheet = .Range("K7").Value                sArr = .Range("E10:E" & R).Resize(, 45).Value:      Rws = UBound(sArr)                For I = 1 To Rws                    If sArr(I, 5) <> Empty Then                        K = K + 1                        dArr(K, 1) = FileName:      dArr(K, 2) = ShName                        dArr(K, 3) = MaSheet:       dArr(K, 4) = TenSheet                        For J = 1 To 45                            dArr(K, J + 5) = sArr(I, J)                        Next J                    End If                Next I            End If        End With    End IfNext WsWith Sheets(TONGHOP)    .Range("B5").Resize(50000, 50).ClearContents    .Range("B5").Resize(K, 50) = dArrEnd WithEnd Sub

Cảm ơn Ba Tê đã giúp tôi có thêm 1 sự lựa chọn và 1 cách để giúp tôi tiếp cận với code.
Tôi đã chạy thử code trên của bạn,kết quả cũng giống như code của bạn befaint (đúng với với mong muốn của tôi)
Nhìn qua code của bạn và befaint không gì khác nhau nhiều về thuật toán ?
Nhưng code của bạn tốc độ có phần nhanh hơn của bạn befaint 1 chút.
Tôi sẽ cố gắng dành thời gian tìm hiểu thêm vì sao lại như vậy.
Nếu gì vướng mắc mong lại được các bạn giúp đỡ.

-------------

Được thôi (chỉ sợ ít người thích nghe)
1> Thứ nhất: Ngay từ đầu đọc code là tôi đã thấy khá lằng nhằng về cách đặt tên biến khiến tôi biết đường nào mà lần
Tên biến cũng có quy định ngầm thế này: tiền tố đầu (từ 1 đến 3 ký tự) mô tả kiểu biến và luôn luôn viết thường, các ký tự sau đó mô tả công dụng của biến với ký tự đầu (hoặc vài ký tự sau đó) được viết hoa. Ví dụ:
wksMain ---> Biết ngay biến này là kiểu worksheet, có tên là Main hoặc có công dụng như một sheet chính
lR hoặc lRow ---> Biến kiểu long, mô tả về chỉ số dòng
aSource hoặc arrSource ---> biến Array mô tả vùng dữ liệu nguồn
vân vân....
2> Thứ hai: Nói về phép so sánh chuỗi: If NS <> TEN0 đây là phép so sánh rất chủ quan, bởi nếu đổi tên sheet thành TONGHOP thì phát biểu IF kia sẽ cho kết quả FALSE mà ta chưa chắc biết lý do tại sao. Cách an toàn là dùng UCase hoặc LCase
Mã:
Const TEN0 = "TONGHOP"
.......
If UCase(NS) <> TEN0 then
Ngoài ra, để chắc ăn cho người chạy code với bất cứ sự thay đổi tên sheet nào, ta nên vẽ 1 button lên sheet tổng hợp, chạy code thông qua button thì sẽ khỏi chạy đâu sai cả (vân vân.. và nhiều cách khác)
3> Thứ ba: kMax = UBound(tmp, 2) trong khi tmp = ws.Range("E10:AW" & z).Value2 là vùng cố định từ cột E đến AW ---> Suy ra kMax này ta luôn luôn biết trước là bao nhiêu cột rồi, vậy tại sao lại đưa vào vòng lập để tính toán?
----------------------------------
Vài góp ý nhỏ. Nhìn chung là code ổn nhưng tôi vẫn không thích tí nào về cách đặt tên biến của code này (chóng mặt, khó dò tìm...). Và cũng bởi chóng mặt, khó tìm nên nếu ai đó muốn sửa code thì chắc người ta thà viết lại từ đâu cho khỏe

Cảm ơn ndu96081631, đã chỉ dẫn.
Tôi là người hỏi nên chắc chắn sẽ tôi là người thích nghe,như vậy là đủ phải không bạn?
Nên bạn không phải lo sợ đâu ạ , tôi đang chưa có kiến thức gì về code, chưa thể nhìn nhận và tự giải quyết được các vấn đề liên quan đến code nên có có ý muốn học hỏi dần dần. Trong quá trình tiếp cận khó có thể tránh khỏi những câu hỏi ngớ ngẩn, vì thế tôi rất mong các bạn chỉ dẫn và góp ý nếu nhìn thấy vấn đề :-=...

1.Về vấn đề đặt tên biến có thể do thói quen hoặc sở thích của mỗi người. Nên thế nào cũng được ạ.
Tuy nhiên nếu đặt theo một chuẩn mực chung như bạn đã góp ý thì chỉ là dễ hiểu hơn thôi chứ code cũng không thay đổi về mặt tốc độ đúng không ạ.
Nhưng chắc cũng không đến mức phải như vậy:
http://www.giaiphapexcel.com/forum/...ó-đọc-cho-những-kẻ-tò-mò)&p=733388#post733388
Tôi chỉ dẫn chứng cho vui, chứ không mong muốn như vậy.Vì tôi cũng đã từng thắc mắc về vấn đề mã hóa code tại chủ đề:
http://www.giaiphapexcel.com/forum/showthread.php?122137-Code-viết-bằng-tiếng-Lào
nên cũng hiểu đó là chuyện mã hóa code nên nó là vấn đề khác.


2.Bạn có thể giải thích thêm dòng này được không ạ:
Ngoài ra, để chắc ăn cho người chạy code với bất cứ sự thay đổi tên sheet nào, ta nên vẽ 1 button lên sheet tổng hợp, chạy code thông qua button thì sẽ khỏi chạy đâu sai cả (vân vân.. và nhiều cách khác)

Việc chạy code thông qua button trên sheet"Tonghop" và chạy Sub trực tiếp trong cửa sổ soạn thảo code thì có gì khác nhau vậy, ý tôi muốn hỏi là chạy "code thông qua button thì sẽ khỏi chạy đâu sai cả..." là để có thể kiểm soá dễ dàng phát hiện được sự sai lệch?
 
Lần chỉnh sửa cuối:
Upvote 0
[thongbao]Việc chạy code thông qua button trên sheet"Tonghop" và chạy Sub trực tiếp trong cửa sổ soạn thảo code thì có gì khác nhau vậy?[/thongbao]

Cái Button đó nằm trên trang 'TongHop'; & để nhấn được vô nó, điều cần thiết là fải kích hoạt trang tính đó lên (làm trang tính hiện hành).

1 khi đã là trang hiện hành thì tên nó là gì thì mặc kệ nó; Chắc vậy.
 
Upvote 0
[thongbao]Việc chạy code thông qua button trên sheet"Tonghop" và chạy Sub trực tiếp trong cửa sổ soạn thảo code thì có gì khác nhau vậy?[/thongbao]

Cái Button đó nằm trên trang 'TongHop'; & để nhấn được vô nó, điều cần thiết là fải kích hoạt trang tính đó lên (làm trang tính hiện hành).

1 khi đã là trang hiện hành thì tên nó là gì thì mặc kệ nó; Chắc vậy.

Cảm ơn bạn đã giúp tôi hiểu được vấn đề,
Nghĩa là:
Mã:
If NS <> TEN0 Then
Sửa lại:
Mã:
If NS <> ActiveSheet.Name Then

Phải như vậy không bạn?
 
Upvote 0
Việc chạy code thông qua button trên sheet"Tonghop" và chạy Sub trực tiếp trong cửa sổ soạn thảo code thì có gì khác nhau vậy, ý tôi muốn hỏi là chạy "code thông qua button thì sẽ khỏi chạy đâu sai cả..." là để có thể kiểm soá dễ dàng phát hiện được sự sai lệch?
Ví dụ trường hợp này:
Mã:
Sub vidu()
range("A1")=1 
End sub
Trong cửa sổ vba mà chạy đoạn trên thì cứ sheet (xét cả workbook) nào được active (hiện hành) thì gán A1=1
Để chắc ăn thì gán nó vào cái nút ở sheet chỉ định cần chạy sub trên thì chỉ định gán A1=1 ở sheet có nút đó.
Hoặc viết chỉ định đích danh workbook.worksheet.range/cell
Mã:
Sub vidu()
Thisworkbook.sheets(1).range("A1")=1 
End sub
thì không quan tâm sheet nào đang active, khi chạy đoạn đó trong cửa sổ vba đều chỉ gán A1=1 ở sheets(1) của workbook hiện hành.
 
Lần chỉnh sửa cuối:
Upvote 0
Việc chạy code thông qua button trên sheet"Tonghop" và chạy Sub trực tiếp trong cửa sổ soạn thảo code thì có gì khác nhau vậy, ý tôi muốn hỏi là chạy "code thông qua button thì sẽ khỏi chạy đâu sai cả..." là để có thể kiểm soá dễ dàng phát hiện được sự sai lệch?
Bởi Button nằm tại sheet Tonghop nên đương nhiên bạn phải "đứng" tại sheet Tonghop mới chạy được. Và người ta sẽ có cách viết code đại khái thế này: Sheet nào có chứa cái Button thì sheet đó chính là sheet Tonghop (cho dù nó hổng phải tên Tonghop cũng không sao) và code bắt buộc phải chạy thông qua button chứ không thể chạy từ cửa sổ VBA
Như vậy sẽ rất là.. ổn
--------------------------------
1.Về vấn đề đặt tên biến có thể do thói quen hoặc sở thích của mỗi người. Nên thế nào cũng được ạ.
Với bạn hoặc những ai mới bắt đầu với lập trình thì "nên thế nào cũng được" hoàn toàn không có vấn đề, miễn ra được kết quả là tốt rồi
Với rất nhiều thành viên am hiểu lập trình thì điều đó hoàn toàn không thể chấp nhận (trừ phi bạn đủ tài "chế" ra chuẩn mực mới khiến cả thế giới phải làm theo)
Nói nôm na như việc quản lý tại 1 cty: nếu mọi thứ đều tuân theo 1 chuẩn mực cho trước thì dễ quản lý hơn thay vì mạnh ai nấy làm theo ý mình, đúng không?
 
Upvote 0
Cảm ơn bạn đã giúp tôi hiểu được vấn đề,
Nghĩa là:
Mã:
If NS <> TEN0 Then
Sửa lại:
Mã:
If NS <> ActiveSheet.Name Then

Phải như vậy không bạn?

Xem chừng cũng hơi khó hiểu. Thôi thì thì làm cái thí nghiệm để minh họa nhé!
Đại khái code trong file đính kèm dưới đây sẽ lấy dữ liệu tại cell A1 của tất cả các sheet rồi đưa vào cột A của sheet hiện hành (sheet chứa button). Code chỉ chạy khi bạn nhấn vào button, ngoài ra cho dù bạn chạy code từ cửa sổ VBA hay nhấn Alt + F8 để chạy đều không được. Từ đây bất kể bạn dời sheet đi đâu hay đổi tên sheet thành thứ gì cũng được, miễn sheet đó có chứa cái Button thì code mới chạy
Mục đích của tôi là: định vị tên sheet Tonghop theo cách khác an toàn hơn
 

File đính kèm

Upvote 0
Ahihi!
Cảm ơn befaint , cảm ơn ndu96081631,
Đến giờ phút này, qua các ví dụ của 2 bạn tôi đã thấu được vấn đề:
"Việc chạy code thông qua button trên sheet"
-----------
Cứ tưởng học trên này không mất bất cứ 1 khoản phí nào. :-=
Ai ngờ kết quả sau 1 buổi tìm hiểu về code thì đã mất 20k tiền mua "Panadol", chắc vấn đề này chưa dừng lại ở đây.. --=0
Nếu không có sự hỗ trợ chỉ dẫn tận tình của các bạn chắc tôi còn mệt dài và nặng gấp nhiều lần hơn thế.
 
Upvote 0
Web KT

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

Back
Top Bottom