elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado: Guía actualizada para evitar que un ransomware ataque tu empresa


+  Foro de elhacker.net
|-+  Programación
| |-+  Programación General
| | |-+  .NET (C#, VB.NET, ASP)
| | | |-+  Programación Visual Basic (Moderadores: LeandroA, seba123neo)
| | | | |-+  Números enteros en VBA
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] Ir Abajo Respuesta Imprimir
Autor Tema: Números enteros en VBA  (Leído 690 veces)
isam

Desconectado Desconectado

Mensajes: 2


Ver Perfil
Números enteros en VBA
« en: 8 Noviembre 2020, 20:32 pm »

Holaa,


Apenas estoy iniciando con el mundo de programación y tengo un problema con un código. Acabo de hacer un código para un formulario el cual necesito que los números que se ingresen sean mayores de 0 y menores de 50, y a la vez sean enteros. Mi problema está en poder realizar el código en la parte de números enteros ya que no logro configurarlo. Adjunto el código que realicé:

Código
  1. Private Sub TextBox2_afterupdate()
  2. If Val(TextBox2) < 1 Or Val(TextBox2) > 50 Or Val(TextBox2) Mod 1 = 0 Then
  3.        MsgBox ("Dato incorrecto")
  4.        TextBox2.Value = ""
  5.    Else
  6.        nota1 = TextBox2
  7. End If
  8. End Sub
  9.  
  10.  

Les agradecería mucho

[MOD] Usar las etiquetas GeSHi para publicar código.


« Última modificación: 8 Noviembre 2020, 21:24 pm por simorg » En línea

EdePC
Moderador Global
***
Desconectado Desconectado

Mensajes: 1.809



Ver Perfil
Re: Números enteros en VBA
« Respuesta #1 en: 9 Noviembre 2020, 03:43 am »

Los operadores de división y residuo en VisualBasic es un lío, has de saber que el operador Mod siempre devuelve un número entero por lo que no te va ha servir para hallar un residuo decimal.

Una opción es hallar el residuo a mano con la fórmula:

Código
  1. residuo = Dividendo - (divisor * cociente_entero)

- Puedes usar Fix(numero) para obtener el Entero de un número decimal, ya que cInt(), Int(), etc también redondean XD, solo Fix() obtiene el Entero tal cual.

Quedaría así:

Código
  1. If Val(TextBox2) < 1 Or Val(TextBox2) > 50 Or Val(TextBox2) - Fix(Val(TextBox2) / 1) <> 0 Then

Otra opción más simple es comparar el número con su entero, cosa que si ambos son enteros deben ser iguales, caso contrario uno será decimal y el otro entero:

Código
  1. If Val(TextBox2) < 1 Or Val(TextBox2) > 50 Or Val(TextBox2) <> Fix(Val(TextBox2)) Then

Referencias:

https://docs.microsoft.com/en-us/dotnet/visual-basic/language-reference/operators/mod-operator
https://docs.microsoft.com/en-us/office/vba/language/concepts/getting-started/type-conversion-functions#cint-function-example
https://stackoverflow.com/questions/10631992/function-to-remove-the-decimal-places


En línea

Serapis
Colaborador
***
Desconectado Desconectado

Mensajes: 2.865


Ver Perfil
Re: Números enteros en VBA
« Respuesta #2 en: 9 Noviembre 2020, 21:00 pm »

Es importante saber primero si para tí es válido la introducción de valores decimales o no. Es decir si es válido que pueda truncarse o si debe ser rechazado...

Supongamos que es aceptable truncar un valor con decimales al valor entero, tú código vendría a ser:
Código
  1. Private Sub TextBox2_afterupdate()
  2.    dim k as integer
  3.  
  4.    k = val(textbox2.value)  ' el valor queda truncado al tipo de datos de destino... un entero al caso.
  5.    If ((k < 1) Or (k > 50))  Then
  6.        MsgBox ("Dato incorrecto")
  7.        TextBox2.Value = ""
  8.    Else
  9.        nota1 = k.tostring  ' si es que quieres un string.
  10.    End If
  11. End Sub

Si para tí es inaceptable truncar el valor entonces el código cambia ligeramente:
Código
  1. Private Sub TextBox2_afterupdate()
  2.    dim k as single  ' nota el cambio de tipo...
  3.  
  4.    k = val(textbox2.value)  ' el valor queda truncado al tipo de datos de destino... aora un 'single'.
  5.    If ((k < 1) Or (k > 50) or ((k mod 1)<>0))  Then
  6.        MsgBox ("Dato incorrecto")
  7.        TextBox2.Value = ""
  8.    Else
  9.        nota1 = k.tostring  ' si es que quieres un string.
  10.    End If
  11. End Sub

OJO: la instrucción 'Val' acepta el '.' como separador decimal, pero no ',' luego para un texto como: val("123,45") devuelve 123'0
En cambio Convert.ToSingle("123.45") tiene en cuenta el idioma y lo interpreta como separador de miles (si es español), luego devuelve 12345'0.

Y en cualquier caso, pon mensajes más específicos... 'dato incorrecto', no determina que se espera que se introduzca... redacta mensajes específicos y al caso mejor diferenciar cuando el fallo es fuera de rango de cuando contiene decimales. Por ejemplo (en VB-NET):
Código
  1.    Private Sub TextBox1_Validating(ByVal sender As Object, ByVal e As System.ComponentModel.CancelEventArgs) Handles TextBox1.Validating
  2.        Dim k As Single
  3.  
  4.        k = Val(TextBox1.Text)
  5.        'k = Convert.ToSingle(TextBox1.Text)
  6.        If ((k Mod 1) <> 0) Then
  7.            MessageBox.Show("Debe ser un número entero. No se admiten decimales...")
  8.        ElseIf ((k < 0) Or (k > 50)) Then
  9.            MessageBox.Show("El valor a introducir debe estar en el rango 1-50.")
  10.        Else
  11.            nota1 = k.ToString ' ok...
  12.        End If
  13.    End Sub
  14.  

Y aprovechando que estás aprendiendo... un consejo... utiliza los paréntesis para encerrar el orden de evaluación de las expresiones, es muy fácil para los que empiezan cometer este tipo de errores que luego no logran ver donde está le fallo, porque todo aparentemente está bien.

Aunque de entrada tienes un error semántico...
Citar
... or Val(TextBox2) Mod 1 = 0
Se supone que si el resto es 0, entonces se trata de un número entero, para que 'caiga en ese saco' con los condiionantes indicando fuera de rango unidos por or, el operador debe ndicar distinto de 0, no igual a 0...
Código:
resto = (k mod 1)
Si (k < 1) o (k > 50) o (resto <> 0) ...
' o si no cambialo a la inclusión del rango:
Si (k >= 0) y (k <= 50) y (resto = 0) ...
' Ambas expresiones son idénticas en cuanto a semántica.

Los operadores de división y residuo en VisualBasic es un lío,
?????...

has de saber que el operador Mod siempre devuelve un número entero por lo que no te va ha servir para hallar un residuo decimal.
Esto es falso... en todas las versiones de visual Basic, el operador mod está capacitado para devolver un valor decimal. Otra cosa es que VB trunca de modo automático el dato devuelto al tipo de destino, cuando es posible.

Además cuando existiere algún problema el operador mod puede ser sobrecargado, para que se comporte como uno pudiera esperar/desear...  (por ejemplo hacer un modulo a un tipo de datos de una estructura 'area-point' con decimales).

Operador mod (en español, que existe):
https://docs.microsoft.com/es-es/dotnet/visual-basic/language-reference/operators/mod-operator
« Última modificación: 9 Noviembre 2020, 21:10 pm por NEBIRE » En línea

EdePC
Moderador Global
***
Desconectado Desconectado

Mensajes: 1.809



Ver Perfil
Re: Números enteros en VBA
« Respuesta #3 en: 9 Noviembre 2020, 22:02 pm »

Los operadores de división y residuo en VisualBasic es un lío, has de saber que el operador Mod siempre devuelve un número entero por lo que no te va ha servir para hallar un residuo decimal.

Según las pruebas que hice en un Excel 2013 VBA, en su ventanita de Inmediato (Ctrl + G) tuve feos problemas leyendo la documentación ya que al momento de convertir un dato Decimal a Entero tenia comportamientos diferentes dependiendo de que si era positivo, negativo, la función que convierte, etc. La documentación lo dice, pero es un poco problemático.

Código
  1. ? 2.0 Mod 0.2
  2. ` Error división entre 0
  3.  
  4. ? 2D Mod 0.2D
  5. ` Error de sintaxis
  6.  
  7. ? 3.6 Mod 1
  8. 0
  9.  
  10. ? 3.6 Mod 1.0
  11. 0
  12.  
  13. ? 3.6 Mod 2.3
  14. 0
  15.  
  16. ? 32.7 \ 1
  17. 33
  18.  
  19. ? 32.7 / 1
  20. 32,7
  21.  

Es medio especial el VBA en el tratamiento de Mod, división y conversión a enteros. Tampoco he logrado obtener un residuo decimal como en otros lenguajes, a parte que según la documentación dice que primero redondea los operadores antes de hacer la operación, Dividendo Mod 1 se utiliza en otros lenguajes para saber si el número dado es Entero o Decimal, pero en VBA el operador Mod siempre me ha devuelto un Entero redondeado XD

Para el ejemplo:

Código
  1. dim k as integer
  2. k = val(textbox2.value)  ' el valor queda truncado al tipo de datos de destino... un entero al caso.

- Si se le pone un 2.8, k termina valiendo 3 porque se redondea

Para el ejemplo:
Código
  1. Dim k As Single  ' nota el cambio de tipo...
  2.  
  3. k = Val(TextBox2.Value)  ' el valor queda truncado al tipo de datos de destino... aora un 'single'.
  4. If ((k < 1) Or (k > 50) Or ((k Mod 1) <> 0)) Then

- Si se le pone un 2.8, termina dando por válido el valor porque k Mod 1 devuelve 0

Obviamente es asunto de VBA, ya que por los ejemplos mostrados si debe de funcionar en Visual Basic 6.0 y .NET. O es mi versión de Excel XD
En línea

Páginas: [1] Ir Arriba Respuesta Imprimir 

Ir a:  

Mensajes similares
Asunto Iniciado por Respuestas Vistas Último mensaje
number_format() y numeros enteros (Solucionado) « 1 2 »
PHP
Littl3 10 11,990 Último mensaje 14 Octubre 2010, 17:34 pm
por ~ Yoya ~
50 números enteros introducidos por teclado
Programación C/C++
douglascarvallo 4 3,892 Último mensaje 23 Junio 2013, 06:58 am
por douglascarvallo
Programa que factorize números enteros
Programación C/C++
Einstein92 5 2,399 Último mensaje 25 Enero 2014, 21:49 pm
por Einstein92
cambiar numeros decimales a enteros
Dudas Generales
ZeroRcp 4 1,671 Último mensaje 27 Julio 2015, 19:38 pm
por engel lex
Programa que lea números enteros y nos diga cuántos números son pares.
Programación C/C++
estudiante_1 3 1,834 Último mensaje 20 Agosto 2015, 18:58 pm
por estudiante_1
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines