.Replace What:=oldText, Replacement:=newText, LookAt:=xlPart, SearchOrder _
:=xlByRows, MatchCase:=False, SearchFormat:=False, ReplaceFormat:=False
Option Explicit
Sub TimVaThayThe()
Dim DiaChi As String 'Sa
Dim MyRng As Range, Rng As Range
Set MyRng = Range(Cells(1, 1), Cells(18, 4))
Dim oldText As String, newText As String
oldText = "3"
newText = "test"
With MyRng
Set Rng = .Find(What:=oldText, LookIn:=xlValues, LookAt:=xlWhole)
Set Rng = .Find(What:=oldText, After:=ActiveCell,LookIn:=xlValues, LookAt:=xlxlPart)
If Not Rng Is Nothing Then
DiaChi = Rng.Address
Do
With Rng.Offset(, 5)
With Rng
.Value = newText
.Interior.ColorIndex = 36
.Font.Bold = True
End With
Set Rng = .FindNext(Rng)
If Rng Is Nothing Then Exit Sub
Loop While Not Rng Is Nothing And Rng.Address <> DiaChi
End If
End With
End Sub
Sub TimVaGan()
Dim DiaChi As String, i As Long
Dim MyRng As Range, Rng As Range
Set MyRng = Range(Cells(1, 1), Cells(18, 4))
Dim oldText As String
Dim MyArr()
i = 1
ReDim MyArr(1 To MyRng.Count)
oldText = "3"
With MyRng
Set Rng = .Find(What:=oldText, LookIn:=xlValues, LookAt:=xlPart)
If Not Rng Is Nothing Then
DiaChi = Rng.Address
Do
MyArr(i) = Rng.Value
i = i + 1
Set Rng = .FindNext(Rng)
If Rng Is Nothing Then GoTo bien
Loop While Not Rng Is Nothing And Rng.Address <> DiaChi
End If
End With
bien:
With Sheets("sheet2")
.Cells.ClearContents
For i = LBound(MyArr) To UBound(MyArr)
.Cells(i, 1) = MyArr(i)
Next
End With
End Sub
ThuNghi nhờ thì hiệu đính thôi, chứ tuyệt nhiên không có ý định gây áp lực đâu HoangDanh nhaBác Sa hiệu đính lại giúp. Cám ơn Bác. Hậu tạ.
Các bạn cứ xem mình cũng mới biết Find() qua bài dịch của Kiệt (Ca_dafi).
Option Explicit
Sub TimVaThayThe()
Dim DiaChi As String
Dim MyRng As Range, Rng As Range
Set MyRng = Range(Cells(1, 1), Cells(18, "D"))
' Dim newText As String'
Const oldText As Long = 3
With MyRng
Set Rng = .Find(What:=oldText, LookIn:=xlValues, LookAt:=xlWhole)
If Not Rng Is Nothing Then
DiaChi = Rng.Address
Do
With Rng
.Value = "test": .Font.Bold = True
.Interior.ColorIndex = 36
End With
Set Rng = .FindNext(Rng)
If Rng Is Nothing Then Exit Sub
Loop While Not Rng Is Nothing And Rng.Address <> DiaChi
End If
End With
End Sub
Option Explicit
Sub xIndex()
With Application
.ScreenUpdating = False
End With
Dim DiaChi As String, eRow As Long, iR As Long
Dim MyRng As Range, Rng As Range, RngDM As Range
Dim oldText As String
Sheets("Data").Select
With Sheets("Index")
eRow = .[a1000].End(xlUp).Row - 1
Set RngDM = .Range(.Cells(2, 1), .Cells(eRow, 3))
End With
Columns("B:B").ClearComments
Columns("A:D").ClearFormats
eRow = [a1000].End(xlUp).Row
Range(Cells(2, 3), Cells(eRow, 4)).ClearContents
Set MyRng = Range(Cells(2, 2), Cells(eRow, 2))
For iR = 1 To eRow
oldText = RngDM.Cells(iR)
With MyRng
Set Rng = .Find(What:=oldText, LookIn:=xlValues, LookAt:=xlWhole)
If Not Rng Is Nothing Then
DiaChi = Rng.Address
Do
With Rng
If .Value = "A1" Then
With .Offset(0, -1).Resize(, 4).Font
.ColorIndex = 5
.Bold = True
End With
.AddComment
.Comment.Visible = False
.Comment.Text Text:="GPE:" & Chr(10) & "OK"
End If
.Offset(, 1).Value = RngDM.Cells(iR).Offset(, 1)
With .Offset(, 2)
.Value = RngDM.Cells(iR).Offset(, 2)
.NumberFormat = "#,##0"
End With
End With
Set Rng = .FindNext(Rng)
If Rng Is Nothing Then Exit Sub
Loop While Not Rng Is Nothing And Rng.Address <> DiaChi
End If
End With
Next
Set RngDM = Nothing
Set MyRng = Nothing
With Application
.ScreenUpdating = True
End With
End Sub
Theo ý mình nó như vầy; Nói nhỏ:"Ngoài cách giới thiệu phương thức FIND(), macro này là một điển hình về cách dùngEm vẫn trung thành đặt thêm biến NewText hay là NewS. Dù nó chỉ 1 lần nhưng khi thay đổi Code thì tìm mau hơn.
Bỏ một bữa eat out nghiên cứu tìm thấy thêm 1 vấn đề. Có thể dùng Find để thay thế Vlookup, Index Match tiện hơn thay vì for i.
Tôi làm thử 1 ví dụ xem thử. Lấy thông số ở sh Index gán vào cột C, D của sh Data. Format (tô), insert comment theo điều kiện chọn.
Hóa ra vừa nghiên cứu thêm mà lại giữ sức khỏe. Xin Bác Sa edit tiếp nhé. Cám ơn Bác.
Option Explicit
Sub xIndex()
Dim DiaChi As String, eRow As Long, jF As Long
Dim MyRng As Range, Rng As Range, RngDM As Range
Dim OldText As String
Application .ScreenUpdating = False
With Sheets("Index")
eRow = .[a1000].End(xlUp).Row - 1
Set RngDM = .Range(.Cells(2, 1), .Cells(eRow, "C"))
End With
Sheets("Data").Select
Columns("B:B").ClearComments
Columns("A:D").ClearFormats: eRow = [a65000].End(xlUp).Row
Range(Cells(2, 3), Cells(eRow, 4)).ClearContents
Set MyRng = Range([B2], Cells(eRow, 2))
For jF = 1 To eRow
OldText = RngDM.Cells(jF)
With MyRng
Set Rng = .Find(What:=OldText, LookIn:=xlValues, LookAt:=xlWhole)
If Not Rng Is Nothing Then
DiaChi = Rng.Address
Do
With Rng
If .Value = "A1" Then
With .Offset(0, -1).Resize(, 4).Font
.ColorIndex = 5: .Bold = True
End With
.AddComment: .Comment.Visible = False
.Comment.Text Text:="GPE:" & Chr(10) & "OK"
End If
.Offset(, 1).Value = RngDM.Cells(jF).Offset(, 1)
With .Offset(, 2)
.Value = RngDM.Cells(jF).Offset(, 2)
.NumberFormat = "#,##0"
End With
End With
Set Rng = .FindNext(Rng)
If Rng Is Nothing Then Exit Sub
Loop While Not Rng Is Nothing And Rng.Address <> DiaChi
End If
End With
Next
Set RngDM = Nothing: Set MyRng = Nothing
End Sub
With MyRng
Set Rng = .Find(What:=OldText, LookIn:=xlValues, LookAt:=xlWhole)
If Not Rng Is Nothing Then
...
End With
Sub MyFind()
Dim r As Long, rW As Long, rF1 As Long, rF2 As Long, S As Long
Dim sFind
On Error Resume Next
Columns("B").ClearContents
r = 1
sFind = InputBox("Nhap du lieu tim:")
rF1 = [COLOR=Red][B]Columns("A")[/B][/COLOR].Find(What:=sFind, After:=Cells(1, 1)).Row
If rF1 = 0 Then Exit Sub
rF2 = rF1
Do
Cells(r, 2) = Cells(rF2, 1)
r = r + 1
rF2 = Columns("A").Find(What:=sFind, After:=Cells(rF2, 1)).Row
If rF2 <= rF1 Then Exit Do
Loop
End Sub
Cách của thầy Long cũng như cách khác, đều dùng vòng lặp Do . . . Loop cả mà!Xin tham gia đề tài một ví dụ về Find
Tôi lại không thích dùng:
Mã:With MyRng Set Rng = .Find(What:=OldText, LookIn:=xlValues, LookAt:=xlWhole) If Not Rng Is Nothing Then ... End With
Mà dùng vòng lặp Do ... Loop
Code dưới đây tìm chuỗi sFind (nhập từ InputBox) trong cột A và ghi cột B nội dung ô tìm được.. . .
Chưa so sánh xem 2 cách có khác nhau về tốc độ không nhưng viết gọn hơn
Sub Find_Sun()
Dim lCount As Long '(Ozgrid.com)
Dim rFoundCell As Range
Set rFoundCell = Range("A1")
For lCount = 1 To WorksheetFunction.CountIf(Columns(1), "Sun")
Set rFoundCell = Columns(1).Find(What:="Sun", After:=rFoundCell, _
LookIn:=xlValues, LookAt:=xlPart, SearchOrder:=xlByRows, _
SearchDirection:=xlNext, MatchCase:=False)
With rFoundCell.Offset(, 2)
.Value = rFoundCell
.ClearComments
.AddComment Text:="Ozgrid.com"
End With
Next lCount
End Sub
Tôi cụ thể bài dịch của Find Method theo Ozgrid.com bằng code sau:
Tôi xin thay Cat=Sun vì tôi ghét Cat
Code này tìm trong côt 1 những chữ "Sun" thì AddComment Text:="Ozgrid.com" vào cell bên cạnh. Để ý Next lCount rất hay.PHP:Sub Find_Sun() Dim lCount As Long '(Ozgrid.com) Dim rFoundCell As Range Set rFoundCell = Range("A1") For lCount = 1 To WorksheetFunction.CountIf(Columns(1), "Sun") Set rFoundCell = Columns(1).Find(What:="Sun", After:=rFoundCell, _ LookIn:=xlValues, LookAt:=xlPart, SearchOrder:=xlByRows, _ SearchDirection:=xlNext, MatchCase:=False) With rFoundCell.Offset(, 2) .Value = rFoundCell .ClearComments .AddComment Text:="Ozgrid.com" End With Next lCount End Sub
Code này sẽ khác phục vòng lặp Do...Loop vì nó chỉ
số lần findNext =WorksheetFunction.CountIf(Columns(1), "Sun")
Còn nhanh , chậm thì em chưa biết.
To: Thầy Long
Code của Thầy còn thiếu
range(....).select
Còn nếu column(1).select
rF1 = column(1).Find(What:=sFind, After:=Cells(1, 1)).Row
thì dòng lệnh này dư After:=Cells(1, 1), bởi chắc rằng ta đang tìm trên côt 1.
Thú thật cái After:=ActiveCells này có cần thiết với find không thì em chưa biết, bởi vì khi ta select thì ta chắc rằng find tìm hết selection.
Loop While Not Rng Is Nothing And Rng.Address <> DiaChi
For lCount = 1 To WorksheetFunction.CountIf(Columns(1), "Sun")
Cám ơn lời gợi ý, nhờ vậy mình mới tìm thấy cái hay của find. Các bạn xem thử code sau, tìm trong A, B, C có những cell nào có "ch". Ta chọn thử MyRng là 3 cột A, B, CNhưng dù sao thì đây cũng là một ý tưởng hay, tuy nhiên nếu áp dụng cho nhiều cột thì có vẻ khó hơn cho For Next (dùng Countif)
VD : Tìm các khách hàng có một trong các cột Mã, họ, tên đệm, tên, địa chỉ có ký tự ch để cho vào danh sách.
Sub Find_CaiGiDo()
Dim lCount As Long '(Ozgrid.com)
Dim rFoundCell As Range, MyRng As Range, Dem As Long
Set MyRng = Sheet2.Range(Cells(1, 1), Cells(25, 3))
MyRng.ClearComments
Set rFoundCell = Range("A1")
Dem = WorksheetFunction.CountIf(MyRng, "*ch*")
For lCount = 1 To Dem
Set rFoundCell = MyRng.Find(What:="ch", After:=rFoundCell, _
LookIn:=xlValues, LookAt:=xlPart, SearchOrder:=xlByColumns, _
SearchDirection:=xlNext, MatchCase:=False)
With rFoundCell
.Value = rFoundCell
.ClearComments
.AddComment Text:="Ozgrid.com"
End With
Next lCount
End Sub
SearchOrder:=xlByColumns hay làLookAt Optional Variant. Can be one of the following XlLookAt constants: xlWhole or xlPart.
LookAt (Cách thức tìm kiếm): Không bắt buộc, khai báo dạng Variant. Có thể là một trong các dạng XILookAt hằng số theo sau đây: xlWhole (Tìm toàn bộ) hoặc xlPart (tìm một phần)
Đúng là thiếu. Lúc chạy thử đang đã chọn cột A nên nó chạy tốt nhờ Selection.Find ...To: Thầy Long
Code của Thầy còn thiếu
range(....).select
rF1 = column(1).Find(What:=sFind, After:=Cells(1, 1)).Row tìm ô đầu tiên thỏa mãn điều kiện tìm thì After:=Cells(1, 1) thừa.Còn nếu column(1).select
rF1 = column(1).Find(What:=sFind, After:=Cells(1, 1)).Row
thì dòng lệnh này dư After:=Cells(1, 1), bởi chắc rằng ta đang tìm trên côt 1.
Thú thật cái After:=ActiveCells này có cần thiết với find không thì em chưa biết, bởi vì khi ta select thì ta chắc rằng find tìm hết selection.
Sub TaoPN()
Dim iRow As Long, EndR As Long
Dim MyRng As Range, rFoundCell As Range, SoCT As String
With Application
.DisplayAlerts = False
.ScreenUpdating = False
.Calculation = xlCalculationManual
End With
Sheets("PhNK").Select
[a14:i27].ClearContents
[C6:C8].ClearContents
SoCT = [H5]
With Sheets("BKNhap")
EndR = .[a65000].End(xlUp).Row
Set MyRng = .Range(.Cells(1, 5), .Cells(EndR, 5)) 'Sửa 2 thành 1'
EndR = WorksheetFunction.CountIf(MyRng, SoCT)
Set rFoundCell = MyRng(1)
Set rFoundCell = MyRng.Find(What:=SoCT, After:=rFoundCell, _
LookIn:=xlValues, LookAt:=xlWhole, SearchOrder:=xlByRows, _
SearchDirection:=xlNext, MatchCase:=True)
With rFoundCell
Cells(4, 4) = .Offset(iRow, -4).Value
Cells(6, 3) = .Offset(iRow, 1).Value
Cells(8, 3) = "Nhap theo HD" & .Offset(iRow, -1).Value
For iRow = 0 To EndR - 1
Cells(iRow + 14, 1) = iRow + 1
Cells(iRow + 14, 2) = .Offset(iRow, 2).Value
Cells(iRow + 14, 3) = .Offset(iRow, 3).Value
Cells(iRow + 14, 4) = .Offset(iRow, 7).Value
Cells(iRow + 14, 6) = .Offset(iRow, 4).Value
Cells(iRow + 14, 7) = .Offset(iRow, 5).Value
Cells(iRow + 14, 8) = .Offset(iRow, 6).Value
Cells(iRow + 14, 9) = "HD" & .Offset(iRow, -1).Value
Next
End With
End With
Set MyRng = Nothing
Set rFoundCell = Nothing
With Application
.DisplayAlerts = True
.ScreenUpdating = True
.Calculation = xlCalculationAutomatic
End With
End Sub
Sub Find_Format1()
Dim lCount As Long
Dim rFoundCell As Range, MyRng As Range, Dem As Long
Set MyRng = Sheet1.Range(Cells(1, 1), Cells(50, 1))
MyRng.ClearComments
Set rFoundCell = Range("A1")
Dem = WorksheetFunction.CountIf(MyRng, "sun")
For lCount = 1 To Dem
Set rFoundCell = MyRng.Find(What:="sun", After:=rFoundCell, _
LookIn:=xlValues, LookAt:=xlPart, SearchOrder:=xlByColumns, _
SearchDirection:=xlNext, MatchCase:=False)
With rFoundCell
If .Font.Bold = True And .Font.ColorIndex = 3 Then
.AddComment Text:="TN"
End If
End With
Next lCount
End Sub
Sub Find_Format()
Dim lCount As Long
Dim rFoundCell As Range, MyRng As Range, Dem As Long
Set MyRng = Sheet1.Range(Cells(1, 1), Cells(50, 1))
MyRng.ClearComments
Set rFoundCell = Range("A1")
Dem = WorksheetFunction.CountIf(MyRng, "sun")
With Application.FindFormat.Font
.FontStyle = "Bold"
.ColorIndex = 3
End With
For lCount = 1 To Dem
Set rFoundCell = MyRng.Find(What:="sun", After:=rFoundCell, _
LookIn:=xlValues, LookAt:=xlPart, SearchOrder:=xlByColumns, _
SearchDirection:=xlNext, MatchCase:=False, searchFormat:=True)
On Error Resume Next
With rFoundCell
.AddComment Text:="Tim thay roi TN oi!"
End With
Next lCount
End Sub
Ta sẽ dùng phương thức Find để tìm ra trong vùng A1:A10 những ô nào có ký tự 1
Ta dùng chuột bôi đen vùng A1:A10 và cho chạy Macro sau :
PHP:Sub Test1() Dim Rng As Range Set Rng = Selection.Find("1*", LookIn:=xlValues, LookAt:=xlWhole) If Not Rng Is Nothing Then Do MsgBox Rng.Address Set Rng = Selection.FindNext(Rng) Loop End If End Sub
Set Rng = Selection.Find("*1*", LookIn:=xlValues, LookAt:=xlWhole)
Xin lỗi các hạ xíu, nếu là chen ngang.
Nếu tìm những ô có ký tự là 1 thì phải là :
chứ nếu như Code trên thì chỉ là : Tìm những Cell bắt đầu bằng ký tự 1.PHP:Set Rng = Selection.Find("*1*", LookIn:=xlValues, LookAt:=xlWhole)
Nếu có gì sai sót thì mong các hạ bỏ qua vì với VBA thì tại hạ mới là nhập môn thôi.
Kính!
Cám ơn lời gợi ý, nhờ vậy mình mới tìm thấy cái hay của find. Các bạn xem thử code sau, tìm trong A, B, C có những cell nào có "ch". Ta chọn thử MyRng là 3 cột A, B, C
PHP:Sub Find_CaiGiDo() Dim lCount As Long '(Ozgrid.com) Dim rFoundCell As Range, MyRng As Range, Dem As Long Set MyRng = Sheet2.Range(Cells(1, 1), Cells(25, 3)) MyRng.ClearComments Set rFoundCell = Range("A1") Dem = WorksheetFunction.CountIf(MyRng, "*ch*") For lCount = 1 To Dem Set rFoundCell = MyRng.Find(What:="ch", After:=rFoundCell, _ LookIn:=xlValues, LookAt:=xlPart, SearchOrder:=xlByColumns, _ SearchDirection:=xlNext, MatchCase:=False) With rFoundCell .Value = rFoundCell .ClearComments .AddComment Text:="Ozgrid.com" End With Next lCount End Sub
Dem = WorksheetFunction.CountIf(MyRng, "*ch*")
Lúc này ta sẽ vận dụng sức mạnh của countif
LookAt:=xlPart: tìm một phần
SearchOrder:=xlByColumns hay là
SearchOrder:=xlByRows
Cái này cũng có tác dụng của nó, nếu row > iR có thể exit sub.
Và cũng không nên quên
MatchCase:=False/True
VD : Tìm các khách hàng có một trong các cột Mã, họ, tên đệm, tên, địa chỉ có ký tự ch để cho vào danh sách.
expression: Required. An expression that returns a Range object.expression.Find(What, After, LookIn, LookAt, SearchOrder, SearchDirection, MatchCase, MatchByte, SearchFormat)
Cells.Find(What:="SUN", After:=ActiveCell, LookIn:=xlValues, LookAt:= _
xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:=False, _
SearchFormat:=False).Activate
Tìm toàn bộ cell (Cells)
What:=”SUN”: tìm từ SUN
After:=ActiveCell: vị trí bắt đầu tìm: từ sau cell active
LookIn:=xlValues: Tìm giá trị (phần này còn có thông số formulas)
Các thông số khác:
LookAt:= xlPart, MatchCase:=False và
LookAt:= xlWhole, MatchCase:=True
Muốn dễ hiểu nhất thì khi bạn ghi macro, Ctr F vào khung option và tùy chọn các
- Match entire cell contents
- Match case
Bạn sẽ hình dung cụ thể.
SearchOrder:=xlByRows, SearchDirection:=xlNext, SearchFormat:=False
Các thông số còn lại đã diễn giải phần trên.
Sub TestFind()
With Worksheets("Sheet1").Range("A1:A500")
Set Rng = .Find(2, LookIn:=xlValues)
If Not Rng Is Nothing Then ‘Nếu giá trị Rng trả về không phải là Nothing thì
firstAddress = Rng.Address ‘Lưu lại địa chỉ ô đầu tiên tìm được.
Do
Rng.Value = 5
Set Rng = .FindNext(Rng) ‘Tìm tiếp
Loop While Not Rng Is Nothing And Rng.Address <> firstAddress
‘Dừng vòng lặp Do..Loop khi giá trị Rng trả về là Nothing hoặc
‘địa chỉ Rng trả về trùng với địa chỉ của ô tìm được đầu tiên.
End If
End With
End Sub
Sub FindCatOtherSheet()
Dim rFound As Range
On Error Resume Next
With Sheet1
Set rFound = .Columns(1).Find(What:="Cat", After:=.Cells(1, 1), _
LookIn:=xlValues, LookAt:= _
xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:=False , _
SearchFormat:=False)
On Error GoTo 0
If Not rFound Is Nothing Then Application.Goto rFound, True
End With
Sub Find_Bold_Cat()
Dim lCount As Long
Dim rFoundCell As Range
Set rFoundCell = Range("A1")
For lCount = 1 To WorksheetFunction.CountIf(Columns(1), "Cat")
Set rFoundCell = Columns(1).Find(What:="Cat", After:=rFoundCell, _
LookIn:=xlValues, LookAt:=xlPart, SearchOrder:=xlByRows, _
SearchDirection:=xlNext, MatchCase:=False)
With rFoundCell
.ClearComments
.AddComment Text:="Cat lives here"
End With
Next lCount
End Sub
Sub Find_Bold_Cat()
‘Tìm những chữ Cat và thêm 1 comment là "Cat lives here"
‘’===========================================
‘Đếm những “Cat” trong cột A và xác định những lần tìm là kết quả đếm.
For lCount = 1 To WorksheetFunction.CountIf(Columns(1), "Cat")
‘Tìm trong cột A, xác định ô tìm thấy có chữ “Cat” gán vào biến rFoundCell
Set rFoundCell = Columns(1).Find(What:="Cat", After:=rFoundCell,
LookIn:=xlValues, LookAt:=xlPart, SearchOrder:=xlByRows, _
SearchDirection:=xlNext, MatchCase:=False)
‘Tại Range tìm thấy, xóa các comment và gán Comment "Cat lives here"
With rFoundCell
.ClearComments
.AddComment Text:="Cat lives here"
End With
‘Tìm tiếp tục cho đến khi số lần tìm = lCount
Next
End Sub
For Each Rng In [A1:C5]
If Rng.Font.Name Like "Cour*" Then
Rng.Font.Name = "Times New Roman"
End If
Next
Cells.Find(What:="SUN", After:=ActiveCell, LookIn:=xlValues, LookAt:= _
xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:=False, _
SearchFormat:=False).Activate
Tôi thêm vào để cho bình dân hóa.Sub TestFind()
With Worksheets("Sheet1").Range("A1:A500")
Set Rng = .Find(2, LookIn:=xlValues)
If Not Rng Is Nothing Then ‘Nếu giá trị Rng trả về không phải là Nothing thì : hay nói cách khác : Nếu tìm thấy thì
firstAddress = Rng.Address ‘Lưu lại địa chỉ ô đầu tiên tìm được.
Do
Rng.Value = 5
Set Rng = .FindNext(Rng) ‘Tìm tiếp
Loop While Not Rng Is Nothing And Rng.Address <> firstAddress
‘Dừng vòng lặp Do..Loop khi giá trị Rng trả về là Nothing hoặc
‘địa chỉ Rng trả về trùng với địa chỉ của ô tìm được đầu tiên. (địa chỉ ô tìm thấy được lặp lại)
End If
End With
End Sub
Sub Find_Bold_Cat()
Dim lCount As Long
Dim rFoundCell As Range
Set rFoundCell = Range("A1")
For lCount = 1 To WorksheetFunction.CountIf(Columns(1), "Cat")
Set rFoundCell = Columns(1).Find(What:="Cat", After:=rFoundCell, _
LookIn:=xlValues, LookAt:=xlPart, SearchOrder:=xlByRows, _
SearchDirection:=xlNext, MatchCase:=False)
With rFoundCell
.ClearComments
.AddComment Text:="Cat lives here"
End With
Next lCount
End Sub
Đếm tất cả các Cell trong cột 1 có giá trị là ký tự Cat (toàn bộ Cell)WorksheetFunction.CountIf(Columns(1), "Cat")
Tìm tất cả các Cell trong cột 1 có chứa ký tự Cat (Một phần Cell)Columns(1).Find(What:="Cat", After:=rFoundCell, _
LookIn:=xlValues, LookAt:=xlPart, SearchOrder:=xlByRows, _
SearchDirection:=xlNext, MatchCase:=False)
Chúng ta đang xét đến việc tìm trên 1 cột; Nếu ta thực hiện việc này trong lệnh của menu ta sẽ thấy excel tìm từ đầu cho đến cuối vùng (VD ta đã kích hoạt vùng từ 'A1:A500')Sub TestFind()
With Worksheets("Sheet1").Range("A1:A500")
Set Rng = .Find(2, LookIn:=xlValues)
If Not Rng Is Nothing Then ‘Nếu giá trị Rng trả về không phải là Nothing thì : hay nói cách khác : Nếu tìm thấy thì
firstAddress = Rng.Address ‘Lưu lại địa chỉ ô đầu tiên tìm được.
Do
Rng.Value = 5
Set Rng = .FindNext(Rng) ‘Tìm tiếp
Loop While Not Rng Is Nothing And Rng.Address <> firstAddress
‘Dừng vòng lặp Do..Loop khi giá trị Rng trả về là Nothing hoặc
‘địa chỉ Rng trả về trùng với địa chỉ của ô tìm được đầu tiên. (địa chỉ ô tìm thấy được lặp lại)
End If
End With
End SubTôi thêm vào để cho bình dân hóa. Chúc vui!
Loop While Not Rng Is Nothing And Rng.Address <> firstAddress
Nên bạn dùng chữ "hoặc" mình thấy chưa rõ hết nghĩa.
Quy trình tìm trong VBA theo mình nghĩ cũng như trên:
Tìm thấy anh đầu tiên, ta cùng excel ghi nhận ô đó vô biến Rng & địa chỉ vô biến kiểu chuỗi;
Sau đó dùng vòng lặp tìm tiếp . . .
Dòng lệnh thoát vòng lặp khi cùng tìm thấy theo điều kiện (Có nghĩa thấy Rng thỏa) & địa chỉ nó trùng với địa chỉ lưu trong biến chuỗi (Khi đi tìm & thấy đã giáp 1 vòng) lúc đó mới thoát.
Rất cảm ơn bạn!
Theo tôi nghĩ là chưa chính xác.Dòng lệnh thoát vòng lặp khi cùng tìm thấy theo điều kiện (Có nghĩa thấy Rng thỏa) & địa chỉ nó trùng với địa chỉ lưu trong biến chuỗi (Khi đi tìm & thấy đã giáp 1 vòng) lúc đó mới thoát
If Not Intersect(Target, [b3]) Is Nothing Then
'Đoạn mã Mới:'
Dim MyDir As String, KhTiep As Boolean
If Not IsNumeric(Target.Value) Then
MsgBox "Khong Fai Só Tu Nhien": Exit Sub
End If
If Target.Value <= 0 Then
MyDir = "Só Quá Bé!": KhTiep = True
End If
If Int(Target.Value) < Target.Value Then
MyDir = "Khong Chap Nhan Só Thap Fan!": KhTiep = True
End If
If KhTiep Then
MsgBox MyDir: Exit Sub
End If
'* * * * * *'
Dim Rng As Range, sRng As Range, Rg0 As Range
Dim MyAdd As String '<=| Dòng Lenh Này Da Duoc Sua Lại'
Dim Jj As Byte
Hi bạn,
Cho mình hỏi ngu tí, sao cáo code của sub TimvaThaythe không chạy được nhỉ, nó báo lỗi Loop without Do
À mình đang nói tới code #3 của ThuNghi.Bạn đang nói đến Sub T... đang ở bài nào trong topic (nào?) vậy.
Option Explicit
Sub TimVaThayThe()
Dim OldText As String, NewText As String, DiaChi As String 'Sa'
Dim MyRng As Range, Rng As Range
1 Set MyRng = Range(Cells(1, 1), Cells(18, 4))
OldText = "3": NewText = "test"
With MyRng
2 Set Rng = .Find(What:=OldText, LookIn:=xlValues, LookAt:=xlWhole)
3 If Not Rng Is Nothing Then
DiaChi = Rng.Address
Do
With Rng.Offset(, 5)
5 ' With Rng <=| Khong Càn Dòng Này'
.Value = NewText
.Interior.ColorIndex = 36
.Font.Bold = True
End With
Set Rng = .FindNext(Rng)
7 ' If Rng Is Nothing Then Exit Sub <=| Khong Càn Dòng Này'
Loop While Not Rng Is Nothing And Rng.Address <> DiaChi
9 End If
End With
End Sub
1 Set MyRng = Cells(1, 1).CurrentRegion
2 Set Rng = .Find(OldText, , xlValues, xlWhole)
3 If Not Rng Is Nothing Then
'. . . . . '
Else
Exit Sub
9 End If
Thanks bạn nhen.[ThongBao](2) À mình đang nói tới code #3 của ThuNghi.
(1) Nhân tiện mình đang có một vấn đề:
Mình có một danh sách các khế ước vay. Mình đang muốn viết một code để tìm xem có khế ước vay mới nào phát sinh thêm không (chưa có trong danh sách khế ước đã có) -> Nếu có thì copy khế ước đó vào dòng tiếp theo của danh sách khế ước cũ (chỉ copy một lần đối với mỗi khế ước mới). Mong các bạn chỉ giúp, mình rất gà về VBA.[/ThongBao]
(1) Bạn nên đưa file giả lập lên; Cũng nhiều người lười biếng làm file giả lập cho bạn lắm đấy!
(2) Bạn lấy cái ni thay thế:
PHP:Option Explicit Sub TimVaThayThe() Dim OldText As String, NewText As String, DiaChi As String 'Sa' Dim MyRng As Range, Rng As Range 1 Set MyRng = Range(Cells(1, 1), Cells(18, 4)) OldText = "3": NewText = "test" With MyRng 2 Set Rng = .Find(What:=OldText, LookIn:=xlValues, LookAt:=xlWhole) 3 If Not Rng Is Nothing Then DiaChi = Rng.Address Do With Rng.Offset(, 5) 5 ' With Rng <=| Khong Càn Dòng Này' .Value = NewText .Interior.ColorIndex = 36 .Font.Bold = True End With Set Rng = .FindNext(Rng) 7 ' If Rng Is Nothing Then Exit Sub <=| Khong Càn Dòng Này' Loop While Not Rng Is Nothing And Rng.Address <> DiaChi 9 End If End With End Sub
Với những ghi chú thêm như sau:
a./ Câu lệnh mang số 1 có thể thay bằng câu lệnh:
Mã:1 Set MyRng = Cells(1, 1).CurrentRegion
Tương tự như vậy câu lệnh mang số 2 sẽ có thể là:
Mã:2 Set Rng = .Find(OldText, , xlValues, xlWhole)
b./ Câu lệnh mang số 5 là dư hẵn; Để tránh sai sót này, những nhà lập trình amatơ nên thụt đầu dòng các khối lệnh thẳng cột
C./ Câu lệnh mang số 7 cũng dư thừa không cần thiết;
Điều này rõ hơn khi ta xem khối lệnh điều kiện từ dòng lệnh mang số 3 đến dòng lệnh mang số 9; Trong điều kiện này thì không thể nào sẩy ra trường hợp để thực thi dòng lệnh dư này; Nó chỉ để đó như ngồi chơi xơi nước mà thôi.
Muốn viết làm nó có tác dụng thực tế ta fải viết vầy:
Mã:3 If Not Rng Is Nothing Then '. . . . . ' Else Exit Sub 9 End If
(Rồi sau này bạn sẽ biết, rằng cũng chả nhứt thiết fải xài bổ sung nó làm chi!)
![]()
![]()
![]()
![]()
Thân.
Nhân tiện đây các bạn cho mình hỏi cái code sau của mình sao nó không chạy đuoc voi. Mình muốn kiểm tra các giá trị tại cột C,nếu >0 thì copy giá trị đó sang một vị trí khác, ở đây là cột D tương ứng. (mình ko copy code vào đây được)
Sub Teting()
Dim x As Integer
Worksheets ("Sheet1").Select
For x = 1 To 100
If Range ("C"&x).Value>0 Then
Range ("C"&x).Copy Range("D"&x)
Else
Exit For
End If
Next x
End Sub
Sub Teting()
Dim x As Integer
Worksheets ("Sheet1").Select
For x = 1 To 100
If Range ("C"&x).Value>0 Then
Range ("C"&x).Copy Range("D"&x)
[B][COLOR=#ff0000]Else
Exit For[/COLOR][/B]
End If
Next x
End Sub
(2) Bạn lấy cái ni thay thế:
PHP:Option Explicit Sub TimVaThayThe() Dim OldText As String, NewText As String, DiaChi As String 'Sa' Dim MyRng As Range, Rng As Range 1 Set MyRng = Range(Cells(1, 1), Cells(18, 4)) OldText = "3": NewText = "test" With MyRng 2 Set Rng = .Find(What:=OldText, LookIn:=xlValues, LookAt:=xlWhole) 3 If Not Rng Is Nothing Then DiaChi = Rng.Address Do With Rng.Offset(, 5) 5 ' With Rng <=| Khong Càn Dòng Này' .Value = NewText .Interior.ColorIndex = 36 .Font.Bold = True End With Set Rng = .FindNext(Rng) 7 ' If Rng Is Nothing Then Exit Sub <=| Khong Càn Dòng Này' Loop While Not Rng Is Nothing And Rng.Address <> DiaChi 9 End If End With End Sub
Với những ghi chú thêm như sau:
C./ Câu lệnh mang số 7 cũng dư thừa không cần thiết;
Loop While Not Rng Is Nothing And Rng.Address <> DiaChi
Điều này rõ hơn khi ta xem khối lệnh điều kiện từ dòng lệnh mang số 3 đến dòng lệnh mang số 9; Trong điều kiện này thì không thể nào sẩy ra trường hợp để thực thi dòng lệnh dư này
Set Rng = .FindNext(Rng)
Nó chỉ để đó như ngồi chơi xơi nước mà thôi.
Bạn bị dính chưởng ở dòng màu đỏ, xoá nó đi là OK:
Mã:Sub Teting() Dim x As Integer Worksheets ("Sheet1").Select For x = 1 To 100 If Range ("C"&x).Value>0 Then Range ("C"&x).Copy Range("D"&x) [B][COLOR=#ff0000]Else Exit For[/COLOR][/B] End If Next x End Sub
Sub Update()
Dim SaveRg As Range, Cl As Range, Tm, i
Tm = Application.InputBox("Chon vung DL moi PS:(3 cot: Khe uoc-Tien Vay-Tien tra)", "CHON DU LIEU UPDATE", , , , , , 64)
For i = 1 To UBound(Tm, 1)
Set SaveRg = Sheet2.Range("A2:A" & Sheet2.Cells(Rows.Count, 1).End(3).Row)
Set Cl = SaveRg.Find(what:=Tm(i, 1))
If Cl Is Nothing Then
Sheet2.Cells(SaveRg.Rows.Count + 2, 3) = Tm(i, 3)
Sheet2.Cells(SaveRg.Rows.Count + 2, 2) = Tm(i, 2)
Sheet2.Cells(SaveRg.Rows.Count + 2, 1) = IIf(IsNumeric(Tm(i, 1)), "'" & Tm(i, 1), Tm(i, 1))
Else
Cl.Offset(, 1) = Cl.Offset(, 1) + Tm(i, 2)
Cl.Offset(, 2) = Cl.Offset(, 2) + Tm(i, 3)
End If
Next
End Sub
Bạn ơi vui lòng giải thích cái macro trên giúp mình được không.Bạn ráp thử code này xem sao.
(Mình Modify 1 chút:Để theo dõi phát sinh vay trả nên nếu chưa có thì thêm vào với tiền vay trả, nếu có rồi thì cộng thêm tiền phát sinh vào)
Mã:Sub Update() Dim SaveRg As Range, Cl As Range, Tm, i Tm = Application.InputBox("Chon vung DL moi PS:(3 cot: Khe uoc-Tien Vay-Tien tra)", "CHON DU LIEU UPDATE", , , , , , 64) For i = 1 To UBound(Tm, 1) Set SaveRg = Sheet2.Range("A2:A" & Sheet2.Cells(Rows.Count, 1).End(3).Row) Set Cl = SaveRg.Find(what:=Tm(i, 1)) If Cl Is Nothing Then Sheet2.Cells(SaveRg.Rows.Count + 2, 3) = Tm(i, 3) Sheet2.Cells(SaveRg.Rows.Count + 2, 2) = Tm(i, 2) Sheet2.Cells(SaveRg.Rows.Count + 2, 1) = IIf(IsNumeric(Tm(i, 1)), "'" & Tm(i, 1), Tm(i, 1)) Else Cl.Offset(, 1) = Cl.Offset(, 1) + Tm(i, 2) Cl.Offset(, 2) = Cl.Offset(, 2) + Tm(i, 3) End If Next End Sub
Lỗi là phải rồi. Bạn khai Tm là Range đối tượng sau đó thì gán Tm = ...Bạn ơi,
mình dùng dòng lệnh dưới để gán vùng lọc được vào Range Tm mà sao khi chạy nó báo lỗi "Object variable or With block is not set"
Coi giúp mình với.
Dim Tm as Range
Tm = Sheets("Input").Range("A4").AutoFilter(Field:=1, Criteria1:="nh10")
Mình đã dùng Set Tm = Sheets("Input").Range("A4").AutoFilter(Field:=1, Criteria1:="nh10")
Tuy nhiên nó báo lỗi Type mismatch
Các bạn giúp với ạ.
Có cách nào để mình gán kết quả lọc vào một biến không?
Sub Test()
Dim [COLOR=#ff0000]Tm As Range[/COLOR]
With Sheets("Input").Range("A4")
.AutoFilter Field:=1, Criteria1:="nh10"
[COLOR=#ff0000] Set Tm = .Parent.AutoFilter.Range[/COLOR]
End With
End Sub
Cái đó chưa chắc nha!Vì có nhiều ngân hàng nên em mới muốn lọc rồi gán sau đó mới dò tìm để nhanh hơn là sử dụng toàn bộ dữ liệu input để dò tìm.
Mong thầy chỉ thêm cho
Cái đó chưa chắc nha!
Tôi dùng mảng, chẳng cần lọc gì cả, cứ dò tìm từ trên xuống dưới cũng bảo đảm nhanh hơn cách dùng AutoFilter của bạn
--------------------------
Tuy nhiên xin nhắc rằng: Nếu câu hỏi của bạn không liên quan đến Find Method thì vui lòng post vào 1 box khác
(tôi đoán chừng bài toán của bạn liên quan đến lọc hoặc so sánh thì phải)
With SaveRg
[FONT=arial].Range("A" & ER + 1).Formula = "'" & Mang_DL(i, 2)
.Range("B" & ER + 1).Value = Application.SumIf(.Range("Khe_uoc"), .Range("A" & ER + 1), .Range("So_vay"))
.Range("C" & ER + 1).Value = Application.SumIf(.Range("Khe_uoc"), .Range("A" & ER + 1), .Range("So_tra"))
.Range("D" & ER + 1).Value = Application.Sum(.Range("B" & ER + 1), -.Range("C" & ER + 1))[/FONT]
End With