- Tham gia
- 3/6/06
- Bài viết
- 1,611
- Được thích
- 14,002
- Nghề nghiệp
- ...thiết kế máy bay cho VOI tự lái...^.^
Chúng ta biết tại sao chỉ có mấy hàm của Excel mà chúng ta mỗi người mỗi nghề có thể dùng nó để giải quyết công việc. Các hàm được xây dựng phải giải quyết theo hướng tổng quát không nên cụ thể một chi tiết trừ khi bắt buộc. Người dùng Excel có thể vận dụng hàm để sáng tác ra các công thức khác nhau, sự thông minh (công thức ngắn gọn+tốc độ xửa lý nhanh+dễ nhớ...) của nó tùy vào sáng tạo và tư duy của mỗi người. Đây chính là điểm mạnh của Excel và làm cho chúng ta cứ như mắc nợ Excel!
Chắc hẳn chúng ta ai cũng muốn mình học VBA để biết tạo ra các hàm không những cho mình và cả những người khác sử dụng! Vậy chúng nên thiết kế hàm như thế nào là tốt nhất? Để giải quyết câu hỏi này chúng ta bắt đầu từng việc:
1-Khai báo và đặt tên Thủ tục, Hàm, Biến, Hằng (Sub, Function, Dim, Const)
Bàn vào việc đặt tên mỗi người nên chọn một kiểu gọi là "chuẩn", có thể bằng tiếng Anh hay Việt. Theo tôi các bạn nên đặt theo tiếng Anh vì ngắn gọn hơn.
Việc đặt tên thực sự rất quan trọng (chúng ta trân trọng như là đặt tên cho con mình). Các bạn hình dung thế này, nếu chúng ta có hàng trăm phương tiện, công cụ làm việc, khi cần một việc gì đó chúng ta cần gọi nó ra ngay thì liệu chúng ta có nhớ tên gọi của nó không? Phương pháp đặt tên để giúp ta dễ nhớ hơn.
+ Tên Thủ tục, Hàm: Tên phải hàm ý về nội dung giải quyết của nó. Điều quan trọng là không được trùng với từ khóa của Excel. Ví dụ không được đặt tên là "Sub", "Do", "Loop" hay các hàm sẵn có của VBA là "Left", "Right",...
Ví dụ tôi muốn tạo một hàm để tìm chuỗi, vậy tên tôi sẽ đặt tên function là "Timchuoi", "BatdaulaChuhoa" là hàm đổi các ký tự đầu của mỗi từ thành chữ hoa (Trong Excel có hàm Proper để làm nhưng hàm này bị lỗi với font với kiểu gõ không phải Unicode và có dấu), tại sao không đặt là "Chuhoa" để ngắn hơn? Vì có thể bị nhầm sang đổi chuỗi thành chữ hoa (UPPER, VBA-Ucase).
Chúng ta đặt tên sao cho không bị nhầm chức năng.
Trong VBA khai báo như sau
+ Tên Dim, Const: Cách thức cũng như phần đặ tên cho Sub/Function nhưng thêm các ký tự định nghĩa để làm sáng tỏ kiểu giá trị (Type)
Kiểu giá trị gồm: String, Byte, Integer, Long, Date, Object, Boolean....
Với tôi, tôi hay đặt tên với phần đầu là kiểu giá trị, các kiểu Byte, Integer, Long thì dùng chữ "n"-Number để đại diện vì cơ bản là giá trị số. Kiểu Boolean thì dùng chuỗi "Is".
......
Khi tôi viết hướng dẫn sử dụng hàm LEFT trên Excel tôi viết cấu trúc thế này LEFT(strChuoi, nKytu). Như vậy thì ta hiểu đối số đầu tiên là kiểu String - Chuỗi văn bản, nKytu là giá trị đưa vào kiểu số.
Có nhiều bạn khi khai báo kiểu giá trị thường hay bỏ lửng như Dim strHoTen mà không có kết thúc là "String" - Không nên chút nào! Việc xác định rõ giá trị còn là quy ước khi sử dụng chúng trong thân chương trình.
+ Xác định tham số cho Sub, Function
Nhắc lại về hàm LEFT(strChuoi, nKytu). Chúng ta cứ tự hỏi tại sao phải có 2 đối số? Tại sao? Muốn lấy bên trái với n ký tự thì buộc người dùng phải đưa vào strChuoi - chuối để lấy, nKytu là số ký tự cần lấy.
Như vậy tham số cho Sub, Function là những tham số mà người dùng phải buộc đưa vào thì Sub, Function mới xử lý được. Tên các tham số này người dùng (bất kỳ ai sử dụng) phải gần như tự đọc hiểu được).
Có một ví dụ về kiểu khai báo thế này:
Function Tachten(St as String,Bt as Integer)
St, Bt là cái gì? Viết thế này thì chỉ có tác giả mới hiểu và đến lúc nào đó chính họ sẽ không biết nó là cái gì nữa!
Khi đưa biến vào làm tham số chúng ta cũng cần chú ý một cách để Optional - Tùy ý và gán giá trị ngầm định.
Ví dụ:
Hàm "Timchuoi" để tìm strChuoiTim trong strChuoi, ngầm định (Optional) tìm từ trái sang phải.
A1="090 4210337"
=Timchuoi(A1," ")
Hàm sẽ tìm ký tự " " trong ô A1 và trả về vị trí tìm được, chúng ta nếu tìm từ trái thì không cần phải vào tham số thứ 3 vì ngầm định TuBenTrai=True rồi
Nếu tìm từ bên phải thì =Timchuoi(A1," ", False)
Chúng ta gán Optional đầu tiên trước khai báo Byval hay Byref khi biết chắc đa số mọi người sẽ quy ước biến này về một giá trị nào đó, sử dụng Optional để người dùng sử dụng ngắn gọn hơn (Bản chất là ta khai báo giá trị tham số giúp cho người dùng).
2- Tạo ra Sub, Function để giải quyết mấu chốt công việc, khai thác triệt để các hàm sãn có
Chúng viết các Sub, Function là để giải quyết mấu chốt công việc, không nên quá cụ thể nếu điều đó không phải là bắt buộc.
Tôi sẽ viết hàm "Timchuoi". Hàm này sẽ tìm chuỗi từ trái sang phải hoặc ngược lại, kết quả tìm được sẽ cho ra một số >0 là vị trí tìm được, =0 nếu không tìm được.
Cách 1
Mặc dù Cách 1 Khá chặt chẽ nhưng không hay chút nào vì vừa dài lại vừa không khai thác các hàm mà VBA đã cung cấp->Tốc độ xử lý rất có thể bị chậm hơn nhiều với việc áp dụng hàm đã có
Cách 2: 'Khai thác hàm đã có Instr và InstrRev
Ứng dụng hàm "Timchuoi"
Trích nguyên văn:
+ Hàm tách tên
+ Tách tên
Giả sử cột A là Họ và tên. Cần tách tên
Cách 1
=MID(A1,Timchuoi(A1," ",False)+1)
Cách 2
=TachTen(A1)
+ Tách dịch vụ điện thoại di động theo mã số
Giả sử cột A là các số điện thoại 090 4210337; 091 3255126; 098 555444; 0916 066512...
Cần lấy mã dịch vụ
=LEFT(A1,Timchuoi(A1," ")-1)
+ Từ số điện thoại cố định, tách mã vùng
Giả sử cột A là các số điện thoại 04 7544525 08 899655; 051 545222; 020 123456;...
=LEFT(A1,Timchuoi(A1," ")-1)
+ Tách tên tệp ra khỏi đường dẫn
'Sử dụng trong môi trương VBE
Sub VD()
Dim strFullPath as String
Dim strFileName as String
strFullPath = ActiveWorkbook.FullPath
strFileName=Mid(strFullPath,Timchuoi(strFullPath," \",False)+1)
'Thông báo
Msgbox strFileName,,strFullPath
End Sub
Như vậy chỉ có một hàm "Timchuoi" mà giải quyết được những vấn đề về cắt chuỗi theo các mục đích khác nhau.
Vấn đề tôi muốn nhấn mạnh là chúng ta viết hàm không phải để nó chỉ giải quyết một việc cụ thể mà nó phải giải quyết những bào toán tổng quát. Hàm như một linh kiện máy tính PC có thể lắp vào máy này hay máy khác.
Việc viết hàm và thủ tục còn có rất nhiều các thuật toán hay giúp cho bài toán của bạn được đánh giá ử mức tối ưu. Việc đặt tên cũng vậy còn nhiều trường hợp để đặt khác. Trong phạm vi một bài viết ngắn tôi chỉ có thể đưa ra những lý giải cơ bản và ví dụ nhỏ, các bạn xem và tự tích tũy dần những kiến thức cũng như kinh nghiệm về việc coding.
Chắc hẳn chúng ta ai cũng muốn mình học VBA để biết tạo ra các hàm không những cho mình và cả những người khác sử dụng! Vậy chúng nên thiết kế hàm như thế nào là tốt nhất? Để giải quyết câu hỏi này chúng ta bắt đầu từng việc:
1-Khai báo và đặt tên Thủ tục, Hàm, Biến, Hằng (Sub, Function, Dim, Const)
Bàn vào việc đặt tên mỗi người nên chọn một kiểu gọi là "chuẩn", có thể bằng tiếng Anh hay Việt. Theo tôi các bạn nên đặt theo tiếng Anh vì ngắn gọn hơn.
Việc đặt tên thực sự rất quan trọng (chúng ta trân trọng như là đặt tên cho con mình). Các bạn hình dung thế này, nếu chúng ta có hàng trăm phương tiện, công cụ làm việc, khi cần một việc gì đó chúng ta cần gọi nó ra ngay thì liệu chúng ta có nhớ tên gọi của nó không? Phương pháp đặt tên để giúp ta dễ nhớ hơn.
+ Tên Thủ tục, Hàm: Tên phải hàm ý về nội dung giải quyết của nó. Điều quan trọng là không được trùng với từ khóa của Excel. Ví dụ không được đặt tên là "Sub", "Do", "Loop" hay các hàm sẵn có của VBA là "Left", "Right",...
Ví dụ tôi muốn tạo một hàm để tìm chuỗi, vậy tên tôi sẽ đặt tên function là "Timchuoi", "BatdaulaChuhoa" là hàm đổi các ký tự đầu của mỗi từ thành chữ hoa (Trong Excel có hàm Proper để làm nhưng hàm này bị lỗi với font với kiểu gõ không phải Unicode và có dấu), tại sao không đặt là "Chuhoa" để ngắn hơn? Vì có thể bị nhầm sang đổi chuỗi thành chữ hoa (UPPER, VBA-Ucase).
Chúng ta đặt tên sao cho không bị nhầm chức năng.
Trong VBA khai báo như sau
PHP:
Function Timchuoi()
End Function
Function BatdaulaChuhoa()[HTML][/HTML]
End Function
+ Tên Dim, Const: Cách thức cũng như phần đặ tên cho Sub/Function nhưng thêm các ký tự định nghĩa để làm sáng tỏ kiểu giá trị (Type)
Kiểu giá trị gồm: String, Byte, Integer, Long, Date, Object, Boolean....
Với tôi, tôi hay đặt tên với phần đầu là kiểu giá trị, các kiểu Byte, Integer, Long thì dùng chữ "n"-Number để đại diện vì cơ bản là giá trị số. Kiểu Boolean thì dùng chuỗi "Is".
Mã:
Dim strHoTen as String
Dim IsNam as Boolean
Dim dNgay as Date
Khi tôi viết hướng dẫn sử dụng hàm LEFT trên Excel tôi viết cấu trúc thế này LEFT(strChuoi, nKytu). Như vậy thì ta hiểu đối số đầu tiên là kiểu String - Chuỗi văn bản, nKytu là giá trị đưa vào kiểu số.
Có nhiều bạn khi khai báo kiểu giá trị thường hay bỏ lửng như Dim strHoTen mà không có kết thúc là "String" - Không nên chút nào! Việc xác định rõ giá trị còn là quy ước khi sử dụng chúng trong thân chương trình.
+ Xác định tham số cho Sub, Function
Nhắc lại về hàm LEFT(strChuoi, nKytu). Chúng ta cứ tự hỏi tại sao phải có 2 đối số? Tại sao? Muốn lấy bên trái với n ký tự thì buộc người dùng phải đưa vào strChuoi - chuối để lấy, nKytu là số ký tự cần lấy.
Như vậy tham số cho Sub, Function là những tham số mà người dùng phải buộc đưa vào thì Sub, Function mới xử lý được. Tên các tham số này người dùng (bất kỳ ai sử dụng) phải gần như tự đọc hiểu được).
Có một ví dụ về kiểu khai báo thế này:
Function Tachten(St as String,Bt as Integer)
St, Bt là cái gì? Viết thế này thì chỉ có tác giả mới hiểu và đến lúc nào đó chính họ sẽ không biết nó là cái gì nữa!
Khi đưa biến vào làm tham số chúng ta cũng cần chú ý một cách để Optional - Tùy ý và gán giá trị ngầm định.
Ví dụ:
PHP:
Function Timchuoi(Byval strChuoi as String,Byval strChuoiTim as String, _
Optional Byval TuBenTrai as Boolean = True) as Long
End Function
Hàm "Timchuoi" để tìm strChuoiTim trong strChuoi, ngầm định (Optional) tìm từ trái sang phải.
A1="090 4210337"
=Timchuoi(A1," ")
Hàm sẽ tìm ký tự " " trong ô A1 và trả về vị trí tìm được, chúng ta nếu tìm từ trái thì không cần phải vào tham số thứ 3 vì ngầm định TuBenTrai=True rồi
Nếu tìm từ bên phải thì =Timchuoi(A1," ", False)
Chúng ta gán Optional đầu tiên trước khai báo Byval hay Byref khi biết chắc đa số mọi người sẽ quy ước biến này về một giá trị nào đó, sử dụng Optional để người dùng sử dụng ngắn gọn hơn (Bản chất là ta khai báo giá trị tham số giúp cho người dùng).
2- Tạo ra Sub, Function để giải quyết mấu chốt công việc, khai thác triệt để các hàm sãn có
Chúng viết các Sub, Function là để giải quyết mấu chốt công việc, không nên quá cụ thể nếu điều đó không phải là bắt buộc.
Tôi sẽ viết hàm "Timchuoi". Hàm này sẽ tìm chuỗi từ trái sang phải hoặc ngược lại, kết quả tìm được sẽ cho ra một số >0 là vị trí tìm được, =0 nếu không tìm được.
Cách 1
PHP:
Function Timchuoi(Byval strChuoi as String, Byval strChuoiTim as String, _
Optional Byval TuBenTrai as Boolean = True) as Long
Dim I as Long
Dim nKytuChuoitim as Long
Dim nKytuChuoi as Long
nKytuChuoi=Len(strChuoi)
nKytuChuoitim =Len(strChuoiTim)
If nKytuChuoi<nKytuChuoitim then Exit Function
If TuBenTrai Then
For I=1 To nKytuChuoi
If Mid(strChuoi,I,nKytuChuoitim)=strChuoiTim Then
Timchuoi=I
Goto Done:
End if
Next I
Else
For I=nKytuChuoi To 1 Step -1
If Not (nKytuChuoi-I< nKytuChuoitim) Then
If Mid(strChuoi,I,nKytuChuoitim)=strChuoiTim Then
Timchuoi=I
Goto Done:
End if
End if
Next I
End If
Done:
End Function
Cách 2: 'Khai thác hàm đã có Instr và InstrRev
PHP:
Function Timchuoi(Byval strChuoi as String, Byval strChuoiTim as String, _
Optional Byval TuBenTrai as Boolean = True) as Long
Dim I as Long
Dim nKytuChuoitim as Long
Dim nKytuChuoi as Long
nKytuChuoi=Len(strChuoi)
nKytuChuoitim =Len(strChuoiTim)
If nKytuChuoi<nKytuChuoitim then Exit Function
If TuBenTrai Then
Timchuoi=Instr(strChuoi,strChuoiTim)
Else
Timchuoi=InstrRev(strChuoi,strChuoiTim)
End If
End Function
Ứng dụng hàm "Timchuoi"
Trích nguyên văn:
+ Hàm tách tên
Mã:
Function TachTen(Byval strHoTen as String) as String
TachTen=Mid(strHoTen,Timchuoi(strHoTen," ",False)+1)
End Function
Giả sử cột A là Họ và tên. Cần tách tên
Cách 1
=MID(A1,Timchuoi(A1," ",False)+1)
Cách 2
=TachTen(A1)
+ Tách dịch vụ điện thoại di động theo mã số
Giả sử cột A là các số điện thoại 090 4210337; 091 3255126; 098 555444; 0916 066512...
Cần lấy mã dịch vụ
=LEFT(A1,Timchuoi(A1," ")-1)
+ Từ số điện thoại cố định, tách mã vùng
Giả sử cột A là các số điện thoại 04 7544525 08 899655; 051 545222; 020 123456;...
=LEFT(A1,Timchuoi(A1," ")-1)
+ Tách tên tệp ra khỏi đường dẫn
'Sử dụng trong môi trương VBE
Sub VD()
Dim strFullPath as String
Dim strFileName as String
strFullPath = ActiveWorkbook.FullPath
strFileName=Mid(strFullPath,Timchuoi(strFullPath," \",False)+1)
'Thông báo
Msgbox strFileName,,strFullPath
End Sub
Như vậy chỉ có một hàm "Timchuoi" mà giải quyết được những vấn đề về cắt chuỗi theo các mục đích khác nhau.
Vấn đề tôi muốn nhấn mạnh là chúng ta viết hàm không phải để nó chỉ giải quyết một việc cụ thể mà nó phải giải quyết những bào toán tổng quát. Hàm như một linh kiện máy tính PC có thể lắp vào máy này hay máy khác.
Việc viết hàm và thủ tục còn có rất nhiều các thuật toán hay giúp cho bài toán của bạn được đánh giá ử mức tối ưu. Việc đặt tên cũng vậy còn nhiều trường hợp để đặt khác. Trong phạm vi một bài viết ngắn tôi chỉ có thể đưa ra những lý giải cơ bản và ví dụ nhỏ, các bạn xem và tự tích tũy dần những kiến thức cũng như kinh nghiệm về việc coding.
(Trích bài của anh Tuanktcdcn)
Lần chỉnh sửa cuối: