tangoctuan
Thành viên hoạt động
- Tham gia
- 22/4/08
- Bài viết
- 153
- Được thích
- 19
Oh sr bạn, đã hiểu vì sao rồi, không được để trống cột stt. Hi. Cám ơn bạn nhiều, mình đã dùng được rồi.
Bạn ơi chỉnh lại giúp mình chỗ cột "Tổng thời gian chạy máy trong ngày" với, nó là giá trị tổng thời gian của tất cả các dòng trong ngày đó, chứ không phải giá trị thời gian của riêng dòng đó à. Mình làm tay như trong file để bạn hiểu ý mình hơn. Bạn xem lại giúp mình nhé.Chạy code
Trong ngày chạy máy bị trùng thời gian, công hết hay loại trùng?Bạn ơi chỉnh lại giúp mình chỗ cột "Tổng thời gian chạy máy trong ngày" với, nó là giá trị tổng thời gian của tất cả các dòng trong ngày đó, chứ không phải giá trị thời gian của riêng dòng đó à. Mình làm tay như trong file để bạn hiểu ý mình hơn. Bạn xem lại giúp mình nhé.
Với ngày chạy máy bị trùng thời gian thì vẫn cộng lại hết bạn à.Trong ngày chạy máy bị trùng thời gian, công hết hay loại trùng?
Chỉnh codeVới ngày chạy máy bị trùng thời gian thì vẫn cộng lại hết bạn à.
Sub ThuTu()
Dim sArr(), Res(), Arr(), Arr2(), S, Dic As Object, iKey$
Dim eRow&, sRow&, i&, r&, d As Double
Dim May$, fTime, eTime, fDate&, eDate&
With Sheets("Sheet4")
eRow = .Range("A" & Rows.Count).End(xlUp).Row
If eRow < 3 Then MsgBox ("Khong co du lieu"): Exit Sub
Application.ScreenUpdating = False
.Range("A2:D" & eRow).Sort .[B2], 1, .[C2], , 1, Header:=xlYes
sArr = .Range("B2:D" & eRow).Value
End With
sRow = UBound(sArr)
Set Dic = CreateObject("scripting.dictionary")
ReDim Res(2 To sRow, 1 To 2)
For i = 2 To sRow
May = sArr(i, 1)
fDate = DateValue(sArr(i, 2)): eDate = DateValue(sArr(i, 3))
If eDate >= fDate Then
ReDim Arr(fDate To eDate)
ReDim Arr2(fDate To eDate)
For r = fDate To eDate
If r > fDate Then fTime = r Else fTime = sArr(i, 2)
If r < eDate Then eTime = r + 1 Else eTime = sArr(i, 3)
d = Round((eTime - fTime) * 1440, 2)
iKey = sArr(i, 1) & "#" & r
If Dic.exists(iKey) = False Then
Dic.Add iKey, Array(1, d)
Else
S = Dic.Item(iKey)
S(0) = S(0) + 1
S(1) = S(1) + d
Dic.Item(iKey) = S
End If
If fDate = eDate Then
Arr(r) = Dic.Item(iKey)(0)
Arr2(r) = iKey
Else
Arr(r) = Dic.Item(iKey)(0) & " (" & Format(r, "dd/mm") & ")"
Arr2(r) = iKey & " (" & Format(r, "dd/mm") & ")"
End If
Next r
Res(i, 1) = Join(Arr, "; ")
Res(i, 2) = Join(Arr2, "; ")
End If
Next i
For i = 2 To sRow
fDate = DateValue(sArr(i, 2)): eDate = DateValue(sArr(i, 3))
If eDate >= fDate Then
For r = fDate To eDate
iKey = sArr(i, 1) & "#" & r
Res(i, 2) = Replace(Res(i, 2), iKey, Dic.Item(iKey)(1))
Next r
End If
Next i
With Sheets("Sheet4")
.Range("E3").Resize(sRow - 1, 2) = Res
.Range("A2:F" & eRow).Sort .[A2], 1, Header:=xlYes
End With
Application.ScreenUpdating = True
End Sub
Đẹp quá. Cảm ơn bạn nhé.Chỉnh code
Bạn ơi cho mình hỏi chút, mình chạy vba ra kết quả như file đính kèm. Kết quả ô P10701 lớn hơn rất nhiều so với kết quả ở ô Q10701 (mà đúng ra phải tương đương, kết quả cột P với các giá trị thấp đều rất chuẩn so với cột Q tương ứng). Nhờ bạn xem hộ vì sao với? Mình đang suy đoán có phải do 1 cell bị giới hạn ký tự nên không list được hết không nhỉ?Chỉnh code
Trong code có lệnhBạn ơi cho mình hỏi chút, mình chạy vba ra kết quả như file đính kèm. Kết quả ô P10701 lớn hơn rất nhiều so với kết quả ở ô Q10701 (mà đúng ra phải tương đương, kết quả cột P với các giá trị thấp đều rất chuẩn so với cột Q tương ứng). Nhờ bạn xem hộ vì sao với? Mình đang suy đoán có phải do 1 cell bị giới hạn ký tự nên không list được hết không nhỉ?
Nhờ bạn xem hộ thêm 1 vấn đề này nữa với, cùng vba đó, mình chạy cho 2 tập data: 1 tập 49k dòng, 1 tập 11k dòng (nằm trong (thuộc) tập 49k dòng) => Thì kết quả trả về ở cột P ở mỗi file lại khác nhau? Trong khi đúng ra nó phải như nhau vì thuật toán check ở cột P chỉ phụ thuộc vào cột B (khi cùng giá trị ở cột B thì mới xét "khác trạm, khác máy"). File 11k là tập con của file 49k nên cột P đối với cùng 1 STT phải như nhau.Chỉnh code
Code nhầm vị trí lệnh Exit forNhờ bạn xem hộ thêm 1 vấn đề này nữa với, cùng vba đó, mình chạy cho 2 tập data: 1 tập 49k dòng, 1 tập 11k dòng (nằm trong (thuộc) tập 49k dòng) => Thì kết quả trả về ở cột P ở mỗi file lại khác nhau? Trong khi đúng ra nó phải như nhau vì thuật toán check ở cột P chỉ phụ thuộc vào cột B (khi cùng giá trị ở cột B thì mới xét "khác trạm, khác máy"). File 11k là tập con của file 49k nên cột P đối với cùng 1 STT phải như nhau.
Trong file đính kèm mình filter sẵn ví dụ 1 STT bị như thế. Vậy rất mong bạn xem giúp mình là bị sao với?
Sub XetTrung()
Dim sArr(), Res()
Dim eRow&, sRow&, j&, i&, r&, tmp$, d As Double
Dim stt&, kVuc$, Tram$, May$, fTime, eTime
Application.ScreenUpdating = False
With Sheets("Check")
eRow = .Range("B" & Rows.Count).End(xlUp).Row
If eRow < 3 Then MsgBox ("Khong co du lieu"): Exit Sub
.Range("A2:R" & eRow).Sort .[E2], 1, Header:=xlYes
sArr = .Range("A3:F" & eRow).Value
End With
sRow = UBound(sArr)
ReDim Res(1 To sRow, 1 To 12)
For i = 1 To sRow - 1
stt = sArr(i, 1): kVuc = sArr(i, 2): Tram = sArr(i, 3)
May = sArr(i, 4): fTime = sArr(i, 5): eTime = sArr(i, 6)
If fTime < eTime Then
For r = i + 1 To sRow
If sArr(r, 5) < eTime Then
If sArr(r, 5) < sArr(r, 6) Then
If sArr(r, 3) = Tram Then j = 1 Else j = 7
If sArr(r, 4) <> May Then j = j + 3
If sArr(r, 2) = kVuc Or j <> 10 Then
Res(i, j) = Res(i, j) + 1
Res(r, j) = Res(r, j) + 1
If Len(Res(i, j + 1)) Then
If Len(Res(i, j + 1)) < 250 Then Res(i, j + 1) = Res(i, j + 1) & ", " & sArr(r, 1) 'Gioi han so ky tu ket qua
Else
Res(i, j + 1) = sArr(r, 1)
End If
If Len(Res(r, j + 1)) Then
If Len(Res(r, j + 1)) < 250 Then Res(r, j + 1) = Res(r, j + 1) & ", " & sArr(i, 1)
Else
Res(r, j + 1) = sArr(i, 1)
End If
If sArr(r, 6) < eTime Then d = sArr(r, 6) - sArr(r, 5) Else d = eTime - sArr(r, 5)
Res(i, j + 2) = Res(i, j + 2) + d
Res(r, j + 2) = Res(r, j + 2) + d
If d < 0 Then
a = 1
End If
End If
End If
Else
Exit For
End If
Next r
End If
Next i
With Sheets("Check")
.Range("G3").Resize(sRow, 12).Value = Res
.Range("A2:R" & eRow).Sort .[A2], 1, Header:=xlYes
End With
Erase sArr: Erase Res
Application.ScreenUpdating = True
End Sub
Tks bạn nhiều!Code nhầm vị trí lệnh Exit for
Bạn ơi mình chạy code cho 1 trường hợp (như file) thì thấy có 1 vấn đề như này.Code nhầm vị trí lệnh Exit for
End IfMã:Sub XetTrung() Dim sArr(), Res() Dim eRow&, sRow&, j&, i&, r&, tmp$, d As Double Dim stt&, kVuc$, Tram$, May$, fTime, eTime Application.ScreenUpdating = False With Sheets("Check") eRow = .Range("B" & Rows.Count).End(xlUp).Row If eRow < 3 Then MsgBox ("Khong co du lieu"): Exit Sub .Range("A2:R" & eRow).Sort .[E2], 1, Header:=xlYes sArr = .Range("A3:F" & eRow).Value End With sRow = UBound(sArr) ReDim Res(1 To sRow, 1 To 12) For i = 1 To sRow - 1 stt = sArr(i, 1): kVuc = sArr(i, 2): Tram = sArr(i, 3) May = sArr(i, 4): fTime = sArr(i, 5): eTime = sArr(i, 6) If fTime < eTime Then For r = i + 1 To sRow If sArr(r, 5) < eTime Then If sArr(r, 5) < sArr(r, 6) Then If sArr(r, 3) = Tram Then j = 1 Else j = 7 If sArr(r, 4) <> May Then j = j + 3 If sArr(r, 2) = kVuc Or j <> 10 Then Res(i, j) = Res(i, j) + 1 Res(r, j) = Res(r, j) + 1 If Len(Res(i, j + 1)) Then If Len(Res(i, j + 1)) < 250 Then Res(i, j + 1) = Res(i, j + 1) & ", " & sArr(r, 1) 'Gioi han so ky tu ket qua Else Res(i, j + 1) = sArr(r, 1) End If If Len(Res(r, j + 1)) Then If Len(Res(r, j + 1)) < 250 Then Res(r, j + 1) = Res(r, j + 1) & ", " & sArr(i, 1) Else Res(r, j + 1) = sArr(i, 1) End If If sArr(r, 6) < eTime Then d = sArr(r, 6) - sArr(r, 5) Else d = eTime - sArr(r, 5) Res(i, j + 2) = Res(i, j + 2) + d Res(r, j + 2) = Res(r, j + 2) + d If d < 0 Then a = 1 End If End If End If Else Exit For End If Next r End If Next i With Sheets("Check") .Range("G3").Resize(sRow, 12).Value = Res .Range("A2:R" & eRow).Sort .[A2], 1, Header:=xlYes End With Erase sArr: Erase Res Application.ScreenUpdating = True End Sub
Else
Exit For
End If
Next r
End If
Next i
Số 488 là số lần trùng với dòng khác không phân biệt cùng máy hay khác máyBạn ơi mình chạy code cho 1 trường hợp (như file) thì thấy có 1 vấn đề như này.
Tổng số máy ở cột D chỉ là 37, nhưng kết quả trùng trạm khác máy ở J3 lại là 488. Đúng ra thì KQ luôn phải nhỏ hơn 37 (số giá trị khác nhau duy nhất ở cột D).
View attachment 227797
Mình gửi file chạy dữ liệu. Nhờ bạn xem giúp với.
Vậy riêng chỗ này nhờ bạn code lại giúp để phân biệt chỉ tính khác máy thôi với. Trùng trạm và khác máy (có giao trong khoảng thời gian đó).Số 488 là số lần trùng với dòng khác không phân biệt cùng máy hay khác máy
Kiểm tra lạiVậy riêng chỗ này nhờ bạn code lại giúp để phân biệt chỉ tính khác máy thôi với. Trùng trạm và khác máy (có giao trong khoảng thời gian đó).
Tương tự như thế, cột M cũng chỉ tính khác trạm.
Sub XetTrung()
Dim sArr(), Res(), Dic As Object
Dim eRow&, sRow&, j&, i&, r&, tmp$, d As Double
Dim stt$, stt2$, kVuc$, Tram$, May$, fTime, eTime
Application.ScreenUpdating = False
With Sheets("Check")
eRow = .Range("B" & Rows.Count).End(xlUp).Row
If eRow < 3 Then MsgBox ("Khong co du lieu"): Exit Sub
.Range("A2:R" & eRow).Sort .[E2], 1, Header:=xlYes
sArr = .Range("A3:F" & eRow).Value
End With
Set Dic = CreateObject("scripting.dictionary")
sRow = UBound(sArr)
ReDim Res(1 To sRow, 1 To 12)
For i = 1 To sRow - 1
stt = sArr(i, 1): kVuc = sArr(i, 2): Tram = sArr(i, 3)
May = sArr(i, 4): fTime = sArr(i, 5): eTime = sArr(i, 6)
If fTime < eTime Then
For r = i + 1 To sRow
If sArr(r, 5) < eTime Then
If sArr(r, 5) < sArr(r, 6) Then
If sArr(r, 3) = Tram Then j = 1 Else j = 7
If sArr(r, 4) <> May Then j = j + 3
stt2 = sArr(r, 1)
If sArr(r, 2) = kVuc Or j <> 10 Then
If j = 4 Then
tmp = Dic.Item(stt) & ","
If InStr(1, tmp, "," & sArr(r, 4) & ",") = 0 Then
Res(i, j) = Res(i, j) + 1
Dic.Item(stt) = Dic.Item(stt) & "," & sArr(r, 4)
End If
tmp = Dic.Item(stt2) & ","
If InStr(1, tmp, "," & sArr(i, 4) & ",") = 0 Then
Res(r, j) = Res(r, j) + 1
Dic.Item(stt2) = Dic.Item(stt2) & "," & sArr(i, 4)
End If
ElseIf j = 7 Then
tmp = Dic.Item(stt) & ","
If InStr(1, tmp, "," & sArr(r, 3) & ",") = 0 Then
Res(i, j) = Res(i, j) + 1
Dic.Item(stt) = Dic.Item(stt) & "," & sArr(r, 3)
End If
tmp = Dic.Item(stt2) & ","
If InStr(1, tmp, "," & sArr(i, 3) & ",") = 0 Then
Res(r, j) = Res(r, j) + 1
Dic.Item(stt2) = Dic.Item(stt2) & "," & sArr(i, 3)
End If
Else
Res(i, j) = Res(i, j) + 1
Res(r, j) = Res(r, j) + 1
End If
If Len(Res(i, j + 1)) Then
If Len(Res(i, j + 1)) < 250 Then Res(i, j + 1) = Res(i, j + 1) & ", " & sArr(r, 1) 'Gioi han so ky tu ket qua
Else
Res(i, j + 1) = sArr(r, 1)
End If
If Len(Res(r, j + 1)) Then
If Len(Res(r, j + 1)) < 250 Then Res(r, j + 1) = Res(r, j + 1) & ", " & sArr(i, 1)
Else
Res(r, j + 1) = sArr(i, 1)
End If
If sArr(r, 6) < eTime Then d = sArr(r, 6) - sArr(r, 5) Else d = eTime - sArr(r, 5)
Res(i, j + 2) = Res(i, j + 2) + d
Res(r, j + 2) = Res(r, j + 2) + d
End If
End If
Else
Exit For
End If
Next r
End If
Next i
With Sheets("Check")
.Range("G3").Resize(sRow, 12).Value = Res
.Range("A2:R" & eRow).Sort .[A2], 1, Header:=xlYes
End With
Erase sArr: Erase Res
Application.ScreenUpdating = True
End Sub
Tuyệt vời, một lần nữa cảm ơn bạn rất nhiều và chúc bạn sức khỏe!Kiểm tra lại
Mã:Sub XetTrung() Dim sArr(), Res(), Dic As Object Dim eRow&, sRow&, j&, i&, r&, tmp$, d As Double Dim stt$, stt2$, kVuc$, Tram$, May$, fTime, eTime Application.ScreenUpdating = False With Sheets("Check") eRow = .Range("B" & Rows.Count).End(xlUp).Row If eRow < 3 Then MsgBox ("Khong co du lieu"): Exit Sub .Range("A2:R" & eRow).Sort .[E2], 1, Header:=xlYes sArr = .Range("A3:F" & eRow).Value End With Set Dic = CreateObject("scripting.dictionary") sRow = UBound(sArr) ReDim Res(1 To sRow, 1 To 12) For i = 1 To sRow - 1 stt = sArr(i, 1): kVuc = sArr(i, 2): Tram = sArr(i, 3) May = sArr(i, 4): fTime = sArr(i, 5): eTime = sArr(i, 6) If fTime < eTime Then For r = i + 1 To sRow If sArr(r, 5) < eTime Then If sArr(r, 5) < sArr(r, 6) Then If sArr(r, 3) = Tram Then j = 1 Else j = 7 If sArr(r, 4) <> May Then j = j + 3 stt2 = sArr(r, 1) If sArr(r, 2) = kVuc Or j <> 10 Then If j = 4 Then tmp = Dic.Item(stt) & "," If InStr(1, tmp, "," & sArr(r, 4) & ",") = 0 Then Res(i, j) = Res(i, j) + 1 Dic.Item(stt) = Dic.Item(stt) & "," & sArr(r, 4) End If tmp = Dic.Item(stt2) & "," If InStr(1, tmp, "," & sArr(i, 4) & ",") = 0 Then Res(r, j) = Res(r, j) + 1 Dic.Item(stt2) = Dic.Item(stt2) & "," & sArr(i, 4) End If ElseIf j = 7 Then tmp = Dic.Item(stt) & "," If InStr(1, tmp, "," & sArr(r, 3) & ",") = 0 Then Res(i, j) = Res(i, j) + 1 Dic.Item(stt) = Dic.Item(stt) & "," & sArr(r, 3) End If tmp = Dic.Item(stt2) & "," If InStr(1, tmp, "," & sArr(i, 3) & ",") = 0 Then Res(r, j) = Res(r, j) + 1 Dic.Item(stt2) = Dic.Item(stt2) & "," & sArr(i, 3) End If Else Res(i, j) = Res(i, j) + 1 Res(r, j) = Res(r, j) + 1 End If If Len(Res(i, j + 1)) Then If Len(Res(i, j + 1)) < 250 Then Res(i, j + 1) = Res(i, j + 1) & ", " & sArr(r, 1) 'Gioi han so ky tu ket qua Else Res(i, j + 1) = sArr(r, 1) End If If Len(Res(r, j + 1)) Then If Len(Res(r, j + 1)) < 250 Then Res(r, j + 1) = Res(r, j + 1) & ", " & sArr(i, 1) Else Res(r, j + 1) = sArr(i, 1) End If If sArr(r, 6) < eTime Then d = sArr(r, 6) - sArr(r, 5) Else d = eTime - sArr(r, 5) Res(i, j + 2) = Res(i, j + 2) + d Res(r, j + 2) = Res(r, j + 2) + d End If End If Else Exit For End If Next r End If Next i With Sheets("Check") .Range("G3").Resize(sRow, 12).Value = Res .Range("A2:R" & eRow).Sort .[A2], 1, Header:=xlYes End With Erase sArr: Erase Res Application.ScreenUpdating = True End Sub
Bạn ơi xem giúp hộ mình file dữ liệu này chạy với code này thì báo lỗi không biết là lỗi gì nhỉ?Chỉnh code
Mã:Sub ThuTu() Dim sArr(), Res(), Arr(), Arr2(), S, Dic As Object, iKey$ Dim eRow&, sRow&, i&, r&, d As Double Dim May$, fTime, eTime, fDate&, eDate& With Sheets("Sheet4") eRow = .Range("A" & Rows.Count).End(xlUp).Row If eRow < 3 Then MsgBox ("Khong co du lieu"): Exit Sub Application.ScreenUpdating = False .Range("A2:D" & eRow).Sort .[B2], 1, .[C2], , 1, Header:=xlYes sArr = .Range("B2:D" & eRow).Value End With sRow = UBound(sArr) Set Dic = CreateObject("scripting.dictionary") ReDim Res(2 To sRow, 1 To 2) For i = 2 To sRow May = sArr(i, 1) fDate = DateValue(sArr(i, 2)): eDate = DateValue(sArr(i, 3)) If eDate >= fDate Then ReDim Arr(fDate To eDate) ReDim Arr2(fDate To eDate) For r = fDate To eDate If r > fDate Then fTime = r Else fTime = sArr(i, 2) If r < eDate Then eTime = r + 1 Else eTime = sArr(i, 3) d = Round((eTime - fTime) * 1440, 2) iKey = sArr(i, 1) & "#" & r If Dic.exists(iKey) = False Then Dic.Add iKey, Array(1, d) Else S = Dic.Item(iKey) S(0) = S(0) + 1 S(1) = S(1) + d Dic.Item(iKey) = S End If If fDate = eDate Then Arr(r) = Dic.Item(iKey)(0) Arr2(r) = iKey Else Arr(r) = Dic.Item(iKey)(0) & " (" & Format(r, "dd/mm") & ")" Arr2(r) = iKey & " (" & Format(r, "dd/mm") & ")" End If Next r Res(i, 1) = Join(Arr, "; ") Res(i, 2) = Join(Arr2, "; ") End If Next i For i = 2 To sRow fDate = DateValue(sArr(i, 2)): eDate = DateValue(sArr(i, 3)) If eDate >= fDate Then For r = fDate To eDate iKey = sArr(i, 1) & "#" & r Res(i, 2) = Replace(Res(i, 2), iKey, Dic.Item(iKey)(1)) Next r End If Next i With Sheets("Sheet4") .Range("E3").Resize(sRow - 1, 2) = Res .Range("A2:F" & eRow).Sort .[A2], 1, Header:=xlYes End With Application.ScreenUpdating = True End Sub