Chuyên đề giải đáp những thắc mắc về code VBA

Liên hệ QC

maytinhvp01

Thành viên thường trực
Tham gia
27/7/13
Bài viết
390
Được thích
179
Mình muốn nhờ giải thich câu lệnh " If Ran.Cells(d, c) > max Then max = Ran.Cells(d, c) "
trong ví du:
Public Function LonNhat(Ran As Range)
Dim max As Double, v As Integer, d As Integer, c As Integer
max = Ran.Cells(1, 1)
For d = 1 To Ran.Rows.Count
For c = 1 To Ran.Columns.Count
If Ran.Cells(d, c) > max Then max = Ran.Cells(d, c)
Next c
Next d
v = Tim(max, Ran)
LonNhat = max
End Function
-------------------------------------------------------
[INFO1]Thông báo:
Vì topic này:
http://www.giaiphapexcel.com/forum/...ải-thích-các-code-đề-nghị-các-bạn-gửi-vào-đây
đã quá dài nên BQT đóng lại.
Nay tôi mở topic mới với cùng chủ đề: GIẢI THÍCH NHỮNG THẮC MẮC VỀ CODE
Các bạn nếu có nhu cầu giải thích code, vui lòng post tại đây nhé
NDU96081631

[/INFO1]
 
Chỉnh sửa lần cuối bởi điều hành viên:
Upvote 0
Mình có đoạn code như sau:
Sub PTVT()
Call Code_Begin
Call Code_End
................................
Có cách nào tăng tốc code không.........................
1/ Code_begin và Code_end chỉ là tắt chế độ màn hình và chế độ tính toán tự động sao không cho nó chung vào một.
2/ Thay vì sử dụng AutoFilter sao không dùng Advanced Filter nó cũng có chức năng Filter.
3/ Trong code mà sử dụng Select và ActiveSheet nên nó chậm là phải rồi.
 
Upvote 0
1/ Code_begin và Code_end chỉ là tắt chế độ màn hình và chế độ tính toán tự động sao không cho nó chung vào một.
2/ Thay vì sử dụng AutoFilter sao không dùng Advanced Filter nó cũng có chức năng Filter.
3/ Trong code mà sử dụng Select và ActiveSheet nên nó chậm là phải rồi.
Call Code_Begin: để tắt các chức năng
Call Code_End: Để bật trở lại
 
Upvote 0
Em đang phải học lại dictionary nên đoạn code sau chưa hiểu, chưa biết làm như thế nào để tính tổng theo code duy nhất ah. Mong Thầy chỉ giúp!

Sub T2()
Worksheets("Data").Range("F2", Range("I65536").End(xlUp)).Select
Selection.ClearContents
Range("F1").Select
Range("F1").Value = "GtriDuynhatCode"
Range("G1").Value = "Product_Gom"
Range("H1").Value = "TongTheoCode"
Range("I1").Value = "count"

Dim dic As Object, dic2 As Object
Set dic = CreateObject("Scripting.dictionary")
Set dic2 = CreateObject("Scripting.dictionary")

Dim Arr As Variant
Dim VungDuLieu
Set VungDuLieu = Worksheets("Data").Range("A2", Range("C65536").End(xlUp))
Arr = VungDuLieu.Value
ReDim dArr(1 To UBound(Arr, 1), 1 To 3)

Dim iRow As Long, i As Long, j As Long
For iRow = 1 To UBound(Arr, 1)
If Not IsEmpty(Arr(iRow, 1)) And Not dic.Exists(Arr(iRow, 1)) Then
i = i + 1
dic.Add Key:=Arr(iRow, 1), Item:=i

dArr(i, 1) = Arr(iRow, 1)

'MsgBox "iTems " & dic.Count & " cua dic " & " tai dong thu: " & (iRow + 1) _
' & "___" & Arr(iRow, 1) & "___" & Arr(iRow, 2) _
' & "___" & Arr(iRow, 3)

'MsgBox dic.Count & vbCrLf & Join(dic.keys, vbLf) 'Cau lenh rat hay ve dictionary
'MsgBox dic.Count & vbCrLf & Join(dic.Keys, vbLf) & vbCrLf _
' & vbCrLf & (iRow + 1) & "___" _
' & "___" & Arr(iRow, 2) _
' & "___" & Arr(iRow, 3)
' 'Arr(iRow, 1)~Join(dic.keys, vbLf)
'MsgBox UBound(dic.Keys) + 1 'So luong gia tri duy nhat Keys

Else
'MsgBox UBound(dic.Items) + 1
End If
Next

'Tra ket qua
Range("F2").Resize(i, 4).Value = dArr
Range("F1").Select

'MsgBox "So luong iTems la: " & dic.Count
Set dic = Nothing
Set dic2 = Nothing
'MsgBox "Done"
End Sub
 

File đính kèm

  • Example-3.xls
    67.5 KB · Đọc: 6
Upvote 0
Em đang phải học lại dictionary nên đoạn code sau chưa hiểu, chưa biết làm như thế nào để tính tổng theo code duy nhất ah. Mong Thầy chỉ giúp!
Tổng theo Code duy nhất hay theo Code+Product duy nhất?
Nếu theo Code+Product duy nhất thì xem cái này.
PHP:
Sub s_Gpe()
Application.ScreenUpdating = False
Dim Dic As Object, Tem As String
Dim sArr(), dArr(), I As Long, K As Long, R As Long, Rws As Long
Set Dic = CreateObject("Scripting.Dictionary")
    sArr = Range("A2", Range("C65536").End(xlUp))
    Rws = UBound(sArr)
ReDim dArr(1 To Rws, 1 To 4)
dArr(1, 1) = "GtriDuynhatCode"
dArr(1, 2) = "Product_Gom"
dArr(1, 3) = "TongTheoCode"
dArr(1, 4) = "Count"
K = 1
For I = 1 To Rws
    Tem = sArr(I, 1) & "#" & sArr(I, 2)
    If Not Dic.Exists(Tem) Then
        K = K + 1
        Dic.Item(Tem) = K
        dArr(K, 1) = sArr(I, 1)
        dArr(K, 2) = sArr(I, 2)
        dArr(K, 3) = sArr(I, 3)
        dArr(K, 4) = 1
    Else
        R = Dic.Item(Tem)
        dArr(R, 3) = dArr(R, 3) + sArr(I, 3)
        dArr(R, 4) = dArr(R, 4) + 1
    End If
Next I
Range("F1:I1").Resize(K) = dArr
Range("F2:I2").Resize(K).Sort Key1:=Range("F2"), Key2:=Range("G2")
Set Dic = Nothing
End Sub
 
Upvote 0
Tuyệt vời! code này em phải vọc thật kỹ mới được! quá hay luôn ấy!
Nếu chỉ tính tổng theo code duy nhất thì ntn ah?
 
Upvote 0
Anh Chị cho em hỏi! khi xuất hiện msgbox thông báo phải tắt đi thì mới kích chuột được ra vùng khác phải làm như nào. Em xin cảm ơn
 
Upvote 0
Cho em hỏi có code nào bắt được sự kiện enter không?
Em muốn nếu khi em enter ở sheet chỉ định thì nó sẽ thực hiện một lệnh nào đó
Em tìm được code này trên mạng nhưng chưa làm cho nó chạy được (Em gán trực tiếp code này vào sheet)
PHP:
Private Sub BatsuKien()
    Application.OnKey "{ENTER}", "MyEnterEvent"
End Sub
Sub MyEnterEvent()
    Cells(RDB_Last(1, [B:B]), 2).Select
End Sub
 
Lần chỉnh sửa cuối:
Upvote 0
Cho em hỏi có code nào bắt được sự kiện enter không?
Em muốn nếu khi em enter ở sheet chỉ định thì nó sẽ thực hiện một lệnh nào đó
Em tìm được code này trên mạng nhưng chưa làm cho nó chạy được (Em gán trực tiếp code này vào sheet)
PHP:
Private Sub BatsuKien()
    Application.OnKey "{ENTER}", "MyEnterEvent"
End Sub
Sub MyEnterEvent()
    Cells(RDB_Last(1, [B:B]), 2).Select
End Sub
Thử dùng lệnh batsukien trong sub auto_open xem sao.
 
Lần chỉnh sửa cuối:
Upvote 0
Cho em hỏi có code nào bắt được sự kiện enter không?
Em muốn nếu khi em enter ở sheet chỉ định thì nó sẽ thực hiện một lệnh nào đó
Em tìm được code này trên mạng nhưng chưa làm cho nó chạy được (Em gán trực tiếp code này vào sheet)
PHP:
Private Sub BatsuKien()
    Application.OnKey "{ENTER}", "MyEnterEvent"
End Sub
Sub MyEnterEvent()
    Cells(RDB_Last(1, [B:B]), 2).Select
End Sub
Sao bạn không đọc Help nhỉ? Bởi nếu có đọc thì sẽ biết:
- Phím Enter trên bàn phím số được ghi là "{ENTER}"
- Phím Enter thường được ghi là "~"
Vậy bạn đang cần cái Enter nào?
Ngoài ra, muốn code chạy khi gõ bàn phím thì đương nhiên phải kích hoạt nó trước. Cụ thể để code của bạn hoạt động thì phải chạy Sub BatsuKien trước, sau đó gõ phím rồi Enter mới có tác dụng
 
Upvote 0
Sao bạn không đọc Help nhỉ? Bởi nếu có đọc thì sẽ biết:
- Phím Enter trên bàn phím số được ghi là "{ENTER}"
- Phím Enter thường được ghi là "~"
Vậy bạn đang cần cái Enter nào?
Ngoài ra, muốn code chạy khi gõ bàn phím thì đương nhiên phải kích hoạt nó trước. Cụ thể để code của bạn hoạt động thì phải chạy Sub BatsuKien trước, sau đó gõ phím rồi Enter mới có tác dụng

Em có đọc về hai phím enter như thầy bảo và em chọn bắt sự kiện enter trên bàn phím số.
Em muốn khi em enter bàn phím số thì Sub MyEnterEvent sẽ chạy.
Cụ thể khi em enter thì em muốn nó sẽ tự động chuyển xuống dòng cuối cùng của cột B tại sheet mà em gán code.
 
Lần chỉnh sửa cuối:
Upvote 0
Em có đọc về hai phím enter như thầy bảo và em chọn bắt sự kiện enter trên bàn phím số.
Em muốn khi em enter bàn phím số thì Sub MyEnterEvent sẽ chạy.
Cụ thể khi em enter thì em muốn nó sẽ tự động chuyển xuống dòng cuối cùng của cột B tại sheet mà em gán code.
Xem thử đúng yêu cầu chưa.
 

File đính kèm

  • Bat su kien phim Enter.xlsm
    20.7 KB · Đọc: 8
Upvote 0
Xem thử đúng yêu cầu chưa.
Đúng ý mình rồi, cảm ơn bạn nhé :)

Cho mình hỏi đoạn này có tác dụng gì mà xóa đi vẫn thấy chạy
PHP:
Private Sub Workbook_SheetDeactivate(ByVal Sh As Object)
    If Sh.Name = "GPE" Then Application.OnKey "{ENTER}", ""
End Sub

À có một điều là khi tải file về mình phải chuyển sang sheet khác để Enter rồi quay lại sheet GPE mới có tác dụng. Vì sao vậy nhỉ bạn?
 
Lần chỉnh sửa cuối:
Upvote 0
Cho mình hỏi đoạn này có tác dụng gì mà xóa đi vẫn thấy chạy
PHP:
Private Sub Workbook_SheetDeactivate(ByVal Sh As Object)
    If Sh.Name = "GPE" Then Application.OnKey "{ENTER}", ""
End Sub
Bạn thử xóa nó và chọn qua sheet1, sheet2 và nhấn Enter thử xem.
À có một điều là khi tải file về mình phải chuyển sang sheet khác để Enter rồi quay lại sheet GPE mới có tác dụng. Vì sao vậy nhỉ bạn?
Bạn thêm đoạn code này vào ThisWorkbook thử xem.
Mã:
Private Sub Workbook_Open()
    If ActiveSheet.Name = "GPE" Then Application.OnKey "{ENTER}", "MyEnterEvent"
End Sub
Cụ thể code trong ThisWorkbook sẽ là.
Mã:
Private Sub Workbook_Open()
    If ActiveSheet.Name = "GPE" Then Application.OnKey "{ENTER}", "MyEnterEvent"
End Sub
Private Sub Workbook_SheetActivate(ByVal Sh As Object)
     If Sh.Name = "GPE" Then Application.OnKey "{ENTER}", "MyEnterEvent"
End Sub
Private Sub Workbook_SheetDeactivate(ByVal Sh As Object)
    If Sh.Name = "GPE" Then Application.OnKey "{ENTER}", ""
End Sub
 
Upvote 0
Cho em hỏi hai cái này thì có gì khác nhau?
Tem = arr(i,1)
1. Dic.Add Tem, i
2. Dic.Item(Tem) = i

Em có đọc trong bài Tổng quan về Scripting Ditionary thì có đoạn code sau
PHP:
With MyDictionary
         .Add 1, "number"
         .Item("1") = "text"
End With

Như vậy về bản chất cái Tem trong 1 và 2 của em nó đều là key còn i là item có phải không?
 
Lần chỉnh sửa cuối:
Upvote 0
Cho em hỏi hai cái này thì có gì khác nhau?
Tem = arr(i,1)
1. Dic.Add Tem, i
2. Dic.Item(Tem) = i
...

Khác nhau:
trường hợp 1, sẽ ghi thêm một cặp key-item với key là Tem và item là i. Vì vậy nếu đã có Tem sẵn rồi thì sẽ bị lỗi.
trường hợp 2, sẽ lôi cặp key-item với key là Tem ra và sửa item nó thành i. Nếu chưa có Tem thì tự thêm vào. Nếu đã có sẵn Tem thì item trước đó sẽ bị ghi chồng.
(chú: nhiều ngừoi ở diễn đàn này có thói quen dùng từ Tem để đặt tên cho biến. Theo lệ chung của lập trình thì tem, tmp temp chỉ nên dùng cho biến có giá trj tạm. Dùng để đặt tên key là lạm dụng)

Dictionary, theo định nghĩa là một tập hợp của những phát sinh, mỗi phát sinh là một cặp key-item.
 
Upvote 0
Phiếm bàn về "Tem":
Tôi đoán là khi viết code, ngừoi ta muốn nói đến từ "temporary" (tạm thời) trong tiếng Anh. Chứ thực sự, trong ngữ cảnh những đoạn code được dùng ở diễn đàn này thì Têm (trầu?) hay Tem (thư?) chả có nghĩa lý gì cả.
Với tên gọi (từ ngữ lập trình là identifier) "tem", người lập trình viên căn bản chỉ dùng cho biến có mục đích tạm, nó không nhất thiết phải mang ý nghĩa hay chỉ vào cái gì. Trường hợp điển hình là code hoán chuyển trị
tem = a: a = b: b = tem ' đoạn code hoán chuyển trị a và b
tem đáp ứng điều kiện thứ nhất: mục đích tạm; và điều kiện thứ hai: nó làm nhiệm vụ trung gian giữa a b mà không cần biết a và b là cái gì.
Cái "mục đích tạm" nó cần được diễn giải thêm rằng thường thì người đọc code tự động hiểu rằng cái tầm vực của trị này không đi xa quá 3 dòng.

Dùng tem cho trường hợp chung chung khác có thể gây hiểu lầm cho người không quen đọc code của mình.
Trên thực tế tem, tm, tmp, temp còn có thể là từ tắt của temperature.
 
Upvote 0
Web KT
Back
Top Bottom