Foto de Rui S.
Rui há 1 ano
Enviada pelo
Site

Devolve texto errado vba

Bom dia,

Tenho um código VBA, que devolve o valor numerário em euros por extenso.

Exemplo 1.521.01€, ele devolve ( um mil, quinhentos e vinte e um euros e um centimo), o erro é que ele devolve um mil, e devia ser só mil, quinhentos e vinte e um euros e um centimo.

Se pudessem ajudar, agradecia.

OBRIGADOS

__________________________________________________________________

Function Extenso_Valor(valor As Double) As String
    Dim strMoeda    As String
    Dim cents       As Variant
    Dim decimalSep  As String

'   Se o valor for igual ou maior que 1 quatrilhao
'   passar erro e sair da funcao
    If valor > 999999999999999# Then
        Extenso_Valor = "Valor excede 999.999.999.999.999"
        Exit Function
    End If

'   Se valor for igual a 1, a unidade está no singular
    If WorksheetFunction.RoundDown(valor, 0) = 1 Then
'       a string da moeda no singular
        strMoeda = " euro"
'       Se for maior que 1 a unidade está no plural
        ElseIf WorksheetFunction.RoundDown(valor, 0) > 1 Then
            strMoeda = " euros"
    End If
   
'   Remove os centavos
    cents = valor - WorksheetFunction.RoundDown(valor, 0)
'   Remove os centavos do valor
    valor = valor - CDbl(cents)
'       Passo o extenso dos centavos
        cents = centavos(CDbl(cents) * 100)
'    End If
'   Caso a string seja diferente de branco e valor seja maior ou igual a 1
    If cents <> "" And valor >= 1 Then
'       acrescentar uma vírgula antes do extenso
        cents = " e " & cents
    End If
'   Iniciar o processo de conversao dos valores longos
    strMoeda = Trim(Trilhoes(valor)) & strMoeda & cents
    strMoeda = Replace(strMoeda, ", e", " e")
    strMoeda = Replace(strMoeda, ", r", " r")
    If Left(strMoeda, 2) = "e " Then
        strMoeda = Mid(strMoeda, 3, Len(strMoeda))
        'ElseIf Left(strMoeda, 5) = "mil e" Then
           ' strMoeda = Mid(strMoeda, 5, Len(strMoeda))
    End If
    vzz = "00000000000000000000"
    vtam = Len(Trim(Mid(Trim(valor), 2, 100)))
    If Right(vzz + vzz + vzz + vzz, vtam) = Mid(Trim(valor), 2, 100) And InStr(UCase(strMoeda), UCase("es ")) > 0 Then
        vetor = Split(strMoeda, " ")
        vtrocar = vetor(UBound(vetor))
        strMoeda = Replace(strMoeda, vtrocar, "de " + vtrocar)
    End If
       
       
    Extenso_Valor = strMoeda

End Function

Private Function centavos(valor As Double) As String
    Dim dezena      As Integer
    Dim unidade     As Integer
   
'   Passa o valor para base decimal
    valor = Round(CDbl(valor / 100), 2)

'   Se for um centavo, escrever valor e sair da funcao
    If valor = 0.01 Then
        centavos = "um cêntimo"
        Exit Function
    End If
   
'   Repassa valor para dezenas
    valor = valor * 100

'   Se nao houver dezenas no valor passado
    If dezenas(valor) = "" Then
'       a string centavos fica em branco
        centavos = ""
    Else
'       caso contrário, passar extenso das dezenas e concatenar
'       com a palavra centavos
        centavos = dezenas(valor) & " cêntimos"
    End If

End Function

Private Function unidades(unidade As Double) As String
    Dim unid(9)
'   Define as unidades a serem usadas
    unid(1) = "um": unid(6) = "seis"
    unid(2) = "dois": unid(7) = "sete"
    unid(3) = "três": unid(8) = "oito"
    unid(4) = "quatro": unid(9) = "nove"
    unid(5) = "cinco"

'   Retorna a string referente a unidade passada para
'   esta funcao
    unidades = Trim(unid(unidade))
End Function

Private Function dezenas(dezena As Double) As String
    Dim dezes(9)
    Dim dez(9)
    Dim intDezena       As Double
    Dim intUnidade      As Double
    Dim tmpStr          As String

'   Define as dezenas a serem utilizadas
    dezes(1) = "onze": dezes(6) = "dezesseis"
    dezes(2) = "doze": dezes(7) = "dezessete"
    dezes(3) = "treze": dezes(8) = "dezoito"
    dezes(4) = "quatorze": dezes(9) = "dezenove"
    dezes(5) = "quinze"
   
    dez(1) = "dez": dez(6) = "sessenta"
    dez(2) = "vinte": dez(7) = "setenta"
    dez(3) = "trinta": dez(8) = "oitenta"
    dez(4) = "quarenta": dez(9) = "noventa"
    dez(5) = "cinquenta"
   
'   Calcula o inteiro da dezena
    intDezena = Int(dezena / 10)
'   Calcula o inteiro da unidade
    intUnidade = dezena Mod 10
'   Se o inteiro da dezena for zero
    If intDezena = 0 Then
'       dezenas sao iguais as unidades
        dezenas = unidades(intUnidade)
        Exit Function
    Else:
'       caso contrário, é igual a dez
        dezenas = dez(intDezena)
    End If

'   Se o inteiro da dezena for igual a 1 e
'   o inteiro da unidade for zero, os valores estao
'   entre 11 e 19
    If (intDezena = 1 And intUnidade > 0) Then
        dezenas = dezes(intUnidade)
    Else
'   Caso contrário, valor está entre 20 e 90 inclusive
        If (intDezena > 1 And intUnidade > 0) Then
'           Concatena a string da dezena com a string da unidade
            dezenas = dezenas & " e " & unidades(intUnidade)
        End If
    End If
    dezenas = dezenas
End Function

Private Function centenas(centena As Double) As String
    Dim tmpCento      As Double
    Dim tmpDez        As Double
    Dim tmpUni        As Double
    Dim tmpUniMod     As Double
    Dim tmpModDez     As Double
    Dim centoString   As String
    Dim cento(9)

'   Define as centenas
    cento(1) = "cento": cento(6) = "seiscentos"
    cento(2) = "duzentos": cento(7) = "setecentos"
    cento(3) = "trezentos": cento(8) = "oitocentos"
    cento(4) = "quatrocentos": cento(9) = "novecentos"
    cento(5) = "quinhentos"
       
'   Calcula o inteiro da centena
    tmpCento = Int(centena / 100)
'   Calcula a parte da dezena
    tmpDez = centena - (tmpCento * 100)
'   Calcula o inteiro da unidade
    tmpUni = Int(tmpDez / 10)
'   Calcula o resto da unidade
    tmpUniMod = tmpUni Mod 10
'   Calcula o resto da dezena
    tmpModDez = tmpDez Mod 10
'   Se centena for cem, definir string como "cem " e sair
    If centena = 100 Then
        centoString = "cem "
    Else
'   Caso contrário definir a string da centena
        centoString = cento(tmpCento)
    End If
'   Avalia se a unidade é maior ou igual a zero, se o resto da unidade é igual ou
'   maior que zero, se a dezena é maior ou igual a um e se a centena é igual ou
'   maior que 1. Se forem verdadeiros; entao, adicionar " e " a string da centena
    If (tmpUni >= 0 And tmpUniMod >= 0 And tmpDez >= 1 And tmpCento >= 1) Then
        centoString = centoString & " e "
    End If
'   Concatena a string do cento com a string da dezena
    centenas = Trim(centoString & dezenas(tmpDez))
End Function

Private Function milhares(milhar As Double) As String
    Dim tmpMilhar      As Double
    Dim tmpCento       As Double
    Dim milString      As String
   
'   Calcula o inteiro da milhar
    tmpMilhar = Int(milhar / 1000)
'   Calcula o cento dentro da milhar
    tmpCento = milhar - (tmpMilhar * 1000)
'   Se milhar for zero, entao a string da milhar fica em branco
    If tmpMilhar = 0 Then milString = ""
'   Se for igual a 1, entao
 '   If '(tmpMilhar = 1) Then
'       string da milhar é igual a unidade e "mil"
        'milString = unidades(tmpMilhar) & "um mil "
'       se maior que 1 e menor que dez, string igual a unidades
    If (tmpMilhar >= 1 And tmpMilhar < 10) Then
            milString = unidades(tmpMilhar) & " mil, "
'           Se for entre 10 e 100, entao string igual a dezenas
            ElseIf (tmpMilhar >= 10 And tmpMilhar < 100) Then
                milString = dezenas(tmpMilhar) & " mil, "
'               Se for entre 100 e 1000, entao igual string centenas
                ElseIf (tmpMilhar >= 100 And tmpMilhar < 1000) Then
                    milString = centenas(tmpMilhar) & " mil, "
    End If
    'If tmpCento = 1 Then milString = " e "
    If (tmpCento >= 1 And tmpCento <= 100) Then milString = milString & "e "
    milhares = Trim(milString & centenas(tmpCento))
End Function

Private Function milhoes(milhao As Double) As String
'   Ver comentários para milhares acima
    Dim tmpMilhao      As Double
    Dim tmpMilhares    As Double
    Dim miString       As String
   
    tmpMilhao = Int(milhao / 1000000)
    tmpMilhares = milhao - (tmpMilhao * 1000000)
    If tmpMilhao = 0 Then miString = ""
    If (tmpMilhao = 1) Then
        miString = unidades(tmpMilhao) & " milhão, "
        ElseIf (tmpMilhao > 1 And tmpMilhao < 10) Then
            miString = unidades(tmpMilhao) & " milhões, "
            ElseIf (tmpMilhao >= 10 And tmpMilhao < 100) Then
                miString = dezenas(tmpMilhao) & " milhões, "
                ElseIf (tmpMilhao >= 100 And tmpMilhao < 1000) Then
                    miString = centenas(tmpMilhao) & " milhões, "
    End If
    If milhao = 1000000# Then miString = "um milhão de "
    milhoes = Trim(miString & milhares(tmpMilhares))
End Function

Private Function bilhoes(bilhao As Double) As String
'   Ver comentários para milhares acima
    Dim tmpBilhao     As Double
    Dim tmpMilhao       As Double
    'Dim tmpMilhoes      As Double
    Dim biString       As String
   
    tmpBilhao = Int(bilhao / 1000000000)
    tmpMilhao = bilhao - (tmpBilhao * 1000000000)
    If (tmpBilhao = 1) Then
        biString = unidades(tmpBilhao) & " bilhão, "
        ElseIf (tmpBilhao > 1 And tmpBilhao < 10) Then
            biString = unidades(tmpBilhao) & " bilhões, "
            ElseIf (tmpBilhao >= 10 And tmpBilhao < 100) Then
                biString = dezenas(tmpBilhao) & " bilhões, "
                ElseIf (tmpBilhao >= 100 And tmpBilhao < 1000) Then
                    biString = centenas(tmpBilhao) & " bilhões, "
    End If
    If bilhao = 1000000000# Then biString = "um bilhão de "
    bilhoes = Trim(biString & milhoes(tmpMilhao))
End Function

Private Function Trilhoes(Trilhao As Double) As String
'   Ver comentários para milhares acima
    Dim tmpTrilhao     As Double
    Dim tmpBilhao       As Double
    Dim triString       As String
   
    tmpTrilhao = Int(Trilhao / 1000000000000#)
    tmpBilhao = Trilhao - (tmpTrilhao * 1000000000000#)
    If (tmpTrilhao = 1) Then
        triString = unidades(tmpTrilhao) & " trilhão, "
        ElseIf (tmpTrilhao > 1 And tmpTrilhao < 10) Then
            triString = unidades(tmpTrilhao) & " trilhões, "
            ElseIf (tmpTrilhao >= 10 And tmpTrilhao < 100) Then
                triString = dezenas(tmpTrilhao) & " trilhões, "
                ElseIf (tmpTrilhao >= 100 And tmpTrilhao < 1000) Then
                    triString = centenas(tmpTrilhao) & " trilhões, "
    End If
    If Trilhao = 1000000000000# Then triString = "um trilhão de "
    Trilhoes = Trim(triString & bilhoes(tmpBilhao))
End Function

Function arredBaixo(valor)
    Dim tmpValor
    tmpValor = Round(CDbl(Right(Round(valor, 2) * 100, 2)) / 100, 2)
    arredBaixo = Round(Round(valor, 2) - tmpValor, 0)
End Function
Sub extenso()

End Sub

Professor Washington A.
Identidade verificada
  • CPF verificado
  • E-mail verificado
Respondeu há 1 ano
Contatar Washington

Para tal pode simplificar bem o seu código...

Function ValorPorExtenso(ByVal valor As Double) As String

    Dim intParte As Long
    Dim decParte As Long
    Dim strMoeda As String
    Dim strIntParte As String
    Dim strDecParte As String
    Dim strPorExtenso As String
    Dim strMilhar As String
    Dim strCentavo As String
    Dim arrUnidades As Variant
    Dim arrDezenas As Variant
    Dim arrCentenas As Variant
    Dim arrEscala As Variant
    
    ' Definição das constantes
    strMoeda = "euro(s)"
    strMilhar = "mil"
    strCentavo = "centavo(s)"
    
    ' Definição dos arrays de unidades, dezenas, centenas e escalas
    arrUnidades = Array("zero", "um", "dois", "três", "quatro", "cinco", "seis", "sete", "oito", "nove", "dez", "onze", "doze", "treze", "catorze", "quinze", "dezesseis", "dezessete", "dezoito", "dezenove")
    arrDezenas = Array("zero", "dez", "vinte", "trinta", "quarenta", "cinquenta", "sessenta", "setenta", "oitenta", "noventa")
    arrCentenas = Array("zero", "cem", "duzentos", "trezentos", "quatrocentos", "quinhentos", "seiscentos", "setecentos", "oitocentos", "novecentos")
    arrEscala = Array("", "mil", "milhão(s)", "bilhão(ões)", "trilhão(ões)", "quadrilhão(ões)", "quintilhão(ões)", "sextilhão(ões)", "septilhão(ões)", "octilhão(ões)", "nonilhão(ões)", "decilhão(ões)")
    
    ' Separação da parte inteira e da parte decimal
    intParte = Int(valor)
    decParte = Round((valor - intParte) * 100)
    
    ' Conversão da parte inteira para por extenso
    If intParte = 0 Then
        strIntParte = "zero"
    Else
        strIntParte = ConverteValor(intParte, arrUnidades, arrDezenas, arrCentenas, arrEscala)
    End If
    
    ' Conversão da parte decimal para por extenso
    If decParte = 0 Then
        strDecParte = ""
    ElseIf decParte = 1 Then
        strDecParte = "um " & strCentavo
    Else
        strDecParte = ConverteValor(decParte, arrUnidades, arrDezenas, arrCentenas, arrEscala) & " " & strCentavo
    End If
    
    ' Concatenação do resultado final
    If strIntParte = "" Then
        strPorExtenso = "zero " & strMoeda
    ElseIf strDecParte = "" Then
        strPorExtenso = strIntParte & " " & strMoeda
    Else
        strPorExtenso = strIntParte

    If intParte = 1 Then
        strPorExtenso = strPorExtenso & " " & strMoeda & " e " & strDecParte
    Else
        strPorExtenso = strPorExtenso & " " & strMoeda & " e " & strDecParte
    End If
End If

' Retorna o valor por extenso
ValorPorExtenso = strPorExtenso
End Function

Function ConverteValor(ByVal valor As Long, ByVal arrUnidades As Variant, ByVal arrDezenas As Variant, ByVal arrCentenas As Variant, ByVal arrEscala As Variant) As String
Dim strResultado As String
Dim intParte As Long
Dim resto As Long

' Se o valor for menor que 20, utiliza o array de unidades
If valor < 20 Then
    strResultado = arrUnidades(valor)
' Se o valor for menor que 100, utiliza o array de dezenas
ElseIf valor < 100 Then
    intParte = Int(valor / 10)
    resto = valor Mod 10
    If resto = 0 Then
        strResultado = arrDezenas(intParte)
    Else
        strResultado = arrDezenas(intParte) & " e " & arrUnidades(resto)
    End If
' Se o valor for menor que 1000, utiliza o array de centenas
ElseIf valor < 1000 Then
    intParte = Int(valor / 100)
    resto = valor Mod 100
    If resto = 0 Then
        strResultado = arrCentenas(intParte)
    Else
        strResultado = arrCentenas(intParte) & " e " & ConverteValor(resto, arrUnidades, arrDezenas, arrCentenas, arrEscala)
    End If
' Se o valor for maior que 1000, utiliza o array de escalas
Else
    For i = UBound(arrEscala) To 1 Step -1
        If valor >= 10 ^ (3 * i) Then
            intParte = Int(valor / (10 ^ (3 * i)))
            resto = valor Mod (10 ^ (3 * i))
            If intParte = 1 Then
                strResultado = "um " & arrEscala(i)
            Else
                strResultado = ConverteValor(intParte, arrUnidades, arrDezenas, arrCentenas, arrEscala) & " " & arrEscala(i)
            End If
            If resto > 0 Then
                strResultado = strResultado & " " & ConverteValor(resto, arrUnidades, arrDezenas, arrCentenas, arrEscala)
            End If
            Exit For
        End If
    Next i
End If

' Retorna o valor por extenso
ConverteValor = strResultado
End Function

Para utilizá-lo, basta chamar a função `ValorPorExtenso` e passar o valor monetário em euros como argumento. Por exemplo:

```vb
Sub TesteValorPorExtenso()

    Dim valor As Double
    
    valor = 1521.01
    
    MsgBox ValorPorExtenso(valor)
    
End Sub

Um professor já respondeu

Envie você também uma dúvida grátis
Ver resposta
Envie uma dúvida grátis
Resposta na hora da Minerva IA e de professores particulares
Enviar dúvida
Professor Michell O.
Identidade verificada
  • CPF verificado
  • E-mail verificado
Respondeu há 1 ano
Contatar Michell Ailton Riciere

Ola Rui! 

O ideal é contratar aulas com um(a) professor(a) pra ter além da resposta apoio para compreender a questão.

Um professor já respondeu

Envie você também uma dúvida grátis
Ver resposta
Minerva IA
do Profes
Respostas na hora
100% no WhatsApp
Envie suas dúvidas pelo App. Baixe agora
Precisa de outra solução? Conheça
Aulas particulares Encontre um professor para combinar e agendar aulas particulares Buscar professor