Cái vụ này mà dùng công thức thì có vẻ hơi oải đấy.Em có 1 bảng excel như trong sheet 1, dùng cái gì để có thể xử lý dữ liệu đó thành bảng như sheet 2? Xin xem file đính kèm. Cảm ơn anh chị giúp đỡ.
Tổng quát hơn một chút:Cám ơn bạn NghiaPhuc, bạn có thể giải thích giúp mình cái Code đó không vì có thể cái bảng tính sheet 1 nó to hơn nữa. Ví dụ không phải là 5 project mà tới 10 project trên 1 hàng chẳng hạn. Mình hiểu cái code thì có thể áp dụng được. Cảm ơn bạn.
Kệ nó, có hay không thì cũng cứ đưa vào mảng, nếu không có thì dữ liệu của cột Comment tương ứng sẽ để trống. Code chỉ quan tâm đến các cột Project, hễ cột này có giá trị thì sẽ đưa giá trị của nhóm 4 cột tương ứng vào mảng.Bạn Phúc ơi, nếu bây giờ gặp trường hợp tổng quát hơn là có thêm 1 cột Comment, mà Comment thì không phải là required field, lúc có lúc không. Như thế mình phải viết code như thế nào?
Sub TongHop()
Dim Tmp, Arr(), i As Long, j As Long, k As Long
Sheet2.[A2:E65000].ClearContents
Tmp = Sheet1.[A2:IV10000]
ReDim Arr(1 To 10 * UBound(Tmp), 1 To [COLOR=#ff0000][B]6[/B][/COLOR])
For i = 1 To UBound(Tmp)
If Tmp(i, 1) = "" Then Exit For
For j = 3 To UBound(Tmp, 1) Step [B][COLOR=#ff0000]4[/COLOR][/B]
If Tmp(i, j) = "" Then Exit For
k = k + 1
Arr(k, 1) = Tmp(i, 1): Arr(k, 2) = Tmp(i, 2)
Arr(k, 3) = Tmp(i, j): Arr(k, 4) = Tmp(i, j + 1)
Arr(k, 5) = Tmp(i, j + 2): [COLOR=#ff0000][B]Arr(k, 6) = Tmp(i, j + 3)[/B][/COLOR]
Next
Next
Sheet2.[A2].Resize(k, [COLOR=#ff0000][B]6[/B][/COLOR]).Value = Arr
End Sub
ngoài vùng này thì không lấy dữ liệu nữa IV10000Mình đã tự sửa code đó theo bạn hướng dẫn và kết quả y như bạn vừa mới viết ra đây giúp mình. Bây giờ mình còn 1 thắng mắc là cái nút "Tổng Hợp" bạn làm như thế nào vậy?
Cái VBA này giới hạn của nó là bao nhiêu dòng excel vậy bạn? Ý mình là sheet 1 tối đa được bao nhiêu dòng thì vượt quá khả năng của code này?
Về cái nút "Tổng hợp" thì bạn chọn tab Developer (nếu không thấy tab này thì click phải, chọn Customize the Ribbon và tick chọn nó), nhấn nút Insert\Button (Form control), vẽ nó lên sheet rồi Assign cho nó Macro TongHop.Mình đã tự sửa code đó theo bạn hướng dẫn và kết quả y như bạn vừa mới viết ra đây giúp mình. Bây giờ mình còn 1 thắng mắc là cái nút "Tổng Hợp" bạn làm như thế nào vậy?
Cái VBA này giới hạn của nó là bao nhiêu dòng excel vậy bạn? Ý mình là sheet 1 tối đa được bao nhiêu dòng thì vượt quá khả năng của code này?
Bạn cứ yên tâm đi, code chạy cái rẹt là xong chứ có gì mà phải bận tâm đến chuyện cái có rồi với cái chưa có đâu. Bạn cứ thử thêm vài ngàn dòng dữ liệu rồi chạy code xem mất bao nhiêu giây.Mình đã sử dụng code này và nó hoạt động rất tốt. Mình đặt ra thêm 1 vấn đề nhờ các bạn giúp đỡ.
Vẫn với bảng excel đó, hằng ngày Sheet 1 được add thêm data mới. Khi đó nhấn vào nút "Tổng hợp" thì nó phải duyệt lại từ đầu để tổng hợp lại bảng mới ở Sheet 2.
Có cách nào (code nào) để khi nhấn vào nút "Tổng hợp" thì excel update tiếp cái bảng đã có ở sheet 2 mà không phải trở lại từ đầu không?
Bạn cứ yên tâm đi, code chạy cái rẹt là xong chứ có gì mà phải bận tâm đến chuyện cái có rồi với cái chưa có đâu. Bạn cứ thử thêm vài ngàn dòng dữ liệu rồi chạy code xem mất bao nhiêu giây.
Mình còn cần 1 macro giúp replace all nhiều thứ cùng 1 lúc với nhau, Ví dụ replace A thành B, replace D thành E và replace F thành G. liệu VBA có làm được điều này không?
Việc này không khó, cần 2 mảng (có thể là hằng mảng hoặc lấy từ bảng tra trên sheet). Tiếp theo sử dụng một vòng lặp duyệt mảng nguồn và thay thế bằng giá trị tương ứng trên mảng đích, sử dụng phương thức Replace. Để trưa nay tôi viết thử, bây giờ online bằng điện thoại nên không làm được.Mình còn cần 1 macro giúp replace all nhiều thứ cùng 1 lúc với nhau, Ví dụ replace A thành B, replace D thành E và replace F thành G. liệu VBA có làm được điều này không?
Đây là một ví dụ về code thay thế hàng loạt trên 1 vùng:Việc này không khó, cần 2 mảng (có thể là hằng mảng hoặc lấy từ bảng tra trên sheet). Tiếp theo sử dụng một vòng lặp duyệt mảng nguồn và thay thế bằng giá trị tương ứng trên mảng đích, sử dụng phương thức Replace. Để trưa nay tôi viết thử, bây giờ online bằng điện thoại nên không làm được.
Đây là một ví dụ về code thay thế hàng loạt trên 1 vùng:
[GPECODE=vb]Sub ReplaceText()
Dim Sou, Des, i As Long
Sou = Array("A", "C", "E", "G")
Des = Array("B", "D", "F", "H")
For i = 1 To UBound(Sou)
Sheet1.[A1:F100].Replace Sou(i), Des(i), xlWhole
Next
End Sub[/GPECODE]
Bạn có thể thay đổi theo yêu cầu:
- Các biến Sou, Des nhận các giá trị khác, có thể là 2 vùng tương ứng trên sheet (lưu ý: 2 mảng này phải có cùng số phần tử).
- Vùng Sheet1.A1:F100 có thể thay bởi vùng khác
- xlWhole có thể thay bởi xlPart nếu bạn chỉ muốn tìm kiếm các từ có trong ô (chứ không phải nội dung cả ô)
- Thêm , MatchCase:=True vào sau xlWhole nếu muốn phân biệt chữ hoa, chữ thường.
Bạn dùng code này nhé:Mình đang phải tổng hợp lại các dữ liệu cũ mà nếu gõ lại từ đầu hoặc copy paste bằng tay không chỉ mất thời gian mà nguy cơ sai cũng rất cao. Nay mình lại có một bảng dữ liệu dạng Sheet 1 cần chuyển giống như Sheet 2. Các cột A B C D là không đổi nhưng cột E F G H (có thể nhiều hơn nữa).. cần phải chuyển lại dạng hàng dọc và thành 2 cột Name và Time spent (như sheet 2)
Nhờ các bạn giúp mình code để chuyển đổi nhanh và chính xác.
Cám ơn các bạn.
Bạn dùng code này nhé:
[GPECODE=vb]Sub TongHop()
Dim Tmp, Arr(), i As Long, j As Long, k As Long
Application.ScreenUpdating = False
Sheet2.[A2:F65000].Clear
Tmp = Sheet1.[A1:IV10000]
ReDim Arr(1 To UBound(Tmp), 1 To 6)
For i = 2 To UBound(Tmp)
If Tmp(i, 1) = "" Then Exit For
k = k + 1
For j = 1 To 4
Arr(k, j) = Tmp(i, j)
Next
For j = 5 To UBound(Tmp, 1)
If Len(Tmp(i, j)) Then
Arr(k, 5) = Tmp(1, j)
Arr(k, 6) = Tmp(i, j)
Exit For
End If
Next
Next
With Sheet2.[A2]
.Resize(k).NumberFormat = "dd/MMM"
.Resize(k, 6).Value = Arr
.Resize(k, 6).Borders.LineStyle = 1
End With
Application.ScreenUpdating = True
End Sub[/GPECODE]
Nếu muốn tiết kiệm bộ nhớ 1 chút thì bạn có thể thay dòng này trong code của anh Phúc :Bạn Nghiaphuc thật giỏi và giải đáp rất nhanh, rất cảm ơn bạn giúp đỡ.
With Sheet1
Tmp = Range(.Cells(1, 1), .Cells(Sheet1.[A65536].End(xlUp).Row, .[IV1].End(xlToLeft).Column))
End With
Cái vụ End(xlUp), End(xlToLeft) này thì anh cũng có biết, và lúc đầu viết code cũng có nghĩ đến nó, nhưng mà nghĩ lại: Đã dùng đến mảng thì cứ vô tư đi mà, "kệ tía" nó. Hơn nữa, trong vòng 2 vòng For, anh đã đặt sẵn lệnh Exit For, hễ "gặp thời cơ" là nó thoát ngay thôi mà.Nếu muốn tiết kiệm bộ nhớ 1 chút thì bạn có thể thay dòng này trong code của anh Phúc :
Tmp = Sheet1.[A1:IV10000]
Bằng đoạn này :
PHP:With Sheet1 Tmp = Range(.Cells(1, 1), .Cells(Sheet1.[A65536].End(xlUp).Row, .[IV1].End(xlToLeft).Column)) End With
Thực ra bàn chuyện nhanh hay chậm thì em không bàn, có lẽ là do thói quen "tiết kiệm" của mỗi người khi viết code thôi. Cái này em nghĩ cũng chỉ là tiểu tiết vì thuật toán thì code của anh quá chuẩn rùi, riêng em em cho rằng khi gán thằng Tmp = cả vùng A1:IV10000 thì máy tính đã phải đọc hết số phần tử đó vào bộ nhớ máy tính rùi khi Ubound nó để Redim xác định kích cỡ của mảng Arr qua Tmp thì nó hơi mệt xíu thôi ạ! Chắc là bệnh của em, hihihiCái vụ End(xlUp), End(xlToLeft) này thì anh cũng có biết, và lúc đầu viết code cũng có nghĩ đến nó, nhưng mà nghĩ lại: Đã dùng đến mảng thì cứ vô tư đi mà, "kệ tía" nó. Hơn nữa, trong vòng 2 vòng For, anh đã đặt sẵn lệnh Exit For, hễ "gặp thời cơ" là nó thoát ngay thôi mà.
Lúc trước anh cũng hay dùng đến mấy cái End() này, nhưng từ khi làm quen với mảng (món này anh còn biết sau em xa) thì tự nhiên "lười", mà hình như cái "bệnh lười" này là anh nhiễm từ anh ndu đấy.Thực ra bàn chuyện nhanh hay chậm thì em không bàn, có lẽ là do thói quen "tiết kiệm" của mỗi người khi viết code thôi. Cái này em nghĩ cũng chỉ là tiểu tiết vì thuật toán thì code của anh quá chuẩn rùi, riêng em em cho rằng khi gán thằng Tmp = cả vùng A1:IV10000 thì máy tính đã phải đọc hết số phần tử đó vào bộ nhớ máy tính rùi khi Ubound nó để Redim xác định kích cỡ của mảng Arr qua Tmp thì nó hơi mệt xíu thôi ạ! Chắc là bệnh của em, hihihi