Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                

Macros Excel

Descargar como pdf o txt
Descargar como pdf o txt
Está en la página 1de 122

Macros

personalizadas en
Excel

Visual Basic para Aplicaciones


VBA

03/08/2010 Adolfo Aparicio 1


mii primera
i Macro
M
z Editor de Visual Basic
z Alt+F11
z Barra de Herramientas: Visual Basic
z H
Herramientas,
i t Macro, Editor
M Edit d de V
V.B.B
z Insertar Módulo
z Primera macro
Sub Hola_Mundo()
ActiveCell.Value = "Hola Mundo"
End Sub

03/08/2010 Adolfo Aparicio 2


Obj t Rango
Objeto R
z Programa que deja un valor en una celda y
modifica su formato

Sub Saludo()
Worksheets("Hoja2")
Worksheets( Hoja2 ).Activate
Activate
ActiveSheet.Range("C5").Value = "¿Cómo esta usted?"
ActiveSheet.Range("C5").Font.Bold = True
ActiveSheet.Range("C5").Font.Color = RGB(255, 0, 0)
End Sub

03/08/2010 Adolfo Aparicio 3


Range y Offset
Sub primero()
'Queremos asignar un valor al objeto Range
Range("B10").Value = "Hola"
' Otra forma de trabajar es poniendo el objeto WorkSheets que está por encima de Range
Worksheets(1) Range("B11")
Worksheets(1).Range( B11 ).Value
Value = "¿Qué
¿Qué tal?"
tal?
' Y aún podemos poner los objetos superiores
' Application que hace referencia a la aplicación Excel
' Y WorkBooks que se refiere al libro de trabajo
Application.Workbooks(1).Worksheets(1).Range("B12").Value = "Felicidades"
Application.Workbooks("Mac01.xls").Worksheets("Hoja1").Range("B13").Value = "América"
' Application normalmente no se pone porque todo cuelga de Excel
' WorkBooks conviene ponerlo cuando se trabaja con varios libros
' WorkSheet conviene si se trabaja con varias hojas, aunque muchas veces no se pone
Range("B14")
Range( B14 ).Value
Value = 88.6
6 'Los
Los decimales con punto
Range("B15").Select
Application.ActiveWindow.ActiveCell.Value = "Adios"
' Señale con el ratón ActiveWindow y pulse F1 que es la ayuda
ActiveCell.Offset(1, 0).Value = "Bye"
ActiveCell.Offset(2, 0).Activate
ActiveCell.Value = "Hasta la vista"
ActiveSheet.Range("A1").Offset(17, 1).Value = "100%"
End Sub

03/08/2010 Adolfo Aparicio 4


L Estructura
La E t t With - End
E d With
z Sirve para ejecutar una serie de acciones sobre un mismo
Objeto, sin tener que repetir toda su jerarquía
z Ej.: Propiedades del objeto Range
Sub Escribe()
ActiveSheet.Range("C7").Value = "Cta. Resultados"
ActiveSheet.Range("C7").Font.Bold = True
ActiveSheet.Range("C7").Font.Color
ct eS eet a ge( C ) o t Co o = RGB(0, G (0, 255,
55, 0)
End Sub

Sub Escribe_bis()
With ActiveSheet.Range("C7")
.Value = "Cta. Resultados"
.Font.Bold = True
.Font.Color = RGB(0, 255, 0)
End With
End Sub

03/08/2010 Adolfo Aparicio 5


Di e InputBox
Dim I tB
z Option Explicit sirve para que nos obliguemos ha definir todas las variables
z Dim permite definir el tipo de variable
z Si no se definen las variables se toman como VARIAN que son las que más
ocupan
z InputBox permite capturar datos del usuario
z InputBox devuelve siempre datos tipo String
z Chr(13) es para cambiar de línea

Option Explicit

Sub Entrar_Valor()
Dim Texto As String
T
Texto = InputBox("Introducir
I B ("I d i un texto"" & Ch
Chr(13)
(13) & "P
"Para lla C
Casilla
ill D10"
D10", "E
"Entrada
d dde
Datos")
ActiveSheet.Range("D10").Value = Texto
End Sub

03/08/2010 Adolfo Aparicio 6


Di e InputBox
Dim I tB
InputBox(Mensaje, Título, Valor por defecto, Posición horizontal, Posición Vertical,
Archivoayuda, Número de contexto para la ayuda)

Sub Entrar_Valor_Bis()
'Este procedimiento es igual que el anterior pero no utiliza variables
ActiveSheet.Range("D11").Value _
= InputBox("Introducir un texto " & Chr(10) & "Para la casilla D11", "Entrada de datos")
'El guión bajo permite partir una línea de código demasiado larga. Ver Chr(10)
End Sub

Sub Entrar_Valor_Tris()
Entrar Valor Tris()
'En este caso se pide al usuario que entre la casilla donde se introducirá el texto
Dim Casilla As String 'Casilla puede ser por ejemplo D12
Dim Texto As String
Casilla = InputBox(
InputBox("EnEn que casilla quiere entrar el valor"
valor , "Entrar
Entrar Casilla")
Casilla )
Texto = InputBox("Introducir un texto" & Chr(13) _
& "Para la casilla " & Casilla, "Entrada de datos") ‘ Operador de concatenación &
ActiveSheet.Range(Casilla).Value = Texto
End Sub

03/08/2010 Adolfo Aparicio 7


Tipos de variables
Tipo de datos Tamaño de almacenamiento Intervalo
Byte 1 byte 0 a 255
Boolean 2 bytes True o False
Integer 2 bytes -32.768 a 32.767
Long (entero largo) 4 bytes -2.147.483.648 a 2.147.483.647
-3,402823E38
3,402823E38 a -1,401298E-45
1,401298E 45 para valores negativos;
Single
Si l (coma
( flotante/precisión
fl t t / i ió
4 bytes 1,401298E-45 a 3,402823E38 para valores
simple)
positivos
-1,79769313486232E308 a -4,94065645841247E-324
Double (coma flotante/precisión
8 bytes para valores negativos; 4,94065645841247E-324
doble)
a 1,79769313486232E308 para valores positivos
-922.337.203.685.477,5808 a
Currency (entero a escala) 8 bytes
922.337.203.685.477,5807
+/-79.228.162.514.264.337.593.543.950.335 sin punto
decimal; +/-7,9228162514264337593543950335
Decimal 14 bytes con 28 posiciones a la derecha del signo decimal;
el número más pequeño distinto de cero es +/-
/
0,0000000000000000000000000001
Date 8 bytes 1 de enero de 100 a 31 de diciembre de 9999
Object 4 bytes Cualquier referencia a tipo Object
String (longitud variable) 10 bytes + longitud de la cadena Desde 0 a 2.000 millones
String (longitud fija) Longitud de la cadena Desde 1 a 65.400 aproximadamente
Cualquier valor numérico hasta el intervalo de un tipo
Variant (con números) 16 bytes
Double
El mismo intervalo que para un tipo String de longitud
Variant (con caracteres) 22 bytes + longitud de cadena
variable
i bl
Definido por el usuario (utilizando Número requerido por los El intervalo de cada elemento es el mismo que el
Type)
03/08/2010 elementos Adolfo Aparicio intervalo de su tipo de datos. 8
Ejercicio 1
Crear un libro llamado “Rellena.xls”
Programar un procedimiento que nos pregunte en
que hoja queremos situarnos
Nos p g
pregunte en qque celda q
queremos situarnos
Nos pregunte lo que queremos escribir
El programa pone lo que hemos dicho y lo pone
de color
co o verde cursiva,
e de y cu sobre
s a, sob e fondo
o do rojo
ojo
Pista: ActiveCell.Interior.Color=RGB(x,y,z)
Ejecute el programa
Primero, dando una sola celda
Segundo. Cuando pida la celda introduzca un rango para
ver como funciona Range
¿Ha usado With – End With?
03/08/2010 Adolfo Aparicio 9
Suma dos números
z Val(Cadena). Convierte la cadena a un valor numérico
Val(Cadena)
z Str(Número). Convierte el número a una expresión cadena
z CBool, CByte, CCur, CCur, CDate, CDec, CInt, CLng, CSng, CStr, CVar

Sub Sumar()()
'Pide dos números y pone en una celda su suma
'Dim Numero1 As Integer
'Dim Numero2 As Integer
Numero1 = InputBox("Entrar el primer valor", "Entrada de datos")
Numero2 = InputBox(
InputBox("Entrar
Entrar el segundo valor"
valor , "Entrada
Entrada de datos
datos"))
Worksheets("Hoja1").Activate 'Esto se pone por si estamos en una hoja distinta de la Hoja1
ActiveSheet.Range("E10").Value = Numero1 + Numero2
End Sub

Sub Sumar_Bis()
Sumar Bis()
'Este procedimiento es similar al anterior
'En el procedimiento anterior si se mete como variable una palabra, da error.
'Por eso en este procedimiento añadimos la función Val
Dim Numero1 As Integer
Di Numero2
Dim N 2 As
A Integer
I t
Numero1 = Val(InputBox("Entrar el primer valor", "Entrada de datos"))
Numero2 = Val(InputBox("Entrar el segundo valor", "Entrada de datos"))
ActiveSheet.Range("E11").Value = Numero1 + Numero2
End Sub

03/08/2010 Adolfo Aparicio 10


Ejercicio 2
El siguiente programa no funciona bien
El á
área d
dell un rectángulo
tá l dde b
base 4
4,5
5 y altura
lt 5
5,5
5 es 24
24,75
75
Pero este programa da 24. El problema es que no da ERROR
Modifique el código del procedimiento para solucionarlo

Sub area()
Dim base As Integer
Dim altura As Integer
Dim superficie As Integer
'Los decimales se introducen con coma en un inputbox, y con punto en el código
altura = InputBox("Introduzca la altura del rectángulo")
base = InputBox("Introduzca la base del rectángulo")
superficie = base * altura
MsgBox ("El área del rectángulo es " & superficie)
End Sub
03/08/2010 Adolfo Aparicio 11
P bli – Private.
Public P i t Cells
C ll
z Public. Indica que el procedimiento Sub es accesible para todos
los demás procedimientos de todos los módulos
z Private. Indica que el procedimiento Sub es accesible sólo para
otros procedimientos del módulo en el que se declara
z Por defecto los procedimientos son Public
z Cells comienza a contar filas y columnas a partir del rango
especificado en el objeto Range
Cells(fila,columna)
Private Sub Celda()
Cells(12, 3).Value = "Solo " & 2
ActiveSheet.Cells(10, 6).Value = "Paris"
'La
La Celda 10,6 es la F10
Range("C13:D14").Value = "Cuadrado"
Range(Cells(15, 3), Cells(16, 4)).Value = "Cubo"
Range("C17:F20").Cells(2, 1).Value = "Elipse" 'Esto solo pone una elipse
End Sub
S

03/08/2010 Adolfo Aparicio 12


Variables de objetos
ƒ Una variable objeto sirve para hacer referencia a un objeto
objeto, esto significa
que podremos acceder a las propiedades de un objeto e invocar sus
métodos a través de la variable en lugar de hacerlo directamente a través
del objeto.
ƒ Para declarar una variable objeto
j se utiliza también la p
palabra Dim
Dim Var_Objeto As Objeto
ƒ Por Ejemplo
Dim R As Range
Dim Hoja As WorkSheet
ƒ Para asignar un objeto a una variable debe utilizar la instrucción Set
Set..
Set Variable_Objeto = Objeto
ƒ Por Ejemplo
Set R= ActiveSheet.Range("A1:B10")
Set Hoja = ActiveSheet
Set Hoja = WorkSheets(1)
ƒ A veces pude ser interesante desasignar una variable objeto
Dim Var_Objeto = Nothing
03/08/2010 Adolfo Aparicio 13
Variables de objetos
ƒ Posiblemente no se utilice demasiado esta clase de variables
(dependerá de las preferencias del programador), pero hay casos en
los que no hay más remedio que utilizarlas, por ejemplo en
estructuras For Each ... Next como veremos, o cuando sea necesario
construir funciones que devuelvan rangos
rangos, referencias a hojas
hojas, etc
etc.

Sub objeto()
Di R As
Dim A Range
R
Set R = ActiveSheet.Range("H21:I22")
R.Value = "Roma"
R.Font.Bold = True
R.Font.Color = RGB(0, 255, 100)
End Sub

03/08/2010 Adolfo Aparicio 14


E t
Estructuras
t Condicionales
C di i l
If Condición Then
S té i 1
Senténcia1
Senténcia2
.
.
SenténciaN
End If

Sub Condicional()
ActiveSheet.Range("E14").Value = 0
ActiveSheet.Range("E15").Value
ct eS eet a ge( 5 ) a ue = 0
ActiveSheet.Range("E16").Value = 0
ActiveSheet.Range("E14").Value = Val(InputBox("Entrar el precio", "Entrar"))
'Si el valor de la casilla E14 es mayor que 1000, entonces pedir descuento
If ActiveSheet.Range("E14").Value > 1000 Then
ActiveSheet.Range("E15").Value = Val(InputBox("Entrar Descuento", "Entrar"))
End If
ActiveSheet.Range("E16").Value = _
ActiveSheet.Range("E14").Value - ActiveSheet.Range("E15")
End Sub

03/08/2010 Adolfo Aparicio 15


E t
Estructuras
t Condicionales
C di i l
Sub Condicional_Bis()
'Igual que el procedimiento anterior pero ahora usando variables
Dim Precio As Integer
Di Descuento
Dim D t AsA IInteger
t
Precio = 0
Descuento = 0
Precio = Val(InputBox("Entrar el precio", "Entrar"))
' Si el valor de la variable precio es mayor que 1000, entonces, pedir descuento
If Precio > 1000 Then
Descuento = Val(InputBox("Entrar descuento", "Entrar"))
End If
ActiveSheet.Range("F14").Value = Precio
ActiveSheet.Range("F15").Value = Descuento
ActiveSheet.Range("F16").Value = Precio - Descuento
End Sub

Sub Condicional2()
If ActiveSheet.Range("F14").Value = ActiveSheet.Range("F16").Value Then
ActiveSheet.Range("F14").Font.Color = RGB(0, 0, 255)
ActiveSheet.Range("F16").Font.Color = RGB(0, 0, 255)
End If
End Sub

03/08/2010 Adolfo Aparicio 16


Estructuras Condicionales.
Else
El
Sub Condicional_Else()
Dim Precio As Single
Dim Descuento As Single
Precio = 0
Descuento = 0
Precio = Val(InputBox("Entrar el precio", "Entrar"))
' Si el valor de la variable precio es mayor que 1000,
1000 entonces,
entonces aplicar descuento del 10%
If Precio > 1000 Then
Descuento = Precio * (10 / 100)
ActiveSheet.Range("G13").Value = 0.1
Else ' Sino Aplicar descuento del 5%
Descuento = Precio * (5 / 100)
ActiveSheet.Range("G13").Value = 0.05
End If
g ( )
ActiveSheet.Range("G14").Value = Precio
ActiveSheet.Range("G15").Value = Descuento
ActiveSheet.Range("G16").Value = Precio - Descuento
End Sub

03/08/2010 Adolfo Aparicio 17


Estructuras Condicionales.
Else
Sub Condicional_Else2()
'Ponga valores en G10 y en G11.
'La macro calcula la diferencia la pone en G12 y asigna color
ActiveSheet.Range("G12").Value = ActiveSheet.Range("G10").Value -
ActiveSheet.Range("G11").Value
If Range("G12").Value < 0 Then
'Si la diferencia es negativa pone color rojo
ActiveSheet.Range("G12").Font.Color = RGB(255, 0, 0)
Else
'En caso contrario pone color azul
ActiveSheet Range("G12")
ActiveSheet.Range( G12 ).Font.Color
Font Color = RGB(0
RGB(0, 0
0, 255)
End If
End Sub

03/08/2010 Adolfo Aparicio 18


El valor Nothing
z Algunas veces puede que sea necesario desasignar una variable del objeto al cual hace
referencia, en este caso debe igualar la variable al valor Nothing de la forma siguiente.
Set Variable_Objeto = Nothing
z Habitualmente se utiliza Nothing en una estructura condicional para comprobar si la variable
objeto está asignada. Observe que si se utiliza una variable objeto a la cual todavía no se le ha
hecho ninguna asignación el programa dará error y detendrá su ejecución. Es buena práctica
hacer este tipo de comprobaciones antes de trabajar con variables objeto.

Sub
S b objeto_Bis()
bj Bi ()
Dim R As Range
Set R = ActiveSheet.Range("E12:F13")
R.Value = "Milan"
R.Font.Bold = True
Set R = Nothing 'Nothing permite asigna a la variable objeto un valor nulo.
' Esto es útil junto con un IF para verificar si la variable esta asignada
If R Is Nothing Then
MsgBox Prompt:="La variable Objeto no ha sido asignada", Buttons:=vbOK, _
Title:="Error"
Else
R.Value = "Hola"
End If
End Sub

03/08/2010 Adolfo Aparicio 19


C di i
Condicionales
l anidadas
id d
Sub Condicional_doble()
g
Dim a As Integer
Dim b As Integer
Dim C As String
a = ActiveSheet.Range("G10").Value
b = ActiveSheet.Range("G11").Value
If a = b Then
C = "Los valores de G10 y G11 son iguales"
Else
If a > b Then
C = "G10 es mayor que G11"
Else
C = "G10 es menor que G11"
End If
End If
ActiveSheet.Range("G9").Value = C
End Sub

03/08/2010 Adolfo Aparicio 20


El If
ElseIf
z El procedimiento anterior se puede abreviar con un EsleIf
If condición 1 Then Sub Condicional_doble_2()
Condicional doble 2()
Sentencia 1 Dim a As Integer
Sentencia 2 Dim b As Integer
ElseIf condición 2 Then Dim C As String
Sentencia 3 a = ActiveSheet
ActiveSheet.Range(
Range("G10")
G10 ).Value
Value
Sentencia 4 b = ActiveSheet.Range("G11").Value
ElseIf condición 3 Then If a = b Then
Sentencia 5 C = "Los valores de G10 y G11 son iguales“
Sentencia 6 ElseIf abrevia dos condicuonales anidados
'ElseIf
ElseIf condición 4 Then ElseIf a > b Then
Sentencia 7 C = "G10 es mayor que G11"
Sentencia 8 Else
Else C = "G10 es menor q
que G11"
Sentencia 9 End If
Sentencia 10 ActiveSheet.Range("G9").Value = C
EndIf End Sub

03/08/2010 Adolfo Aparicio 21


Operador
p Lógico
g AND
Sub YAcero() 'Uso del condicional AND
Dim Producto As String, Cantidad As String, Precio As Single
Dim Total As Single, Descuento As Single, Total_Descuento As Single
Precio = 0 'UCase convierte a mayúsculas
Producto = UCase(InputBox("Entrar nombre del Producto", "Entrar"))
Precio = Val(InputBox("Entrar Precio", "Entrar"))
Cantidad = Val(InputBox("Entrar Cantidad", "Entrar"))
Total = Precio * Cantidad
ActiveSheet Range("H10")
ActiveSheet.Range( H10 ).Value
Value = Producto
ActiveSheet.Range("H11").Value = Precio
ActiveSheet.Range("H12").Value = Cantidad
ActiveSheet.Range("H13").Value = Total
'Si el Total es mayor que 10000 y el producto es Acero, aplicar descuento
If Total > 10000 And Producto = "ACERO" Then
Descuento = Val(InputBox("Entrar Descuento", "Entrar"))
Total_Descuento = Total * (Descuento / 100)
Total = Total - Total_Descuento
Acti eSheet Range("H14") Val e = Total_Descuento
ActiveSheet.Range("H14").Value Total Desc ento
ActiveSheet.Range("H15").Value = Total
End If
Range("H12").NumberFormat = "#,##0“'Formato de Celdas
Range("H11,H13,H14,H15").NumberFormat
g ( , , , ) = "#,##0.00
, $
$"
End Sub

03/08/2010 Adolfo Aparicio 22


Operador
p Lógico
g OR
Sub OAcero() ' Condicional OR
Dim Producto As String, Cantidad As Integer, Precio As Single
Dim Total As Single, Descuento As Single, Total_Descuento As Single
P
Precio
i =0
'LCase convierte a minúsculas
Producto = LCase(InputBox("Entrar Nombre del Producto", "Entrar"))
Precio = Val(InputBox("Entrar el Precio", "Entrar"))
Cantidad = Val(InputBox("Entrar
( p ( la Cantidad",, "Entrar"))
))
Total = Precio * Cantidad
ActiveSheet.Range("I10").Value = Producto
ActiveSheet.Range("I11").Value = Precio
ActiveSheet.Range("I12").Value = Cantidad
ActiveSheet.Range("I13").Value
i Sh (" 3") l = Totall
'si Total es mayor de 10.000 o el producto es Acero, aplicar descuento
If Total > 10000 Or Producto = “acero" Then
Descuento = Val(InputBox("Entrad Descuento", "Entrar"))
Total Descuento = Total * (Descuento / 100)
Total_Descuento
Total = Total - Total_Descuento
ActiveSheet.Range("I14").Value = Total_Descuento
ActiveSheet.Range("I15").Value = Total
End If
End Sub

03/08/2010 Adolfo Aparicio 23


Operador
p Lógico
g NOT
Sub operadorNO()
Dim Precio As Integer
Dim Descuento As Integer
Precio = 0
Descuento = 0
Precio = Val(InputBox("Entrar
( p ( el Precio",, "Entrar"))
))
' Si el valor de la variable precio NO es menor o igual que
1000,
' entonces pedir descuento
If Not Precio
P ecio <
<= 1000 Then
Descuento = Val(InputBox("Entrar Descuento", "Entrar"))
End If
ActiveSheet.Range("B19").Value
ActiveSheet.Range( B19 ).Value = Precio
ActiveSheet.Range("B20").Value = Descuento
ActiveSheet.Range("B21").Value = Precio - Descuento
End Sub

03/08/2010 Adolfo Aparicio 24


Tablas de Verdad
A B C NO(A) Y(A;B;C) O(A;B;C)

VERDADERO VERDADERO VERDADERO FALSO VERDADERO VERDADERO

VERDADERO VERDADERO FALSO FALSO FALSO VERDADERO

VERDADERO FALSO VERDADERO FALSO FALSO VERDADERO

VERDADERO FALSO FALSO FALSO FALSO VERDADERO

FALSO VERDADERO VERDADERO VERDADERO FALSO VERDADERO

FALSO VERDADERO FALSO VERDADERO FALSO VERDADERO

FALSO FALSO VERDADERO VERDADERO FALSO VERDADERO

FALSO FALSO FALSO VERDADERO FALSO FALSO

03/08/2010 Adolfo Aparicio 25


Calculadora
z Macro que suma,
suma resta,
resta multiplica o divide los valores de las casillas C19 y C20 dependiendo de si C21 contiene
el signo +, -, x, :
z El resultado lo deja en C22. Si en C21 no hay ninguno de los signos anteriores en C22 debe dejarse un 0

Sub Calculadora()
Dim Signo
g As String g * 1 'Un solo carácter alfanumérico
Dim Valor1 As Integer, Valor2 As Integer, Total As Integer
Valor1 = ActiveSheet.Range("C19").Value
Valor2 = ActiveSheet.Range("C20").Value
Signo = ActiveSheet.Range("C21").Value
Total = 0
If Signo = "+" Then
Total = Valor1 + Valor2
End If
If Signo = "-" Then
Total = Valor1 - Valor2
End If
If Signo = "x" Then
Total = Valor1 * Valor2
End If
If Signo = ":"
: Then
Total = Valor1 / Valor2
End If
ActiveSheet.Range("C22").Value = Total
End Sub

03/08/2010 Adolfo Aparicio 26


La estructura Select Case
z La estructura Select Case da mayor legibilidad al programa anterior

Sub calcula_case()
calcula case()
Dim Signo As String * 1
Dim Valor1 As Integer, Valor2 As Integer, Total As Integer
Valor1 = ActiveSheet.Range("D19").Value
Valor2 = ActiveSheet.Range("D20").Value
Signo = ActiveSheet
ActiveSheet.Range("D21").Value
Range("D21") Value
Select Case Signo
Case "+"
Total = Valor1 + Valor2
Case "-"
T t l = Valor1
Total V l 1 - Valor2
V l 2
Case "x"
Total = Valor1 * Valor2
Case “:"
Total = Valor1 / Valor2
Case Else
Total = 0
End Select
ActiveSheet.Range("D22").Value = Total
End Sub

03/08/2010 Adolfo Aparicio 27


Ejercicio

Cree un programa que pregunte la


fecha de nacimiento, calcule cuantos
días han transcurrido hasta el
momento actual y diga en qué día de
la semana nació
nació.

03/08/2010 Adolfo Aparicio 28


Solución Ejercicio
Sub nacimiento()
Dim dias As Integer, Dsemana As Integer, Factual As Date, d As String
'Dsemana es una variable que da un número que indica el día de la semana
'dado por la función WEEKDAY, que en Excel es =DIASEM(fecha)
Static Fnacimiento As Date
Factual = Date 'Date es la función de VBA equivalente a =HOY()
Fnacimiento = Factual
Fnacimiento = InputBox(Prompt:="Introduzca su fecha de nacimiento", Title:="Formato DD-MM-AAAA",
Default:=Fnacimiento))
dias = Factual - Fnacimiento
Dsemana = Application.WorksheetFunction.Weekday(Fnacimiento)
Select Case Dsemana
Case 1: d = "Domingo"
Case 2: d = "Lunes"
Case 3: d = "Martes"
Case 4: d = "Miercoles"
Case 5: d = "Jueves"
Case 6: d = "Viernes"
Case 7: d = "Sabado"
End Select
MsgBox Prompt:="Usted nació un " & d & " hace " & dias & " días" & Chr(10), Title:="Esta información es
correcta siempre que hoy sea " & Factual
End Sub
03/08/2010 Adolfo Aparicio 29
Cada sentencia Case evalúa un rango de valores
Sub Media()
Dim Nota1 As Single, Nota2 As Single, Nota3 As Single
Dim califica As String, Media As Single
Nota1 = CSng(InputBox(
CSng(InputBox("Entrar
Entrar Nota primera evaluación
evaluación", "Nota"))
Nota ))
Nota2 = CSng(InputBox("Entrar Nota Segunda evaluación", "Nota"))
Nota3 = CSng(InputBox("Entrar Nota Tercera evaluación", "Nota"))
Media = (Nota1 + Nota2 + Nota3) / 3
ActiveSheet.Range("C17").Value = Nota1
ActiveSheet Range("D17")
ActiveSheet.Range( D17 ).Value
Value = Nota2
ActiveSheet.Range("E17").Value = Nota3
ActiveSheet.Range("D18").Value = Media
Select Case Media
Case Is < 5
califica
lifi = "S"Suspenso""
Case 5 To 6.99
califica = "Aprobado"
Case 6.99 To 8.99
califica = "Notable"
Case Is > 8, 99
califica = "Sobresaliente"
End Select
ActiveSheet.Range("E18").Value = califica
End Sub

03/08/2010 Adolfo Aparicio 30


Select Case y Filtros
Sub con_case_y_filtro() If IsEmpty(ActiveSheet.Range("E21")) Then
Dim Signo As String MsgBox Prompt:="la casilla E21 está vacía",
Dim Valor1 As Variant, Valor2 As Variant, Total As Title:="ERROR"
Single Continuar = False
Dim Continuar As Boolean End If
Valor1 = ActiveSheet.Range("E19").Value If Continuar Then
Valor2 = ActiveSheet.Range("E20").Value Select Case Signo
Signo = ActiveSheet.Range("E21").Value Case "+"
Continuar = True Total = Valor1 + Valor2
' Si en la casilla E19 no ha
hay un
n valor
alor n
numérico
mérico Case "-"
""
If Not IsNumeric(ActiveSheet.Range("E19")) Then Total = Valor1 - Valor2
MsgBox Prompt:="En E19 no hay ningún valor Case "x"
numérico", Title:="ERROR" Total = Valor1 * Valor2
Continuar = False Case "/"
End If Total = Valor1
1 / Valor2
2
' Si en la casilla E20 no hay un valor numérico Case Else
If Not IsNumeric(ActiveSheet.Range("E20")) Then Total = 0
MsgBox Prompt:="En E20 no hay ningún valor End Select
numérico", Title:="ERROR" ActiveSheet.Range("E22").Value = Total
Continuar = False End If
End If End Sub

03/08/2010 Adolfo Aparicio 31


Lista de Funciones de
C
Comprobación
b ió
z IsNuméric(Expresión)
z Comprueba si expresión tiene un valor que se puede interpretar como 'numérico.
z IsDate(Expresión)
z Comprueba si expresión tiene un valor que se puede interpretar como tipo fecha.
z IsEmpty(Expresión)
z Comprueba que expresión tenga algún valor, que se haya inicializado.
z I E
IsError(Expresión)
(E ió )
z Comprueba si expresión devuelve algún valor de error.
z IsArray(Expresión)
z Comprueba si expresión (una variable) es un array o no.
z IsObject(Expresión)
z Comprueba si expresión (una variable) representa una variable tipo objeto.
z IsNull(Expresión)
z Comprueba si expresión contiene un valor nulo debido a datos no válidos.
z Nothing
g
z No es propiamente una función, sirve para comprobar si una variable objeto esta 'asociada a un
objeto antes de hacer cualquier operación con ella. Recuerde que para trabajar con 'una variable
objeto antes debe asignarse a uno (mediante la instrucción Set), en caso contrario se producirá un
error en el programa cuando utilice el objeto y se detendrá su ejecución.

03/08/2010 Adolfo Aparicio 32


Select Case y Filtro
Sub con_case_y_filtro_Bis()
' En lugar de los tres If de comprobación se puede utilizar el operador OR de la manera siguiente
Dim Signo As String
Dim Valor1 As Variant, Valor2 As Variant, Total As Single
Di Continuar
Dim C ti A Boolean
As B l
Valor1 = ActiveSheet.Range("F19").Value
Valor2 = ActiveSheet.Range("F20").Value
Signo = ActiveSheet.Range("F21").Value
Continuar = True
' Si en la casilla F19 no hay un valor numérico
If Not IsNumeric(ActiveSheet.Range("F19")) Or Not IsNumeric(ActiveSheet.Range("F20")) Or
IsEmpty(ActiveSheet.Range("F21")) Then
MsgBox Prompt:="Debe entrar número en F19, F20 y un signo (+,-,x,/) en F21", Title:="ERROR"
Else
S
Select Case
C S
Signo
Case "+“: Total = Valor1 + Valor2
Case "-“: Total = Valor1 - Valor2
Case "x“: Total = Valor1 * Valor2
Case "/“: Total = Valor1 / Valor2
Case Else: Total = 0
End Select
ActiveSheet.Range("F22").Value = Total
End If
End Sub

03/08/2010 Adolfo Aparicio 33


La función MsgBox (F1)
z Muestra un mensaje en un cuadro de diálogo hasta que el usuario pulse un botón.
La función devuelve un dato tipo Integer en función del botón pulsado por el
usuario. A la hora de invocar está función, se permiten diferentes tipos de
botones.
MsgBox( Mensaje, Botones, Título, Archivo de ayuda, contexto)
z Mensaje: Obligatorio, es el mensaje que se muestra dentro del cuadro de diálogo.
z Botones: Opcional. Es un número o una suma de números o constantes, que
sirve para mostrar determinados botones e iconos dentro del cuadro de diálogo
diálogo.
Si se omite este argumento asume valor 0 que corresponde a un único Botón OK.
z Título : Opcional. Es el texto que se mostrará en la barra del título del cuadro de
diálogo.
MsgBox Prompt:="En la casilla A1 no hay ningún valor numérico"
numérico", Title:="ERROR"
MsgBox Prompt := "La variable Objeto no ha sido asignada", Buttons:=vbOk, Title := "Error"
X= MsgBox ("Hola usuario, Ha acabado el proceso", VbOkOnly, "Mensaje")
X=MsgBox("Desea Continuar", vbYesNo + vbQuestion, "Opción",,)
Mas datos = MsgBox(
Mas_datos MsgBox("Otro
Otro registro ?"
? , vbYesNo+vbQuestion,
vbYesNo+vbQuestion "Entrada
Entrada de datos
datos"))
MsgBox Prompt:=Texto, Buttons:=vbOKOnly + vbInformation, Title:=Titulo
MsgBox ("Debe introducir valores numéricos")

03/08/2010 Adolfo Aparicio 34


MsgBox
Sub MesajeCaja()
Dim nom As String, Respuesta As Integer
nom = "Antonio"
MsgBox ("Hola " & nom) 'Se pueden poner paréntesis o no
MsgBox "Hola " & nom
MsgBox "Mire el Título", , "Aqui se puede poner el título que se desee"
MsgBox "Observe este texto" & vbCrLf & "que ocupa" & vbCrLf & "tres líneas",, "Título"
MsgBox "Mire el icono de" & vbCrLf & "Interrogación", vbQuestion, _
"Icono de Interrogación"
MsgBox "Otro icono", vbCritical, "Icono Crítico" 'Sonido
MsgBox "Otro", vbExclamation, "Icono Exclamación" 'Sonido
MsgBox "Otro más", vbInformation, "Icono Información" 'Sonido
Respuesta = MsgBox("Observe que al incluir más" & vbCrLf & _
"de un botón, en el MsgBox" & vbCrLf & "pongo paréntesis y utilizo" _
& vbCrLf & "una variable qque recogerá"
g & vbCrLf & "el botón qque hemos p
pulsado",, _
vbYesNo + vbQuestion, "Dos Botones")
MsgBox "La Respuesta ha sido " & Respuesta, , "Respuesta"
Respuesta = MsgBox("Tres Botones", vbYesNoCancel + vbInformation, _
"Con icono de Información") 'Con paréntesis necesariamente
MsgBox "La
La Respuesta ha sido " & Respuesta,
Respuesta , "Respuesta"
Respuesta
Respuesta = MsgBox("Tres Botones pero" & vbCrLf & "el activo es el segundo", _
vbAbortRetryIgnore + vbCritical + vbDefaultButton2, "Icono Crítico")
MsgBox "La Respuesta ha sido " & Respuesta, , "Respuesta"
End Sub

03/08/2010 Adolfo Aparicio 35


I
InputBox
tB
z Variable = InputBox (mensaje, Titulo, Defecto, Coordenada Horizontal,
Coordenada Vertical))
z Las coordenadas se miden en Twips desde el extremo superior
izquierdo de la ventana
z 1 cm = 566 Twips
z 1 pixel = 15 Twips

Sub InputCaja()
Dim Respuesta As String
Respuesta = InputBox("Primera Línea" & vbCrLf & Chr(9) _
& "Segunda Línea con Tabulador Chr(9)", "Aquí el Título") 'Chr(10) equivale a vbCrLf
Respuesta = InputBox("Haz clic en [Cancel]", "A ver que pasa si se cacela")
MsgBox "Al pulsar Calcelar el resultado es = " & Respuesta 'Respuesta nula ""
Respuesta = InputBox("Aparece un valor por defecto", "Título", "Aparece esto por defecto")
Respuesta = InputBox("Situo la ventana", "1200 Twips a la derecha y 1400 hacia abajo", "coordenadas
1200x1400", 1200, 1400)
Respuesta = InputBox("Otra posición", , "1 cm = 566 Twips y 1 pixel = 15 Twips", 50, 75)
E dS
End Subb

03/08/2010 Adolfo Aparicio 36


La instrucción With (repaso)
Sub OAcero_with() ' Si total mayor que 10.000 o el producto es Acero,
Dim Producto As String aplicar descuento.
Dim Cantidad As Integer If Total > 10000 Or Producto = "Acero" Then
Dim Precio As Single Descuento = Val(InputBox("Entrar Descuento",
Di Total
Dim T t l As
A Single
Si l "Entrar"))
Entrar ))
Dim Descuento As Single Total_Descuento = Total * (Descuento / 100)
Dim Total_Descuento As Single Total = Total - Total_Descuento
Precio = 0 With ActiveSheet
Producto = LCase(InputBox("Entrar
( p ( Nombre del .Range("J14").Value = Total_Descuento
Producto", "Entrar")) .Range("J15").Value = Total
Precio = Val(InputBox("Entrar el precio", "Entrar")) End With
Cantidad = Val(InputBox("Entrar la cantidad", "Entrar")) End If
Total = Precio * Cantidad End Sub
With ActiveSheet
.Range("J10").Value = Producto
.Range("J11").Value = Precio
.Range("J12").Value = Cantidad
.Range("J13").Value
g ( ) = Total
End With

03/08/2010 Adolfo Aparicio 37


E t
Estructuras
t repetitivas
titi
Sub Media_notas() Nota = Val(InputBox("Entrar la Nota 3: ", "Entrar
Dim Nota As Integer Nota"))
Dim Media As Single A ti Sh t R
ActiveSheet.Range("G19").Value
("G19") V l = N Nota
t
Media = Media + Nota
Media = 0
Nota = Val(InputBox("Entrar la Nota 4: ", "Entrar
'Observe que este
'Ob t programa repite
it ell siguiente
i i t Nota"))
Nota ))
bloque de sentencias, 5 veces ActiveSheet.Range("G20").Value = Nota
Media = Media + Nota
Nota = Val(InputBox("Entrar la Nota 1: ", "Entrar
Nota"))
Nota )) Nota = Val(InputBox(
Val(InputBox("Entrar
Entrar la Nota 5: ",, "Entrar
Entrar
ActiveSheet.Range("G17").Value = Nota Nota"))
Media = Media + Nota ActiveSheet.Range("g21").Value = Nota
Media = Media + Nota
( p (
Nota = Val(InputBox("Entrar la Nota 2: ", "Entrar
Nota")) Media = Media / 5
ActiveSheet.Range("G18").Value = Nota ActiveSheet.Range("G22").Value = Media
Media = Media + Nota End Sub

03/08/2010 Adolfo Aparicio 38


B l F
Bucle For … Next
N t
Sub Totalizar()

Dim i As Integer
Dim Total As Integer
Dim Valor As Integer

For i = 1 To 10
a o = Val(InputBox("Entrar
Valor a ( put o ( ta e el valor
a o " & i,, "Entrada"))
t ada ))
Total = Total + Valor
Next i

ActiveSheet.Range("C11").Value = Total
End Sub

03/08/2010 Adolfo Aparicio 39


Recorrer casillas de una Hoja
z Propiedad Cells
z sirve p
para referenciar una celda o un rango
g de celdas
según coordenadas de fila y columna
Sub rellenar() 'Rellena de H16 a H20 con los pares del 2 al 10
Dim Filaa Ass Integer,
tege , i Ass Integer
tege
Fila = 16
For i = 2 To 10 Step 2
ActiveSheet.Cells(Fila, 8).Value = i
Fila = Fila + 1 'Esto es un contador
Next i
End Sub
Sub rellenar_Bis() 'Rellena de H16 a H20 con los pares del 2 al 10, sin contador Fila
Dim i As Integer
g
For i = 16 To 20
ActiveSheet.Cells(i, 9).Value = i * 2 - 30
Next i
End Sub

03/08/2010 Adolfo Aparicio 40


Rellenar una serie
z Llenar un rango de filas, empezando por una celda, que se debe especificar desde
teclado, con una serie de 10 valores correlativos (comenzando por el 1).

Sub serie()
Dim Casilla_Inicial As String
Dim i As Integer
Di Fila
Dim Fil As
A Integer,
I C l
Columna A Integer
As I
Casilla_Inicial = InputBox("Introducir la casilla Inicial : “ & chr(10) & “Por ejemplo la K10”,
"Casilla Inicial")
ActiveSheet.Range(Casilla_Inicial).Activate
Fila = ActiveCell.Row
ActiveCell Row
Columna = ActiveCell.Column
'ROW y COLUMN devuelven la fila y la columna de un objeto range.
'en este caso se utilizan para obtener la fila y la columna de la casilla activa.
For i = 1 To 10
ActiveSheet.Cells(Fila, Columna).Value = i
Fila = Fila + 1
Next i
End Sub

03/08/2010 Adolfo Aparicio 41


Rellenar una serie
z Recuerde que cuando utilizamos Cells como propiedad de un rango (Objeto Range),
Cells empieza a contar a partir de la casilla referenciada por Range

Sub serie_Bis()
Dim Casilla_Inicial As String
Dim i As Integer
g
Dim Fila As Integer, Columna As Integer
Casilla_Inicial = InputBox("Introducir la casilla Inicial : " & chr(10) & “Por ejemplo
la L10”, "Casilla Inicial")
ActiveSheet Range(Casilla Inicial) Activate
ActiveSheet.Range(Casilla_Inicial).Activate
Fila = 1
For i = 1 To 10
ActiveSheet.Range(Casilla_Inicial).Cells(Fila, 1).Value = i
Fila = Fila + 1
Next i
End Sub

03/08/2010 Adolfo Aparicio 42


Rellenar una serie
z Una variante del programa anterior.
z No se usa Fila, se usa la variable del For

Sub serie_Tris()
Dim Casilla_Inicial As String
Dim i As Integer
Dim Fila As Integer, Columna As Integer
Casilla_Inicial = InputBox("Introducir la casilla Inicial : " & chr(10) &
“Por ejemplo la M10”, "Casilla Inicial")
ActiveSheet.Range(Casilla_Inicial).Activate
‘ Activate (con Range) activa una sola celda. Range("B2").Activate
‘ Para seleccionar un rango de celdas, use el método Select. Range("A1:C3").Select
For i = 1 To 10
ActiveSheet.Range(Casilla_Inicial).Cells(i, 1).Value = i
Next i
E dS
End Sub b
03/08/2010 Adolfo Aparicio 43
For-Next
For Next y Cells
z Volvemos a calcular las notas medias, pero usando la estructura For_Next y la
propiedad Cells

Sub Media_notas_Bis()
Dim Nota As Integer
Dim Media As Single
Dim Fila As Integer
Media = 0
For Fila = 1 To 5
( p (
Nota = Val(InputBox("Entrar la " & " Nota " & Fila, "Entrar Nota"))
))
ActiveSheet.Range(“N10").Cells(Fila, 1) = Nota
'lo de Range(“N10") se pone para marcar la celda de inicio,
'si no se pone comienza en A1
Media = Media + Nota 'esto
esto es un acumulado
Next Fila
Media = Media / 5
ActiveSheet.Range(“N10").Cells(6, 1).Value = Media
End Sub

03/08/2010 Adolfo Aparicio 44


P i d d Off
Propiedad Offsett
z Esta propiedad es también muy útil a la hora de
recorrer rango.
z Offset, que significa desplazamiento, es una
propiedad del objeto Range y se utiliza para
referenciar una casilla situada a n Filas y n
Columnas de una casilla dada.
z Ejemplos:
z ActiveSheet.Range("A1").Offset(2, 2).Value = "Hola“
z Casilla C3 = Hola, 2 filas y 2 columnas desde A1.
z ActiveCell Offset(5 1) Value = "Hola“
ActiveCell.Offset(5,1).Value Hola
z 5 Filas por debajo de la casilla Activa = Hola
z ActiveCell.Offset(2,2).Activate
z Activar la casilla que está 2 filas y 2 columnas de la activa

03/08/2010 Adolfo Aparicio 45


For-Next y Offset.
Sin cambiar celda activa
z Recorrer rangos con la propiedad OffSet (desplazamiento)

Sub Media_notas_Tris()
Dim Nota As Integer
Dim Media As Single
Dim Fila As Integer
Media = 0
ActiveSheet.Range("O10").Activate 'la casilla activa siempre es la misma
For Fila = 0 To 4
Nota = Val(InputBox("Entrar la " & " Nota " & Fila + 1, "Entrar Nota"))
ActiveCell.Offset(Fila, 0).Value = Nota
Media = Media + Nota
Next Fila
Media = Media / 5
ActiveCell.Offset(5, 0).Value = Media
End Sub

03/08/2010 Adolfo Aparicio 46


For-Next y Offset.
Cambia Celda Activa
Sub Media_notas_Tetra()
Dim Nota As Integer
Dim Media As Single
Dim i As Integer
Media = 0
ActiveSheet Range("P10")
ActiveSheet.Range( P10 ).Activate
Activate
For i = 1 To 5
Nota = Val(InputBox("Entrar la " & " Nota " & i, "Entrar Nota"))
ActiveCell.Value = Nota
Media = Media + Nota
'Hacer activa la casilla situada una fila por debajo de la actual
ActiveCell.Offset(1, 0).Activate
Next i
Media = Media / 5
ActiveCell.Value = Media
End Sub

03/08/2010 Adolfo Aparicio 47


D Whil
Do While..Loop
L
Estructura Repetitiva (Hacer Mientras)
z La estructura repetitiva FOR se adapta perfectamente a aquellas
situaciones en que se sabe previamente el número de veces que
se ha de repetir un proceso
z Do While..Loop p es una estructura repetitiva
p q
que se repite
p
mientras se cumpla el criterio

Do While Condición z En las sentencias interiores se


Sentencia1 tiene que producir en algún
Sentencia2 momento un cambio que haga
. que la condición deje
q j de
. cumplirse para así poder salir
Sentencia N
del bucle.
Loop

03/08/2010 Adolfo Aparicio 48


Rellenar una Base de Datos
Sub Registros() Do While Nombre <> ""
'Rellenar los registros de una Base de Datos. Hoja3 Ciudad = InputBox("Entre la Ciudad : ", "Ciudad")
Dim Nombre As String, Ciudad As String Edad = Val(InputBox("Entre la Edad : ", "Edad"))
Dim Edad As Integer, Fecha As Date Fecha = CDate(InputBox("Entra la Fecha : ", "Fecha"))
'Activar Hoja3 'Copiar los datos en las casillas correspondientes
Worksheets("Hoja3").Activate
( j ) With ActiveCell
With ActiveSheet .Value = Nombre
.Range("B4").Value = "Nombre" .Offset(0, 1).Value = Ciudad
.Range("C4").Value = "Ciudad" .Offset(0, 2).Value = Edad
.Range("D4").Value = "Edad" .Offset(0, 3).Value = Fecha
.Range(
Range("E4")
E4 ).Value
Value = "Fecha"
Fecha End With
End With 'Hacer activa la celda de la fila siguiente a la actual
'Para poner negrita y centrar la cabecera ActiveCell.Offset(1, 0).Activate
Range("B4:E4").Select Nombre = InputBox("Entre el Nombre (Return para
With Selection Terminar) : ", "Nombre")
.Font.Bold
Font Bold = True Loop 'pide
pide nuevos datos mientras nombre no este vacío
.HorizontalAlignment = xlCenter 'Seleccionamos la Base de Datos y la ponemos amarilla
End With Application.Goto Reference:="R4C2"
'Activar casilla B5 Selection.CurrentRegion.Select
ActiveSheet.Range("B5").Activate With Selection.Interior
Nombre = InputBox("Entre
Inp tBo ("Entre el Nombre (Return
(Ret rn para Terminar) ColorIndex = 6
.ColorIndex
: ", "Nombre") .Pattern = xlSolid
'Mientras la variable Nombre sea diferente a cadena vacía End With
End Sub

03/08/2010 Adolfo Aparicio 49


Detecta donde nos hemos quedado
Sub Registros_Bis() Do While Nombre <> ""
Dim Nombre As String Ciudad = InputBox("Entre la Ciudad : ",
Dim Ciudad As String "Ciudad")
Dim Edad As Integer Edad = Val(InputBox("Entre
Val(InputBox( Entre la Edad : ",
Dim Fecha As Date "Edad"))
Worksheets("Hoja3").Activate Fecha = CDate(InputBox("Entra la Fecha
: ", "Fecha"))
ActiveSheet.Range("B4").Activate
With ActiveCell
Buscar la primera celda vacía de la columna
'Buscar
B y convertirla en activa .Value = Nombre
Do While Not IsEmpty(ActiveCell) .Offset(0, 1).Value = Ciudad
ActiveCell.Offset(1, 0).Activate .Offset(0, 2).Value = Edad
Loopp .Offset(0, 3).Value = Fecha
Nombre = InputBox("Entre el Nombre End With
(Return para Terminar) : ", "Nombre") ActiveCell.Offset(1, 0).Activate
' Mientras la variable Nombre sea diferente a Nombre = InputBox("Entre el Nombre
cadena vacía (Return para Terminar) : ", "Nombre")
Loop
End Sub

03/08/2010 Adolfo Aparicio 50


¿Desea introducir más datos ?
Sub Registros_Tris() Do While Mas_datos = vbYes
Dim Nombre As String Nombre = InputBox("Entre el Nombre: ",
Dim Ciudad As String "Nombre")
Dim Edad As Integer Ciudad = InputBox("Entre
p ( la Ciudad : ",, "Ciudad"))
Dim Fecha As Date Edad = Val(InputBox("Entre la Edad : ", "Edad"))
Dim Mas_datos As Integer 'Mas_datos es Fecha = CDate(InputBox("Entra la Fecha : ",
una variable de tipo Integer "Fecha"))
Worksheets("Hoja3").Activate With ActiveCell
A ti Sh t R
ActiveSheet.Range("B4").Activate
("B4") A ti t .Value
Value = Nombre
'Buscar la primera celda vacía de la .Offset(0, 1).Value = Ciudad
columna B y convertirla en activa .Offset(0, 2).Value = Edad
Do While Not IsEmpty(ActiveCell) .Offset(0, 3).Value = Fecha
ActiveCell.Offset(1, 0).Activate End With
Loop ActiveCell.Offset(1, 0).Activate
Mas_datos = vbYes 'Preguntar al usuario si desea entrar otro registro
'es necesaria la línea anterior al bucle Mas_datos = MsgBox("Otro registro ?", vbYesNo +
Mas_datos = vbYes, para que cuando se vbQuestion, "Entrada de datos")
evalúe la Loop
'condición por vez primera esta se cumpla y End Sub
se ejecuten las sentencias de dentro del bucle

03/08/2010 Adolfo Aparicio 51


E t
Estructura
t Do..Loop
D L While
Whil
z El funcionamiento de esta estructura repetitiva es similar a la
anterior salvo que la condición se evalúa al final, la inmediata
consecuencia de esto es que las instrucciones del cuerpo del
bucle se ejecutaran al menos una vez.
z Esta estructura es más adecuada para casos como el anterior.
Si vamos a entrar datos, al menos uno entraremos, por tanto las
instrucciones del cuerpo del bucle se deben ejecutar al menos
una vez, luego
l ya d
decidiremos
idi sii se repiten
it o no.
z En este caso no es necesario la línea Mas_Datos = vbYes antes
de Do para forzar la entrada en el bucle ya que la condición va al
final.
final

03/08/2010 Adolfo Aparicio 52


D L
Do..Loop Whil
While
Sub Registros_Tetra() Do
Dim Nombre As String Nombre = InputBox("Entre el Nombre: ", "Nombre")
Dim Ciudad As String Ciudad = InputBox("Entre la Ciudad : ", "Ciudad")
Dim Edad As Integer Edad = Val(InputBox("Entre la Edad : ", "Edad"))
Dim Fecha As Date Fecha = CDate(InputBox("Entra la Fecha : ", "Fecha"))
Dim Mas_datos As Integer With ActiveCell
'M
'Mas_datos
d t es una variable
i bl dde titipo .Value
V l =N Nombreb
Integer .Offset(0, 1).Value = Ciudad
Worksheets("Hoja3").Activate .Offset(0, 2).Value = Edad
ActiveSheet.Range("B4").Activate .Offset(0, 3).Value = Fecha
Buscar la primera celda vacía de la
'Buscar End With
columna B y convertirla en activa ActiveCell.Offset(1, 0).Activate
Do While Not IsEmpty(ActiveCell) Mas_datos = MsgBox("Otro registro ?", vbYesNo +
ActiveCell.Offset(1, 0).Activate vbQuestion, "Entrada de datos")
Loopp Mientras Mas_datos
'Mientras Mas datos = vbYes
Loop While Mas_datos = vbYes
End Sub

03/08/2010 Adolfo Aparicio 53


E t t
Estructura Do..Loop
D L Until
U til
z Hacer.. Hasta que se cumpla la condición
Hacer
z Es otra estructura que evalúa la condición al final.
z La interpretación es distinta
distinta, ya que el bucle se va
repitiendo HASTA que se cumple la condición,
z no MIENTRAS se cumple p la condición.
z De las dos estructura use la que más le guste

03/08/2010 Adolfo Aparicio 54


D L
Do..Loop U
Until
til
Sub Registros_Penta() Do
Di Nombre
Dim N b As A String
St i N b = IInputBox("Entre
Nombre tB ("E t ell Nombre:
N b "", "N"Nombre")
b ")
Dim Ciudad As String Ciudad = InputBox("Entre la Ciudad: ", "Ciudad")
Dim Edad As Integer Edad = Val(InputBox("Entre la Edad: ", "Edad"))
Dim Fecha As Date Fecha = CDate(InputBox("Entre la Fecha: ", "Fecha"))
Dim Mas_datos
Mas datos As Integer With ActiveCell
Acti eCell
'Mas_datos es una variable de tipo .Value = Nombre
Integer .Offset(0, 1).Value = Ciudad
Worksheets("Hoja3").Activate .Offset(0, 2).Value = Edad
ActiveSheet Range("B4")
ActiveSheet.Range( B4 ).Activate
Activate Offset(0 3).Value
.Offset(0, 3) Value = Fecha
'Buscar la primera celda vacía de la End With
columna B y convertirla en activa ActiveCell.Offset(1, 0).Activate
Do While Not IsEmpty(ActiveCell) Mas_datos = MsgBox("Otro registro ?", vbYesNo +
ActiveCell.Offset(1, 0).Activate Q , "Entrada de datos"))
vbQuestion,
Loop 'Hasta que Mas_Datos sea igual a vbNo
Loop Until Mas_datos = vbNo
End Sub

03/08/2010 Adolfo Aparicio 55


E t t
Estructura For
F Each
E h
z Este bucle se utiliza básicamente para ejecutar un grupo de sentencias
con los elementos de una colección o una matriz.
z Rec erde q
Recuerde que
e una
na colección es un
n conj
conjunto
nto de objetos
objetos, hojas
hojas, rangos
rangos,
etc.
‘Para cambiar los nombres de las hojas de un libro de trabajo
Sub NombraHojas()
j ()
'Programa que pregunta el nombre para cada hoja de un libro de trabajo,
'si no se pone nombre a la hoja, queda el que tiene.
Dim Nuevo_Nombre As String
Dim hoja As Worksheet
' Para
P cada
d h
hoja
j d
dell conjunto
j t W WorkSheets
kSh t
For Each hoja In Worksheets
Nuevo_Nombre = InputBox("Nombre de la Hoja : " & hoja.Name, "Nombrar Hojas")
If Nuevo_Nombre <> "" Then
hoja.Name
j = Nuevo_Nombre
End If
Next
'** Hoja va referenciando cada una de las hojas del conjunto WorkSheets a cada paso de bucle
End Sub

03/08/2010 Adolfo Aparicio 56


EXIT FOR
z Esta macro es una variante de la anterior
z Si se pulsa CANCEL o el nombre de hoja esta vacío “” se sale del bucle con un
EXIT FOR
FOR.
z EXIT FOR permite salir de un bucle FOR o FOR EACH, mientras que EXIT DO
abandona directamente un bucle DO
z Además nos hemos ahorrado el END IF

Sub NombraHojas2()
'Si se pulsa cancelar o no se pone nada en el nombre se sale con el EXIT FOR
Dim Nuevo_Nombre As String
Di hoja
Dim h j As
A Worksheet
W k h
For Each hoja In Worksheets
Nuevo_Nombre = InputBox("Nombre de la Hoja : " & hoja.Name, "Nombrar Hojas",
hoja.Name)
If Nuevo_Nombre = "" Then Exit For 'EXIT FOR sale del bucle
hoja.Name = Nuevo_Nombre
Next
End Sub

03/08/2010 Adolfo Aparicio 57


Ll
Llenar un Rango
R
Sub Llena_Rango()
Dim R As Range
Worksheets("Hoja1").Activate
' Para cada celda del rango N16:P19 de la Hoja1
For Each R In ActiveSheet.Range("N16:P19")
R.Value = InputBox("Entrar valor para la celda " & R.Address, "Entrada de
valores")
Next
E dS
End Sub
b

z Se ha declarado una variable tipo Range, este tipo de datos sirve para guardar
Rangos de una o más casillas, estas variables pueden luego utilizar todas las
propiedades y métodos propios de los Objetos Range
Range.
z La asignación de las variables que sirven para guardar o referenciar objetos
(Range, WorkSheet, etc.) deben inicializarse muchas veces a través de la
instrucción SET

03/08/2010 Adolfo Aparicio 58


P
Procedimientos
z
di i t
En los programas largos conviene dividir el trabajo en varios procedimientos.
z Inconvenientes de los procedimientos largos:
z grandes bloques de código implican mayor complicación del mismo
z repetición de sentencias
z mayores problemas de seguimiento a la hora de:
z depurar errores
z ampliar funcionalidades
z incluir modificaciones
z Fil
Filosofía
fí dde “di
“divide
id y vencerás”
á ”
z tratar cada problema o tarea de forma más o menos aislada
z Para llamar un procedimiento desde otro se utiliza la instrucción
Call Nombre_Procedimiento
Sub P_Uno()
P Uno()
Sentencias
.
Call P_Dos()
.
Sentencias
.
End Sub

03/08/2010 Adolfo Aparicio 59


Call
Sub Registros_Hexa() Do
'el mismo procedimiento que Registros_Bis() pero Nombre = InputBox("Entre el Nombre: ",
usando una llamada CALL a otro procedimiento "Nombre")
el código que salta casilla hasta que se encuentra
'el Ciudad = InputBox("Entre
InputBox( Entre la Ciudad : ", "Ciudad")
Ciudad )
una vacía se implementa en un procedimiento Edad = Val(InputBox("Entre la Edad : ", "Edad"))
'llamado, Saltar_Celdas_Llenas. fecha = CDate(InputBox("Entra la Fecha : ",
'Para entrar valores se ha sustituido Do While..Loop "Fecha"))
por Do.. Loop While. With ActiveCell
Dim Nombre As String .Value = Nombre
Dim Ciudad As String .Offset(0, 1).Value = Ciudad
Dim Edad As Integer .Offset(0, 2).Value = Edad
Dim fecha As Date .Offset(0, 3).Value = fecha
Dim Mas_datos As Integer End With
' Llamada a la función Saltar_Celdas_Llenas, el ActiveCell.Offset(1, 0).Activate
programa salta aquí a ejecutar las Mas_datos = MsgBox("Otro registro ?", vbYesNo
' instrucciones de este procedimiento y luego + vbQuestion, "Entrada de datos")
vuelve para continuar la ejecución Loop While Mas_datos = vbYes
' a partir de la instrucción Do End Sub
Call Saltar_Celdas_Llenas

03/08/2010 Adolfo Aparicio 60


F
Función
ió llamada
ll d
Sub Saltar_Celdas_Llenas()
Worksheets("Hoja3")
Worksheets( Hoja3 ).Activate
Activate
ActiveSheet.Range("B4").Activate
Do While Not IsEmpty(ActiveCell)
ActiveCell Offset(1 0)
ActiveCell.Offset(1, 0).Activate
Activate
Loop
End Sub

z Función que salta celdas de una misma columna.


z Sirve para encontrar la primera celda vacía de la columna

03/08/2010 Adolfo Aparicio 61


P
Pasar parámetros
á t
z Los parámetros son el mecanismo por el cual un procedimiento puede
pasarle valores a otro y de esta forma condicionar, moldear, etc. las
acciones
i que ejecuta.
j t
z El procedimiento llamado gana entonces en flexibilidad. La sintaxis de
llamada de un procedimiento es la siguiente:
Call Procedimiento(Parámetro1,
Procedimiento(Parámetro1 Parámetro2
Parámetro2,..., ParámetroN)
z Los parámetros pueden ser valores o variables.
z La sintaxis para el procedimiento llamado es la siguiente:
Sub Procedimiento(Parámetro1 as Tipo,..., ParámetroN As Tipo)
z Observe que aquí los parámetros son variables que recibirán los
valores y evidentemente debe haber coincidencia de tipo.
z Por ejemplo, si el primer parámetro es una variable tipo Integer, el primer
valor que se le debe pasar al procedimiento cuando se llama también ha de
ser de tipo Integer (recuerde que puede ser un valor directamente o una
variable).

03/08/2010 Adolfo Aparicio 62


Call Procedimiento(Parámetro1, Parámetro2,..., ParámetroN)

Sub Registros_Septa() Do
Dim Nombre As String Nombre = InputBox("Entre el Nombre : ", "Nombre")
Dim Ciudad As String Ciudad = InputBox("Entre la Ciudad : ", "Ciudad")
Dim Edad As Integer Edad = Val(InputBox("Entre la Edad : ", "Edad"))
Dim fecha As Date fecha = CDate(InputBox("Entre la Fecha : ", "Fecha"))
Dim Mas_datos As Integer With ActiveCell
' Llamada a la función .Value = Nombre
Saltar_Celdas_Llenas_Bis .Offset(0, 1).Value = Ciudad
' Mediante dos parámetros se .Offset(0, 2).Value = Edad
comunica al procedimiento llamado en .Offset(0, 3).Value = fecha
que hoja y celda comenzar
End With
Call
Saltar_Celdas_Llenas_Bis("Hoja3", "B4") ActiveCell.Offset(1, 0).Activate
'Los parámetros pueden ser valores o Mas_datos = MsgBox("Otro registro ?", vbYesNo +
variables vbQuestion "Entrada
vbQuestion, Entrada de datos")
datos )
Loop While Mas_datos = vbYes
End Sub

03/08/2010 Adolfo Aparicio 63


P
Procedimiento
di i t con parámetros
á t
Sub Saltar_Celdas_Llenas_Bis(hoja As String, Casilla_Inicial As String)
'los parámetros son variables que recibirán los valores
'debe haber coincidencia de tipos.
Worksheets(hoja).Activate
ActiveSheet.Range(Casilla_Inicial).Activate
Do While Not IsEmpty(ActiveCell)
ActiveCell.Offset(1, 0).Activate
Loop
End Sub

z Sirve para Saltar celdas llenas de una columna hasta encontrar una vacía que
se convierte en activa
z Parámetros :
z Hoja : Hoja donde está el rango a saltar.
z Casilla_Inicial : Casilla Inicial de la columna
z Gracias a los parámetros, sirve para recorrer cualquier rango en cualquier hoja.

03/08/2010 Adolfo Aparicio 64


Los parámetros pueden ser valores o
variables
Sub Registros_Octa()
Registros Octa()
Dim Nombre As String, Ciudad As String, Edad As Integer, fecha As Date, Mas_datos As Integer
' Al procedimiento Saltar_Celdas_Llenas_Bis se le pueden pasar valores como en el caso anterior, o variables como en este.
'******************* novedad **********************
Dim hoja As String
Dim Casilla_Inicial
Casilla Inicial As String
hoja = InputBox("En que hoja está la base de datos : ", "Entrar Nombre de Hoja")
Casilla_Inicial = InputBox("En que casilla comienza la base de datos", "Casilla Inicial")
' Observe que los parámetros son dos variables cuyo valor se ha entrado desde teclado en
' las dos instrucciones InputBox anteriores.
C ll Saltar_Celdas_Llenas_Bis(hoja,
Call S lt C ld Ll Bi (h j Casilla_Inicial)
C ill I i i l)
'******************* novedad **********************
Do
Nombre = InputBox("Entre el Nombre : ", "Nombre")
Ciudad = InputBox("Entre la Ciudad : ", "Ciudad")
Edad = Val(InputBox("Entre la Edad : ", "Edad"))
fecha = CDate(InputBox("Entre la Fecha : ", "Fecha"))
With ActiveCell
.Value = Nombre
.Offset(0, 1).Value = Ciudad
.Offset(0, 2).Value = Edad
.Offset(0, 3).Value = fecha
End With
ActiveCell.Offset(1, 0).Activate
Mas_datos = MsgBox("Otro
g ( registro
g ?", vbYesNo + vbQuestion, "Entrada de datos"))
Loop While Mas_datos = vbYes
End Sub
03/08/2010 Adolfo Aparicio 65
Variables Locales y variables Globales
z El ámbito de una variable declarada dentro de una función es la propia función
función.
z Es decir, no podrá utilizarse fuera de dicha función.
z Así, el siguiente programa que debería sumar las cinco filas siguientes a partir de la casilla
activa y guardar el resultado en la sexta es incorrecto.

Sub Hacer() Sub Sumar_Cinco_Siguientes()


. Dim i As Integer
. Dim Suma As Single
Call Sumar_Cinco_Siguientes
Sumar Cinco Siguientes Suma=0
ActiveCell.Offset(6,0).Value = Suma For i=1 To 5
. Suma = Suma+ActiveCell.Offset(i,0).Value
. Next i
End Sub End Sub

z Es incorrecto porque tanto las variable i como la variable Suma están declaradas dentro del
procedimiento Sumar_Cinco_Siguientes consecuentemente, su ámbito de acción es este procedimiento.
z Por tanto, la instrucción ActiveCell.Offset(6,0).Value
( ) = Suma del p
procedimiento Hacer, g
generaría un error
(con Option Explicit activado) ya que la variable Suma no está declarada dentro de él.
z Si piensa en declarar la variable Suma dentro del procedimiento Hacer, no solucionará nada porque esta
será local a dicho procedimiento, en este caso tendría dos variables llamadas Suma pero cada una de
ellas local a su propio procedimiento y consecuentemente con el ámbito de acción restringido a ellos.

03/08/2010 Adolfo Aparicio 66


Variables Globales
z Una solución seria declarar “suma” como variable global.
z Una variable global se declara fuera de todos los procedimientos y es
reconocida por todos los procedimientos del mód
módulo.lo

Option Explicit
Di Suma
Dim S A Si
As Single
l ‘Suma
‘S es una variable
i bl global
l b l reconocida
id por ttodos
d llos procedimientos
di i t d dell módulo
ód l

Sub Hacer_Bis()
.
Call Sumar_Cinco_Siguientes_Bis
ActiveCell.Offset(6,0).Value = Suma
.
End Sub

Sub Sumar_Cinco_Siguientes_Bis()
Dim i As Integer
Suma=0
For i=1 To 5
Suma = Suma+ActiveCell.Offset(i,0).Value
Next i
E d Sub
End S b

03/08/2010 Adolfo Aparicio 67


Pasar variables como
parámetros
á t
z La variable parámetro S (a la que se ha cambiado el nombre adrede) de
Sumar Cinco Siguientes Tris es la variable Suma declarada en
Sumar_Cinco_Siguientes_Tris
Hacer_Tris.
z Funcionará porque en Visual Basic, a menos que se indique lo
contrario, el paso de parámetros es por referencia.

Sub Hacer_Tris() Sub Sumar_Cinco_Siguientes_Tris(S As Single)


Dim Suma As Single Dim i As Integer
. Suma=0
. For i=1 To 5
‘ Llamada a la función Sumar_Cinco_Siguientes S = S+ActiveCell.Offset(i,0).Value
pasándole la variable Suma Next i
Call Sumar_Cinco_Siguientes
g _Tris(Suma)
( ) End Sub
ActiveCell.Offset(6,0).Value = Suma
.
.
End Sub

03/08/2010 Adolfo Aparicio 68


Paso por referencia y paso por valor
z El paso por valor significa que la variable parámetro del procedimiento recibe el
valor de la variable (o directamente el valor) de su parámetro correspondiente
de la instrucción de llamada y en el paso por referencia, la variable parámetro
del procedimiento es la misma que su parámetro correspondiente de la
instrucción de llamada, es decir, la declarada en el procedimiento desde el que
se hace la llamada.
z Por defecto, y siempre que en la instrucción de llamada se utilicen variables, las
llamadas son por referencia.
z Si desea que el paso de parámetros sea por valor, debe anteponer a la variable
parámetro la palabra reservada ByVal
Sub Saltar_Celdas_Llenas(ByVal Hoja As String, ByVal Casilla_Inicial As String)

z Aunque lo elegante y efectivo por razones de memoria seria pasar siempre que
sea posible por valor, es poco habitual que así se haga en Visual Basic,
seguramente por comodidad.
comodidad
z Como suponemos que hará como la mayoría, es decir, pasar por referencia,
tenga cuidado con los (indeseables) efectos laterales.

03/08/2010 Adolfo Aparicio 69


Ef t Lateral
Efecto L t l
z Este p
programa
g no funciona bien
z En la Hoja4 disponemos de 5 valores en cada una de las tres columnas B,C,D, y deseamos sumarlos
z Debería sumar los cinco valores de cada columna y poner su suma justo bajo ellos
z El mal funcionamiento se debe a que la variable Fila pasa al procedimiento llamado, como variable y no
como valor, pese a que se cambia el nombre por F, sigue siendo la misma

Sub Efecto_Lateral() Sub Recorrer_Sumar(F As Integer, C As Integer, Q As Integer)


Dim Fila As Integer Dim i As Integer
Worksheets("Hoja4").Activate Dim Total As Integer
Fila = 5 Total = 0
Call Recorrer_Sumar(Fila, 2, 5) ' Columna B For i = 1 To Q
Call Recorrer_Sumar(Fila, 3, 5) ' Columna C Total = Total + ActiveSheet.Cells(F, C).Value
Call Recorrer_Sumar(Fila,
Recorrer Sumar(Fila 44, 5) ' Columna D F = F + 1 ' OJO con esta asignación
asignación, recuerde que F es la variable Fila
End Sub declarada en el procedimiento Efecto_Lateral
Next i
ActiveSheet.Cells(F, C) = Total
End Sub

03/08/2010 Adolfo Aparicio 70


B V l
ByVal
z Se corrige
g añadiendo ByVal
y a la variable, lo q
que hace q
que p
pase como valor.

Sub Efecto_Lateral_bis() 'Este procedimiento es Sub Recorrer_Sumar_bis(ByVal F As Integer, C As Integer,


igual al Efecto_Lateral Q As Integer)
'con la salvedad de que en este se llama a 'Este sub es idéntico al anterior salvo porque en la variable
Recorrer_Sumar_bis F hemos añadido ByVal,
Dim Fila As Integer 'que transfiere el parámetro como valor y no como variable
Worksheets("Hoja4").Activate Dim i As Integer
Fila = 5 Dim Total As Integer
Call Recorrer_Sumar_bis(Fila, 2, 5) ' Total = 0
Columna B For i = 1 To Q
Call Recorrer_Sumar_bis(Fila, 3, 5) ' Total = Total + ActiveSheet.Cells(F, C).Value
Columna C F=F+1
Call Recorrer_Sumar_bis(Fila, 4, 5) ' Next i
Columna D
ActiveSheet.Cells(F, C) = Total
End Sub
End Sub

03/08/2010 Adolfo Aparicio 71


F
Funciones
i
z Las funciones no ejecutan acciones,
acciones simplemente dan como resultado
un valor
z Las variables de la función se introducen como argumentos
Function Area_Cuadrado(x,
Area Cuadrado(x y)
Area_Cuadrado = x * y
End Function

z En la categoría de Funciones “Definidas por el usuario” encontrará esta


función que podrá aplicar normalmente a la hoja de cálculo.
z También se puede usar esta función llamándola desde un
procedimiento o desde otra función.

03/08/2010 Adolfo Aparicio 72


F
Función
ió llllamada
d por un S
Sub
b
z Una función puede ser llamada por un procedimiento u otra función.
z Las funciones tienen tipo (esta es de tipo integer) ya que devuelven un valor
Sub Llama_suma() 'Procedimiento que llama a una función de varias formas. Ver distintas formas.
Dim x As Integer
Dim n1 As Integer, n2 As Integer
( 5))
x = Sumardos(5,
n1 = Val(InputBox("Entrar un número : ", "Entrada"))
n2 = Val(InputBox("Entrar otro número : ", "Entrada"))
x = Sumardos(n1, n2)
ActiveCell.Value = Sumardos(ActiveSheet.Range("K10").Value, ActiveSheet.Range("K11").Value)
x = Sumardos(5, 4) + Sumardos(n1, n2)
End Sub
Function Sumardos(V1 As Integer, V2 As Integer) As Integer
Dim Total As Integer
Total = V1 + V2
Sumardos = Total
End Function

03/08/2010 Adolfo Aparicio 73


Ejercicio

Cree una función que calcule el


factorial de un número
Por ejemplo
ejemplo.
Factorial(5)=5x4x3x2x1=120
A
Aunque i t una función
ya existe f ió en
Excel que calcula el factorial:
=FACT(numero)

03/08/2010 Adolfo Aparicio 74


Función Factorial
Function factori(n As Long) 'FUNCIÓN que calcula el factorial de un número
Dim F As Long
Dim i As Long g
F=1
For i = n To 1 Step -1
F=F*i
Next
factori = F
End Function
Function Factorial(ByVal n As Integer)
' Un buen ejemplo del uso de ByVal para transferir variables
' Si no se pusiera en este caso no calcularía bien
n=n-1
If n = 0 Then
Factorial = 1
Exit Function
End If
( ) * ((n + 1))
Factorial = Factorial(n)
End Function
03/08/2010 Adolfo Aparicio 75
Función que detecta Celda
V í
VacíaSub Detecta_Vacia()
Dim Casilla As String
Worksheets("Hoja4").Activate
Casilla = Casilla_Vacia("B5") 'Llama a la función Casilla_Vacia
MsgBox Prompt:=Casilla, Title:="La primera celda vacía"
End Sub

z Función Casilla_Vacia de Tipo String


z Sirve para Recorrer las filas de una columna hasta encontrar una vacía.
z Parámetros :
z Casilla_Inicio : Casilla donde debe empezar a buscar.
z D
Devuelve
l un string
t i que contiene
ti la
l referencia
f i de
d la
l primera
i casilla
ill

Function Casilla_Vacia(Casilla_Inicio As String) As String


ActiveSheet.Range(Casilla_Inicio).Activate
Do While Not IsEmpty(ActiveCell)
ActiveCell.Offset(1, 0).Activate
Loop
Casilla_Vacia = ActiveCell.Address
End Function

03/08/2010 Adolfo Aparicio 76


F
Función
ió que Busca
B un Valor
V l
Sub Busca()
Dim Casilla As String,g Valor As Integer
g
Worksheets("Hoja4").Activate
Valor = CInt(InputBox("Valor buscado: ", "Entrar Datos"))
Casilla = Buscar_Valor("C5", Valor) ‘Llama a la función Buscar_Valor
If Casilla = "" Then ' Si valor no encontrado
MsgBox ("NO se ha encontrado el valor buscado")
Else 'Valor encontrado
MsgBox ("El primer " & Valor & " esta en la celda: " & Casilla)
End If
End Sub

z Función que devuelve la dirección de la primera celda vacía de un rango.


z La ffunción
nción es de tipo String ya
aqque
e de
devuelve
el e la casilla en la forma "FilaCol
"FilaColumna
mna "", por
ejemplo "A10".
z Utilizaremos la propiedad Address del objeto range, esta propiedad devuelve un string
que contiene la referencia "FilaColumna" de una casilla o rango de casillas.
z En el caso de un rango devuelve, "FilaColumna_Inicial:FilaColumna_Final", por ejemplo
"A1 C10"
"A1:C10"

03/08/2010 Adolfo Aparicio 77


Función q
que Busca un Valor
z Función Buscar de Tipo String
z Sirve para: Recorrer las filas de una columna hasta encontrar el valor buscado o una de vacía.
z Parámetros :
z Casilla_Inicial: Casilla donde debe empezar a buscar
z Valor Buscado: Valor que se debe encontrar
Valor_Buscado:
z Devuelve: Un string que contiene la referencia de la casilla donde se ha encontrado el valor
z También puede devolver "" en caso que el valor buscado no esté

Function Buscar_Valor(Casilla_Inicial As String, Valor_Buscado As Integer) As String


ActiveSheet.Range(Casilla_Inicial).Activate
' Mientras casilla no vacía Y valor de casilla diferente al buscado
Do While Not IsEmpty(ActiveCell) And ActiveCell.Value <> Valor_Buscado
ActiveCell.Offset(1, 0).Activate
Loop
' Si la casilla donde se ha detenido la búsqueda NO ESTÁ VACÍA es que se ha encontrado
' el valor
If Not IsEmpty(ActiveCell) Then
B scar Valor = Acti
Buscar_Valor ActiveCell.Address
eCell Address ' Devolver
De ol er la casilla donde se ha encontrado el valor
alor
Else ' La casilla está vacía, NO se ha encontrado el valor buscado
Buscar_Valor = "" ' Devolver una cadena vacía
End If
End Function

03/08/2010 Adolfo Aparicio 78


Busca Valor por filas y
columnas
l
z Procedimiento idéntico a Buscar() pero que llama a la función
Buscar Valor Bis que busca por filas y columnas
Buscar_Valor_Bis

Sub Busca_Bis()
Dim Casilla As String
Dim Valor As Integer
Worksheets("Hoja4").Activate
Valor = CInt(InputBox("Valor buscado: ", "Entrar Datos"))
C ill = Buscar_Valor_Bis("B5",
Casilla B V l Bi ("B5" VValor)
l ) 'Ver
'V lal función
f ió B Buscar_Valor_Bis
V l Bi
' Si valor no encontrado
If Casilla = "" Then
MsgBox ("NO se ha encontrado el valor buscado")
Else 'Valor encontrado
MsgBox ("El primer " & Valor & " esta en la celda: " & Casilla)
End If
End Sub

03/08/2010 Adolfo Aparicio 79


Busca Valor por filas y columnas
Function Buscar_Valor_Bis(Casilla_Inicial As String, If Not IsEmpty(ActiveCell.Offset(0, Incremento_Columna)) Then
Valor_Buscado As Integer) As String Continuar = False
Dim Incremento_Columna As Integer Else ' La casilla está vacía, no se ha encontrado el valor
Dim Continuar As Boolean ActiveCell.Offset(1, 0).Activate ' Saltar a una nueva fila
ActiveSheet.Range(Casilla_Inicial).Activate If IsEmpty(ActiveCell) Then ' Si la casilla de la nueva fila
Continuar = True está vacía
Do While Continuar Continuar = False ' Parar la búsqueda, no hay más
Incremento_Columna = 0 casilla a recorrer
' Buscar el valor por las columnas hasta End If
encontrarlo o encontrar una celda vacía. End If
Do While Not IsEmpty(ActiveCell.Offset(0, Loop
Incremento_Columna)) And _ ' Si la casilla donde se ha detenido la búsqueda NO ESTÁ
ActiveCell.Offset(0, VACÍA es que se ha encontrado el valor.
Incremento Columna) Value <> Valor
Incremento_Columna).Value Valor_Buscado
Buscado If Not IsEmpty(ActiveCell) Then
' Siguiente columna Buscar_Valor_Bis = ActiveCell(0,
Incremento_Columna = Incremento_Columna).Address ' Devolver la casilla donde ' se
Incremento_Columna + 1 ha encontrado el valor
Loop Else ' La casilla está vacía, NO se ha encontrado el valor
' Si no está vacía la casilla entonces parar la b scado
buscado
búsqueda, se ha encontrado el valor Buscar_Valor_Bis = "" ' Devolver una cadema vacía
End If
End Function

03/08/2010 Adolfo Aparicio 80


L cláusula
La lá l PPrivate
i t
z Puede anteponer la cláusula private a todos los procedimientos y funciones que sean
llamados sólo desde el mismo módulo
módulo.
z Es una forma de ahorrar memoria y hacer que el programa corra un poco más rápido.
z Si necesita llamar un procedimiento o función desde otro módulo, nunca debe precederlo
por la cláusula private

' Módulo 1 ' Módulo 2


Sub General Sub Procedimiento_de_modulo2
Procedimiento de modulo2
.... ‘ Esto es correcto. Llama al procedimiento General definido en Módulo1
End Sub Call General
' Esto no es correcto. Llama al procedimiento Privado definido en Módulo 1, este
' procedimiento va precedido pro la cláusula Private, por tanto sólo puede ser llamado
Private
P i Sub
S b Privado
Pi d ' desde procedimientos de su propio módulo
.... Call Privado
End Sub End Sub

03/08/2010 Adolfo Aparicio 81


Ejercicio

Programe una macro que proporcione


las 4!=24 combinaciones de las
cuatro letras ABCD

03/08/2010 Adolfo Aparicio 82


Permutaciones de ABCD
Sub permuta() Function palabra(i As Byte, j As
Dim i As Byte, j As Byte, k As Byte, l As Byte Byte, k As Byte, l As Byte) As
Dim a() As Byte, mensaje As String String
For i = 1 To 4 Di letra
Dim l t AsA String
St i * 1
For j = 1 To 4 Dim n As Byte, x As Byte
For k = 1 To 4 Dim a(1 To 4) As Byte
For l = 1 To 4 a(1)
( ) = i: a(2)
( ) = j:
j a(3)
( ) = k: a(4)
( )=l
If i = j Or i = k Or i = l Or j = k Or j = l Or k = l Then For n = 1 To 4
Else x = a(n)
mensaje = mensaje & palabra(i, j, k, l) & vbCrLf Select Case x
Exit For Case 1: letra = "A"
End If Case 2: letra = "B"
Next l Case 3: letra = "C"
Next k Case 4: letra = "D"
Next j End Select
Next i palabra = palabra & letra
MsgBox mensaje Next n
End Sub End Function

03/08/2010 Adolfo Aparicio 83


Permutaciones de ABCD con RND
Sub permuta_bis() For j = 1 To i - 1
'Permutaciones de ABCD 4!=24 If a(i) = a(j) Then i = i - 1: Exit For
Dim i As Byte, j As Byte, n As Byte Next j
Dim a(1 To 4) As String Next i
Dim b(1 To 24) As String b(n) = ""
Dim frase As String For i = 1 To 4
Dim x As Single b(n) = b(n) & a(i)
Randomize Next i
For n = 1 To 24 For j = 1 To n - 1
F i = 1 To
For T 4 If b(j) = b(
b(n)) Then
Th n = n - 1: 1 Exit
E it For
F
x = Rnd Next j
Select Case x Next n
Case Is < 0.25: a(i)
( ) = "A" For n = 1 To 24
Case 0.25 To 0.5: a(i) = "B" frase = frase & b(n) & vbCrLf
Case 0.5 To 0.75: a(i) = "C" Next n
Case Is > 0.75: a(i) = "D" MsgBox frase
End Select End Sub

03/08/2010 Adolfo Aparicio 84


I
Importar
t y Exportar
E t módulos
ód l
z Ciertos p
procedimientos q que p
pueden ser utilizados en multitud de
ocasiones, seria interesante tenerlos disponibles en cualquiera de las
hojas que confeccionemos.
z Podría pensar en utilizar las opciones de copiar y pegar para pasar
z procedimientos de una hoja a otra
otra, es un método totalmente válido y
efectivo, pero existe otro método más "profesional“.
z Consiste en guardar los procedimientos de un módulo aparte y
exportarlo a un archivo .BAS que es independiente de cualquier hoja
de cálculo.
cálculo
z Luego, cuando en una nueva hoja necesite estas funciones, solo
deberá importar este archivo para incorporarlo.
z Consejo: Aproveche las ventajas que proporciona la programación
modular.
modular
z Consejo: agrupe todas las funciones que usted considere de utilización
general en uno o dos módulos y luego utilice las opciones de
importación y exportación para incorporarlos a sus programas.

03/08/2010 Adolfo Aparicio 85


I
Importar
t y Exportar
E t módulos
ód l
Exportar
p un módulo. Guardar un módulo en un archivo
z Abra la hoja donde tiene los procedimientos que desea exportar
z 1. Pase al editor de Visual Basic y active el módulo a exportar.
z 2. Active la opción de la barra de menús Archivo/ Exportar archivo. Aparece un cuadro de
diálogo.
z 3 En cuadro de edición Nombre de Archivo,
3. Archivo teclee el nombre para el archivo donde se
guardará el módulo, por ejemplo "General.Bas", observe que .BAS es la extensión de estos
archivos.
z 4. Pulse sobre el botón Guardar.

Importar un módulo
z Cierre todos los archivos de Excel y abra uno nuevo.
z 1. Active el editor Visual Basic.
z 2. Active opción de la barra de menús Archivo/ Importar Archivo. Aparece un cuadro de
diálogo.
z 3 Seleccione en la lista Buscar en: la carpeta donde tiene ubicado el archivo a importar
3.
z 4. Una vez localizada la carpeta, seleccione el archivo a importar (General.Bas en el ejemplo) y
pulse sobre Abrir.
z Observe como en la ventana de proyecto se ha incorporado un nuevo módulo que contiene todos
los procedimientos y funciones del archivo importado.

03/08/2010 Adolfo Aparicio 86


L grabadora
La b d d
de macros
z Microsoft Excel lleva incluida una utilidad que sirve para registrar acciones que se llevan a
cabo
b en un lib
libro dde ttrabajo
b j y registrarlas
i t l en fforma d de macro.
z Podemos aprovechar esta utilidad para generar código engorroso por su sintaxis un tanto
complicada de recordar, además de ahorrar tiempo.
z Casi siempre después deberemos modificarlo para adaptarlo a nuestros programas

03/08/2010 Adolfo Aparicio 87


Macro realizada con Grabadora y alguna modificación

Sub Poner_Bordes() With Selection.Borders(xlEdgeRight) ' Borde derecho


W k h t ("H j 4") A ti t
Worksheets("Hoja4").Activate .LineStyle
Li St l = xlContinuous
lC ti
' Seleccionar el rango B5:D10 .Weight = xlMedium
Range("B5:D10").Select .ColorIndex = xlAutomatic
' No hay borde diagonal hacia abajo End With
Selection.Borders(xlDiagonalDown).LineStyle = xlNone ' Bordes verticales interiores de la selección
' No hay borde diagonal hacia arriba With Selection.Borders(xlInsideVertical)
Selection.Borders(xlDiagonalUp).LineStyle = xlNone .LineStyle = xlContinuous
' Borde izquierdo de la seleccón .Weight = xlThin ' Ancho Simple.
With Selection.Borders(xlEdgeLeft) .ColorIndex = xlAutomatic
.LineStyle = xlContinuous 'Estilo de línea continuo End With
.Weight = xlMedium ' Ancho de línea Medio ' No hay bordes horiontales interiores en la selección
.ColorIndex = xlAutomatic ' Color de línea automático Selection.Borders(xlInsideHorizontal).LineStyle = xlNone
(negro) ' Seleccionar rango B9:D9
End With Range("B9:D9").Select
' Borde superior de la selección ' No hayy borde diagonal
g hacia arriba
With Selection.Borders(xlEdgeTop) Selection.Borders(xlDiagonalDown).LineStyle = xlNone
.LineStyle = xlContinuous ' No hay borde diagonal hacia arriba
.Weight = xlMedium Selection.Borders(xlDiagonalUp).LineStyle = xlNone
.ColorIndex = xlAutomatic ' Borde inferior de la selección
End With With Selection.Borders(xlEdgeBottom) ' Doble línea
' Borde inferior de la selección .LineStyle = xlDouble
With Selection.Borders(xlEdgeBottom) .Weight = xlThick
.LineStyle = xlContinuous .ColorIndex = xlAutomatic
.Weight = xlMedium End With
.ColorIndex = xlAutomatic Range("A1")
Range( A1 ).Select
Select
End With End Sub

03/08/2010 Adolfo Aparicio 88


Macro con Grabadora y
generalizada
li d
z Fichero decora.bas
z Podemos crear una Macro con la Grabadora y luego perfeccionarla y darle
carácter más general introduciendo parámetros.
z Esta macro pone bordes a una tabla, en la primera fila pone doble línea.
z El p
primer p
parámetro es el número de hoja j ((no el nombre),
), y el segundo
g la casilla
inicial
z La macro se encargará de seleccionar todas las casillas adyacentes y de
buscar la primera fila.
z En esta macro además se han incluido funcionalidades como borrar los
f
formatost antes
t ded aplicar
li llas lí
líneas, ajustar
j t ell anchoh d
de llas columnas,
l etc.
t
z Observe la propiedad CurrentRegion del objeto Range, esta propiedad
devuelve el rango de las casillas llenas adyacentes a una dada.
z Por ejemplo imagine una hoja con el rango A1:B10 lleno de valores, la
instrucción
ActiveSheet.Range("A1").CurrentRegion.Select
Seleccionaria el rango correspondiente a A1:B10

03/08/2010 Adolfo Aparicio 89


Insertar funciones en una Hoja
j
'va pidiendo números y los va colocando en las celdas de la ' Establecer la casilla inicial del rango a sumar
columna B partir de B12 Casilla_Inicial = "B12"
'al final coloca la función =SUMA para sumar los valores ' Establecer la casilla final del rango a sumar.
introducidos y la función =PROMEDIO
PROMEDIO ' Coger
C lla di
dirección
ió d
de lla casilla
ill activa,
ti lla últi
última
Sub Sumar() Casilla_FInal = ActiveCell.Address
Worksheets("Hoja4").Activate ActiveCell.Offset(1, 0).Activate
Dim Valor As Integer ' Poner en la casilla activa la función SUMA
Dim Casilla_Inicial As String ActiveCell.Formula = "=Sum(" & Casilla_Inicial & ":" &
Dim Casilla_FInal
Casilla FInal As String C ill FI l & ")"
Casilla_FInal
' Hacer activa la casilla B12 de la hoja activa ActiveCell.Offset(1, 0).Activate
ActiveSheet.Range("B12").Activate ' Poner en la casilla activa la función promedio
Do ActiveCell.Formula = "=Average(" & Casilla_Inicial & ":" &
' Entrar un valor y convertirlo a numérico Casilla_FInal & ")"
V l =V
Valor Val(InputBox("Entrar
l(I tB ("E t un valor", l " "Entrada"))
"E t d ")) 'Ob
'Observar que las
l ffunciones
i se ponen en iingléslé y que all
' Si el valor es distinto de 0 ejecutarse se traducen automáticamente
If Valor <> 0 Then 'Si no se conoce el nombre de una función puede usarse la
' Guardar el valor en la casilla activa grabadora
ActiveCell.Value = Valor End Sub
' Hacer activa la casilla de la fila siguiente
ActiveCell.Offset(1, 0).Activate
End If
Loop Until Valor = 0

03/08/2010 Adolfo Aparicio 90


Operar con Funciones de
E
Excel
l
z Podemos operar con Funciones de Excel sin necesidad de insertarlas
en una celda
z Vea la siguiente Calculadora Préstamos

Sub prestamo()
Static Principal ‘ Variable estática.
estática No cambia
Static Tasa
Static Terminos
Dim Pago As Double
Principal = Application.InputBox(Prompt:="Principal (100000 por ejemplo)", _
Default:=Principal)
Tasa = Application.InputBox(Prompt:="Tipo de interés nominal anual (4,75 por ejemplo)", _
Default:=Tasa)
Terminos = Application.InputBox(Prompt:="Número de años (30 por ejemplo)", _
Default:=Terminos)
‘ Vea como se usa la función de Excel Pmt (Pago) sin necesidad de calcularla en una celda
Pago = Application.WorksheetFunction.Pmt(Tasa / 1200, Terminos * 12, Principal)
MsgBox Prompt:="La Mensualidad es " & Format(-Pago, "Currency"), Title:="Calculadora de Préstamos"
End Sub

03/08/2010 Adolfo Aparicio 91


Ejercicio
El siguiente programa calcula la longitud de una circunferencia
C
Cree otros
t d programas que efectúen
dos f tú ese mismoi cálculo
ál l usando
d
la función de Excel =PI()
Uno de ellos insertando la función en una celda
El otro sin necesidad de usar la hoja de Excel

Sub perimetro()
Dim radio As Double, longitud
g As Double
Const pi = 3.141592
radio = InputBox("Introduzca el radio de la circunferencia")
longitud = 2 * pi * radio
ActiveCell.Value = longitud
End Sub

03/08/2010 Adolfo Aparicio 92


Solución Ejercicio
Sub perimetro2()
Dim radio As Double, longitud As Double
Dim pi As Double Worksheets("Hoja1").Range("B3").Formula = "=pi()"
pi = Range("B3").Value
radio = InputBox("Introduzca el radio de la circunferencia")
longitud = 2 * pi * radio
ActiveCell.Value = longitud
End Sub

Sub perimetro3()
Dim radio As Double, longitud As Double
Dim pi As Double
pi = Application.WorksheetFunction.pi()
radio = InputBox("Introduzca el radio de la circunferencia")
longitud = 2 * pi * radio
MsgBox = longitud
End Sub

03/08/2010 Adolfo Aparicio 93


Array = Matriz
Sub Array1() Sub Array2() 'Para una matriz verticar usando dos
'Declarar una matriz de tamaño 10 dimensiones
Dim x(1 To 10) As Double 'Declarar una matriz de 10 filas y una columna
'C l l valores
'Calcular l aleatorios
l t i Dim x(1 To 10,10 1 To 1) As Double
For j = 1 To 10 'Calcular valores aleatorios
x(j) = Round(Rnd() * 100, 0) For j = 1 To 10
'Los valores aleatorios se calculan usando formulas VBA x(j, 1) = Round(Rnd() * 100, 0)
Next j Next j
'Transferir el contenido de la matriz a una fila 'T
'Transferir
f i ell contenido
t id de
d lla matriz
t i a una columna
l
Range(Cells(2, 2), Cells(2, 11)).FormulaArray = x Range(Cells(4, 2), Cells(13, 2)).FormulaArray = x
End Sub End Sub

Sub Array3()
'Calcular valores aleatorios
'En este caso, los valores aleatorios se calculan usando formulas
Excel
Range(Cells(4, 3), Cells(13, 3)).FormulaArray = "=Round(Rand() *
100, 0)"
'Vea la diferencia entre Rnd (del caso anterior) y Rand.
'Una es una fórmula VBA la otra es una fórmula Excel en inglés
End Sub

03/08/2010 Adolfo Aparicio 94


Horas Semanales Trabajadas
Sub HorasSemanales() For j = 1 To 2
'Calcula las horas semanales If j = 1 Then
t b j d
trabajadas jornada = "INICIO"
Dim a(1 To 5, 1 To 2) As Single Else
Dim dia As String, jornada As String jornada = "FINAL"
Dim i As Byte,
y j As Bytey End If
'Tipo byte entre 0 y 255 a(i, j) = InputBox("Introduzca la hora de " &
Dim horas As Single jornada _
For i = 1 To 5 & " de la jornada de " & dia & "," & vbCrLf & _
Select Case i "en
en formato decimal.
decimal Por ejemplo 17:30 son las
Case 1: dia = "Lunes" 17,5")
Case 2: dia = "Martes" If j = 2 Then horas = horas + a(i, 2) - a(i, 1)
Case 3: dia = "Miercoles" Next j
Case 4: dia = "Jueves" Next i
Case 5: dia = "Viernes" MsgBox "Horas semanales = " & horas
End Select End Sub

03/08/2010 Adolfo Aparicio 95


Beneficio Medio de un Grupo
p de Empresas
p
Sub BeneficioMedio()
'Calcula el beneficio medio de un grupo de empresas
Di a()
Dim () As
A Double
D bl 'Define
'D fi una matriz t i sin
i ddecir
i aún
ú lla di
dimensión

Dim n As Byte
Dim i As Byte
Dim media As Double
n = InputBox("Número de empresas del Grupo =")
ReDim a(n) 'Redimensiona una matriz dinámica
For i = 1 To n
a(i) = InputBox("Beneficio de la Empresa " & i & " = ", "La Media hasta ahora
es " & media)
media = (media * (i - 1) + a(i)) / i
Next
MsgBox "Beneficio Medio del Grupo de Empresas= " & media
End Sub

03/08/2010 Adolfo Aparicio 96


D t
Detección
ió dde E
Errores
z Errores en tiempo de compilación. Son los típicos errores que impiden hacer funcionar el
programa
p g debido,, p
por ejemplo,
j p , a errores de sintaxis en las instrucciones,, llamadas a funciones
que no existen o llamadas con el tipo o el número de parámetros incorrectos, etc. Este tipo de
errores no dan demasiados problemas, primero porque el compilador avisa de donde se han
producido y luego porque simplemente revisando la sintaxis se solucionan rápidamente.
z Errores en tiempo de ejecución. Estos errores se producen por una mala programación del
código al no haber previsto determinados casos concretos o especiales, como por ejemplo
intentar abrir un archivo que no existe
existe, imprimir sin comprobar que la impresora está conectada
conectada,
definir mal la dimensión de un array e intentar acceder a miembros que no existen, etc. Cuando
se produce este tipo de errores se detiene la ejecución del programa y normalmente se informa
del tipo de error que se ha producido. Muchos de estos errores se pueden solucionar mediante
rutinas o funciones de tratamiento de errores.
z Errores de función. Son los más complicados
p de detectar yya q
que ni se detectan en la fase de
ejecución, ni provocan la detención del programa, son debidos a la incorrecta programación de
algún proceso y como resultado se obtienen datos erróneos. Errores de este tipo son cálculos
mal hechos, bucles infinitos, devolución de valores incorrectos, etc. Como ni los detecta el
compilador, ni provocan la interrupción del programa deben revisarse a mano usando las
herramientas de depuración.

z Consejo: modularice su programa utilizando procedimientos cortos que realicen trabajos


concretos y precisos, de esta forma conseguirá, además de que el programa quede más elegante
y en un futuro sea más sencillo modificarlo y depurarlo.

03/08/2010 Adolfo Aparicio 97


Ejercicio

Cree una Macro con un juego que


consiste en que la máquina piensa un
número entre 0 y 100100, y el jugador
debe adivinarlo. Para ello, dispone de
10 tiradas
tiradas, y el programa le indica si
el número secreto es mayor o menor
al introducido
introducido.

03/08/2010 Adolfo Aparicio 98


Solución Ejercicio: Adivina
Sub adivina()
Dim zona As String
Dim x As Byte, n As Byte
Dim tirada As Byte
Randomize
x = Fix(Rnd * 101) : tirada = 1 'FIX=INT=parte entera
Do
If zona = "" Then
n = InputBox("Introduzca un número entero del 0 al 100" & vbCrLf _
& "Dispone
Dispone de 10 tiradas para lograrlo"
lograrlo , "Tirada
Tirada número " & tirada)
Else
n = InputBox("El número secreto es " & zona & vbCrLf & "Introduzca otro", "Tirada número " & tirada)
End If
If n = x Then
MsgBox "Felicidades!!!"
Felicidades!!! & vbCrLf & "Ha
Ha adivinado el número secreto " & x & ", en " & tirada & " tiradas
tiradas"
Exit Sub
End If
If x < n Then
zona = "Inferior"
Else
El
zona = "Superior"
End If
tirada = tirada + 1
Loop Until tirada > 10
MsgBox "Ha agotado las 10 tiradas disponibles" & vbCrLf & "El número secreto es " & x
End Sub
03/08/2010 Adolfo Aparicio 99
D
Depuración
ió dde programas
z Estas herramientas son muy útiles a la hora de comprobar paso a paso el funcionamiento del
programa y detectar los procesos que provocan un mal funcionamiento del mismo.
z Importe Módulo5.bas
z Active la barra de depuración
z (Ver/ Barras de Herramientas/ Depuración)
z Modo Ejecución paso a paso
z Paso a Paso por Instrucciones. F8
z Paso a Paso por Procedimientos. MAY+F8
z Sirve para ejecutar todo un procedimiento. Cuando en la ejecución de un procedimiento, se llega a
una línea que llama a otro procedimiento o función, pulsando este botón se puede provocar la
ejecución de todo el código de esta función para luego continuar con el modo paso a paso.
z Modo Interrupción
z En programas largos resulta fastidioso tener que ejecutarlos paso a paso, sobretodo si sabemos que el
error se produce en una parte avanzada del programa. El modo interrupción, permite la ejecución del
programa hasta una instrucción determinada para, a partir de esta, ejecutar paso a paso y así poder
detectar el error.
z Definir p
puntos de interrupción
p
z 1. Sitúe el cursor sobre la instrucción en la cual debe detenerse el programa para continuar paso a
paso.
z 2. Pulse sobre el botón . También puede activar la opción Depuración/ Alternar punto de
interrupción, pulsar la tecla F9 o bien hacer un clic en la parte izquierda de la ventana del módulo
(la franja vertical en color gris).
z Para desactivar un punto de interrupción siga los mismos pasos

03/08/2010 Adolfo Aparicio 100


L Ventana
La V t de
d Inspección
I ió
z Inspecciones rápidas de variables
z Estas opciones sirven para revisar el valor de las variables a medida que se va ejecutando
el programa.
p g
z Para ver los valores que van tomando las variables es conveniente tener visible la Ventana
de inspección, para activarla Ver/ Ventana de Inspección
z Añadir una variable a la ventana de inspección
z 1. Seleccione la variable que desee añadir a la ventana haciendo un clic sobre ella.
z 2 Activar Depuración/ Inspección rápida o MaY+F9.
2. MaY+F9
z Aparece un cuadro de diálogo donde se muestra el valor actual de la variable. Si no
está ejecutando el programa paso a paso, aparecerá el valor Fuera de Contexto.
z 3. Pulse sobre el botón Agregar para añadir la variable a la ventana de inspección.
z Debe tener en cuenta que para revisar las variables las expresiones que les asignan
valores deben de ejecutarse al menos una vez.
vez
z Cuando ejecuta el programa paso a paso, si sitúa el puntero de ratón sobre
una variable, se muestra el valor de la misma
z Borrar una variable de la ventana de Inspección
z Sólo debe seleccionarla en la ventana de inspección y pulsar sobre la tecla SUPR.
SUPR
z Modificar el valor de una variable en tiempo de ejecución
z A veces resulta interesante cambiar el valor de alguna variable cuando se está ejecutando
el programa, para ver que ocurre si coge determinados valores, para terminar un bucle,…

03/08/2010 Adolfo Aparicio 101


E
Expresiones
i d
de R
Revisión
i ió
z Además de permitir añadir una variable o
expresión
ió ddentro
t d de lla Ventana
V t IInmediato,
di t
una Expresión de Revisión permite
interrumpir la ejecución del programa
cuando una variable coge determinado
valor.
z Piense que muchas veces un programa deja
de funcionar, o funciona mal cuando una
variable coge determinados valores.
z Con una expresión de revisión, podremos
detener la ejecución del programa cuando
una variable contiene determinado valor ( a
partir
ti d
de d
determinado
t i d valor),
l ) lluego,
podremos continuar con la ejecución paso a
paso para ver que ocurre a partir de este
punto.
z Sitúe el cursor sobre una variable y
seleccione Agregar Inspección
Inspección, Interrupción
cuando el valor sea verdadero, y luego en la
ventana de inspecciones, editar la variable y
añadirla una condición lógica que al
cumplirse parará el procedimiento.

03/08/2010 Adolfo Aparicio 102


L V
La Ventana
t Inmediato
I di t
z Es otra forma de inspeccionar
variables cuando el programa está
en modo interrupción (ejecutándose
paso a paso)
z Además, ofrece la posibilidad de
cambiar valores de las variables
z E incluso ejecutar
j o evaluar
expresiones. Para ver el valor de
una variable en la ventana
inmediato debe anteponerle un ? y
luego pulsar Enter.
z Para activar la ventana Inmediato
Inmediato,
active opción Ver/Inmediato, o
pulse la combinación CONTROL+G.
z Pruebe
z ?2+3
z ?2^3
z ?exp(1)
z ?Suma_Columna

03/08/2010 Adolfo Aparicio 103


L iinstrucción
La t ió DDebug.Print
b Pi t
z Esta instrucción se utiliza
directamente sobre el código del
programa
z Permite ver todos los valores que
ha ido tomando una variable o
expresión durante la ejecución del
programa.
z Los valores se mostrarán en la
ventana Inmediato una vez
finalizado el programa.
p g
z Esta expresión resulta útil en una
fase avanzada de depuración ya
que permite ir viendo la evolución
de una variable o expresión sin
necesidad de poner puntos de
interrupción.
z Cuando el programa esté listo
deben eliminarse.
z Ejecute Dos
Dos_a_la_diez()
a la diez()

03/08/2010 Adolfo Aparicio 104


F
Formularios
l i

z Mostrar la barra de herramientas para cuadros de control


z Cuadro de Texto
z Etiqueta
z Botón de Comando
z Modo Diseño
z Propiedades
z En la
E l propiedad
i d d Caption,
C ti cambien
bi ell ttexto
t Label1
L b l1 por Datos
D t a
Buscar

03/08/2010 Adolfo Aparicio 105


L eventos
Los t
z Cuando se programan controles bien sea directamente en la
hoja o desde un formulario, debe tener en cuenta los eventos.
z Un evento se da cuando ocurre algo sobre un objeto
z En entornos Windows constantemente se están produciendo
eventos que son recogidos por el sistema.
z Clicks con el ratón sobre un control
z Teclear sobre un cuadro de texto,
texto etc
etc.
z Programar un evento significa hacer que se ejecuten
determinadas instrucciones cuando ocurra dicho evento.
z En general,
general todos los controles son capaces de capturar
diferentes eventos.

03/08/2010 Adolfo Aparicio 106


C d
Cuadros Combinados
C bi d (C (ComboBox)
b B )
z Con un ComboBox podremos escoger el campocampo, es
decir, podremos extraer coincidencias de Nombre,
Apellidos,
p la Ciudad, etc.
z Para ello incluiremos un cuadro combinado que
permita escoger en que campo o columna tiene que
b
buscarse lla coincidencia.
i id i
z La lista, por supuesto, mostrará los nombres de las
columnas.
columnas

03/08/2010 Adolfo Aparicio 107


Formularios y
Controles
„ Cree un nuevo libro (mundo.xls)
„ Acceda al Editor de Visual Basic
„ Menú, Insertar, UserForm
„ En el formulario que aparece UserForm1 se insertarán
á los
controles del Cuadro de Herramientas que también ha
aparecido. Si no aparece haga clic en el icono “Cuadro de
Herramientas”.
„ Insertemos Controles
„ Clic en el “Cuadro de Texto” del cuadro de herramientas
„ Marcar un recuadro en el UserForm1
„ Clic
l en ell “Botón
“ ó de d Comando”d ”
„ Marcar un pequeño recuadro en el UserForm1
„ Inserte un segundo Botón de Comando

03/08/2010 Adolfo Aparicio 108


Hola Mundo
„ Seleccione el CommandButton1 y vea las propiedades. Si no
aparecen pulse el icono Ventana de Propiedades
„ En la propiedad Caption escriba Saludo
„ En la propiedad Caption del CommandButton2 escriba Borrar
„ Haga clic en el icono Ver Código de la Ventana de Proyecto
„ Observe que aparece un área para introducir e códigog de los
eventos asociados al formulario
„ Arriba aparecen dos desplegables. El de la izquierda contiene
los Objetos y el de la derecha los Procedimientos
„ Seleccione
l del
d l desplegable
d l bl ell objeto
b CommandButton1.
d
„ En el otro desplegable aparece automáticamente Click
„ Escribe el siguiente código

03/08/2010 Adolfo Aparicio 109


Código para el UserForm

Private Sub CommandButton1_Click()


TextBox1.Text = "Hola Mundo"
E d Sub
End S b
Private Sub CommandButton2_Click()
TextBox1.Text = ""
End Sub

„ Vuelva al formulario. Basta cerrar la ventna, o mejor hacer clic


en el icono Ver Objeto
„ Grabar
„ Ejecutar el programa
„ Son procedimientos de evento
03/08/2010 Adolfo Aparicio 110
Programar User Forms

„ El procedimiento a seguir es:


1. Menú Insertar UserForm
– Cuadro de Herramientas
2. Establecer Propiedades
p de los objetos
j
3. Escribir el código

03/08/2010 Adolfo Aparicio 111


Contraseña
„ Insertar un nuevo formulario. UserForm2
„ Propiedades del UserForm2
– Name = frmClave
– Caption = Contraseña
„ Insertar una Etiqueta (label
(label))
– Name =lblClave
– Caption = Introduzca la clave secreta
„ Inserte un Cuadro de Texto (TextBox)
– Name = txtContraseña
– MaxLength = 6
– PasswordChar = *
„ Inserte el CommandBooton1 „ Si un botón se pone como
Dafault = True, automáticamente
– Name = cdmAceptar los demás se p
ponen Default =
– D f lt = T
Default True False
– Caption = Aceptar
„ Inserte el CommandBooton2 „ En un formulario solo puede
– Name = cdmCancelar haber un botón con la propiedad
– Caption = Cancelar Cancel = True
– Cancel = True
03/08/2010 Adolfo Aparicio 112
Código
g del UserForm
Contraseña
„ Escriba los siguientes procedimientos de evento
„ Y ejecute el formulario para ver el funcionamiento
Private Sub cmdAceptar_Click()
If UCase(txtContraseña.Text) <> "MACROS" Then
MsgBox "Contraseña Incorrecta", vbCritical
End
Else
MsgBox "Contraseña Aceptada", vbExclamation
End
End If
End Sub

Private Sub cmdCancelar_Click()


End
End Sub
03/08/2010 Adolfo Aparicio 113
Formulario
Fechas
„ Nuevo Libro Fechas.xls
„ Abrir el Editor de Visual Basic
„ Insertar un UserForm
„ Incrustar los controles de la imagen

03/08/2010 Adolfo Aparicio 114


Propiedades
– UserForm1 – TextBox1
„ Name = frmFechas „ Name =
„ Caption = Fechas txtPrimeroMesViene
– Label1 – TextBox2
„ Name = lblEtiq1 „ Name = txtFecha
„ Caption = Hoy es – Label5
– Label2 „ Name = lblEtiq4
„ Name = lblHoy „ Caption = 1
1º Mes
Siguiente
– Label3
„ Name = lblEtiq2
– TextBox3
„ Caption = Primero del mes „ Name = txtSiguiente
que viene – CommanButton1
– Label4 „ Name = cmdCalcular
„ Caption = Calcular
„ Name = lblEtiq3
– CommandButton2
„ Caption
p = Escribe una fecha „ Name = cmdOtra
„ Caption = Otra
03/08/2010 Adolfo Aparicio 115
Procedimientos de Evento
Private Sub Private Sub cdmCalcula_Click()
UserForm_Activate() txtSiguiente.Text =
lblHoy Caption = Date
lblHoy.Caption PrimeroMesCualquiera(txtFecha Text)
PrimeroMesCualquiera(txtFecha.Text)
txtPrimeroMesViene.Text = End Sub
PrimeroMes Private Sub cmdOtra_Click()
txtFecha Text = Date
txtFecha.Text txtFecha Text = ""
txtFecha.Text
txtFecha.SetFocus txtSiguiente.Text = ""
End Sub txtFecha.SetFocus
E d Sub
End S b
Function PrimeroMes()
PrimeroMes = DateSerial(Year(Now), Month(Now) + 1, 1)
End Function
Function PrimeroMesCualquiera(Cual As Date) As Date
PrimeroMesCualquiera = DateSerial(Year(Cual), Month(Cual) + 1, 1)
End Function
03/08/2010 Adolfo Aparicio 116
Pasar una Matriz a una Función
Sub SumaCien() Function calcula(a() As Byte) As
Dim i As Byte Single
Dim a(100) As Byte
Dim i As Byte
'Genera una matriz de números aleatorios
enteros entre 0 y 100 Dim s As Single
Randomize 'Calcula la suma de los 100
'Si no se pone Randomize los valores números que contiene la matriz
aleatorios siempre son los mismos
'Pruebelo. Abra el libro y vuelva a lanzar la
For i = 1 To 100
macro. Los resultado serán los mismos. s = s + a(i)
For i = 1 To 100 Next i
a(i) = Int(Rnd * 101)
calcula = s
Next i
MsgBox "Suma de 100 números aleatorios" End Function
& vbCrLf & _
"enteros entre 0 y 100" & vbCrLf & vbCrLf &
Chr(9) & calcula(a())
End Sub
03/08/2010 Adolfo Aparicio 117
C
Consulta
lt News
N
z Asunto: Consulta como buscar ultimo
z Quiero averiguar como se hace una

búsqueda
d d de un ultimo
lti registro
i t d dentro
t d de un
rango determinado. Ej. Tengo un rango de
A1:A10 en donde hay datos desde A1 hasta
A6. En la celda A15 quiero obtener el valor o
dato que haya en la última celda ocupada del
rango A1:A10, es decir que me escriba en
este caso lo que hay en A6.
03/08/2010 Adolfo Aparicio 118
S l ió
Solución
Sub UltimoValor()
Worksheets("Hoja1").Activate 'Aqui le dices la hoja
ActiveSheet.Range("A10").Activate 'Aqui le dices el final del
rango
Do While IsEmpty(ActiveCell)
ActiveCell.Offset(-1, 0).Activate
Loop
Range("A15").Value = ActiveCell.Value
End Sub
z Se pude hacer con una formula, pero si tiene celdas vacías intermedias no funciona
=INDIRECTO(CONCATENAR("A";CONTAR(A1:A10)))

03/08/2010 Adolfo Aparicio 119


P
Pregunta
t CColor
l
z Asunto: codigo para contar celdas de X
z alguien me puede pasar el codigo - formula
para contar
t ell numero de
d celdas
ld que titienen
X's color (trama) saludos!!

03/08/2010 Adolfo Aparicio 120


R
Respuesta
t CColor
l 1
z Primero vamos a colorear unas cuantas celdas del rango
D1:D30. Para ello ejecuta el siguiente código:
Sub colorea()
Dim Celda
Dim R As Range
Set R = Range("D1.D30")
R Select
R.Select
For Each Celda In R
Celda.Interior.ColorIndex = Int(Rnd * 10) + 1
Next
End Sub

z En el código anterior hemos pedido que nos coloree con un máximo


de 10 colores, aunque sabemos que existen 56 colores distintos.
03/08/2010 Adolfo Aparicio 121
R
Respuesta
t CColor
l 2
z En segundo lugar ejecuta esta macro:
Sub pru()
MsgBox "Celdas de color Rojo (3): " & CuentaColor(Range("D6.D30"), 3)
End Sub

z Se basa en la función CuentaColor, que cuenta el color rojo (# 3)


Function CuentaColor(R As Range, tono As Byte) As Byte
Dim num As Long g
Dim Celda
For Each Celda In R
If Celda.Interior.ColorIndex = 3 Then num = num + 1
Next
CuentaColor = num
End Function

z V fichero
Ver fi h C
CeldaColor.xls
ld C l l
03/08/2010 Adolfo Aparicio 122

También podría gustarte