Trong khi chờ các giải pháp cao siêu hơn khác, hay thử xem.Thân gửi anh chị !
Nhờ anh chị viết code cho file, từ cột H - > AQ, mỗi một cột em đã có để công thức ở cột đó,
Vậy rất mong anh chị giúp đỡ, em cảm ơn ạ
View attachment 276133
Đợt này thấy chú hay viết Dic ra riêng 1 sub nhỉ?dòng bôi màu vàng là dòng để thử, Bạn hãy thay đổi, thêm bớt dữ liệu để test
Tôi viết thế là kết quả học được anh Ndu anh ấy có nói đại ý là đối vói những bài cần lấy dữ liệu nhiều lần từ dic (như kiểu hàm Vlookup) thì nên viết Add_Dic riêng ra để khi cần lấy dữ liệu (khi có thêm dữ liệu cần phải lấy dữ liệu ở sheet khác) sẽ đỡ phải chạy lại dic. Tôi thấy nhiều bài Chỉ cần chạy dic 1 lần khi mở máy và sau đó cứ lấy từ đó ra. Khi có sự thay đổi ở sheet DanhMuc thì sub Add_dic lại được gọi. Việc này tôi thấy là rất có lợi khi ta code phải test đi test lại nhiều lần.Đợt này thấy chú hay viết Dic ra riêng 1 sub nhỉ?
Cháu chỉ thấy thắc mắc thế thôi. Như chú viết và chỉ điểm như vậy cũng có cái hay mà. tự dưng nhìn Dic nó tách riêng 1 sub chưa quen lắm. HihiTôi viết thế là kết quả học được anh Ndu anh ấy có nói đại ý là đối vói những bài cần lấy dữ liệu nhiều lần từ dic (như kiểu hàm Vlookup) thì nên viết Add_Dic riêng ra để khi cần lấy dữ liệu (khi có thêm dữ liệu cần phải lấy dữ liệu ở sheet khác) sẽ đỡ phải chạy lại dic. Tôi thấy nhiều bài Chỉ cần chạy dic 1 lần khi mở máy và sau đó cứ lấy từ đó ra. Khi có sự thay đổi ở sheet DanhMuc thì sub Add_dic lại được gọi. Việc này tôi thấy là rất có lợi khi ta code phải test đi test lại nhiều lần.
Còn không thì Ghép chung sub add_dic vào trong 1 sub nào đó cũng được mà.
Không biết áp dụng có phần cứng nhắc ấy có vấn đề gì không? Bạn cho mình xin ý kiến nhé
được rồi ạ, em cảm ơn anh chị đã giúp đỡ ạTrong khi chờ các giải pháp cao siêu hơn khác, hay thử xem.
Nhấn vào mặt cười để thưởng thức kết quả.
(dòng bôi màu vàng là dòng để thử, Bạn hãy thay đổi, thêm bớt dữ liệu để test)
Tôi sử dụng dic khá thành thạo nhưng hiếm khi tách riêng ra như thế này. Dic chỉ cần 1s để nạp dữ liệu. Viết rõ ràng sẽ dễ dàng cho việc sửa code khi cần thiết.Tôi viết thế là kết quả học được anh Ndu anh ấy có nói đại ý là đối vói những bài cần lấy dữ liệu nhiều lần từ dic (như kiểu hàm Vlookup) thì nên viết Add_Dic riêng ra để khi cần lấy dữ liệu (khi có thêm dữ liệu cần phải lấy dữ liệu ở sheet khác) sẽ đỡ phải chạy lại dic. Tôi thấy nhiều bài Chỉ cần chạy dic 1 lần khi mở máy và sau đó cứ lấy từ đó ra. Khi có sự thay đổi ở sheet DanhMuc thì sub Add_dic lại được gọi. Việc này tôi thấy là rất có lợi khi ta code phải test đi test lại nhiều lần.
Còn không thì Ghép chung sub add_dic vào trong 1 sub nào đó cũng được mà.
Không biết áp dụng có phần cứng nhắc ấy có vấn đề gì không? Bạn cho mình xin ý kiến nhé
Hên sui thì nhận thấy kết quả sai nếu thay đổi it.Mà code viết kiểu này cứ như đi ngược.Chạy tốn vòng lặp hơn.Code chỉ đúng duy nhất 1 trường hợp: Chạy lần đầu và dữ liệu ở Sheet (Công tháng 02) không đổi.
Nếu thêm dữ liệu ở Sheet (Công tháng 02) rồi chạy code lần kế tiếp thì không đúng.
Cháu chỉ thấy thắc mắc thế thôi. Như chú viết và chỉ điểm như vậy cũng có cái hay mà. tự dưng nhìn Dic nó tách riêng 1 sub chưa quen lắm. Hihi
Tôi sử dụng dic khá thành thạo nhưng hiếm khi tách riêng ra như thế này. Dic chỉ cần 1s để nạp dữ liệu. Viết rõ ràng sẽ dễ dàng cho việc sửa code khi cần thiết.
Code chỉ đúng duy nhất 1 trường hợp: Chạy lần đầu và dữ liệu ở Sheet (Công tháng 02) không đổi.
Nếu thêm dữ liệu ở Sheet (Công tháng 02) rồi chạy code lần kế tiếp thì không đúng.
Tôi tin là mọi người đều đã đọc bài này:Hên sui thì nhận thấy kết quả sai nếu thay đổi it.Mà code viết kiểu này cứ như đi ngược.Chạy tốn vòng lặp hơn.
Bạn cóp cái code đó ra đây, cả hàm lẫn code gọi nó, thì có thể tôi sẽ giải thích tại sao nó nên tách riêng.Cháu chỉ thấy thắc mắc thế thôi. Như chú viết và chỉ điểm như vậy cũng có cái hay mà. tự dưng nhìn Dic nó tách riêng 1 sub chưa quen lắm. Hihi
Xin phép chú @HUONGHCKT nhé. Tại muốn nghe và hiểu xem cụ thể cái được và mất nếu tách riêng code của Dic ra nó như thế nào? Có gì chú bỏ qua nhéBạn cóp cái code đó ra đây, cả hàm lẫn code gọi nó, thì có thể tôi sẽ giải thích tại sao nó nên tách riêng.
Option Explicit
Public Result(), Dic As Object
Sub Add_Dic()
Dim i&, j&, t&, Lr&
Dim Arr(), Key
Dim Ws As Worksheet
Set Ws = Sheets("Công tháng 02")
Lr = Ws.Cells(Rows.Count, "B").End(xlUp).Row
If Lr < 2 Then Exit Sub
Arr = Ws.Range("A2:AG" & Lr).Value
Set Dic = CreateObject("Scripting.Dictionary")
ReDim Result(1 To UBound(Arr), 1 To 2)
For i = 1 To UBound(Arr)
Key = Arr(i, 3) & "#" & Arr(i, 2)
If Not Dic.exists(Key) Then
t = t + 1: Dic.Add (Key), t
Result(t, 1) = Key
Result(t, 2) = Arr(i, 33)
End If
Next i
End Sub
Sub KimThoa89()
Dim i&, j&, t&, Lr&
Dim Arr(), Res(), Temp
Dim Ws As Worksheet
Set Ws = Sheets("Check")
Lr = Ws.Cells(Rows.Count, "B").End(xlUp).Row
If Lr < 2 Then Exit Sub
If Dic Is Nothing Then Add_Dic
Arr = Ws.Range("A1:AN" & Lr).Value
ReDim Res(1 To UBound(Arr), 1 To 34)
Ws.Range("H2:H" & Lr).FormulaR1C1 = _
"=NETWORKDAYS.INTL(RC[-2],RC[-1],""0000001"",{""2022/1/31"";""2022/2/4""})"
For i = 2 To UBound(Arr)
'Res(i, 1) = Application.WorksheetFunction.NetworkDays(Arr(i, 6), Arr(i, 7), 1, Holiday1, Holiday2)
Res(i - 1, 2) = Arr(i, 6)
Res(i - 1, 3) = Arr(i, 7)
For j = 13 To 40
Temp = Arr(i, 2) & "#" & Arr(1, j)
If Dic.exists(Temp) Then Res(i - 1, j - 8) = Result(Dic.Item(Temp), 2)
Next j
Next i
Ws.Range("I2").Resize(i - 1, 34) = Res
MsgBox "Xong"
End Sub
Như bạn @befaint nhận xét, bạn nên thêm sự kiện khi dữ liệu sheet công tháng 2 thay đổi cần chay lại sub Add_DicXin phép chú @HUONGHCKT nhé. Tại muốn nghe và hiểu xem cụ thể cái được và mất nếu tách riêng code của Dic ra nó như thế nào? Có gì chú bỏ qua nhé
@VetMini Nhờ chú chỉ dạy thêm ạ.
Đây là code nạp Dic
Và đây là code sử dụng nó ạMã:Option Explicit Public Result(), Dic As Object Sub Add_Dic() Dim i&, j&, t&, Lr& Dim Arr(), Key Dim Ws As Worksheet Set Ws = Sheets("Công tháng 02") Lr = Ws.Cells(Rows.Count, "B").End(xlUp).Row If Lr < 2 Then Exit Sub Arr = Ws.Range("A2:AG" & Lr).Value Set Dic = CreateObject("Scripting.Dictionary") ReDim Result(1 To UBound(Arr), 1 To 2) For i = 1 To UBound(Arr) Key = Arr(i, 3) & "#" & Arr(i, 2) If Not Dic.exists(Key) Then t = t + 1: Dic.Add (Key), t Result(t, 1) = Key Result(t, 2) = Arr(i, 33) End If Next i End Sub
Cháu xin lắng nghe và cám ơn trước ạMã:Sub KimThoa89() Dim i&, j&, t&, Lr& Dim Arr(), Res(), Temp Dim Ws As Worksheet Set Ws = Sheets("Check") Lr = Ws.Cells(Rows.Count, "B").End(xlUp).Row If Lr < 2 Then Exit Sub If Dic Is Nothing Then Add_Dic Arr = Ws.Range("A1:AN" & Lr).Value ReDim Res(1 To UBound(Arr), 1 To 34) Ws.Range("H2:H" & Lr).FormulaR1C1 = _ "=NETWORKDAYS.INTL(RC[-2],RC[-1],""0000001"",{""2022/1/31"";""2022/2/4""})" For i = 2 To UBound(Arr) 'Res(i, 1) = Application.WorksheetFunction.NetworkDays(Arr(i, 6), Arr(i, 7), 1, Holiday1, Holiday2) Res(i - 1, 2) = Arr(i, 6) Res(i - 1, 3) = Arr(i, 7) For j = 13 To 40 Temp = Arr(i, 2) & "#" & Arr(1, j) If Dic.exists(Temp) Then Res(i - 1, j - 8) = Result(Dic.Item(Temp), 2) Next j Next i Ws.Range("I2").Resize(i - 1, 34) = Res MsgBox "Xong" End Sub
Có chứ anh, trong file gửi kèm đã có code bắt sự kiện ở Sheet Công nợ tháng 2 rồi màNhư bạn @befaint nhận xét, bạn nên thêm sự kiện khi dữ liệu sheet công tháng 2 thay đổi cần chay lại sub Add_Dic
Với bài nầy tách add dic thành sub riêng không thực sự cần thiết
Option Explicit
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Row >= 2 Then
If Target.Column = 2 Or Target.Column = 3 Or Target.Column = 40 Then Call Add_Dic
End If
End Sub
.....
Res(k,1)= Application.WorksheetFunction.NetworkDays.INTL(Arr(i, 6), Arr(i, 7), 1, Holiday1, Holiday2)
.....
Thử bỏ .INTLCó chứ anh, trong file gửi kèm đã có code bắt sự kiện ở Sheet Công nợ tháng 2 rồi mà
Nhân tiện đây xin hỏi các anh đã ghé qua là khi gọi hàm NetworkDays.INTL của Excel thì đề báo lỗi, cụ thể như sau:Mã:Option Explicit Private Sub Worksheet_Change(ByVal Target As Range) If Target.Row >= 2 Then If Target.Column = 2 Or Target.Column = 3 Or Target.Column = 40 Then Call Add_Dic End If End Sub
Với Arr(i,6) và Arr(i,7) là hai phần tử có định dạng ngày tháng năm, Hai biến Holiday1, holiday2 được khai báo là Varial, Số 1 trong hàm lúc đầu là "0000001"> Xin các anh lời chỉ dẫn là cần viết thế nào cho đúng để không vấp lỗi.Mã:..... Res(k,1)= Application.WorksheetFunction.NetworkDays.INTL(Arr(i, 6), Arr(i, 7), 1, Holiday1, Holiday2) .....
Trân trọng cảm ơn.