[Hỏi] Viết module theo hướng dẫn của thầy mà k chạy dc. (1 người xem)

Liên hệ QC

Người dùng đang xem chủ đề này

truonglong1206

Thành viên mới
Tham gia
4/10/13
Bài viết
6
Được thích
3
CODE:
Public Function AmLich(Nam As Integer) As String
Dim Can, Chi, KetQua As String
ModCan = Nam Mod 10
ModChi = Nam Mod 12
Select Case ModCan
Case 0
Can = "Canh"
Case 1
Can = "Tan"
Case 2
Can = "Nham"
Case 3
Can = "Quy"
Case 4
Can = "Giap"
Case 5
Can = "At"
Case 6
Can = "Binh"
Case 7
Can = "Dinh"
Case 8
Can = "Mau"
Case 9
Can = "Ky"
End Select

Select Case ModChi
Case 0
Chi = "Than"
Case 1
Chi = "Dau"
Case 2
Chi = "Tuat"
Case 3
Chi = "Hoi"
Case 4
Chi = "Ty"
Case 5
Chi = "Suu"
Case 6
Chi = "Dan"
Case 7
Chi = "Meo"
Case 8
Chi = "Thin"
Case 9
Chi = "Ty"
Case 10
Chi = "Ngo"
Case 11
Chi = "Mui"
End Select

KetQua = Can & " " & Chi
AmLich = KetQua
End Function



Hàm tìm tên âm lịch của 1 năm.
Chạy thì báo lỗi: "Compiler error: Expected variable or proceduce , not module"

Mọi người giúp giùm mình nha!
Tks mọi người nhiều!
 
Bạn gửi tập tin của bạn lên xem! Tôi nhìn hàm thì cấu trúc không sai. Tôi nghĩ bạn đặt hàm không đúng chỗ mà thôi.
 
Upvote 0
Có lẽ do bạn sử dụng tùy chọn Option Explicit nhưng lại khai báo thiếu các biến ModCan và ModChi, bạn khai báo thêm vào xem có còn lỗi không nhé.
Trong code trên thì biến KetQua là thừa, có thể gán AmLich = Can & " " & Chi luôn.
Nếu sử dụng hàm Choose thì hàm trên có thể rút gọn đi khá nhiều:
[GPECODE=vb]Function AmLich(Nam As Long) As String
Dim Can As String, Chi As String, ModCan As Long, ModChi As Long
ModCan = Nam Mod 10
ModChi = Nam Mod 12
Can = Choose(ModCan + 1, "Canh", "Tan", "Nham", "Quy", "Giap", "At", "Binh", "Dinh", "Mau", "Ky")
Chi = Choose(ModChi + 1, "Than", "Dau", "Tuat", "Hoi", "Ty'", "Suu", "Dan", "Meo", "Thin", "Ty.", "Ngo", "Mui")
AmLich = Can & " " & Chi
End Function[/GPECODE]
2 biến ModCan và ModChi cũng có thể bỏ đi, gán phép toán Mod trực tiếp vào hàm Choose luôn. Thậm chí chịu khó nhìn câu lệnh dài một chút thì có thể bỏ luôn các biến Can, Chi, toàn bộ hàm chỉ còn 1 câu lệnh:
[GPECODE=vb]Function AmLich(Nam As Long) As String
AmLich = Choose(Nam Mod 10 + 1, "Canh", "Tan", "Nham", "Quy", "Giap", "At", "Binh", "Dinh", "Mau", "Ky") & " " _
& Choose(Nam Mod 12 + 1, "Than", "Dau", "Tuat", "Hoi", "Ty'", "Suu", "Dan", "Meo", "Thin", "Ty.", "Ngo", "Mui")
End Function[/GPECODE]
 
Upvote 0
Upvote 0
Mình cũng thấy vậy. Vì trên lớp thầy dạy như vậy. mình chỉ đánh lại thôi.
http://cl.ly/320m0a2B0S1w
Bạn down về xem hộ mình với
Tặng bạn thêm một hàm Can Chi nữa nè (có dấu tiếng Việt Unicode luôn đấy nhé)!

[GPECODE=vb]Function CanChiUni(ByVal sYear As Long)

Dim xx As Byte, yy As Byte
Dim Can(), Chi()

xx = ((sYear - 4) Mod 10)
yy = ((sYear - 4) Mod 12)

Can = Array("Giáp", ChrW(7844) & "t", "Bính", ChrW(272) & "inh", "M" & ChrW(7853) & "u", _
"K" & ChrW(7927), "Canh", "Tân", "Nhâm", "Quý")

Chi = Array("Tý", "S" & ChrW(7917) & "u", "D" & ChrW(7847) & "n", "M" & ChrW(227) & "o", _
"Thìn", "T" & ChrW(7925), "Ng" & ChrW(7885), "Mùi", "Thân", "D" & ChrW(7853) & "u", _
"Tu" & ChrW(7845) & "t", "H" & ChrW(7907) & "i")


CanChiUni = Can(xx) & " " & Chi(yy)

End Function


[/GPECODE]
 
Upvote 0
Tặng bạn thêm một hàm Can Chi nữa nè (có dấu tiếng Việt Unicode luôn đấy nhé)!

[GPECODE=vb]Function CanChiUni(ByVal sYear As Long)

Dim xx As Byte, yy As Byte
Dim Can(), Chi()

xx = ((sYear - 4) Mod 10)
yy = ((sYear - 4) Mod 12)

Can = Array("Giáp", ChrW(7844) & "t", "Bính", ChrW(272) & "inh", "M" & ChrW(7853) & "u", _
"K" & ChrW(7927), "Canh", "Tân", "Nhâm", "Quý")

Chi = Array("Tý", "S" & ChrW(7917) & "u", "D" & ChrW(7847) & "n", "M" & ChrW(227) & "o", _
"Thìn", "T" & ChrW(7925), "Ng" & ChrW(7885), "Mùi", "Thân", "D" & ChrW(7853) & "u", _
"Tu" & ChrW(7845) & "t", "H" & ChrW(7907) & "i")


CanChiUni = Can(xx) & " " & Chi(yy)

End Function


[/GPECODE]

Về cấu trúc thì thấy hàm trên ngắn gọn, nhưng về nguyên tắc tôi cảm thấy Select Case có vẻ cho tốc độ nhanh hơn (mặc dù không thể đo được vì đo thời gian cái nào cũng bằng 0 cả).

[GPECODE=vb]Function CanChiUni2(ByVal sYear As Long) As String
Dim Can As String, Chi As String

Select Case (sYear - 4) Mod 10
Case 0: Can = "Giáp"
Case 1: Can = ChrW(7844) & "t"
Case 2: Can = "Bính"
Case 3: Can = ChrW(272) & "inh"
Case 4: Can = "M" & ChrW(7853) & "u"
Case 5: Can = "K" & ChrW(7927)
Case 6: Can = "Canh"
Case 7: Can = "Tân"
Case 8: Can = "Nhâm"
Case 9: Can = "Quý"
End Select


Select Case (sYear - 4) Mod 12
Case 0: Chi = "Tý"
Case 1: Chi = "S" & ChrW(7917) & "u"
Case 2: Chi = "D" & ChrW(7847) & "n"
Case 3: Chi = "M" & ChrW(227) & "o"
Case 4: Chi = "Thìn"
Case 5: Chi = "T" & ChrW(7925)
Case 6: Chi = "Ng" & ChrW(7885)
Case 7: Chi = "Mùi"
Case 8: Chi = "Thân"
Case 9: Chi = "D" & ChrW(7853) & "u"
Case 10: Chi = "Tu" & ChrW(7845) & "t"
Case 11: Chi = "H" & ChrW(7907) & "i"
End Select

CanChiUni2 = Can & " " & Chi

End Function
[/GPECODE]

Lý do hàm dùng Array, tôi nghĩ nó phải tính toán rồi add mảng vào 2 mảng Can() và Chi() sau đó dò tìm phần tử trong mảng.

Còn hàm thứ 2 với Select Case, sau khi tính toán nó chỉ việc tìm thỏa điều kiện có sẳn mà cho kết quả thôi, cho nên sẽ nhanh hơn hàm kia.

Chỉ là suy nghĩ chủ quan của tôi, không biết các cao thủ có cao kiến gì không nhỉ?
 
Upvote 0
Về cấu trúc thì thấy hàm trên ngắn gọn, nhưng về nguyên tắc tôi cảm thấy Select Case có vẻ cho tốc độ nhanh hơn (mặc dù không thể đo được vì đo thời gian cái nào cũng bằng 0 cả).

Chỉ có mỗi cái CAN với CHI mà quan tâm đến TỐC ĐỘ xem ra hơi.. thừa
Cũng giống như ta di chuyển có 5 mét thì đi xe đạp hay đi xe máy cũng chẳng phân biệt gì
 
Upvote 0
Chỉ có mỗi cái CAN với CHI mà quan tâm đến TỐC ĐỘ xem ra hơi.. thừa
Cũng giống như ta di chuyển có 5 mét thì đi xe đạp hay đi xe máy cũng chẳng phân biệt gì
Đó là chuyện nhỏ, nhưng về logic, nếu ta xét được cái nào có hiệu quả hơn thì dùng ngay từ đầu cho những project lớn ạ.
 
Upvote 0
Đó là chuyện nhỏ, nhưng về logic, nếu ta xét được cái nào có hiệu quả hơn thì dùng ngay từ đầu cho những project lớn ạ.

Với năm Âm Lịch, nguyên tắc 60 năm quay lại 1 lần
Vậy ta tạo 1 biến dic (Dictionary) dạng Public, dùng Auto_Open nạp 60 năm âm lịch vào dic. Trong hàm, chỉ cần lấy Mod 60 của năm dương lịch, tra vào dic là ra
Đó cũng là dạng tăng tốc đấy!
Với dạng bài toán chuyển VLOOKUP thành VBA, tôi hay dùng cách này. Bảo đảm nhanh thần tốc (vì dictionary chỉ chạy 1 lần duy nhất)
 
Upvote 0
Quan niệm tôi thì có lẽ trái ngược với hầu hết các bạn trên GPE này. Chỉ khi nào viết code real time - cần hải xử lý kịp lúc, vd code điều khiển máy tự động - thì mới cần tốc độ. Ngoài ra thì viết code sao cho dễ xài.

Theo tinh thần đó tôi sẽ viết Can và Chi thành 2 hàm riêng nhau. Như vậy tôi có thể dùng tính được cả Can, Chi và Tên năm.

Mã:
Function AmLichCan(ByVal nam As Integer) As String
AmLichCan = Trim(Mid("CanhTan NhamQuy GiapAt  BinhDinhMau Ky  ", (nam Mod 10) * 4 + 1, 4))
End Function


Function AmLichChi(ByVal nam As Integer) As String
AmLichChi = Trim(Mid("ThanDau TuatHoi Ty  Suu Dan Meo ThinTy  Ngo Mui ", (nam Mod 12) * 4 + 1, 4))
End Function


Function AmLichTenNam(ByVal nam As Integer) As String
AmLichTenNam = AmLichCan(nam) & " " & AmLichChi(nam)
End Function
 
Upvote 0
Đó là chuyện nhỏ, nhưng về logic, nếu ta xét được cái nào có hiệu quả hơn thì dùng ngay từ đầu cho những project lớn ạ.

Hiệu quả ứng dụng code trong project lớn chưa chắc đã là tốc độ. Cái quan trọng nhất của code project lớn là DỄ HIỂU DỄ TEST DỄ DEBUG DỄ SỬA
 
Upvote 0
Hiệu quả ứng dụng code trong project lớn chưa chắc đã là tốc độ. Cái quan trọng nhất của code project lớn là DỄ HIỂU DỄ TEST DỄ DEBUG DỄ SỬA


Với bài bạn vừa nói thì quá mâu thuẫn với các hàm của bài này:

Mã:
Function AmLichCan(ByVal nam As Integer) As String
AmLichCan = [COLOR=#ff0000]Trim(Mid[/COLOR]([B][COLOR=#0000ff]"CanhTan NhamQuy GiapAt  BinhDinhMau Ky  "[/COLOR][/B],[COLOR=#ff0000] (nam Mod 10) * 4 + 1, 4)[/COLOR])
End Function


Function AmLichChi(ByVal nam As Integer) As String
AmLichChi = [COLOR=#ff0000]Trim(Mid[/COLOR]([B][COLOR=#0000ff]"ThanDau TuatHoi Ty  Suu Dan Meo ThinTy  Ngo Mui "[/COLOR][/B],[COLOR=#ff0000] (nam Mod 12) * 4 + 1, 4)[/COLOR])
End Function

Nhìn 2 hàm trên, tôi không biết thế nào gọi là "DỄ HIỂU - DỄ TEST - DỄ DEBUG - DỄ SỬA" như thế nào nữa (ai mà ở không ngồi đếm ký tự để đánh các chuỗi số như màu xanh như thế, rồi lại dùng hàm TRIM, hàm MID tùm lum, lỡ trong quá trình sao chép hay viết mà thiếu 1 ký tự trắng thôi hoặc thêm vào khoảng trắng thôi là tèo, biết sai chỗ nào mà sửa hả?), so với 2 hàm dưới đây xem cái nào"DỄ HIỂU - DỄ TEST - DỄ DEBUG - DỄ SỬA" hơn hả? Ngoại trừ dùng hàm MOD thì có cần dùng thêm hàm gì nữa không?

Mã:
Function ThienCan(ByVal sYear As Long) As String
    Select Case [COLOR=#ff0000](sYear - 4) Mod 10[/COLOR]
        Case 0: ThienCan = "Giap"
        Case 1: ThienCan = "At"
        Case 2: ThienCan = "Binh"
        Case 3: ThienCan = "Dinh"
        Case 4: ThienCan = "Mau"
        Case 5: ThienCan = "Ky"
        Case 6: ThienCan = "Canh"
        Case 7: ThienCan = "Tan"
        Case 8: ThienCan = "Nham"
        Case 9: ThienCan = "Quy"
    End Select
End Function


Function DiaChi(ByVal sYear As Long) As String
    Select Case [COLOR=#ff0000](sYear - 4) Mod 12[/COLOR]
        Case 0: DiaChi = "Ti"
        Case 1: DiaChi = "Suu"
        Case 2: DiaChi = "Dan"
        Case 3: DiaChi = "Mao"
        Case 4: DiaChi = "Thin"
        Case 5: DiaChi = "Ty"
        Case 6: DiaChi = "Ngo"
        Case 7: DiaChi = "Mui"
        Case 8: DiaChi = "Than"
        Case 9: DiaChi = "Dau"
        Case 10: DiaChi = "Tuat"
        Case 11: DiaChi = "Hoi"
    End Select
End Function

Hoặc 2 hàm dưới đây:

Mã:
Function ThienCan2(ByVal sYear As Long) As String
    Dim Can()
    Can = Array("Giap", "At", "Binh", "Dinh", "Mau", "Ky", "Canh", "Tan", "Nham", "Quy")
    ThienCan2 = Can([COLOR=#ff0000](sYear - 4) Mod 10[/COLOR])
End Function


Function DiaChi2(ByVal sYear As Long) As String
    Dim Chi()
    Chi = Array("Ti", "Suu", "Dan", "Mao", "Thin", "Ty", "Ngo", "Mui", "Than", "Dau", "Tuat", "Hoi")
    DiaChi2 = Chi([COLOR=#ff0000](sYear - 4) Mod 12[/COLOR])
End Function
 
Lần chỉnh sửa cuối:
Upvote 0
Hiệu quả ứng dụng code trong project lớn chưa chắc đã là tốc độ. Cái quan trọng nhất của code project lớn là DỄ HIỂU DỄ TEST DỄ DEBUG DỄ SỬA

Cũng nói thêm rằng, cũng là kết quả như nhau, nhưng nếu ngay từ đầu ta đi đúng phương pháp thì tốc độ phải là tiêu chí hàng đầu.

Giả dụ ta cần có 1 chuỗi dài 10.000 từ, ta dùng vòng lặp để tạo chuỗi.

Ta có 2 thủ tục:

Thủ thục 1:

Mã:
Sub test1()
    Dim i As Long, str As String, t As Double
    t = Timer
    For i = 1 To 10000
        str = str & ", " & "nghia" & i
    Next
    str = Right(str, Len(str) - 2)
    MsgBox Timer - t
End Sub

Thủ tục 2:

Mã:
Sub test2()
    Dim i As Long, str As String, Arr(1 To 10000), t As Double
    t = Timer
    For i = 1 To 10000
        Arr(i) = "nghia" & i
    Next
    str = Join(Arr, ", ")
    MsgBox Timer - t
End Sub

Nếu đem so sánh 2 kết quả thì như nhau, nhưng việc xử lý chuỗi kiểu ghép chuỗi như Thủ tục 1 thì thời gian cho ra kết quả quá chậm!

Vì vậy, đã là người lập trình thì nên định hướng ngay từ đầu các phương án tối ưu để khi làm một project nào đó ta sẽ không mắc phải sai lầm sau khi đạt được kết quả.
 
Upvote 0
Từ "DỄ" nằm trong nhóm tĩnh tự xác suất, tức là tự nó không có tính chất tuyệt đối. Đã vậy nó còn nằm trong nhánh chủ quan, tức là tuỳ theo đối tượng sử dụng nó.

Một việc đầy tính chất xác xuất và chủ quan đem ra bàn cãi thì thỉ đến chừng nào mới dứt. Vì vậy tôi không nói tiếp chuyện "DỄ HIỂU DỄ TEST DỄ DEBUG DỄ SỬA" nữa.

Việc ví dụ ghép chuỗi thì tôi chẳng hiểu bạn đưa ra làm gì. Dân lập trình ai cũng biết ghép chuỗi là một công việc rất tốn kém. Ghép hằng ngàn lần mà không sử dụng hàm chuyên thì là việc chỉ có tay mơ mới làm. Lập trình viên nào trong nhóm tôi làm kiểu này là tôi sẽ kêu người khác viết lại tất cả những code của nó. Ngay cả những ngôn ngữ không có hàm nối chuỗi người ta cũng tự viết ra các hàm phụ để chuyên làm việc này.

Chính tại GPE tôi cũng từng nói về tính chất không thay đổi được của loại biến chuỗi trong VBA.
 
Upvote 0
Web KT

Bài viết mới nhất

Back
Top Bottom