Chuyển chữ số từ dạng Ả-rập sang dạng La Mã và ngược lại

Liên hệ QC

NguyenNgocSon

KEEP WALKING
Tham gia
4/4/08
Bài viết
280
Được thích
833
Nghề nghiệp
Ths. Cầu hầm
[FONT=verdana,arial,helvetica,sans-serif]Cú pháp hàm như sau :
[/FONT]
[FONT=verdana,arial,helvetica,sans-serif]Roman(number, type) [/FONT]
[FONT=verdana,arial,helvetica,sans-serif]+ “Number” ở đây chính là một ký số bất kỳ nào hoặc là số ô chứa ký số mà bạn muốn thực hiện việc chuyển đổi sang hệ chữ La Mã. [/FONT]
[FONT=verdana,arial,helvetica,sans-serif]+ “Type” ở đây là một toán tùy ý. [/FONT]
[FONT=verdana,arial,helvetica,sans-serif]Sau khi được thi hành, hàm Roman sẽ tính toán và đưa ra kết quả chuyển đổi một cách chính xác và nhanh chóng nhất. Trong trường hợp bạn cố nhập một ký số có giá trị lớn hơn 3999, hàm này sẽ báo lỗi và không thể thực hiện được. Vì vậy việc chuyển đổi chỉ có thể thành công khi các giá trị ký số mà bạn muốn chuyển đổi nhỏ hơn 4000. [/FONT]
 
[FONT=verdana,arial,helvetica,sans-serif]Trong trường hợp bạn cố nhập một ký số có giá trị lớn hơn 3999, hàm này sẽ báo lỗi và không thể thực hiện được. Vì vậy việc chuyển đổi chỉ có thể thành công khi các giá trị ký số mà bạn muốn chuyển đổi nhỏ hơn 4000. [/FONT]

Tại sao lại chỉ chuyển đổi số nhỏ hơn 4000 bạn nhỉ ?
 
[FONT=verdana,arial,helvetica,sans-serif]Cú pháp hàm như sau :
[/FONT]
[FONT=verdana,arial,helvetica,sans-serif]Roman(number, type) [/FONT]
[FONT=verdana,arial,helvetica,sans-serif]+ “Number” ở đây chính là một ký số bất kỳ nào hoặc là số ô chứa ký số mà bạn muốn thực hiện việc chuyển đổi sang hệ chữ La Mã. [/FONT]
[FONT=verdana,arial,helvetica,sans-serif]+ “Type” ở đây là một toán tùy ý. [/FONT]
[FONT=verdana,arial,helvetica,sans-serif]Sau khi được thi hành, hàm Roman sẽ tính toán và đưa ra kết quả chuyển đổi một cách chính xác và nhanh chóng nhất. Trong trường hợp bạn cố nhập một ký số có giá trị lớn hơn 3999, hàm này sẽ báo lỗi và không thể thực hiện được. Vì vậy việc chuyển đổi chỉ có thể thành công khi các giá trị ký số mà bạn muốn chuyển đổi nhỏ hơn 4000. [/FONT]
Nếu nói về HÀM và cú pháp của HÀM, có lẽ không cần đưa lên thêm... Tất cả đã được BNTT tổng hợp đầy đủ... Xem tại dây:
http://www.giaiphapexcel.com/forum/showpost.php?p=54563&postcount=33
Bài toán dạng chuyển ngược từ ROMAN 2 DECIMAL mới là cái đáng bàn
 
Lần chỉnh sửa cuối:
Trên thực tế cũng có nhu cầu chuyển đổi từ chữ số La mã sang số Ả-rập. Vậy không biết có hàm nào thực hiện được không, ai biết mách dùm, xin cảm ơn!
 
Trên thực tế cũng có nhu cầu chuyển đổi từ chữ số La mã sang số Ả-rập. Vậy không biết có hàm nào thực hiện được không, ai biết mách dùm, xin cảm ơn!
Tôi chưa biết số Ả-rập ---> Bạn đưa file lên tôi xem thử số ấy như thế nào ---> Tôi nghĩ là có thể chuyển được (nếu tôi biết số ấy là gì)
 
Tôi chưa biết số Ả-rập ---> Bạn đưa file lên tôi xem thử số ấy như thế nào ---> Tôi nghĩ là có thể chuyển được (nếu tôi biết số ấy là gì)
Số Ả-rập là số chúng ta đang sử dụng hằng ngày đấy anh Tuấn à: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9.
 
Số Ả-rập là số chúng ta đang sử dụng hằng ngày đấy anh Tuấn à: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9.
Ôi trời... vậy mà cứ tưởng nó giống vầy: أنا أحبك
Hiii...
Vậy thì có gì đâu mà khó ---> GPE đã có bài này rồi ---> Tìm xem
 
Trên thực tế cũng có nhu cầu chuyển đổi từ chữ số La mã sang số Ả-rập. Vậy không biết có hàm nào thực hiện được không, ai biết mách dùm, xin cảm ơn!

Từ số Ả rập chuyển sang số La Mã, bạn có thể dùng hàm ROMAN, tuy nhiên hàm này chỉ dùng được đến số 3999 thôi bạn à.

Ngược lại thì mình đang bó tay, sẽ cố gắng tìm kiếm giúp bạn.
 
Đây là công thức chuyển ngược từ số dạng La-mã sang số dạng Ả-rập:
=MATCH(A1, ROMAN(ROW($1:$3999)), 0) (công thức mảng)​
Với ô A1 là ô chứa con số ở dạng La-mã cần chuyển đổi, và công thức nằm ở B1. Công thức này rất hay, xin cảm ơn Anhtuan1066.

Em xin mạn phép giải thích công thức này một chút, cho những bạn không hiểu.
  • ROW($1:$3999)
    Tạo ra một mảng các số từ 1 đến 3999, tạm gọi là mảng ARAP

  • ROMAN(ROW($1:$3999))
    Chuyển hết các số trong mảng ARAP sang dạng La-mã

  • MATCH(A1, ROMAN(ROW($1:$3999)), 0)
    Đem con số (La-mã) ở ô A1 đi dò trong mảng ARAP với cách dò chính xác, xem nó nằm ở hàng nào trong mảng này, và đó chính là kết quả cần tìm.
Bởi công thức này làm việc với một mảng ảo (mảng ARAP, do hàm ROW tạo ra), nên phải nhập công thức này ở dạng mảng (nhấn Ctrl+Shift+Enter sau khi nhập).
 
Công thức thì đã có rồi, xin góp vui bằng 1 code sau.
Mã:
Function Roman2Dec(str As String) As Long
    str = UCase(str)
    If Not IsValidLM(str) Then
        Roman2Dec = ""
        Exit Function
    End If
    Dim ret As Long
    Dim i As Integer
    ret = LM(Right(str, 1))
    For i = Len(str) - 1 To 1 Step -1
        If LM(Mid(str, i, 1)) < LM(Mid(str, i + 1, 1)) Then
            ret = ret - LM(Mid(str, i, 1))
        Else
            ret = ret + LM(Mid(str, i, 1))
        End If
    Next
    Roman2Dec = ret
End Function

Private Function LM(s As String) As Long
    Select Case s
        Case "I": LM = 1
        Case "V": LM = 5
        Case "X": LM = 10
        Case "L": LM = 50
        Case "C": LM = 100
        Case "D": LM = 500
        Case "M": LM = 1000
    End Select
End Function

Private Function IsValidLM(str As String) As Boolean
    Dim i As Integer
    Dim ret As Boolean
    ret = InStr(1, str, "IIII") = 0
    ret = ret And InStr(1, str, "VVVV") = 0
    ret = ret And InStr(1, str, "XXXX") = 0
    ret = ret And InStr(1, str, "LLLL") = 0
    ret = ret And InStr(1, str, "CCCC") = 0
    ret = ret And InStr(1, str, "DDDD") = 0
    ret = ret And InStr(1, str, "MMMM") = 0
    If ret Then
        For i = 1 To Len(str)
            If InStr(1, "IVXLCDM", Mid(str, i, 1)) = 0 Then
                ret = False
                Exit For
            End If
        Next
    End If
    IsValidLM = ret
End Function
 
Hàm Roman2Dec() này của rollover79 còn thiếu bẫy lỗi khi nhập số LA MÃ không đúng quy cách.

Xin đơn cử vài ví dụ vui vui:
Roman2Dec(IXI) = 10
Roman2Dec(IIIX) = 11
Roman2Dec(IIIXI) = 12
Roman2Dec(IIIXII) = 13
Roman2Dec(IIIXIII) = 14
Roman2Dec(IIIXIV) = 15
Roman2Dec(XIIX) = 20
Roman2Dec(XIIX) = 20
Roman2Dec(IIIXX) = 21
v.v...​
 
Không biết thuật toán của bạn Rollover79 của nhanh hay không, nhưng sao không làm đơn giản hơn:
PHP:
Function Roman2Dec(Rom As String) As Long
  Dim i As Long
  For i = 1 To 39999
    If WorksheetFunction.Roman(i) = Rom Then Roman2Dec = i: Exit For
  Next
End Function
Còn việc bẩy lỗi tôi nghĩ không cần ---> Gõ sai ráng chịu chứ ---> Hàm của bác Bill tạo ra vẫn vậy mà
 
Không biết thuật toán của bạn Rollover79 của nhanh hay không, nhưng sao không làm đơn giản hơn:
PHP:
Function Roman2Dec(Rom As String) As Long
  Dim i As Long
  For i = 1 To 39999
    If WorksheetFunction.Roman(i) = Rom Then Roman2Dec = i: Exit For
  Next
End Function
Còn việc bẩy lỗi tôi nghĩ không cần ---> Gõ sai ráng chịu chứ ---> Hàm của bác Bill tạo ra vẫn vậy mà
Hàm này giống với cách diễn giải công thức ở dưới hơn. Hàm của tôi đang muốn nói đến giải thuật chung để chuyển đổi từ số la mã sang số thập phân. Còn việc bẫy lỗi như bác BNTT đề cập tôi nghĩ là cần thiết. Nếu nhập sai định dạng thì phải trả về lỗi chứ không thể đưa ra 1 kết quả sai được.
 
Em không nghĩ thế. Hàm của bác Bill, nếu gõ sai, bác ấy nói là #VALUE!, chứ bác ấy không cho ra kết quả sai.
Ý mình là thế này:
- Với hàm ROMAN (là hàm có sẳn), nếu tham chiếu không phải dạng số thì nó ra kết quả #VALUE!
- Với hàm tự tạo ở trên, khi dử liệu nhập bị sai (không phải dạng La Mã) thì nó cũng ra lỗi #VALUE! thôi ---> Vậy cần bẩy lỗi gì nữa
 
Hàm FormatRoman chuyển đổi số nguyên (Integer) sang Roman.
Nguồn http://www.source-code.biz/snippets/vbasic/7.htm
Mã:
' Formats a number as a roman numeral.
' Author: Christian d'Heureuse (www.source-code.biz)
Public Function FormatRoman(ByVal n As Integer) As String
   If n = 0 Then FormatRoman = "0": Exit Function
      ' There is no roman symbol for 0, but we don't want to return an empty string.
   Const r = "IVXLCDM"              ' roman symbols
   Dim i As Integer: i = Abs(n)
   Dim s As String, p As Integer
   For p = 1 To 5 Step 2
      Dim d As Integer: d = i Mod 10: i = i \ 10
      Select Case d                 ' format a decimal digit
         Case 0 To 3: s = String(d, Mid(r, p, 1)) & s
         Case 4:      s = Mid(r, p, 2) & s
         Case 5 To 8: s = Mid(r, p + 1, 1) & String(d - 5, Mid(r, p, 1)) & s
         Case 9:      s = Mid(r, p, 1) & Mid(r, p + 2, 1) & s
         End Select
      Next
   s = String(i, "M") & s           ' format thousands
   If n < 0 Then s = "-" & s        ' insert sign if negative (non-standard)
   FormatRoman = s
   End Function
 
Hàm ConvertToRomanNumerals chuyển đổi số nguyên sang Roman. Text thử thấy chuyển đến số 3.276.700
Nguồn
http://www.freevbcode.com/ShowCode.asp?ID=3234


Mã:
Function ConvertToRomanNumerals(lngNumber As Long) As String

    Dim lngThousands As Long
    Dim lngFiveHundreds As Long
    Dim lngHundreds As Long
    Dim lngFifties As Long
    Dim lngTens As Long
    Dim lngFives As Long
    Dim lngOnes As Long

    lngOnes = lngNumber
    lngThousands = lngOnes \ 1000
    lngOnes = lngOnes - lngThousands * 1000
    lngFiveHundreds = lngOnes \ 500
    lngOnes = lngOnes - lngFiveHundreds * 500
    lngHundreds = lngOnes \ 100
    lngOnes = lngOnes - lngHundreds * 100
    lngFifties = lngOnes \ 50
    lngOnes = lngOnes - lngFifties * 50
    lngTens = lngOnes \ 10
    lngOnes = lngOnes - lngTens * 10
    lngFives = lngOnes \ 5
    lngOnes = lngOnes - lngFives * 5

    ConvertToRomanNumerals = String(lngThousands, "M")

    If lngHundreds = 4 Then
        If lngFiveHundreds = 1 Then
            ConvertToRomanNumerals = ConvertToRomanNumerals & "CM"
        Else
            ConvertToRomanNumerals = ConvertToRomanNumerals & "CD"
        End If
    Else
        ConvertToRomanNumerals = ConvertToRomanNumerals _
                & String(lngFiveHundreds, "D") & String(lngHundreds, "C")
    End If

    If lngTens = 4 Then
        If lngFifties = 1 Then
            ConvertToRomanNumerals = ConvertToRomanNumerals & "XC"
        Else
            ConvertToRomanNumerals = ConvertToRomanNumerals & "XL"
        End If
    Else
        ConvertToRomanNumerals = ConvertToRomanNumerals _
                & String(lngFifties, "L") & String(lngTens, "X")
    End If

    If lngOnes = 4 Then
        If lngFives = 1 Then
            ConvertToRomanNumerals = ConvertToRomanNumerals & "IX"
        Else
            ConvertToRomanNumerals = ConvertToRomanNumerals & "IV"
        End If
    Else
        ConvertToRomanNumerals = ConvertToRomanNumerals _
                & String(lngFives, "V") & String(lngOnes, "I")
    End If
End Function
 
Ý mình là thế này:
- Với hàm ROMAN (là hàm có sẳn), nếu tham chiếu không phải dạng số thì nó ra kết quả #VALUE!
- Với hàm tự tạo ở trên, khi dử liệu nhập bị sai (không phải dạng La Mã) thì nó cũng ra lỗi #VALUE! thôi ---> Vậy cần bẩy lỗi gì nữa
Code của anh thì em không nói. Em nói chuyện bẫy lỗi, là góp ý cho code của Rovoller79 kia.
 
Web KT

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

Back
Top Bottom