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:
Private Sub TextBox2_afterupdate()
dim k as integer
k = val(textbox2.value) ' el valor queda truncado al tipo de datos de destino... un entero al caso.
If ((k < 1) Or (k > 50)) Then
MsgBox ("Dato incorrecto")
TextBox2.Value = ""
Else
nota1 = k.tostring ' si es que quieres un string.
End If
End Sub
Si para tí es inaceptable truncar el valor entonces el código cambia ligeramente:
Private Sub TextBox2_afterupdate()
dim k as single ' nota el cambio de tipo...
k = val(textbox2.value) ' el valor queda truncado al tipo de datos de destino... aora un 'single'.
If ((k < 1) Or (k > 50) or ((k mod 1)<>0)) Then
MsgBox ("Dato incorrecto")
TextBox2.Value = ""
Else
nota1 = k.tostring ' si es que quieres un string.
End If
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):
Private Sub TextBox1_Validating(ByVal sender As Object, ByVal e As System.ComponentModel.CancelEventArgs) Handles TextBox1.Validating
Dim k As Single
k = Val(TextBox1.Text)
'k = Convert.ToSingle(TextBox1.Text)
If ((k Mod 1) <> 0) Then
MessageBox.Show("Debe ser un número entero. No se admiten decimales...")
ElseIf ((k < 0) Or (k > 50)) Then
MessageBox.Show("El valor a introducir debe estar en el rango 1-50.")
Else
nota1 = k.ToString ' ok...
End If
End Sub
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...
... 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...
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