Kể từ hôm nay, tất cả những câu hỏi nhờ giải thích dùm một đoạn code, hay là hỏi những vấn đề linh tinh gì liên quan đến cách viết code, đề nghị các bạn gửi chung vào đây.
Những đề tài mới với tiêu đề: "Nhờ giải thích dùm đoạn code", mà không nói rõ là code gì, code dùng để làm gì, sẽ bị xóa.
With Range(ActiveCell, Cells(Cells.Rows.Count - 1, ActiveCell.Column))
Range(.Cells(1), Intersect(.Cells, .Offset(1)).SpecialCells(12)(1)).Select
End With
With Range(ActiveCell, Cells(Cells.Rows.Count - 1, ActiveCell.Column))
Range(.Cells(1), Intersect(.Cells, .Offset(1)).SpecialCells(12)(1)).Select
End With
1. Dịch nghĩa của những câu tô đỏ đậm trong đoạn code sau:
Mã:
Private Sub Worksheet_Change(ByVal Target As Range)
If [COLOR=Red][B]Intersect[/B][/COLOR](ActiveCell, Range("B2:C10")) [COLOR=Red][B]Is Nothing[/B][/COLOR] Then
MsgBox Target.Address & " nam trong vung B2:C10"
Else
MsgBox Target.Address & " nam ngoai vung B2:C10"
End If
End Sub
2. Tôi muốn khi ô hiện hành nằm trong vùng B2:C10 thì kết quả là Msgbox (1) và khi ô hiện hành nằm ngoài vùng B2:C10 thì cho kết quả là Msgbox (2). Nhưng đoạn code này chỉ cho một kết quả là Msgbox (1) dù ô hiện hành nằm trong vùng hoặc ngoài vùng. Vậy code này sai ở đâu và phải sửa như thế nào ?? Thanks!
1. Dịch nghĩa của những câu tô đỏ đậm trong đoạn code sau:
Mã:
Private Sub Worksheet_Change(ByVal Target As Range)
If [COLOR=Red][B]Intersect[/B][/COLOR](ActiveCell, Range("B2:C10")) [COLOR=Red][B]Is Nothing[/B][/COLOR] Then
MsgBox Target.Address & " nam trong vung B2:C10"
Else
MsgBox Target.Address & " nam ngoai vung B2:C10"
End If
End Sub
2. Tôi muốn khi ô hiện hành nằm trong vùng B2:C10 thì kết quả là Msgbox (1) và khi ô hiện hành nằm ngoài vùng B2:C10 thì cho kết quả là Msgbox (2). Nhưng đoạn code này chỉ cho một kết quả là Msgbox (1) dù ô hiện hành nằm trong vùng hoặc ngoài vùng. Vậy code này sai ở đâu và phải sửa như thế nào ?? Thanks!
Private Sub Worksheet_Change(ByVal Target As Range)
If Not Intersect(Target, Range("B2:C10")) Is Nothing Then
MsgBox Target.Address & " nam trong vung B2:C10"
Else
MsgBox Target.Address & " nam ngoai vung B2:C10"
End If
End Sub
Intersect(Target, Range("B2:C10")) là vùng GIAO ĐIỂM giữa Target và Range("B2:C10") hay cũng chính là Target luôn Intersect(Target, Range("B2:C10")) Is Nothing ý muốn nói KHÔNG CÓ GIAO ĐIỂM NÀO
Vậy NotIntersect(Target, Range("B2:C10")) Is Nothing là CÓ TÌM THẤY GIAO ĐIỂM
-------------- Ví dụ minh họa về Intersect
Intersect([B2:C10], [C813]) sẽ là Range("C8:C10")
Tôi mới học viết code nên còn nhiều lệnh chưa biết hết cách dùng, nhờ mọi người giải thích và cho ví dụ giùm :
1, Lệnh Controls(...) có ý nghĩa gì ? Tôi đã được giải thích là để lấy giá trị nào đó trong mảng nhưng vẫn không hình dung được.
2, Lệnh Split(chuỗi cần tách, mark để tách, số lượng chuỗi con cần tách) nhưng tôi vấn không thực hiện được.
Ví dụ ở ô A1 tôi gõ "Truong-Giang-73", tôi cần tách là Ô B1 = "Truong", B2 = "Giang", B3 = "73" nhưng tôi dùng các lệnh sau trong Immediate :
* rangre("b1") = split(rangge("a1"), "-",1) cho KQ = "Truong"
* rangre("b2") = split(rangge("a1"), "-",2) cho KQ cũng = "Truong"
* rangre("b3") = split(rangge("a1"), "-",20) cũng cho KQ là = "Truong"
Xin mọi người giải thích kỹ kỹ và cho ví dụ luôn nhá.
TG73 xin cảm ơn nhiều.
Split trả về giá trị là 1 mảng. Vậy mà bạn gán mảng đó cho 1 range thì nó chỉ lấy giá trị đầu tiên của mảng mà thôi.
Bạn thử code này sẽ hiểu lý do tại sao? Thay mSplit bằng các giá trị khác nhau để rút ra kết luận.
[highlight=VB]
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
On Error Resume Next
Dim myArr As Variant, mSplit As Long, i As Long
mSplit = 3
myArr = Split([A1], "-", mSplit)
For i = 1 To mSplit
Cells(i, 2).Value = myArr(i - 1)
Next i
End Sub
[/highlight]
Cảm ơn anh Cada_fi, qua bài test của anh tôi đã hiểu. Vì trước tôi có gặp một ví dụ về lệnh Split nhưng thiếu thông số "mSplit" và chưa hiểu về mảng nên xoay đi xoay lại mãi vẫn là số "0".
Còn Controls(i) có phải là đối tượng i trong Form không ah ?
Tôi vừa xem một bài trên GPE có đoạn code (của Ndu) nhưng có nhiều câu tôi chưa hiểu. Nhờ các bạn dịch nghĩa giúp tôi đoạn code này (dịch xen kẽ từng dòng lệnh). Thanks !
Mã:
Function GroupJoin(Find_String As String, Find_Range As Range, Col_Index As Long, Optional Sep As String = "-") As String
Dim i As Long, [COLOR=Red]Dic[/COLOR]
On Error Resume Next
Set Dic = CreateObject("[COLOR=Red]Scripting.Dictionary[/COLOR]")
For i = 1 To Len([COLOR=Red]Find_String[/COLOR])
With [COLOR=Red]Find_Range.Find(Mid(Find_String, i, 1), , , xlWhole, , , False)[/COLOR]
If Not .Cells Is Nothing Then
[COLOR=Red]Dic.Add i, .Cells(, Col_Index)[/COLOR]
End If
End With
Next i
[COLOR=Red]GroupJoin = Join(Dic.Items, Sep)[/COLOR]
End Function
Function GroupJoin(Find_String As String, Find_Range As Range, Col_Index As Long, Optional Sep As String = "-") As String| Cái này chỉ là đặt tên biến và kiểu biến thôi. "Optional" dùng để chỉ rằng biến này có hay ko cũng được.
Dim i As Long,
Dic| Đặt biến
On Error Resume Next|Xử lý lỗi trả về dòng tiếp theo dòng bị lỗi
Set Dic = CreateObject("
Scripting.Dictionary
")|
Dùng
để tạo 1 Object mới (dạng mãng chứa text) và đặt cho biến Dic
For i = 1 To Len(
Find_String
)| chạy vòng lặp từ 1 đến độ dài ký tự
Find_String
With
Find_Range.Find(Mid(Find_String, i, 1), , , xlWhole, , , False)| VớiFind_Range (là vùng địa chỉ cần tìm); lệnh Find() là tìm một giá trị nào đó trong vùng Find_Range (và chỉ lấy ô đầu tiên tìm thấy nếu trùng)
If Not .Cells Is Nothing Then| Nếu vùng tìm được đó không phải là rỗng thì Dic.Add i, .Cells(, Col_Index)|Nạp dữ liệu đó cho Dic ở vị trí i; dữ liệu thuộc vùng mới tìm được lấy cột thứ Col_Index
End If| kết thúc
IF
End With| kết thúc
With
Next i|kết thúc lần thứ
i
của
ForGroupJoin = Join(Dic.Items, Sep)| Lệnh Join(<Text>,<ký tự cách>) dùng để ghép các đoạn text của một mãng. Dic.Items để lấy các phần tử được nạp trong Dic ra.
End Function
Đây là những gì em biết. Nếu có gì thiếu sót thì xin mọi người bổ sung giúp... em cũng cố thêm kiến thức nha! Ths.
Thân.
Tôi vừa xem một bài trên GPE có đoạn code (của Ndu) nhưng có nhiều câu tôi chưa hiểu. Nhờ các bạn dịch nghĩa giúp tôi đoạn code này (dịch xen kẽ từng dòng lệnh). Thanks !
Mã:
Function GroupJoin(Find_String As String, Find_Range As Range, Col_Index As Long, Optional Sep As String = "-") As String
Dim i As Long, [COLOR=Red]Dic[/COLOR]
On Error Resume Next
Set Dic = CreateObject("[COLOR=Red]Scripting.Dictionary[/COLOR]")
For i = 1 To Len([COLOR=Red]Find_String[/COLOR])
With [COLOR=Red]Find_Range.Find(Mid(Find_String, i, 1), , , xlWhole, , , False)[/COLOR]
If Not .Cells Is Nothing Then
[COLOR=Red]Dic.Add i, .Cells(, Col_Index)[/COLOR]
End If
End With
Next i
[COLOR=Red]GroupJoin = Join(Dic.Items, Sep)[/COLOR]
End Function
Em nghĩ chắc chỉ có 1 chổ anh chưa biết, đó là Dictionary Object ---> Cái này chuyên dùng để xử lý mãng, rất dể dùng
1> Để dùng Dictionary thì đầu tiên anh phải khởi tạo cho nó bằng lệnh:
Set object = CreateObject("Scripting.Dictionary")
2> Câu lệnh quan trong nhất và thường dùng nhất trong Dictionary là phương thức Add
Cú pháp object.Add key, item Ý nghĩa: Add 1 key nào đó và 1 Item nào đó vào Object
Trong đó ta phải lưu ý 1 điều quan trọng:
- Item có thể bỏ qua nhưng Key bắt buộc phải có
- Key luôn là 1 phần tử duy nhất ---> Tức nếu anh add 1 key đã tồn tại trước đó thì nó sẽ... cằn nhằn ----> Người ta tận dụng đặc điểm này để lọc dử liệu duy nhất đấy
3> Sau khi đã hoàn tất việc Add dử liệu vào Object, cuối cùng ta được 2 mãng:
Object.Keys và Object.Items
4> Việc truy xuất các phần tử trong Object này hoàn toàn giống như với mãng, tức
Object.Keys(0) ---> Lấy giá trị đầu tiên trong Keys
Object.Items(0) ---> Lấy giá trị đầu tiên trong Items
.....
Object.Keys(Object.Count) ---> Lấy phần tử cuối cùng của Keys
Object.Items(Object.Count) ---> Lấy phần tử cuối cùng của Items
-----------
Đây là nhưng phương thức thường dùng, ngoài ra còn nhiều phương thức khác như Exists, Remove, RemoveAll... vân vân...
Theo nhận định của em, khi làm việc với mãng ta dùng Dictionary Object sẽ dể hơn nhiều so với cách thông thường (phải ReDim tùm lum cả)
-------------
Em ví dụ dùng Dictionary Object để lấy phần tử duy nhất nha:
PHP:
Sub Unique()
Dim Clls As Range, Dic
On Error Resume Next
With Application
Set Dic = CreateObject("Scripting.Dictionary")
For Each Clls In .InputBox("Chon vung chua du lieu", Type:=8)
If Not IsEmpty(Clls) Then Dic.Add Clls.Value, ""
Next
ActiveCell.Resize(Dic.Count) = .Transpose(Dic.Keys)
End With
End Sub
Thử chạy code và chọn 1 cột nào đó có dử liệu xem
Tất nhiên với bài toán này ta có thể dùng Advanced Filter, nhưng nếu dử liệu được bố trí ngang hoặc có từ 2 cột trở lên thì Advanced Filter "xơi" nó đâu có dể ---> Trong khi đó Dictionary làm tất tần tật
1> Để dùng Dictionary thì đầu tiên anh phải khởi tạo cho nó bằng lệnh: Set object = CreateObject("Scripting.Dictionary") 2> Câu lệnh quan trong nhất và thường dùng nhất trong Dictionary là phương thức Add
Cú pháp object.Add key, item Ý nghĩa: Add 1 key nào đó và 1 Item nào đó vào Object
Trong đó ta phải lưu ý 1 điều quan trọng:
- Item có thể bỏ qua nhưng Key bắt buộc phải có
- Key luôn là 1 phần tử duy nhất ---> Tức nếu anh add 1 key đã tồn tại trước đó thì nó sẽ... cằn nhằn ----> Người ta tận dụng đặc điểm này để lọc dử liệu duy nhất đấy
3> Sau khi đã hoàn tất việc Add dử liệu vào Object, cuối cùng ta được 2 mãng:
Object.Keys và Object.Items
.......
Mã:
Sub Unique()
Dim Clls As Range, Dic
On Error Resume Next
With Application
Set Dic = CreateObject("Scripting.Dictionary")
For Each Clls In .InputBox("Chon vung chua du lieu", Type:=8)
If Not IsEmpty(Clls) Then Dic.[COLOR=Red][B]Add Clls[/B][/COLOR].Value, ""
Next
ActiveCell.Resize(Dic.Count) = .Transpose([COLOR=Red][B]Dic.Keys[/B][/COLOR])
End With
Test đoạn code này mới nhớ tới bài lọc duy nhất đã xem lâu rồi nhưng vẫn bỏ đó, nếu không bài này thì có lẽ chẳng bao giờ mình hiểu được để vận dụng. Bây giờ thì hơi hơi hiểu: vậy trong đoạn code trên Clls có phải là Keys không (chỉ thấy Add Clls chứ không thấy Add Keys). Nếu đúng thì Keys trong Dic.Keyslà như thế nào ? Rất mong các bạn vui lòng giúp tiếp. Thanks!
Test đoạn code này mới nhớ tới bài lọc duy nhất đã xem lâu rồi nhưng vẫn bỏ đó, nếu không bài này thì có lẽ chẳng bao giờ mình hiểu được để vận dụng. Bây giờ thì hơi hơi hiểu: vậy trong đoạn code trên Clls có phải là Keys không (chỉ thấy Add Clls chứ không thấy Add Keys). Nếu đúng thì Keys trong Dic.Keyslà như thế nào ? Rất mong các bạn vui lòng giúp tiếp. Thanks!
Đúng rồi ---> Clls.Value là key đấy ---> Key nằm trong nhóm Keys
Ý nghĩa đoạn code của em là: Vòng lập duyệt qua các cell (Clls) ---> Nếu đạt điều kiện thì add Clls.Value vào Dic
Như cú pháp em đã đưa ở trên Object.Add Key, Item ---> Key và Item anh muốn là gì thì tự điền vào thôi
--------------
Còn Keys trong Dic.Keys nghĩa là nguyên 1 đóng bao gồm tất cả các key đã add vào Dic
Giống vầy nè anh Set Rng = Range("A1:A10") Rng.Cells là tất cả các cell có trong Rng
--------------- Anh để ý Keys và Key... Item và Items : Khác nhau chử s Trong Dic có 2 mãng (tạm gọi là 2 nhóm)
Nhóm Keys bao gồm tất cả các Key
Nhóm Items bao gồm tất cả các Item
@ Ndu: Cảm ơn bạn rất nhiều, bây giờ thì mình tạm hiểu rồi đặc biệt là: "Keys và Key... Item và Items : Khác nhau chử s". Sử dụng Dictionary Object để làm việc với mảng thì ngoài việc lọc dử liệu duy nhất còn ứng dụng vào các trường hợp nào là phổ biến? bạn có thể gợi ý giúp tôi một trường hợp, tôi sẽ tự làm xem sao có gì chưa hiểu tôi sẽ hỏi tiếp.
Thân!
@ Ndu: Cảm ơn bạn rất nhiều, bây giờ thì mình tạm hiểu rồi đặc biệt là: "Keys và Key... Item và Items : Khác nhau chử s". Sử dụng Dictionary Object để làm việc với mảng thì ngoài việc lọc dử liệu duy nhất còn ứng dụng vào các trường hợp nào là phổ biến? bạn có thể gợi ý giúp tôi một trường hợp, tôi sẽ tự làm xem sao có gì chưa hiểu tôi sẽ hỏi tiếp.
Thân!
Mục đích sử dụng chỉ có thể là: "Thu gom" mọi thứ dựa vào 1 tiêu chỉ lọc nào đó
- Nếu anh dùng mãng thông thường, anh phải mất công Dim và ReDim đủ các kiểu
- Nếu anh dùng phương pháp nối chuổi, anh sẽ mất công cắt những phần thừa ở cuối quá trình
Với Dictionary thì hầu như anh chẳng phải làm gì ---> Đúng điều kiện thì anh Add vào (Dic.Add) ---> Kết thúc quá trình, muốn lấy ra thì mang cái Dic.Keys hoặc Dic.Items ra "xử"
Ví dụ nhỏ: "thu gom" tên các sheet
PHP:
Function SheetCol()
Dim Sh As Worksheet, Temp As New Dictionary
For Each Sh In ThisWorkbook.Worksheets
Temp.Add Sh.Name, "A"
Next
SheetCol = Temp.Keys
End Function
PHP:
Sub Test()
With Range("A1").Resize(UBound(SheetCol) + 1)
.Value = WorksheetFunction.Transpose(SheetCol)
End With
End Sub
Thêm 1 ví dụ nữa: Lấy số cell rổng lớn nhất nằm liền nhau trong 1 cột
PHP:
Function MaxBlank(Vung As Range)
Dim Clls As Range, Max As Long, Dic
Set Dic = CreateObject("Scripting.Dictionary")
For Each Clls In Vung
If IsEmpty(Clls) Then
Max = Max + 1
Else
Dic.Add Clls, Max
Max = 0
End If
Next
MaxBlank = WorksheetFunction.Max(Dic.Items)
End Function
vân vân và vân vân ---> Tùy theo khả năng anh có thể nghĩ ra được
Dim MyRng As Range, RngFound As Range, iA As Long
Dim ei As Long, iFind As String, Dem As Long
Dim MyArr() As Variant
ei = [a65000].End(xlUp).Row
Set MyRng = Range("A1:A" & Er)
MyArr = Array("FRE", "SYD", "MEL", "BNE")
For iA = LBound(MyArr()) To UBound(MyArr())
iFind = MyArr(iA)
Dem = WorksheetFunction.CountIf(MyRng, "*" & iFind & "*")
Set RngFound = MyRng(1)
For i = 1 To Dem
With MyRng
Set RngFound = .Find(iFind, After:=RngFound, SearchOrder:=xlColumns, _
LookIn:=xlFormulas, LookAt:=xlPart, SearchDirection:=xlPrevious)
End With
With RngFound
.Value = Replace(.Value, "KKLU", "KLIS")
End With
Next
Next
thưa anh, chị
Trong đoạn code trên có đoạn sau em chưa hiểu, kính mong được chỉ dạy
PHP:
Set MyRng = Range("A1:A" & Er)
Set RngFound = MyRng(1)
ở trên ta set range MyRng, nhưng em chưa hiểu chỗ MyRng(1) có ý nghĩa gì
--
Em xin phép hỏi thêm một câu nữa
Trong đoạn code trên nếu phương thức FInd Previous thay bằng Find Next thì có ảnh hưởng gì không?
thưa anh, chị
Trong đoạn code trên có đoạn sau em chưa hiểu, kính mong được chỉ dạy
PHP:
Set MyRng = Range("A1:A" & Er)
Set RngFound = MyRng(1)
ở trên ta set range MyRng, nhưng em chưa hiểu chỗ MyRng(1) có ý nghĩa gì
--
Em xin phép hỏi thêm một câu nữa
Trong đoạn code trên nếu phương thức FInd Previous thay bằng Find Next thì có ảnh hưởng gì không?
Trong PT Find, RngFound là vùng range tìm thấy, ta Set RngFound = MyRng(1) nghĩa là ta bắt đầu tìm từ ô đầu tiên của MyRng. ở đây là tìm từ A1 tìm và tìm ngựoc FInd Previous A1 -> A er, A er -1. Bạn có thể thay thành Find Next. Bạn cứ thử xem.
Xin chào các cao thủ Excel, mình có một câu hỏi muốn nhờ tất cả mọi người giúp đỡ.
mình có 2 hàng dữ liệu (hàng 2 và hàng 3). Bây giờ mình muốn gộp 2 hàng dữ liệu này thành một hàng (như hàng 6) thì mình phải làm thế nào. Mong các bạn chỉ giúp. Mình xin cảm ơn trước.
Mình có 2 hàng dữ liệu (hàng 2 và hàng 3). Bây giờ mình muốn gộp 2 hàng dữ liệu này thành một hàng (như hàng 6) thì mình phải làm thế nào. Mong các bạn chỉ giúp. Mình xin cảm ơn trước.