You are on page 1of 26

Clcul Digital Aplicat

Mtodes Matemtics
Curs 2012-2013

IQS, J .J .Molins, CDA-MM. Curso 2012-2013. Fundamentos de Programacin en Visual Basic 2010 1
Microsoft

Visual Basic 2010 Express


Fundamentos de Programacin en Visual Basic 2010
Este documento pretende ser una gua bsica de programacin para desarrollar aplicaciones en Microsoft


Visual Basic 2010 y por tanto se va a centrar en la escritura correcta de cdigo.
Se supone que el alumno ya est familiarizado con el diseo de formularios y cmo se incluyen controles en
stos. En el documento referido a controles se describen cules estn disponibles en esta versin del
programa y cul es su utilidad. Por tanto se parte de que el alumno ya conoce cmo ejecutar un programa,
bien pulsando un elemento de un men, bien activando un evento de uno de los controles situados en el
formulario, como puede ser pulsar un botn de comando.
Por tanto, se parte de una aplicacin en la que se ha completado la fase de diseo y se ha de incluir el
cdigo para que funcione correctamente.
Escritura de cdigo en una aplicacin
Seguidamente se va a empezar a escribir cdigo para observar cmo se declaran las variables, cmo se
modifican propiedades de controles en cdigo, cmo se ejecutan mtodos y cmo se llama a eventos.
La primera etapa que se va a explicar es escribir el cdigo para poder finalizar la aplicacin. Para ello, se
activa la ventana de cdigo correspondiente al formulario se pulsa la lista desplegable que aparece en la
parte izquierda. Tal como se puede apreciar aparece una lista con todos los controles incluidos en el
formulario con su nombre correspondiente, la referencia al formulario, y la palabra (GENERAL), que hace
alusin al cdigo que no est vinculado a un objeto especfico.

2 IQS, J .J .Molins, CDA-MM. Curso 2012-2013. Fundamentos de Programacin en Visual Basic 2010
Cdigo para finalizar una aplicacin
Normalmente, en una aplicacin siempre se incluye un botn o una opcin de men que permite finalizar el
programa. En este caso, si hay una opcin de men denominada mnuSalir que tiene como objetivo finalizar
la aplicacin, se selecciona. A continuacin se despliega la lista de la parte derecha en la que aparecen todos
los eventos posibles que se pueden producir con el elemento del men.

Como se puede observar en la figura, Microsoft

Visual Basic rellena automticamente el cdigo que hace


referencia al encabezado del evento CLICK, que corresponde a pulsar el botn principal del ratn sobre el
elemento del men. ste es el evento predefinido para este tipo de control, sin embargo se puede apreciar
que se dispone de un nmero considerable de eventos tal como aparece en la lista desplegable, aunque los
que se van a emplear en la asignatura van a ser bsicamente aqullos que realicen una accin, como
efectuar un clculo numrico, y no los que se emplean en el diseo de las aplicaciones.
Una vez seleccionado el evento CLICK se puede escribir el cdigo siguiente:

Si se ejecuta la aplicacin, tras guardar los cambios, y se pulsa sobre el elemento de men mnuSalir se
observa que se cierra el formulario y que finaliza la aplicacin. Como es lgico, en todos los proyectos
siempre se debe incluir un botn de comando o una opcin de men que permita salir del formulario.
Se puede observar que el texto escrito tras el apstrofe est en un color diferente al del resto de la lnea.
Ello es debido a que este texto es un comentario, no es cdigo de Microsoft

Visual Basic 2010. Conviene


aadir comentarios a lo largo del cdigo que clarifiquen el propsito del mismo, especialmente en algoritmos
complejos.
IQS, J .J .Molins, CDA-MM. Curso 2012-2013. Fundamentos de Programacin en Visual Basic 2010 3
Declaracin de variables y constantes
En primer lugar, en cualquier cdigo que se desarrolle, se deben haber declarado las variables y constantes
con las que se trabaja. Si se ha configurado correctamente Microsoft

Visual Basic 2010 est activada la


opcin OPTION EXPLICIT que obliga a que todas las variables y constantes se declaren explcitamente, activada
tambin la opcin OPTION STRICT y desactivada la opcin OPTION INFER.
Si en algn momento de la ejecucin aparece un mensaje como el siguiente en la lista de errores, indica que
una variable no se ha declarado. La aplicacin resalta qu variable es, y el programador debe declarar dicha
variable en el lugar correspondiente, si no la ha declarado, o bien, si se trata de un error tipogrfico porque
ha escrito mal la variable, rectificarlo.

Adems el programa incorpora una serie de ayudas visuales cuando se desarrolla el cdigo que son de gran
utilidad para prevenir los errores.

Para declarar una variable o constante se debe tener en cuenta los siguientes aspectos
Si es una variable o una constante
El tipo de dato que ha de contener
El mbito de validez
Cuando se declara una variable o constante, deben especificarse claramente todos estos aspectos. Las
declaraciones de variables o constantes siempre se efectan en el inicio del procedimiento o del mdulo en
el que se utilicen o en el caso de variables empleadas nicamente en bucles al inicio de stos.
Variable o constante
Como su nombre indica, una variable contiene informacin que puede modificarse a lo largo del programa, o
entre ejecuciones diferentes del programa. As, las dimensiones de una matriz pueden no cambiar a lo largo
de la ejecucin de un programa pero, si se cambia el problema es probable que las dimensiones sean
diferentes. Por ello, las dimensiones de esa matriz se declararn como variables.
Una constante es un valor que no va a modificarse nunca. Ejemplos de constantes seran el nmero e o el
nmero , el lmite de precisin admisible en un mtodo numrico, el nmero mximo de iteraciones
permitidas, etc. En todos estos casos, los valores no cambian a lo largo de un problema ni al resolver
problemas diferentes. La palabra clave que permite especificar que es una constante es Const.
4 IQS, J .J .Molins, CDA-MM. Curso 2012-2013. Fundamentos de Programacin en Visual Basic 2010
Microsoft

Visual Basic 2010 en su librera matemtica (Math) incluye los valores de las dos constantes
matemticas ms empleadas, mencionadas previamente, e y . Se presenta en la siguiente lnea cmo se
puede acceder a dichos valores en una lnea de cdigo, junto a algunas funciones matemticas.
valor = Math.Cos(2.0 * Math.PI * frec * t)
numero = Math.Log10(Math.E)
Tipo de dato
Una variable o constante debe de estar asociada siempre a un tipo de dato. Es obligatorio, al declarar una
variable o constante, especificar qu tipo de dato contiene. Los tipos de datos ms habituales en la
resolucin de problemas numricos son los siguientes:
VALORES ENTEROS
Segn el margen de valores que se vayan a emplear se dispone de tres tipos de datos:
Short (2 bytes): Admite valores de -32 768 a 32 767
Integer (4 bytes): Admite valores de -2 147 483 648 a 2 147 483 647.
Long (8 bytes): Admite valores de -9 223 372 036 854 775 808 y 9 223 372 036 854 775 807
Las operaciones con nmeros enteros que devuelven nmeros enteros no tienen asociado error de
redondeo. Adems las operaciones con nmeros enteros son ms rpidas que con otro tipo de
datos. El tipo de valor entero que se va a emplear habitualmente es Integer.
VALORES EN COMA FLOTANTE
Segn el margen de valores que se vayan a emplear se dispone de dos tipos de datos:
Single (4 bytes): El margen de valores va de -3,4028235E+38 a -1,401298E-45 para valores
negativos, de 1,401298E-45 a 3,4028235E+38 para valores positivos y el cero.
Double (8 bytes): Los valores van de -1,79769313486231570E+308 a -4,94065645841246544E-324
para nmeros negativos, de 4,94065645841246544E-324 a 1,79769313486231570E+308 para valores
positivos y el cero.
El tipo de valor en coma flotante que se va a emplear habitualmente es Double.
VALORES DE CADENA DE TEXTO
String (el nmero de bytes depende de la longitud de la cadena).
VALORES LGICOS
Boolean (2 bytes): nicamente puede contener valores de S o No (True o False).
mbito de validez
Una variable o constante tiene asociado un mbito de validez, es decir, en qu lugar de cdigo se puede
emplear dicha variable o constante. Existen tres mbitos de validez:
PROCEDIMIENTO O LOCAL: El mbito de validez est restringido al de la rutina en la que se encuentran
declaradas. Es la mejor opcin, ya que as se evitan problemas de modificacin del valor de las
variables en diferentes lugares del cdigo, lo que hara muy difcil la depuracin de errores. Se pueden
emplear los mismos nombres de las variables en rutinas diferentes sin que haya que tener ninguna
precaucin especial.
Existen dos variantes de variables locales. La forma normal es declarar una variable mediante la
palabra Dim. En este caso, cada vez que se llama al procedimiento en Visual Basic se inicializa la
variable (si es una variable numrica se pone a cero, si es una cadena de texto es la cadena vaca y si
es una variable booleana su valor es FALSE), a no ser que se especifique directamente otro valor.
IQS, J .J .Molins, CDA-MM. Curso 2012-2013. Fundamentos de Programacin en Visual Basic 2010 5
Si la variable se declara mediante la sentencia Static, indica que la variable es esttica. Eso quiere
decir que al acabar de ejecutar el procedimiento la variable permanece residente en memoria y al
llamar de nuevo al procedimiento sigue manteniendo su ltimo valor.
MDULO: En este caso el valor de la variable o constante es accesible en todos los procedimientos que
se incluyen en el formulario o mdulo en el que se trabaja. nicamente se deben declarar como
variables de mdulo aquellas que compartan informacin entre diferentes procedimientos
de evento. La palabra clave que se emplea para declarar una variable de mdulo es Private.
GLOBAL: Su mbito de validez es para todo el proyecto, o sea se puede utilizar y modificar en cualquier
procedimiento de la aplicacin. Se debe evitar su uso, salvo en casos muy justificados. La palabra
clave que se emplea para declarar una variable global es Public.
Por tanto, hay que dejar bien claro, respecto al mbito de validez de las variables que, siempre que sea
posible, lo mejor es definirlas como de procedimiento (locales). En el caso de que haya variables cuyo valor
se deba compartir por diferentes eventos (y nicamente en este caso) de un formulario se deben definir
como variables de mdulo. Las variables globales tienen que ser de uso muy restringido y, por tanto, no es
en absoluto recomendable su uso ya que la depuracin de errores se complica enormemente.
Ejemplos de declaraciones de variables y constantes
VARIABLES Y CONSTANTES LOCALES O DE PROCEDIMIENTO
Dentro de un procedimiento, y justo despus del encabezado iran las declaraciones:
Private Sub Procedimiento()
Const EPS As Double = 0.0000001 'Declaracin de una constante
Dim valor1 As Integer 'Declaracin de un nmero entero
Dim valor1a As Integer = 165 'Nmero entero con valor inicial
Static valor2 As Double 'Declaracin de una variable esttica
Static valor2a As Double = 1.0 'Variable esttica con valor inicial
Se pueden declarar varias variables en la misma lnea con su correspondiente tipo de datos
Dim valor As Integer, i As Integer, texto As String
Sin embargo en Microsoft

Visual Basic 2010 se pueden definir las variables sin poner al lado su tipo de
datos ya que toman el tipo de datos correspondiente al que aparece despus de la primera variable a la que
se le asigna uno. As en la siguiente lnea de cdigo
Dim valor, i As Integer, texto As String
la primera variable, valor es de tipo INTEGER al igual que la segunda, i, que tambin lo es. Lo normal es
separar las variables por tipo y definir en lneas separadas los tipos de datos diferentes.
VARIABLES Y CONSTANTES DE MDULO
Estas variables o constantes se deben declarar en la seccin DECLARACIONES del apartado (GENERAL) del
cdigo del formulario o mdulo en donde se declaren.
Private Const EPS As Double = 0.00000000000001 'Declaracin de una constante
Private valorModulo As Integer 'Declaracin de una variable
La palabra Private que aparece al declarar la variable o constante hace referencia a que tiene un mbito
de validez privado de dicho mdulo (o formulario), con lo que los procedimientos exteriores a dicho mdulo
o formulario no pueden acceder a dicho valor.
6 IQS, J .J .Molins, CDA-MM. Curso 2012-2013. Fundamentos de Programacin en Visual Basic 2010
Es posible que haya variables, por ejemplo un contador como puede ser la variable i, que aparezcan en ms
de un procedimiento del mdulo (o formulario). Hay que tener claro que no se deben definir como
variables de mdulo ya que en cada procedimiento tienen un valor especfico que no debe compartirse
con otros procedimientos, por tanto se deben declarar siempre como variables locales y no de mdulo.
VARIABLES Y CONSTANTES GLOBALES
Las variables globales nicamente se pueden declarar en la seccin DECLARACIONES de (GENERAL) en un
mdulo de cdigo (Module con nombre de archivo *.vb). Si se realiza en un formulario, Visual Basic
generar automticamente un error como dicha variable aparezca en cualquier otro elemento. Para que eso
no suceda, debe incluirse en un mdulo de cdigo.
Public Const EPS As Double = 0.00000000000001 'Declaracin de una constante
Public final As Boolean 'Declaracin de una variable booleana global
Public numDades As Long 'Declaracin de una variable entera global
CONSIDERACIONES SOBRE DECLARACIONES DE VARIABLES Y CONSTANTES
Hay que tener clara la prioridad a la hora de definir el mbito de validez de las variables. La mayor prioridad
es la de las variables locales o de procedimiento, a continuacin las de mdulo y por ltimo las globales. Sin
embargo, como ya se ha comentado anteriormente, el uso de variables de mdulo y, en especial, globales
se debe restringir al mximo para evitar problemas de interferencias entre valores de variables.
Existen una serie de directrices a la hora de declarar variables y constantes.
En una aplicacin de Visual Basic, las variables pblicas o globales se deben usar slo cuando no exista
ninguna otra forma cmoda de compartir datos entre formularios. Cuando haya que usar variables
globales, es conveniente declararlas todas en un nico mdulo agrupadas por funciones y dar al mdulo
un nombre significativo que indique su finalidad, como PUBLIC.VB.
Una variable tiene alcance global si se declara como PUBLIC en un mdulo. Una variable tiene alcance de
nivel de mdulo si se declara como PRIVATE en un mdulo o en un formulario, respectivamente.
Constantes
El cuerpo del nombre de las constantes se debe escribir en maysculas con las palabras separadas por el
carcter subrayado. Por ejemplo:
MAX_I TERACI ONES Nmero mximo de iteraciones
LI MI TE_ERROR Valor lmite del error de clculo de un mtodo numrico
Variables
El cuerpo de un nombre de variable se debe iniciar en minscula y debe tener la longitud necesaria para
describir su funcionalidad. Si est formado por ms de una palabra, las siguientes deben empezar por
maysculas. Por ejemplo:
numer oDat os
val or Fi nal
Para nombres que se usen con frecuencia o para trminos largos, se recomienda usar abreviaturas
estndar para que los nombres tengan una longitud razonable. En general, los nombres de variables con
ms de 32 caracteres pueden ser difciles de leer.
Cuando se usen abreviaturas, hay que asegurarse de que sean coherentes en toda la aplicacin. Alternar
aleatoriamente entre CNT y CONTAR dentro de un proyecto provoca una confusin innecesaria.
IQS, J .J .Molins, CDA-MM. Curso 2012-2013. Fundamentos de Programacin en Visual Basic 2010 7
Vectores y matrices
Visual Basic permite definir variables que contengan varios valores del mismo tipo de dato. De esta manera
se puede manipular de forma eficiente vectores y matrices. Para acceder a uno de los valores de dicha
matriz o vector, basta nicamente especificar el ndice correspondiente y el sistema accede directamente a
dicho valor. Todo lo explicado previamente en cuanto a variables es aplicable a los vectores o matrices.
Para declarar un vector se indica con el nombre de la variable y a continuacin un parntesis abierto y otro
cerrado. En el caso de una matriz, como tiene ms de un ndice, hay que incluir una coma entre los
parntesis para cada nuevo ndice que incluya. As, una matriz de dos ndices se indica con un parntesis
abierto, una coma y un parntesis cerrado tal como se muestra en la instruccin siguiente.
Dim matriz(,) As Double, texto() As String 'matriz: 2 ndices; texto(): 1 ndice
Antes de asignar valores a un vector o matriz es necesario especificar sus dimensiones. Si las dimensiones
son funcin de variables, ya que pueden cambiar entre ejecuciones, la matriz se puede declarar en funcin
de dichas dimensiones.
Dim matriz(n, m) As Double, texto(nPalabras) As String
Sin embargo, es posible que dentro del mismo procedimiento, en ocasiones, se deba cambiar las
dimensiones. En este caso se emplea la instruccin REDIM, tal como se muestra a continuacin. Al efectuar
una instruccin REDIM se inicializan todos los valores de la matriz.
ReDim matriz(0 To n, 0 To m), texto(nPalabras)
En el primer tipo de declaracin se indican el lmite de los ndices, entre 0 y n el primero y entre 0 y m el
segundo. En el segundo caso nicamente se indica el lmite superior, nPalabras. En Visual Basic 2010 el
valor inferior del ndice para todos los vectores o matrices es siempre 0, por tanto en este segundo
caso los elementos del vector texto son los comprendidos entre 0 y nPalabras, y por tanto el nmero de
elementos del vector es de nPalabras+1. Normalmente no se especifican los dos lmites en vectores
y matrices ya que es reiterativo.
En algunas ocasiones puede que no se conozca a priori el nmero de elementos que debe contener un
vector o matriz, ya que es posible que se lean desde un archivo del que se desconoce el nmero de datos
que contiene. En estos casos si se va cambiando la dimensin de la matriz o vector se debe evitar perder los
valores ya incluidos en el vector o matriz. Para ello se debe incluir la palabra clave PRESERVE despus de la
instruccin REDIM.
ReDim Preserve matriz(n, m), texto(nPalabras)
Se debe de tener en cuenta que con la palabra clave Preserve nicamente se puede cambiar el valor
del ltimo ndice de la matriz. En un vector no representa ningn problema, pero en el caso de una matriz
nicamente podr variarse el segundo ndice, no el primero. En caso de que se intentara modificar los lmites
del primer ndice se generara un error en tiempo de ejecucin.
En algunos casos algunas matrices pueden tener un nmero de dimensiones fijas, y que no cambie en
distintas ejecuciones. Este tipo de matrices, denominadas estticas se pueden declarar directamente con sus
dimensiones, que no se podrn modificar cuando se ejecute el programa. Un ejemplo podra ser la
declaracin de una matriz que contenga un tablero de un Sudoku que tiene un nmero fijo de filas y
columnas (9x9). En este caso se podra declarar la matriz tal como se muestra en la siguiente instruccin.
Dim matrizSudoku(8, 8) As Integer
8 IQS, J .J .Molins, CDA-MM. Curso 2012-2013. Fundamentos de Programacin en Visual Basic 2010
Inicializacin de valores en matrices
Para asignar valores a vectores y matrices es posible efectuarlo o bien igualando elemento a elemento de la
matriz o vector al valor deseado o en Visual Basic 2010 es posible inicializar los valores que contiene un
vector o matriz de la siguiente manera que es mucho ms cmoda de escribir en cdigo.
Dim a(,) As Double = {{1.5, 3.2, -4.5}, {-3.2, 4.1, 6.0}} 'Matriz (2x3)
Dim ncoef() As Integer = {1, 3, 2, -4, 5, -3, -2, 4, 1, 6, 0} 'Vector de 11 elementos
En este caso no se indican las dimensiones de la matriz o vector ya que directamente a partir de la
asignacin de valores el sistema obtiene las correspondientes dimensiones.
Estructuras
En ciertas ocasiones, el programador debe poder trabajar con algn tipo de variable que no se encuentra
disponible en los tipos de datos del lenguaje de programacin. En Visual Basic es posible crear estructuras
que permiten una mayor flexibilidad al lenguaje. Un ejemplo sera crear una estructura que permitiera
trabajar con nmeros complejos.
Las estructuras se deben incluir en la seccin de declaraciones de un mdulo (*.vb), no un formulario, de la
forma siguiente.

Public Structure Complex
Public r As Double
Public i As Double

Public Sub New(ByVal re As Double, ByVal im As Double)
Me.r = re
Me.i = im
End Sub

Public Sub New(ByVal re As Double)
Me.r = re
Me.i = 0.0
End Sub

Public Sub New(ByVal Number As Complex)
Me.r = Number.r
Me.i = Number.i
End Sub

Public Overrides Function ToString() As String
If Me.i < 0.0 Then
Return Me.r & " " & Me.i & " i"
Else
Return Me.r & " +" & Me.i & " i"
End If
End Function

Public Shared Function Real(ByVal a As Complex) As Double
Return a.r
End Function

Public Shared Function Imag(ByVal a As Complex) As Double
Return a.i
End Function

IQS, J .J .Molins, CDA-MM. Curso 2012-2013. Fundamentos de Programacin en Visual Basic 2010 9

Se puede observar que es posible definir la operacin suma entre nmeros complejos, e igualmente la resta,
el producto, la divisin, operaciones entre nmeros reales y complejos, el mdulo de un nmero complejo,
etc. Una vez definida la estructura se pueden declarar variables o constantes, crear matrices o vectores
exactamente igual que si fuera cualquier otro tipo de dato.
Dim variableCompleja As Complex
Se pueden asignar valores y se pueden operar como si fuera cualquier otra variable.
variableCompleja = New Complex(5.0)
resultado = Math.Atan(Complex.Imag(variableCompleja) / Complex.Real(variableCompleja))
variableCompleja += New Complex(5.0, 5.0)
Public Shared Function Polar(ByVal modulus As Double,
ByVal argument As Double) As Complex
Return New Complex(modulus * Math.Cos(argument), modulus * Math.Sin(argument))
End Function

Public Shared Operator +(ByVal a As Complex, ByVal b As Complex) As Complex
Return New Complex(a.r + b.r, a.i + b.i)
End Operator



End Structure
10 IQS, J .J .Molins, CDA-MM. Curso 2012-2013. Fundamentos de Programacin en Visual Basic 2010
Estructuras de control
ESTRUCTURAS DE SELECCIN
Estructura IfThenElseIfElseEnd If
ESTRUCTURA SIMPLE
La primera estructura de seleccin es la que se presenta a continuacin.
If Condicion Then
Instrucciones
End If
Tal como se puede apreciar, cada vez que Condicion sea cierto se realizarn una serie de Instrucciones,
mientras que en caso contrario, no se har nada. Condicion puede ser una variable booleana, el resultado
de una expresin lgica, un valor devuelto por una funcin o incluso el valor de una variable, que se deber
convertir en valor booleano. Cualquier valor que haya se debe transformar, si no lo es, en una variable de
tipo booleano, teniendo en cuenta que si corresponde a una variable numrica, si es cero se transforma en
FALSE y cualquier otro valor corresponder a un valor TRUE. En funcin de dicho resultado se ejecutan o no
las correspondientes instrucciones.
ESTRUCTURA DOBLE
Se puede complicar algo ms la estructura IFTHEN aadiendo que efecte otras instrucciones en caso de
que la condicin sea falsa. As, la estructura doble queda de la siguiente manera.
If Condicion Then
Instrucciones_1
Else
Instrucciones_2
End If
En este caso si Condicion es cierta ejecuta Instrucciones_1, mientras que en caso contrario se ejecuta
Instrucciones_2.
ESTRUCTURA MLTIPLE
Por ltimo, en este caso la estructura mltiple permite seleccionar una opcin entre varias posibles, segn el
caso en que la condicin sea cierta. En este caso el sistema ejecutar la primera condicin que sea cierta, y
no comprobar el resto de condiciones, an en el hipottico caso de que stas tambin fueran ciertas.
If Condicion1 Then
Instrucciones_1
ElseIf Condicion2 Then
Instrucciones_2
ElseIf Condicion3 Then
Instrucciones_3
Else
Instrucciones_n
End If
Si ninguna de las condiciones fuera cierta, se ejecutaran las Instrucciones_n, que corresponden al caso
de la opcin Else.
IQS, J .J .Molins, CDA-MM. Curso 2012-2013. Fundamentos de Programacin en Visual Basic 2010 11
Estructura Select CaseCaseCase ElseEnd Select
La estructura SELECT CASE es una estructura en la que se compara un valor de referencia, en el caso
presentado Valor, con diferentes opciones. En el momento en que se cumpla la condicin, se ejecutar el
cdigo correspondiente y se continuar la ejecucin a partir del final de la estructura. Eso quiere decir que
se ejecutar siempre la primera condicin que sea cierta. A diferencia de la estructura IF vista
anteriormente, el valor con el que se comparan las condiciones en una estructura SELECT CASE es siempre el
mismo.
Select Case Valor
Case Caso_1
Instrucciones_1
Case Caso_2
Instrucciones_2
Case Caso_3
Instrucciones_3
Case Else
Instrucciones_n
End Select
Si no se cumple que Valor corresponde a alguno de los casos Caso_1, Caso_2 o Caso_3, se ejecutarn las
instrucciones incluidas en la opcin Else.
ESTRUCTURAS DE REPETICIN
Estructura ForNext
Las estructuras de repeticin FOR...NEXT se emplean cuando se conoce el nmero de veces que se debe
repetir las instrucciones que contiene. Ello implica que el contador que se utiliza para saber cuntas veces se
ha ejecutado el bucle debe ser un nmero entero, ya que en caso contrario no se puede asegurar que la
estructura se ejecute un nmero correcto de veces.
Dim i, numMaximo As Integer

...
For i = 1 To numMaximo
Instrucciones
Next
En este caso el cdigo contenido en Instrucciones se ejecuta el nmero de veces que contenga la variable
numMaximo. El paso, si no se especifica lo contrario, es de uno en uno. En caso de que sea diferente, es
necesario especificarlo aadiendo al final de la lnea que contiene el FOR la expresin STEP junto con el
tamao del paso.
La siguiente estructura FOR...NEXT sera incorrecta, ya que no cumple con los requerimientos explicados
Dim i, numMaximo As Double

...
For i = 1 To numMaximo / 10 Step 0.1
Instrucciones_1
Next
En este caso, el nmero de veces que se ejecutar Instrucciones_1 no tiene porqu corresponder al
indicado en la variable numMaximo por problemas de redondeo. Por tanto, debe quedar claro, que los bucles
FORNEXT se deben realizar siempre con variables de tipo entero (SHORT, INTEGER o LONG y de las tres,
preferiblemente con INTEGER, ya que es en con la que se ejecuta ms rpidamente), nunca con valores
SINGLE o DOUBLE. Si se necesita calcular valores en coma flotante de simple o doble precisin, se debe
12 IQS, J .J .Molins, CDA-MM. Curso 2012-2013. Fundamentos de Programacin en Visual Basic 2010
evaluar a partir de la variable contador, mediante una adecuada conversin del valor, utilizando operaciones
o funciones disponibles en Visual Basic.
Adems, se debe tener en cuenta que dentro de una estructura FOR...NEXT, no se debe variar el valor de la
variable contador, en este caso la variable i, ni el lmite de las iteraciones, numMaximo.
Otra consideracin importante es que si el paso del contador es positivo y el lmite final del contador es
menor que el inicial, o bien el paso del contador es negativo y el lmite final del contador es mayor que el
inicial, no se ejecutarn nunca las instrucciones que se encuentran dentro del bucle FOR...NEXT.
Estructuras DoLoop
Existen cuatro variantes de estructuras DO...LOOP en Visual Basic. Todas ellas se emplean cuando se
desconoce a priori el nmero de iteraciones que se van a realizar en un procedimiento, como es el caso de
algoritmos numricos de tipo iterativo.
Do While Condicion
Instrucciones
Loop
En este caso mientras Condicion sea cierta se ejecutarn las Instrucciones. Como ya se ha comentado
anteriormente, Condicion puede ser una variable booleana, el resultado de una expresin lgica, un valor
devuelto por una funcin o incluso el valor de una variable, que se deber convertir en valor booleano.
Cualquier valor que haya se debe transformar en una valor de tipo booleano, teniendo en cuenta que si
corresponde a una variable numrica, si es cero se transforma en FALSE y cualquier otro valor corresponder
a un valor TRUE. En funcin de dicho resultado se ejecutan o no las correspondientes instrucciones.
Do Until Condicion
Instrucciones
Loop
Este caso es equivalente al anterior, slo que mientras Condicion sea falso se ejecutarn las
Instrucciones. En estos dos casos descritos es posible que Instrucciones no se ejecuten nunca porque
como se evala la Condicion al inicio segn el resultado obtenido puede saltar directamente al final de la
estructura.
Do
Instrucciones
Loop While Condicion
En este caso, Instrucciones se repetirn mientras Condicion sea cierta.
Do
Instrucciones
Loop Until Condicion
Este caso es equivalente al anterior, slo que Instrucciones se repetir mientras Condicion sea falsa. En
estos dos ltimos casos Instrucciones se ejecutar al menos una vez, ya que Condicion se evala al final
de la estructura.
Estructura WhileEnd While
Existe otra estructura que se puede emplear en Visual Basic cuando se desconoce a priori el nmero de
iteraciones que se van a realizar en un procedimiento.
While Condicion
Instrucciones
End While
IQS, J .J .Molins, CDA-MM. Curso 2012-2013. Fundamentos de Programacin en Visual Basic 2010 13
Este caso es equivalente a la primera de las variantes vista de la estructura DO...LOOP. Mientras Condicion
sea cierta se ejecutarn las Instrucciones. Condicion puede ser una variable booleana, el resultado de
una expresin lgica, un valor devuelto por una funcin o incluso el valor de una variable, que se deber
convertir en valor booleano. Cualquier valor que haya se debe transformar en una valor de tipo booleano,
teniendo en cuenta que si corresponde a una variable numrica, si es cero se transforma en FALSE y
cualquier otro valor corresponder a un valor TRUE. En funcin de dicho resultado se ejecutan o no las
correspondientes instrucciones.
ERRORES EN LAS ESTRUCTURAS DE CONTROL
ERROR POR EXCESO DEL NMERO DE ITERACIONES
Es posible que en los bucles DOLOOP o WHILEEND WHILE se entre en un bucle sin fin. En rutinas de clculo
que correspondan a mtodos iterativos, se debe incluir un contador dentro del bucle para que, dentro de la
condicin de salida del bucle, se verifique el nmero de iteraciones efectuadas y si se sobrepasa el lmite,
finalizar el bucle.
ERROR DE ANIDAMIENTO
Las estructuras deben estar correctamente anidadas, o sea toda estructura de control ha de estar contenida
dentro de otra. En caso contrario Visual Basic generar un error por lo que el programa no puede compilarse
y no inicia la ejecucin.

El editor de cdigo de Visual Basic indica, tal como se muestra en la imagen anterior, la existencia de este
problema, ya que estn cruzadas las estructuras. Adems el propio editor, en el momento en que se escribe
la primera lnea de una estructura y se valida la entrada con el retorno de carro, aade automticamente la
lnea final de la estructura. De esta forma es ms difcil que se produzca este tipo de error.
ERROR POR MODIFICACIN DEL CONTADOR
Aunque Microsoft

Visual Basic no d un error en ejecucin, no se debe modificar dentro de un bucle


FORNEXT el valor de la variable contador, ya que se pueden obtener resultados inesperados.
Si se desea cambiar el valor del contador con un paso distinto de uno, se puede cambiar el valor de ste
(STEP) al especificar los datos en la sentencia correspondiente del bucle FORNEXT. Si lo que se desea es
salir del bucle, se deben emplear las instrucciones especficas para ello.
Por supuesto, tampoco se debe modificar dentro del bucle el valor superior (TO) o el incremento (STEP) de
cada iteracin si estn especificados como variables, ya que los resultados que se pueden obtener son
impredecibles. Para efectuar este tipo de iteraciones con estas modificaciones se debe emplear un bucle
DOLOOP o WHILEEND WHILE en vez de un FORNEXT.
14 IQS, J .J .Molins, CDA-MM. Curso 2012-2013. Fundamentos de Programacin en Visual Basic 2010
Instrucciones Exit Do, Exit While y Exit For
Es posible finalizar la ejecucin de un bucle FOR...NEXT, un bucle DO...LOOP o un bucle WHILEEND WHILE
antes de tiempo empleando las instrucciones Exit For, Exit Do o Exit While, respectivamente.
Normalmente dichas instrucciones se encuentran dentro de una estructura IF...THEN, de forma que cuando
se cumpla una condicin determinada finalice el bucle.
For i = 1 To nIteraciones
Instrucciones_1
If Condicion Then
Exit For
End If
Instrucciones_2
Next
Si hubiera ms de una estructura FOR...NEXT anidada, la sentencia Exit For finaliza el bucle interior. La
sentencia Exit Do se puede aplicar adems de a los bucles DO...LOOP descritos anteriormente, a un bucle
DOLOOP sin condiciones ni al inicio ni al final, tal como se muestra en el siguiente fragmento de cdigo.
Do
Instrucciones_1
If Condicion Then
Exit Do
End If
Instrucciones_2
Loop
Como se puede apreciar en este caso, el bucle DOLOOP no tiene ninguna condicin al inicio o al final, con lo
que presenta un aspecto de bucle sin fin. Por ello es necesario incluir la sentencia Exit Do entre medio para
que pueda finalizar en algn momento dicho bucle cuando se cumpla la condicin especificada por el
programador.
IQS, J .J .Molins, CDA-MM. Curso 2012-2013. Fundamentos de Programacin en Visual Basic 2010 15
Funciones y Subrutinas
DECLARACIN DE UN PROCEDIMIENTO
Al igual que con las variables, es necesario declarar correctamente los procedimientos contenidos en una
aplicacin. En Visual Basic se dispone de dos tipos de procedimientos: funciones y subrutinas. El primero de
ellos devuelve un valor, del tipo con el que se haya declarado la funcin, mientras que el segundo no
devuelve un valor.
Al declarar un procedimiento se debe especificar:
mbito de validez
Tipo de procedimiento
Nombre del procedimiento
Parmetros de entrada y salida
En el caso de una funcin, el tipo de dato que devuelve.
Se va a especificar cmo se debe de incluir cada uno de ellos en la declaracin.
MBITO DE VALIDEZ
Al igual que sucede con las variables, los procedimientos pueden ser accesibles desde todos los
procedimientos de una aplicacin, o bien nicamente desde los procedimientos de su mdulo o formulario.
As, si se declara como Private, nicamente es accesible por parte de los procedimientos que se
encuentran en su mismo mdulo o formulario. Es la opcin por defecto para todos los procedimientos que se
encuentran dentro de un formulario (se supone que el formulario contiene procedimientos que nicamente
interaccionan con los elementos que contiene).
Si se declara como Public, es accesible por todos los procedimientos de la aplicacin. Es la opcin por
defecto para todos los procedimientos que se encuentran en un mdulo de cdigo (se supone que el cdigo
del mdulo tiene propsito general y se debe de poder acceder desde cualquier lugar de la aplicacin).
TIPO DE PROCEDIMIENTO
Si se desea que el procedimiento sea una funcin se emplea la palabra clave Function, mientras que si se
desea que sea una subrutina la palabra clave es Sub. La nica diferencia entre ambas es que el
procedimiento Function devuelve un valor, mientras que el Sub, no.
NOMBRE DEL PROCEDIMIENTO
El cuerpo de un nombre de un procedimiento se debe escribir en maysculas y minsculas, empezando por
maysculas y debe tener la longitud necesaria para describir su funcionalidad. Adems, los nombres de
procedimientos deben empezar con un verbo, como I NICIARNOMBREMATRIZ o CERRARDILOGO, para indicar que
realizan una accin.
PARMETROS DE ENTRADA Y SALIDA
A continuacin se incluyen los parmetros de entrada y salida del procedimiento. Para cada parmetro se
debe de especificar su nombre y el tipo de dato que contiene. Si un procedimiento no necesita parmetros
de entrada y salida, se puede dejar en blanco. Los nombres que se especifiquen en los parmetros tienen la
consideracin de variables locales y por tanto su mbito de validez es el del procedimiento donde se
declaren. Tomarn los valores correspondientes a los que se les asigne desde el procedimiento en el que se
les llame.
Cuando se definan los parmetros es obligatorio especificar si el paso de los valores al procedimiento se
hace por valor (ByVal) o por referencia (ByRef). Pasar por valor una variable a un procedimiento quiere
16 IQS, J .J .Molins, CDA-MM. Curso 2012-2013. Fundamentos de Programacin en Visual Basic 2010
decir que se hace una copia del valor que contiene el programa principal en la memoria del procedimiento.
Todos los cambios que se hagan en l no afectarn al programa principal. Es la opcin que se debe emplear
en aquellas variables que corresponden a valores de entrada al procedimiento.
Pasar por referencia una variable a un procedimiento quiere decir que se enva al procedimiento la posicin
de memoria de la variable del programa principal. Todos los cambios que se hagan sobre la variable
afectarn al programa principal ya que se hacen directamente sobre la posicin de memoria. Es la opcin
que se debe emplear en aquellas variables que son de entrada y salida o nicamente de salida del
procedimiento.
En Microsoft

Visual Basic 2010, si no se especifica nada, el programa considera que la variable se pasa por
valor y aade ByVal automticamente.
TIPO DE DATO
En el caso de los procedimientos Function se debe especificar el tipo de dato que devuelve. El tipo de dato
es uno cualquiera de los vistos anteriormente para las variables o constantes, o bien matrices o vectores.
Para que la funcin devuelva el valor deseado, se puede asignar dentro del cdigo de la funcin dicho valor
al nombre de la funcin, o bien emplear la instruccin Return junto al valor que devuelve la funcin.
EJ EMPLOS DE DECLARACIN DE PROCEDIMIENTOS
Public Sub EscribirValores(ByVal valor As Integer, ByRef referencia As Integer)
Private Sub cmdActivar_Click()
Public Function CalcularAleatorio(ByVal inferior As Integer,
ByVal superior As Integer) As Integer
LLAMADA A UN PROCEDIMIENTO
La forma de llamar a una rutina depende de si sta es un procedimiento SUB o FUNCTION. En caso de que sea
un procedimiento SUB se debe escribir el nombre del procedimiento seguido por los parmetros que se
incluyen en la lista de argumentos entre parntesis. Para el ejemplo anterior sera:
EscribirValores(numeroValor, numeroReferencia)
Para un procedimiento Function la llamada se suele hacer desde una expresin, o bien se asigna su
resultado a una variable. As, dos formas posibles de llamar a la funcin declarada anteriormente sera:
If CalcularAleatorio(3, 9) = 8 Then
resultado = CalcularAleatorio(minimo, maximo)
El orden en que aparecen los argumentos en cualquier llamada a un procedimiento debe corresponder,
exactamente, al que aparece en la definicin de ste. Si no es as, no se obtiene un resultado correcto ya
que pueden ocurrir dos situaciones diferentes. La primera se produce cuando los tipos de variables no
coinciden o faltan o sobran parmetros de la lista. En este caso Microsoft

Visual Basic genera un error de


compilacin y el usuario debe corregirlo para poder ejecutar la aplicacin. La segunda situacin corresponde
al caso en que los parmetros se dieran desordenados pero que los tipos de datos coincidieran. En esta
ocasin no se produce un error de compilacin, con lo cual es ms difcil de localizar ya que no se obtiene
ningn mensaje de error por parte del programa. Por tanto, se debe ser especialmente cuidadoso con las
llamadas a procedimientos para referir adecuadamente los parmetros necesarios y pasarlos en el orden
correspondiente.
IQS, J .J .Molins, CDA-MM. Curso 2012-2013. Fundamentos de Programacin en Visual Basic 2010 17
EJ EMPLOS DE PROCEDIMI ENTOS
Este primer ejemplo corresponde a una funcin. Se puede observar cmo se devuelve la funcin dentro del
cdigo.

Este procedimiento rellena un control DATAGRIDVIEW con los valores contenidos en la matriz MATRIU.

Si se desea presentar una matriz en la que adems de los datos numricos se tenga un vector con los
encabezados de fila y otro con los encabezados de columna se puede efectuar con un procedimiento que
tenga el mismo nombre, pero como los parmetros son distintos Visual Basic podr distinguir a cul de los
procedimientos corresponde la llamada.

Public Function CalcularAleatorio(ByVal inferior As Integer, ByVal _
superior As Integer) As Integer
Return CInt(Int((superior - inferior + 1) * Rnd() + inferior))
End Function
Public Sub PresentacionGrid(ByVal dgvw As DataGridView, ByVal matriu(,) As Double)
Dim nfilas As Integer = matriu.GetLength(0), ncols As Integer = matriu.GetLength(1)
With dgvw
.RowCount = nfilas
.ColumnCount = ncols
For i As Integer = 0 To nfilas - 1
.Rows(i).HeaderCell.Value = "Fila " & (i + 1).ToString
For j As Integer = 0 To ncols - 1
.Item(j, i).Value = matriu(i, j).ToString
Next j
Next i
For j As Integer = 0 To ncols - 1
.Columns(j).HeaderCell.Value = "Col " & (j + 1).ToString
Next j
.AutoResizeRowHeadersWidth(
DataGridViewRowHeadersWidthSizeMode.AutoSizeToAllHeaders)
.AutoResizeColumns(DataGridViewAutoSizeColumnsMode.AllCells)
.AutoResizeRows(DataGridViewAutoSizeRowsMode.AllCells)
.DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight
.DefaultCellStyle.SelectionBackColor = .DefaultCellStyle.BackColor
.DefaultCellStyle.SelectionForeColor = .DefaultCellStyle.ForeColor
'.Enabled = False
End With
End Sub
Public Sub PresentacionGrid(ByVal dgvw As DataGridView, ByVal matriu(,) As Double,
ByVal TitulosCol() As String, ByVal TitulosFila() As String)
Dim nfilas As Integer = matriu.GetLength(0), ncols As Integer = matriu.GetLength(1)
With dgvw
.RowCount = nfilas
.ColumnCount = ncols
For i As Integer = 0 To nfilas - 1
.Rows(i).HeaderCell.Value = TitulosFila(i)
For j As Integer = 0 To ncols - 1
.Item(j, i).Value = matriu(i, j).ToString
Next j
Next i
For j As Integer = 0 To ncols - 1
.Columns(j).HeaderCell.Value = TitulosCol(j + 1)
Next j
.TopLeftHeaderCell.Value = TitulosCol(0)
.AutoResizeRowHeadersWidth(
DataGridViewRowHeadersWidthSizeMode.AutoSizeToAllHeaders)
18 IQS, J .J .Molins, CDA-MM. Curso 2012-2013. Fundamentos de Programacin en Visual Basic 2010

El siguiente procedimiento efecta el producto de dos matrices. Devuelve con el nombre de la funcin si es
posible realizar dicho producto (una variable Booleana que ser True si se puede efectuar el producto y
False si no es posible). Adems, en caso de que sea posible efecta la operacin.

Esta funcin se podra llamar de dos formas posibles, como funcin o como subrutina, ya que Visual Basic
admite ambas opciones en este caso:
If MultiplicarMatrices(matrizA, matrizB, matrizC) Then
MultiplicarMatrices(matrizA, matrizB, matrizC)
Para comprobar el distinto comportamiento de una variable si se para por valor o por referencia se puede
visualizar qu ocurre si se llama el siguiente procedimiento desde el programa principal, que se incluye
posteriormente.

Aunque como ya se ha comentado, la opcin por defecto que asigna automticamente Visual Basic 2010 es
por valor, se debe especificar en cada caso el tipo de paso de datos y siempre se debe verificar que se ha
efectuado correctamente segn los criterios indicados anteriormente.
.AutoResizeColumns(DataGridViewAutoSizeColumnsMode.AllCells)
.AutoResizeRows(DataGridViewAutoSizeRowsMode.AllCells)
.DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight
.DefaultCellStyle.SelectionBackColor = .DefaultCellStyle.BackColor
.DefaultCellStyle.SelectionForeColor = .DefaultCellStyle.ForeColor
'.Enabled = False
End With
End Sub
Public Function MultiplicarMatrices(ByVal a(,) As Double, ByVal b(,) As Double,
ByRef c(,) As Double) As Boolean
Dim nFilasA As Integer = a.GetLength(0) - 1, nColsA As Integer = a.GetLength(1) - 1
Dim nFilasB As Integer = b.GetLength(0) - 1, nColsB As Integer = b.GetLength(1) - 1

If nColsA = nFilasB Then
ReDim c(nFilasA, nColsB)
For i As Integer = 0 To nFilasA
For j As Integer = 0 To nColsB
For k As Integer = 0 To nColsA
c(i, j) += a(i, k) * b(k, j)
Next
Next
Next
Return True
End If
Return False
End Function
Public Sub PasarValores(ByVal valor As Integer, ByRef referencia As Integer)

referencia = referencia + 1
valor = valor + 1
End Sub

Private Sub cmdActivar_Click()
Dim nval, nref As Integer

Do
PasarValores(nval, nref)
'Escribir nval y nref en algn control para visualizar su valor
Loop While nref < 100
End Sub
IQS, J .J .Molins, CDA-MM. Curso 2012-2013. Fundamentos de Programacin en Visual Basic 2010 19
Acceso a ficheros secuenciales
La mayora de valores disponibles para el clculo numrico se encuentran almacenados en ficheros de tipo
secuencial. Por tanto, es necesario conocer cmo poder leer el contenido de dichos archivos.
Normalmente, los archivos de tipo secuencial incluyen valores en el que el separador entre ellos es una
coma y el separador decimal es un punto. Se deben tener en cuenta esa informacin para poder leer
correctamente la informacin contenida en el fichero.
Se puede suponer que se dispone de un archivo que contiene cuatro valores numricos diferentes, los dos
primeros enteros y los otros dos en coma flotante separados por comas, tabuladores o espacios en blanco.
El siguiente cdigo permite leer los cuatro valores y asignar cada uno a una variable diferente.

Tambin es posible efectuar la misma operacin con un cdigo alternativo que permitir, como veremos
posteriormente ms opciones.

La variable archivo, que aparece en ambos cdigos, se puede generar desde el programa principal
empleando el control OPENFILEDIALOG disponible en esta versin de Visual Basic y que permite seleccionar el
archivo deseado.
Public Sub LeerSecuencial_VB(ByVal archivo As String, ByRef valor1 As Integer,
ByRef valor2 As Integer, ByRef valor3 As Double, ByRef valor4 As Double)
Dim NumArxiu As Integer

NumArxiu = FreeFile()
FileOpen(NumArxiu, archivo, OpenMode.Input)
Input(NumArxiu, valor1)
Input(NumArxiu, valor2)
Input(NumArxiu, valor3)
Input(NumArxiu, valor4)
FileClose(NumArxiu)
End Sub

Public Sub LeerSecuencial_NET(ByVal archivo As String, ByRef valor1 As Integer,
ByRef valor2 As Integer, ByRef valor3 As Double, ByRef valor4 As Double)

Dim aux(-1) As String
Dim k As Integer = 0
Dim MyReader As New Microsoft.VisualBasic.FileIO.TextFieldParser(archivo)
MyReader.TextFieldType = FileIO.FieldType.Delimited
MyReader.SetDelimiters(" ")

Dim currentRow As String() = MyReader.ReadFields()
'Evita errores en el caso de ms de un espacio entre datos
For i As Integer = 0 To currentRow.Length - 1
If Len(currentRow(i)) > 0 Then
ReDim Preserve aux(k)
aux(k) = currentRow(i)
k += 1
End If
Next

valor1 = CInt(aux(0))
valor2 = CInt(aux(1))
valor3 = Val(aux(2))
valor4 = Val(aux(3))
End Sub
20 IQS, J .J .Molins, CDA-MM. Curso 2012-2013. Fundamentos de Programacin en Visual Basic 2010
Si se desea leer una matriz de datos en coma flotante de la que se conoce el nmero de filas y el nmero de
columnas porque son los dos primeros valores contenidos en el fichero, el cdigo que permite leerla es el
siguiente.

Este cdigo permite leer cualquier archivo con contenido numrico en forma matricial, en el que los dos
primeros valores del fichero indican el nmero de filas y el nmero de columnas respectivamente, y el resto
de valores los almacena en una matriz que se ha declarado como Double.
La siguiente rutina efecta la misma operacin mediante una estrategia diferente de lectura de fichero.

Se podra leer dicha matriz desde el programa principal mediante el siguiente cdigo, en donde
dlgOpenFile corresponde a un control OPENFILEDIALOG que se encuentra en el correspondiente formulario y
dgvwMatriu y dgvwMatriu1 corresponden a sendos controles DATAGRIDVIEW.

Public Sub LeerSecuencialMatriz_VB(ByVal archivo As String, ByRef a(,) As Double)
Dim nFilas, nCols As Integer
Dim numArxiu As Integer

numArxiu = FreeFile()
FileOpen(numArxiu, archivo, OpenMode.Input)
Input(numArxiu, nFilas)
Input(numArxiu, nCols)
'Los ndices van desde 0 hasta nFilas - 1 o nCols - 1, respectivamente
ReDim a(nFilas - 1, nCols - 1)
For i As Integer = 0 To nFilas - 1
For j As Integer = 0 To nCols - 1
Input(numArxiu, a(i, j))
Next
Next
FileClose(numArxiu)
End Sub
Public Sub LeerSecuencialMatriz_NET(ByVal archivo As String, ByRef a(,) As Double)
Dim nFilas, nCols As Integer
Dim currentRow As String()
Dim MyReader As New Microsoft.VisualBasic.FileIO.TextFieldParser(archivo)

MyReader.TextFieldType = FileIO.FieldType.Delimited
MyReader.SetDelimiters(" ", vbTab, ",")
currentRow = MyReader.ReadFields()

nFilas = CInt(currentRow(0))
nCols = CInt(currentRow(1))
ReDim a(nFilas - 1, nCols - 1)
For i As Integer = 0 To nFilas - 1
currentRow = MyReader.ReadFields()
For j As Integer = 0 To nCols - 1
a(i, j) = Val(currentRow(j))
Next
Next
End Sub
Private Sub mnuLeerDatos2_Click(ByVal sender As System.Object,
ByVal e As System.EventArgs) Handles mnuLeerDatos2.Click
Dim matriuA(-1, 0), matriuB(-1, 0) As Double

dlgOpenFile.InitialDirectory = My.Application.Info.DirectoryPath
dlgOpenFile.FileName = ""
dlgOpenFile.Title = "Abrir fichero de datos"
dlgOpenFile.Filter = _
"Archivos de texto (*.txt)|*.txt|Todos los archivos (*.*)|*.*"
dlgOpenFile.ShowDialog()
IQS, J .J .Molins, CDA-MM. Curso 2012-2013. Fundamentos de Programacin en Visual Basic 2010 21

A continuacin se va a presentar otra forma de poder leer informacin de un fichero secuencial. Hay que
tener en cuenta que no siempre se incluye, como informacin en el fichero, el nmero de valores que
contiene. Por ello es necesario saber leer un fichero en el que se desconoce el nmero de datos, sin que se
genere un error.
En primer lugar se va a escribir el cdigo para leer la informacin contenida en un fichero lnea a lnea. Para
ello se debe escribir el siguiente procedimiento en el mdulo.

En l se emplea el bucle DO UNTIL EOF(NUMARXIU)LOOP, que se va a ejecutar hasta que se alcance el final
del archivo. Esta estructura tambin es posible emplearla para leer valores de un vector sin conocer
previamente el nmero de elementos que contiene, ya que bastara sustituir la funcin LINE INPUT por INPUT
si los valores fueran numricos y aunque no se encontraran en lneas distintas.
Una forma alternativa de efectuar la misma operacin es la del cdigo siguiente.

Si se desea leer un fichero que contiene una matriz de la que no se dispone ni del nmero de filas ni del de
columnas, se puede escribir el siguiente cdigo. En caso de que sea posible leer la matriz se puede operar
posteriormente con ella.

Dim archivo As String = dlgOpenFile.FileName
If len(archivo) > 0 Then
LeerSecuencialMatriz_VB(archivo, matriuA)
PresentacionGrid(dgvwMatriu, matriuA)
LeerSecuencialMatriz_NET(archivo, matriuB)
PresentacionGrid(dgvwMatriu1, matriuB)
End If
End Sub
Public Sub LeerSecuencialLineas_VB(ByVal archivo As String, ByRef a() As String)
Dim nLineas, NumArxiu As Integer

NumArxiu = FreeFile()
FileOpen(NumArxiu, archivo, OpenMode.Input)
Do Until EOF(NumArxiu)
ReDim Preserve a(nLineas)
a(nLineas) = LineInput(NumArxiu)
nLineas += 1
Loop
FileClose(NumArxiu)
End Sub
Public Sub LeerSecuencialLineas_NET(ByVal archivo As String, ByRef a() As String)
Dim nLineas As Integer
Dim sr As System.IO.StreamReader = New System.IO.StreamReader(archivo)
Do
ReDim Preserve a(nLineas)
a(nLineas) = sr.ReadLine()
nLineas += 1
Loop Until a(nLineas - 1) Is Nothing
sr.Close()
End Sub
Public Function LeerMatlab_VB(ByVal archivo As String,
ByRef datos(,) As Double) As Boolean
Dim nCols, numFitx, nColsN As Integer, nFilas As Integer = 0
Dim valores(-1), datosAux(-1, 1) As Double
Dim aux As String, separador As String = ""

numFitx = FreeFile()
FileOpen(numFitx, archivo, OpenMode.Input)
22 IQS, J .J .Molins, CDA-MM. Curso 2012-2013. Fundamentos de Programacin en Visual Basic 2010

Do Until EOF(numFitx)
aux = LineInput(numFitx)
If nFilas = 0 Then
separador = DefinirDelimitador(aux)
End If
EstablecerSeparacion(aux, nColsN, valores, separador)
If nFilas = 0 Then
nCols = nColsN
Else
If nCols <> nColsN Then
Return False
End If
End If
ReDim Preserve datosAux(nCols - 1, nFilas)
For i As Integer = 0 To nCols - 1
datosAux(i, nFilas) = valores(i)
Next
nFilas += 1
Loop
FileClose(numFitx)
ReDim datos(nFilas - 1, nCols - 1)
For i As Integer = 0 To nFilas - 1
For j As Integer = 0 To nCols - 1
datos(i, j) = datosAux(j, i)
Next
Next
Return True
End Function

Public Sub EstablecerSeparacion(ByVal cadena As String, ByRef ndatos As Integer,
ByRef valores() As Double, ByVal separador As String)
Dim pos As Integer

ndatos = 0
Do While CBool(InStr(1, cadena, separador))
pos = InStr(1, cadena, separador)
If IsNumeric(Left(cadena, pos - 1)) Then
ReDim Preserve valores(ndatos)
valores(ndatos) = Val(Left(cadena, pos - 1))
ndatos += 1
End If
cadena = Right(cadena, Len(cadena) - pos)
Loop
If IsNumeric(cadena) Then
ReDim Preserve valores(ndatos)
valores(ndatos) = Val(cadena)
ndatos += 1
End If
End Sub

Public Function DefinirDelimitador(ByVal cadena As String) As String
Dim espacio, tabulador, coma As Integer

For i As Integer = 1 To Len(cadena)
Select Case Mid(cadena, i, 1)
Case vbTab
tabulador += 1
Case ","
coma += 1
Case " "
espacio += 1
End Select
Next
IQS, J .J .Molins, CDA-MM. Curso 2012-2013. Fundamentos de Programacin en Visual Basic 2010 23

Se puede efectuar el mismo proceso de forma alternativa a partir del cdigo de la siguiente rutina. Como se
puede observar, en este caso esta estrategia es ms sencilla.

Sin embargo, en muchas ocasiones la tabla de datos numrica viene acompaada por textos de encabezado
de filas y columnas que describen el contenido de la tabla. Con el cdigo anterior es imposible leer ese tipo
de archivos ya que nicamente espera valores numricos. Para ello es necesario modificar la rutina anterior.
En este caso el contenido del archivo se separa en una matriz con los valores numricos y dos vectores que
contienen los encabezados de fila y de columna.
If tabulador > 0 Then
Return vbTab
ElseIf coma > 0 Then
Return ","
ElseIf espacio > 0 Then
Return " "
Else
Return ""
End If
End Function
Public Function LeerMatlab_NET(ByVal archivo As String,
ByRef datos(,) As Double) As Boolean

Dim nFilas As Integer = 0, nCols As Integer
Dim datosAux(-1, 0) As Double
Dim MyReader As New Microsoft.VisualBasic.FileIO.TextFieldParser(archivo)

MyReader.TextFieldType = FileIO.FieldType.Delimited
MyReader.SetDelimiters(" ", vbTab, ",")

Do Until MyReader.EndOfData
Dim currentRow As String() = MyReader.ReadFields
If nFilas = 0 Then
nCols = currentRow.Length
Else
If nCols <> currentRow.Length Then
Return False
End If
End If
ReDim Preserve datosAux(nCols - 1, nFilas)
For i As Integer = 0 To nCols - 1
If Len(currentRow(i)) > 0 Then
datosAux(i, nFilas) = Val(currentRow(i))
Else
Return False
End If
Next
nFilas += 1
Loop
ReDim datos(nFilas - 1, nCols - 1)
For i As Integer = 0 To nFilas - 1
For j As Integer = 0 To nCols - 1
datos(i, j) = datosAux(j, i)
Next
Next
Return True
End Function
24 IQS, J .J .Molins, CDA-MM. Curso 2012-2013. Fundamentos de Programacin en Visual Basic 2010

A partir de estas rutinas bsicas, es posible generar los procedimientos necesarios para leer cualquier
combinacin de datos en un fichero.
Para poder guardar datos, la estructura es equivalente y lo nico que hay que hacer es sustituir las
sentencias que leen datos por aquellas que escriben.
As, si se desea crear un archivo que contenga cuatro valores numricos diferentes, los dos primeros enteros
y los otros dos en coma flotante separados por comas, basta ejecutar el siguiente cdigo.

Public Function LeerTablaDatos_NET(ByVal archivo As String, ByRef datos(,) As Double,
ByRef TitulosCol() As String, ByRef TitulosFila() As String) As Boolean

Dim nFilas As Integer = 0, nCols As Integer
Dim datosAux(-1, 0) As Double
Dim MyReader As New Microsoft.VisualBasic.FileIO.TextFieldParser(archivo)
MyReader.TextFieldType = FileIO.FieldType.Delimited
MyReader.SetDelimiters(" ", vbTab, ",")

Do Until MyReader.EndOfData
Dim currentRow As String() = MyReader.ReadFields
If nFilas = 0 Then
nCols = currentRow.Length
ReDim TitulosCol(nCols - 1)
For i As Integer = 0 To nCols - 1
TitulosCol(i) = currentRow(i)
Next
Else
If nCols <> currentRow.Length Then
Return False
End If
ReDim Preserve datosAux(nCols - 2, nFilas - 1), TitulosFila(nFilas - 1)
TitulosFila(nFilas - 1) = currentRow(0)
For i As Integer = 1 To nCols - 1
If Len(currentRow(i)) > 0 Then
datosAux(i - 1, nFilas - 1) = Val(currentRow(i))
Else
Return False
End If
Next
End If
nFilas += 1
Loop
ReDim datos(nFilas - 2, nCols - 2)
For i As Integer = 0 To nFilas - 2
For j As Integer = 0 To nCols - 2
datos(i, j) = datosAux(j, i)
Next
Next
Return True
End Function
Public Sub EscribirSecuencial_VB(ByVal archivo As String, ByVal valor1 As Integer,
ByVal valor2 As Integer, ByVal valor3 As Double, ByVal valor4 As Double)
Dim NumArxiu As Integer

NumArxiu = FreeFile()
FileOpen(NumArxiu, archivo, OpenMode.Output)
WriteLine(NumArxiu, valor1, valor2, valor3, valor4)
FileClose(NumArxiu)
End Sub
IQS, J .J .Molins, CDA-MM. Curso 2012-2013. Fundamentos de Programacin en Visual Basic 2010 25
Se puede, tambin al escribir datos en un fichero utilizar otra alternativa tal como se observa en el siguiente
cdigo.

Si se quiere escribir una matriz de datos en coma flotante y especificar el nmero de filas y el nmero de
columnas que sern los dos primeros valores que contendr el fichero, el cdigo que permite escribirla es el
siguiente.

El cdigo equivalente con la opcin de usar la clase StreamWriter es el que se presenta seguidamente. El
archivo generado es idntico al anterior.

Si se pretende escribir la matriz con la estructura de filas y columnas y sin valores al inicio que especifiquen
su nmero de filas y columnas, se puede generar a partir del siguiente cdigo.

Public Sub EscribirSecuencial_NET(ByVal archivo As String, ByVal valor1 As Integer,
ByVal valor2 As Integer, ByVal valor3 As Double, ByVal valor4 As Double)

Dim file As System.IO.StreamWriter =
My.Computer.FileSystem.OpenTextFileWriter(archivo, False)
file.WriteLine("{0},{1},{2},{3}", valor1, valor2, valor3, valor4)
file.Close()
End Sub
Public Sub EscribirSecuencialMatriz_VB(ByVal archivo As String, ByVal a(,) As Double)
Dim numArxiu As Integer

numArxiu = FreeFile()
FileOpen(numArxiu, archivo, OpenMode.Output)
WriteLine(numArxiu, a.GetLength(0), a.GetLength(1))
For i As Integer = 0 To a.GetLength(0) - 1
For j As Integer = 0 To a.GetLength(1) - 1
Write(numArxiu, a(i, j))
Next
Next
FileClose(numArxiu)
End Sub
Public Sub EscribirSecuencialMatriz1_NET(ByVal archivo As String, ByVal a(,) As Double)

Dim file As System.IO.StreamWriter =
My.Computer.FileSystem.OpenTextFileWriter(archivo, False)
file.WriteLine("{0},{1}", a.GetLength(0), a.GetLength(1))
For i As Integer = 0 To a.GetLength(0) - 1
For j As Integer = 0 To a.GetLength(1) - 1
file.Write("{0},", a(i, j))
Next
Next
file.WriteLine()
file.Close()
End Sub
Public Sub EscribirSecuencialMatriz2_NET(ByVal archivo As String, ByVal a(,) As Double)

Dim file As System.IO.StreamWriter =
My.Computer.FileSystem.OpenTextFileWriter(archivo, False)
For i As Integer = 0 To a.GetLength(0) - 1
For j As Integer = 0 To a.GetLength(1) - 2
file.Write("{0},", a(i, j))
Next
file.WriteLine("{0}", a(i, a.GetLength(1) - 1))
Next
file.Close()
End Sub
26 IQS, J .J .Molins, CDA-MM. Curso 2012-2013. Fundamentos de Programacin en Visual Basic 2010
Por ltimo, se presenta cmo escribir un archivo en el que adems de los valores numricos de los
resultados se incluyan los encabezados de filas y columnas para poder describir su contenido y etiquetar
convenientemente los valores. En este caso, adems, se ha escogido separar los diferentes valores con
tabuladores, de forma que acabe teniendo la apariencia de una tabla de datos que sera posible importar
desde diferentes programas para un tratamiento posterior (informes, etc.).

A partir de los ejemplos presentados, es posible modificarlos para adaptarse a cualquier formato o necesidad
que se desee, sin dificultad.
Para crear un archivo secuencial y poder comprobar si la rutina desarrollada lo lee correctamente, basta
generarlo con el Bloc de Notas. Igualmente, para visualizar si el cdigo desarrollado ha creado un archivo
con la estructura deseada, basta abrirlo, igualmente, con dicho programa.
Public Sub EscribirTablaDatos_NET(ByVal archivo As String, ByVal datos(,) As Double,
ByVal TitulosCol() As String, ByVal TitulosFila() As String)

Dim file As System.IO.StreamWriter =
My.Computer.FileSystem.OpenTextFileWriter(archivo, False)
For j As Integer = 0 To TitulosCol.Length - 2
file.Write("{0}" & vbTab, TitulosCol(j))
Next
file.WriteLine("{0}", TitulosCol(TitulosCol.Length - 1))
For i As Integer = 0 To datos.GetLength(0) - 1
file.Write("{0}" & vbTab, TitulosFila(i))
For j As Integer = 0 To datos.GetLength(1) - 2
file.Write("{0}" & vbTab, datos(i, j))
Next
file.WriteLine("{0}", datos(i, datos.GetLength(1) - 1))
Next
file.Close()
End Sub

You might also like