doatmenhhon
Thành viên tiêu biểu

- Tham gia
- 20/4/15
- Bài viết
- 525
- Được thích
- 682
Thầy ndu code của em vẫn còn sai tung tóe. Thầy thử xem có được ko?
Thầy ndu code của em vẫn còn sai tung tóe. Thầy thử xem có được ko?
Sub Button5_Click()
Dim a, tmp
Dim i As Long, ii As Long, n As Long
Dim rng As Range, dic As Object
Set rng = ActiveSheet.UsedRange
With rng
For i = 1 To .Columns.Count
a = .Columns(i).Value
If IsArray(a) Then
[COLOR=#ff0000]Set dic = CreateObject("Scripting.Dictionary")
dic.CompareMode = vbTextCompare[/COLOR]
ReDim b(1 To UBound(a), 1 To 1)
[COLOR=#ff0000] n = 0[/COLOR]
For ii = 1 To UBound(a)
tmp = CStr(a(ii, 1))
If Len(tmp) Then
If Not dic.Exists(tmp) Then
n = n + 1
dic.Add tmp, n
b(n, 1) = tmp
End If
End If
Next
If n Then .Columns(i).Value = b
End If
Next
End With
End Sub
Em gửi file mẫu đây ạ, dữ liệu không chính xác nhưng kiểu dữ liệu thì đúng ạ.Vậy thì bạn vui lòng đưa dữ liệu gần giống thật nhất lên đây, nêu rõ kết quả lọc đặt tại đâu nhé!
Bởi với dữ liệu đơn sơ như ở bài 2 thì tôi tin chắc rằng sau khi viết code xong, bạn ráp vào file thật không được lại chạy lên hỏi tiếp cho mà coi
Em mới thử có bao nhiêu cột được hếtSửa code của bạn:
Mã:Sub Button5_Click() Dim a, tmp Dim i As Long, ii As Long, n As Long Dim rng As Range, dic As Object Set rng = ActiveSheet.UsedRange With rng For i = 1 To .Columns.Count a = .Columns(i).Value If IsArray(a) Then [COLOR=#ff0000]Set dic = CreateObject("Scripting.Dictionary") dic.CompareMode = vbTextCompare[/COLOR] ReDim b(1 To UBound(a), 1 To 1) [COLOR=#ff0000] n = 0[/COLOR] For ii = 1 To UBound(a) tmp = CStr(a(ii, 1)) If Len(tmp) Then If Not dic.Exists(tmp) Then n = n + 1 dic.Add tmp, n b(n, 1) = tmp End If End If Next If n Then .Columns(i).Value = b End If Next End With End Sub
Em gửi file mẫu đây ạ, dữ liệu không chính xác nhưng kiểu dữ liệu thì đúng ạ.
Thầy xem giúp em với ạ.
Nhưng khu vực lọc ra kết quả bạn cho sẵn 10 dòng. Sao bạn biết chắc kết quả chỉ 10 dòng? Lỡ kết quả 20 dòng thì sao?Lọc hết Cod và Qty Exp của ngày thường
-----------------------
Nói thêm: Trong file của bạn, tại cell B70 tôi thấy bạn ghi:
Nhưng khu vực lọc ra kết quả bạn cho sẵn 10 dòng. Sao bạn biết chắc kết quả chỉ 10 dòng? Lỡ kết quả 20 dòng thì sao?
Thấy chưa! Dữ liệu mới đưa lên chẳng giống chút nào so với yêu cầu ban đầu
Bài này mà làm cũng không phải chuyện dễ đâu à nghen
Mời các cao thủ thử sức
-----------------------
Nói thêm: Trong file của bạn, tại cell B70 tôi thấy bạn ghi:
Nhưng khu vực lọc ra kết quả bạn cho sẵn 10 dòng. Sao bạn biết chắc kết quả chỉ 10 dòng? Lỡ kết quả 20 dòng thì sao?
Public Sub hello()
Dim rgName As String, arr As Variant, Dic As Object, tempKey As Variant
Dim r As Long, c As Long, preDay As Byte, dArr As Variant, arRow(1 To 4) As Long
Set Dic = CreateObject("Scripting.Dictionary")
With Sheet18
rgName = .Range("B10").CurrentRegion.Address
arr = .Range("C10" & Mid(rgName, InStr(rgName, ":"))).Value
ReDim dArr(1 To 40, 1 To UBound(arr, 2) - 1)
For c = 2 To UBound(arr, 2) Step 1
arr(1, c) = IIf(Len(arr(1, c)) > 0, Weekday(arr(1, c), vbMonday), preDay)
preDay = arr(1, c)
arRow(1) = 0: arRow(2) = 10: arRow(3) = 20: arRow(4) = 30
Dic.RemoveAll
For r = 3 To UBound(arr) Step 1
If Len(arr(r, c)) > 0 Then
tempKey = arr(r, 1) & ";" & arr(r, c)
If Not Dic.exists(tempKey) Then
Dic(tempKey) = 1
If arr(r, 1) = "Exp" Then
If arr(1, c) < 6 Then
arRow(1) = WorksheetFunction.Min(arRow(1) + 1, 10)
dArr(arRow(1), c - 1) = arr(r, c)
End If
ElseIf arr(r, 1) = "Imp" Then
If arr(1, c) < 6 Then
arRow(2) = WorksheetFunction.Min(arRow(2) + 1, 20)
dArr(arRow(2), c - 1) = arr(r, c)
ElseIf arr(1, c) = 6 Then
arRow(3) = WorksheetFunction.Min(arRow(3) + 1, 30)
dArr(arRow(3), c - 1) = arr(r, c)
Else
arRow(4) = WorksheetFunction.Min(arRow(4) + 1, 40)
dArr(arRow(4), c - 1) = arr(r, c)
End If
End If
End If
End If
Next
Next
.Range("D" & .Range("D" & Mid(rgName, InStrRev(rgName, "$") + 1)).End(xlDown).Row + 1) _
.Resize(40, UBound(dArr, 2)).Value = dArr
End With
End Sub
=
dòng sau khả năng của em chưa hiểu tới...Nếu được xin anh chỉ dùm
dic.CompareMode = vbTextCompare
Em cảm ơn
Sub Test_1()
Dim dic As Object
Set dic = CreateObject("Scripting.Dictionary")
dic.Add "a", ""
dic.Add "A", ""
End Sub
Sub Test_2()
Dim dic As Object
Set dic = CreateObject("Scripting.Dictionary")
[COLOR=#ff0000]dic.CompareMode = vbTextCompare[/COLOR]
dic.Add "a", ""
dic.Add "A", ""
End Sub
Thanks bác, chuẩn rồi bác ơi. Nhưng e có thắc mắc chút là sao nó lại có cái dòng ô mang giá trị 118 ở bên cột Cod như hình thế ah? Bác xem bỏ giúp em với.tính đi rồi mà nghe thầy NDU quảng cáo dữ quá , quay lại đu dây tí . hi hi
Mã:Public Sub hello() Dim rgName As String, arr As Variant, Dic As Object, tempKey As Variant Dim r As Long, c As Long, preDay As Byte, dArr As Variant, arRow(1 To 4) As Long Set Dic = CreateObject("Scripting.Dictionary") With Sheet18 rgName = .Range("B10").CurrentRegion.Address arr = .Range("C10" & Mid(rgName, InStr(rgName, ":"))).Value ReDim dArr(1 To 40, 1 To UBound(arr, 2) - 1) For c = 2 To UBound(arr, 2) Step 1 arr(1, c) = IIf(Len(arr(1, c)) > 0, Weekday(arr(1, c), vbMonday), preDay) preDay = arr(1, c) arRow(1) = 0: arRow(2) = 10: arRow(3) = 20: arRow(4) = 30 Dic.RemoveAll For r = 3 To UBound(arr) Step 1 If Len(arr(r, c)) > 0 Then tempKey = arr(r, 1) & ";" & arr(r, c) If Not Dic.exists(tempKey) Then Dic(tempKey) = 1 If arr(r, 1) = "Exp" Then If arr(1, c) < 6 Then arRow(1) = WorksheetFunction.Min(arRow(1) + 1, 10) dArr(arRow(1), c - 1) = arr(r, c) End If ElseIf arr(r, 1) = "Imp" Then If arr(1, c) < 6 Then arRow(2) = WorksheetFunction.Min(arRow(2) + 1, 20) dArr(arRow(2), c - 1) = arr(r, c) ElseIf arr(1, c) = 6 Then arRow(3) = WorksheetFunction.Min(arRow(3) + 1, 30) dArr(arRow(3), c - 1) = arr(r, c) Else arRow(4) = WorksheetFunction.Min(arRow(4) + 1, 40) dArr(arRow(4), c - 1) = arr(r, c) End If End If End If End If Next Next .Range("D" & .Range("D" & Mid(rgName, InStrRev(rgName, "$") + 1)).End(xlDown).Row + 1) _ .Resize(40, UBound(dArr, 2)).Value = dArr End With End Sub
Thanks bác, chuẩn rồi bác ơi. Nhưng e có thắc mắc chút là sao nó lại có cái dòng ô mang giá trị 118 ở bên cột Cod như hình thế ah? Bác xem bỏ giúp em với.
View attachment 147440
E hơi tham lam chút :
Bác có thể giúp e làm cho cái macro nó tụ chạy mà ko cần phải ấn Alt+F8 -> Run không ạ?
Bác hộ e chỉnh sột Qty ko phải là list duy nhất mà là total của từng mã ở cột Cod bên cạnh.
E thấy code của bác chạy rất nhanh. Các bác giúp e với nhé. Cảm ơn các bác nhiều ạ.
mình bị dị ứng với các thể loại cứ làm xong là bên kia thay đổi yêu cầu . nên trong vài ngày tới mình không làm đâu . bạn cứ yên tâm mà chờ thành viên khác
Cái này là do xác định mảng arr sai.Thanks bác, chuẩn rồi bác ơi. Nhưng e có thắc mắc chút là sao nó lại có cái dòng ô mang giá trị 118 ở bên cột Cod như hình thế ah? ....
arr = .Range("C10" & Mid(rgName, InStr(rgName, ":"))).Value
arr = .Range("C10:LA65").value
Chuẩn rồi bạn ơi. Thanks bạn nhé.Cái này là do xác định mảng arr sai.
mấy số đó chính là số ở dòng Summary by Day
nếu bảng tính không thay đổi về KT thì bạn có thể thay :
thành :PHP:arr = .Range("C10" & Mid(rgName, InStr(rgName, ":"))).Value
PHP:arr = .Range("C10:LA65").value
tính đi rồi mà nghe thầy NDU quảng cáo dữ quá , quay lại đu dây tí . hi hi
Mã:Public Sub hello() Dim rgName As String, arr As Variant, Dic As Object, tempKey As Variant Dim r As Long, c As Long, preDay As Byte, dArr As Variant, arRow(1 To 4) As Long Set Dic = CreateObject("Scripting.Dictionary") With [COLOR=#ff0000]Sheet18[/COLOR] rgName = .Range("B10").CurrentRegion.Address arr = .Range("C10" & Mid(rgName, InStr(rgName, ":"))).Value ReDim dArr(1 To 40, 1 To UBound(arr, 2) - 1) For c = 2 To UBound(arr, 2) Step 1 arr(1, c) = IIf(Len(arr(1, c)) > 0, Weekday(arr(1, c), vbMonday), preDay) preDay = arr(1, c) arRow(1) = 0: arRow(2) = 10: arRow(3) = 20: arRow(4) = 30 Dic.RemoveAll For r = 3 To UBound(arr) Step 1 If Len(arr(r, c)) > 0 Then tempKey = arr(r, 1) & ";" & arr(r, c) If Not Dic.exists(tempKey) Then Dic(tempKey) = 1 If arr(r, 1) = "Exp" Then If arr(1, c) < 6 Then arRow(1) = WorksheetFunction.Min(arRow(1) + 1, 10) dArr(arRow(1), c - 1) = arr(r, c) End If ElseIf arr(r, 1) = "Imp" Then If arr(1, c) < 6 Then arRow(2) = WorksheetFunction.Min(arRow(2) + 1, 20) dArr(arRow(2), c - 1) = arr(r, c) ElseIf arr(1, c) = 6 Then arRow(3) = WorksheetFunction.Min(arRow(3) + 1, 30) dArr(arRow(3), c - 1) = arr(r, c) Else arRow(4) = WorksheetFunction.Min(arRow(4) + 1, 40) dArr(arRow(4), c - 1) = arr(r, c) End If End If End If End If Next Next .Range("D" & .Range("D" & Mid(rgName, InStrRev(rgName, "$") + 1)).End(xlDown).Row + 1) _ .Resize(40, UBound(dArr, 2)).Value = dArr End With End Sub
With Sheet18
Có bác nào thử code này với file có nhiều sheet chưa ạ? mình làm trên 1 sheet thì ok. Nhưng trên nhiều sheet thì không chạy được.
Có lẽ là do dòng này (mình đoán vậy) mà ko biết sửa thế nào.
With Sheet18
Mong các bạn chỉ giúp.
Bạn có thể giúp mình chỉnh lại code chút xíu được ko? Bỏ dữ liệu bên cột số đi để mình đưa công thức tính tổng từng code bên cạnh vào. nếu bạn sửa được code để nó tự tính tổng luôn thì đẹp quá.
Thanks bạn.Có thể sửa thành : With ActiveSheet
còn cái này là tổng thế nào ?
Ý bạn là các mã cùng cột mà trùng nhau thì sum lại với nhau.Thanks bạn.
Mình up file dữ liệu mẫu, đã qua tính toán theo cách thủ công ( chưa áp code vào). Mình đã chú thích thêm trong đó rồi nhé.
Public Sub hello()
Dim arr As Variant, Dic As Object, tempKey As Variant
Dim r As Long, c As Long, preDay As Byte, dArr As Variant, arRow(1 To 4) As Long
Set Dic = CreateObject("Scripting.Dictionary")
With ActiveSheet
arr = .Range("C10:LA65").Value
ReDim dArr(1 To 40, 1 To UBound(arr, 2) - 1)
For c = 2 To UBound(arr, 2) Step 2
arr(1, c) = IIf(Len(arr(1, c)) > 0, Weekday(arr(1, c), vbMonday), preDay)
preDay = arr(1, c)
arRow(1) = 0: arRow(2) = 10: arRow(3) = 20: arRow(4) = 30
Dic.RemoveAll
For r = 3 To UBound(arr) Step 1
If Len(arr(r, c)) > 0 Then
tempKey = arr(r, 1) & ";" & arr(r, c)
If Not Dic.exists(tempKey) Then
If arr(r, 1) = "Exp" Then
If arr(1, c) < 6 Then
arRow(1) = WorksheetFunction.Min(arRow(1) + 1, 10)
Dic.Add tempKey, arRow(1)
dArr(arRow(1), c - 1) = arr(r, c)
dArr(arRow(1), c) = arr(r, c + 1)
End If
ElseIf arr(r, 1) = "Imp" Then
If arr(1, c) < 6 Then
arRow(2) = WorksheetFunction.Min(arRow(2) + 1, 20)
Dic.Add tempKey, arRow(2)
dArr(arRow(2), c - 1) = arr(r, c)
dArr(arRow(2), c) = arr(r, c + 1)
ElseIf arr(1, c) = 6 Then
arRow(3) = WorksheetFunction.Min(arRow(3) + 1, 30)
Dic.Add tempKey, arRow(3)
dArr(arRow(3), c - 1) = arr(r, c)
dArr(arRow(3), c) = arr(r, c + 1)
Else
arRow(4) = WorksheetFunction.Min(arRow(4) + 1, 40)
Dic.Add tempKey, arRow(4)
dArr(arRow(4), c - 1) = arr(r, c)
dArr(arRow(4), c) = arr(r, c + 1)
End If
End If
Else
dArr(Dic.Item(tempKey), c) = dArr(Dic.Item(tempKey), c) + arr(r, c + 1)
End If
End If
Next
Next
.Range("D70:LA109") = dArr
End With
End Sub