Code vba về độ phút giấy không hiển thị được (1 người xem)

  • Thread starter Thread starter ltng82
  • Ngày gửi Ngày gửi
Liên hệ QC

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

ltng82

Thành viên mới
Tham gia
14/5/12
Bài viết
14
Được thích
0
Đây là lần đầu tiên mình viết code, mình muốn tính teta theo beta bằng cách nếu bêta >180 thì teta = beta - 180, beta < 180 thì teta = 180 - beta; Ở đây mình muốn tách góc beta nhập vào theo dạng vd: 150d30'30"
Vì không hiểu mấy cái code trên(lấy trên mạng) nên đành thử nghiệm teta = công thức như dưới đây, nhưng không đc
Chắc là sai tè le. Giúp mình với.
 

File đính kèm

Lần chỉnh sửa cuối:
Đây là lần đầu tiên mình viết code, mình muốn tính teta theo beta bằng cách nếu bêta >180 thì teta = beta - 180, beta < 180 thì teta = 180 - beta; Ở đây mình muốn tách góc beta nhập vào theo dạng vd: 150d30'30"
Vì không hiểu mấy cái code trên(lấy trên mạng) nên đành thử nghiệm teta = công thức như dưới đây, nhưng không đc
Chắc là sai tè le. Giúp mình với.

Bạn có góc 150d20'30" thì sao bạn lại nhập vào ô E4 giá trị "150d20'30"""??? Phải nhập vào 150d20'30"
Trước tiên ta "học" trên lỗi đã mắc phải để lần sau không phạm lỗi nữa.
Mã:
Function gocteta(tugoc_beta As String) As Variant
Dim do_beta As Double
Dim phut_beta As Double
Dim giay_beta As Double
Dim do_teta As Double
Dim phut_teta As Double
Dim giay_teta As Double
    do_beta = Val(Left(tugoc_beta, InStr(1, tugoc_beta, "d") - 1))
    phut_beta = Val(Mid(tugoc_beta, InStr(1, tugocteta, "d") + [COLOR=#ff0000]2[/COLOR], _
    InStr(1, tugoc_beta, "'") - InStr(1, tugoc_beta, "d") - [COLOR=#ff0000]2[/COLOR]))
    giay_beta = Val(Mid(tugoc_beta, InStr(1, tugoc_beta, "'") + [COLOR=#ff0000]2[/COLOR], _
    Len(tugoc_beta) - InStr(1, tugoc_beta, "'") - [COLOR=#ff0000]2[/COLOR]))
    gocteta = do_beta & "d " & phut_beta & "' " & giay_beta [COLOR=#ff0000]+[/COLOR] Chr(34)
End Function
sửa thành

Mã:
do_beta = Val(Left(tugoc_beta, InStr(1, tugoc_beta, "d") - 1))
phut_beta = Val(Mid(tugoc_beta, InStr(1, tugoc_beta, "d") + [COLOR=#ff0000]1[/COLOR], _
InStr(1, tugoc_beta, "'") - InStr(1, tugoc_beta, "d") - [COLOR=#ff0000]1[/COLOR]))
giay_beta = Val(Mid(tugoc_beta, InStr(1, tugoc_beta, "'") + [COLOR=#ff0000]1[/COLOR], _
Len(tugoc_beta) - InStr(1, tugoc_beta, "'") - [COLOR=#ff0000]1[/COLOR]))
gocteta = do_beta & "d " & phut_beta & "' " & giay_beta [COLOR=#ff0000]&[/COLOR] Chr(34)
Về mặt lập trình thì code trên tuy đã không lỗi nhưng không chấp nhận được. Bạn phải biết là đọc giá trị từ biến bao giờ cũng nhanh hơn là đọc từ thuộc tính, gọi hàm v...v. Về phương diện bộ vi xử lý thì đọc từ biến bao giờ cũng tốn ít "nhịp đồng hồ" hơn và bộ vi xử lý "ít mệt" hơn. Vậy nếu bạn cần tính ở nhiều chỗ giá trị vd. InStr(1, tugoc_beta, "d") thì bạn gọi hàm 1 lần và ghi giá trị trả về vào biến, còn các lần tiếp theo đọc từ biến ra. Vậy ta sửa tiếp code như sau:

Mã:
k = InStr(1, tugoc_beta, "d")
n = InStr(1, tugoc_beta, "'")
do_beta = Val(Left(tugoc_beta, k - 1))
phut_beta = Val(Mid(tugoc_beta, k + 1, n - k - 1))
giay_beta = Val(Mid(tugoc_beta, n + 1, Len(tugoc_beta) - n - 1))
gocteta = do_beta & "d " & phut_beta & "' " & giay_beta & Chr(34)
Nhìn code trên thì ta thấy:
1. Giá trị trả về đâu có phải "gocteta"? Nó vẫn là góc "beta" thôi, vì θ = abs(β - 180) cơ mà.
2. Cứ cho là giá trị trả về là gocteta thì ở dạng ấy nó không thể dùng cho những tính toán tiếp theo. Nó chỉ dùng cho hiển thị, vd. như bạn nhập vào ô "E6". Chả nhẽ để tính toán ta phải gọi hàm "gocteta_thuc_su_day"???
3. Góc được cho dưới dạng (abc)d(ab)'(ab)" tức đã phải có hàm nào đó trên cơ sở "độ", "phút", "giây" tạo ra chuỗi như thế. Nếu thế thì hàm đó phải trả về chuỗi mà trong đó "phút", "giây" luôn có 2 ký tự, thậm chí vd. 15d00'00". Ngoài ra sao lại dùng dạng (abc)d(ab)'(ab)" mà lại không là (abc)°(ab)'(ab)" cho nó "chuẩn"??? Tây nhìn cũng hiểu.
Nếu đúng thế thì code rút gọn thành:

Mã:
k = InStr(1, tugoc_beta, "d")
n = InStr(1, tugoc_beta, "'")
do_beta = Val(Left(tugoc_beta, k - 1))
phut_beta = Val(Mid(tugoc_beta, k + 1, 2))
giay_beta = Val(Mid(tugoc_beta, n + 1, 2))
gocteta = do_beta & "d " & phut_beta & "' " & giay_beta & Chr(34)
4. Nếu góc được cho ở dạng (abc)d(ab)'(ab)" thì (abc), (ab) là những số nguyên vì chả có lý gì hàm trả về vd. 15,5d12'30" mà không phải là 15d42'30".
5. Theo tôi bạn nên trả về góc bằng radian. Trong toán học tất cả các công thức được "cho" với góc được tính bằng đơn vị chuẩn quốc tế là radian.
vd. bạn có công thức tính cung đường tròn bán kính r mà góc ở tâm là α: l = α * r
Công thức chỉ đúng khi α được tính bằng radian.
vd. trong công thức Maclaurin cho hàm sinx và cosx thì x được tính bằng radian.
Để trả về góc θ thì ta sửa code như sau:

Mã:
Function gocteta(ByVal goc_beta As String) As Double
Dim do_beta As Long
Dim phut_beta As Long
Dim giay_beta As Long
Dim k As Long
    k = InStr(1, goc_beta, "d")
    do_beta = CLng(Left(goc_beta, k - 1)) ' CInt
    phut_beta = CLng(Mid(goc_beta, k + 1, 2))
    giay_beta = CLng(Mid(goc_beta, InStr(1, goc_beta, "'") + 1, 2))
    'gocteta = Abs(do_beta + phut_beta / 60 + giay_beta / 3600 - 180)    ' trả về độ
    gocteta = WorksheetFunction.Radians(Abs(do_beta + phut_beta / 60 + giay_beta / 3600 - 180))  ' trả về radian
End Function
 
Upvote 0
Cảm ơn bạn siwtom rất nhiều, hiện h thì mình đã hiểu hàm instr().
Mã:
Function gocteta(tugoc_beta As String) As Variant'khai bao goc beta
Dim do_beta As Double
Dim phut_beta As Double
Dim giay_beta As Double
'cac gia tri cua goc teta can tim
Dim do_teta As Double
Dim phut_teta As Double
Dim giay_teta As Double
Dim k As Long
Dim n As Long
k = InStr(1, tugoc_beta, "d")
n = InStr(1, tugoc_beta, "'")
do_beta = Val(Left(tugoc_beta, k - 1))
phut_beta = Val(Mid(tugoc_beta, k + 1, 2))
giay_beta = Val(Mid(tugoc_beta, n + 1, 2))
gocteta = do_beta & "d " & phut_beta & "' " & giay_beta & Chr(34)
End Function
Nó đã hiện thị thành công góc nhập. H mình viết tiếp đây.
 
Lần chỉnh sửa cuối:
Upvote 0
Mình đã viết theo đúng ý của mình, liệu bạn nào cỏ thể rút ngắn code của mình đc không. Thank trước

 

File đính kèm

Upvote 0
Mình đã viết theo đúng ý của mình, liệu bạn nào cỏ thể rút ngắn code của mình đc không. Thank trước

Tôi đã nói rõ là nếu ta chắc chắn là nếu dữ liệu vào có dạng sao cho phút và giây luôn có 2 ký tự thì mới được viết:
Mã:
phut_beta = Val(Mid(tugoc_beta, k + 1, [COLOR=#ff0000]2[/COLOR]))
giay_beta = Val(Mid(tugoc_beta, n + 1, [COLOR=#ff0000]2[/COLOR]))
còn không thì phải là
Mã:
phut_beta = Val(Mid(tugoc_beta, k + 1, [COLOR=#ff0000]n - k - 1[/COLOR]))
giay_beta = Val(Mid(tugoc_beta, n + 1, [COLOR=#ff0000]Len(tugoc_beta) - n - 1[/COLOR]))
Ngoài ra với kiểu nhập dữ liệu của bạn thì bạn cho phép nhập 123.456d12.345'12.345" và bạn chấp nhận trả về góc 55,544d46,655'47,655"
Tôi không chấp nhận kiểu 12.5d20'30" mà chỉ chấp nhận 12d50'30" nên tôi khai báo do_beta, ..., là Long. Nếu bạn thích thì đổi thành Double
Bạn chấp nhận dữ liệu kiểu 12d-33'-43"???
----------
Tôi sửa qua thế này, mà sửa "chay" thôi, tức nhìn tới đâu viết tới đó, không test gì cả. Bạn tự test và bổ sung. Nói chung trước tiên bạn xác định mình chấp nhận dạng dữ liệu thế nào rồi code kiểm tra

Mã:
Function gocteta(tugoc_beta As String) As Variant
'khai bao goc beta
Dim do_beta As Long 'Double
Dim phut_beta As Long   'Double
Dim giay_beta As Long   'Double
Dim k As Long
Dim n As Long
    ' de phong truong hop nhap vd. 23'168d30"
    If Not tugoc_beta Like "*d*'*""" Then
        gocteta = "nhap sai goc"
        Exit Function
    End If
    
    k = InStr(1, tugoc_beta, "d")
    n = InStr(1, tugoc_beta, "'")
    do_beta = Val(Left(tugoc_beta, k - 1))
    phut_beta = Val(Mid(tugoc_beta, k + 1, n - k - 1))
    giay_beta = Val(Mid(tugoc_beta, n + 1, Len(tugoc_beta) - n - 1))
    
    If do_beta > 360 Or do_beta < 0 Or phut_beta >= 60 Or phut_beta < 0 Or giay_beta >= 60 Or _
        giay_beta < 0 Or (do_beta = 360 And (phut_beta > 0 Or giay_beta > 0)) Then
        gocteta = "nhap sai goc"
        Exit Function
    ElseIf do_beta >= 180 Then
        do_beta = do_beta - 180
    Else
        do_beta = 180 - do_beta
        If phut_beta > 0 Or giay_beta > 0 Then
            do_beta = do_beta - 1
            phut_beta = 60 - phut_beta
            If giay_beta > 0 Then
                phut_beta = phut_beta - 1
                giay_beta = 60 - giay_beta
            End If
        End If
    End If
    gocteta = do_beta & "d" & phut_beta & "'" & giay_beta & Chr(34)
End Function
 
Upvote 0
Không sao mình hiểu tất cả các hàm trong code rồi mình viết lại như thế này
Mã:
Function DoiDo(goc_do As String) As Variant
'Doi don vi goc tu dinh dang 00d00'00" sang he thap phan
Dim do_goc As Double
Dim phut_goc As Double
Dim giay_goc As Double
Dim f As Long
Dim m As Long
f = InStr(1, goc_do, "d")
m = InStr(1, goc_do, "'")
do_goc = Val(Left(goc_do, f - 1))
phut_goc = Val(Mid(goc_do, f + 1, m - f - 1))
giay_goc = Val(Mid(goc_do, m + 1, Len(goc_do) - m - 1))
DoiDo = do_goc + phut_goc / 60 + giay_goc / 3600
End Function
Function DoiThapPhan(goc_thapphan) As Variant
'Doi don vi goc tu do thap phan sang don vi co dang 00d00'00"
    With Application
    doo = Int(goc_thapphan)
    phut = (goc_thapphan - doo) * 60
    giay = Format(((phut - Int(phut)) * 60), "0")
    DoiThapPhan = doo & "d" & Int(phut) & "'" & giay & Chr(34)
    End With
End Function
Đầu vào thì luôn có dạng 00d00'00" mình đã test thành công. Do mới viết code nên khi đọc mấy code lấy ở trên mạng mình không hiểu. Cảm ơn bạn siwtom nhiều.
 
Lần chỉnh sửa cuối:
Upvote 0
Web KT

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

Back
Top Bottom