LamNA
Thành viên tích cực


- Tham gia
- 3/6/14
- Bài viết
- 900
- Được thích
- 727
- Giới tính
- Nam
- Nghề nghiệp
- Quản Lý Cửa Hàng
Cái này bạn dùng hàm được mà. Bạn muốn dùng code vba để làm gì?
Phần thu Macro xong tạo nút bấm em xử lý được ý em muốn nó hoàn toàn tự động cho file. HihiBạn thao tác lọc nhờ AdvancedFilter cho thật nhuyễn;
Sau đó mở bộ thu macro lên & thu các thao tác lọc nêu trên là được 90% công việc theo iêu cầu của bạn rồi.
10% còn lại nhờ Cộng đồng sẽ trao chuốt cho bạn.
File ví dụ cũng 1 phần rõ ràng rồi đó anh,Hời hợt quá! Lọc cái gì, lọc theo tiêu chí nào, kết quả lọc vứt vào đâu, và đây là file dữ liệu ảo, file thật đâu, viết code trên file ảo, rồi lại sửa tùm lum à.
Dạ đúng ý của em nếu em muốn chạy hết cột B:B , C:C: , DBạn gõ ngày vào cột A rồi enter , từ dòng 2 xuống, thì tự động cho kết quả.
Bạn xem có đúng ý không
Em nhập ngày tháng từng ô thì chạy code nhưng khi copy hay kéo xuống thì nó lại báo lỗi, nhờ anh hỗ trợ giúp em nhe
Em cám ơn
View attachment 194687
Lọc đâu mà lọc???? Rõ là đổi ngày (dd/mm/yyyy) thành ngày - tháng - năm - tuần - thứ!!!!!!!!!!!!!Rất mong anh chị hỗ trợ trường hợp này giúp em ạ
Em nhập ngày tháng từng ô thì chạy code nhưng khi copy hay kéo xuống thì nó lại báo lỗi, nhờ anh hỗ trợ giúp em nhe
Em cám ơn
Private Sub Worksheet_Change(ByVal Target As Range)
Dim rng As Range, change As Range
Set change = Intersect(Target, Range("A2:A500000"))
If Not change Is Nothing Then
Application.EnableEvents = False
Application.ScreenUpdating = False
For Each rng In change
With rng
.Offset(0, 1).Value = Format(rng, "d")
.Offset(0, 2).Value = Format(rng, "m")
.Offset(0, 3).Value = Format(rng, "yyyy")
.Offset(0, 4).Value = Format(rng, "ww")
End With
Next rng
Application.ScreenUpdating = True
Application.EnableEvents = True
End If
End Sub
Function ConvertDate2ABC(ByVal dDate As Long)
Dim a(1 To 5)
a(1) = Day(dDate)
a(2) = Month(dDate)
a(3) = Year(dDate)
' a(4) = Weekday(dDate)
a(4) = WorksheetFunction.WeekNum(dDate) 'Sửa dòng này'
a(5) = WorksheetFunction.Text(dDate, "[$-42A]dddd") 'Tiêng Viêt'
'a(5) = WorksheetFunction.Text(dDate, "dddd") 'Tiêng Anh'
ConvertDate2ABC = a
End Function
Target.Offset(0, 1).Resize(1, 5) = ConvertDate2ABC(CLng(Val(Target.Value2)))
'Hoặc theo bài trên:'
[code]
With rng
.Offset(0, 1).Resize(1, 5) = ConvertDate2ABC(CLng(Val(Target.Value2)))
End With
Rảnh nghịch tẹo...
Ở module
Ở worksheetPHP:Function ConvertDate2ABC(ByVal dDate As Long) Dim a(1 To 5) a(1) = Day(dDate) a(2) = Month(dDate) a(3) = Year(dDate) ' a(4) = Weekday(dDate) a(4) = WorksheetFunction.WeekNum(dDate) 'Sửa dòng này' a(5) = WorksheetFunction.Text(dDate, "[$-42A]dddd") 'Tiêng Viêt' 'a(5) = WorksheetFunction.Text(dDate, "dddd") 'Tiêng Anh' ConvertDate2ABC = a End Function
Mã:Target.Offset(0, 1).Resize(1, 5) = ConvertDate2ABC(CLng(Val(Target.Value2))) 'Hoặc theo bài trên:' [code] With rng .Offset(0, 1).Resize(1, 5) = ConvertDate2ABC(CLng(Val(Target.Value2))) End With
Thay bằng code mới
Mã:Private Sub Worksheet_Change(ByVal Target As Range) Dim rng As Range, change As Range Set change = Intersect(Target, Range("A2:A500000")) If Not change Is Nothing Then Application.EnableEvents = False Application.ScreenUpdating = False For Each rng In change With rng .Offset(0, 1).Value = Format(rng, "d") .Offset(0, 2).Value = Format(rng, "m") .Offset(0, 3).Value = Format(rng, "yyyy") .Offset(0, 4).Value = Format(rng, "ww") End With Next rng Application.ScreenUpdating = True Application.EnableEvents = True End If End Sub
Rảnh nghịch tẹo...
Ở module
Ở worksheetPHP:Function ConvertDate2ABC(ByVal dDate As Long) ... ConvertDate2ABC = a End Function
'Hoặc theo bài trên:'
With rng
.Offset(0, 1).Resize(1, 5) = ConvertDate2ABC(CLng(Val(Target.Value2)))
End With
Người ta không nói kéo xuống bao nhiêu nên để đề phòng kéo hàng ngàn dòng thì tôi có vd. Application.ScreenUpdating = False / True.nhưng khi copy hay kéo xuống
.Offset(0, 1).Resize(1, 5) = ConvertDate2ABC(CLng(Val(Target.Value2)))
Thêm phần Thứ vào code của batman1 , chắc lần này được rồi nghe.
Dạ em chạy code rất tốt, em cám ơn anh đã giúp đỡ
Anh có thể cho em hỏi thêm nếu em muốn tính thêm cột thứ theo Format: CN-T2-T3.....T7, thì mình thêm đoạn code như thế nào ạ
Em cám ơn
Option Explicit
Private Sub Worksheet_Change(ByVal Target As Range)
Dim rTarget As Range, aTarget, i As Long, n As Long
Dim Arr1(), Arr2(), Arr3(), Arr4(), Arr5(), Arr6(), Arr7(), tmp
On Error Resume Next
If Dic Is Nothing Then Vlookup_DATA_SP
If Not Intersect(Range("D851:D600000"), Target) Is Nothing Then
Set rTarget = Intersect(Range("D851:D600000"), Target)
If IsArray(rTarget.Value) Then
aTarget = rTarget.Value
Else
ReDim aTarget(1 To 1, 1 To 1)
aTarget(1, 1) = rTarget.Value
End If
ReDim Arr1(1 To UBound(aTarget, 1), 1 To 1)
ReDim Arr2(1 To UBound(aTarget, 1), 1 To 1)
ReDim Arr5(1 To UBound(aTarget, 1), 1 To 1)
For i = 1 To UBound(aTarget, 1)
If aTarget(i, 1) <> "" Then
tmp = aTarget(i, 1)
If Dic.Exists(tmp) Then
Arr1(i, 1) = aResult(Dic.Item(tmp), 3) 'NGANH HANG
Arr2(i, 1) = aResult(Dic.Item(tmp), 4) 'HANG
Arr5(i, 1) = aResult(Dic.Item(tmp), 5) 'LOAI HANG
End If
End If
Next
rTarget.Offset(, 36).Resize(, 1).Value = Arr1 'Vi tri tham chieu NGANH HANG
rTarget.Offset(, 38).Resize(, 1).Value = Arr2 'Vi tri tham chieu HANG
rTarget.Offset(, 37).Resize(, 1).Value = Arr5 'Vi tri tham chieu LOAI HANG
End If
End Sub
Private Sub Worksheet_Change1(ByVal Target As Range)
Dim rng As Range, change As Range
Set change = Intersect(Target, Range("M851:M600000"))
If Not change Is Nothing Then
Application.EnableEvents = False
Application.ScreenUpdating = False
For Each rng In change
With rng
.Offset(0, 34).Value = Format(rng, "d")
.Offset(0, 35).Value = Format(rng, "m")
.Offset(0, 36).Value = Format(rng, "yyyy")
.Offset(0, 32).Value = Format(rng, "ww")
End With
Next rng
Application.ScreenUpdating = True
Application.EnableEvents = True
End If
End Sub
(1) thì thôi ạ.Không đơn giản thế đâu.
1. Theo lôgíc của tôi thì khi nhập ngày tháng ở A thì trong 5 cột tiếp theo sẽ có kết quả. Vậy khi xóa A thì 5 cột kia cũng phải rỗng. Nhưng trong code của bạn khi xóa A thì dDate = 0, như vậy trong 5 cột vẫn có dữ liệu - của những năm tháng xa xôi.
2. Người ta có
Người ta không nói kéo xuống bao nhiêu nên để đề phòng kéo hàng ngàn dòng thì tôi có vd. Application.ScreenUpdating = False / True.
Khi người ta kéo như thế thì Target là nhiều cell nên chắc chắn có lỗi ở dòng
Target.Value2 là cả một mảng giá trị nên CLng(Val(Target.Value2)) sẽ có lỗi.Mã:.Offset(0, 1).Resize(1, 5) = ConvertDate2ABC(CLng(Val(Target.Value2)))
Có thể giúp em ở bài 21 không anh?(1) thì thôi ạ.
(2) Em sửa lại: .Offset(0, 1).Resize(1, 5) = ConvertDate2ABC(CLng(Val(.Value2))) được không anh?
Chúc anh tối vui!
Private Sub Worksheet_Change(ByVal Target As Range)
Dim rTarget As Range, aTarget, i As Long, n As Long
Dim Arr1(), Arr2(), Arr3(), Arr4(), Arr5(), Arr6(), Arr7(), tmp
Dim rng As Range, change As Range
On Error Resume Next
If dic Is Nothing Then Vlookup_DATA_SP
If Not Intersect(Range("D851:D600000"), Target) Is Nothing Then
Set rTarget = Intersect(Range("D851:D600000"), Target)
If IsArray(rTarget.Value) Then
aTarget = rTarget.Value
Else
ReDim aTarget(1 To 1, 1 To 1)
aTarget(1, 1) = rTarget.Value
End If
ReDim Arr1(1 To UBound(aTarget, 1), 1 To 1)
ReDim Arr2(1 To UBound(aTarget, 1), 1 To 1)
ReDim Arr5(1 To UBound(aTarget, 1), 1 To 1)
For i = 1 To UBound(aTarget, 1)
If aTarget(i, 1) <> "" Then
tmp = aTarget(i, 1)
If dic.Exists(tmp) Then
Arr1(i, 1) = aResult(dic.Item(tmp), 3) 'NGANH HANG
Arr2(i, 1) = aResult(dic.Item(tmp), 4) 'HANG
Arr5(i, 1) = aResult(dic.Item(tmp), 5) 'LOAI HANG
End If
End If
Next
rTarget.Offset(, 36).Resize(, 1).Value = Arr1 'Vi tri tham chieu NGANH HANG
rTarget.Offset(, 38).Resize(, 1).Value = Arr2 'Vi tri tham chieu HANG
rTarget.Offset(, 37).Resize(, 1).Value = Arr5 'Vi tri tham chieu LOAI HANG
Else
Set change = Intersect(Target, Range("M851:M600000"))
If Not change Is Nothing Then
Application.EnableEvents = False
Application.ScreenUpdating = False
For Each rng In change
With rng
.Offset(0, 34).Value = Format(rng, "d")
.Offset(0, 35).Value = Format(rng, "m")
.Offset(0, 36).Value = Format(rng, "yyyy")
.Offset(0, 32).Value = Format(rng, "ww")
End With
Next rng
Application.ScreenUpdating = True
Application.EnableEvents = True
End If
End If
End Sub
Tôi không bao giờ thích những câu hỏi như thế này. Khi đã biết cần phải xét những trường hợp như thế nào thì mỗi người tự kiểm tra thôi chứ sao lại phải hỏi?(2) Em sửa lại: .Offset(0, 1).Resize(1, 5) = ConvertDate2ABC(CLng(Val(.Value2))) được không anh?
Đây không phải procedure bình thường để bạn khai báo tên bất kỳ.
Private Sub Worksheet_Change() có nghĩa là đây là procedure phục vụ sự kiện "thay đổi" trên sheet, và nó sẽ được gọi khi có sự thay đổi nào đó trên sheet.
Bạn click để mở combobox ở bên phải thì thấy có dòng "Change". Tức đối tượng sheet có event procedure với tên là Change. Làm gì có event Change1? Nếu bạn có Private Sub Worksheet_Change1() thì lúc đó nó được coi là procedure bình thường có tên là Worksheet_Change1. Nó không phải là event procedure. Thế thôi. Procedure ấy sẽ vô dụng vì không được gọi khi có sự thay đổi trên sheet.
Nếu cần thì gộp 2 thành 1. Tôi chỉ gộp cho bạn thôi chứ không sửa, không làm tối ưu code đầu. Bạn tự làm.
Mã:Private Sub Worksheet_Change(ByVal Target As Range) Dim rTarget As Range, aTarget, i As Long, n As Long Dim Arr1(), Arr2(), Arr3(), Arr4(), Arr5(), Arr6(), Arr7(), tmp Dim rng As Range, change As Range On Error Resume Next If dic Is Nothing Then Vlookup_DATA_SP If Not Intersect(Range("D851:D600000"), Target) Is Nothing Then Set rTarget = Intersect(Range("D851:D600000"), Target) If IsArray(rTarget.Value) Then aTarget = rTarget.Value Else ReDim aTarget(1 To 1, 1 To 1) aTarget(1, 1) = rTarget.Value End If ReDim Arr1(1 To UBound(aTarget, 1), 1 To 1) ReDim Arr2(1 To UBound(aTarget, 1), 1 To 1) ReDim Arr5(1 To UBound(aTarget, 1), 1 To 1) For i = 1 To UBound(aTarget, 1) If aTarget(i, 1) <> "" Then tmp = aTarget(i, 1) If dic.Exists(tmp) Then Arr1(i, 1) = aResult(dic.Item(tmp), 3) 'NGANH HANG Arr2(i, 1) = aResult(dic.Item(tmp), 4) 'HANG Arr5(i, 1) = aResult(dic.Item(tmp), 5) 'LOAI HANG End If End If Next rTarget.Offset(, 36).Resize(, 1).Value = Arr1 'Vi tri tham chieu NGANH HANG rTarget.Offset(, 38).Resize(, 1).Value = Arr2 'Vi tri tham chieu HANG rTarget.Offset(, 37).Resize(, 1).Value = Arr5 'Vi tri tham chieu LOAI HANG Else Set change = Intersect(Target, Range("M851:M600000")) If Not change Is Nothing Then Application.EnableEvents = False Application.ScreenUpdating = False For Each rng In change With rng .Offset(0, 34).Value = Format(rng, "d") .Offset(0, 35).Value = Format(rng, "m") .Offset(0, 36).Value = Format(rng, "yyyy") .Offset(0, 32).Value = Format(rng, "ww") End With Next rng Application.ScreenUpdating = True Application.EnableEvents = True End If End If End Sub
If Not Intersect(Range("D851:D600000"), Target) Is Nothing Then
...
End If
Set change = Intersect(Target, Range("M851:M600000"))
If Not change Is Nothing Then
...
End If
Thực ra cũng tùy. Thực ra có thể viết không có ELSE
Nếu bạn thay đổi chỉ cột D hoặc M thì code trước và code này như nhau. Nhưng nếu bạn dán 1 lần vào cả 2 cột D và M thì có sự khác nhau. Code trước chỉ thực hiện phần trước ELSE. Code sau thì thực hiện cả cho sự thay đổi trong cột D và cả cho sự thay đổi trong cột M. Do bạn chỉ tung code lên mà không giải thích gì thêm nên tôi gộp với ELSE. Nhưng phải ý thức được là có trường hợp, dù là lý thuyết, khi bạn dán vào đồng thời 2 cột D và M. Nếu lúc đó bạn muốn xử lý cả 2 hậu quả thì phải dùng code không có ELSE ở trên.Mã:If Not Intersect(Range("D851:D600000"), Target) Is Nothing Then ... End If Set change = Intersect(Target, Range("M851:M600000")) If Not change Is Nothing Then ... End If
Tôi biết là bạn xử lý sự thay đổi ở cột D, M. Ý tôi nói là có sự khác biệt khi chỉ thay đổi D hoặc M, và lúc khác lại D hoặc M và trường hợp khi bạn đồng thời thay đổi cả D và M.Dạ anh!
Các dữ liệu cột D và M em đều muốn thay đổi mỗi khi thay số liệu, hiện tại em test thôi code anh hướng dẫn đang chạy rất hoàn hảo, giảm đi dung lượng đáng kể thay vì dùng hàm.
Hiện tại tôi đang phải dịch một bản tài liệu sang tiếng Việt. Chưa biết khi nào xong.Sẵn tiện anh hỗ trợ em cách thay hàm if và giá như file đính kèm, mục đích dùng code để tối ưu hóa báo cáo trong kinh doanh của em
Nó sẽ hoàn hảo khi giải quyết được tất cả như trong file
Set change = Intersect(Target, Range("Y3:Y600000"))
If Not change Is Nothing Then
Application.EnableEvents = False
Application.ScreenUpdating = False
For Each rng In change
If Len(rng.Value) Then
Select Case rng.Value / 10 ^ 6
Case Is <= 1: rng.Offset(0, 18).Value = "<1M"
Case Is <= 2: rng.Offset(0, 18).Value = "1M-2M"
Case Is <= 4: rng.Offset(0, 18).Value = "2M-4M"
Case Is <= 6: rng.Offset(0, 18).Value = "4M-6M"
Case Is <= 8: rng.Offset(0, 18).Value = "6M-8M"
Case Is <= 10: rng.Offset(0, 18).Value = "8M-10M"
Case Is <= 12: rng.Offset(0, 18).Value = "10M-12M"
Case Is <= 14: rng.Offset(0, 18).Value = "12M-14M"
Case Is <= 16: rng.Offset(0, 18).Value = "14M-16M"
Case Is <= 18: rng.Offset(0, 18).Value = "16M-18M"
Case Is <= 20: rng.Offset(0, 18).Value = "18M-20M"
Case Else: rng.Offset(0, 18).Value = "Tren 20M"
End Select
Else
rng.Offset(0, 18).Value = Empty
End If
Next rng
Application.EnableEvents = True
Application.ScreenUpdating = True
End If
Select Case rng.Value / 10 ^ 6
...
End Select
Thế trong cột Y có công thức hay dữ liệu nhập bằng tay, bằng máy?
Nếu không phải công thức thì:
1. Xóa toàn bộ công thức trong cột AQ.
2. Trong Worksheet_Change thêm đoạn
Cách thêm thì tôi đã giải thích rồi, bạn tự chọn.Mã:Set change = Intersect(Target, Range("Y3:Y600000")) If Not change Is Nothing Then Application.EnableEvents = False Application.ScreenUpdating = False For Each rng In change If Len(rng.Value) Then Select Case rng.Value / 10 ^ 6 Case Is <= 1: rng.Offset(0, 18).Value = "<1M" Case Is <= 2: rng.Offset(0, 18).Value = "1M-2M" Case Is <= 4: rng.Offset(0, 18).Value = "2M-4M" Case Is <= 6: rng.Offset(0, 18).Value = "4M-6M" Case Is <= 8: rng.Offset(0, 18).Value = "6M-8M" Case Is <= 10: rng.Offset(0, 18).Value = "8M-10M" Case Is <= 12: rng.Offset(0, 18).Value = "10M-12M" Case Is <= 14: rng.Offset(0, 18).Value = "12M-14M" Case Is <= 16: rng.Offset(0, 18).Value = "14M-16M" Case Is <= 18: rng.Offset(0, 18).Value = "16M-18M" Case Is <= 20: rng.Offset(0, 18).Value = "18M-20M" Case Else: rng.Offset(0, 18).Value = "Tren 20M" End Select Else rng.Offset(0, 18).Value = Empty End If Next rng Application.EnableEvents = True Application.ScreenUpdating = True End If
Có thể thay đoạn
bằng Application.VLookup. Bạn tự đọc, tự nghiên cứu.Mã:Select Case rng.Value / 10 ^ 6 ... End Select
Vì code vào giữa chừng cuộc chơi nên nó không thể phản ứng với những dữ liệu đã có trong cột Y - sự kiện Change đã sảy ra hôm qua, tuần trước. Vì thế nếu đã có dữ liệu trong cột Y thì làm 1 lần các thao tác: Chọn toàn bộ dữ liệu cột Y -> nhấn Ctrl + C -> nhấn Ctrl + V (mục đích để tạo ra sự kiện Change cho những dữ liệu đã có)
Xóa dữ liệu cột Y thì cột AQ sẽ rỗng.
Thế trong cột Y có công thức hay dữ liệu nhập bằng tay, bằng máy?
Nếu không phải công thức thì:
1. Xóa toàn bộ công thức trong cột AQ.
2. Trong Worksheet_Change thêm đoạn
Cách thêm thì tôi đã giải thích rồi, bạn tự chọn.Mã:Set change = Intersect(Target, Range("Y3:Y600000")) If Not change Is Nothing Then Application.EnableEvents = False Application.ScreenUpdating = False For Each rng In change If Len(rng.Value) Then Select Case rng.Value / 10 ^ 6 Case Is <= 1: rng.Offset(0, 18).Value = "<1M" Case Is <= 2: rng.Offset(0, 18).Value = "1M-2M" Case Is <= 4: rng.Offset(0, 18).Value = "2M-4M" Case Is <= 6: rng.Offset(0, 18).Value = "4M-6M" Case Is <= 8: rng.Offset(0, 18).Value = "6M-8M" Case Is <= 10: rng.Offset(0, 18).Value = "8M-10M" Case Is <= 12: rng.Offset(0, 18).Value = "10M-12M" Case Is <= 14: rng.Offset(0, 18).Value = "12M-14M" Case Is <= 16: rng.Offset(0, 18).Value = "14M-16M" Case Is <= 18: rng.Offset(0, 18).Value = "16M-18M" Case Is <= 20: rng.Offset(0, 18).Value = "18M-20M" Case Else: rng.Offset(0, 18).Value = "Tren 20M" End Select Else rng.Offset(0, 18).Value = Empty End If Next rng Application.EnableEvents = True Application.ScreenUpdating = True End If
Có thể thay đoạn
bằng Application.VLookup. Bạn tự đọc, tự nghiên cứu.Mã:Select Case rng.Value / 10 ^ 6 ... End Select
Vì code vào giữa chừng cuộc chơi nên nó không thể phản ứng với những dữ liệu đã có trong cột Y - sự kiện Change đã sảy ra hôm qua, tuần trước. Vì thế nếu đã có dữ liệu trong cột Y thì làm 1 lần các thao tác: Chọn toàn bộ dữ liệu cột Y -> nhấn Ctrl + C -> nhấn Ctrl + V (mục đích để tạo ra sự kiện Change cho những dữ liệu đã có)
Xóa dữ liệu cột Y thì cột AQ sẽ rỗng.
Thế trong cột Y có công thức hay dữ liệu nhập bằng tay, bằng máy?
Nếu không phải công thức thì:
1. Xóa toàn bộ công thức trong cột AQ.
2. Trong Worksheet_Change thêm đoạn
Cách thêm thì tôi đã giải thích rồi, bạn tự chọn.Mã:Set change = Intersect(Target, Range("Y3:Y600000")) If Not change Is Nothing Then Application.EnableEvents = False Application.ScreenUpdating = False For Each rng In change If Len(rng.Value) Then Select Case rng.Value / 10 ^ 6 Case Is <= 1: rng.Offset(0, 18).Value = "<1M" Case Is <= 2: rng.Offset(0, 18).Value = "1M-2M" Case Is <= 4: rng.Offset(0, 18).Value = "2M-4M" Case Is <= 6: rng.Offset(0, 18).Value = "4M-6M" Case Is <= 8: rng.Offset(0, 18).Value = "6M-8M" Case Is <= 10: rng.Offset(0, 18).Value = "8M-10M" Case Is <= 12: rng.Offset(0, 18).Value = "10M-12M" Case Is <= 14: rng.Offset(0, 18).Value = "12M-14M" Case Is <= 16: rng.Offset(0, 18).Value = "14M-16M" Case Is <= 18: rng.Offset(0, 18).Value = "16M-18M" Case Is <= 20: rng.Offset(0, 18).Value = "18M-20M" Case Else: rng.Offset(0, 18).Value = "Tren 20M" End Select Else rng.Offset(0, 18).Value = Empty End If Next rng Application.EnableEvents = True Application.ScreenUpdating = True End If
Có thể thay đoạn
bằng Application.VLookup. Bạn tự đọc, tự nghiên cứu.Mã:Select Case rng.Value / 10 ^ 6 ... End Select
Vì code vào giữa chừng cuộc chơi nên nó không thể phản ứng với những dữ liệu đã có trong cột Y - sự kiện Change đã sảy ra hôm qua, tuần trước. Vì thế nếu đã có dữ liệu trong cột Y thì làm 1 lần các thao tác: Chọn toàn bộ dữ liệu cột Y -> nhấn Ctrl + C -> nhấn Ctrl + V (mục đích để tạo ra sự kiện Change cho những dữ liệu đã có)
Xóa dữ liệu cột Y thì cột AQ sẽ rỗng.
Private Sub Worksheet_Change(ByVal Target As Range)
Dim rTarget As Range, aTarget, i As Long, n As Long
Dim Arr1(), Arr2(), Arr3(), Arr4(), Arr5(), Arr6(), Arr7(), tmp
Dim rng As Range, change As Range
On Error Resume Next
If Dic Is Nothing Then Vlookup_DATA_SP
If Not Intersect(Range("D851:D600000"), Target) Is Nothing Then
Set rTarget = Intersect(Range("D851:D600000"), Target)
If IsArray(rTarget.Value) Then
aTarget = rTarget.Value
Else
ReDim aTarget(1 To 1, 1 To 1)
aTarget(1, 1) = rTarget.Value
End If
ReDim Arr1(1 To UBound(aTarget, 1), 1 To 1)
ReDim Arr2(1 To UBound(aTarget, 1), 1 To 1)
ReDim Arr5(1 To UBound(aTarget, 1), 1 To 1)
For i = 1 To UBound(aTarget, 1)
If aTarget(i, 1) <> "" Then
tmp = aTarget(i, 1)
If Dic.Exists(tmp) Then
Arr1(i, 1) = aResult(Dic.Item(tmp), 3) 'NGANH HANG
Arr2(i, 1) = aResult(Dic.Item(tmp), 4) 'HANG
Arr5(i, 1) = aResult(Dic.Item(tmp), 5) 'LOAI HANG
End If
End If
Next
rTarget.Offset(, 36).Resize(, 1).Value = Arr1 'Vi tri tham chieu NGANH HANG
rTarget.Offset(, 38).Resize(, 1).Value = Arr2 'Vi tri tham chieu HANG
rTarget.Offset(, 37).Resize(, 1).Value = Arr5 'Vi tri tham chieu LOAI HANG
Else
Set change = Intersect(Target, Range("M851:M600000")) ' Ngay Thang Nam, Tuan
If Not change Is Nothing Then
Application.EnableEvents = False
Application.ScreenUpdating = False
For Each rng In change
With rng
.Offset(0, 33).Value = Format(rng, "d")
.Offset(0, 34).Value = Format(rng, "m")
.Offset(0, 35).Value = Format(rng, "yyyy")
.Offset(0, 31).Value = Format(rng, "ww")
End With
Next rng
Application.ScreenUpdating = True
Application.EnableEvents = True
Else 'Phan Khuc Gia
Set change = Intersect(Target, Range("AC851:AC600000"))
If Not change Is Nothing Then
Application.EnableEvents = False
Application.ScreenUpdating = False
For Each rng In change
If Len(rng.Value) Then
Select Case rng.Value / 10 ^ 6
Case Is <= 1: rng.Offset(0, 14).Value = "<1M"
Case Is <= 2: rng.Offset(0, 14).Value = "1M-2M"
Case Is <= 4: rng.Offset(0, 14).Value = "2M-4M"
Case Is <= 6: rng.Offset(0, 14).Value = "4M-6M"
Case Is <= 8: rng.Offset(0, 14).Value = "6M-8M"
Case Is <= 10: rng.Offset(0, 14).Value = "8M-10M"
Case Is <= 12: rng.Offset(0, 14).Value = "10M-12M"
Case Is <= 14: rng.Offset(0, 14).Value = "12M-14M"
Case Is <= 16: rng.Offset(0, 14).Value = "14M-16M"
Case Is <= 18: rng.Offset(0, 14).Value = "16M-18M"
Case Is <= 20: rng.Offset(0, 14).Value = "18M-20M"
Case Else: rng.Offset(0, 14).Value = "Tren 20M"
End Select
Else
rng.Offset(0, 14).Value = Empty
End If
Next rng
Application.EnableEvents = True
Application.ScreenUpdating = True
End If
End If
End If
End Sub
Tôi đã nói với bạn là tùy vào trường hợp mà dùng. Có ai bắt dùng ELSE đâu?Về phần này anh nói rất đúng, nếu em đổ dữ liệu copy vào thì nó chỉ chạy code đầu tiền, riêng code ngày tháng năm tuần và phân khúc giá không chạy, mà phải copy và dán dòng tương úng thì nó mới chạy.
Tôi đã nói với bạn là tùy vào trường hợp mà dùng. Có ai bắt dùng ELSE đâu?
Mà bạn hãy mô tả cái "đổ dữ liệu copy vào". Đổ thế nào, bằng cái gì, từ đâu tới đâu.
------
Mà nên giải thích kỹ cách hoạt động của tập tin. Trong Change bạn dùng dic và aResult. Chả biết dic được tạo ở đâu, khi nào. aResult mặt mũi thế nào. Vlookup_DATA_SP nằm ở đâu, làm những gì, việc làm có thay đổi gì trên sheet không. Vì lúc đó code đã tạo ra sự kiện Change ...
Không phải ai cũng thích mất thời gian, thích sửa đi sửa lại. Viết từng khúc riêng biệt để rồi chắp vá lại với nhau.
Tôi có viếtDạ em gửi file để anh dễ hiểu từng code như trên, anh xem giúp em nhe
Em cám ơn
Nhưng bạn không trả lời.Mà bạn hãy mô tả cái "đổ dữ liệu copy vào". Đổ thế nào, bằng cái gì, từ đâu tới đâu.
Private Sub Worksheet_Change(ByVal Target As Range)
Dim rTarget As Range, aTarget, i As Long, n As Long
Dim Arr1(), Arr2(), Arr3(), Arr4(), Arr5(), Arr6(), Arr7(), tmp
Dim rng As Range, change As Range
On Error Resume Next
If Dic Is Nothing Then Vlookup_DATA_SP
If Not Intersect(Range("D851:D600000"), Target) Is Nothing Then
Set rTarget = Intersect(Range("D851:D600000"), Target)
If IsArray(rTarget.Value) Then
aTarget = rTarget.Value
Else
ReDim aTarget(1 To 1, 1 To 1)
aTarget(1, 1) = rTarget.Value
End If
ReDim Arr1(1 To UBound(aTarget, 1), 1 To 1)
ReDim Arr2(1 To UBound(aTarget, 1), 1 To 1)
ReDim Arr5(1 To UBound(aTarget, 1), 1 To 1)
For i = 1 To UBound(aTarget, 1)
If aTarget(i, 1) <> "" Then
tmp = aTarget(i, 1)
If Dic.Exists(tmp) Then
Arr1(i, 1) = aResult(Dic.Item(tmp), 3) 'NGANH HANG
Arr2(i, 1) = aResult(Dic.Item(tmp), 4) 'HANG
Arr5(i, 1) = aResult(Dic.Item(tmp), 5) 'LOAI HANG
End If
End If
Next
rTarget.Offset(, 36).Resize(, 1).Value = Arr1 'Vi tri tham chieu NGANH HANG
rTarget.Offset(, 38).Resize(, 1).Value = Arr2 'Vi tri tham chieu HANG
rTarget.Offset(, 37).Resize(, 1).Value = Arr5 'Vi tri tham chieu LOAI HANG
End If
' ngay thang
Set change = Intersect(Target, Range("M851:M600000")) ' Ngay Thang Nam, Tuan
If Not change Is Nothing Then
Application.EnableEvents = False
Application.ScreenUpdating = False
For Each rng In change
With rng
.Offset(0, 33).Value = Format(rng, "d")
.Offset(0, 34).Value = Format(rng, "m")
.Offset(0, 35).Value = Format(rng, "yyyy")
.Offset(0, 31).Value = Format(rng, "ww")
End With
Next rng
Application.ScreenUpdating = True
Application.EnableEvents = True
End If
' Phan Khuc Gia
Set change = Intersect(Target, Range("AC851:AC600000"))
If Not change Is Nothing Then
Application.EnableEvents = False
Application.ScreenUpdating = False
For Each rng In change
If Len(rng.Value) Then
Select Case rng.Value / 10 ^ 6
Case Is <= 1: rng.Offset(0, 14).Value = "<1M"
Case Is <= 2: rng.Offset(0, 14).Value = "1M-2M"
Case Is <= 4: rng.Offset(0, 14).Value = "2M-4M"
Case Is <= 6: rng.Offset(0, 14).Value = "4M-6M"
Case Is <= 8: rng.Offset(0, 14).Value = "6M-8M"
Case Is <= 10: rng.Offset(0, 14).Value = "8M-10M"
Case Is <= 12: rng.Offset(0, 14).Value = "10M-12M"
Case Is <= 14: rng.Offset(0, 14).Value = "12M-14M"
Case Is <= 16: rng.Offset(0, 14).Value = "14M-16M"
Case Is <= 18: rng.Offset(0, 14).Value = "16M-18M"
Case Is <= 20: rng.Offset(0, 14).Value = "18M-20M"
Case Else: rng.Offset(0, 14).Value = "Tren 20M"
End Select
Else
rng.Offset(0, 14).Value = Empty
End If
Next rng
Application.EnableEvents = True
Application.ScreenUpdating = True
End If
End Sub
Tôi có viết
Nhưng bạn không trả lời.
Thôi, tôi sửa thế này. Bạn tự kiểm tra.
Mã:Private Sub Worksheet_Change(ByVal Target As Range) Dim rTarget As Range, aTarget, i As Long, n As Long Dim Arr1(), Arr2(), Arr3(), Arr4(), Arr5(), Arr6(), Arr7(), tmp Dim rng As Range, change As Range On Error Resume Next If Dic Is Nothing Then Vlookup_DATA_SP If Not Intersect(Range("D851:D600000"), Target) Is Nothing Then Set rTarget = Intersect(Range("D851:D600000"), Target) If IsArray(rTarget.Value) Then aTarget = rTarget.Value Else ReDim aTarget(1 To 1, 1 To 1) aTarget(1, 1) = rTarget.Value End If ReDim Arr1(1 To UBound(aTarget, 1), 1 To 1) ReDim Arr2(1 To UBound(aTarget, 1), 1 To 1) ReDim Arr5(1 To UBound(aTarget, 1), 1 To 1) For i = 1 To UBound(aTarget, 1) If aTarget(i, 1) <> "" Then tmp = aTarget(i, 1) If Dic.Exists(tmp) Then Arr1(i, 1) = aResult(Dic.Item(tmp), 3) 'NGANH HANG Arr2(i, 1) = aResult(Dic.Item(tmp), 4) 'HANG Arr5(i, 1) = aResult(Dic.Item(tmp), 5) 'LOAI HANG End If End If Next rTarget.Offset(, 36).Resize(, 1).Value = Arr1 'Vi tri tham chieu NGANH HANG rTarget.Offset(, 38).Resize(, 1).Value = Arr2 'Vi tri tham chieu HANG rTarget.Offset(, 37).Resize(, 1).Value = Arr5 'Vi tri tham chieu LOAI HANG End If ' ngay thang Set change = Intersect(Target, Range("M851:M600000")) ' Ngay Thang Nam, Tuan If Not change Is Nothing Then Application.EnableEvents = False Application.ScreenUpdating = False For Each rng In change With rng .Offset(0, 33).Value = Format(rng, "d") .Offset(0, 34).Value = Format(rng, "m") .Offset(0, 35).Value = Format(rng, "yyyy") .Offset(0, 31).Value = Format(rng, "ww") End With Next rng Application.ScreenUpdating = True Application.EnableEvents = True End If ' Phan Khuc Gia Set change = Intersect(Target, Range("AC851:AC600000")) If Not change Is Nothing Then Application.EnableEvents = False Application.ScreenUpdating = False For Each rng In change If Len(rng.Value) Then Select Case rng.Value / 10 ^ 6 Case Is <= 1: rng.Offset(0, 14).Value = "<1M" Case Is <= 2: rng.Offset(0, 14).Value = "1M-2M" Case Is <= 4: rng.Offset(0, 14).Value = "2M-4M" Case Is <= 6: rng.Offset(0, 14).Value = "4M-6M" Case Is <= 8: rng.Offset(0, 14).Value = "6M-8M" Case Is <= 10: rng.Offset(0, 14).Value = "8M-10M" Case Is <= 12: rng.Offset(0, 14).Value = "10M-12M" Case Is <= 14: rng.Offset(0, 14).Value = "12M-14M" Case Is <= 16: rng.Offset(0, 14).Value = "14M-16M" Case Is <= 18: rng.Offset(0, 14).Value = "16M-18M" Case Is <= 20: rng.Offset(0, 14).Value = "18M-20M" Case Else: rng.Offset(0, 14).Value = "Tren 20M" End Select Else rng.Offset(0, 14).Value = Empty End If Next rng Application.EnableEvents = True Application.ScreenUpdating = True End If End Sub
Thế bạn đã thử code tôi vừa sửa không?
Private Sub Worksheet_Change(ByVal Target As Range)
Dim i As Long, tmp
Dim result(), ba(), change As Range, songayma As String, so_ngay_ma As Object
If Dic Is Nothing Then Vlookup_DATA_SP
Application.EnableEvents = False
Application.ScreenUpdating = False
Set change = Intersect(Range("D851:D600000"), Target)
If Not change Is Nothing Then
result = change.Resize(change.Rows.Count + 1).Value
ReDim Preserve result(1 To UBound(result), 1 To 3)
For i = 1 To UBound(result) - 1
If Len(result(i, 1)) Then
tmp = result(i, 1)
If Dic.exists(tmp) Then
result(i, 1) = aResult(Dic.Item(tmp), 3) 'NGANH HANG
result(i, 2) = aResult(Dic.Item(tmp), 5) 'LOAI HANG
result(i, 3) = aResult(Dic.Item(tmp), 4) 'HANG
End If
End If
Next i
change.Offset(0, 36).Resize(, 3).Value = result
End If
' ngay thang
Set change = Intersect(Target, Range("M851:M600000")) ' Ngay Thang Nam, Tuan
If Not change Is Nothing Then
result = change.Resize(change.Rows.Count + 1).Value
ReDim Preserve result(1 To UBound(result), 1 To 5)
For i = 1 To UBound(result) - 1
If Len(result(i, 1)) Then
result(i, 2) = WorksheetFunction.Text(result(i, 1), "[$-42A]ddd")
result(i, 3) = Format(result(i, 1), "d")
result(i, 4) = Format(result(i, 1), "m")
result(i, 5) = Format(result(i, 1), "yyyy")
result(i, 1) = Format(result(i, 1), "ww")
End If
Next i
change.Offset(0, 31).Resize(, 5).Value = result
End If
' Phan Khuc Gia va cot BA
Set change = Intersect(Target, Range("AC851:AC600000"))
If Not change Is Nothing Then
result = change.Resize(change.Rows.Count + 1).Value
ba = result
For i = 1 To UBound(result) - 1
ba(i, 1) = result(i, 1) / 101
If Len(result(i, 1)) Then
Select Case result(i, 1) / 10 ^ 6
Case Is <= 1: result(i, 1) = "<1M"
Case Is <= 2: result(i, 1) = "1M-2M"
Case Is <= 4: result(i, 1) = "2M-4M"
Case Is <= 6: result(i, 1) = "4M-6M"
Case Is <= 8: result(i, 1) = "6M-8M"
Case Is <= 10: result(i, 1) = "8M-10M"
Case Is <= 12: result(i, 1) = "10M-12M"
Case Is <= 14: result(i, 1) = "12M-14M"
Case Is <= 16: result(i, 1) = "14M-16M"
Case Is <= 18: result(i, 1) = "16M-18M"
Case Is <= 20: result(i, 1) = "18M-20M"
Case Else: result(i, 1) = "Tren 20M"
End Select
End If
Next i
' Phan Khuc Gia
change.Offset(0, 14).Value = result
' cot BA
Range("BA" & change.Row).Resize(UBound(ba) - 1).Value = ba
End If
' cot AY
Set change = Intersect(Target, Range("M851:M600000, P851:P600000"))
If Not change Is Nothing Then
Set so_ngay_ma = CreateObject("Scripting.Dictionary")
result = Range(Cells(change.Row, "M"), Cells(change.Row + change.Rows.Count - 1, "P"))
For i = 1 To UBound(result)
songayma = result(i, 1) & "-" & result(i, 4)
If so_ngay_ma.exists(songayma) Then
result(i, 1) = 0
Else
result(i, 1) = 1
so_ngay_ma.Add songayma, ""
End If
Next i
Cells(change.Row, "AY").Resize(UBound(result)).Value = result
Set so_ngay_ma = Nothing
End If
' cot AZ
Set change = Intersect(Target, Range("C851:C600000, M851:M600000"))
If Not change Is Nothing Then
Set so_ngay_ma = CreateObject("Scripting.Dictionary")
result = Range(Cells(change.Row, "C"), Cells(change.Row + change.Rows.Count - 1, "M"))
For i = 1 To UBound(result)
songayma = result(i, 1) & "-" & result(i, 11)
If so_ngay_ma.exists(songayma) Then
result(i, 1) = 0
Else
result(i, 1) = 1
so_ngay_ma.Add songayma, ""
End If
Next i
Cells(change.Row, "AZ").Resize(UBound(result)).Value = result
Set so_ngay_ma = Nothing
End If
Application.EnableEvents = True
Application.ScreenUpdating = True
End Sub
Code đòi hỏi cột M phải là ngày tháng chứ không phải trông giống ngày tháng. Hiện cột D không chứa ngày tháng theo đúng triết lý của Excel. D chỉ chứa chuỗi thôi. Tự bạn nhập lại hoặc nhờ ai đó sửa lại. Tôi không muốn mất công chỉ vì ai đó cẩu thả.
Tôi viết lại code vì thấy bạn phục vụ tới 600000 dòng, và có chuyện "đổ" dữ liệu vào sheet. Nếu đổ mỗi lần hàng ngàn, chục ngàn dòng thì code cũ chạy lâu.
Mã:Private Sub Worksheet_Change(ByVal Target As Range) Dim i As Long, tmp Dim result(), ba(), change As Range, songayma As String, so_ngay_ma As Object If Dic Is Nothing Then Vlookup_DATA_SP Application.EnableEvents = False Application.ScreenUpdating = False Set change = Intersect(Range("D851:D600000"), Target) If Not change Is Nothing Then result = change.Resize(change.Rows.Count + 1).Value ReDim Preserve result(1 To UBound(result), 1 To 3) For i = 1 To UBound(result) - 1 If Len(result(i, 1)) Then tmp = result(i, 1) If Dic.exists(tmp) Then result(i, 1) = aResult(Dic.Item(tmp), 3) 'NGANH HANG result(i, 2) = aResult(Dic.Item(tmp), 5) 'LOAI HANG result(i, 3) = aResult(Dic.Item(tmp), 4) 'HANG End If End If Next i change.Offset(0, 36).Resize(, 3).Value = result End If ' ngay thang Set change = Intersect(Target, Range("M851:M600000")) ' Ngay Thang Nam, Tuan If Not change Is Nothing Then result = change.Resize(change.Rows.Count + 1).Value ReDim Preserve result(1 To UBound(result), 1 To 5) For i = 1 To UBound(result) - 1 If Len(result(i, 1)) Then result(i, 2) = WorksheetFunction.Text(result(i, 1), "[$-42A]ddd") result(i, 3) = Format(result(i, 1), "d") result(i, 4) = Format(result(i, 1), "m") result(i, 5) = Format(result(i, 1), "yyyy") result(i, 1) = Format(result(i, 1), "ww") End If Next i change.Offset(0, 31).Resize(, 5).Value = result End If ' Phan Khuc Gia va cot BA Set change = Intersect(Target, Range("AC851:AC600000")) If Not change Is Nothing Then result = change.Resize(change.Rows.Count + 1).Value ba = result For i = 1 To UBound(result) - 1 ba(i, 1) = result(i, 1) / 101 If Len(result(i, 1)) Then Select Case result(i, 1) / 10 ^ 6 Case Is <= 1: result(i, 1) = "<1M" Case Is <= 2: result(i, 1) = "1M-2M" Case Is <= 4: result(i, 1) = "2M-4M" Case Is <= 6: result(i, 1) = "4M-6M" Case Is <= 8: result(i, 1) = "6M-8M" Case Is <= 10: result(i, 1) = "8M-10M" Case Is <= 12: result(i, 1) = "10M-12M" Case Is <= 14: result(i, 1) = "12M-14M" Case Is <= 16: result(i, 1) = "14M-16M" Case Is <= 18: result(i, 1) = "16M-18M" Case Is <= 20: result(i, 1) = "18M-20M" Case Else: result(i, 1) = "Tren 20M" End Select End If Next i ' Phan Khuc Gia change.Offset(0, 14).Value = result ' cot BA Range("BA" & change.Row).Resize(UBound(ba) - 1).Value = ba End If ' cot AY Set change = Intersect(Target, Range("M851:M600000, P851:P600000")) If Not change Is Nothing Then Set so_ngay_ma = CreateObject("Scripting.Dictionary") result = Range(Cells(change.Row, "M"), Cells(change.Row + change.Rows.Count - 1, "P")) For i = 1 To UBound(result) songayma = result(i, 1) & "-" & result(i, 4) If so_ngay_ma.exists(songayma) Then result(i, 1) = 0 Else result(i, 1) = 1 so_ngay_ma.Add songayma, "" End If Next i Cells(change.Row, "AY").Resize(UBound(result)).Value = result Set so_ngay_ma = Nothing End If ' cot AZ Set change = Intersect(Target, Range("C851:C600000, M851:M600000")) If Not change Is Nothing Then Set so_ngay_ma = CreateObject("Scripting.Dictionary") result = Range(Cells(change.Row, "C"), Cells(change.Row + change.Rows.Count - 1, "M")) For i = 1 To UBound(result) songayma = result(i, 1) & "-" & result(i, 11) If so_ngay_ma.exists(songayma) Then result(i, 1) = 0 Else result(i, 1) = 1 so_ngay_ma.Add songayma, "" End If Next i Cells(change.Row, "AZ").Resize(UBound(result)).Value = result Set so_ngay_ma = Nothing End If Application.EnableEvents = True Application.ScreenUpdating = True End Sub
Cần gì thêm thì nên mở chủ đề mới nhé.
Ý bạn muốn nói là công thức tuy nặng nhưng tính nhanh hơn?Em cám ơn anh nhều, nó tính hơi lâu bù lại file nhẹ, cái nào cũng có ưu nhược điểm.
If Dic.exists(tmp) Then
result(i, 1) = aResult(Dic.Item(tmp), 3) 'NGANH HANG
result(i, 2) = aResult(Dic.Item(tmp), 5) 'LOAI HANG
result(i, 3) = aResult(Dic.Item(tmp), 4) 'HANG
End If
If Dic.exists(tmp) Then
result(i, 1) = aResult(Dic.Item(tmp), 3) 'NGANH HANG
result(i, 2) = aResult(Dic.Item(tmp), 5) 'LOAI HANG
result(i, 3) = aResult(Dic.Item(tmp), 4) 'HANG
Else
result(i, 1) = Empty
End If
Else
result(i, 1) = Empty
Private Sub Worksheet_Change(ByVal Target As Range)
Dim i As Long, tmp
Dim result(), cot2(), ba(), change As Range, songayma As String, so_ngay_ma As Object, t
t = Timer
If Dic Is Nothing Then Vlookup_DATA_SP
Application.EnableEvents = False
Application.ScreenUpdating = False
Set change = Intersect(Range("D851:D600000"), Target)
If Not change Is Nothing Then
result = change.Resize(change.Rows.Count + 1).Value
ReDim Preserve result(1 To UBound(result), 1 To 3)
For i = 1 To UBound(result) - 1
If Len(result(i, 1)) Then
tmp = result(i, 1)
If Dic.exists(tmp) Then
result(i, 1) = aResult(Dic.Item(tmp), 3) 'NGANH HANG
result(i, 2) = aResult(Dic.Item(tmp), 5) 'LOAI HANG
result(i, 3) = aResult(Dic.Item(tmp), 4) 'HANG
Else
result(i, 1) = Empty
End If
End If
Next i
change.Offset(0, 36).Resize(, 3).Value = result
End If
' ngay thang
Set change = Intersect(Target, Range("M851:M600000")) ' Ngay Thang Nam, Tuan
If Not change Is Nothing Then
result = change.Resize(change.Rows.Count + 1).Value
ReDim Preserve result(1 To UBound(result), 1 To 5)
For i = 1 To UBound(result) - 1
If Len(result(i, 1)) Then
result(i, 2) = WorksheetFunction.Text(result(i, 1), "[$-42A]ddd")
result(i, 3) = Format(result(i, 1), "d")
result(i, 4) = Format(result(i, 1), "m")
result(i, 5) = Format(result(i, 1), "yyyy")
result(i, 1) = Format(result(i, 1), "ww")
End If
Next i
change.Offset(0, 31).Resize(, 5).Value = result
End If
' Phan Khuc Gia va cot BA
Set change = Intersect(Target, Range("AC851:AC600000"))
If Not change Is Nothing Then
result = change.Resize(change.Rows.Count + 1).Value
ba = result
For i = 1 To UBound(result) - 1
ba(i, 1) = result(i, 1) / 101
If Len(result(i, 1)) Then
Select Case result(i, 1) / 10 ^ 6
Case Is <= 1: result(i, 1) = "<1M"
Case Is <= 2: result(i, 1) = "1M-2M"
Case Is <= 4: result(i, 1) = "2M-4M"
Case Is <= 6: result(i, 1) = "4M-6M"
Case Is <= 8: result(i, 1) = "6M-8M"
Case Is <= 10: result(i, 1) = "8M-10M"
Case Is <= 12: result(i, 1) = "10M-12M"
Case Is <= 14: result(i, 1) = "12M-14M"
Case Is <= 16: result(i, 1) = "14M-16M"
Case Is <= 18: result(i, 1) = "16M-18M"
Case Is <= 20: result(i, 1) = "18M-20M"
Case Else: result(i, 1) = "Tren 20M"
End Select
End If
Next i
' Phan Khuc Gia
change.Offset(0, 14).Value = result
' cot BA
Range("BA" & change.Row).Resize(UBound(ba) - 1).Value = ba
End If
' cot AY
Set change = Intersect(Target, Range("M851:M600000, P851:P600000"))
If Not change Is Nothing Then
Set so_ngay_ma = CreateObject("Scripting.Dictionary")
result = Range("M" & change.Row).Resize(change.Rows.Count + 1).Value
cot2 = Range("M" & change.Row).Offset(0, 3).Resize(change.Rows.Count + 1).Value
For i = 1 To UBound(result) - 1
songayma = result(i, 1) & "-" & cot2(i, 1)
If so_ngay_ma.exists(songayma) Then
result(i, 1) = 0
Else
result(i, 1) = 1
so_ngay_ma.Add songayma, ""
End If
Next i
Cells(change.Row, "AY").Resize(UBound(result) - 1).Value = result
Set so_ngay_ma = Nothing
End If
' cot AZ
Set change = Intersect(Target, Range("C851:C600000, M851:M600000"))
If Not change Is Nothing Then
Set so_ngay_ma = CreateObject("Scripting.Dictionary")
result = Range("C" & change.Row).Resize(change.Rows.Count + 1).Value
cot2 = Range("C" & change.Row).Offset(0, 10).Resize(change.Rows.Count + 1).Value
For i = 1 To UBound(result) - 1
songayma = result(i, 1) & "-" & cot2(i, 1)
If so_ngay_ma.exists(songayma) Then
result(i, 1) = 0
Else
result(i, 1) = 1
so_ngay_ma.Add songayma, ""
End If
Next i
Cells(change.Row, "AZ").Resize(UBound(result) - 1).Value = result
Set so_ngay_ma = Nothing
End If
Application.EnableEvents = True
Application.ScreenUpdating = True
Debug.Print Timer - t
End Sub
Khi viết lại đoạn code đầu của bạn tôi đã bỏ xót việc xóa dữ liệu của cột đầu ở mảng kết quả
Hãy sửa
thànhMã:If Dic.exists(tmp) Then result(i, 1) = aResult(Dic.Item(tmp), 3) 'NGANH HANG result(i, 2) = aResult(Dic.Item(tmp), 5) 'LOAI HANG result(i, 3) = aResult(Dic.Item(tmp), 4) 'HANG End If
Tức thêm 2 dòngMã:If Dic.exists(tmp) Then result(i, 1) = aResult(Dic.Item(tmp), 3) 'NGANH HANG result(i, 2) = aResult(Dic.Item(tmp), 5) 'LOAI HANG result(i, 3) = aResult(Dic.Item(tmp), 4) 'HANG Else result(i, 1) = Empty End If
----------------Mã:Else result(i, 1) = Empty
Bạn cũng có thể dùng phiên bản mới dùng ít bộ nhớ hơn - mảng làm việc nhỏ hơn
Mã:Private Sub Worksheet_Change(ByVal Target As Range) Dim i As Long, tmp Dim result(), cot2(), ba(), change As Range, songayma As String, so_ngay_ma As Object, t t = Timer If Dic Is Nothing Then Vlookup_DATA_SP Application.EnableEvents = False Application.ScreenUpdating = False Set change = Intersect(Range("D851:D600000"), Target) If Not change Is Nothing Then result = change.Resize(change.Rows.Count + 1).Value ReDim Preserve result(1 To UBound(result), 1 To 3) For i = 1 To UBound(result) - 1 If Len(result(i, 1)) Then tmp = result(i, 1) If Dic.exists(tmp) Then result(i, 1) = aResult(Dic.Item(tmp), 3) 'NGANH HANG result(i, 2) = aResult(Dic.Item(tmp), 5) 'LOAI HANG result(i, 3) = aResult(Dic.Item(tmp), 4) 'HANG Else result(i, 1) = Empty End If End If Next i change.Offset(0, 36).Resize(, 3).Value = result End If ' ngay thang Set change = Intersect(Target, Range("M851:M600000")) ' Ngay Thang Nam, Tuan If Not change Is Nothing Then result = change.Resize(change.Rows.Count + 1).Value ReDim Preserve result(1 To UBound(result), 1 To 5) For i = 1 To UBound(result) - 1 If Len(result(i, 1)) Then result(i, 2) = WorksheetFunction.Text(result(i, 1), "[$-42A]ddd") result(i, 3) = Format(result(i, 1), "d") result(i, 4) = Format(result(i, 1), "m") result(i, 5) = Format(result(i, 1), "yyyy") result(i, 1) = Format(result(i, 1), "ww") End If Next i change.Offset(0, 31).Resize(, 5).Value = result End If ' Phan Khuc Gia va cot BA Set change = Intersect(Target, Range("AC851:AC600000")) If Not change Is Nothing Then result = change.Resize(change.Rows.Count + 1).Value ba = result For i = 1 To UBound(result) - 1 ba(i, 1) = result(i, 1) / 101 If Len(result(i, 1)) Then Select Case result(i, 1) / 10 ^ 6 Case Is <= 1: result(i, 1) = "<1M" Case Is <= 2: result(i, 1) = "1M-2M" Case Is <= 4: result(i, 1) = "2M-4M" Case Is <= 6: result(i, 1) = "4M-6M" Case Is <= 8: result(i, 1) = "6M-8M" Case Is <= 10: result(i, 1) = "8M-10M" Case Is <= 12: result(i, 1) = "10M-12M" Case Is <= 14: result(i, 1) = "12M-14M" Case Is <= 16: result(i, 1) = "14M-16M" Case Is <= 18: result(i, 1) = "16M-18M" Case Is <= 20: result(i, 1) = "18M-20M" Case Else: result(i, 1) = "Tren 20M" End Select End If Next i ' Phan Khuc Gia change.Offset(0, 14).Value = result ' cot BA Range("BA" & change.Row).Resize(UBound(ba) - 1).Value = ba End If ' cot AY Set change = Intersect(Target, Range("M851:M600000, P851:P600000")) If Not change Is Nothing Then Set so_ngay_ma = CreateObject("Scripting.Dictionary") result = Range("M" & change.Row).Resize(change.Rows.Count + 1).Value cot2 = Range("M" & change.Row).Offset(0, 3).Resize(change.Rows.Count + 1).Value For i = 1 To UBound(result) - 1 songayma = result(i, 1) & "-" & cot2(i, 1) If so_ngay_ma.exists(songayma) Then result(i, 1) = 0 Else result(i, 1) = 1 so_ngay_ma.Add songayma, "" End If Next i Cells(change.Row, "AY").Resize(UBound(result) - 1).Value = result Set so_ngay_ma = Nothing End If ' cot AZ Set change = Intersect(Target, Range("C851:C600000, M851:M600000")) If Not change Is Nothing Then Set so_ngay_ma = CreateObject("Scripting.Dictionary") result = Range("C" & change.Row).Resize(change.Rows.Count + 1).Value cot2 = Range("C" & change.Row).Offset(0, 10).Resize(change.Rows.Count + 1).Value For i = 1 To UBound(result) - 1 songayma = result(i, 1) & "-" & cot2(i, 1) If so_ngay_ma.exists(songayma) Then result(i, 1) = 0 Else result(i, 1) = 1 so_ngay_ma.Add songayma, "" End If Next i Cells(change.Row, "AZ").Resize(UBound(result) - 1).Value = result Set so_ngay_ma = Nothing End If Application.EnableEvents = True Application.ScreenUpdating = True Debug.Print Timer - t End Sub
Private Sub Worksheet_Change(ByVal Target As Range)
Dim i As Long, tmp
Dim result(), cot2(), ba(), change As Range, songayma As String, so_ngay_ma As Object, t
t = Timer
If Dic Is Nothing Then Vlookup_DATA_SP
Application.EnableEvents = False
Application.ScreenUpdating = False
Set change = Intersect(Range("D851:D600000"), Target)
If Not change Is Nothing Then
result = change.Resize(change.Rows.Count + 1).Value
ReDim Preserve result(1 To UBound(result), 1 To 3)
For i = 1 To UBound(result) - 1
If Len(result(i, 1)) Then
tmp = result(i, 1)
If Dic.exists(tmp) Then
result(i, 1) = aResult(Dic.Item(tmp), 3) 'NGANH HANG
result(i, 2) = aResult(Dic.Item(tmp), 5) 'LOAI HANG
result(i, 3) = aResult(Dic.Item(tmp), 4) 'HANG
Else
result(i, 1) = "KHÁC"
result(i, 2) = "KHÁC" ' Thêm
result(i, 3) = "KHÁC" ' Thêm
End If
End If
Next i
change.Offset(0, 36).Resize(, 3).Value = result
End If
' ngay thang
Set change = Intersect(Target, Range("M851:M600000")) ' Ngay Thang Nam, Tuan
If Not change Is Nothing Then
result = change.Resize(change.Rows.Count + 1).Value
ReDim Preserve result(1 To UBound(result), 1 To 5)
For i = 1 To UBound(result) - 1
If Len(result(i, 1)) Then
result(i, 2) = WorksheetFunction.Text(result(i, 1), "[$-42A]ddd")
result(i, 3) = Format(result(i, 1), "d")
result(i, 4) = Format(result(i, 1), "m")
result(i, 5) = Format(result(i, 1), "yyyy")
result(i, 1) = Format(result(i, 1), "ww")
End If
Next i
change.Offset(0, 31).Resize(, 5).Value = result
End If
' Phan Khuc Gia va cot BA
Set change = Intersect(Target, Range("AC851:AC600000"))
If Not change Is Nothing Then
result = change.Resize(change.Rows.Count + 1).Value
ba = result
For i = 1 To UBound(result) - 1
ba(i, 1) = result(i, 1) / 1.1
If Len(result(i, 1)) Then
Select Case result(i, 1) / 10 ^ 6
Case Is <= 1: result(i, 1) = "<1M"
Case Is <= 2: result(i, 1) = "1M-2M"
Case Is <= 4: result(i, 1) = "2M-4M"
Case Is <= 6: result(i, 1) = "4M-6M"
Case Is <= 8: result(i, 1) = "6M-8M"
Case Is <= 10: result(i, 1) = "8M-10M"
Case Is <= 12: result(i, 1) = "10M-12M"
Case Is <= 14: result(i, 1) = "12M-14M"
Case Is <= 16: result(i, 1) = "14M-16M"
Case Is <= 18: result(i, 1) = "16M-18M"
Case Is <= 20: result(i, 1) = "18M-20M"
Case Else: result(i, 1) = "Tren 20M"
End Select
End If
Next i
' Phan Khuc Gia
change.Offset(0, 14).Value = result
' cot BA
Range("BA" & change.Row).Resize(UBound(ba) - 1).Value = ba
End If
' cot AY
Set change = Intersect(Target, Range("M851:M600000, P851:P600000"))
If Not change Is Nothing Then
Set so_ngay_ma = CreateObject("Scripting.Dictionary")
result = Range("M" & change.Row).Resize(change.Rows.Count + 1).Value
cot2 = Range("M" & change.Row).Offset(0, 3).Resize(change.Rows.Count + 1).Value
For i = 1 To UBound(result) - 1
songayma = result(i, 1) & "-" & cot2(i, 1)
If so_ngay_ma.exists(songayma) Then
result(i, 1) = 0
Else
result(i, 1) = 1
so_ngay_ma.Add songayma, ""
End If
Next i
Cells(change.Row, "AY").Resize(UBound(result) - 1).Value = result
Set so_ngay_ma = Nothing
End If
' cot AZ
Set change = Intersect(Target, Range("C851:C600000, M851:M600000"))
If Not change Is Nothing Then
Set so_ngay_ma = CreateObject("Scripting.Dictionary")
result = Range("C" & change.Row).Resize(change.Rows.Count + 1).Value
cot2 = Range("C" & change.Row).Offset(0, 10).Resize(change.Rows.Count + 1).Value
For i = 1 To UBound(result) - 1
songayma = result(i, 1) & "-" & cot2(i, 1)
If so_ngay_ma.exists(songayma) Then
result(i, 1) = 0
Else
result(i, 1) = 1
so_ngay_ma.Add songayma, ""
End If
Next i
Cells(change.Row, "AZ").Resize(UBound(result) - 1).Value = result
Set so_ngay_ma = Nothing
End If
Application.EnableEvents = True
Application.ScreenUpdating = True
Debug.Print Timer - t
End Sub
Do bạn không nói nên tôi làm theo công thức thôi. Công thức không trả về chuỗi rỗng khi xóa dữ liệu nguồnTuy nhiên
- cột AY (LUOT KHACH MUA) ,
- cột AZ (SỐ BILL),
- cột BA ( DOANH THU)
Khi em xóa dữ liệu thì nó không xóa kết quả, anh hỗ trợ em phần này nhe
=N(COUNTIFS($P$3:P3;P3;$M$3:M3;M3)=1)
Private Sub Worksheet_Change(ByVal Target As Range)
Dim i As Long, tmp
Dim result(), cot2(), ba(), change As Range, songayma As String, so_ngay_ma As Object
Application.EnableEvents = False
Application.ScreenUpdating = False
Set change = Intersect(Range("D851:D600000"), Target)
If Not change Is Nothing Then
If Dic Is Nothing Then Vlookup_DATA_SP
result = change.Resize(change.Rows.Count + 1).Value
ReDim Preserve result(1 To UBound(result), 1 To 3)
For i = 1 To UBound(result) - 1
If Len(result(i, 1)) Then
tmp = result(i, 1)
If Dic.exists(tmp) Then
result(i, 1) = aResult(Dic.Item(tmp), 3) 'NGANH HANG
result(i, 2) = aResult(Dic.Item(tmp), 5) 'LOAI HANG
result(i, 3) = aResult(Dic.Item(tmp), 4) 'HANG
Else
result(i, 1) = "KHÁC"
result(i, 2) = "KHÁC" ' Them
result(i, 3) = "KHÁC" ' Them
End If
End If
Next i
change.Offset(0, 36).Resize(, 3).Value = result
End If
' ngay thang
Set change = Intersect(Target, Range("M851:M600000")) ' Ngay Thang Nam, Tuan
If Not change Is Nothing Then
result = change.Resize(change.Rows.Count + 1).Value
ReDim Preserve result(1 To UBound(result), 1 To 5)
For i = 1 To UBound(result) - 1
If Len(result(i, 1)) Then
result(i, 2) = WorksheetFunction.Text(result(i, 1), "[$-42A]ddd")
result(i, 3) = Format(result(i, 1), "d")
result(i, 4) = Format(result(i, 1), "m")
result(i, 5) = Format(result(i, 1), "yyyy")
result(i, 1) = Format(result(i, 1), "ww")
End If
Next i
change.Offset(0, 31).Resize(, 5).Value = result
End If
' Phan Khuc Gia va cot BA
Set change = Intersect(Target, Range("AC851:AC600000"))
If Not change Is Nothing Then
result = change.Resize(change.Rows.Count + 1).Value
ba = result
For i = 1 To UBound(result) - 1
If Len(result(i, 1)) Then
ba(i, 1) = result(i, 1) / 1.1
Select Case result(i, 1) / 10 ^ 6
Case Is <= 1: result(i, 1) = "<1M"
Case Is <= 2: result(i, 1) = "1M-2M"
Case Is <= 4: result(i, 1) = "2M-4M"
Case Is <= 6: result(i, 1) = "4M-6M"
Case Is <= 8: result(i, 1) = "6M-8M"
Case Is <= 10: result(i, 1) = "8M-10M"
Case Is <= 12: result(i, 1) = "10M-12M"
Case Is <= 14: result(i, 1) = "12M-14M"
Case Is <= 16: result(i, 1) = "14M-16M"
Case Is <= 18: result(i, 1) = "16M-18M"
Case Is <= 20: result(i, 1) = "18M-20M"
Case Else: result(i, 1) = "Tren 20M"
End Select
End If
Next i
' Phan Khuc Gia
change.Offset(0, 14).Value = result
' cot BA
Range("BA" & change.Row).Resize(UBound(ba) - 1).Value = ba
End If
' cot AY
Set change = Intersect(Target, Range("M851:M600000, P851:P600000"))
If Not change Is Nothing Then
Set so_ngay_ma = CreateObject("Scripting.Dictionary")
result = Range("M" & change.Row).Resize(change.Rows.Count + 1).Value
cot2 = Range("M" & change.Row).Offset(0, 3).Resize(change.Rows.Count + 1).Value
For i = 1 To UBound(result) - 1
If Len(result(i, 1)) And Len(cot2(i, 1)) Then
songayma = result(i, 1) & "-" & cot2(i, 1)
If so_ngay_ma.exists(songayma) Then
result(i, 1) = 0
Else
result(i, 1) = 1
so_ngay_ma.Add songayma, ""
End If
Else
result(i, 1) = Empty
End If
Next i
Cells(change.Row, "AY").Resize(UBound(result) - 1).Value = result
Set so_ngay_ma = Nothing
End If
' cot AZ
Set change = Intersect(Target, Range("C851:C600000, M851:M600000"))
If Not change Is Nothing Then
Set so_ngay_ma = CreateObject("Scripting.Dictionary")
result = Range("C" & change.Row).Resize(change.Rows.Count + 1).Value
cot2 = Range("C" & change.Row).Offset(0, 10).Resize(change.Rows.Count + 1).Value
For i = 1 To UBound(result) - 1
If Len(result(i, 1)) And Len(cot2(i, 1)) Then
songayma = result(i, 1) & "-" & cot2(i, 1)
If so_ngay_ma.exists(songayma) Then
result(i, 1) = 0
Else
result(i, 1) = 1
so_ngay_ma.Add songayma, ""
End If
Else
result(i, 1) = Empty
End If
Next i
Cells(change.Row, "AZ").Resize(UBound(result) - 1).Value = result
Set so_ngay_ma = Nothing
End If
Application.EnableEvents = True
Application.ScreenUpdating = True
End Sub
Quá tuyệt vời1. Chỉ cần hoặc M hoặc P rỗng thì cột AY rỗng. Tức không cần đồng thời M và P rỗng. Tất nhiên theo lôgíc thì khi M rỗng thì P cũng phải rỗng. Nhưng đây là việc của người "đổ dữ liệu vào sheet"
2. Chỉ cần hoặc C hoặc M rỗng thì cột AZ rỗng. Tức không cần đồng thời C và M rỗng. Tất nhiên theo lôgíc thì khi C rỗng thì M cũng phải rỗng. Nhưng đây là việc của người "đổ dữ liệu vào sheet"
Mã:Private Sub Worksheet_Change(ByVal Target As Range) Dim i As Long, tmp Dim result(), cot2(), ba(), change As Range, songayma As String, so_ngay_ma As Object Application.EnableEvents = False Application.ScreenUpdating = False Set change = Intersect(Range("D851:D600000"), Target) If Not change Is Nothing Then If Dic Is Nothing Then Vlookup_DATA_SP result = change.Resize(change.Rows.Count + 1).Value ReDim Preserve result(1 To UBound(result), 1 To 3) For i = 1 To UBound(result) - 1 If Len(result(i, 1)) Then tmp = result(i, 1) If Dic.exists(tmp) Then result(i, 1) = aResult(Dic.Item(tmp), 3) 'NGANH HANG result(i, 2) = aResult(Dic.Item(tmp), 5) 'LOAI HANG result(i, 3) = aResult(Dic.Item(tmp), 4) 'HANG Else result(i, 1) = "KHÁC" result(i, 2) = "KHÁC" ' Them result(i, 3) = "KHÁC" ' Them End If End If Next i change.Offset(0, 36).Resize(, 3).Value = result End If ' ngay thang Set change = Intersect(Target, Range("M851:M600000")) ' Ngay Thang Nam, Tuan If Not change Is Nothing Then result = change.Resize(change.Rows.Count + 1).Value ReDim Preserve result(1 To UBound(result), 1 To 5) For i = 1 To UBound(result) - 1 If Len(result(i, 1)) Then result(i, 2) = WorksheetFunction.Text(result(i, 1), "[$-42A]ddd") result(i, 3) = Format(result(i, 1), "d") result(i, 4) = Format(result(i, 1), "m") result(i, 5) = Format(result(i, 1), "yyyy") result(i, 1) = Format(result(i, 1), "ww") End If Next i change.Offset(0, 31).Resize(, 5).Value = result End If ' Phan Khuc Gia va cot BA Set change = Intersect(Target, Range("AC851:AC600000")) If Not change Is Nothing Then result = change.Resize(change.Rows.Count + 1).Value ba = result For i = 1 To UBound(result) - 1 If Len(result(i, 1)) Then ba(i, 1) = result(i, 1) / 1.1 Select Case result(i, 1) / 10 ^ 6 Case Is <= 1: result(i, 1) = "<1M" Case Is <= 2: result(i, 1) = "1M-2M" Case Is <= 4: result(i, 1) = "2M-4M" Case Is <= 6: result(i, 1) = "4M-6M" Case Is <= 8: result(i, 1) = "6M-8M" Case Is <= 10: result(i, 1) = "8M-10M" Case Is <= 12: result(i, 1) = "10M-12M" Case Is <= 14: result(i, 1) = "12M-14M" Case Is <= 16: result(i, 1) = "14M-16M" Case Is <= 18: result(i, 1) = "16M-18M" Case Is <= 20: result(i, 1) = "18M-20M" Case Else: result(i, 1) = "Tren 20M" End Select End If Next i ' Phan Khuc Gia change.Offset(0, 14).Value = result ' cot BA Range("BA" & change.Row).Resize(UBound(ba) - 1).Value = ba End If ' cot AY Set change = Intersect(Target, Range("M851:M600000, P851:P600000")) If Not change Is Nothing Then Set so_ngay_ma = CreateObject("Scripting.Dictionary") result = Range("M" & change.Row).Resize(change.Rows.Count + 1).Value cot2 = Range("M" & change.Row).Offset(0, 3).Resize(change.Rows.Count + 1).Value For i = 1 To UBound(result) - 1 If Len(result(i, 1)) And Len(cot2(i, 1)) Then songayma = result(i, 1) & "-" & cot2(i, 1) If so_ngay_ma.exists(songayma) Then result(i, 1) = 0 Else result(i, 1) = 1 so_ngay_ma.Add songayma, "" End If Else result(i, 1) = Empty End If Next i Cells(change.Row, "AY").Resize(UBound(result) - 1).Value = result Set so_ngay_ma = Nothing End If ' cot AZ Set change = Intersect(Target, Range("C851:C600000, M851:M600000")) If Not change Is Nothing Then Set so_ngay_ma = CreateObject("Scripting.Dictionary") result = Range("C" & change.Row).Resize(change.Rows.Count + 1).Value cot2 = Range("C" & change.Row).Offset(0, 10).Resize(change.Rows.Count + 1).Value For i = 1 To UBound(result) - 1 If Len(result(i, 1)) And Len(cot2(i, 1)) Then songayma = result(i, 1) & "-" & cot2(i, 1) If so_ngay_ma.exists(songayma) Then result(i, 1) = 0 Else result(i, 1) = 1 so_ngay_ma.Add songayma, "" End If Else result(i, 1) = Empty End If Next i Cells(change.Row, "AZ").Resize(UBound(result) - 1).Value = result Set so_ngay_ma = Nothing End If Application.EnableEvents = True Application.ScreenUpdating = True End Sub