Skip to content

2. Fundamentos del lenguaje VB.NET

2.1. Introducción

En primer lugar, trataremos VB.NET como un lenguaje de programación clásico. Abordaremos los objetos más adelante.

En un programa hay dos elementos

  • datos
  • las instrucciones que los manipulan

Por lo general, se busca separar los datos de las instrucciones:

2.2. Los datos de VB.NET

VB.NET utiliza los siguientes tipos de datos:

  1. números enteros, reales y decimales
  1. caracteres y cadenas de caracteres
  2. booleanos
  3. fechas
  4. objetos

2.2.1. Los tipos de datos predefinidos

Tipo VB
Tipo .NET equivalente
Tamaño
Rango de valores
Booleano
System.Boolean
2 bytes
Verdadero o Falso.
Byte
System.Byte
1 byte
De 0 a 255 (sin signo).
Caractere
System.Char
2 bytes
De 0 a 65 535 (sin signo).
Fecha
System.DateTime
8 bytes
Desde las 0:00:00 del 1 de enero de 0001 hasta las 23:59:59 del 31 de diciembre de 9999.
Decimal
System.Decimal
16 bytes
De 0 a +/-79 228 162 514 264 337 593 543 950 335 sin decimales; de 0 a +/-7,9228162514264337593543950335 con 28 decimales; el número más pequeño distinto de cero es +/-0,0000000000000000000000000001 (+/-1E-28).
Doble
System.Double
8 bytes
-1,79769313486231E+308 a
-4,94065645841247E-324 para los valores negativos; de 4,94065645841247E-324 a 1,79769313486231E+308 para los valores positivos.
Integer
System.Int32
4 bytes
-2 147 483 648 a 2 147 483 647.
Long
System.Int64
8 bytes
-9 223 372 036 854 775 808 a 9 223 372 036 854 775 807.
Objeto
System.Object
4 bytes
En una variable de tipo Objeto se puede almacenar cualquier tipo.
Short
System.Int16
2 bytes
-32 768 a 32 767.
Single
System.Single
4 bytes
-3,402823E+38 a -1,401298E-45 para los valores negativos; 1,401298E-45 a 3,402823E+38 para los valores positivos.
Cadena
System.String (clase)
 
De 0 a aproximadamente 2 mil millones de caracteres Unicode.

En la tabla anterior, se observa que hay dos tipos posibles para un entero de 32 bits: Integer y System.Int32. Ambos tipos son intercambiables. Lo mismo ocurre con los demás tipos VB y sus equivalentes en la plataforma .NET. A continuación se muestra un ejemplo de programa:


Module types
    Sub Main()
        ' números enteros
        Dim var1 As Integer = 100
        Dim var2 As Long = 10000000000L
        Dim var3 As Byte = 100
        Dim var4 As Short = 4
        ' números reales
        Dim var5 As Decimal = 4.56789D
        Dim var6 As Double = 3.4
        Dim var7 As Single = -0.000103F
        ' fecha
        Dim var8 As Date = New Date(2003, 1, 1, 12, 8, 4)
        ' booleano
        Dim var9 As Boolean = True
        ' carácter
        Dim var10 As Char = "A"c
        ' cadena de caracteres
        Dim var11 As String = "abcde"
        ' objeto
        Dim var12 As Object = New Object
        ' visualizaciones
        Console.Out.WriteLine("var1=" + var1.ToString)
        Console.Out.WriteLine("var2=" + var2.ToString)
        Console.Out.WriteLine("var3=" + var3.ToString)
        Console.Out.WriteLine("var4=" + var4.ToString)
        Console.Out.WriteLine("var5=" + var5.ToString)
        Console.Out.WriteLine("var6=" + var6.ToString)
        Console.Out.WriteLine("var7=" + var7.ToString)
        Console.Out.WriteLine("var8=" + var8.ToString)
        Console.Out.WriteLine("var9=" + var9.ToString)
        Console.Out.WriteLine("var10=" + var10)
        Console.Out.WriteLine("var11=" + var11)
        Console.Out.WriteLine("var12=" + var12.ToString)
    End Sub
End Module

La ejecución arroja los siguientes resultados:

var1=100
var2=10000000000
var3=100
var4=4
var5=4,56789
var6=3,4
var7=-0,000103
var8=01/01/2003 12:08:04
var9=True
var10=A
var11=abcde
var12=System.Object

2.2.2. Notación de datos literales

Integer
145, -7, &FF (hexadecimal)
Long
100000L
Double
134,789, -45E-18 (-45 × 10⁻¹⁸)
Single
134.789F, -45E-18F (-45 10-18)
Decimal
100000D
Char
"A"c
String
"hoy"
Boolean
verdadero, falso
date
New Date(2003, 1, 1) para el 01/01/2003

Cabe destacar los siguientes puntos:

  • 100000L, la L indica que el número se considera un entero largo
  • 134.789F, la «F» indica que el número se considera un número real de precisión simple
  • 100000D, la D indica que el número se considera un número real decimal
  • "A"c, para convertir la cadena de caracteres "A" en el carácter 'A'
  • La cadena de caracteres está entre comillas. Si la cadena debe contener el carácter "", este se duplica, como en "abcd""e", para representar la cadena [abcd"e].

2.2.3. Declaración de datos

2.2.3.1. Función de las declaraciones

Un programa maneja datos caracterizados por un nombre y un tipo. Estos datos se almacenan en la memoria. Al momento de la compilación del programa, el compilador asigna a cada dato un espacio en la memoria caracterizado por una dirección y un tamaño. Lo hace con la ayuda de las declaraciones realizadas por el programador. Además, estas declaraciones permiten al compilador detectar errores de programación. Así, la operación x=x*2 se considerará errónea si x es una cadena de caracteres, por ejemplo.

2.2.3.2. Declaración de constantes

La sintaxis para declarar una constante es la siguiente:

const identificador as tipo=valor

por ejemplo, [const PI as double=3.141592]. ¿Por qué declarar constantes?

  1. La lectura del programa será más fácil si se le da a la constante un nombre significativo: [const taux_tva as single=0.186F]
  2. Modificar el programa será más sencillo si la «constante» llega a cambiar. Así, en el caso anterior, si la tasa del IVA pasa a ser del 33 %, la única modificación que habrá que hacer será cambiar la instrucción que define su valor: [const taux_tva as single=0.336F]. Si se hubiera utilizado 0.186 explícitamente en el programa, habría que modificar numerosas instrucciones.

2.2.3.3. Declaración de variables

Una variable se identifica mediante un nombre y se refiere a un tipo de datos. VB.NET no distingue entre mayúsculas y minúsculas. Por lo tanto, las variables FIN y fin son idénticas. Las variables pueden inicializarse al momento de su declaración. La sintaxis para declarar una o más variables es:

dim variable1, variable2, ..., variableN as identificador_de_tipo

donde identificateur_de_type es un tipo predefinido o un tipo definido por el programador.

2.2.4. Las conversiones entre números y cadenas de caracteres

nombre -> chaîne
nombre.ToString o "" & número o CType(número, String)
objet -> chaîne
objet.ToString
chaine -> Integer
Integer.Parse(cadena) o Int32.Parse
chaîne -> Long
Long.Parse (cadena) o Int64.Parse
chaîne -> Double
Double.Parse (cadena)
chaîne -> Single
Single.Parse (cadena)

La conversión de una cadena a un número puede fallar si la cadena no representa un número válido. En ese caso, se genera un error fatal denominado excepción en VB.NET. Este error se puede manejar mediante la siguiente cláusula try/catch:

try
        appel de la fonction susceptible de générer l'exception
 catch e as Exception
        traiter l'exception e
end try
instruction suivante

Si la función no genera una excepción, se pasa a la siguiente instrucción; de lo contrario, se pasa al cuerpo de la cláusula catch y luego a la siguiente instrucción. Más adelante volveremos a abordar el manejo de excepciones. A continuación se presenta un programa que muestra las principales técnicas de conversión entre números y cadenas de caracteres. En este ejemplo, la función muestra en pantalla el valor de su parámetro. Así, affiche(S) muestra el valor de S en pantalla.


' directivas
Option Strict On

' espacios de nombres importados
Imports System

' el módulo de prueba
Module Module1

    Sub Main()
        ' procedimiento principal
        ' datos locales
        Dim S As String
        Const i As Integer = 10
        Const l As Long = 100000
        Const f As Single = 45.78F
        Dim d As Double = -14.98

        ' número --> cadena
        affiche(CType(i, String))
        affiche(CType(l, String))
        affiche(CType(f, String))
        affiche(CType(d, String))

        'booleano --> cadena
        Const b As Boolean = False
        affiche(b.ToString)

        ' cadena --> entero
        Dim i1 As Integer = Integer.Parse("10")
        affiche(i1.ToString)
        Try
            i1 = Integer.Parse("10.67")
            affiche(i1.ToString)
        Catch e As Exception
            affiche("Erreur [10.67] : " + e.Message)
        End Try

        ' cadena --> entero largo
        Dim l1 As Long = Long.Parse("100")
        affiche("" + l1.ToString)
        Try
            l1 = Long.Parse("10.675")
            affiche("" & l1)
        Catch e As Exception
            affiche("Erreur [10.675] : " + e.Message)
        End Try

        ' cadena --> doble
        Dim d1 As Double = Double.Parse("100,87")
        affiche(d1.ToString)
        Try
            d1 = Double.Parse("abcd")
            affiche("" & d1)
        Catch e As Exception
            affiche("Erreur [abcd] : " + e.Message)
        End Try

        ' cadena --> single
        Dim f1 As Single = Single.Parse("100,87")
        affiche(f1.ToString)
        Try
            d1 = Single.Parse("abcd")
            affiche(f1.ToString)
        Catch e As Exception
            affiche("Erreur [abcd] : " + e.Message)
        End Try
    End Sub

    ' muestra
    Public Sub affiche(ByVal S As String)
        Console.Out.WriteLine("S=" + S)
    End Sub
End Module

Los resultados obtenidos son los siguientes:

S=10
S=100000
S=45,78
S=-14,98
S=False
S=10
S=Erreur [10.67] : Le format de la chaîne d'entrée est incorrect.
S=100
S=Erreur [10.675] : Le format de la chaîne d'entrée est incorrect.
S=100,87
S=Erreur [abcd] : Le format de la chaîne d'entrée est incorrect.
S=100,87
S=Erreur [abcd] : Le format de la chaîne d'entrée est incorrect.

Cabe señalar que los números reales en forma de cadena de caracteres deben utilizar la coma y no el punto decimal. Por lo tanto, se escribirá Dim d As Double = -14.98, pero Dim d1 As Double = Double.Parse("100,87")

2.2.5. Las tablas de datos

Una tabla VB.NET es un objeto que permite agrupar datos del mismo tipo bajo un mismo identificador. Su declaración es la siguiente:

Dim Tabla(n) as tipo o Dim Tabla() as tipo = New tipo(n) {}

donde n es el índice del último elemento de la matriz. La sintaxis Tableau(i) hace referencia al dato n.º i, donde i pertenece al intervalo [0,n]. Cualquier referencia al dato Tableau(i), en la que i no pertenezca al intervalo [0,n], provocará una excepción. Un array puede inicializarse al mismo tiempo que se declara. En este caso, no es necesario indicar el número del último elemento.


        Dim entiers() As Integer = {0, 10, 20, 30}

Los arrays tienen una propiedad llamada Length, que representa el número de elementos del array. A continuación se muestra un programa de ejemplo:


Module tab0
    Sub Main()
        ' una primera tabla
        Dim tab0(5) As Integer
        For i As Integer = 0 To UBound(tab0)
            tab0(i) = i
        Next
        For i As Integer = 0 To UBound(tab0)
            Console.Out.WriteLine("tab0(" + i.ToString + ")=" + tab0(i).tostring)
        Next

        ' un segundo cuadro
        Dim tab1() As Integer = New Integer(5) {}
        For i As Integer = 0 To tab1.Length - 1
            tab1(i) = i * 10
        Next
        For i As Integer = 0 To tab1.Length - 1
            Console.Out.WriteLine("tab1(" + i.ToString + ")=" + tab1(i).tostring)
        Next
    End Sub
End Module

y su ejecución:

tab0(0)=0
tab0(1)=1
tab0(2)=2
tab0(3)=3
tab0(4)=4
tab0(5)=5
tab1(0)=0
tab1(1)=10
tab1(2)=20
tab1(3)=30
tab1(4)=40
tab1(5)=50

Una matriz bidimensional se puede declarar de la siguiente manera:

Dim Matriz(n,m) as Tipo o Dim Matriz(,) as Tipo = New Tipo(n,m) {}

donde n+1 es el número de filas y m+1 el número de columnas. La sintaxis Matriz(i,j) hace referencia al elemento j de la fila i de Matriz. La matriz bidimensional también se puede inicializar al mismo tiempo que se declara:


        Dim réels(,) As Double = {{0.5, 1.7}, {8.4, -6}}

El número de elementos en cada una de las dimensiones se puede obtener mediante el método GetLenth(i), donde i=0 representa la dimensión correspondiente al primer índice, i=1 la dimensión correspondiente al segundo índice, … A continuación se muestra un programa de ejemplo:


Module Module2
    Sub Main()
        ' un primer cuadro
        Dim tab0(2, 1) As Integer
        For i As Integer = 0 To UBound(tab0)
            For j As Integer = 0 To tab0.GetLength(1) - 1
                tab0(i, j) = i * 10 + j
            Next
        Next
        For i As Integer = 0 To UBound(tab0)
            For j As Integer = 0 To tab0.GetLength(1) - 1
                Console.Out.WriteLine("tab0(" + i.ToString + "," + j.ToString + ")=" + tab0(i, j).tostring)
            Next
        Next

        ' un segundo cuadro
        Dim tab1(,) As Integer = New Integer(2, 1) {}
        For i As Integer = 0 To tab1.GetLength(0) - 1
            For j As Integer = 0 To tab1.GetLength(1) - 1
                tab1(i, j) = i * 100 + j
            Next
        Next
        For i As Integer = 0 To tab1.GetLength(0) - 1
            For j As Integer = 0 To tab1.GetLength(1) - 1
                Console.Out.WriteLine("tab1(" + i.ToString + "," + j.ToString + ")=" + tab1(i, j).tostring)
            Next
        Next
    End Sub
End Module

y los resultados de su ejecución:

tab0(0)=0
tab0(1)=1
tab0(2)=2
tab0(3)=3
tab0(4)=4
tab0(5)=5
tab1(0)=0
tab1(1)=10
tab1(2)=20
tab1(3)=30
tab1(4)=40
tab1(5)=50

Una matriz de matrices se declara de la siguiente manera:

Dim Matriz(n)() as Tipo o Dim Matriz()() as Tipo = new Tipo(n)()

La declaración anterior crea una matriz de n+1 filas. Cada elemento Matriz(i) es una referencia a una matriz unidimensional. Estas matrices no se crean al realizar la declaración anterior. El siguiente ejemplo ilustra la creación de una matriz de matrices:


         ' una matriz de matrices
        Dim noms()() As String = New String(3)() {}
         ' inicialización
        For i = 0 To noms.Length - 1
            noms(i) = New String(i) {}
            For j = 0 To noms(i).Length - 1
                noms(i)(j) = "nom" & i & j
            Next
        Next

Aquí, noms(i) es un array de i+1 elementos. Como noms(i) es un array, noms(i).Length es su número de elementos. A continuación se muestra un ejemplo que reúne los tres tipos de arrays que acabamos de presentar:


' directivas
Option Strict On
Option Explicit On 

' importaciones
Imports System

' clase de prueba
Module test
    Sub main()
        ' un array unidimensional inicializado
        Dim entiers() As Integer = {0, 10, 20, 30}
        Dim i As Integer
        For i = 0 To entiers.Length - 1
            Console.Out.WriteLine("entiers[" & i & "]=" & entiers(i))
        Next

        ' un array bidimensional inicializado
        Dim réels(,) As Double = {{0.5, 1.7}, {8.4, -6}}
        Dim j As Integer
        For i = 0 To réels.GetLength(0) - 1
            For j = 0 To réels.GetLength(1) - 1
                Console.Out.WriteLine("réels[" & i & "," & j & "]=" & réels(i, j))
            Next
        Next

        ' una matriz de matrices
        Dim noms()() As String = New String(3)() {}

        ' inicialización
        For i = 0 To noms.Length°- 1
            noms(i) =°New String(i) {}
            For j = 0 To noms(i).Length - 1
                noms(i)(j) = "nom" & i & j
            Next
        Next

        ' visualización
        For i = 0 To noms.Length°- 1
            For j = 0 To noms(i).Length - 1
                Console.Out.WriteLine("noms[" & i & "][" & j & "]=" & noms(i)(j))
            Next
        Next
    End Sub
End Module

Al ejecutarlo, obtenemos los siguientes resultados:

entiers[0]=0
entiers[1]=10
entiers[2]=20
entiers[3]=30
réels[0,0]=0,5
réels[0,1]=1,7
réels[1,0]=8,4
réels[1,1]=-6
noms[0][0]=nom00
noms[1][0]=nom10
noms[1][1]=nom11
noms[2][0]=nom20
noms[2][1]=nom21
noms[2][2]=nom22
noms[3][0]=nom30
noms[3][1]=nom31
noms[3][2]=nom32
noms[3][3]=nom33

2.3. Las instrucciones básicas de VB.NET

Se distingue

1 las instrucciones elementales ejecutadas por la computadora.

2 las instrucciones de control del desarrollo del programa.

Las instrucciones elementales se hacen evidentes al analizar la estructura de una computadora y sus periféricos.

  1. Lectura de información proveniente del teclado

  2. procesamiento de información

  3. Escribir información en la pantalla

  4. Lectura de información de un archivo en disco

  5. Escribir información en un archivo de disco

2.3.1. Escritura en pantalla

Existen diferentes instrucciones para escribir en pantalla:

Console.Out.WriteLine(expression)
Console.WriteLine(expression)
Console.Error.WriteLine (expression)

donde expression representa cualquier tipo de dato que pueda convertirse en una cadena de caracteres para mostrarse en pantalla. En los ejemplos vistos hasta ahora, solo hemos utilizado la instrucción Console.Out.WriteLine(expresión).

La clase System.Console brinda acceso a las operaciones de escritura en pantalla (Write, WriteLine). La clase Console tiene dos propiedades, Out y Error, que son flujos de escritura de tipo StreamWriter:

  • Console.WriteLine() es equivalente a Console.Out.WriteLine() y escribe en el flujo Out, que por lo general está asociado a la pantalla.
  • Console.Error.WriteLine() escribe en el flujo Error, que por lo general también está asociado a la pantalla.

Los flujos Out y Error están asociados por defecto a la pantalla. Sin embargo, pueden redirigirse a archivos de texto durante la ejecución del programa, como veremos a continuación.

2.3.2. Lectura de datos ingresados desde el teclado

El flujo de datos proveniente del teclado está representado por el objeto Console.In de tipo StreamReader. Este tipo de objetos permite leer una línea de texto con el método ReadLine:


        Dim ligne As String = Console.In.ReadLine()

La línea escrita en el teclado se almacena en la variable ligne y luego puede ser procesada por el flujo de entrada programme.Le, el cual puede redirigirse a un archivo, al igual que los flujos de salida y de error.

2.3.3. Ejemplo de entradas y salidas

A continuación se muestra un breve programa que ilustra las operaciones de entrada y salida del teclado y la pantalla:


' opciones
Option Explicit On 
Option Strict On

' espacios de nombres
Imports System

' módulo
Module io1
    Sub Main()
        ' escritura en el flujo de salida
        Dim obj As New Object
        Console.Out.WriteLine(("" & obj.ToString))

        ' escritura en el flujo Error
        Dim i As Integer = 10
        Console.Error.WriteLine(("i=" & i))

        ' lectura de una línea ingresada desde el teclado
        Console.Out.Write("Tapez une ligne : ")
        Dim ligne As String = Console.In.ReadLine()
        Console.Out.WriteLine(("ligne=" + ligne))
    End Sub
End Module

y los resultados de la ejecución:

System.Object
i=10
Tapez une ligne : ceci est un essai
ligne=ceci est un essai

Las instrucciones


        Dim obj As New Object
        Console.Out.WriteLine(obj.ToString)

solo sirven para mostrar que cualquier objeto puede ser objeto de una visualización. Aquí no buscaremos explicar el significado de lo que se muestra.

2.3.4. Redirección de E/S

En DOS/Windows existen tres dispositivos estándar denominados:

  1. dispositivo de entrada estándar: por defecto, se refiere al teclado y lleva el n.º 0
  2. dispositivo de salida estándar: por defecto, se refiere a la pantalla y tiene el n.º 1
  3. dispositivo de error estándar: por defecto, se refiere a la pantalla y lleva el n.º 2

En VB.NET, el flujo de escritura Console.Out escribe en el dispositivo 1, el flujo de escritura Console.Error escribe en el dispositivo 2 y el flujo de lectura Console.In lee los datos del dispositivo 0. Al ejecutar un programa en una ventana de DOS en Windows, se puede definir cuáles serán los dispositivos 0, 1 y 2 para el programa que se ejecuta. Consideremos la siguiente línea de comando:

pg arg1 arg2 .. argn

Mediante los argumentos argi del programa pg, se pueden redirigir los dispositivos de E/S estándar a archivos:

0<in.txt
el flujo de entrada estándar n.º 0 se redirige al archivo in.txt. Por lo tanto, en el programa, el flujo Console.In obtendrá sus datos del archivo in.txt.
 
1>out.txt
redirige la salida n.º 1 al archivo out.txt. Esto implica que, en el programa, el flujo Console.Out escribirá sus datos en el archivo out.txt
  
1>>out.txt
Lo mismo, pero los datos escritos se agregan al contenido actual del archivo out.txt.
  
2>error.txt
redirige la salida n.º 2 al archivo error.txt. Esto implica que, en el programa, el flujo Console.Error escribirá sus datos en el archivo error.txt
  
2>>error.txt
Lo mismo, pero los datos escritos se agregan al contenido actual del archivo error.txt.
  
1>out.txt 2>error.txt
Los dispositivos 1 y 2 se redirigen ambos a archivos
  

Cabe señalar que, para redirigir los flujos de E/S del programa pg hacia archivos, no es necesario modificar el programa pg. Es el programa OS el que determina la naturaleza de los dispositivos 0, 1 y 2. Consideremos el siguiente programa:


' opciones
Option Explicit On 
Option Strict On

' espacios de nombres
Imports System

' redirecciones
Module console2
    Sub Main()
        ' lectura del flujo In
        Dim data As String = Console.In.ReadLine()
        ' escritura del flujo de salida
        Console.Out.WriteLine(("écriture dans flux Out : " + data))
        ' escritura en flujo de error
        Console.Error.WriteLine(("écriture dans flux Error : " + data))
    End Sub
End Module

Compilemos este programa:

dos>vbc es2.vb
Compilateur Microsoft (R) Visual Basic .NET version 7.10.3052.4 pour Microsoft (R) .NET Framework version 1.1.4322.573
Copyright (C) Microsoft Corporation 1987-2002. Tous droits réservés.

dos>dir
24/02/2004  15:39                  416 es2.vb
11/03/2004  08:20                3 584 es2.exe

Hagamos una primera ejecución:

dos>es2.exe
un premier test
écriture dans flux Out : un premier test
écriture dans flux Error : un premier test

La ejecución anterior no redirige ninguno de los flujos de E/S estándar In, Out ni Error. Ahora vamos a redirigir los tres flujos. El flujo In se redirigirá a un archivo in.txt, el flujo Out al archivo out.txt, y el flujo Error al archivo error.txt. Esta redirección se realiza en la línea de comandos de la siguiente manera

dos>es2.exe 0<in.txt 1>out.txt 2>error.txt

La ejecución arroja los siguientes resultados:

dos>more in.txt
un second test

dos>es2.exe 0<in.txt 1>out.txt 2>error.txt

dos>more out.txt
écriture dans flux Out : un second test

dos>more error.txt
écriture dans flux Error : un second test

Se ve claramente que los flujos Out y Error no escriben en los mismos dispositivos.

2.3.5. Asignación del valor de una expresión a una variable

Aquí nos enfocamos en la operación variable=expression.. La expresión puede ser de tipo: aritmética, relacional, booleana o de caracteres.

2.3.5.1. Lista de operadores

Acción
Elemento del lenguaje
Arithmétique
^, –, *, /, \, Mod, +, =
Assignation
=, ^=, *=, /=, \=, +=, -=, &=
Comparaison
=, <>, <, >, <=, >=, Like, Is
Concaténation
&, +
Opérations logiques/de bits
Not, And, Or, Xor, AndAlso, OrElse
Opérations diverses
AddressOf, GetType

2.3.5.2. Expresión aritmética

Los operadores de las expresiones aritméticas son los siguientes:

Arithmétique
^, –, *, /, \, Mod, +, =

+: suma, -: resta, *: multiplicación, /: división real, \: cociente de la división entera, Mod: resto de la división entera, ^: elevación a una potencia. Así, el siguiente programa:


' operadores aritméticos
Module operateursarithmetiques
    Sub Main()
        Dim i, j As Integer
        i = 4 : j = 3
        Console.Out.WriteLine(i & "/" & j & "=" & (i / j))
        Console.Out.WriteLine(i & "\" & j & "=" & (i \ j))
        Console.Out.WriteLine(i & " mod " & j & "=" & (i Mod j))

        Dim r1, r2 As Double
        r1 = 4.1 : r2 = 3.6
        Console.Out.WriteLine(r1 & "/" & r2 & "=" & (r1 / r2))
        Console.Out.WriteLine(r1 & "^2=" & (r1 ^ 2))
        Console.Out.WriteLine(Math.Cos(3))
    End Sub
End Module

da los siguientes resultados:

4/3=1,33333333333333
4\3=1
4 mod 3=1
4,1/3,6=1,13888888888889
4,1^2=16,81
-0,989992496600445

Existen diversas funciones matemáticas. Estas son algunas de ellas:


Public Shared Function Sqrt(ByVal d As Double ) As Double
raíz cuadrada

[Visual Basic]
Public Shared Function Cos(ByVal d As Double ) As Double
coseno

Public Shared Function Sin(ByVal a As Double) As Double
Senos

[Visual Basic]
Public Shared Function Tan(ByVal a As Double) As Double
Tangente

[Visual Basic]
Public Shared Function Pow(ByVal x As Double,ByVal y As Double) As Double
x elevado a y (x > 0)

[Visual Basic]
Public Shared Function Exp(ByVal d As Double) As Double
Exponencial

[Visual Basic]
Overloads Public Shared Function Log( ByVal d As Double ) As Double
Logaritmo natural

Overloads Public Shared Function Abs(ByVal value As Double ) As Double
valor absoluto
....
 

Todas estas funciones están definidas en una clase llamada Math. Al utilizarlas, hay que anteponerles el nombre de la clase en la que están definidas. Por lo tanto, se escribirá:

        Dim r1, r2 As Double
        r2 = Math.Sqrt(9)
        r1 = Math.Cos(3)

La definición completa de la clase Math es la siguiente:

E 
Representa la base del logaritmo natural especificada por la constante e.
  
PI 
Representa la relación entre la circunferencia de un círculo y su diámetro, especificada por la constante π.
  
Abs 
Sobrescrito. Devuelve el valor absoluto de un número especificado.
 
Acos 
Devuelve el ángulo cuyo coseno es el número especificado.
 
Asin 
Devuelve el ángulo cuyo seno es el número especificado.
 
Atan 
Devuelve el ángulo cuyo valor de tangente es el número especificado.
 
Atan2 
Devuelve el ángulo cuya tangente es el cociente de dos números especificados.
 
BigMul
Genera el producto integral de dos números de 32 bits.
 
Ceiling 
Devuelve el número entero más pequeño mayor o igual que el número especificado.
 
Cos 
Devuelve el coseno del ángulo especificado.
 
Cosh 
Devuelve el coseno hiperbólico del ángulo especificado.
 
DivRem
Sobrecargada. Devuelve el cociente de dos números, pasando el resto como parámetro de salida.
 
Exp 
Devuelve e elevado a la potencia especificada.
 
Floor 
Devuelve el número entero más grande menor o igual que el número especificado.
 
IEEERemainder 
Devuelve el resto de la división de un número especificado por otro.
 
Log 
Sobrecargada. Devuelve el logaritmo de un número especificado.
 
Log10 
Devuelve el logaritmo en base 10 de un número especificado.
 
Max 
Sobrecargada. Devuelve el mayor de dos números especificados.
 
Min 
Sobrecargada. Devuelve el menor de dos números.
 
Pow 
Devuelve un número especificado elevado a la potencia especificada.
 
Round 
Sobrecargada. Devuelve el número más cercano al valor especificado.
 
Sign 
Sobrecargada. Devuelve un valor que indica el signo de un número.
 
Sin 
Devuelve el seno del ángulo especificado.
 
Sinh 
Devuelve el seno hiperbólico del ángulo especificado.
 
Sqrt 
Devuelve la raíz cuadrada de un número especificado.
 
Tan 
Devuelve la tangente del ángulo especificado.
 
Tanh 
Devuelve la tangente hiperbólica del ángulo especificado.
 

Cuando una función se declara «sobrecargada», significa que existe para diversos tipos de parámetros. Por ejemplo, la función Abs(x) existe para x de tipo Integer, Long, Decimal, Single y Float. Para cada uno de estos tipos existe una definición separada de la función Abs. Por lo tanto, se dice que está sobrecargada.

2.3.5.3. Prioridades en la evaluación de expresiones aritméticas

La prioridad de los operadores al evaluar una expresión aritmética es la siguiente (de mayor a menor prioridad):

Categoría
Operadores
Primaire
Todas las expresiones sin operadores: funciones, paréntesis
Élévation à la puissance
^
Négation unaire
+, -
Multiplication
*, /
Division par un entier
\
Modulo
Mod
Addition
+, -

2.3.5.4. Expresiones relacionales

Los operadores son los siguientes:

Comparaison
=, <>, <, >, <=, >=, Like, Is

=: igual a, <>: diferente de, <: menor que (estricto), >: mayor que (estricto), <=: menor o igual que, >=: mayor o igual que, Like: coincide con un patrón, Is: identidad de objetos. Todos estos operadores tienen la misma prioridad. Se evalúan de izquierda a derecha. El resultado de una expresión relacional es un valor booleano.

Comparación de cadenas de caracteres: consideremos el siguiente programa:


' espacios de nombres
Imports System

Module string1
    Sub main()
        Dim ch1 As Char = "A"c
        Dim ch2 As Char = "B"c
        Dim ch3 As Char = "a"c
        Console.Out.WriteLine("A<B=" & (ch1 < ch2))
        Console.Out.WriteLine("A<a=" & (ch1 < ch3))
        Dim chat As String = "chat"
        Dim chien As String = "chien"
        Dim chaton As String = "chaton"
        Dim chat2 As String = "CHAT"
        Console.Out.WriteLine("chat<chien=" & (chat < chien))
        Console.Out.WriteLine("chat<chaton=" & (chat < chaton))
        Console.Out.WriteLine("chat<CHAT=" & (chat < chat2))
        Console.Out.WriteLine("chaton like chat*=" & ("chaton" Like "chat*"))
    End Sub
End Module

y el resultado de su ejecución:

A<B=True
A<a=True
chat<chien=True
chat<chaton=True
chat<CHAT=False
chaton like chat*=True

Supongamos que tenemos dos caracteres: C1 y C2. Es posible compararlos con los operadores: <, <=, =, <>, >, >=. En este caso, lo que se compara son los valores Unicode de los caracteres, que son números. Según el orden Unicode, se dan las siguientes relaciones:

espacio < .. < '0' < '1' < .. < '9' < .. < 'A' < 'B' < .. < 'Z' < .. < 'a' < 'b' < .. < 'z'

Las cadenas de caracteres se comparan carácter por carácter. La primera desigualdad que se encuentra entre dos caracteres implica una desigualdad del mismo sentido en las cadenas. Con estas explicaciones, se invita al lector a analizar los resultados del programa anterior.

2.3.5.5. Expresiones booleanas

Los operadores son los siguientes:

Opérations logiques/de bits
Not, And, Or, Xor, AndAlso, OrElse

Not: «y» lógico, Or: «o» lógico, Not: negación, Xor: «o» exclusivo.

op1 AndAlso op2: si op1 es falso, op2 no se evalúa y el resultado es falso.

op1 OrElse op2: si op1 es verdadero, op2 no se evalúa y el resultado es verdadero.

La prioridad de estos operadores entre sí es la siguiente:

NOT logique
Not
AND logique
Y, AndAlso
OR logique
O bien, OrElse
XOR logique
XOR

El resultado de una expresión booleana es un valor booleano.

2.3.5.6. Operaciones con bits

Por un lado, encontramos los mismos operadores que los booleanos, con la misma prioridad. También hay dos operadores de desplazamiento: << y >>. Sean i y j dos números enteros.

i<<n
desplaza a i n bits hacia la izquierda. Los bits que se añaden son ceros.
i>>n
desplaza i n bits hacia la derecha. Si i es un entero con signo (signed char, int, long), se conserva el bit de signo.
i & j
realiza la operación lógica ET entre i y j, bit por bit.
i | j
realiza la operación lógica bit a bit entre i y j (OU).
~i
incrementa i en 1
i^j
crea el OU y el EXCLUSIF a partir de i y j

Sea el siguiente programa:


Module operationsbit
    Sub main()
        ' manipulación de bits
        Dim i As Short = &H123F
        Dim k As Short = &H7123
        Console.Out.WriteLine("i<<4=" & (i << 4).ToString("X"))
        Console.Out.WriteLine("i>>4=" & (i >> 4).ToString("X"))
        Console.Out.WriteLine("k>>4=" & (k >> 4).ToString("X"))
        Console.Out.WriteLine("i and 4=" & (i And 4).ToString("X"))
        Console.Out.WriteLine("i or 4 =" & (i Or 4).ToString("X"))
        Console.Out.WriteLine("not i=" & (Not i).ToString("X"))
    End Sub
End Module

Su ejecución arroja los siguientes resultados:

i<<4=23F0
i>>4=123
k>>4=712
i and 4=4
i or k =123F
not i=EDC0

2.3.5.7. Operador asociado a una asignación

Es posible escribir a+=b, lo que significa a=a+b. La lista de operadores que se pueden combinar con la operación de asignación es la siguiente:

combinaison d'opérateurs
^=, *=, /=, \=, +=, -=, &=

2.3.5.8. Prioridad general de los operadores

Categoría
Operadores
Primaire
Todas las expresiones sin operadores
Élévation à la puissance
^
Négation unaire
+, -
Multiplication
*, /
Division par un entier
\
Modulo
Mod
Addition
+, -
Concaténation
&
Déplacement
<<, >>
Relationnel
=, <>, <, >, <=, >=, Like, Is, TypeOf...Is
NOT logique
Not
AND logique
Y, AndAlso
OR logique
O bien, OrElse
XOR logique
XOR

Cuando un operando se coloca entre dos operadores de la misma prioridad, la asociatividad de los operadores determina el orden en que se realizan las operaciones. Todos los operadores son asociativos por la izquierda, lo que significa que las operaciones se ejecutan de izquierda a derecha. La prioridad y la asociatividad se pueden controlar mediante expresiones entre paréntesis.

2.3.5.9. Las conversiones de tipo

Existen varias funciones predefinidas que permiten pasar de un tipo de datos a otro. La lista es la siguiente:

CBool,CByte,CChar,CDate,CDbl,CDec,CInt,CLng,CObj,CShort,CSng,CStr

Estas funciones aceptan como argumento una expresión numérica o una cadena de caracteres. El tipo del resultado se indica en la siguiente tabla:

función
resultado
Rango de valores del parámetro de la función
CBool
Booleano
Cualquier cadena o expresión numérica válida.
CByte
Byte
De 0 a 255; las fracciones se redondean.
CChar
Caracter
Cualquier expresión de cadena válida; el valor puede estar entre 0 y 65 535.
CDate
Fecha
Cualquier representación válida de la fecha y la hora.
CDbl
Doble
-1,79769313486231E+308 a
-4,94065645841247E-324 para valores negativos; de 4,94065645841247E-324 a 1,79769313486231E+308 para valores positivos.
CDec
Decimal
+/-79 228 162 514 264 337 593 543 950 335 para los números sin decimales. El rango de valores de los números con 28 decimales es
+/-7,9228162514264337593543950335. El número más pequeño distinto de cero es 0,0000000000000000000000000001.
CInt
Entero
de -2 147 483 648 a 2 147 483 647; las fracciones se redondean.
CLng
Long
De -9 223 372 036 854 775 808 a 9 223 372 036 854 775 807; las fracciones se redondean.

CObj 
Objeto
Cualquier expresión válida.
CShort
Corto
De -32 768 a 32 767; las fracciones se redondean.
CSng
Single
De -3,402823E+38 a -1,401298E-45 para los valores negativos; de 1,401298E-45 a 3,402823E+38 para los valores positivos.
CStr
Cadena
Los valores que devuelve la función Cstr dependen del argumento expresión.

A continuación se muestra un programa de ejemplo:


Module conversion
    Sub main()
        Dim var1 As Boolean = CBool("true")
        Dim var2 As Byte = CByte("100")
        Dim var3 As Char = CChar("A")
        Dim var4 As Date = CDate("30 janvier 2004")
        Dim var5 As Double = CDbl("100,45")
        Dim var6 As Decimal = CDec("1000,67")
        Dim var7 As Integer = CInt("-30")
        Dim var8 As Long = CLng("456")
        Dim var9 As Short = CShort("-14")
        Dim var10 As Single = CSng("56,78")
        Console.Out.WriteLine("var1=" & var1)
        Console.Out.WriteLine("var2=" & var2)
        Console.Out.WriteLine("var3=" & var3)
        Console.Out.WriteLine("var4=" & var4)
        Console.Out.WriteLine("var5=" & var5)
        Console.Out.WriteLine("var6=" & var6)
        Console.Out.WriteLine("var7=" & var7)
        Console.Out.WriteLine("var8=" & var8)
        Console.Out.WriteLine("var9=" & var9)
        Console.Out.WriteLine("var10=" & var10)
    End Sub
End Module

y los resultados de su ejecución:

var1=True
var2=100
var3=A
var4=30/01/2004
var5=100,45
var6=1000,67
var7=-30
var8=456
var9=-14
var10=56,78

También se puede utilizar la función CType(expression, type) como se muestra en el siguiente programa:


Module ctype1
    Sub main()
        Dim var1 As Boolean = CType("true", Boolean)
        Dim var2 As Byte = CType("100", Byte)
        Dim var3 As Char = CType("A", Char)
        Dim var4 As Date = CType("30 janvier 2004", Date)
        Dim var5 As Double = CType("100,45", Double)
        Dim var6 As Decimal = CType("1000,67", Decimal)
        Dim var7 As Integer = CType("-30", Integer)
        Dim var8 As Long = CType("456", Long)
        Dim var9 As Short = CType("-14", Short)
        Dim var10 As Single = CType("56,78", Single)
        Dim var11 As String = CType("47,89", String)
        Dim var12 As String = 47.89.ToString
        Dim var13 As String = "" & 47.89
        Console.Out.WriteLine("var1=" & var1)
        Console.Out.WriteLine("var2=" & var2)
        Console.Out.WriteLine("var3=" & var3)
        Console.Out.WriteLine("var4=" & var4)
        Console.Out.WriteLine("var5=" & var5)
        Console.Out.WriteLine("var6=" & var6)
        Console.Out.WriteLine("var7=" & var7)
        Console.Out.WriteLine("var8=" & var8)
        Console.Out.WriteLine("var9=" & var9)
        Console.Out.WriteLine("var10=" & var10)
        Console.Out.WriteLine("var11=" & var11)
        Console.Out.WriteLine("var12=" & var12)
        Console.Out.WriteLine("var13=" & var13)
    End Sub
End Module

lo cual arroja los siguientes resultados:

var1=True
var2=100
var3=A
var4=30/01/2004
var5=100,45
var6=1000,67
var7=-30
var8=456
var9=-14
var10=56,78
var11=47,89
var12=47,89
var13=47,89

2.4. Instrucciones para el control del desarrollo del programa

2.4.1. Detener

El método Exit, definido en la clase Environment, permite detener la ejecución de un programa:


[Visual Basic]
Public Shared Sub Exit(ByVal exitCode As Integer )

detiene el proceso en curso y devuelve el valor exitCode al proceso padre. Este último puede utilizar el valor de exitCode. En DOS, esta variable de estado se devuelve a DOS en la variable de sistema ERRORLEVEL, cuyo valor se puede comprobar en un archivo por lotes. En Unix, la variable $? recupera el valor de exitCode.

    Environment.Exit(0)

detendrá la ejecución del programa con un valor de estado de 0.

2.4.2. Estructura de selección simple

if condition then
    actions_alors
else
    actions_sinon
end if
  • cada acción está en una línea
  • la cláusula else puede omitirse.

Se pueden anidar las estructuras de selección, como lo muestra el siguiente ejemplo:


' opciones
Option Explicit On 
Option Strict On

' espacios de nombres
Imports System

Module if1
    Sub main()
        Dim i As Integer = 10
        If i > 4 Then
            Console.Out.WriteLine(i & " est > " & 4)
        Else
            If i = 4 Then
                Console.Out.WriteLine(i & " est = " & 4)
            Else
                Console.Out.WriteLine(i & " est < " & 4)
            End If
        End If
    End Sub
End Module

El resultado obtenido:

10 est > 4

2.4.3. Estructura de casos

La sintaxis es la siguiente:

select case expression
    case liste_valeurs1
        actions1
case liste_valeurs2
        actions2
...
case else
        actions_sinon
end select
  • El tipo de [expression] debe ser uno de los siguientes:
Boolean, Byte, Char, Date, Decimal, Double, Integer, Long, Object, Short, Single et String
  • La cláusula [case else] puede omitirse.
  • [liste_valeursi] son valores posibles de la expresión. [listes_valeursi] representa una lista de condiciones: condición1, condición2, ..., condiciónx. Si [expression] cumple alguna de las condiciones, se ejecutan las acciones asociadas a la cláusula [liste_valeursi]. Las condiciones pueden tener la siguiente forma:
  • val1 to val2: verdadero si [expression] pertenece al dominio [val1,val2]
  • val1: verdadero si [expression] es igual a val1
  • is > val1: verdadero si [expression] > val1. La palabra clave [is] puede omitirse
  • Lo mismo ocurre con los operadores =, <, <=, >, >=, <>
  • solo se ejecutan las acciones relacionadas con la primera condición que se cumple.

Consideremos el siguiente programa:


' opciones
Option Explicit On 
Option Strict On

' espacios de nombres
Imports System

Module selectcase1
    Sub main()
        Dim i As Integer = 10
        Select Case i
            Case 1 To 4, 7 To 8
                Console.Out.WriteLine("i est dans l'intervalle [1,4] ou [7,8]")
            Case Is > 12
                Console.Out.WriteLine("i est > 12")
            Case Is < 15
                Console.Out.WriteLine("i est < 15")
            Case Is < 20
                Console.Out.WriteLine("i est < 20")
        End Select
    End Sub
End Module

Da los siguientes resultados:

i est < 15

2.4.4. Estructura de repetición

2.4.4.1. Número de repeticiones conocido


For counter [ As datatype ] = start To end [ Step step ]
   actions
Next [ counter ]

Las acciones se realizan para cada uno de los valores que toma la variable [counter]. Consideremos el siguiente programa:


' opciones
Option Explicit On 
Option Strict On

' espacios de nombres
Imports System

Module for1
    Sub main()
        Dim somme As Integer = 0
        Dim résultat As String = "somme("
        For i As Integer = 0 To 10 Step 2
            somme += i
            résultat += " " + i.ToString
        Next
        résultat += ")=" + somme.ToString
        Console.Out.WriteLine(résultat)
    End Sub
End Module

Los resultados:

somme( 0 2 4 6 8 10)=30

Otra estructura de iteración con un número conocido de iteraciones es la siguiente:


For Each element [ As datatype ] In groupe
   [ actions ]
Next [ element ]
  • groupe es una colección de objetos. La colección de objetos que ya conocemos es el array
  • datatype es el tipo de los objetos de la colección. En el caso de un array, sería el tipo de los elementos del array
  • element es una variable local del bucle que tomará sucesivamente como valor todos los valores de la colección.

Así, el siguiente código:


' opciones
Option Explicit On 
Option Strict On

' espacios de nombres
Imports System

Module foreach1
    Sub main()
        Dim amis() As String = {"paul", "hélène", "jacques", "sylvie"}
        For Each nom As String In amis
            Console.Out.WriteLine(nom)
        Next
    End Sub
End Module

mostraría:

paul
hélène
jacques
sylvie

2.4.4.2. Número de repeticiones desconocido

Existen numerosas estructuras en VB.NET para este caso.


Do { While | Until } condition
   [ statements ]
Loop

El bucle continúa mientras se cumpla la condición (while) o hasta que se cumpla la condición (until). Es posible que el bucle nunca se ejecute.


Do
   [ statements ]
Loop { While | Until } condition

El bucle se repite mientras se cumpla la condición (while) o hasta que se cumpla la condición (until). El bucle siempre se ejecuta al menos una vez.


While condition
   [ statements ]
End While

El bucle continúa mientras se cumpla la condición. Es posible que el bucle nunca se ejecute. Los siguientes bucles calculan la suma de los primeros 10 números enteros.


' opciones
Option Explicit On 
Option Strict On

' espacios de nombres
Imports System

Module boucles1
    Sub main()
        Dim i, somme As Integer
        i = 0 : somme = 0
        Do While i < 11
            somme += i
            i += 1
        Loop
        Console.Out.WriteLine("somme=" + somme.ToString)
        i = 0 : somme = 0
        Do Until i = 11
            somme += i
            i += 1
        Loop
        Console.Out.WriteLine("somme=" + somme.ToString)
        i = 0 : somme = 0
        Do
            somme += i
            i += 1
        Loop Until i = 11
        Console.Out.WriteLine("somme=" + somme.ToString)
        i = 0 : somme = 0
        Do
            somme += i
            i += 1
        Loop While i < 11
        Console.Out.WriteLine("somme=" + somme.ToString)
    End Sub
End Module
somme=55
somme=55
somme=55
somme=55

2.4.4.3. Instrucciones para la gestión de bucles

exit do
sale de un bucle do ... loop
exit for
sale de un bucle «for»

2.5. La estructura de un programa VB.NET

Un programa VB.NET que no utilice clases definidas por el usuario ni funciones distintas de la función principal Main puede tener la siguiente estructura:


' opciones
Option Explicit On 
Option Strict On

' espacios de nombres
Imports espace1
Imports ....

Module nomDuModule
    Sub main()
....
    End Sub
End Module
  • La directiva [Option Explicit on] exige la declaración de las variables. En VB.NET, esto no es obligatorio. Una variable no declarada es, entonces, de tipo Object.
  • La directiva [Option Strict on] prohíbe cualquier conversión de tipos de datos que pueda provocar una pérdida de datos, así como cualquier conversión entre tipos numéricos y cadenas. Por lo tanto, es necesario utilizar explícitamente funciones de conversión.
  • El programa importa todos los espacios de nombres que necesita. Aún no hemos introducido este concepto. En los programas anteriores, a menudo nos hemos encontrado con instrucciones del tipo:
        Console.Out.WriteLine(unechaine)

En realidad, hubiéramos tenido que escribir:

        System.Console.Out.WriteLine(unechaine)

donde System es el espacio de nombres que contiene la clase [Console]. Al importar el espacio de nombres [System] con una instrucción Imports, VB.NET lo explorará sistemáticamente cada vez que encuentre una clase que no conozca. Repetirá la búsqueda en todos los espacios de nombres declarados hasta encontrar la clase buscada. Entonces se escribe:


' espacios de nombres
Imports System
....

        Console.Out.WriteLine(unechaine)

Un ejemplo de programa podría ser el siguiente:


' opciones
Option Explicit On 
Option Strict On

'espacios de nombres
Imports System

' módulo principal
Module main1
    Sub main()
        Console.Out.WriteLine("main1")
    End Sub
End Module

El mismo programa se puede escribir de la siguiente manera:


' opciones
Option Explicit On 
Option Strict On

'espacios de nombres
Imports System

' clase de prueba
Public Class main2
    Public Shared Sub main()
        Console.Out.WriteLine("main2")
    End Sub
End Class

Aquí utilizamos el concepto de clase que se presentará en el siguiente capítulo. Cuando una clase de este tipo contiene un procedimiento estático (compartido) llamado main, este se ejecuta. Si incluimos esta sintaxis aquí es porque el lenguaje gemelo de VB.NET, que es C#, solo conoce el concepto de clase, c.a.d, por lo que todo código ejecutado pertenece necesariamente a una clase. El concepto de clase forma parte de la programación orientada a objetos. Imponerlo en el diseño de cualquier programa resulta un poco torpe. Esto se ve aquí en la versión 2 del programa anterior, donde nos vemos obligados a introducir un concepto de clase y de método estático donde no es necesario. Por lo tanto, de ahora en adelante, solo introduciremos el concepto de clase cuando sea necesario. En los demás casos, utilizaremos el concepto de módulo, como en la versión 1 anterior.

2.6. Compilación y ejecución de un programa VB.NET

La compilación de un programa VB.NET solo requiere el SDK.NET. Tomemos el siguiente programa:


' opciones
Option Explicit On 
Option Strict On

' espacios de nombres
Imports System

Module boucles1
    Sub main()
        Dim i, somme As Integer
        i = 0 : somme = 0
        Do While i < 11
            somme += i
            i += 1
        Loop
        Console.Out.WriteLine("somme=" + somme.ToString)
        i = 0 : somme = 0
        Do Until i = 11
            somme += i
            i += 1
        Loop
        Console.Out.WriteLine("somme=" + somme.ToString)
        i = 0 : somme = 0
        Do
            somme += i
            i += 1
        Loop Until i = 11
        Console.Out.WriteLine("somme=" + somme.ToString)
        i = 0 : somme = 0
        Do
            somme += i
            i += 1
        Loop While i < 11
        Console.Out.WriteLine("somme=" + somme.ToString)
    End Sub
End Module

Supongamos que se encuentra en un archivo llamado [boucles1.vb]. Para compilarlo, procedemos de la siguiente manera:

dos>dir boucles1.vb
11/03/2004  15:55                  583 boucles1.vb

dos>vbc boucles1.vb
Compilateur Microsoft (R) Visual Basic .NET version 7.10.3052.4
pour Microsoft (R) .NET Framework version 1.1.4322.573
Copyright (C) Microsoft Corporation 1987-2002. Tous droits réservés.

dos>dir boucles1.*
11/03/2004  16:04                  601 boucles1.vb
11/03/2004  16:04                3 584 boucles1.exe

El programa vbc.exe es el compilador VB.NET. Aquí, se encontraba en el PATH del DOS:


dos>path
PATH=E:\Program Files\Microsoft Visual Studio .NET 2003\Common7\IDE;E:\Program Files\Microsoft Visual Studio .NET 2003\VC7\BIN;E:\Program Files\Microsoft Visual Studio .NET 2003\Common7\Tools;E:\Program Files\Microsoft Visual Studio .NET 2003\Common7\Tools\bin\prerelease;E:\Program Files\Microsoft Visual Studio .NET 2003\Common7\Tools\bin;E:\Program Files\Microsoft Visual Studio .NET 2003\SDK\v1.1\bin;E:\WINNT\Microsoft.NET\Framework\v1.1.4322;e:\winnt\system32;e:\winnt;

dos>dir E:\WINNT\Microsoft.NET\Framework\v1.1.4322\vbc.exe
21/02/2003  10:20              737 280 vbc.exe

El compilador [vbc] genera un archivo .exe ejecutable por la máquina virtual .NET:

dos>boucles1
somme=55
somme=55
somme=55
somme=55

2.7. El ejemplo IMPOTS

Nos proponemos escribir un programa que permita calcular el impuesto de un contribuyente. Consideremos el caso simplificado de un contribuyente que solo tiene que declarar su salario:

  • se calcula el número de cuotas del empleado nbParts = nbEnfants/2 + 1 si no está casado, nbEnfants/2 + 2 si está casado, donde nbEnfants es el número de hijos que tiene.
  • si tiene al menos tres hijos, cuenta con media parte adicional
  • se calcula su ingreso imponible R = 0,72 * S, donde S es su salario anual
  • se calcula su coeficiente familiar QF = R / nbParts
  • Se calcula su impuesto I. Consideremos la siguiente tabla:
12620.0
0
0
13 190
0,05
631
15640
0,1
1290,5
24 740
0,15
2072,5
31 810
0,2
3309,5
39 970
0,25
4900
48 360
0,3
6898,5
55 790
0,35
9316,5
92 970
0,4
12106
127 860
0,45
16 754,5
151 250
0,50
23 147,5
172 040
0,55
30 710
195 000
0,60
39312
0
0,65
49 062

Cada línea tiene 3 campos. Para calcular el impuesto I, se busca la primera línea en la que QF sea menor o igual que el campo 1. Por ejemplo, si QF = 23000, se encontrará la línea

    24740        0.15        2072.5

El impuesto I es entonces igual a 0,15*R - 2072,5*nbParts. Si QF es tal que la relación QF<=campo1 nunca se cumple, entonces se utilizan los coeficientes de la última línea. En este caso:

    0                0.65        49062

lo que da como resultado el impuesto I = 0,65 * R - 49062 * nbParts. El programa VB.NET correspondiente es el siguiente:


' opciones
Option Explicit On 
Option Strict On

' espacios de nombres
Imports System

Module impots
    ' ------------ principal
    Sub Main()

        ' tablas de datos necesarias para el cálculo del impuesto
        Dim Limites() As Decimal = {12620D, 13190D, 15640D, 24740D, 31810D, 39970D, 48360D, 55790D, 92970D, 127860D, 151250D, 172040D, 195000D, 0D}
        Dim CoeffN() As Decimal = {0D, 631D, 1290.5D, 2072.5D, 3309.5D, 4900D, 6898.5D, 9316.5D, 12106D, 16754.5D, 23147.5D, 30710D, 39312D, 49062D}

        ' se obtiene el estado civil
        Dim OK As Boolean = False
        Dim reponse As String = Nothing
        While Not OK
            Console.Out.Write("Etes-vous marié(e) (O/N) ? ")
            reponse = Console.In.ReadLine().Trim().ToLower()
            If reponse <> "o" And reponse <> "n" Then
                Console.Error.WriteLine("Réponse incorrecte. Recommencez")
            Else
                OK = True
            End If
        End While
        Dim Marie As Boolean = reponse = "o"

        ' número de hijos
        OK = False
        Dim NbEnfants As Integer = 0
        While Not OK
            Console.Out.Write("Nombre d'enfants : ")
            reponse = Console.In.ReadLine()
            Try
                NbEnfants = Integer.Parse(reponse)
                If NbEnfants >= 0 Then
                    OK = True
                Else
                    Console.Error.WriteLine("Réponse incorrecte. Recommencez")
                End If
            Catch
                Console.Error.WriteLine("Réponse incorrecte. Recommencez")
            End Try
        End While
        ' salario
        OK = False
        Dim Salaire As Integer = 0
        While Not OK
            Console.Out.Write("Salaire annuel : ")
            reponse = Console.In.ReadLine()
            Try
                Salaire = Integer.Parse(reponse)
                If Salaire >= 0 Then
                    OK = True
                Else
                    Console.Error.WriteLine("Réponse incorrecte. Recommencez")
                End If
            Catch
                Console.Error.WriteLine("Réponse incorrecte. Recommencez")
            End Try
        End While
        ' cálculo del número de cuotas
        Dim NbParts As Decimal
        If Marie Then
            NbParts = CDec(NbEnfants) / 2 + 2
        Else
            NbParts = CDec(NbEnfants) / 2 + 1
        End If
        If NbEnfants >= 3 Then
            NbParts += 0.5D
        End If
        ' ingreso imponible
        Dim Revenu As Decimal
        Revenu = 0.72D * Salaire

        ' coeficiente familiar
        Dim QF As Decimal
        QF = Revenu / NbParts

        ' búsqueda del tramo impositivo correspondiente a QF
        Dim i As Integer
        Dim NbTranches As Integer = Limites.Length
        Limites((NbTranches - 1)) = QF
        i = 0
        While QF > Limites(i)
            i += 1
        End While
        ' el impuesto
        Dim impots As Integer = CInt(i * 0.05D * Revenu - CoeffN(i) * NbParts)

        ' se muestra el resultado
        Console.Out.WriteLine(("Impôt à payer : " & impots))
    End Sub
End Module

El programa se compila en una ventana de DOS con:

dos>vbc impots1.vb
Compilateur Microsoft (R) Visual Basic .NET version 7.10.3052.4 pour Microsoft (R) .NET Framework version 1.1.4322.573

dos>dir impots1.exe
24/02/2004  15:42                5 632 impots1.exe

La compilación genera un ejecutable llamado impots.exe. Cabe señalar que impots.exe no es directamente ejecutable por el procesador. En realidad, contiene código intermedio que solo es ejecutable en una plataforma .NET. Los resultados obtenidos son los siguientes:

dos>impots1
Etes-vous marié(e) (O/N) ? o
Nombre d'enfants : 3
Salaire annuel : 200000
Impôt à payer : 16400
dos>impots1
Etes-vous marié(e) (O/N) ? n
Nombre d'enfants : 2
Salaire annuel : 200000
Impôt à payer : 33388
dos>impots1
Etes-vous marié(e) (O/N) ? w
Réponse incorrecte. Recommencez
Etes-vous marié(e) (O/N) ? q
Réponse incorrecte. Recommencez
Etes-vous marié(e) (O/N) ? o
Nombre d'enfants : q
Réponse incorrecte. Recommencez
Nombre d'enfants : 2
Salaire annuel : q
Réponse incorrecte. Recommencez
Salaire annuel : 1
Impôt à payer : 0

2.8. Argumentos del programa principal

El procedimiento principal Main puede aceptar como parámetro una matriz de cadenas:


    Sub main(ByVal args() As String)

El parámetro args es una matriz de cadenas de caracteres que recibe los argumentos pasados en la línea de comandos al llamar al programa.

  • args.Length es el número de elementos del array args
  • args(i) es el elemento i de la matriz

Si se ejecuta el programa P con el comando: P arg0 arg1 … argn y si el procedimiento Main del programa P está declarado de la siguiente manera:


    Sub main(ByVal args() As String)

tendremos arg(0)="arg0", arg(1)="arg1" … He aquí un ejemplo:


' directrices
Option Strict On
Option Explicit On 

' espacios de nombres
Imports System

Module arg
    Sub main(ByVal args() As String)
        ' número de argumentos
        console.out.writeline("Il y a " & args.length & " arguments")
        Dim i As Integer
        For i = 0 To args.Length - 1
            Console.Out.WriteLine("argument n° " & i & "=" & args(i))
        Next
    End Sub
End Module

La ejecución arroja los siguientes resultados:

dos>arg1 a b c
Il y a 3 arguments
argument n° 0=a
argument n° 1=b
argument n° 2=c

2.9. Las enumeraciones

Una enumeración es un tipo de datos cuyo dominio de valores es un conjunto de constantes enteras. Consideremos un programa que debe gestionar las calificaciones de un examen. Habría cinco: Aceptable, AssezBien, Bien, TrèsBien, Excelente. Entonces, podríamos definir una enumeración para estas cinco constantes:


    Enum mention
        Passable
        AssezBien
        Bien
        TrésBien
        Excellent
    End Enum

Internamente, estas cinco constantes se codifican mediante números enteros consecutivos que comienzan con 0 para la primera constante, 1 para la siguiente, etc. Se puede declarar una variable para que adopte estos valores en la enumeración:


         ' una variable que toma sus valores de la enumeración mencionada
        Dim maMention As mention = mention.Passable

Se puede comparar una variable con los distintos valores posibles de la enumeración:


         ' comparación con un valor de la enumeración
        If (maMention = mention.Passable) Then
            Console.Out.WriteLine("Peut mieux faire")
        End If

Se pueden obtener todos los valores de la enumeración:


        For Each m In mention.GetValues(maMention.GetType)
            Console.Out.WriteLine(m)
        Next

De la misma manera que el tipo simple Integer es equivalente a la estructura Int32, el tipo simple Enum es equivalente a la estructura Enum. Esta clase cuenta con un método estático GetValues que permite obtener todos los valores de un tipo enumerado que se pase como parámetro. Este debe ser un objeto de tipo Type, que es una clase que proporciona información sobre el tipo de un dato. El tipo de una variable v se obtiene mediante v.GetType(). Por lo tanto, aquí maMention.GetType() devuelve el objeto Type de la enumeración mentions y Enum.GetValues(maMention.GetType()) la lista de valores de la enumeración mentions.

Esto es lo que muestra el siguiente programa:


' directivas
Option Strict On
Option Explicit On 

' espacios de nombres
Imports System

Public Module enum2

    ' una enumeración
    Enum mention
        Passable
        AssezBien
        Bien
        TrèsBien
        Excellent
    End Enum

    ' página de prueba
    Sub Main()

        ' una variable que toma sus valores de la enumeración mencionada
        Dim maMention As mention = mention.Passable

        ' visualización del valor de la variable
        Console.Out.WriteLine("mention=" & maMention)

        ' prueba con el valor de la enumeración
        If (maMention = mention.Passable) Then
            Console.Out.WriteLine("Peut mieux faire")
        End If

        ' lista de menciones literales
        For Each m As mention In [Enum].GetValues(maMention.GetType)
            Console.Out.WriteLine(m.ToString)
        Next

        ' lista de menciones completas
        For Each m As Integer In [Enum].GetValues(maMention.GetType)
            Console.Out.WriteLine(m)
        Next
    End Sub
End Module

Los resultados de la ejecución son los siguientes:

dos>enum2
mention=0
Peut mieux faire
Passable
AssezBien
Bien
TrèsBien
Excellent
0
1
2
3
4

2.10. Manejo de excepciones

Muchas funciones de VB.NET pueden generar excepciones, es decir, errores. Cuando una función puede generar una excepción, el programador debe manejarla con el objetivo de lograr programas más resistentes a los errores: siempre hay que evitar que una aplicación se «cuelgue» de manera inesperada.

La gestión de una excepción se realiza según el siguiente esquema:

try
    appel de la fonction susceptible de générer l'exception
catch  e as Exception e)
    traiter l'exception e
end try
instruction suivante

Si la función no genera una excepción, se pasa a la siguiente instrucción; de lo contrario, se pasa al cuerpo de la cláusula catch y luego a la siguiente instrucción. Tenga en cuenta lo siguiente:

  • e es un objeto derivado del tipo Exception. Se puede ser más preciso utilizando tipos como IOException, SystemException, etc.: existen varios tipos de excepciones. Al escribir catch e as Exception, se indica que se desea manejar todos los tipos de excepciones. Si el código de la cláusula try puede generar varios tipos de excepciones, es posible que se desee ser más preciso manejando la excepción con varias cláusulas catch:
try
    appel de la fonction susceptible de générer l'exception
catch e as IOException 
    traiter l'exception e
catch  e as SystemException
    traiter l'exception e
end try
instruction suivante
  • Se puede agregar una cláusula «finally» a las cláusulas try/catch:
try
    appel de la fonction susceptible de générer l'exception
catch  e as Exception
    traiter l'exception e
finally
    code exécuté après try ou catch
end try
instruction suivante

Independientemente de si hay una excepción o no, el código de la cláusula finally siempre se ejecutará.

  • En la cláusula catch, es posible que no se desee utilizar el objeto Exception disponible. En lugar de escribir catch e as Exception, se escribe catch.
  • La clase Exception tiene una propiedad Message que contiene un mensaje con detalles del error que se produjo. Por lo tanto, si se desea mostrar este mensaje, se escribirá:
catch e as Exception
    Console.Error.WriteLine("L'erreur suivante s'est produite : "+e.Message);
    ...
end try
  • La clase Exception cuenta con un método ToString que devuelve una cadena de caracteres que indica el tipo de la excepción, así como el valor de la propiedad Message. De esta manera, se puede escribir:
catch  ex as Exception
    Console.Error.WriteLine("L'erreur suivante s'est produite : "+ex.ToString)
    ...
end try

El siguiente ejemplo muestra una excepción generada al utilizar un elemento de la tabla que no existe:


' opciones
Option Explicit On 
Option Strict On

' espacios de nombres
Imports System

Module tab1
    Sub Main()
        ' declaración e inicialización de un array
        Dim tab() As Integer = {0, 1, 2, 3}
        Dim i As Integer

        ' visualización de una matriz con un «for»
        For i = 0 To tab.Length - 1
            Console.Out.WriteLine(("tab[" & i & "]=" & tab(i)))
        Next i

        ' Visualización de un array con un for each
        Dim élmt As Integer
        For Each élmt In tab
            Console.Out.WriteLine(élmt)
        Next élmt

        ' generación de una excepción
        Try
            tab(100) = 6
        Catch e As Exception
            Console.Error.WriteLine(("L'erreur suivante s'est produite : " & e.Message))
        End Try
    End Sub
End Module

La ejecución del programa arroja los siguientes resultados:

dos>exception1
tab[0]=0
tab[1]=1
tab[2]=2
tab[3]=3
0
1
2
3
L'erreur suivante s'est produite : L'index se trouve en dehors des limites du tableau.

Aquí hay otro ejemplo en el que se maneja la excepción provocada por la asignación de una cadena de caracteres a un número cuando la cadena no representa un número:


' opciones
Option Strict On
Option Explicit On 

'importaciones
Imports System

Public Module console1
  Public Sub Main()
    ' Se solicita el nombre
    System.Console.Write("Nom : ")

        ' lectura de la respuesta
    Dim nom As String = System.Console.ReadLine()

        ' Se solicita la edad
    Dim age As Integer
    Dim ageOK As Boolean = False
    Do While Not ageOK
      ' pregunta
      Console.Out.Write("âge : ")
      ' lectura y verificación de la respuesta
      Try
        age = Int32.Parse(System.Console.ReadLine())
        If age < 0 Then Throw New Exception
        ageOK = True
      Catch
        Console.Error.WriteLine("Age incorrect, recommencez...")
      End Try
    Loop

        ' pantalla final
    Console.Out.WriteLine("Vous vous appelez [" & nom & "] et vous avez [" & age & "] ans")
  End Sub
End Module

Algunos resultados de la ejecución:

dos>console1
Nom : dupont
âge : 23
Vous vous appelez dupont et vous avez 23 ans
dos>console1
Nom : dupont
âge : xx
Age incorrect, recommencez...
âge : 12
Vous vous appelez dupont et vous avez 12 ans

2.11. Paso de parámetros a una función

Aquí nos enfocamos en cómo se pasan los parámetros a una función. Consideremos la función:


    Sub changeInt(ByVal a As Integer)
        a = 30
        Console.Out.WriteLine(("Paramètre formel a=" & a))
    End Sub    

En la definición de la función, a se denomina parámetro formal. Solo está ahí para los fines de la definición de la función changeInt. También podría haberse llamado b. Veamos ahora un ejemplo de uso de esta función:


    Sub Main()
        Dim age As Integer = 20
        changeInt(age)
        Console.Out.WriteLine(("Paramètre effectif age=" & age))
    End Sub

Aquí, en la instrucción changeInt(edad), age es el parámetro efectivo que transmitirá su valor al parámetro formal a. Nos interesa saber cómo un parámetro formal recupera el valor del parámetro efectivo que le corresponde.

2.11.1. Paso por valor

El siguiente ejemplo nos muestra que los parámetros de una función o procedimiento se pasan por defecto por valor: es decir, el valor del parámetro efectivo se copia en el parámetro formal correspondiente. Se trata de dos entidades distintas. Si la función modifica el parámetro formal, el parámetro efectivo no se ve modificado en absoluto.


' opciones
Option Explicit On 
Option Strict On

' paso de parámetros por valor a una función
Imports System

Module param1
    Sub Main()
        Dim age As Integer = 20
        changeInt(age)
        Console.Out.WriteLine(("Paramètre effectif age=" & age))
    End Sub

    Sub changeInt(ByVal a As Integer)
        a = 30
        Console.Out.WriteLine(("Paramètre formel a=" & a))
    End Sub
End Module

Los resultados obtenidos son los siguientes:

Paramètre formel a=30
Paramètre effectif age=20

El valor 20 del parámetro efectivo se copió en el parámetro formal a. Este último se modificó posteriormente. El parámetro efectivo, por su parte, permaneció sin cambios. Este modo de paso es adecuado para los parámetros de entrada de una función.

2.11.2. Pase por referencia

En un paso por referencia, el parámetro efectivo y el parámetro formal son una misma entidad. Si la función modifica el parámetro formal, el parámetro efectivo también se modifica. En VB.NET, el parámetro formal debe ir precedido de la palabra clave ByRef. A continuación se muestra un ejemplo:


' opciones
Option Explicit On 
Option Strict On

' paso de parámetros por valor a una función
Imports System

Module param2
    Sub Main()
        Dim age As Integer = 20
        changeInt(age)
        Console.Out.WriteLine(("Paramètre effectif age=" & age))
    End Sub

    Sub changeInt(ByRef a As Integer)
        a = 30
        Console.Out.WriteLine(("Paramètre formel a=" & a))
    End Sub
End Module

y los resultados de la ejecución:

Paramètre formel a=30
Paramètre effectif age=30

El parámetro efectivo se ha actualizado tras la modificación del parámetro formal. Este modo de paso es adecuado para los parámetros de salida de una función.