Sin título de diapositiva

Anuncio
Algoritmos y Programación
Clase 8
Ordenamiento y Búsqueda
Anexo: Uso de Procedimientos Sub y
Procedimientos Function
1
EXAMEN
1.
Lunes 16 de abril 4 pm.
2.
Tema: Lo visto hasta la clase de hoy.
2
Clase 8
Contenido
Ordenamiento y Búsqueda
1.1 Ejemplos.
1.2 Métodos de Ordenamiento:
Intercambio o Burbuja
Selección
Inserción (Anexo, para estudiar)
1.3 Métodos de búsqueda:
Secuencial
Binaria
3
Clase 8
1.1 Ejemplos
„
Ordenamiento y búsqueda:
„
En el directorio telefónico.
„
En el diccionario.
„
Inventarios.
„
Lista de carnés.
„
Billetes (con repetición)
„
Facturación, proveedores.
„
Biblioteca, etc.
4
Clase 8
Ordenamiento
„
„
„
El ordenamiento de una serie de
datos puede ser ascendente o
descendente:
Orden ascendente: X1 ≤ X2 ≤... ≤ Xi-1 ≤
Xi ≤ Xi+1 ≤... ≤ Xn
Orden descendente: X1 ≥ X2 ≥... ≥ Xi-1 ≥
Xi ≥ Xi+1 ≥ ... ≥ Xn
5
Clase 8
Métodos de ordenamiento
„
Cinco métodos básicos de ordenamiento de
vectores:
„ Intercambio (“Burbuja”)
„ Selección
„ Inserción
„ *Shell
Tarea
„ *QuickSort
Ejemplo: Un mazo de cartas, de una sola pinta.
6
Clase 8
1.2.1 Método de Ordenamiento
Intercambio (Burbuja)
7
Intercambio (Burbuja), cont.
1. Desplegar las cartas sobre una
mesa,en línea, figuras hacia arriba
Para abreviar la explicación del algoritmo se toma
un subconjunto del mazo de cartas, por ejemplo el
conformado por las cartas que se muestran.
Clase 8
8
Intercambio (Burbuja), cont.
2. Intercambiar las cartas que están
desordenadas: (se compara la primera
con todas las demás)
1
2
3
4
5
6
7
2.1 La carta de la primera posición es mayor que la carta
ubicada en la segunda posición. Hay que efectuar
intercambio.
intercambio La carta 5 se lleva a la posición 1, y la carta 99
Clase 8
a la posición 2.
Intercambio (Burbuja), cont.
2. Intercambiar las cartas que están
desordenadas: (se compara la primera con
todas las demás)
2.1 La carta en la primera
posición se lleva a una
ubicación temporal.
Esta carta se ubicará
en la segunda posición
10
Clase 8
Intercambio (Burbuja), cont.
La carta en la ubicación temporal se lleva a la
segunda posición. Así se ha efectuado un proceso de
intercambio (transposición, permutación).
11
Clase 8
Intercambio (Burbuja), cont.
RESULTADO PARCIAL DEL ORDENAMIENTO
12
Clase 8
Intercambio (Burbuja), cont.
Ahora, la carta 5 es la primera, y es menor que la carta 9.
Es decir, NO se realiza intercambio.
Luego la carta 5 se compara con la siguiente (4).
La carta 5 es mayor que la 4.
Entonces Æ Sí se efectúa el intercambio.
intercambio
13
Clase 8
Intercambio (Burbuja), cont.
RESULTADO PARCIAL DEL ORDENAMIENTO
La carta 4, en la posición 3, se lleva a una ubicación
temporal; la carta 5, en la posición 1, se lleva a la
posición 3; y la carta 4 se lleva de la posición temporal
a la posición 1.
Clase 8
14
Intercambio (Burbuja), cont.
La carta 4, en la posición 1, se compara con las
demás; el intercambio se hace con la carta 2, que está
en la posición 5.
15
Clase 8
Intercambio (Burbuja), cont.
2. Intercambiar las cartas que están
desordenadas: (se compara la primera
con todas las demás)
1
2
3
4
5
6
7
2.2 La carta 2, ahora en la posición 1, es la de menor
valor.
16
Clase 8
Intercambio (Burbuja), cont.
2. Intercambiar las cartas que están
desordenadas: (se compara la segunda
con todas las demás)
1
2
3
4
5
6
7
El proceso de intercambio se repite hasta que las cartas
estén ordenadas ascendentemente.
17
Clase 8
Intercambio (Burbuja), cont.
3. Finalizar cuando todas las cartas
están ordenadas:
1
2
3
4
5
6
7
Este método implica dos iteraciones: una que toma cada
carta; y otra que compara la carta tomada con todas las
demás; en dicha comparación se decide efectuar, o no,
18
Clase 8
el intercambio.
intercambio
Intercambio (Burbuja)
„
Ordenar ascendentemente:
1. Desplegar las cartas sobre una mesa, en
línea, figuras hacia arriba.
2. Intercambiar las cartas que están
desordenadas:
2.1 Llevar la carta con número inferior a la
posición de la carta con la cual se va a
intercambiar.
2.2 Llevar la carta con número superior a la
posición de la carta descrita en 2.1.
3. Repetir el paso 2, hasta que no se
encuentren cartas desordenadas.
19
Clase 8
Intercambio (Burbuja), cont.
„
El algoritmo en Visual Basic:
For i = 1 To N-1
For j= i+1 To N
If(X(j) > X(i))Then
temp = X(i)
Máximo
X(i) = X(j)
N-1
N-1
X(j) = temp
End if
Next j
Next i
2
Número
de
comparaciones
~
N
Clase 8
20
Intercambio (Burbuja), cont.
„
Ejemplo de la función de la variable
Temporal (Temp):
Temp
Clase 8
21
Intercambio (Burbuja), cont.
„
Ejemplo de la función de la variable
Temporal (Temp):
1
Temp
Clase 8
22
Intercambio (Burbuja), cont.
„
Ejemplo de la función de la variable
Temporal (Temp):
2
Temp
Clase 8
23
Intercambio (Burbuja), cont.
„
Ejemplo de la función de la variable
Temporal (Temp):
3
Temp
Clase 8
24
# de comparaciones
1.2.1 Intercambio (“Burbuja”), cont.
Algoritmo
exponencial ~ N2
número de elementos
25
Clase 8
1.2.2 Método de Ordenamiento
Selección
26
2 Método de Selección, cont.
1. Desplegar las cartas sobre una mesa
figuras hacia arriba
27
Clase 8
Método de Selección, cont.
2. Retirar la carta de menor valor y ubicarla en otro
sitio:
28
Clase 8
Método de Selección, cont.
3. Del mazo restante en la mesa, seleccionar la
carta de menor valor, retirarla de la mesa y
ponerla en el otro sitio, detrás de la anterior.
29
Clase 8
Método de Selección, cont.
4. Al finalizar, las cartas estarán ordenadas
ascendentemente:
Puede demostrarse que el método de selección requiere
un número de comparaciones de (N2 - N)/2. En el mejor
de los casos, el número de intercambios es cero y
en el peor de los casos es (N2 - N)/2.
30
Clase 8
Ejemplo utilizando el Mazo de Cartas
de una sola pinta
1.Desplegar las cartas sobre una mesa,
figuras hacia arriba.
2.Seleccionar la carta de menor valor,
retirarla de la mesa, ponerla en la
mano.
3.Del mazo restante en la mesa,
seleccionar la carta de menor valor,
retirarla de la mesa y ponerla en la
mano, detrás de la anterior.
4.Repetir paso 3. Al terminar, las
cartas están ordenadas en la mano.
31
Clase 8
Método de Selección, cont.
Programa en Visual Basic:
For i = 1 To N-1
c = i : t = X(i)
For j = i+1 To N
If(X(j) >= t)Then
c = j : t = X(j)
End If
Next j
X(c) = X(i)
X(i) = t
Next i
32
Clase 8
Eficiencia de los Métodos
„
Algunos parámetros a
considerar son:
1.Número de comparaciones que
se efectúan.
2.Número de intercambios de
posición (transposiciones) que
se ejecutan.
Las transposiciones toman la
mayor parte del tiempo.
33
Clase 8
1.3 Métodos de Búsqueda
„
La búsqueda implica hallar un elemento
en una lista de datos.
„
Métodos de búsqueda:
Secuencial
„ Binaria
„
Clase 8
1.3.1 Búsqueda Secuencial
35
Búsqueda Secuencial
Lectura de datos vector A(N)
K=0
~N
Do
k=k+1
Loop Until(Dato = A(k) or k=N)
El arreglo puede estar, o no estar, ordenado .
Clase 8
Búsqueda Secuencial
If k = n And dato <> a(k) Then
Text1.Text = "dato no encontrado "
Else
Text1.Text = "Posición " & k
Text2.Text = "Dato " & dato
End If
37
Clase 8
1.3.2 Búsqueda Binaria
38
2 Búsqueda Binaria
„
El arreglo está ordenado ascendentemente:
1. Comparar el “dato” buscado con el elemento del
medio.
1.1. Si aquel es menor que el dato del medio,
entonces la búsqueda se hace en la primera
mitad.
1.2. De lo contrario, el “dato” buscado puede
estar en la segunda mitad.
2. Repetir el proceso hasta que se encuentre el
“dato” buscado, o hasta que se agoten los
elementos.
Clase 8
Búsqueda
Binaria
A() es un vector ordenado ascendentemente y se esta
buscando un “dato” entre los lìmites superior e inferior.
[a1 a2
a3
a4 … am …
aj
…
an]
Si dato buscado > am
Si dato buscado < am
Sup = m-1
Sup
m=(Inf+Sup)/2
Inf
Inf = m+1
Si dato buscado = am
La posición buscada = m
Clase 8
40
Búsqueda Binaria, cont.
„
Ejemplo: Para hallar el Dato = 40, en la lista
10,20,30,40,50,60,70,80,90
„
„
„
Primero se compara con el elemento del medio,
50. Puesto que Dato < 50, la búsqueda continua
con la primera mitad:
10,20,30,40,50. El elemento del medio es ahora
30, que es menor que 40 (el dato buscado).
La búsqueda sigue con la lista 40,50.
Encontrándose el valor buscado (40) en uno de
los extremos.
Clase 8
Búsqueda Binaria, cont.
Lectura de datos X(N)
Inf = 1 : Sup = N
Do
m = (Inf+Sup)/2
If (dato < X(m))Then
Sup = m
Else If(dato > X(m))Then
Inf = m
End If
Loop Until (dato=X(m) or Inf >= Sup)
Clase 8
Presentación de resultados
If(dato=X(m)) Then
Text1.text = “La posición es:” & m
Text2.text = “El dato es: ” & X(m)
Else
Text1.text = “El dato no se encontro”
EndIf
43
Clase 8
Búsqueda Binaria (cont.)
Este método es más eficiente que el anterior
ya que con las primeras dos comparaciones
se descartan 3/4 de los datos (el 75%).
~ N: Secuencial
Comparaciones
„
~ Log2(N): Binaria
número de elementos
Clase 8
TAREAS
45
Listado de ejercicios…
Calcular el mayor y el menor valor de un
vector.
Calcular la suma y el promedio de un
vector.
Invertir las entradas de un vector sobre
el mismo vector, ej:
„
„
„
„
„
[5, 6, 9, 1, 3, 0, 4]
[4, 0, 3, 1, 9, 6, 5]
46
Clase 8
Listado de ejercicios…
Conocidas las coordenadas de un
conjunto de puntos:
„
„
„
Calcular un vector en la que el elemento
(i) sea la distancia del punto i al origen.
Calcular una matriz en la que el elemento
(i,j) sea la distancia del punto i al punto j.
47
Clase 8
Listado de ejercicios…
Conocido un vector:
„
„
identificar qué posición ocupa el cuarto
siete?
48
Clase 8
ANEXO 1
49
1.2.3 Método de Ordenamiento
Inserción
50
Método de Inserción, cont.
Ejemplo: Ordenar las letras W Q R D C A B
en orden alfabético.
1 2 3 4 5 6 7
Inicial: W Q R D C A B
Paso
Paso
Paso
Paso
Paso
Paso
1:
2:
3:
4:
5:
6:
Q
Q
D
C
A
A
W
R
Q
D
C
B
(posición)
(los dos primeros se ordenan)
W
R
Q
D
C
(insertar tercero, en orden)
W
R
Q
D
(insertar cuarto, en orden)
W (insertar quinto, en orden)
R W (insertar sexto, en orden)
Q R W (insertar séptimo, en
orden)
Clase 8
51
Método de Inserción
1. Sostener el mazo de cartas en la mano.
2. Tomar dos cartas, colocarla en la mesa. La de
menor valor antes de la de mayor valor.
3.Tomar una carta, ubicarla en la mesa,
insertándola en el lugar correcto.
„ Esto implica tener que “empujar” hacia
adelante o hacia atrás, para efectuar la
inserción correspondiente.
4. Repetir paso 3, hasta que se agoten las cartas
de la mano.
52
Clase 8
Método de Inserción, cont.
Programa en Visual Basic:
For i = 2 To N
t = X(i) : j = i-1
Do Until(j = 0 And t >= X(j))
X(j+1) = X(j)
j = j -1
Loop
X(j+1) = t
Next i
Método de Inserción también es ~ N2.
Clase 8
53
ANEXO 2
Subprogramas (Procedimientos):
„
„
Procedimientos Sub
Procedimientos Function
54
Subprogramas
„
„
„
Para simplificar las tareas de programación se
dividen los programas en componentes lógicos
más pequeños.
Estos componentes lógicos se denominan
procedimientos o subrutinas.
subrutinas
Los procedimientos resultan muy útiles para
condensar las tareas repetitivas o compartidas,
como cálculos utilizados frecuentemente,
manipulación de texto y controles, operaciones
con bases de datos, etc.
55
Clase 8
Subprogramas
„
Ya se han utilizado algunos tipos de
subprogramas:
„
„
„
„
Funciones de la librería estándar de VB: Val(), Str(),
Sqr(), Atn(), Abs(), etc.
Otras funciones: MsgBox(), InputBox(), etc.
Métodos propios de algunos controles: Clear, AddItem,
Scale, Cls, Line, Circle, etc.
Procedimientos asociados a eventos:
Private Sub Command1_Click()
End Sub
56
Clase 8
Crear procedimientos
„
„
„
Un procedimiento siempre se define a nivel de
módulo (estándar o de formulario). Por lo tanto,
un procedimiento no se puede anidar dentro de
otro procedimiento.
Todo el código ejecutable de un programa en VB
debe estar contenido en uno o varios
procedimientos.
En VB se utilizan varios tipos de procedimientos:
„
„
Procedimientos Sub que no devuelven un valor.
Procedimientos Function que devuelven un valor.
Clase 8
57
Procedimientos Sub
„
„
„
„
Los procedimientos Sub no devuelven un valor.
Sintaxis:
Alcance Sub NombreProc(parámetros)
CuerpoProcedimiento
End Sub
Alcance:
Alcance Opcional. Es el alcance del procedimiento. Puede
ser Private o Public.
Public Si no se especifica se asume
Public.
Public
NombreProc:
NombreProc Requerido. Es el nombre del procedimiento.
58
Clase 8
Procedimientos Sub
„
parámetros:
parámetros Opcional. Son los parámetros del
procedimiento. (Véase más adelante).
„
CuerpoProcedimiento:
CuerpoProcedimiento Opcional. Son las instrucciones que
conforman al procedimiento.
„
Cada vez que se llama al procedimiento se ejecutan las
instrucciones que hay entre Sub y End Sub.
Sub
„
El cuerpo del procedimiento puede tener instrucciones
Exit Sub,
Sub la cual permite salir de inmediato del
procedimiento. La ejecución del programa continúa con la
instrucción que sigue a la instrucción que llamó el
procedimiento Sub.
59
Clase 8
Procedimientos Sub
„
„
„
„
Existen dos tipos de procedimientos Sub:
Sub Procedimientos
Generales y Procedimientos de Eventos.
Un procedimiento de evento es un procedimiento que hace
referencia a un evento de un objeto. Siempre el nombre de
un procedimiento de evento se compone por el nombre del
objeto, seguido de un subrayado, seguido del nombre del
evento:
nombreObjeto_nombreEvento
Ejemplo: Command1_Click(), Form_Load(), Form_Resize()
Un procedimiento general indica a la aplicación cómo
realizar una tarea específica.
60
Clase 8
Procedimientos Function
„
„
„
„
Son procedimientos que devuelven un valor.
Sintaxis:
Alcance Function NombreProc(parámetros) As Tipo
CuerpoProcedimiento
End Function
Alcance:
Alcance Opcional. Es el alcance del procedimiento. Puede
ser Private o Public.
Public Si no se especifica se asume
Public.
Public
NombreProc:
NombreProc Requerido. Es el nombre del procedimiento.
61
Clase 8
Procedimientos Function
„
parámetros:
parámetros Opcional. Son los parámetros del
procedimiento. (Véase más adelante).
„
CuerpoProcedimiento:
CuerpoProcedimiento Opcional. Son las instrucciones que
conforman al procedimiento. Puede tener instrucciones
Exit Function.
Function
„
Tipo:
Tipo Es el tipo de dato que retorna el procedimiento.
El valor que retorna un procedimiento Function se le
debe asignar al nombre del procedimiento, en caso
contrario se retorna el valor por defecto.
„
62
Clase 8
Argumentos vs Parámetros
„
„
„
Los argumentos pueden ser constantes, variables o
expresiones pasadas a un procedimiento.
Ejemplo: en la expresión: X = Sqr(15),
(15) el valor 15
corresponde al argumento pasado a la función Sqr de la
librería estándar de VB.
El parámetro es el nombre de variable por el cual un
argumento de procedimiento se conoce dentro del
procedimiento. Esta variable recibe el argumento que se
pasa dentro del procedimiento. Su alcance es local, es
decir, el alcance termina cuando el procedimiento finaliza.
63
Clase 8
Declaración de Argumentos
„
Los parámetros de un procedimiento corresponde a una
lista de variables (separadas por comas) que representan
los argumentos que se pasan a un procedimiento cuando
se le llama.
„
La declaración de argumentos (parámetros) de un
procedimiento tiene la siguiente sintaxis:
[Optional]
Optional [ByVal | ByRef]
ByRef [ParamArray]
ParamArray nombre_variable[(
nombre_variable )] [As tipo]
tipo
[= valor_predeterminado]
valor_predeterminado
„
En la sintaxis, los corchetes ([]) significan que la expresión
es opcional y la barra vertical (|) significa exclusión lógica.
64
Clase 8
Declaración de Argumentos
„
ByVal indica que el argumento se pasa por valor, es
decir, se pasa su valor (una copia de la variable) en vez de
su dirección. Como resultado, el valor actual de la variable
no puede ser cambiado por el procedimiento al cual se
pasa.
65
Clase 8
Declaración de Argumentos
„
„
ByRef indica que el argumento se pasa por
referencia, es decir, se pasa su dirección en vez
de su valor. Como resultado, el valor real de la
variable puede ser cambiado por el procedimiento
al cual se pasa.
ByRef es el modo predeterminado en Visual
Basic.
66
Clase 8
Declaración de Argumentos
„
nombre_variable es el nombre del parámetro.
„
Los paréntesis al final del nombre de la variable
significan que el parámetro recibe un array. No se
debe especificar tamaño ni número de
dimensiones del array, sólo se colocan los
paréntesis vacíos.
„
tipo es el tipo de dato del parámetro. Si no se
especifica se asume Variant.
Variant
67
Clase 8
Llamar procedimientos
Utilizando la instrucción Call:
Call nombre_procedimiento(arg1,arg2,…,argN)
„
En este caso, se debe utilizar paréntesis después del nombre del
procedimiento.
„
„
Si el procedimiento retorna un valor, este se pierde.
Útil para procedimientos Sub.
Sub
„
Ejemplo: Call Sqr(15)
68
Clase 8
Llamar procedimientos
En una expresión:
nombre_procedimiento(arg1,arg2,…,argN)
„
En este caso, se debe utilizar paréntesis después del nombre del
procedimiento.
Sólo es válido para procedimientos Function.
Function
„
Ejemplos:
„
X = Sqr(15)
Y = Abs(10 * X – Atn(2))
69
Clase 8
Ejemplo 1
„
„
Realizar un procedimiento genérico que
permita leer una matriz por el teclado de
elementos reales.
Realizar un procedimiento genérico que
permita mostrar una matriz de elementos
reales en una caja de texto.
70
Clase 8
Ejemplo 1: Análisis
„
Un procedimiento genérico para leer una
matriz necesita:
„
„
„
Un parámetro que recibe la matriz de tipo real
simple: A() As Single
Un parámetro por referencia, de tipo entero,
para el número de filas: N As Integer
Un parámetro por referencia, de tipo entero,
para el número de columnas: M As Integer
71
Clase 8
Ejemplo 1: Análisis
„
Un procedimiento genérico para mostrar
una matriz en una caja de texto necesita:
„
„
„
„
Un parámetro que recibe la matriz de tipo real
simple: A() As Single
Un parámetro por valor, de tipo entero, para el
número de filas: ByVal N As Integer
Un parámetro por valor, de tipo entero, para el
número de columnas: ByVal M As Integer
Un parámetro con la referencia de la caja de
texto: txt As TextBox
72
Clase 8
Ejemplo 1: Implementación
„
Procedimiento genérico para leer una matriz:
Public Sub LeerMatriz(A() As Single, N As Integer, _
M As Integer)
Dim I As Integer
N = Val(InputBox("Número de Filas:"))
M = Val(InputBox("Número de Columnas:"))
ReDim A(1 To N, 1 To M)
For I = 1 To N
For J = 1 To M
A(I, J) = Val(InputBox("Ingrese elemento(" & _
I & ", " & J & "):"))
Next J
Next I
End Sub
Clase 8
73
Ejemplo 1: Implementación
„
Procedimiento genérico para mostrar una matriz:
Public Sub MostrarMatriz(A() As Single, ByVal N As Integer, _
ByVal M As Integer, txt As TextBox)
Dim I As Integer
txt.Text = ""
For I = 1 To N
For J = 1 To M
txt.Text = txt.Text & A(I, J) & vbTab
Next J
txt.Text = txt.Text & vbCrLf
Next I
End Sub
74
Clase 8
Ejemplo 2
„
Realizar un procedimiento que permita
multiplicar dos matrices:
Una matriz A de orden mxn y una matriz B
de orden pxq.
„
Nota: Las matrices se pueden multiplicar
si y sólo si n = p. El orden de la matriz
resultante es mxq.
75
Clase 8
Ejemplo 2: Análisis
„
Un procedimiento para multiplicar dos matrices
necesita:
„
„
„
„
Dos parámetros que reciben las matrices de tipo real
simple: A() As Single, B() As Single
Cuatro parámetros por valor, de tipo entero, para el
orden de cada matriz: N1 As Integer, M1 As Integer,
N2 As Integer, M2 As Integer
Un parámetro que devuelve la matriz resultante: C()
As Single
El procedimiento devolverá True si se realizó la
multiplicación, en caso contrario devolverá False.
76
Clase 8
Ejemplo 2: Implementación
„
Procedimiento para multiplicar dos matrices:
Public Function MultMat(A() As Single, B() As Single, _
ByVal N1 As Integer, ByVal M1 As Integer, _
ByVal N2 As Integer, ByVal M2 As Integer, _
C() As Single) As Boolean
Dim I As Integer, J As Integer, K As Integer, Sum As Single
If M1 <> N2 Then MultMat = False: Exit Function
ReDim C(1 To N1, 1 To M2)
For I = 1 To N1
For J = 1 To M2
Sum = 0
For K = 1 To M1
Sum = Sum + A(I, K) * B(K, J)
Next K
C(I, J) = Sum
Next J
Next I
77
MultMat = True
Clase 8
End Function
Ejemplo 3
„
Realizar un programa en VB que permita,
leer, multiplicar dos matrices y mostrar el
resultado.
78
Clase 8
Ejemplo 3: Análisis
„
Un programa que permita multiplicar dos
matrices necesita:
„
„
„
„
Leer las dos matrices
Realizar la multiplicación
Mostrar el resultado si la multiplicación fue posible, en
caso contrario, mostrar un mensaje descriptivo.
El programa puede hacer uso de los
procedimientos definidos anteriormente,
implementándolos en un módulo estándar.
79
Clase 8
Ejemplo 3: Implementación
'En el evento Click de un botón de Comando.
Dim M1() As Single, M2() As Single, M3() As Single
Dim N As Integer, M As Integer, P As Integer, Q As Integer
Call LeerMatriz(M1, N, M)
Call LeerMatriz(M2, P, Q)
If (MultMat(M1, M2, N, M, P, Q, M3)) Then
MostrarMatriz M3, UBound(M3, 1), UBound(M3, 2), Text1
Else
MsgBox "No se puede multiplicar las matrices: " & _
"El número de columnas de la primera matriz es " & _
"diferente al número de filas de la segunda " & _
"matriz.", vbExclamation, "Error"
End If
80
Clase 8
Descargar