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

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

Bạn vướng nhiều thứ thế? không dành đất cho thành viên mới hơn hỏi?
 
Upvote 0
Bạn vướng nhiều thứ thế? không dành đất cho thành viên mới hơn hỏi?

Xin chào Gió Đông,
Dạ vâng, ^_^
Cơ quan của Oanh Thơ nghèo nên không có kinh phí mua phần mềm , do vậy mỗi người phải tự thân vận động bạn ạ.
Đáng buồn nhất là Oanh Thơ hỏi xong áp dụng OK là quên luôn không nhớ gì hết trơn ạ , mặc dù là đôi lúc đã dành tìm hiểu đến (T_T)

Sau 1 thời gian tham gia diễn đàn Oanh thơ cũng cảm thấy nơi đây: Thầy nhiều hơn Trò bạn ah :)
Một môi trường rất hữu ích, cảm giác thật tuyệt vời.

Rất mong được bạn giúp đỡ.
 
Upvote 0
Mã:
Sub TongHop()
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
Const TEN0 As String = "Tonghop" 'Ten sheet Tonghop
Dim wb As Workbook, ws As Worksheet, NB As String, NS As String
Dim tmp() As Variant, z As Long, r As Long, T As Variant
Dim KQ() As Variant, j As Long, k As Long, kMax As Long, maWS As String, tenWS As String
Set wb = ThisWorkbook: NB = wb.Name: NB = Left(NB, Len(NB) - 5)
ReDim KQ(1 To 1000000, 1 To 50)
For Each ws In wb.Worksheets
    NS = ws.Name
    If NS <> TEN0 Then      'Kiem tra: ten sheet <> ten sheet Tonghop
        z = ws.Range("I" & ws.Rows.Count).End(xlUp).Row
        If z > 9 Then
            Erase tmp
            tmp = ws.Range("E10:AW" & z).Value2: z = UBound(tmp, 1): kMax = UBound(tmp, 2)
            maWS = ws.Range("K6"): tenWS = ws.Range("K7")
            For r = 1 To z
                T = tmp(r, 5)
                If T <> Empty Then
                    j = j + 1
                    For k = 1 To kMax
                        KQ(j, k + 5) = tmp(r, k)
                    Next k
                    KQ(j, 1) = NB:      KQ(j, 2) = NS
                    KQ(j, 3) = maWS:    KQ(j, 4) = tenWS
                End If
            Next r
        End If
    End If
Next ws
If j Then
    Sheets(TEN0).Range("B5").Resize(1000000, 50).ClearContents
    Sheets(TEN0).Range("B5").Resize(j, 50) = KQ
End If
Application.ScreenUpdating = True
Application.Calculation = xlCalculationAutomatic
End Sub
p/s: Mỗi ngày oánh quả lẻ một bài rồi sẽ xong việc thôi...
 
Upvote 0
Xin chào Gió Đông,
Dạ vâng, ^_^
Cơ quan của Oanh Thơ nghèo nên không có kinh phí mua phần mềm , do vậy mỗi người phải tự thân vận động bạn ạ.
Đáng buồn nhất là Oanh Thơ hỏi xong áp dụng OK là quên luôn không nhớ gì hết trơn ạ , mặc dù là đôi lúc đã dành tìm hiểu đến (T_T)

Sau 1 thời gian tham gia diễn đàn Oanh thơ cũng cảm thấy nơi đây: Thầy nhiều hơn Trò bạn ah :)
Một môi trường rất hữu ích, cảm giác thật tuyệt vời.

Rất mong được bạn giúp đỡ.

Thế tự mày mò dần đi,
Thầy nhiều hơn trò , nên thành ra càng ngày không có trò nữa, toàn người nhờ luôn. Các thầy thì cứ thích làm luôn.
 
Upvote 0
Mã:
Sub TongHop()
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
Const TEN0 As String = "Tonghop" 'Ten sheet Tonghop
Dim wb As Workbook, ws As Worksheet, NB As String, NS As String
Dim tmp() As Variant, z As Long, r As Long, T As Variant
Dim KQ() As Variant, j As Long, k As Long, kMax As Long, maWS As String, tenWS As String
Set wb = ThisWorkbook: NB = wb.Name: NB = Left(NB, Len(NB) - 5)
ReDim KQ(1 To 1000000, 1 To 50)
For Each ws In wb.Worksheets
    NS = ws.Name
    If NS <> TEN0 Then      'Kiem tra: ten sheet <> ten sheet Tonghop
        z = ws.Range("I" & ws.Rows.Count).End(xlUp).Row
        If z > 9 Then
            Erase tmp
            tmp = ws.Range("E10:AW" & z).Value2: z = UBound(tmp, 1): kMax = UBound(tmp, 2)
            maWS = ws.Range("K6"): tenWS = ws.Range("K7")
            For r = 1 To z
                T = tmp(r, 5)
                If T <> Empty Then
                    j = j + 1
                    For k = 1 To kMax
                        KQ(j, k + 5) = tmp(r, k)
                    Next k
                    KQ(j, 1) = NB:      KQ(j, 2) = NS
                    KQ(j, 3) = maWS:    KQ(j, 4) = tenWS
                End If
            Next r
        End If
    End If
Next ws
If j Then
    Sheets(TEN0).Range("B5").Resize(1000000, 50).ClearContents
    Sheets(TEN0).Range("B5").Resize(j, 50) = KQ
End If
Application.ScreenUpdating = True
Application.Calculation = xlCalculationAutomatic
End Sub

p/s: Mỗi ngày oánh quả lẻ một bài rồi sẽ xong việc thôi...

...Cảm ơn befaint rất nhiều ...!!
cuhanh.png
 
Upvote 0
Thế tự mày mò dần đi,
Thầy nhiều hơn trò , nên thành ra càng ngày không có trò nữa, toàn người nhờ luôn. Các thầy thì cứ thích làm luôn.

Xin chào Gió Đông,
Cảm ơn bạn đã góp ý,Oanh Thơ sẽ cố gắng hơn nữa.

Có 1 câu nói của 1 thành viên ở chữ ký,khiến cho tôi cũng nhớ mãi,có lẽ Oanh Thơ cũng như bạn ấy:
"Hỏi thì ngại mọi người chê mình dốt mà không hỏi thì sẽ dốt cả đời .Học hỏi là để vượt qua chính mình."
OnionCN_A_003.gif


Nhưng sao code tôi không thể ...
m(_ _)m
 
Upvote 0
Xin chào befaint,
Bạn cho hỏi,code của bạn tôi sửa phần màu xanh thì có vấn đề gì không bạn?
Tôi sửa xong chạy chạy thử thì không báo lỗi gì cả. Sở dĩ tôi muốn sửa là vì sau dòng 102 thì cột I còn những dữ liệu khác nữa mà tôi không muốn xét đến.

Mã:
Sub TongHop()
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
Const TEN0 As String = "Tonghop" 'Ten sheet Tonghop
Dim wb As Workbook, ws As Worksheet, NB As String, NS As String
Dim tmp() As Variant, z As Long, r As Long, T As Variant
Dim KQ() As Variant, j As Long, k As Long, kMax As Long, maWS As String, tenWS As String
Set wb = ThisWorkbook: NB = wb.Name: NB = Left(NB, Len(NB) - 5)
ReDim KQ(1 To 1000000, 1 To 50)
For Each ws In wb.Worksheets
    NS = ws.Name
    If NS <> TEN0 Then      'Kiem tra: ten sheet <> ten sheet Tonghop
        z = ws.Range("I" & ws.Rows.Count).End(xlUp).Row
        If z > 9 Then
            Erase tmp
            tmp = ws.Range("E10:[COLOR=#0000ff]AW102[/COLOR][COLOR=#ff0000][/COLOR]").Value2: z = UBound(tmp, 1): kMax = UBound(tmp, 2)
            maWS = ws.Range("K6"): tenWS = ws.Range("K7")
            For r = 1 To z
                T = tmp(r, 5)
                If T <> Empty Then
                    j = j + 1
                    For k = 1 To kMax
                        KQ(j, k + 5) = tmp(r, k)
                    Next k
                    KQ(j, 1) = NB:      KQ(j, 2) = NS
                    KQ(j, 3) = maWS:    KQ(j, 4) = tenWS
                End If
            Next r
        End If
    End If
Next ws
If j Then
    Sheets(TEN0).Range("B5").Resize(1000000, 50).ClearContents
    Sheets(TEN0).Range("B5").Resize(j, 50) = KQ
End If
Application.ScreenUpdating = True
Application.Calculation = xlCalculationAutomatic
End Sub
 
Upvote 0
Xin chào befaint,
Bạn cho hỏi,code của bạn tôi sửa phần màu xanh thì có vấn đề gì không bạn?
Tôi sửa xong chạy chạy thử thì không báo lỗi gì cả. Sở dĩ tôi muốn sửa là vì sau dòng 102 thì cột I còn những dữ liệu khác nữa mà tôi không muốn xét đến.
Bởi vì:
Tổng hợp dữ liệu từ vùng E10:AW102 của sheet1:sheet70 vào sheet Tonghop với điều kiện Cột I (tiêu đề C5) của các sheet con có dữ liệu thì lấy
có chỗ màu đỏ nên theo file ở bài #1 thì:
Mã:
z = ws.Range("I" & ws.Rows.Count).End(xlUp).Row
sẽ xảy ra trường hợp z<102 => giảm được bớt dữ liệu cần xử lý.

Nếu:
Sở dĩ tôi muốn sửa là vì sau dòng 102 thì cột I còn những dữ liệu khác nữa mà tôi không muốn xét đến
thì cố định luôn:
Mã:
tmp = ws.Range("E10:AW102").Value2: z = UBound(tmp, 1): kMax = UBound(tmp, 2)
khi đó xóa bỏ 3 dòng:
Mã:
z = ws.Range("I" & ws.Rows.Count).End(xlUp).Row
If z > 9 Then

End If
 
Upvote 0
Cảm ơn befaint,
Nếu xóa 3 dòng:
Mã:
z = ws.Range("I" & ws.Rows.Count).End(xlUp).Row
If z > 9 Then
End If
thì có phải biến z sẽ không cần thiết nữa phải không ạ, biến z sẽ không có ý nghĩa gì nữa,nếu đúng như vậy thì biến z của dòng code bên dưới có phải sửa thêm gì nữa không bạn?
Mã:
tmp = ws.Range("E10:AW102").Value2: [COLOR=#ff0000][B]z[/B][/COLOR] = UBound(tmp, 1): kMax = UBound(tmp, 2)
 
Upvote 0
Cảm ơn befaint,
Nếu xóa 3 dòng:
Mã:
z = ws.Range("I" & ws.Rows.Count).End(xlUp).Row
If z > 9 Then
End If
thì có phải biến z sẽ không cần thiết nữa phải không ạ, biến z sẽ không có ý nghĩa gì nữa,nếu đúng như vậy thì biến z của dòng code bên dưới có phải sửa thêm gì nữa không bạn?
Mã:
tmp = ws.Range("E10:AW102").Value2: [COLOR=#ff0000][B]z[/B][/COLOR] = UBound(tmp, 1): kMax = UBound(tmp, 2)

Để nguyên.
Cách đó 1 dòng có For r = 1 To z
 
Upvote 0
Để nguyên.
Cách đó 1 dòng có For r = 1 To z

Cảm ơn befaint,
Xin lỗi bạn,tôi vẫn hơi khó hiểu ở chỗ khi xóa:
Mã:
z = ws.Range("I" & ws.Rows.Count).End(xlUp).Row
lúc này biến z sẽ dựa vào đâu để kết thúc vòng lặp for ở trên ạ? mong bạn chỉ dẫn thêm ạ.+-+-+-+
 
Upvote 0
A, tôi thấy rồi!
Biến z sẽ dựa vào mảng tạm tmp :
Mã:
tmp = ws.Range("E10:AW102").Value2: z = UBound(tmp, 1)

Cảm ơn bạn nhiều,befaint
 
Upvote 0
Cảm ơn befaint,
Xin lỗi bạn,tôi vẫn hơi khó hiểu ở chỗ khi xóa:
Mã:
z = ws.Range("I" & ws.Rows.Count).End(xlUp).Row
lúc này biến z sẽ dựa vào đâu để kết thúc vòng lặp for ở trên ạ? mong bạn chỉ dẫn thêm ạ.+-+-+-+

Code 1:
Mã:
For Each ws In wb.Worksheets 'Xét các ws trong wb
    NS = ws.Name 'Lấy tên ws
    If NS <> TEN0 Then      'Kiem tra: ten sheet <> ten sheet Tonghop
        z = ws.Range("I" & ws.Rows.Count).End(xlUp).Row  'Xác định dòng cuối cùng từ dưới lên có dữ liệu ở cột I (1)
        If z > 9 Then 'Kiểm tra điều kiện z>9 mới chạy tiếp, nếu z<=9 tức là (1) không có dữ liệu, chỉ có cái tiêu đề ở dòng 9
            Erase tmp 'Xóa dữ liệu biến tmp
            tmp = ws.Range("E10:AW" & z).Value2: z = UBound(tmp, 1): kMax = UBound(tmp, 2)
    'Gán vùng dữ liệu "E10:AW" & z vào biến tmp
    'Xác định kích thước chiều thứ nhất của mảng tmp(): z = UBound(tmp, 1) (2)
    'Chú thích: Ở đây tận dụng biến z (không thêm biến), biến z sẽ có giá trị mới, giá trị ở (1) bị loại bỏ.
    'Xác định kích thước chiều thức hai của mảng tmp(): kMax = UBound(tmp, 2)
            maWS = ws.Range("K6"): tenWS = ws.Range("K7")
    'Lấy giá trị mã và tên tại K6, K7
            For r = 1 To z
    'Chạy vòng lặp từ 1 tới z (giá trị z ở (2))
Code 2:
Mã:
For Each ws In wb.Worksheets
    NS = ws.Name
    If NS <> TEN0 Then      'Kiem tra: ten sheet <> ten sheet Tonghop
            Erase tmp
            tmp = ws.Range("E10:AW102").Value2: z = UBound(tmp, 1): kMax = UBound(tmp, 2)
    'Gán vùng dữ liệu "E10:AW102" vào biến tmp
    'Xác định kích thước chiều thứ nhất của mảng tmp(): z = UBound(tmp, 1) (*)
    'Xác định kích thước chiều thức hai của mảng tmp(): kMax = UBound(tmp, 2)
            maWS = ws.Range("K6"): tenWS = ws.Range("K7")
            For r = 1 To z
    'Chạy vòng lặp từ 1 tới z (giá trị z ở (*))
                T = tmp(r, 5)
                If T <> Empty Then
                    j = j + 1
                    For k = 1 To kMax
                        KQ(j, k + 5) = tmp(r, k)
                    Next k
                    KQ(j, 1) = NB:      KQ(j, 2) = NS
                    KQ(j, 3) = maWS:    KQ(j, 4) = tenWS
                End If
            Next r
    End If
Next ws
 
Upvote 0
Code 1:
Mã:
For Each ws In wb.Worksheets 'Xét các ws trong wb
    NS = ws.Name 'Lấy tên ws
    If NS <> TEN0 Then      'Kiem tra: ten sheet <> ten sheet Tonghop
        z = ws.Range("I" & ws.Rows.Count).End(xlUp).Row  'Xác định dòng cuối cùng từ dưới lên có dữ liệu ở cột I (1)
        If z > 9 Then 'Kiểm tra điều kiện z>9 mới chạy tiếp, nếu z<=9 tức là (1) không có dữ liệu, chỉ có cái tiêu đề ở dòng 9
            Erase tmp 'Xóa dữ liệu biến tmp
            tmp = ws.Range("E10:AW" & z).Value2: z = UBound(tmp, 1): kMax = UBound(tmp, 2)
    'Gán vùng dữ liệu "E10:AW" & z vào biến tmp
    'Xác định kích thước chiều thứ nhất của mảng tmp(): z = UBound(tmp, 1) (2)
    'Chú thích: Ở đây tận dụng biến z (không thêm biến), biến z sẽ có giá trị mới, giá trị ở (1) bị loại bỏ.
    'Xác định kích thước chiều thức hai của mảng tmp(): kMax = UBound(tmp, 2)
            maWS = ws.Range("K6"): tenWS = ws.Range("K7")
    'Lấy giá trị mã và tên tại K6, K7
            For r = 1 To z
    'Chạy vòng lặp từ 1 tới z (giá trị z ở (2))
Code 2:
Mã:
For Each ws In wb.Worksheets
    NS = ws.Name
    If NS <> TEN0 Then      'Kiem tra: ten sheet <> ten sheet Tonghop
            Erase tmp
            tmp = ws.Range("E10:AW102").Value2: z = UBound(tmp, 1): kMax = UBound(tmp, 2)
    'Gán vùng dữ liệu "E10:AW102" vào biến tmp
    'Xác định kích thước chiều thứ nhất của mảng tmp(): z = UBound(tmp, 1) (*)
    'Xác định kích thước chiều thức hai của mảng tmp(): kMax = UBound(tmp, 2)
            maWS = ws.Range("K6"): tenWS = ws.Range("K7")
            For r = 1 To z
    'Chạy vòng lặp từ 1 tới z (giá trị z ở (*))
                T = tmp(r, 5)
                If T <> Empty Then
                    j = j + 1
                    For k = 1 To kMax
                        KQ(j, k + 5) = tmp(r, k)
                    Next k
                    KQ(j, 1) = NB:      KQ(j, 2) = NS
                    KQ(j, 3) = maWS:    KQ(j, 4) = tenWS
                End If
            Next r
    End If
Next ws

Yeap!!
Cảm ơn befaint,
Các dòng chú thích ở mỗi dòng code tương ứng rất cần thiết và có giá trị rất lớn đối với tôi.
Nhờ đó mà tôi đã hiểu thêm nhiều hơn như tôi tưởng..nếu code nào cũng như thế này thì chả mấy chốc tôi không còn là Trò nữa, hihi =))
 
Upvote 0
Xin chào befaint,
Sau một hồi ngâm cứu tôi có 2 thắc mắc sau, rất mong bạn chỉ dẫn thêm:
1.
Mã:
Dim wb As Workbook, ws As Worksheet, NB As String, NS As String
Dim tmp() As Variant, z As Long, r As Long, T As Variant
Dim KQ() As Variant, j As Long, k As Long, kMax As Long, maWS As String, tenWS As String
Set wb = ThisWorkbook: NB = wb.Name: NB = Left(NB, Len(NB) - 5) 'Ten file
[B]ReDim KQ[/B](1 To 1000000, 1 To 50)
ở trên đã khai báo Dim KQ() As Variant
ở dưới là: ReDim KQ(1 To 1000000, 1 To 50)
ReDim KQ ở đây có vai trò gì ạ?


2.
Mã:
KQ(j, k + 5) = tmp(r, k)
Số 5 ở đây có phải là cột G trong sheet Tonghop?

Còn rất nhiều thắc mắc liên quan đến mảng tôi muốn tìm hiểu thêm, nhưng vấn đề này có lẽ chờ 1 dịp khác ạ.
 
Upvote 0
ở trên đã khai báo Dim KQ() As Variant
ở dưới là: ReDim KQ(1 To 1000000, 1 To 50)
ReDim KQ ở đây có vai trò gì ạ?

Trả lời nôm na thế này cho dễ hiểu: Mảng có 2 loại mảng tĩnh và mảng động. Phân biệt nó như sau:
a) Khi số phần tử trong mảng được cho trước, ta có mảng tĩnh. Ví dụ Dim arr(1 to 10) ---> Số 1 và 10 cố định.
b) Mảng động ngược lại, khi số phần tử trong mảng chưa biết trước mà phải thông qua biến nào đó để tính toán. Khi ấy BẮT BUỘC phải dùng ReDim chứ Dim thì lỗi ngay. Ví dụ ReDim arr(1 to n) với n là biến nào đó
-----------------------------------
Vậy có thể thấy code trên ReDim là thừa bởi mảng trên là mảng tĩnh (chẳng có thứ gì "động đậy" cả). Sửa lại theo 1 trong 2 cách sau:


  • Hoặc: Dim KQ(1 To 1000000, 1 To 50) và bỏ ReDim
  • Hoặc: ReDim KQ(1 To 1000000, 1 To 50) và bỏ Dim
----------------------------------
Ngoài chỗ đó vẫn còn nhiều cái thừa và chưa hợp lý nữa, để bạn và tác giả tự nghiên cứu lấy
 
Upvote 0
1.

ở trên đã khai báo Dim KQ() As Variant
ở dưới là: ReDim KQ(1 To 1000000, 1 To 50) (1)
ReDim KQ ở đây có vai trò gì ạ? (2)
(1) Ban đầu khai báo biến KQ(), mới khai báo là mảng 2 chiều nhưng chưa biết kích thước của mảng đó.
(2) Redim KQ(): Khai báo rõ kích thước cho mảng KQ()
Bạn tìm trên diễn đàn cũng đã có hoặc từ khóa "how to use redim in vba"
2.
Mã:
KQ(j, k + 5) = tmp(r, k)
Số 5 ở đây có phải là cột G trong sheet Tonghop?

Ở sheet "Tonghop" có 50 cột cần tổng hợp (B:AY)
Nên có ReDim KQ(1 To 1000000, 1 To 50)
Trong các sheet nhỏ có 45 cột cần dữ liệu (E:AW) và gán vào sheet "Tonghop" từ cột G tới cột AY (ứng với vị trí cột 6-50 của mảng KQ())
nên xét k=1 tới 45 thì KQ(j, k + 5)=tmp(r, k)
Tức là: KQ(j, từ 6 tới 50)=tmp(r, từ 1 tới 45)
Còn rất nhiều thắc mắc liên quan đến mảng tôi muốn tìm hiểu thêm, nhưng vấn đề này có lẽ chờ 1 dịp khác ạ.
Về mảng: tìm trên diễn đàn rất nhiều...
Bài #4
 
Upvote 0
Trả lời nôm na thế này cho dễ hiểu: Mảng có 2 loại mảng tĩnh và mảng động. Phân biệt nó như sau:
a) Khi số phần tử trong mảng được cho trước, ta có mảng tĩnh. Ví dụ Dim arr(1 to 10) ---> Số 1 và 10 cố định.
b) Mảng động ngược lại, khi số phần tử trong mảng chưa biết trước mà phải thông qua biến nào đó để tính toán. Khi ấy BẮT BUỘC phải dùng ReDim chứ Dim thì lỗi ngay. Ví dụ ReDim arr(1 to n) với n là biến nào đó
-----------------------------------
Vậy có thể thấy code trên ReDim là thừa bởi mảng trên là mảng tĩnh (chẳng có thứ gì "động đậy" cả). Sửa lại theo 1 trong 2 cách sau:


  • Hoặc: Dim KQ(1 To 1000000, 1 To 50) và bỏ ReDim
  • Hoặc: ReDim KQ(1 To 1000000, 1 To 50) và bỏ Dim
----------------------------------
Ngoài chỗ đó vẫn còn nhiều cái thừa và chưa hợp lý nữa, để bạn và tác giả tự nghiên cứu lấ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.

theo như tôi thấy: môi trường này là môi trường học hỏi giúp mọi người có thể hoàn thiện được khả năng của mình.
nếu một người nào đó: tất cả mọi thứ cái gì cũng biết cũng chưa chắc người đó đã tham gia diễn đàn này, phải không bạn?

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

(1) Ban đầu khai báo biến KQ(), mới khai báo là mảng 2 chiều nhưng chưa biết kích thước của mảng đó.
(2) Redim KQ(): Khai báo rõ kích thước cho mảng KQ()
Bạn tìm trên diễn đàn cũng đã có hoặc từ khóa "how to use redim in vba"
[/COLOR]
Ở sheet "Tonghop" có 50 cột cần tổng hợp (B:AY)
Nên có ReDim KQ(1 To 1000000, 1 To 50)
Trong các sheet nhỏ có 45 cột cần dữ liệu (E:AW) và gán vào sheet "Tonghop" từ cột G tới cột AY (ứng với vị trí cột 6-50 của mảng KQ())
nên xét k=1 tới 45 thì KQ(j, k + 5)=tmp(r, k)
Tức là: KQ(j, từ 6 tới 50)=tmp(r, từ 1 tới 45)

Về mảng: tìm trên diễn đàn rất nhiều...
Bài #4

Cảm ơn befaint,
Tôi sẽ cố gắng tìm hiểu thêm theo hướng của bạn đã chỉ dẫn.
 
Upvote 0
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.

theo như tôi thấy: môi trường này là môi trường học hỏi giúp mọi người có thể hoàn thiện được khả năng của mình.
nếu một người nào đó: tất cả mọi thứ cái gì cũng biết cũng chưa chắc người đó đã tham gia diễn đàn này, phải không bạn?

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



Cảm ơn befaint,
Tôi sẽ cố gắng tìm hiểu thêm theo hướng của bạn đã chỉ dẫn.

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 Long
Dim FileName As String, ShName As String, MaSheet As String, TenSheet As String
FileName = 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 If
Next Ws
With Sheets(TONGHOP)
    .Range("B5").Resize(50000, 50).ClearContents
    .Range("B5").Resize(K, 50) = dArr
End With
End Sub
 
Lần chỉnh sửa cuối:
Upvote 0
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

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

Back
Top Bottom