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

- Tham gia
- 8/2/12
- Bài viết
- 412
- Được thích
- 111
=COUNTIF($C$3:$C$10,$C3)>1
Sub Button1_Click()
Dim cls As Range
For Each cls In [c3:c10]
For i = 3 To 10
If cls = Cells(i, 3) And cls.Row <> i Then
Range(Cells(i, 1), Cells(i, 3)).Font.ColorIndex = 3
End If
Next
Next
End Sub
1> Copy 2 đoạn code này vào 1 ModuleCác cách làm trên quá chuẩn rồi, nhưng nếu bài này mà làm bằng VBA thì ta viết thế nào?
Sub sRowColor(ByVal SrcRng As Range, ByVal Color As Long)
Dim Dic As Object, tmpArr, tmpRow(), tmp, Arr(), lR As Long, lC As Long
On Error Resume Next
SrcRng.Font.ColorIndex = -4105
tmpArr = SrcRng.Value
Set Dic = CreateObject("Scripting.Dictionary")
For lR = 1 To UBound(tmpArr, 1)
If tmpArr(lR, 1) <> "" Then
ReDim tmpRow(1 To UBound(tmpArr, 2))
For lC = 1 To UBound(tmpArr, 2)
tmpRow(lC) = tmpArr(lR, lC)
Next
tmp = Join(tmpRow, "")
If Trim(tmp) <> "" Then
tmp = Join(tmpRow, Chr(0))
If Not Dic.Exists(tmp) Then
Dic.Add tmp, lR
Else
SrcRng.Rows(Dic.Item(tmp)).Font.ColorIndex = Color
SrcRng.Rows(lR).Font.ColorIndex = Color
End If
End If
End If
Next
End Sub
Sub Main()
Dim SrcRng As Range
On Error Resume Next
Set SrcRng = Selection
sRowColor SrcRng, 3
End Sub
Bạn thử code này xem
Mã:Sub Button1_Click() Dim cls As Range For Each cls In [c3:c10] For i = 3 To 10 If cls = Cells(i, 3) And cls.Row <> i Then Range(Cells(i, 1), Cells(i, 3)).Font.ColorIndex = 3 End If Next Next End Sub
(Các bài viết không đáng tks sao?)
Được, khoảng 50 màu thôi thì OkNếu bài toán mở rộng là:
Đối với các ô có giá trị bằng nhau (được lặp lại từ 2 lần trở lên) sẽ được tô cùng màu.
Các ô có giá trị khác nhau (vẫn đảm bảo điều kiện lặp từ 2 lần trở lên) thì tô khác màu.
(Số lượng màu dùng để tô có thể lấy ngẫu nhiên).
Liệu bài toán này có thể làm được không
Quét chọn vùng dữ liệu rồi ấn Alt+F8 chạy thử code này nhé bạn.Các cách làm trên quá chuẩn rồi, nhưng nếu bài này mà làm bằng VBA thì ta viết thế nào?
Sub FormatColumnC()
With Selection
.FormatConditions.Add Type:=xlExpression, Formula1:="=COUNTIF($C:$C,$C1)>1"
.FormatConditions(1).Interior.ThemeColor = xlThemeColorAccent6
End With
End Sub
Sub sRowColor(ByVal SrcRng As Range, ByVal Color As Long)
Dim Dic As Object, tmpArr, tmpRow(), tmp, Arr(), lR As Long, lC As Long
On Error Resume Next
SrcRng.Font.ColorIndex = -4105
tmpArr = SrcRng.Value
Set Dic = CreateObject("Scripting.Dictionary")
For lR = 1 To UBound(tmpArr, 1)
If tmpArr(lR, 1) <> "" Then
ReDim tmpRow(1 To UBound(tmpArr, 2))
For lC = 1 To UBound(tmpArr, 2)
tmpRow(lC) = tmpArr(lR, lC)
Next
tmp = Join(tmpRow, "")
If Trim(tmp) <> "" Then
tmp = Join(tmpRow, Chr(0))
If Not Dic.Exists(tmp) Then
Dic.Add tmp, lR
Else
SrcRng.Rows(Dic.Item(tmp)).Font.ColorIndex = Color
SrcRng.Rows(lR).Font.ColorIndex = Color
End If
End If
End If
Next
End Sub
Sub Main()
Dim SrcRng As Range
On Error Resume Next
Set SrcRng = Selection
sRowColor SrcRng, 3
End Sub
1> Copy 2 đoạn code này vào 1 Module
PHP:Sub sRowColor(ByVal SrcRng As Range, ByVal Color As Long) Dim Dic As Object, tmpArr, tmpRow(), tmp, Arr(), lR As Long, lC As Long On Error Resume Next SrcRng.Font.ColorIndex = -4105 tmpArr = SrcRng.Value Set Dic = CreateObject("Scripting.Dictionary") For lR = 1 To UBound(tmpArr, 1) If tmpArr(lR, 1) <> "" Then ReDim tmpRow(1 To UBound(tmpArr, 2)) For lC = 1 To UBound(tmpArr, 2) tmpRow(lC) = tmpArr(lR, lC) Next tmp = Join(tmpRow, "") If Trim(tmp) <> "" Then tmp = Join(tmpRow, Chr(0)) If Not Dic.Exists(tmp) Then Dic.Add tmp, lR Else SrcRng.Rows(Dic.Item(tmp)).Font.ColorIndex = Color SrcRng.Rows(lR).Font.ColorIndex = Color End If End If End If Next End Sub
2> Quét chọn vùng dữ liệu cần tô màu rồi bấm Alt + F8, chạy Sub MainPHP:Sub Main() Dim SrcRng As Range On Error Resume Next Set SrcRng = Selection sRowColor SrcRng, 3 End Sub
------------------
Code này cho phép tô màu dữ liệu trùng trên nhiều cột (có thể cải tiến thêm cho nó tô màu nhiều cột nhưng không nằm liên tục nhau)
Phải quét chọn vùng rồi mới chạy code chứ (vì đã Set SrcRng = Selection rồi còn gì)Sao tôi chạy nó không được nhỉ? Xin thày Ndu và mọi người hướng dẫn cho
Phải quét chọn vùng rồi mới chạy code chứ (vì đã Set SrcRng = Selection rồi còn gì)
Sự liên kết này cũng giống như bạn viết 1 hàm trong VBA rồi gõ lên bảng tính thôiXin nhờ thày giảng hộ cho:
- Tại sao Sub Main nó lại điều khiển được Sub sRowColor (có link)?. Sự liên kết của chúng thể hiện ở dòng nào hả thày?
- sRowColor SrcRng, 3 là gì thế hả thày (chắc gán đối tượng gì gì đó cho nó màu đỏ)?
Vì nhiều cái chưa biết, rất mong thày giải thích giúp.
Vùng A1:C9 chẳng có dòng nào trùng với dòng nào cả, lấy đâu mà tô ---> Thử copy A1:C1 và paste vào A5:C5 rồi chạy lại code xem
Tôi cũng có làm như thày bảo mà, tức là Chọn vùng (A1:C9), sau đó ấn Alt+F8 chạy Sub Main nhưng không thấy bôi màu.
Sự liên kết này cũng giống như bạn viết 1 hàm trong VBA rồi gõ lên bảng tính thôi
- Hàm tự tạo có các tham số
- Khi gõ vào bảng tính, ta sẽ "truyền" các tham số vào bằng các giá trị cụ thể
- Với Sub có tham số truyền (nhu Sub sRowColor) cũng vậy thôi ---> Nó gồm 2 tham số: SrcRng (vùng dữ liệu) và Color (màu tùy chọn)... Giờ bạn đăt SrcRng là vùng nào, với màu nào tùy bạn, nó sẽ chạy thôi
----------------------
Vùng A1:C9 chẳng có dòng nào trùng với dòng nào cả, lấy đâu mà tô ---> Thử copy A1:C1 và paste vào A5:C5 rồi chạy lại code xem
Sub sRowColor(ByVal Vungchon As Range, ByVal Color As Long)
Dim Dic As Object, DL, tmpRow(), Tmp, i As Long
On Error Resume Next
Vungchon.Font.ColorIndex = -4105
DL = Vungchon.Value
Set Dic = CreateObject("Scripting.Dictionary")
For i = 1 To UBound(DL, 1)
If DL(i, 3) <> "" Then
Tmp = DL(i, 3)
If Not Dic.Exits(Tmp) Then
Dic.Add Tmp, i
Else
Vungchon.Rows(Dic.Item(Tmp)).Font.ColorIndex = Color
Vungchon.Rows(i).Font.ColorIndex = Color
End If
End If
Next
End Sub
Sub DMain()
Dim Vungchon As Range
On Error Resume Next
Set Vungchon = Range("A1:C10")
sRowColor Vungchon, 3
End Sub
Chính xác là vậy! Join(Mảng, dấu phân cách) sẽ nối các phần tử trong mảng với nhau bằng dấu phân cách ---------- Muốn dùng cho cột C thì quét chọn cột C thôi Ẹc... Ẹc...Chạy rất tốt rồi ah, hóa ra cái này thày viết cho cả dòng, thế nên mới có Joint Jonit gì đó (đoán vậy chứ Joint chưa biết bao giờ, chỉ thấy dịch sang VN nghĩa là nối thôi), chứ không phải cho cột C Tối nay lại có cái mới để nghiên cứu rồi
Trời, bài của thày tổng quát, muốn đơn giản cột nào thì chọn cột đó thôi, đơn giản vậy mà tôi không nghĩ được, cảm ơn thày rất nhiều.Chính xác là vậy!
Join(Mảng, dấu phân cách) sẽ nối các phần tử trong mảng với nhau bằng dấu phân cách
----------
Muốn dùng cho cột C thì quét chọn cột C thôi
Ẹc... Ẹc...
Nó hiểu nhờ vào câu nàyTôi thắc mắc là cú pháp: sRowColor SrcRng, 3 thì tại sao máy lại hiểu thành phần thứ 3 (tức là số 3) là đặc tính màu của vùng đó, mà không phải là các đặc tính của vùng như Font chữ, cỡ chữ nhỉ?
Hay là nó hiểu được là do cái từ Color trong câu Sub sRowColor(ByVal SrcRng As Range, ByVal Color As Long?
Sub Test()
Dim i As Long
For i = 1 To 56
Cells(i, 1).Interior.ColorIndex = i
Next
End Sub
Sub có tham số truyền phải tổng quat, tức không được chỉ đến chính xác 1 vùng nào cả (khi nào xài mới "truyền")Nhưng do những cái này chưa biết, nghiên cứu cũng rất tốt, vừa rồi có mạo muội làm thử xem như bài trên nhưng chạy không ra được kết quả, xin thày chỉ cho chỗ sai.
Sub có tham số truyền phải tổng quat, tức không được chỉ đến chính xác 1 vùng nào cả (khi nào xài mới "truyền")
Trong khi đó code của bạn lại có đoạn If DL(i, 3) <> "" Then thế hóa ra "buộc" phải luôn luôn làm việc với cột thứ 3 của Vung à? Vô lý! Nếu thế thì thà rằng viết 1 Sub bình thường cho rồi ---> "Truyền nước biển" làm gì cho mất công
Sub Tomau()
Dim Vung, DL(), i As Long, dongcuoi As Long
Set Dic = CreateObject("Scripting.Dictionary")
dongcuoi = [C65000].End(xlUp).Row
Set Vung = Range("A1:C" & dongcuoi)
DL = Vung.Value
For i = 1 To UBound(DL, 1)
If DL(i, 3) <> "" Then
Tmp = DL(i, 3)
If Not Dic.Exists(Tmp) Then
Dic.Add Tmp, i
Else
Vung.Rows(Dic.Item(Tmp)).Font.ColorIndex = 3
Vung.Rows(i).Font.ColorIndex = 3
End If
End If
Next
End Sub
Ah... không!Như vậy hiểu thế này có đúng không ah:
Những từ Color (được bôi màu đỏ) trong các câu:
+ SrcRng.Rows(Dic.Item(tmp)).Font.ColorIndex = Color.
+ Sub sRowColor(ByVal SrcRng As Range, ByVal Color As Long)
Phải hoàn toàn giống nhau và không được thay thế bằng từ khác? (vì nó là từ cứng được định nghĩa trong VBA)?
Không cần phải là bài toán LỌC DUY NHẤT, miễn sao có yếu tố DUY NHẤT hoặc yếu tố TỒN TẠI, KHÔNG TỒN TẠI trong đó là ta có thể nghĩ đến Dictionary (trong bài tô màu này là xét đến yếu tố tồn tại)Thế mới biết thằng "Đít" này lợi hại gớm, nếu sáng tạo ra thì nó có thể ứng dụng vào giải quyết rất nhiều bài chứ không chỉ đơn thuần là lọc duy nhất.
Thành phần SrcRng.Font.ColorIndex = -4105 thày đưa vào nó có ý nghĩa gì thế?
Đương nhiên đâu tiên vào phải xóa hết các màu sắc nếu có của cell, xong rồi mới tô chứ, đúng không?Thành phần SrcRng.Font.ColorIndex = -4105 thày đưa vào nó có ý nghĩa gì thế?