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

FPT_online

Thành viên hoạt động
Tham gia ngày
27 Tháng mười 2013
Bài viết
100
Thích
2
Điểm
170
Tuổi
36
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
 
Tham gia ngày
10 Tháng ba 2018
Bài viết
562
Thích
1,244
Điểm
210

File đính kèm

VetMini

Thành viên gạo cội
Tham gia ngày
21 Tháng mười hai 2012
Bài viết
5,602
Thích
6,320
Điểm
560
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.
 
Tham gia ngày
10 Tháng ba 2018
Bài viết
562
Thích
1,244
Điểm
210
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 ạ
 

VetMini

Thành viên gạo cội
Tham gia ngày
21 Tháng mười hai 2012
Bài viết
5,602
Thích
6,320
Điểm
560
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).
 

truongvu317

Thành viên tích cực
Tham gia ngày
15 Tháng mười một 2010
Bài viết
425
Thích
329
Điểm
410
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.
 

tueyennhi

Thành viên tích cực
Tham gia ngày
18 Tháng mười 2010
Bài viết
980
Thích
58
Điểm
420
Tuổi
29
Liệu có code như này không anh chị
Find("<>1", LookIn:=xlValues, LookAt:=xlWhole)
Em điền thì không thấy có tác dụng gì cả. Em muốn tìm giá trị khác 1
 

Khoakv.vp

Thành viên mới
Tham gia ngày
6 Tháng năm 2016
Bài viết
5
Thích
0
Điểm
0
Tuổi
30
Mọi Người Giúp Mình với:
Mình mới tìm hiểu VBA cho excel. Mình viết 1 hàm đơn giản tính đơn giá cước VC như này:

Mã:
Public Function Don_gia(culi) As Double
' tính don giá cuoc Van chuyen Bê tông
bang_gia = Sheets(1).Ranges("E56:E65")
If culi <= 2 Then
Don_gia = Application.Index(bang_gia, 1)
Exit Function
ElseIf culi <= 5 Then
    Don_gia = Application.Index(bang_gia, 2)
    Exit Function
    ElseIf culi >= 41 Then
        Don_gia = Application.Index(bang_gia, 10)
        Exit Function
        Else: Don_gia = Application.Index(bang_gia, Application.RoundUp(culi / 5, 0))
End If

End Function
Ban đầu save nó yêu cầu save vào file Macro Enable lưu ngon lành ko báo lỗi gì, nhưng khi dùng thì kết quả toàn là #name .... giúp Mình Với.
 

Ba Tê

Cạo Rồi Khỏi Gội
Tham gia ngày
5 Tháng năm 2009
Bài viết
10,222
Thích
14,327
Điểm
1,560
Tuổi
59
Mọi Người Giúp Mình với:
Mình mới tìm hiểu VBA cho excel. Mình viết 1 hàm đơn giản tính đơn giá cước VC như này:

Mã:
Public Function Don_gia(culi) As Double
' tính don giá cuoc Van chuyen Bê tông
bang_gia = Sheets(1).Ranges("E56:E65")
If culi <= 2 Then
Don_gia = Application.Index(bang_gia, 1)
Exit Function
ElseIf culi <= 5 Then
    Don_gia = Application.Index(bang_gia, 2)
    Exit Function
    ElseIf culi >= 41 Then
        Don_gia = Application.Index(bang_gia, 10)
        Exit Function
        Else: Don_gia = Application.Index(bang_gia, Application.RoundUp(culi / 5, 0))
End If

End Function
Ban đầu save nó yêu cầu save vào file Macro Enable lưu ngon lành ko báo lỗi gì, nhưng khi dùng thì kết quả toàn là #name .... giúp Mình Với.
Gởi file và giải thích yêu cầu bạn muốn làm gì mới biết được.
 

HieuCD

Thành viên gạo cội
Tham gia ngày
14 Tháng chín 2010
Bài viết
4,775
Thích
7,237
Điểm
560
Mọi Người Giúp Mình với:
Mình mới tìm hiểu VBA cho excel. Mình viết 1 hàm đơn giản tính đơn giá cước VC như này:

Mã:
Public Function Don_gia(culi) As Double
' tính don giá cuoc Van chuyen Bê tông
bang_gia = Sheets(1).Ranges("E56:E65")
If culi <= 2 Then
Don_gia = Application.Index(bang_gia, 1)
Exit Function
ElseIf culi <= 5 Then
    Don_gia = Application.Index(bang_gia, 2)
    Exit Function
    ElseIf culi >= 41 Then
        Don_gia = Application.Index(bang_gia, 10)
        Exit Function
        Else: Don_gia = Application.Index(bang_gia, Application.RoundUp(culi / 5, 0))
End If

End Function
Ban đầu save nó yêu cầu save vào file Macro Enable lưu ngon lành ko báo lỗi gì, nhưng khi dùng thì kết quả toàn là #name .... giúp Mình Với.
Bạn lưu file với tên và phần mở rộng là gì? Mở file để nhập công thức với tên và phần mở rộng là gì?
 

Khoakv.vp

Thành viên mới
Tham gia ngày
6 Tháng năm 2016
Bài viết
5
Thích
0
Điểm
0
Tuổi
30
Gởi file và giải thích yêu cầu bạn muốn làm gì mới biết được.
MÌnh muốn viết Hàm tính đơn giá cước vận chuyển biến là cự li vận chuyển, Bảng giá là Vùng dữ liệu trong bảng tính có đơn giá cho từng cự li.
Mọi người check code giúp mình xem code đúng không và sao kết quả là lỗi #name nhỉ ?
 

HieuCD

Thành viên gạo cội
Tham gia ngày
14 Tháng chín 2010
Bài viết
4,775
Thích
7,237
Điểm
560
Do trùng tên module, ngoài ra còn bị lổi range
Mã:
Public Function Don_gia1(culi) As Double
' tính don giá cuoc Van chuyen Bê tông
  Dim Bang_Gia As Range
  Set Bang_Gia = Sheets(1).Range("E56:E65")
  If culi <= 2 Then
      Don_gia1 = Application.Index(Bang_Gia, 1)
    ElseIf culi <= 5 Then
      Don_gia1 = Application.Index(Bang_Gia, 2)
    ElseIf culi >= 41 Then
      Don_gia1 = Application.Index(Bang_Gia, 10)
    Else
      Don_gia1 = Application.Index(Bang_Gia, Application.RoundUp(culi / 5, 0) + 1)
  End If
End Function
 

Ba Tê

Cạo Rồi Khỏi Gội
Tham gia ngày
5 Tháng năm 2009
Bài viết
10,222
Thích
14,327
Điểm
1,560
Tuổi
59
Sửa tên Module cho khác với tên Function.
Cho vào mảng gọn hơn.
PHP:
Public Function Don_gia(Culy As Double) As Double
' tính don giá cuoc Van chuyen Bê tông
Dim Bang_gia()
Bang_gia = Sheets("Gia_cuoc").Range("E56:E65").Value
If Culy <= 2 Then
    Don_gia = Bang_gia(1, 1)
ElseIf Culy >= 41 Then
    Don_gia = Bang_gia(10, 1)
Else
    Don_gia = Bang_gia(Application.WorksheetFunction.RoundUp(Culy / 5, 0) + 1, 1)
End If
End Function
 

File đính kèm

ndu96081631

Huyền thoại GPE
Thành viên BQT
Super Moderator
Tham gia ngày
5 Tháng sáu 2008
Bài viết
30,108
Thích
52,067
Điểm
11,910
Sửa tên Module cho khác với tên Function.
Cho vào mảng gọn hơn.
PHP:
Public Function Don_gia(Culy As Double) As Double
' tính don giá cuoc Van chuyen Bê tông
Dim Bang_gia()
Bang_gia = Sheets("Gia_cuoc").Range("E56:E65").Value
If Culy <= 2 Then
    Don_gia = Bang_gia(1, 1)
ElseIf Culy >= 41 Then
    Don_gia = Bang_gia(10, 1)
Else
    Don_gia = Bang_gia(Application.WorksheetFunction.RoundUp(Culy / 5, 0) + 1, 1)
End If
End Function
File của anh vẫn báo lỗi #NAME?
 

Khoakv.vp

Thành viên mới
Tham gia ngày
6 Tháng năm 2016
Bài viết
5
Thích
0
Điểm
0
Tuổi
30
Sửa tên Module cho khác với tên Function.
Cho vào mảng gọn hơn.
PHP:
Public Function Don_gia(Culy As Double) As Double
' tính don giá cuoc Van chuyen Bê tông
Dim Bang_gia()
Bang_gia = Sheets("Gia_cuoc").Range("E56:E65").Value
If Culy <= 2 Then
    Don_gia = Bang_gia(1, 1)
ElseIf Culy >= 41 Then
    Don_gia = Bang_gia(10, 1)
Else
    Don_gia = Bang_gia(Application.WorksheetFunction.RoundUp(Culy / 5, 0) + 1, 1)
End If
End Function
Cảm ơn Bác nhiều nhé !
 
Top