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:
Em chỉ muốn ô đó là ô trống, em tự điền. Nhưng khi em chạy code thì dữ liệu em đã điền bị xóa luôn. Ý là cột 1,2,3 là fill dữ liệu từ code, bỏ cột 4 ( tự điền ), fill cột 5 fill dữ liệu từ code
Bạn xem đúng ý không.
Mã:
Public Sub GPE()
    Dim sArr(), dArr1(), dArr2(), I As Long, J As Long, K As Long, C As Long, R As Long
    With Sheets("Roster")
        C = .Range("F2") - .Range("C2") + 6
        sArr = .Range("B5", .Range("B50000").End(xlUp)).Resize(, C).Value
        R = UBound(sArr, 1)
        ReDim dArr1(1 To R * C, 1 To 3): ReDim dArr2(1 To R * C, 1 To 1)
    End With
    For I = 5 To R Step 5
        If sArr(I, 1) <> Empty Then
            For J = 6 To C
                K = K + 1
                dArr1(K, 1) = sArr(I, 1)
                dArr1(K, 2) = sArr(1, J)
                dArr1(K, 3) = sArr(1, J)
                dArr2(K, 1) = sArr(I, J)
            Next J
        End If
    Next I
    With Sheets("IT2003")
        Range("A2").Resize(100000, 3).ClearContents
        Range("E2").Resize(100000).ClearContents
        If K Then .Range("A2").Resize(K, 3) = dArr1: .Range("E2").Resize(K, 1) = dArr2
    End With
End Sub
 
Upvote 0
Bạn xem đúng ý không.
Mã:
Public Sub GPE()
    Dim sArr(), dArr1(), dArr2(), I As Long, J As Long, K As Long, C As Long, R As Long
    With Sheets("Roster")
        C = .Range("F2") - .Range("C2") + 6
        sArr = .Range("B5", .Range("B50000").End(xlUp)).Resize(, C).Value
        R = UBound(sArr, 1)
        ReDim dArr1(1 To R * C, 1 To 3): ReDim dArr2(1 To R * C, 1 To 1)
    End With
    For I = 5 To R Step 5
        If sArr(I, 1) <> Empty Then
            For J = 6 To C
                K = K + 1
                dArr1(K, 1) = sArr(I, 1)
                dArr1(K, 2) = sArr(1, J)
                dArr1(K, 3) = sArr(1, J)
                dArr2(K, 1) = sArr(I, J)
            Next J
        End If
    Next I
    With Sheets("IT2003")
        Range("A2").Resize(100000, 3).ClearContents
        Range("E2").Resize(100000).ClearContents
        If K Then .Range("A2").Resize(K, 3) = dArr1: .Range("E2").Resize(K, 1) = dArr2
    End With
End Sub
Thành công mỹ mãn. Em cám ơn anh rất nhiều
 
Upvote 0
Hi cả nhà ạ
Mình có viết đoạn code về tìm kiếm trong Combobox như sau:

Dim i As Long
For i = 1 To Application.WorksheetFunction.CountA(Main.Range("F:F"))
If LCase(Left(Main.Cells(i, 1), 1)) = Me.ComboBox1 And Me.ComboBox1 <> "" Then
Me.ComboBox1.AddItem Main.Cells(i, 1)
End If
Next i
Me.ComboBox1.DropDown
With Me
.txtdi.Value = .ComboBox1.List(.ComboBox1.ListIndex, 1)
End With
End Sub

nhưng khi bấm seach thì không hiện ra như mong muốn, chỉ viết tìm kiếm được có một chữ đến 2 chữ cái chứ không viết nhiều được ạ, và viết xong không bấm nút xoá được.
Trong Combobox mình để có 2 cột
Mong cả nhà giúp đỡ ạ
 
Upvote 0
Cho mình hỏi code:
Mã:
Range("$C$3:$C$1734").AutoFilter Field:=1, Criteria1:="*" & Range("C1").Value & "*", Operator:=xlFilterValues
Nghĩ là gì vậy
 
Upvote 0
Cho em hỏi đoạn code em viết này sao nó chậm thế, có cách nào cho nhanh hơn không ạ
 

File đính kèm

  • VD.xls
    70.5 KB · Đọc: 7
Upvote 0
Cho em hỏi nếu viết dưới dạng Application.WorsheetFunction để có thể dùng với nhiều dạng hàm khác thì không được ạ?
 
Upvote 0
Cho em hỏi nếu viết dưới dạng Application.WorsheetFunction để có thể dùng với nhiều dạng hàm khác thì không được ạ?
Em đọc ở đâu đó không nhớ rõ nhưng nếu mà sử dụng Application.WorsheetFunction thì phải thêm gỡ lỗi nữa thì phải..Cái Áp pờ li ca ti on khác với cái Áp pờ li ca ti on guốc sít phăn thì phải.Ôi khó đi ..
 
Lần chỉnh sửa cuối:
Upvote 0
Em đọc ở đâu đó không nhớ rõ nhưng nếu mà sử dụng Application.WorsheetFunction thì phải thêm gỡ lỗi nữa thì phải..Cái Áp pờ li ca ti on khác với cái Áp pờ li ca ti on guốc sít phăn thì phải.Ôi khó đi ..
Dùng cái nào đi nữa đều phải chủ động bẫy lỗi, ví dụ với cái vlookup chẳng hạn, Application.WorsheetFunction khi không dò được thì phát sinh lỗi. Với application tuy không phát sinh lỗi thực thi, nhưng kết quả của nó là Na, vẫn phải bẫy trường hợp này, nếu không code cũng teo.
 
Upvote 0
Dùng cái nào đi nữa đều phải chủ động bẫy lỗi, ví dụ với cái vlookup chẳng hạn, Application.WorsheetFunction khi không dò được thì phát sinh lỗi. Với application tuy không phát sinh lỗi thực thi, nhưng kết quả của nó là Na, vẫn phải bẫy trường hợp này, nếu không code cũng teo.
Em không biết 1 tẹo tiếng anh nào. Nhưng google họ dịch như thế này
Mã:
Thí dụ

Mã số:
Phạm vi ("A1") .Giá trị = Ứng dụng.WorksheetFunction.Vlookup (.....)
Nếu Vlookup không tìm thấy một kết quả phù hợp (# N / A khi được viết trong một ô)
Sau đó, mã của bạn ngừng chạy và bạn nhận được cửa sổ gỡ lỗi.

nếu bạn làm như thế này
Mã số:
x = Application.Vlookup (.....)
Nó không còn dừng lại với gỡ lỗi.
Thay vào đó, biến x được gán giá trị lỗi và mã tiếp tục chạy.
 
Upvote 0
Em không biết 1 tẹo tiếng anh nào. Nhưng google họ dịch như thế này
Mã:
Thí dụ

Mã số:
Phạm vi ("A1") .Giá trị = Ứng dụng.WorksheetFunction.Vlookup (.....)
Nếu Vlookup không tìm thấy một kết quả phù hợp (# N / A khi được viết trong một ô)
Sau đó, mã của bạn ngừng chạy và bạn nhận được cửa sổ gỡ lỗi.

nếu bạn làm như thế này
Mã số:
x = Application.Vlookup (.....)
Nó không còn dừng lại với gỡ lỗi.
Thay vào đó, biến x được gán giá trị lỗi và mã tiếp tục chạy.
Bạn cứ thử đi, biết liền, những điều tớ nói hoàn toàn tương đồng với google dịch.
 
Upvote 0
Nói chung mình muốn hỏi làm sao vẫn dùng Application.WorksheetFunction thì có cách nào cho nhanh không đó, nếu bẫy lỗi thì bẫy thế nào mọi người góp ý giúp
 
Upvote 0

File đính kèm

  • Vidu_0.xls
    70 KB · Đọc: 5
Upvote 0
Upvote 0
Em đọc ở đâu đó không nhớ rõ nhưng nếu mà sử dụng Application.WorsheetFunction thì phải thêm gỡ lỗi nữa thì phải..Cái Áp pờ li ca ti on khác với cái Áp pờ li ca ti on guốc sít phăn thì phải.Ôi khó đi ..

Tôi đã từng viết bài nói về cái này rồi. Nhưng nếu bạn vẫn mù mờ về lỗi thì có lẽ là chưa đọc bài đó.

WorksheetFunction sẽ lăn cù nếu gặp lỗi. Đó là điều kiện của nó. Nếu muốn tránh ngủm thì cái nơi gọi nó phải bẫy lỗi. Code bẫy lỗi thường là "On Error...". Loại code này thì hầu hết mọi người học qua bậc trung VBA đều biết viết.

Khi gọi hàm thẳng qua Application thì bạn có thể coi như là bạn gọi qua lớp bao gián tiếp (wrapper function). Lớp bao này cũng gọi hàm WorksheetFunction nhưng nó thêm cái code bẫy lỗi cho bạn. Nếu hàm bị lỗi thì nó sẽ không tỏi mà trả về một trị Error. Trong trường hợp này, người ta xét trị trả về để biết nó thành công hay error, và nếu error thì là gì.
Ví dụ điển hình:
myVariant = Application.Match(tim, mangDo, 0)
If Not IsError(myVariant) Then ' đây là hàm match cho nên dùng IsNumeric cũng được
' myVariant là kết quả
Else
' sử lý error ở đây
' nhưng 99,99% trường hợp hàm match thì là do tìm không có cho nên cũng dễ biết
' 0,01% còn lại là do dữ liệu dỏm, ví dụ mảng chẳng phải là mảng
End If

Chú: thực ra giữa cách gọi trực tiếp và gián tiếp còn khác nhau ở một vài tính chất mặc định của tham số truyền vào. Nhưng cấp độ này rất cao, thú nhận rằng tôi cũng chỉ biết 1 vài trường hợp chứ chưa nắm hết.
 
Upvote 0
Tôi đã từng viết bài nói về cái này rồi. Nhưng nếu bạn vẫn mù mờ về lỗi thì có lẽ là chưa đọc bài đó.

WorksheetFunction sẽ lăn cù nếu gặp lỗi. Đó là điều kiện của nó. Nếu muốn tránh ngủm thì cái nơi gọi nó phải bẫy lỗi. Code bẫy lỗi thường là "On Error...". Loại code này thì hầu hết mọi người học qua bậc trung VBA đều biết viết.

Khi gọi hàm thẳng qua Application thì bạn có thể coi như là bạn gọi qua lớp bao gián tiếp (wrapper function). Lớp bao này cũng gọi hàm WorksheetFunction nhưng nó thêm cái code bẫy lỗi cho bạn. Nếu hàm bị lỗi thì nó sẽ không tỏi mà trả về một trị Error. Trong trường hợp này, người ta xét trị trả về để biết nó thành công hay error, và nếu error thì là gì.
Ví dụ điển hình:
myVariant = Application.Match(tim, mangDo, 0)
If Not IsError(myVariant) Then ' đây là hàm match cho nên dùng IsNumeric cũng được
' myVariant là kết quả
Else
' sử lý error ở đây
' nhưng 99,99% trường hợp hàm match thì là do tìm không có cho nên cũng dễ biết
' 0,01% còn lại là do dữ liệu dỏm, ví dụ mảng chẳng phải là mảng
End If

Chú: thực ra giữa cách gọi trực tiếp và gián tiếp còn khác nhau ở một vài tính chất mặc định của tham số truyền vào. Nhưng cấp độ này rất cao, thú nhận rằng tôi cũng chỉ biết 1 vài trường hợp chứ chưa nắm hết.
Dạ Cám ơn Thầy. Em cũng mới biết đến cái này ạ. Hôm trước em có đọc qua bài "Viết các UDF hiệu quả của VBA (Phần 2) - sử dụng các hàm Excel bên trong một UDF" họ nói WorksheetFunction tốc đọ nhanh hơn Thầy ạ
 
Upvote 0
Wrapper function nó có cái giá phải trả của nó. Chương trình phải kết nối wrapper và chạy 1 vài dòng code phụ - điển hình là code bẫy lỗi.

Tuy nhiên, nếu tôi không lầm thì trong mẫu code so sánh của bài trên, người ta không có bẫy lỗi. Vì vậy, sự so sánh chỉ trên lý thuyết.
Trên thực tế, code bẫy lỗi của worksheetfunction sẽ tăng nó lên 1 chút. Và bên application thì dùng variant cho nên cũng bị tăng lên một chút. (variant chậm hơn Long).
 
Upvote 0
Tôi đã từng viết bài nói về cái này rồi. Nhưng nếu bạn vẫn mù mờ về lỗi thì có lẽ là chưa đọc bài đó.

WorksheetFunction sẽ lăn cù nếu gặp lỗi. Đó là điều kiện của nó. Nếu muốn tránh ngủm thì cái nơi gọi nó phải bẫy lỗi. Code bẫy lỗi thường là "On Error...". Loại code này thì hầu hết mọi người học qua bậc trung VBA đều biết viết.

Khi gọi hàm thẳng qua Application thì bạn có thể coi như là bạn gọi qua lớp bao gián tiếp (wrapper function). Lớp bao này cũng gọi hàm WorksheetFunction nhưng nó thêm cái code bẫy lỗi cho bạn. Nếu hàm bị lỗi thì nó sẽ không tỏi mà trả về một trị Error. Trong trường hợp này, người ta xét trị trả về để biết nó thành công hay error, và nếu error thì là gì.
Ví dụ điển hình:
myVariant = Application.Match(tim, mangDo, 0)
If Not IsError(myVariant) Then ' đây là hàm match cho nên dùng IsNumeric cũng được
' myVariant là kết quả
Else
' sử lý error ở đây
' nhưng 99,99% trường hợp hàm match thì là do tìm không có cho nên cũng dễ biết
' 0,01% còn lại là do dữ liệu dỏm, ví dụ mảng chẳng phải là mảng
End If

Chú: thực ra giữa cách gọi trực tiếp và gián tiếp còn khác nhau ở một vài tính chất mặc định của tham số truyền vào. Nhưng cấp độ này rất cao, thú nhận rằng tôi cũng chỉ biết 1 vài trường hợp chứ chưa nắm hết.
Thì em mới nói là dùng cái nào cũng phải bẫy lỗi, dùng application thì biến gán phải là variant, nếu không có thể gây ra lỗi.
 
Upvote 0
Web KT
Back
Top Bottom