[VB6] Converter String em int's

eXcept

Power Member
Viva.

Estou a tentar fazer uma label que calcule, on the fly, uma percentagem. Ou seja, à medida que vou escrevendo nas TextBox's, ele vá-me calculando esse valor.

O código está assim:

Código:
Private Sub txt_rematesc_KeyPress(KeyAscii As Integer)
    If (KeyAscii = 8) Or (KeyAscii = 9) Then Exit Sub
    If (KeyAscii < 48) Or (KeyAscii > 57) Then KeyAscii = 0
Dim i, j, k As Integer
i = CInt(Val(Val(txt_golosc)))
j = CInt((Val(txt_rematesc)))
k = (i / j) * 100
MsgBox (k)
''lbl_percentc = k & "%"
End Sub

O erro que dá é "Runtime Error 6 - Overflow

na linha

Código:
k = (i/j) * 100
 
Deves verificar se txt_golosc e txt_rematec têm alguma coisa lá inserida pk no primeiro caracter n deve ter nd e n vejo aí a restrição. Dps o caracter só esta acessivel na text box dps do handle, ou seja só dps do fim da função a n ser k o obrigues a fazer handle...
Dps tb pode ser a divisão por 0 e se "k" é inteiro o k acontece à parte decimal!? (n sei se o vb faz automaticamante o ROUND ao resultado)

Sujestão cria variaveis globais e por cada letra inserida utilizas as variaveis e fazes as contas nelas, n faças com as textbox directamente...

Cumps,
 
Deves verificar se txt_golosc e txt_rematec têm alguma coisa lá inserida pk no primeiro caracter n deve ter nd e n vejo aí a restrição. Dps o caracter só esta acessivel na text box dps do handle, ou seja só dps do fim da função a n ser k o obrigues a fazer handle...
Dps tb pode ser a divisão por 0 e se "k" é inteiro o k acontece à parte decimal!? (n sei se o vb faz automaticamante o ROUND ao resultado)

Sujestão cria variaveis globais e por cada letra inserida utilizas as variaveis e fazes as contas nelas, n faças com as textbox directamente...

Cumps,

as textbox's golosc e rematesc são, à partida, = 0, para evitar a divisão por nada.

O handle é o keypress, logo sempre que é premida uma tecla dentro da textbox, ele devia correr o ciclo e calcular o valor.
 
O mundo não é perfeito :)

Código:
Private Sub txt_rematesc_KeyPress(KeyAscii As Integer)
    If (KeyAscii = 8) Or (KeyAscii = 9) Then Exit Sub
    If (KeyAscii < 48) Or (KeyAscii > 57) Then KeyAscii = 0
Dim i, j, k As Integer
[B]If CInt(Val(txt_golosc)) = 0 Or CInt(Val(txt_rematesc)) = 0 Then Exit Sub[/B]
i = CInt(Val(txt_golosc))
j = CInt(Val(txt_rematesc))
k = (i / j) * 100
MsgBox (k)
''lbl_percentc = k & "%"
End Sub

Não te esqueças que dividir por 0 É dividir por nada ;)

Em princípio deve resultar. Testa ;)

edit - porque é que fazes Val(Val())? O resultado é o mesmo :confused: apenas gastas mais ram/cpu

Cumps [[[[[[[[[[]]]]]]]]]]
angelofwisdom
 
Com isso tem um comportamento esquisito, tanto actualiza como não actualiza ( leia-se tanto entra no ciclo como não entra ) . Ainda não detectei um padrão de comportamento dele para descobrir o que está mal :-|
 
If CInt(Val(txt_golosc)) = 0 Or CInt(Val(txt_rematesc)) = 0 Then Exit Sub

Deve ser essa linha.

Se puderes dá-me uma explicação detalhada de 1) o que é (que vai ser escrito em) cada textbox, e 2) como é que queres que ele trabalhe?
 
If CInt(Val(txt_golosc)) = 0 Or CInt(Val(txt_rematesc)) = 0 Then Exit Sub

Deve ser essa linha.

Se puderes dá-me uma explicação detalhada de 1) o que é (que vai ser escrito em) cada textbox, e 2) como é que queres que ele trabalhe?


1) números. Ou seja o número de remates e o número de golos, em duas textbox's separadas ( txt_golosc e txt_rematesc.

2) pretendo que, a cada caracter introduzido, ele calcule a eficácia ( golos/remates ) em percentagem ( * 100 & "%" ). Isto sempre dinamicamente, imagina ao colocar 20 remates, ao digitar o 2, ele calcule logo, e ao por o 0 seguinte, ele calcule já o valor de 20 remates
 
Deixa-me ver se percebi... quando escreves QUALQUER COISA em QUALQUER textbox ele faz o cálculo?
Nesse caso, espera um pouco que eu já edito este post com um código feito por mim...
 
em qualquer uma das duas textbox's, sim. tendo em conta ke serão sempre caracteres númericos - daí o code
Código:
   If (KeyAscii = 8) Or (KeyAscii = 9) Then Exit Sub
    If (KeyAscii < 48) Or (KeyAscii > 57) Then KeyAscii = 0
 
Decidi não editar aquele post.

Cá vai:

OnKeyPress:
Código:
Private Sub txt_golosc_KeyPress(KeyAscii As Integer)
    Validar KeyAscii
    CalcularPercentagem
End Sub
 
Private Sub txt_rematesc_KeyPress(KeyAscii As Integer)
    Validar KeyAscii
    CalcularPercentagem
End Sub

Sub's auxiliares:
Código:
Private Sub Validar(ByRef KeyAscii As Integer)
    If (KeyAscii < Asc("0") Or KeyAscii > Asc("9")) And Not KeyAscii = 8 Then KeyAscii = 0
End Sub
 
Private Sub CalcularPercentagem()
    If txt_golosc > txt_rematesc Then
        MsgBox "O número de golos é superior ao número de remates. Isto é impossivel ^^"
    Else
        MsgBox "Percentagem de eficácia (remates/golos): " & _
                Fix(Val(txt_golosc.Text) * 100 / Val(txt_rematesc.Text)) & "%"
    End If
    ' remates = 100          golos * 100
    ' -------   --- <=> x =  -----------
    '  golos   =  x             remates
End Sub

Os comentários finais são de ajuda matemática (para eu ter a certeza de que os cálculos estão correctos).

Ajuda?

Nota uma coisa: a validação e os cálculos são efectuados ANTES do número pressionado estar escrito, portanto aconselho-te a não fazeres as coisas dessa forma (on-the-fly)
Se quiseres usar essa forma, deixo-te um código grandinho, e em parte desnecessário:

Código:
Option Explicit
 
Private Sub txt_golosc_KeyPress(KeyAscii As Integer)
    Validar KeyAscii, txt_golosc
    CalcularPercentagem
End Sub
 
Private Sub txt_rematesc_KeyPress(KeyAscii As Integer)
    Validar KeyAscii, txt_rematesc
    CalcularPercentagem
End Sub
 
Private Sub Validar(ByRef KeyAscii As Integer, Caller As Object)
    Dim PosOfCursor As Integer
    If Not TypeOf Caller Is TextBox Then Exit Sub
    PosOfCursor = Caller.SelStart
    If (KeyAscii >= Asc("0") And KeyAscii <= Asc("9")) Then
        Caller.Text = Left(Caller.Text, PosOfCursor) & Chr(KeyAscii) & Mid(Caller.Text, PosOfCursor + 1)
        KeyAscii = 0
    End If
    If Not KeyAscii = 8 Then KeyAscii = 0
    Caller.SelStart = PosOfCursor + 1
End Sub
 
Private Sub CalcularPercentagem()
    If txt_golosc > txt_rematesc Then
        MsgBox "O número de golos é superior ao número de remates. Isto é impossivel ^^"
    Else
        MsgBox "Percentagem de eficácia (remates/golos): " & _
                Fix(Val(txt_golosc.Text) * 100 / Val(txt_rematesc.Text)) & "%"
    End If
    ' remates = 100          golos * 100
    ' -------   --- <=> x =  -----------
    '  golos  =  x             remates
End Sub
Mas aqui estou a reinventar a roda....
 
Última edição:
1º Código - Error Overflow. Debug nesta linha

Código:
        MsgBox "Percentagem de eficácia (remates/golos): " & _
                Fix(Val(txt_golosc.Text) * 100 / Val(txt_rematesc.Text)) & "%"

O segundo funciona, mas se tento por aquilo dentro de uma label em vez de textbox

Código:
lbl_percentc.Caption = Fix(Val(txt_golosc.Text) * 100 / Val(txt_rematesc.Text)) & "%"

ele dá-me na mesma o overflow. Porque será?
 
Não sei! Comigo resulta na boa =X

O código que te aconselho vivamente (fica gravado numa Label):

Código:
Private Sub txt_golosc_KeyPress(KeyAscii As Integer)
    Validar KeyAscii
End Sub
 
Private Sub txt_golosc_KeyUp(KeyCode As Integer, Shift As Integer)
    CalcularPercentagem
End Sub
Private Sub txt_rematesc_KeyPress(KeyAscii As Integer)
    Validar KeyAscii
End Sub
Private Sub txt_rematesc_KeyUp(KeyCode As Integer, Shift As Integer)
    CalcularPercentagem
End Sub
Private Sub Validar(ByRef KeyAscii As Integer)
    If (KeyAscii < Asc("0") Or KeyAscii > Asc("9")) And Not KeyAscii = 8 Then KeyAscii = 0
End Sub
 
Private Sub CalcularPercentagem()
    If Val(txt_golosc.Text) > Val(txt_rematesc.Text) Then
        Label1.Caption = "O número de golos é superior ao número de remates. Isto é impossivel ^^"
    Else
        Label1.Caption = "Percentagem de eficácia (remates/golos): " & _
                Fix(Val(txt_golosc.Text) * 100 / Val(txt_rematesc.Text)) & "%"
    End If
    ' remates = 100          golos * 100
    ' -------   --- <=> x =  -----------
    '  golos   =  x             remates
End Sub

Espero que ajude. Se tiveres mais overflows, diz-me como estás a declarar as variáveis...

EDIT - JÁ SEI O MOTIVO DOS OVERFLOWS!
Acrescenta esta linha logo em baixo do Sub CalcularPercentagem():
If Not IsNumeric(txt_golosc.Text) Or Not IsNumeric(txt_rematesc.Text) Then Exit Sub
e vê se resulta
 
O handle é o keypress, logo sempre que é premida uma tecla dentro da textbox, ele devia correr o ciclo e calcular o valor.

Posso estar errado, mas verifica se o valor da textbox ao correr o ciclo n tem o valor antes da tecla ser inserida? ( se tens o valor 4 na textbox pressionas o 5, tu keres k o valor a calcular seja 45 certo!?, mas, como já disse, penso k dentro do ciclo ao acederes a textbox.text ainda só está lá o 4)

e mais, verifica aki se n esta a ocurrer nd disso tb... n custa verificar
http://www.devx.com/vb2themax/Tip/18524

Cumps
 
Não sei! Comigo resulta na boa =X

O código que te aconselho vivamente (fica gravado numa Label):

Código:
Private Sub txt_golosc_KeyPress(KeyAscii As Integer)
    Validar KeyAscii
End Sub
 
Private Sub txt_golosc_KeyUp(KeyCode As Integer, Shift As Integer)
    CalcularPercentagem
End Sub
Private Sub txt_rematesc_KeyPress(KeyAscii As Integer)
    Validar KeyAscii
End Sub
Private Sub txt_rematesc_KeyUp(KeyCode As Integer, Shift As Integer)
    CalcularPercentagem
End Sub
Private Sub Validar(ByRef KeyAscii As Integer)
    If (KeyAscii < Asc("0") Or KeyAscii > Asc("9")) And Not KeyAscii = 8 Then KeyAscii = 0
End Sub
 
Private Sub CalcularPercentagem()
    If Val(txt_golosc.Text) > Val(txt_rematesc.Text) Then
        Label1.Caption = "O número de golos é superior ao número de remates. Isto é impossivel ^^"
    Else
        Label1.Caption = "Percentagem de eficácia (remates/golos): " & _
                Fix(Val(txt_golosc.Text) * 100 / Val(txt_rematesc.Text)) & "%"
    End If
    ' remates = 100          golos * 100
    ' -------   --- <=> x =  -----------
    '  golos   =  x             remates
End Sub

Espero que ajude. Se tiveres mais overflows, diz-me como estás a declarar as variáveis...

EDIT - JÁ SEI O MOTIVO DOS OVERFLOWS!
Acrescenta esta linha logo em baixo do Sub CalcularPercentagem():
If Not IsNumeric(txt_golosc.Text) Or Not IsNumeric(txt_rematesc.Text) Then Exit Sub
e vê se resulta

Viva

Funciona 5 estrelas

Tks
 
Posso estar errado, mas verifica se o valor da textbox ao correr o ciclo n tem o valor antes da tecla ser inserida? ( se tens o valor 4 na textbox pressionas o 5, tu keres k o valor a calcular seja 45 certo!?, mas, como já disse, penso k dentro do ciclo ao acederes a textbox.text ainda só está lá o 4)

e mais, verifica aki se n esta a ocurrer nd disso tb... n custa verificar
http://www.devx.com/vb2themax/Tip/18524

Cumps
Estás correcto, e esse foi o principal problema :) é que eu tinha de acrescentar o número à textbox antes de fazer os cálculos. Mas foi por isso que eu decidi usar o evento KeyUp - quando este evento é chamado, já a tecla está escrita :)

Viva

Funciona 5 estrelas

Tks
No problem :) Anytime ;)

Cumps [[[[[[[[[[]]]]]]]]]]
angelofwisdom
 
Boas!
Nao sou barra em VB mas penso q s tivesses um Timer com uma funcaozinha q fizesse o calculo da % sempre q clicasses numa key axo q seria de mais facil resolucao e eficacia ;) (tipo,carregavas numa tecla o Timer fikava Enable,calculava a % e de seguida fikava Disable!)!!
Cumps
 
Isso é uma solução meio "martelada". Para além disso, são recursos, memória e até TEMPO desperdiçados, porque a alternativa é o que eu e o eXcept fizemos, e ao que parece resultou 5* ;)

Apesar do nosso código ser maior do que seria se usássemos um timer, nós conseguimos chegar ao objectivo sem acrescentar um controlo extra, e fazendo um código mais... linear... e fácil de perceber e fazer debug em caso de problemas.

;)
 
Código:
Option Explicit

Private Sub TxtGolos_Change()
    Calcular
End Sub

Private Sub TxtRemates_Change()
    Calcular
End Sub

Private Sub Calcular()
    If LTrim(Str(Val(TxtRemates))) <> TxtRemates Or LTrim(Str(Val(TxtGolos))) <> TxtGolos Then
        TxtResultado = "Erro"
    Else
        If Val(TxtRemates) = 0 Then
            TxtResultado = "0 Remates"
        Else
            TxtResultado = (Val(TxtGolos) * 100) / Val(TxtRemates) & " %"
        End If
    End If
End Sub

Esta previsto evitar divisão por zero (0 remates) e perceber se o retorno do Val() corresponde ao que o user pensa que escreveu da textbox (para prever virgulas, pontos, etc)
 
Back
Topo