You are on page 1of 130

Macros

en Excel

MACROSENMSEXCELL

Queesunamacro?.

Unamacrosonunconjuntodeinstruccionesquesirvenparaautomatizarprocesos.Refirindonosaexcel,
supongamosquerealizamosfrecuentementelaaccindeseleccionarunrangoparaaplicarlenegrita,
cambio de fuente y centrado. En lugar de hacer estas acciones manualmente, se puede elaborar una
macro
e invocarla para que ejecute los tres procesos
automticamente.

Objetos,
mtodos.

propiedades

A la hora de trabajar con macros en excel, deben tenerse claros ciertos conceptos de lo que se
llamaprogramacinorientadaaobjetos(OOP).NonosextenderemosdemasiadosobrelaOOP,pero
sidefiniremosacontinuacinlosconceptosdeObjeto,Propiedades yMtodos.

Objeto.

Cuandoenelmundorealnosreferimosaobjetosignificaquehablamosdealgomsomenosabstracto
que puede ser cualquier cosa. Si decidimos concretar un poco ms podemos referirnos a objetos
coche,objetos silla, objetos casa, etc. En OOP, la generalizacin (o definicin) de un objeto se llama
Clase, asla clase coche seria como la representante de todos los coches del mundo, mientras queun
objeto cocheseria un coche en concreto.Demomento,nodefiniremosniestudiaremoslasclases
sinoquenosconcentraremosenlosobjetos,tengaencuentaperoquecualquierobjetoestdefinidoporuna
clase.

Cuandodecimosquelaclasecocherepresentaatodosloscochesdelmundosignificaquedefinecomo
esuncoche,cualquiercoche.Dichodeotraformayparaaproximarnosaladefinicininformtica,la
clasecochedefinealgoquetienecuatroruedas,unmotor,unchasis,...entonces,cualquierobjetoreal
decuatroruedas,unmotor,unchasis,...esunobjetodelaclasecoche.

Propiedades.

Cualquier objeto tiene caractersticas o propiedades como por ejemplo el color, la forma, peso,
medidas,etc. Estas propiedades se definen en la clase y luego se particularizan en cada objeto. As, en
la clasecochesepodran definirlaspropiedadesColor,AnchoyLargo,luegoaldefinirunobjetoconcreto
comocoche ya se particularizaran estas propiedades a, por ejemplo, Color = Rojo, Ancho = 2 metros y
Largo =
3,5metros.

Mtodos.

La mayora de objetos tienen comportamientos o realizan acciones, por ejemplo, una accin evidente
deun objeto coche es el demoverse o lo que es lo mismo, trasladarse de un punto inicial a un punto
final.Cualquierprocesoque implicauna accino pautadecomportamientopor parte deun objeto se
defineensuclaseparaqueluegopuedamanifestarseencualquieradesusobjetos. As, en la clase
coche sedefiniran en el mtodo mover todos los procesos necesarios para llevarlo a cabo (los
procesos paradesplazar de un punto inicial a un punto final), luego cada objeto de la clase coche
simplemente tendra que invocar este mtodo para trasladarse de un punto inicial a un punto final,
cualesquiera que fueran esospuntos.

Repasemosacontinuacintodosestosconceptosperoahoradesdeelpuntodevistadealgunosdelos

Prof. Cesar Apaza CCopa

Pgina 1

Macros en Excel

objetos que nos encontraremos en Excel como WorkSheet(Objeto hoja de clculo) oRange(Objeto
casillaorangodecasillas).

Un objeto Range est definido por una clase donde se definen sus propiedades, recordemos que
unapropiedadesunacaracterstica,modificableono,deunobjeto.Entrelaspropiedadesdeunobjeto
RangeestnValue, que contiene el valor de la casilla , Column yRow que contienen respectivamente la
fila ylacolumnadelacasilla,Fontquecontienelafuentedeloscaracteresquemuestralacasilla,etc.

Prof. Cesar Apaza CCopa

Pgina 2

Macros en Excel

Range, como objeto, tambin tiene mtodos, recordemos que los mtodos sirven llevar a cabo una
accinsobre un objeto. Por ejemplo el mtodo Activate, hace activa una celda determinada, Clear,
borra elcontenido de una celda o rango de celdas, Copy,copiaelcontenidodelaceldaorangode
celdasenelportapapeles,...

Conjuntos.

Una conjunto es una coleccin de objetos del mismo tipo, para los que conozcan algn lenguaje
deprogramacin es un array de objetos. Por ejemplo, dentro de un libro de trabajo puede existir ms de
una hoja (WorkSheet), todas las hojas de un libro de trabajo forman un conjunto, el conjunto
WorkSheets. Cada elemento individual de un conjunto se referencia por un ndice, de esta forma, la
primera, segunda y tercera hoja de un libro de trabajo, se referenciarn por WorkSheets(1), WorkSheets(2) y
WorkSheets(3).

ObjetosdeObjetos.

Esmuyhabitualqueunapropiedaddeunobjetoseaotroobjeto.Siguiendoconelcoche,unadelas
propiedades del coche es el motor, y el motor es un objeto con propiedades como cubicaje,
caballos, nmero de vlvulas, etc. y mtodos, como aumentar_revoluciones, coger_combustible,
mover_pistones,etc.

En Excel, el objeto WorkSheets tiene la propiedadRangeque es un objeto,Range tiene la propiedad


Font que es tambin un objeto yFont tienelapropiedad Bold(negrita). Tenga esto muy presente ya que
utilizaremos frecuentemente Propiedades de un objeto que sern tambin Objetos. Dicho de otra
forma,hay propiedades que devuelven objetos, por ejemplo, la propiedadRange de un objeto
WorkSheetdevuelveunobjetodetipoRange.

ProgramacinOrientadaaObjetosoProgramacinBasadaenObjetos.

Hay una sutil diferencia entre las definiciones del ttulo. Programacin orientada a Objetos, significa que
el programador trabaja con objetos fabricados por l mismo, es decir, el programador es quien
implementa las clases para luego crear objetos a partir de ellas. Lo que haremos nosotros, por el
momento, ser utilizar objetos ya definidos por la aplicacin Excel (WorkSheets, Range,...) sin
implementarninguno de nuevo, por lo que en nuestro caso es ms correcto hablar de
programacinbasadaenobjetos.ObservequeestaesunadelasgrandesventajasdelaOOP,utilizar
objetosdefinidosporalguiensintenerqueconocernadasobresuimplementacin,slo debemos conocer
sus propiedades ymtodosyutilizarlosdeformacorrecta.

Bueno,despusdeestaextensaperonecesariaintroduccinpasemosyaahaceralgunacosaenExcel.No
es necesario que se aprenda lo anterior al pi de la letra y tampoco es necesario que lo comprenda al
cienpor cien, slo tngalo presentepara las definiciones que vienena continuacin yver como va
asimilandolosconceptosdeObjeto,propiedades,mtodos,etc.

Prof. Cesar Apaza CCopa

Pgina 3

Macros en Excel

EditordeVisualBasic.

El editor de visual bsic es la aplicacin que utilizaremos para construir las macros que interactuaran
junto con los libros de trabajo. A continuacin prepararemos un archivo en el que escribiremos las
primerasinstruccionesenVisualbasic.

Prepararunarchivonuevo.

ParaentrareneleditordeVisualBasic,presioneAlt+F11

Insertarunnuevomdulo.

Un mdulo sirve para agrupar procedimientos y funciones. El procedimiento y la funcin son entidades
deprogramacinquesirvenparaagruparinstruccionesdecdigoquerealizanunaaccinconcreta.

Para insertar un mdulo active opcin del men Insertar/ Mdulo. Se activar una nueva ventana, si
aparecedemasiadopequea,maximcela.

Prof. Cesar Apaza CCopa

Pgina 4

Macros en Excel

Insertarunprocedimiento.

Yahemosdicho queunprocedimientoesunbloquedeinstruccionesdecdigoquesirvenparallevara
caboalgunatareaespecfica.Unprocedimientoempiezasiempreconlainstruccin

SubNombre_Procedimiento

Yterminaconlainstruccin

EndSub.

Acontinuacincrearemosunprocedimientoparaponereltexto"Hola"enlacasillaA1.

Ejemplo1

SubPrimero

Range("A1").Value="Hola"

EndSub

Observeelcdigo.

Range("A1").Value="Hola"

EnestalneaestamosindicandoquetrabajamosconunobjetoRange. Paraindicarle que nos referimos


alacasillaA1,encerramosentreparntesisestareferencia(msadelanteverotraformadereferirnosa
lascasillas). De este objeto, indicamos que queremos establecer un nuevo valor para la propiedad
Value,observequeparasepararelobjetodesupropiedadutilizamoslanotacinpunto.

RecuerdequeelconjuntoRange esunobjetoquependedelobjetoWorkSheets,asporejemplo
elsiguientecdigoharalomismoqueelanterior.

WorkSheets(1).Range("A1").Value="Hola"

Bueno, de hecho no hace lo mismo, en la primera opcin,el texto "Hola" se pone dentro de la casilla A1
delahojaactiva,mientrasqueenelsegundoesenlacasillaA1deprimerahoja ( del conjunto de hojas).
La segunda notacin es ms larga, pero tambin ms recomendable ya que se especifican todos
losobjetos. En muchas ocasiones se pueden omitir algunos objetos precedentes, no le aconsejamos
hacerlo,susprogramasperdernclaridadyconcisin.

SideseahacerreferenciaalahojaactivapuedeutilizarActiveSheet,as,elprimerejemplolo
dejaremosdelamanerasiguiente.

SubPrimero

ActiveSheet.Range("A1").Value="Hola"

EndSub

Prof. Cesar Apaza CCopa

Pgina 5

Macros en Excel

Sideseaponer"Hola"(ocualquiervalor)enlacasillaactiva,puedeutilizarlapropiedad(objeto)
ActivecelldeWorkSheets.Asparaponer"Hola"enlacasillaactivadelahojaactivaseria,

SubPrimero

ActiveSheet.ActiveCell.Value="Hola"

EndSub

Para terminar con este primer ejemplo.WorkSheetsestn dentro del Objeto WorkBooks(libros de
trabajo) y WorkBooks estndentrodeApplication.Application eselobjetosuperior,eselque
representalaaplicacinExcel.As,elprimerejemplo,siguiendotodalajerarquadeobjetosquedarade
laformasiguiente.

SubPrimero

Application.WorkBooks(1).WorkSheets(1).Range("A1").Value="Hola"

EndSub

Insistiendo con la nomenclatura, Applicationcasi nunca es necesario especificarlo, piense que todos los
objetospendendeeste,WorkBooks sernecesarioimplementarlosienlasmacrossetrabajacon
diferentes libros de trabajo (diferentes archivos), a partir deWorkSheets,esaconsejableincluirloenel
cdigo, sobre todo si se quiere trabajar con diferentes hojas, ver, sin embargo, que en muchas
ocasionesnoseaplica.

Ejecutarunprocedimientoofuncin.

Pruebe ejecutar el primer procedimiento de


ejemplo.

1. Siteelcursordentrodelprocedimiento.

2. ActiveopcindelabarrademensEjecutar/EjecutarSubUserform.Tambinpuedehacerclic
sobreelbotn

opulsarlateclaF5.

Paraejecutarelprocedimientodesdelahojadeclculo.

Debeestarenunahoja,noeneleditordeVisualBasic

1. ActiveopcindelabarrademensHerramientas/Macro/Macros.Sedespliegaunaventanaque
muestraunalistadondeeststodaslasmacrosincluidasenellibrodetrabajo.

2. SeleccionelamacrodelalistaypulsesobreelbotnEjecutar.

Prof. Cesar Apaza CCopa

Pgina 6

Macros en Excel

Ejemplo2

En este segundo ejemplo simplemente ampliaremos la funcionalidad de la macro del ejemplo 1. Adems
deescribir"Hola"enlacasillaA1delaceldaA1,lapondremosennegrita y le daremos color al texto.
ParaelloutilizaremoslaspropiedadesBoldyColordelobjetoFont.

SubSegundo

ActiveSheet.Range("A1").Value="Hola"
ActiveSheet.Range("A1").Font.Bold=True
ActiveSheet.Range("A1").Font.Color=RGB(255,0,0)

EndSub

True.

True,quetraducidoesverdadero,simplementeindicaquelapropiedadBoldestactivada.Sise
desearadesactivar,bastaraconigualarlaalvalorFalse.

LafuncinRGB.

ObservequeparaestablecerelcolordelapropiedadseutilizalafuncinRGB(Red,Green, Blue),los
tresargumentosparaestafuncinsonvaloresdel0a255quecorrespondenalaintensidaddelos
coloresRojo,VerdeyAzulrespectivamente.

Referenciarunrangodeceldas.

SlotienequecambiaralaformaCasilla_Inicial:Casilla_Final.Porejemploaplicar elltimoejemploal
rangodecasillasquevadelaA1alaA8,ponga.

SubSegundo

ActiveSheet.Range("A1:A8").Value="Hola"
ActiveSheet.Range("A1:A8").Font.Bold=True
ActiveSheet.Range("A1:A8").Font.Color=RGB(255,0,0)

EndSub

Prof. Cesar Apaza CCopa

Pgina 7

Macros en Excel

Variables.

AcontinuacinvamosarepetirelprogramaEjemplo1,peroenlugardeponer"Hola"enlacasillaA1dela
hoja activa, dejaremos que el usuario entre un texto desde teclado y a continuacin guardaremos ese
valorenesacasilla.Observequeelvalorqueentredelusuariodebeguardarseenalgnlugarpara
poderponerlo despus en la casilla A1; pues bien, ese valor se guardar en una variable. Una
variable essimplementeuntrozodememoriaquelafuncinoprocediminetosereservaparaguardar
datos,laformageneraldedeclararunavariablees

DIMvariableAStipo.

SiendovariableelnombrequeseasignaalamismayTipoeltipodedatosqueseguardarn(nmeros,
texto,fecha,boleanos,...).Ennuestroejemplo,declararemoslavariabledetipoString(tipotexto),y
loharemosdelaformasiguiente.

DimTextoAsString

Conestoestamosindicandoquesereserveuntrozodememoria(elquesea),quesellamaTextoyque
eltipodedatosqueseguardarnahserncaracteres.

LaFuncinInputBox.

Estafuncinmuestraunaventanaparaqueelusuariopuedatecleardatos.Cuandosepulsasobre
Aceptar,losdatosentradospasanalavariablealaquesehaigualadolafuncin.Vealalneasiguiente.

Texto=InputBox("Introduzcaeltexto","Entradadedatos").

SienlaventanaquemuestraInputBoxpulsasobreelbotnAceptar,losdatostecleadosseguardarnel
lavariableTexto.

SintaxisdeInputBox.

InputBox(Mensaje,Ttulo,Valorpordefecto,Posicinhorizontal,PosicinVertical,Archivo
ayuda,Nmerodecontextoparalaayuda).

Mensaje:Eselmensajequesemuestraenlaventana.Sideseaponermsdeunalnea
ponga
Chr(13)paracadanuevalnea,veaelejemplosiguiente.

Ttulo:EselttuloparalaventanaInputBox.Esunparmetroopcional.

Valorpordefecto:Eselvalorquemostrarpordefectoelcuadrodondeelusuarioentrael
valor.Parmetroopcional.

Posicin Horizontal:LaposicinXdelapantalladondesemostrarelcuadro,concretamentees
laposicinparalaparteizquierda.Siseomiteelcuadrosepresentahorizontalmentecentrado
alapantalla.

Posicin Vertical:LaposicinYdelapantalladondesemostrarelcuadro,concretamenteesla
posicin para la parte superior. Si se omite elcuadrosepresentaverticalmentecentradoa
lapantalla.

Archivo Ayuda: Es el archivo que contiene la ayuda para el cuadro. Parmetro


opcional.

Nmerodecontextoparalaayuda:Nmeroasignadoquecorrespondealidentificadordel
archivodeayuda,sirveparalocalizareltextoquesedebemostrar.Siseespecificaeste

Prof. Cesar Apaza CCopa

Pgina 8

Macros en Excel

parmetro,debeespecificarseobligatoriamenteelparmetroArchivoAyuda.

Prof. Cesar Apaza CCopa

Pgina 9

Macros en Excel

Ejemplo3

SubEntrar_Valor

DimTextoAsString

'Chr(13)sirveparaqueelmensajesemuestreendosLneas
Texto=InputBox("Introduciruntexto"&Chr(13)&"ParalacasillaA1","Entradadedatos")
ActiveSheet.Range("A1").Value=Texto

EndSub

Esteejemplotambinsepuedehacersinvariables.

SubEntrar_Valor

ActiveSheet.Range("A1").Value=InputBox("Introduciruntexto"&Chr(13)&"Paralacasilla
A1","Entradadedatos")

EndSub

Ejemplo4

Repetiremoselejemplo3,peroenlugardeentrarlosvaloressobrelacasillaA1,haremosqueelusuario
pueda elegir en que casilla quiere entrar los datos, es decir, se le preguntar al usuario mediante
unsegundoInputboxsobrequecasillaquiereentrarelvalordelprimerInputbox.Sernnecesaria
dosvariables,unaparaguardarlacasillaqueescojaelusuarioyotraparaguardarelvalor.

OptionExplicit

SubEntrar_Valor

DimCasillaAsString
DimTextoAsString

Casilla=InputBox("Enquecasillaquiereentrarelvalor","EntrarCasilla")
Texto=InputBox("Introduciruntexto"&Chr(13)&"Paralacasilla"&Casilla,"Entradade
datos")

ActiveSheet.Range(Casilla).Value=Texto

EndSub

Prof. Cesar Apaza CCopa

Pgina 10

Macros en Excel

LasentenciaOptionExplicit.

En visual basic no es necesario declarar las variables, por ejemplo, en el programa anterior se hubiera
podidoprescindirdelaslneas

DimCasillaAsString
DimTextoAsString

A pesar de ello, le recomendamos que siempre declare las variables que va a utilizar, de esta forma
sabrcuales utiliza el procedimiento y que tipo de datos guarda cada una, piense que a medida
quevayaaprendiendo, crear procedimientos cada vez ms complicados y que requerirn el uso de
msvariables,si no declara las variables al principio del procedimiento ocurrirn dos cosas. Primero, las
variables nodeclaradas son asumidas como tipo Variant (este es un tipo de datos que puede
almacenar cualquiervalor, nmero, fechas, texto, etc. pero tenga en cuenta que ocupa 20 Bytes y para
guardar una referencia auna casilla, la edad de alguien, etc. no son necesarios tantos bytes); segundo,
reducir considerablementelalegibilidaddesusprocedimientosyaquelasvariableslasircolocandoa
medidaquelasnecesite,esto,alalargacomplicarlacorreccinomodificacindelprocedimiento.

Bueno, pues toda la explicacin anterior es para que declare todas las variables que va a utilizar.La
sentencia Option Explicit al principio del mdulo fuerza a que se declaren todas las variables. Sial
ejecutar el programa, se encuentra alguna variable sin declarar se producir un error y no se
podrejecutarelprogramahastaquesedeclare.

Si todava no se haconvencidosobrelaconvenienciadedeclararlasvariablesyutilizar Option Explicit,


pruebe el procedimiento siguiente, cpielo tal cual (Texto y Testo estn puestos adrede simulando
quenoshemosequivocadoalteclear).

SubEntrar_Valor

Texto=InputBox("Introduciruntexto"&Chr(13)&"ParalacasillaA1","Entradadedatos")
ActiveSheet.Range("A1").Value=Testo

EndSub

Observequeelprogramanohaceloquesepretendaquehiciera.Efectivamente,TextoyTestosondos
variables diferentes,comonosehadeclaradoningunanisehautilizadoOption Explicit Visual Basic no
daningntipodeerroryejecutaelprograma.Pruebeelsiguientemduloeintenteejecutarlo.

OptionExplicit

SubEntrar_Valor

DimTextoAsString

Texto=InputBox("Introduciruntexto"&Chr(13)&"ParalacasillaA1","Entradadedatos")
ActiveSheet.Range("A1").Value=Testo

EndSub

Observequeelprogramanoseejecuta,alponer Option Explicit, forzamos a que se declaren todas las


variables.VisualBasicdetecta que la variable Testo no ha sido declarada y as lo indica mostrando Error,
entonces es cuando es ms fcil darnos cuenta del error que hemos cometido al teclear y
cambiamosTestoporTexto.Ahoraimaginequeelerrorseproduceenunprogramadecientos de lneas
que necesitaotrastantasvariables.

Prof. Cesar Apaza CCopa

Pgina 11

Macros en Excel

TiposdedatosenVisualBasicparaExcel.(TablacopiadadelaayudaenlneadeVisualBasicpara
Excel).

Tipodedatos

Tamao
Dealmacenamiento
1byte
2bytes
2bytes
4bytes
4bytes

Byte
Boolean
Integer
Long(enterolargo)
Single(comaflotante/
precisinsimple)
Double(comaflotante/
precisindoble)

8bytes

Currency(enteroa
escala)
Decimal

14bytes

Date
Object
String(longitud
variable)

8bytes
4bytes
10bytes+longitud de
lacadena

String(longitudfija)
Variant(connmeros)

Variant(con
caracteres)
Definido porel
usuario(utilizando
Type)

8bytes

Intervalo
0 a 255
True o False
32.768 a 32.767
2.147.483.648 a 2.147.483.647
3,402823E38 a 1,401298E45 para valoresnegativos;
1,401298E45 a 3,402823E38 para valorespositivos
1,79769313486232E308 a 4,94065645841247E324
paravaloresnegativos;4,94065645841247E324a
1,79769313486232E308 para valores positivos
922.337.203.685.477,5808 a
922.337.203.685.477,5807
+/79.228.162.514.264.337.593.543.950.335sinpunto
decimal;+/7,9228162514264337593543950335con
28posicionesaladerechadelsignodecimal;el
nmeromspequeodistintodeceroes+/
0,0000000000000000000000000001
1 de enero de 100 a 31 de diciembre de 9999
Cualquier referencia a tipo Object
Desde 0 a 2.000 millones

Longituddelacadena

Desde 1 a 65.400 aproximadamente

16bytes

Cualquier valor numrico hasta el intervalodeuntipo


Double

22bytes+longitud de
cadena

El mismo intervalo que para un tipo Stringdelongitud


variable

Nmerorequerido por
loselementos

El intervalo de cada elemento es el mismo queel


intervalodesutipodedatos.

ConversindeTiposdedatos.

CopieelsiguienteEjemplo.Simplementesepidendosnmeros,sesumanyseguardanellacasillaA1de
lahojaactiva.

Ejemplo5

OptionExplicit

SubSumar()

DimNumero1AsInteger
DimNumero2AsInteger

Numero1=InputBox("Entrarelprimervalor","Entradadedatos")
Numero2=InputBox("Entrarelprimervalor","Entradadedatos")
ActiveSheet.Range("A1").Value=Numero1+Numero2

EndSub

Prof. Cesar Apaza CCopa

Pgina 12

Macros en Excel

Ejecuteelprocedimientoypongarespectivamentelosvalores25y25.Observequetodohaido
correctamenteyenlacasillaA1delahojaactivaapareceun50.

Ahora,vuelvaaejecutarelprogramaycuandoselepideelprimervalorteclee"Hola".Observequeel
programasedetieneindicandounerroreneltipodedatos.Efectivamente,observequelafuncin
InputBox devuelve siempre datos tipo String, en el primerejemplonohahabidoningnproblema,al
1
entrarcaracteresnumricos , estos pueden asignarse a variables tipo Integer porque Visual Basic hace
automticamente la conversin, pero al entrar texto e intentarlo asignar a una variable Integer
Visual
Basic muestra unerror indicandoque la variable noesadecuada paralos datosque se desean
guardar.

Parasolucionarestosproblemassedebenutilizarfuncionesdeconversindetipo.Estasfunciones,como
su nombre indica, convierten datos de un tipo a otro,deString a Integer, de IntegeraString, de Date
aString,...Aselprocedimientoanteriorquedara.

OptionExplicit

SubSumar()

DimNumero1AsInteger
DimNumero2AsInteger

Numero1=Val(InputBox("Entrarelprimervalor","Entradadedatos"))
Numero2=Val(InputBox("Entrarelprimervalor","Entradadedatos"))
ActiveSheet.Range("A1").Value=Numero1+Numero2

EndSub

La funcin Val(DatoString),convierteunacadenadecaracteresavalornumrico.Silacadenaa
convertircontienealgncarcternonumricodevuelve0.As,sialpedirunvalorseteclea"Hola",la
funcinVal,devolveruncero.

Tenga en cuenta que para los ordenadores no es lo mismo el nmero 1 que el carcter"1". En los
lenguajesdeprogramacinactualeslaconversindecarcter"1"anmero1sehace automticamente
enmuchos casos, esto es bueno y es malo. Es bueno porque nos ahorra tener que hacer las conversiones

Prof. Cesar Apaza CCopa

Pgina 13

Macros en Excel

y esmaloporqueesmsdifcilcontrolarciertoscasos.Sigaconlosejemplosyentenderdeloque
estamoshablando. Slo para su informacin, el ordenador guarda el nmero 1 de la siguiente manera
00000001,mientrasqueelcarcter"1"seguardacomo 00110000(elnmero48delcdigoASCII).

Prof. Cesar Apaza CCopa

Pgina 14

Macros en Excel

Funcionesdeconversindetipos.(TablacopiadadelaayudaenlneadeVisualBasicparaExcel).

Val(Cadena).Conviertelacadenaaunvalornumrico.
Str(Nmero).Convierteelnmeroaunaexpresincadena.

LassiguientesfuncionestienenlaformaFuncin(Expresin).

Funcin
Cbool
Cbyte
Ccur
Cdate
CDbl

Tipodevuelto
Boolean
Byte
Currency
Date
Double

Intervalo del argumento expresin


Cualquier expresin de cadena o numrica vlida.
0 a 255.
922.337.203.685.477,5808 a 922.337.203.685.477,5807.
Cualquier expresin de fecha.
4,94065645841247E324 para valores negativos;
4,94065645841247E324a1,79769313486232E308para
valores positivos.

Cdec

Decimal

+/7,9228162514264337593543950335. La menorposicin
paraunnmeroquenoseaceroes
0,0000000000000000000000000001.

CInt
CLng
CSng

Integer
Long
Single

CVar

Variant

CStr

String

32.768 a 32.767; las fracciones se redondean.


2.147.483.648 a 2.147.483.647; las fracciones se redondean.
3,402823E38 a 1,401298E45 para valores negativos;
1,401298E45 a 3,402823E38 para valores positivos.
El mismo intervalo que Double para valores numricos.El
mismo intervalo que String para valores no numricos.
El valor de retorno de CStr depende del argumentoexpresin.

Bueno,despusdeestaintroduccinalasvariables,pasemosaestudiarunoscuantos
objetosypropiedadesqueseutilizanhabitualmente.

ObjetoCells(fila,columna).

Sirve,comoelobjetorange,parareferenciarunacasillaorangodecasillas,peroenlugardeutilizarla
referenciadelaformaA1,B1,X320,...utilizalafilaylacolumnaqueocupalacasilladentrodelahoja(o
objetoWorkSheet).Porejemplo,paraponerholaenlacasillaA1delahojaactivaseria,

ActiveSheet.Cells(1,1).Value="Hola"

UtilizarCellsparareferenciarunrango.

Esto seria el equivalente a Range("Casilla_Inicial:Casilla_Final"). La forma que se obtiene utilizando


Cells es un poco ms larga, pero se ver que a veces resulta mucho ms funcional queutilizando
nicamenterange.ParareferirnosalrangoA1:B8,pondremos,

Range(Cells(1,1),Cells(8,2)).Value="Hola"
OtraformainteresantedeCellseslasiguiente,
Range("A5:B10").Cells(2,1).Value="Hola"

PondrenlaceldaA6elvalor"Hola",observequeenesteejemplo Cellscomienzaacontarfilasy
columnasapartirdelrangoespecificadoenelobjetoRange.

Prof. Cesar Apaza CCopa

Pgina 15

Macros en Excel

VariablesdeObjetos.

Una variable objeto sirve para hacer referencia a un objeto, esto significa que podremos acceder a
laspropiedadesdeunobjetoeinvocarasusmtodosatravsdelavariableenlugardehacerlo
directamente
a travs del objeto. Posiblemente no se utilice demasiado esta clase de variables (esta claro que esto
depender de las preferencias del programador), pero hay casos en los que no hay ms remedio
queutilizarlas , por ejemplo en estructuras For Each ... Next como veremos, o cuando sea necesario
construirfuncionesquedevuelvanrangos,referenciasahojas,etc.

ParadeclararunavariableobjetoseutilizatambinlapalabraDimdelaformasiguiente,

DimVar_ObjetoAsObjeto

PorEjemplo

DimRAsRange
DimHojaAsWorkSheet

ParaasignarunobjetoaunavariabledebeutilizarlainstruccinSet.

SetVariable_Objeto=Objeto

PorEjemplo

SetR=ActiveSheet.Range("A1:B10")
SetHoja=ActiveSheet
SetHoja=WorkSheets(1)

Veamosacontinuacinunejemplodecmoutilizarestetipodevariables,

Ejemplo6.

Algomuysimple,llenarelrangodeA1aB10conlapalabra"Hola"ydespusponernegrita,observe
comoseasignaunavariableobjetoalobjetoyluegocomosetrabajaconesavariabledelamismaforma
quetrabajaradirectamentesobreelobjeto.

Subobj()

DimRAsRange

SetR=ActiveSheet.Range("A10:B15")
R.Value="Hola"
R.Font.Bold=True

EndSub

ElvalorNothing.

Algunasvecespuedequeseanecesariodesasignarunavariabledelobjetoalcualhacereferencia,en
estecasodebeigualarlavariablealvalorNothingdelaformasiguiente.

SetVariable_Objeto= Nothing

Habitualmente se utiliza Nothingenunaestructuracondicionalparacomprobarsilavariableobjetoest


asignada. Observe que si se utiliza una variable objeto a la cual todava no se le ha hecho ninguna
asignacinelprogramadarerrorydetendrsuejecucin.Esbuenaprcticahacerestetipode
comprobacionesantesdetrabajarconvariablesobjeto.Veremosunejemplodeestoeneltemasiguiente.

Prof. Cesar Apaza CCopa

Pgina 16

Macros en Excel

Estructurascondicionales.

Ahoraqueyahaexperimentadoconunoscuantosobjetosypropiedades,nosdetendremosaestudiarlas
estructuras condicionales. Las estructuras condicionales son instrucciones de programacin que
permitencontrolarlaejecucindeunfragmento de cdigo en funcin de si se cumple o no una
condicin.EstudiaremosenprimerlugarlainstruccinifCondicinthen..Endif(S iCondicinEntonces...FinSi)

LaestructuracondicionalqueseconstruyeconlainstruccinS iCondicinEntonces...FinSitienela
formasiguiente.

.
S iCondicinEntonces
Sentncia1
Sentncia2
.
.
SentnciaN
FinSi
.
.
Cuando el programa llega a la instruccin S i Condicin Entonces, se evala la condicin, si esta se
cumple (es cierta), se ejecutantodas las sentencias que estn encerradas en el bloque, si no se cumple
lacondicin,sesaltanestassentencias.EstaestructuraenVisualBasictienelasintaxissiguiente,

IfCondicinThen
Sentncia1
Sentncia2
.
.
SentnciaN
EndIf

Ejemplo6.

Entrar una cantidad que representa el precio de algo por el teclado con la instruccin InputBoxy
guardarloen la celda A1de la hoja activa. Sielvalorentradodesdeelteclado(yguardadoenA1)es
superiora 1000, pedir descuento con otro InputBox y guardarlo en la casilla A2 de la hoja activa.
CalcularenA3,elpreciodeA1menoseldescuentodeA2.

SubCondicional()

ActiveSheet.Range("A1").Value=0
ActiveSheet.Range("A2").Value=0
ActiveSheet.Range("A3").Value=0

' Ponerlascasillasdondeseguardanlosvalores0.

ActiveSheet.Range("A1").Value=Val(InputBox("Entrarelprecio","Entrar"))

'SielvalordelacasillaA1esmayorque1000,entonces,pedirdescuento
IfActiveSheet.Range("A1").Value>1000Then
ActiveSheet.Range("A2").Value=Val(InputBox("EntrarDescuento","Entrar"))
EndIf

ActiveSheet.Range("A3").Value=ActiveSheet.Range("A1").Value _
ActiveSheet.Range("A2").Value

EndSub

Prof. Cesar Apaza CCopa

Pgina 17

Macros en Excel

Ejemplo7.

Elmismoqueelanteriorperoutilizandovariables.
OptionExplicit

SubCondicional()

DimPrecioAsInteger
DimDescuentoAsInteger

Precio=0
Descuento=0

Precio=Val(InputBox("Entrarelprecio","Entrar"))

'Sielvalordelavariableprecioesmayorque1000,entonces,pedirdescuento
IfPrecio>1000Then
Descuento=Val(InputBox("EntrarDescuento","Entrar"))
EndIf

ActiveSheet.Range("A1").Value=Precio
ActiveSheet.Range("A2").Value=Descuento
ActiveSheet.Range("A3").Value=PrecioDescuento

EndSub

Viendo los dos programas anteriores puede que le surja la duda de si emplear variables o
directamentevaloresalmacenadosenlasceldas.Lasolucinesfcil,loqueleparezcamsconvenienteen
cadacasoconcreto que desee solucionar. Las variables, aunque muchas veces "innecesarias", quizs
dejanlosprogramasmslegiblesyclaros.Ylalegibilidaddeunprogramaeslomsvaliosodelmundo
para un programador (profesionalmente hablando ), sobre todo si se da el caso (inevitable el
99,999...% de las ocasiones) que se tenga que modificar un programa para dotarle de ms
funcionalidades,facilitarsumanejo, etc. En la mayora de ejemplos que encontrar en este manual
ver que se utilizanvariablespreferentemente. Aunque muchas veces su funcin sea simplemente
recoger datos de lasceldas paraoperarlasydejarlasenotrasceldasy,consecuentemente,aumenteel
nmerodeoperaciones,creemosqueconelloseganaenlegibilidadyflexibilidad.

Ejemplo8.

MacroquecomparalosvaloresdelascasillasA1yA2delahojaactiva.Sisonigualesponeelcolordela
fuentedeambasenazul.

SubCondicional2()

If ActiveSheet.Range("A1").Value=ActiveSheet.Range("A2").ValueThen

ActiveSheet.Range("A1").Font.Color=RGB(0,0,255)
ActiveSheet.Range("A2").Font.Color=RGB(0,0,255)

EndIf

EndSub

Prof. Cesar Apaza CCopa

Pgina 18

Macros en Excel

EstructuraIf..Else

Estaestructuraseutilizacuandoserequiereunarespuestaalternativaaunacondicin.Suestructuraes
lasiguiente.

S iCondicinEntonces
Sentncia1
Sentncia2
.
.
SentnciaN
Sino
Sentncia1
Sentncia2
.
.
SentnciaN
FinSi

Observe que,si se cumple la condicin, se ejecuta el bloque de sentencias delimitado por S i Condicin
Entonces y Sinosecumplelacondicin se ejecuta el bloque delimitado por Sino y FinSi.EnVisual
BasiclainstruccinS iCondicinEntonces...Sino...FinSiseexpresaconlasinstruccionessiguientes.

IfCondicinThen
Sentncia1
Sentncia2
.
.
SentnciaN
Else

Sentncia1
Sentncia2
.
.
SentnciaN
EndIf

Ejemplo9.
Entrarunacantidad que representa el precio de algo por el teclado con la instruccin InputBox y
guardarloenlaceldaA1delahojaactiva.Sielvalorentradodesdeelteclado(yguardadoenA1)es
superiora 1000, se aplica undescuento del10%sinose aplicaundescuentodel5%,eldescuentose
guardaenlacasillaA2delahojaactiva.ColocarenA3,eltotaldescuentoyenA4eltotalmenosel
descuento.

Prof. Cesar Apaza CCopa

Pgina 19

Macros en Excel

SubCondicional_Else()

DimPrecioAsSingle
DimDescuentoAsSingle

Precio=0

Precio=Val(InputBox("Entrarelprecio","Entrar"))

'Sielvalordelavariableprecioesmayorque1000,entonces,aplicardescuentodel10%
IfPrecio>1000Then
Descuento=Precio*(10/100)
ActiveSheet.Range("A2").Value=0,1

Else'Sino Aplicardescuentodel5%Descuento
=Precio*(5/100)
ActiveSheet.Range("A2").Value=0,05
EndIf

ActiveSheet.Range("A1").Value=Precio
ActiveSheet.Range("A3").Value=Descuento
ActiveSheet.Range("A4").Value=PrecioDescuento

EndSub

Ejemplo10.

RestarlosvaloresdelascasillaA1yA2.GuardarelresultadoenA3.Sielresultadoespositivoo0,
ponerlafuentedeA3enazul,sinoponerlaenrojo.

SubCondicional_Else2()

ActiveSheet.Range("A3").Value=AvtiveSheet.Range("A1").Value _
ActiveSheet.Range("A2").Value

IfActiveSheet("A3").Value<0Then
ActiveSheet.Range("A3").Font.Color=RGB(255,0,0)

Else
ActiveSheet.Range("A3").Font.Color=RGB(0,0,255)
EndIf

EndSub

EstructurasIfanidadas.

Notienequesorprenderle,dentrodeunaestructuraifpuedeir otra,ydentrodeestaotra,yotra...
Veaelejemplosiguiente.

Ejemplo11.

Comparar los valores de las casilla A1 y A2 de la hoja activa. Si son iguales, escribir en A3 "Los valores
deA1yA2soniguales",sielvalordeA1esmayorqueA2,escribir "A1 mayor que A2", sino, escribir
"A2mayorqueA1".

Prof. Cesar Apaza CCopa

Pgina 20

Macros en Excel

SubCondicional()

IfActiveSheet.Range("A1").Value=ActiveSheet.Range("A2").ValueThen
ActiveSheet.Range("A3").Value="LosValoresdeA1yA2soniguales"

Else
IfActiveSheet.Range("A1").Value>ActiveSheet.Range("A2").ValueThen
ActiveSheet.Range("A3").Value="A1mayorqueA2"

Else

ActiveSheet.Range("A3").Value="A2mayorqueA1"

EndIf
EndIf

EndSub

Observe que la segunda estructuraIf..Else..End If queda dentro delElse de la primeraestructura.Estaes


unareglageneral,cuandoponeunEndIf,estecierrasiempreelltimoIf(oElse)abierto.

Operadores lgicos.

Estos operadores se utilizan cuando se necesitan evaluar dos o ms condiciones para decidir si se
ejecutanonodeterminadasacciones.

OperadorLgicoAnd(Y).

Utilizaremos este operador cuando sea preciso que para ejecutar un bloque de instrucciones se
cumplamsdeunacondicin. Observequedeberncumplirsetodaslascondiciones.Veaelejemplosiguiente.

Ejemplo12.

Entrar el Nombre, la cantidad y el precio de un producto desde el teclado y guardarlos respectivamente


en A1, A2 y A3. Calcular el total y guardarlo en A4. Si el total es superior a 10.000 y el nombre del
productoes"Patatas",pedirundescuento,calcularloeltotaldescuentoyguardarloenA5,luegorestarel
descuentodeltotalyguardarloenA6.

SubEjemplo_12()

DimProductoAsString
DimCantidadAsInteger
DimPrecioAsSingleDim
TotalAsSingle
DimDescuentoAsSingle
DimTotal_DescuentoAsSingle

Precio=0

Producto=InputBox("EntrarNombredelProducto","Entrar")
Precio=Val(InputBox("Entrarelprecio","Entrar"))
Precio=Val(InputBox("Entrarlacantidad","Entrar"))
Total=Precio*Cantidad
ActiveSheet.Range("A1").Value=Producto
ActiveSheet.Range("A2").Value=Precio
ActiveSheet.Range("A3").Value=Cantidad
ActiveSheet.Range("A4").Value=Total

Prof. Cesar Apaza CCopa

Pgina 21

Macros en Excel

'Sitotalmayorque10.000yelproductoesPatatas,aplicardescuento.
IfTotal>10000AndProducto="Patatas"Then
Descuento=Val(InputBox("EntrarDescuento","Entrar"))
Total_Descuento=Total*(Descuento/100)
Total=TotalTotal_Descuento
ActiveSheet.Range("A5").Value=Total_Descuento
ActiveSheet.Range("A6").Value=Total
EndIf

EndSub

Observe que para que se ejecute el bloque de instrucciones entre If.. End Ifdeben cumplirse las
doscondicionesqueseevalan,sifallacualquieradelasdos(olasdosalavez),noseejecutadichobloque.

OperadorLgicoOr(O).

Utilizaremos este operador cuando sea preciso que para ejecutar un bloque de instrucciones se
cumplaalgunadeunaseriedecondiciones.Observequesloesnecesarioquesecumplaalguna
delascondicionesqueseevalan.Veaelejemplosiguiente.

Ejemplo13.

EntrarelNombre,lacantidadyelpreciodeunproductodesdeeltecladoyguardarlosrespectivamente
enA1,A2yA3.CalculareltotalyguardarloenA4.Sieltotalessuperiora10.000oelnombredel
productoel"Patatas",pedirundescuento,calcularloeltotaldescuentoyguardarloenA5,luegorestarel
descuentodeltotalyguardarloenA6.

SubEjemplo_13()

DimProductoAsString
DimCantidadAsInteger
DimPrecioAsSingleDim
TotalAsSingle
DimDescuentoAsSingle
DimTotal_DescuentoAsSingle

Precio=0

Producto=InputBox("EntrarNombredelProducto","Entrar")
Precio=Val(InputBox("Entrarelprecio","Entrar"))
Precio=Val(InputBox("Entrarlacantidad","Entrar"))
Total=Precio*Cantidad
ActiveSheet.Range("A1").Value=Producto
ActiveSheet.Range("A2").Value=Precio
ActiveSheet.Range("A3").Value=Cantidad
ActiveSheet.Range("A4").Value=Total

'Sitotalmayorque10.000oelproductoesPatatas,aplicardescuento.
IfTotal>10000OrProducto="Patatas" Then
Descuento=Val(InputBox("EntrarDescuento","Entrar"))
Total_Descuento=Total*(Descuento/100)
Total=TotalTotal_Descuento
ActiveSheet.Range("A5").Value=Total_Descuento
ActiveSheet.Range("A6").Value=Total
EndIf

EndSub

Prof. Cesar Apaza CCopa

Pgina 22

Macros en Excel

Observe que para que se ejecute el bloque de instrucciones entre If.. End If sloes necesario que se
cumpla alguna de las dos condiciones que se evalan (o las dos a la vez).Slo cuando no se cumple
ningunadelasdosnoseejecutanlasinstruccionesdelbloque.

OperadorLgicoNot(no).

Esteoperadorseutilizapara ver si NO se cumple una condicin. El siguiente ejemplo hace lo mismo que
elejemplo7peroutilizandoeloperadorNot.

Ejemplo14.

Entrar una cantidad que representa el precio de algo por el teclado con la instruccin InputBox y
guardarlo en la celda A1delahojaactiva.Sielvalorentradodesdeelteclado(yguardadoenA1)es
superior a 1000, pedir descuento con otro InputBox y guardarlo en la casilla A2 de la hoja activa.
CalcularenA3,elpreciodeA1menoseldescuentodeA2.

SubEjemplo_14()

DimPrecioAsInteger
DimDescuentoAsInteger

Precio=0
Descuento=0

Precio=Val(InputBox("Entrarelprecio","Entrar"))

'SielvalordelavariableprecioNOesmenorigual1000,entonces,pedirdescuento
IfNot(Precio<=1000)Then
Descuento=Val(InputBox("EntrarDescuento","Entrar"))
EndIf

ActiveSheet.Range("A1").Value=Precio
ActiveSheet.Range("A2").Value=Descuento
ActiveSheet.Range("A3").Value=PrecioDescuento

EndSub

Tablasdelaverdad.

Vea las tablas siguientespara ver los resultados de evaluar dos condiciones con el operador And y con
eloperadorOr.

And.
Condicin1
Falsa
Falsa
Cierta
Cierta

Condicin2
Falsa
Cierta
Falsa
Cierta

Resultado
Falso
Falso
Falso
Cierto

Or.
Condicin1
Falsa
Falsa
Cierta
Cierta

Condicin2
Falsa
Cierta
Falsa
Cierta

Resultado
Falso
Cierto
Cierto
Cierto

ObservequeconeloperadorANDdebendecumplirsetodaslascondiciones(dosoveinticinco)paraque
elresultadoseacierto.ConeloperadorORsloesnecesarioquesecumplauna(delasdosodelas
veinticinco)paraqueelresultadoseacierto.

Prof. Cesar Apaza CCopa

Pgina 23

Macros en Excel

EstructuraSelectCase.

Enocasionessedarelcasoqueenfuncindelvalororangodevaloresquepuedatener una variable,


una casilla,una expresin, etc. debern llevarseacabodiferentesaccionesogruposdeacciones.Veael
ejemplosiguiente.

Ejemplo15.

Macroquesuma,resta,multiplicaodividelosvaloresdelascasillasA1yA2dependiendodesiB1
contiene el signo +, , x, :. El resultado lo deja en A3. Si en B1 no hay ninguno de los signos anteriores
enA3debedejarseun0.

SubEjemplo_15()

DimSignoAsString
DimValor1AsInteger,Valor2AsInteger, TotalAsInteger

Valor1 = ActiveSheet.Range("A1").Value
Valor2 = ActiveSheet.Range("A2").Value
Signo=ActiveSheet.Range("B1").Value

Total=0

If Signo="+"Then
Total=Valor1+Valor2
Endif

If Signo=""Then
Total=Valor1Valor2
Endif

If Signo="x"Then
Total=Valor1*Valor2
Endif

If Signo=":"Then
Total=Valor1/Valor2
Endif

ActiveCell.Range("A3").Value=Total

EndSub

Observe que en el ejemplo anterior todas las instrucciones if evalan la misma variable. El programa
funciona correctamente pero para estos casos es mejor utilizar la instruccin Select Case, el motivo
principalesporlegibilidadyelegancia.SelectCasetienelasintaxissiguiente,

SelectCaseExpresin

Casevalores:
Instrucciones.
Casevalores:
Instrucciones.
EndSelect

Prof. Cesar Apaza CCopa

Pgina 24

Macros en Excel

.
.
C
a
s
e

v
a
l
o
r
e
s
:

I
n
s
t
r
u
c
c
i
o
n
e
s
.
CaseElse
Instruc
ciones
encaso
queno
sean
ningun
odelos
valores
anterio
res.

Prof. Cesar Apaza CCopa

Pgina 25

Macros en Excel

Veaelejemploanteriorsolucionadoconestaestructura.

Ejemplo16.
SubEjemplo_16()

DimSignoAsString
DimValor1AsInteger,Valor2AsInteger, TotalAsInteger

Valor1 = ActiveSheet.Range("A1").Value
Valor2 = ActiveSheet.Range("A2").Value
Signo=ActiveSheet.Range("A3").Value

SelectCasesigno

Case "+"
Total=Valor1+Valor2
Case ""
Total=Valor1Valor2
Case "x"
Total=Valor1*Valor2
Case":"
Total=Valor1/Valor2
CaseElse
Total=0
EndSelect

ActiveCell.Range("A3").Value=Total

EndSub

VeaelejemplosiguientedondecadasentenciaCaseevalaunrangodevalores.

Ejemplo17.

Programa que pide tres notas de un alumno mediante la funcin InputBox. Las notas van a parar
respectivamentealascasillasA1,A2yA3delahojaactiva.ElprogramacalculalamediayladejaenA4.
Si la media est entre 0 y 2 deja en A5 el mensaje "Muy deficiente", si la nota es 3 deja en A5 el
mensaje "Deficiente", si la nota es 4 deja "Insuficiente", si es 5 "Suficiente", si es 6 "Bien", si est entre 7
y8deja"Notable",siesmayorque8deja"Sobresaliente".

SubEjemplo_17()

DimNota1AsInteger,Nota2AsInteger,Nota3AsInteger
DimMediaAsSingle

Nota1=Val(InputBox("EntrarNotaprimeraevaluacin","Nota"))
Nota2=Val(InputBox("EntrarNotaSegundaevaluacin","Nota"))
Nota3=Val(InputBox("EntrarNotaTerceraevaluacin","Nota"))

Media=(Nota1+Nota2+Nota3)/3

ActiveSheet.Range("A1").Value=Nota1
ActiveSheet.Range("A2").Value=Nota2
ActiveSheet.Range("A3").Value=Nota3
ActiveSheet.Range("A4").Value=Media

Prof. Cesar Apaza CCopa

Pgina 26

Macros en Excel

SelectCaseMedia
Case0To2
ActiveSheet.Range("A5").Value="Muydeficiente"
Case3
ActiveSheet.Range("A5").Value="Deficiente"
Case4
ActiveSheet.Range("A5").Value="Insuficiente"
Case5
ActiveSheet.Range("A5").Value="Suficiente"
Case6
ActiveSheet.Range("A5").Value="Bien"
Case7To8
ActiveSheet.Range("A5").Value="Notable"
Case>8
ActiveSheet.Range("A5").Value="Sobresaliente"

EndSelect

EndSub

Funcionesdecomprobacin.

Antesdeterminarconeltemadecondicionalesveremosunasfuncionesquenosserntilesalahora
decomprobar o validar el tipo de los datos entrados desde teclado o simplemente los datos contenidos
en unacasilla.

Volvamos al ejemplo que codificamos de la manera


siguiente.

SubEjemplo_16()

DimSignoAsString
DimValor1AsInteger,Valor2AsInteger, TotalAsInteger

Valor1 = ActiveSheet.Range("A1").Value
Valor2 = ActiveSheet.Range("A2").Value
Signo=ActiveSheet.Range("A3").Value

SelectCasesigno

Case "+"
Total=Valor1+Valor2
Case ""
Total=Valor1Valor2
Case "x"
Total=Valor1*Valor2
Case":"
Total=Valor1/Valor2
CaseElse
Total=0
EndSelect

ActiveCell.Range("A3").Value=Total

EndSub

Prof. Cesar Apaza CCopa

Pgina 27

Macros en Excel

Imagine queenalgunadelascasillasquesedebenoperarnohubieraningnvalorobiendatos
alfanumricos.Alejecutarlamacroseproducirunerror.Aunque con Visual Basic se puede controlar el
flujodelprogramacuandoseproduceunerrorimprevisto,parasolucionaresteproblemautilizaremos
unafuncindecomprobacinquenosdigasienlascasillasA1yA2hayvaloresadecuados(numricos)
paraproseguirconlaejecucindelamacro,encasocontrariosemostrarunerrorynoseejecutar
ningunadelasoperaciones.

La funcin que utilizaremos esIsNumeric(expresin), esta funcin devuelve un valorTrue si la


expresin que se evala es un valor numrico, en caso contrario devuelveFalse.Veacomoquedarael
programa. Tambin se utiliza la funcinIsEmpty para comprobar si en B1 hay algo,
IsEmpty(Expresin)evalasiexpresinestvaca,devuelveTruesiesasyFalseencasocontrario.

Ejemplo18.

SubEjemplo_18()

DimSignoAsString
DimValor1AsInteger,Valor2AsInteger, TotalAsInteger
DimContinuarAsBoolean

Valor1 = ActiveSheet.Range("A1").Value
Valor2 = ActiveSheet.Range("A2").Value
Signo=ActiveSheet.Range("A3").Value

Continuar=True

'SienlacasillaA1nohayunvalornumrico
IfNotIsNumeric(ActiveSheet.Range("A1"))Then
MsgBoxPrompt:="EnlacasillaA1nohayningnvalornumrico",Title:="ERROR"
Continuar=False
EndIf

'SienlacasillaA2nohayunvalornumrico
IfnotIsNumeric(ActiveSheet.Range("A2"))Then
MsgBoxPrompt:="EnlacasillaA2nohayningnvalornumrico",Title:="ERROR"
Continuar=False
EndIf

IfIsEmpty(ActiveSheet.Range("B1"))Then
MsgBoxPrompt:="lacasillaB1estvaca",Title:="ERROR"
Continuar=False
EndIf

IfContinuarThen

SelectCasesigno

Case "+"
Total=Valor1+Valor2
Case ""
Total=Valor1Valor2
Case "x"
Total=Valor1*Valor2
Case":"

Total=Valor1/Valor2

CaseElse
Total=0

Prof. Cesar Apaza CCopa

Pgina 28

Macros en Excel

EndSelect

Prof. Cesar Apaza CCopa

Pgina 29

Macros en Excel

ActiveCell.Range("A3").Value=Total
Endif

EndSub

EnlugardelostresIfdecomprobacinsehubierapodidoutilizareloperadorORdelamanerasiguientes,

IfnotIsNumeric(ActiveSheet.Range("A1")) Or notIsNumeric(ActiveSheet.Range("A2"))_
Or IsEmpty(ActiveSheet.Range("B1"))Then

MsgBoxPrompt:="DebeentrarnmerosenA1yA2yunsigno(+,,x,:)enB1,
Title:="ERROR"

Else

'Instruccionesdelasoperaciones
.......

Endif

ListadeFuncionesdeComprobacin.

IsNumric(Expresin).Compruebasiexpresintieneunvalorquesepuedeinterpretar
comonumrico.

IsDate(Expresin).Compruebasiexpresintieneunvalorquesepuedeinterpretarcomo
tipofecha.

IsEmpty(Expresin).Compruebaqueexpresintengaalgnvalor,quesehayainicializado.
IsError(Expresin).Compruebasiexpresindevuelvealgnvalordeerror.
IsArray(Expresin).Compruebasiexpresin(unavariable)esunarrayono.
IsObject(Expresin).Compruebasiexpresin(unavariable)representaunavariabletipoobjeto.

IsNull(Expresin).Compruebasiexpresincontieneunvalornulodebidoadatosnovlidos.

Nothing. No es propiamente una funcin, sirve para comprobar si una variable objeto esta
asociada a un objeto antes de hacer cualquier operacinconella.Recuerdequeparatrabajar
con una variable objeto antes debe asignarse a uno (mediante la instruccin Set), en caso
contrario seproducirunerrorenelprogramacuandoutiliceelobjetoysedetendrsuejecucin.

SubObj()

DimRAsRange
.
.
'SilavariableResNothingesquenohasidoasignada,nosepuedetrabajarconella
IfRIsNothingThen
MsgBoxPrompt:="LavariableObjetonohasidoasignada",Buttons:=vbOk,_
Title:="Error"
Else

R.Value="Hola"

EndIf
.
.

EndSub

Prof. Cesar Apaza CCopa

Pgina 30

Macros en Excel

LafuncinMsgBox.

Esta funcin muestra un mensaje en un cuadro de dilogo hasta que el usuario pulse un botn. La
funcindevuelveundatotipoIntegerenfuncindelbotnpulsadoporelusuario.Alahoradeinvocar
estfuncin,sepermitendiferentestiposdebotones.

SintxisdeMsgBox.

MsgBox(Mensaje,Botones,Ttulo,Archivodeayuda,contexto)

Mensaje:Obligatorio,eselmensajequesemuestradentrodelcuadrodedilogo.

Botones:Opcional.Esunnmeroounasumadenmerosoconstantes(veatablaValores
parabotoneseIconos),quesirveparamostrardeterminadosbotoneseiconosdentrodel
cuadrodedilogo.Siseomiteesteargumentoasumevalor0quecorrespondeaunnico
BotnOK.

Ttulo:Opcional.Eseltextoquesemostrarenlabarradelttulodelcuadrodedilogo.

ArchivodeAyuda:Opcional.Sihaasignadountextodeayudaalcuadrodedilogo,aqudebe
especificarelnombredelarchivodeayudadondeesteltexto.

Context:Opcional.Eselnmeroquesirveparaidentificareltextoaltemadeayuda
correspondientequeestarcontenidoenelarchivoespecificadoenelparmetroArchivo
deAyuda.

TablaparabotoneseiconosdelcuadroMsgBox.(Tablacopiadadelarchivodeayudade
MicrosoftExcel).

Constante
VbOKOnly
VbOKCancel
VbAbortRetryIgnore
VbYesNoCancel
VbYesNo
VbRetryCancel
VbCritical
VbQuestion
VbExclamation
VbInformation
VbDefaultButton1
VbDefaultButton2
VbDefaultButton3
VbDefaultButton4
VbApplicationModal

Valor
0
1
2
3
4
5
16
32
48
64
0
256
512
768
0

VbSystemModal

4096

Descripcin
Muestra solamente el botn Aceptar.
Muestra los botones Aceptar y Cancelar.
Muestra los botones Anular, Reintentar e Ignorar.
Muestra los botones S, No y Cancelar.
Muestra los botones S y No.
Muestra los botones Reintentar y Cancelar.
Muestra el icono de mensaje crtico.
Muestra el icono de pregunta de advertencia.
Muestra el icono de mensaje de advertencia.
Muestra el icono de mensaje de informacin.
Elprimer botn es el predeterminado.
Elsegundo botn es el predeterminado.
Eltercer botn es el predeterminado.
Elcuarto botn es el predeterminado.
Aplicacin modal; el usuario debe responder al cuadro de mensajes
antesde poder seguir trabajando en la aplicacin actual.
Sistema modal; se suspenden todas las aplicaciones hasta queelusuario
responda al cuadro de mensajes.

El primer grupo de valores (0 a 5) describe el nmero y el tipo de los botones mostrados en el cuadro
dedilogo; el segundo grupo (16, 32, 48, 64) describe el estilo del icono, el tercer grupo (0, 256,
512)determina el botn predeterminado y el cuarto grupo (0, 4096) determina la modalidad del
cuadro demensajes.Cuandosesumannmerosparaobtenerelvalorfinaldelargumentobuttons,
seutilizasolamenteunnmerodecadagrupo.

Nota EstasconstanteslasespecificaVisualBasicforApplications.Portanto,elnombredelasmismas
puedeutilizarseencualquierlugardelcdigoenvezdesusvaloresreales.

Prof. Cesar Apaza CCopa

Pgina 31

Macros en Excel

Losvaloresquepuededevolverlafuncinmsgboxenfuncindelbotnquepulseelusuariose
muestranenlatablasiguiente.

TabladevaloresquepuededevolverMsgBox.(TablacopiadadelarchivodeayudadeMicrosoftVisual
Basicparaaplicaciones).

Constante
VbOK
VbCancel
VbAbort
VbRetry
VbIgnore
VbYes
VbNo

Valor
1
2
3
4
5
6
7

Descripcin
Aceptar
Cancelar
Anular
Reintentar
Ignorar
S
No

EjemplosdeMsgBox.

SubTal()
.
.
'ElcuadroMuestralosbotonesSiyNoyuniconoenformadeinterrogante.Cuandosepulsa
'unbotn,elvalorlorecogelavariableX.Enestecasolosvaloresdevueltospuedenser6o7
'quecorrespondenrespectivamentealasconstantesVbYesyVbNo,observelainstruccinIfde
'despus.
X=MsgBox("DeseaContinuar",vbYesNo+vbQuestion,"Opcin",,)

'SehapulsadosobrebotnSi
IfX=vbYesThen
.....
Else'SehapulsadosobrebotnNo
.....
EndIf
.
.

EndSub

AlgunasvecespuedequeleinteresesimplementedesplegaruncuadroMsgBoxparamostrarun
mensajealusuariosinqueserequierarecogerningnvalor.Enestecasopuedeoptarporlaforma
siguiente,

MsgBoxPrompt:="Holausuaria,Haacabadoelproceso",Buttons:=VbOkOnLy_
Title:="Mensaje"

LoquenopuedehacerporqueVisualBasicdaraerroresponerlaprimeraformasinigualarlaa
ningunavariable.Porejemplo,laexpresinsiguineteesincorrecta,

MsgBox("Holausuario,Haacabadoelproceso",VbOkOnly,"Mensaje")
Seriacorrectoponer
X=MsgBox("Holausuario,Haacabadoelproceso",VbOkOnly,"Mensaje")

Enestecaso,aunqueXrecibaunvalor,luegonoseutilizaparanada,esdecirsimplementesepone
paraqueVisualBasicderror.

Prof. Cesar Apaza CCopa

Pgina 32

Macros en Excel

LainstruccinWith.

Suponemosquellegadoaestepuntoleparecerengorrosotenerquereferirsealosobjetossiguiendo
toda o casi toda la jerarqua. Ya hemos indicado que es mejor hacerlo de esta manera porque el
programa ganaen claridad y elegancia y, consecuentemente, el programador gana tiempo a la
hora de hacermodificacionesoactualizaciones.Lasentencia With leayudaratenerqueescribirmenos
cdigo sin quepor esto el programa pierda en claridad. Concretamente esta funcin sirve para
ejecutar una serie deaccionessobreunmismoObjeto.Susintaxiseslasiguiente.

WithObjeto
Instrucciones
EndWith

Repetiremos el ejemplo 13 utilizando esta sentencia. Observe como con Withse hace referencia al
objeto
ActiveSheet.

Ejemplo19.

Entrar el Nombre, la cantidad y el precio de un producto desde el teclado y guardarlos respectivamente


en A1, A2 y A3. Calcular el total y guardarlo en A4. Si el total es superior a 10.000 o el nombre del
productoel"Patatas",pedirundescuento,calcularloeltotaldescuentoyguardarloenA5,luegorestarel
descuentodeltotalyguardarloenA6.

SubEjemplo_19()

DimProductoAsString
DimCantidadAsInteger
DimPrecioAsSingleDim
TotalAsSingle
DimDescuentoAsSingle
DimTotal_DescuentoAsSingle

Precio=0

Producto=InputBox("EntrarNombredelProducto","Entrar")
Precio=Val(InputBox("Entrarelprecio","Entrar"))
Precio=Val(InputBox("Entrarlacantidad","Entrar"))

Total=Precio*Cantidad

WithActiveSheet
.Range("A1").Value=Producto
.Range("A2").Value=Precio
.Range("A3").Value=Cantidad
.Range("A4").Value=Total
EndWith

'Sitotalmayorque10.000oelproductoesPatatas,aplicardescuento.
If Total>10000OrProducto="Patatas"Then
Descuento=Val(InputBox("EntrarDescuento","Entrar"))
Total_Descuento=Total*(Descuento/100)
Total=TotalTotal_Descuento
WithActiveSheet
.Range("A5").Value=Total_Descuento
.Range("A6").Value=Total
EndWith

Prof. Cesar Apaza CCopa

Pgina 33

Macros en Excel

EndIf
EndSub

Prof. Cesar Apaza CCopa

Pgina 34

Macros en Excel

EstructurasRepetitivas.

Este tipo de estructuras permiten ejecutar ms de una vez un mismo bloque de


sentencias.

Ejemplo20.

Supongamosquetenemosquehacerunprogramaparaentrarlasnotasdeunaclase de 5 alumnos que


seguardaranrespectivamenteenlasceldasdeA1aA5delahojaactiva.Despushacerlamediaquese
guardarenA6.Conlasestructurasvistashastaahora,podramoshacer:

SubEjemplo_20()

DimNotaAsInteger
DimMediaAsSingle

Media=0

Nota=Val(InputBox("Entrarla1Nota:","EntrarNota"))
ActiveSheet.Range("A1").Value=Nota
Media=Media+Nota

Nota=Val(InputBox("Entrarla1Nota:","EntrarNota"))
ActiveSheet.Range("A2").Value=Nota
Media=Media+Nota

Nota=Val(InputBox("Entrarla1Nota:","EntrarNota"))
ActiveSheet.Range("A3").Value=Nota
Media=Media+Nota

Nota=Val(InputBox("Entrarla1Nota:","EntrarNota"))
ActiveSheet.Range("A4").Value=Nota
Media=Media+Nota

Nota=Val(InputBox("Entrarla1Nota:","EntrarNota"))
ActiveSheet.Range("A5").Value=Nota
Media=Media+Nota

Media=Media/5

ActiveSheet.Range("A6").Value=Media

EndSub

Observequeesteprogramarepiteelsiguientebloquedesentencias,5veces.

Nota=Val(InputBox("Entrarla1Nota:","EntrarNota"))
ActiveSheet.Range("A5").Value=Nota
Media=Media+Nota

Para evitar esta tipo de repeticiones de cdigo, los lenguajes de programacin incorporan
instruccionesquepermitenlarepeticindebloquesdecdigo.

Prof. Cesar Apaza CCopa

Pgina 35

Macros en Excel

EstructurarepetitivaPara(for).

Estaestructurasirvepararepetirlaejecucindeunasentenciaobloquedesentencias,unnmero
definidodeveces.Laestructuraeslasiguiente:

Paravar=Valor_InicialHastaValor_FinalPasoIncrementoHacer
Inicio
Sentencia1
Sentencia2
.
.
SentenciaN
Fin

Var esunavariablequelaprimeravezqueseentraenelbucleseigualaaValor_Inicial, las sentencias


delbucleseejecutanhastaque Varllega alValor_Final,cadavezqueseejecutanel bloque de
instruccionesVarseincrementasegnelvalordeIncremento.

EnVisualBasicparaExcellaestructuraParaseimplementaconlainstruccinFor...Next.

ForVarible=Valor_InicialToValor_FinalStepIncremento
Sentencia1
Sentencia2
.
.
SentenciaN
NextVariable

*Sielincrementoes1,nohacefaltaponerStep1.

Ejemplo21.

Entrar10valoresutilizandolafuncinInputBox,sumarlosyguardarelresultadoenlacasillaA1dela
hojaactiva.

SubEjemplo_21()

DimiAsInteger
DimTotalAsInteger
DimValorAsInteger

Fori=1To10
Valor=Val(InputBox("Entrarunvalor","Entrada"))
Total=Total+Valor
Nexti

ActiveCell.Range("A1").Value=Total

EndSub

Prof. Cesar Apaza CCopa

Pgina 36

Macros en Excel

Recorrercasillasdeunahojadeclculo.

Una operacin bastante habitual cuando se trabaja con Exceles el recorridode rangos de casillas para
llenarlasconvalores,mirarsucontenido,etc.Lasestructurasrepetitivassonimprescindiblespararecorrer
grupos de celdas o rangos. Vea los siguientes ejemplosparaver ejemplosdeutilizacindeestructuras
repetitivaspararecorrerrangosdecasillas,observelautilizacindelaspropiedadesCellsyOffset.

PropiedadCells.

Yaconoceestapropiedad,sirveparareferenciarunaceldaounrangodeceldassegncoordenadasde
filaycolumna.

Ejemplo22

LlenarelrangodelascasillasA1..A5convaloresparesconsecutivosempezandoporel2.

SubEjemplo_22()

DimFilaAsInteger
DimiAsInteger

Fila=1
Fori=2To10Step2
ActiveSheet.Cells(Fila,1).Value=i
Fila=Fila+1
Nexti

EndSub

Ejemplo23.

Llenarunrangodefilas,empezandoporunacelda,quesedebeespecificardesdeteclado,conuna
seriede10valorescorrelativos(comenzandoporel1).

SubEjemplo_23()

DimCasilla_InicialAsString
DimiAsInteger
DimFilaAsInteger,ColumnaAsInteger

Casilla_Inicial=InputBox("IntroducirlacasillaInicial:","CasillaInicial")
ActiveSheet.Range(Casilla_Inicial).Activate
CogerelvalordefiladelaceldaactivasobrelavariableFila
Fila=ActiveCell.Row
CogerelvalordecolumnadelaceldaactivasobrelavariableFila
Columna=ActiveCell.Column

Fori=1To10
ActiveSheet.Cells(Fila,Columna).Value=i
Fila=Fila+1
Nexti

EndSub

Prof. Cesar Apaza CCopa

Pgina 37

Macros en Excel

PropiedadesROWyCOLUMN.

Comohabrdeducidodelejemploanteriordevuelvenlafilaylacolumnadeunobjetorange.En
elejemploanteriorseutilizabanconcretamenteparaobtenerlafilaylacolumnadelacasilla
activa.

Otraformadesolucionarelejemplo23seria.
S ubEjemplo_23()

DimCasilla_InicialAsString
DimiAsInteger
DimFilaAsInteger,ColumnaAsInteger

Casilla_Inicial=InputBox("IntroducirlacasillaInicial:","CasillaInicial")
ActiveSheet.Range(Casilla_Inicial).Activate
Fila=1

Fori=1To10
ActiveSheet.Range(Casilla_Inicial).Cells(Fila,1).Value=i
Fila=Fila+1
Nexti

EndSub

** Recuerde que cuando utilizamos Cellscomopropiedaddeunrango(ObjetoRange), Cells empiezaa


contarapartirdelacasillareferenciadaporRange.

Ejemplo24.

Elmismoconelqueintroducamoseltema(ejemplo20),peroutilizandoelforypropiedadCells

SubEjemplo_24()

DimNotaAsInteger
DimMediaAsSingle
DimFilaAsInteger

Media=0
ForFila=1To5

Nota=Val(InputBox("Entrarla"&Fila&"Nota:","EntrarNota"))
ActiveSheet.Cells(Fila,1)=Nota
Media=Media+Nota

NextFila
Media=Media/5
ActiveSheet.Cells(6,1).Value=Media

EndSub

Prof. Cesar Apaza CCopa

Pgina 38

Macros en Excel

PropiedadOffset.

Estapropiedadestambinmuytilalahoraderecorrerrango.Offset, que significa desplazamiento, es


una propiedad del objetoRangey se utiliza para referenciar una casilla situada a n Filas y n Columnas de
unacasilladada.Vealosejemplossiguientes.

ActiveSheet.Range("A1").Offset(2,2).Value="Hola"'CasillaC3=Hola,2filasy2
columnasdesdeA1.

ActiveCell.Offset(5,1).Value="Hola"'5FilaspordebajodelacasillaActiva=Hola

ActiveCell.Offset(2,2).Activate 'Activarlacasillaqueest2filasy2columnasdelaactiva

Ejemplo25.

Elmismoconelqueintroducamoseltema(ejemplo20),peroutilizandoelForypropiedadOffset
SubEjemplo_25()

DimNotaAsInteger
DimMediaAsSingle
DimFilaAsInteger

Media=0

ActiveSheet.Range("A1").Activate

ForFila=0To4

Nota=Val(InputBox("Entrarla"&Fila+1&"Nota:","EntrarNota"))
ActiveCell.Offset(Fila,0).Value=Nota
Media=Media+Nota

NextFila
Media=Media/5
ActiveCell.Offset(6,1).Value=Media

EndSub

Ejemplo26.

Elmismoconelqueintroducamoseltema(ejemplo20),peroutilizandoelForypropiedadOffset.
Observequeahoravamoscambiandodeceldaactiva.

SubEjemplo_26()

DimNotaAsInteger
DimMediaAsSingle
DimiAsInteger

Media=0

ActiveSheet.Range("A1").Activate

Fori=1To5

Nota=Val(InputBox("Entrarla"&i&"Nota:","EntrarNota"))

Prof. Cesar Apaza CCopa

Pgina 39

Macros en Excel

ActiveCell.Value=Nota

Prof. Cesar Apaza CCopa

Pgina 40

Macros en Excel

Media=Media+Nota
Haceractivalacasillasituadaunafilapordebajodelaactual
ActiveCell.Offset(1,0).Activate

NextFila
Media=Media/5
ActiveCell.Value=Media

EndSub

Observeladiferenciaentrelosejemplos25y26,ambosutilizanlapropiedad Offsetde diferente forma,


enelejemplo25lacasillaactivasiempreeslamisma A1,Offset se utiliza para referenciar una casilla a
partir de esta. En A26 sevacambiando de casilla activacada vez de forma que, cuando termina la
ejecucindelprogramalacasillaactivaesA6.

Cuandoutilizarcadamtodo,comocasisiempredependedeloquesepretendahacer.Aquesbastante
claro, si le interesa que no cambie la casilla utilice Offset como en el ejemplo 25, en caso que interese
quevayacambiando,hagacomoenelEjemplo6.Porsupuestohaymuchasvariantessobreelestilode
recorrer Celdas, tanto conCells como conOffset, solo tiene que ir probando y, como casisiempre, el que
msleguste.

EstructurarepetitivaDoWhile..Loop(HacerMientras).

La estructura repetitiva for seadaptaperfectamenteaaquellassituacionesenque se sabe previamente


elnmerodevecesquesehaderepetirunproceso, entrar veinte valores, recorrer cincuenta celdas, etc.
Perohay ocasiones o casos en los que no se sabe previamente el nmero de veces que se debe
repetir unproceso. Por ejemplo, suponga que ha de recorrer un rango de filas en los que no se sabe
cuantos valoreshabr (esto es, cuantas filas llenas habr), en ocasiones puede que hayan veinte, en
ocasionestreinta,enocasionesninguna,etc.Paraestoscasoslaestructura for no es adecuada y
deberemos recurrir a lasentencia Do While..Loopen alguna de sus formas. Esta estructura repetitiva
est controlada por una o varias condiciones, la repeticin del bloque de sentencias depender de si se va
cumpliendolacondicinocondiciones.

HacerMientras(secumplalacondicin)
Sentencia1
Sentencia2
.
.
SentenciaN
FinHacerMientras

EnVisualBasic

DoWhile(secumplalacondicin)
Sentencia1
Sentencia2
.
.
SentenciaN
Loop

** Los ejemplos que veremos a continuacin sobre la instruccin Do While..Loop seharnsobreuna


base de datos. Una base de datos en Excel es simplemente un rango de celdas en que cada fila
representaun registro y cada columna un campo de registro, la primera fila es la que da nombre a los
campos. Paranuestra base de datos utilizaremos los campos siguientes, Nombre, Ciudad, Edad,Fecha.
Ponga estosttulos en el rango A1:D1 de la Hoja1 (En A1 ponga Nombre, en B1 ponga Ciudad, en C1

Prof. Cesar Apaza CCopa

Pgina 41

Macros en Excel

ponga Edad yenD1Fecha),observequelosdatosseempezarnaentrarapartirdeA2.

Prof. Cesar Apaza CCopa

Pgina 42

Macros en Excel

Ejemplo27.

Programa para entrar registros en labasededatos.CadacamposeentraconInputBox.Elprogramava


pidiendodatosmientrasseentreunvalorenelInputBoxcorrespondientealnombre,esdecircuando
alpreguntar el nombre no se entre ningn valor, terminar la ejecucin del bloque encerrado entre
DoWhile...Loop.Observelautilizacindelapropiedad Offsetparacolocarlosdatosenlas
celdascorrespondientes.

SubEjemplo_27()

DimNombreAsString
DimCiudadAsString
DimEdadAsInteger
DimfechaAsDate

Activarhoja1
WorkSheets("Hoja1").Activate
ActivarcasillaA2
ActiveSheet.Range("A2").Activate

Nombre=InputBox("EntreelNombre(ReturnparaTerminar):","Nombre")

MientraslavariableNombreseadiferenteacadenavaca
DoWhileNombre<>""
Ciudad=InputBox("EntrelaCiudad:","Ciudad")
Edad=Val(InputBox("EntrelaEdad:","Edad"))
Fecha=Cdate(InputBox("EntralaFecha:","Fecha"))

Copiarlosdatosenlascasillascorrespondientes
WithActiveCell
.Value=Nombre
.Offset(0,1).Value=Ciudad
.Offset(0,2).Value=Edad
.Offset(0,3).Value=fecha
EndWith

Haceractivalaceldadelafilasiguientealaactual
ActiveCell.Offset(1,0).Activate

Nombre=InputBox("EntreelNombre(ReturnparaTerminar):","Nombre")
Loop

EndSub

Ejemplo28.

Presteespecialatencinaesteejemployaqueseguroqueelcdigoquevieneacontinuacinlo
utilizaren muchas ocasiones. Antes que nada observe el ejemplo anterior, fjese en que siempre
empezamos allenar el rango de la hoja a partir de lacelda A2, esto tiene una nefasta consecuencia, la
segunda vez queejecute la macro machacar los datos de A2:D2 y si continua ejecutando machacar
los datos de losrangossiguientes.Unasolucinseriaobservarcualeslacasillavacasiguientey
cambiar enlainstruccinActiveSheet.Range("A2").Activate, la referencia A2 por la que corresponde
a la primeracasillavacadelacolumnaA.El cdigoquelemostramosacontinuacinharestopor
nosotros,esdecirrecorrer una fila de celdas a partir de A1 hasta encontrar una vaca y dejar a esta
como celda activa paraquelaentradadedatoscomienceapartirdeella.

Prof. Cesar Apaza CCopa

Pgina 43

Macros en Excel

SubEjemplo_28()
.
.
Activarhoja1
WorkSheets("Hoja1").Activate
ActivarcasillaA2
ActiveSheet.Range("A1").Activate

Mientraslaceldaactivanoestvaca
DoWhileNotIsEmpty(ActiveCell)
Haceractivalaceldasituadaunafilapordebajodelaactual
ActiveCell.Offset(1,0).Activate
Loop
.
.

EndSub

Ejemplo29.

Es la uninde los dos programasanteriores. Es decir habr un bucle Do Whileque buscar la primera
casilla vaca de la base da datos y otro para pedir los valores de los campos hasta que se pulse Enter
enNombre.

SubEjemplo_28()

DimNombreAsString
DimCiudadAsString
DimEdadAsInteger
DimfechaAsDate

WorkSheets("Hoja1").Activate
ActiveSheet.Range("A1").Activate

BuscarlaprimeraceldavacadelacolumnaAyconvertirlaenactiva
DoWhileNotIsEmpty(ActiveCell)
ActiveCell.Offset(1,0).Activate
Loop

Nombre=InputBox("EntreelNombre(ReturnparaTerminar):","Nombre")

MientraslavariableNombreseadiferenteacadenavaca
DoWhileNombre<>""
Ciudad=InputBox("EntrelaCiudad:","Ciudad")
Edad=Val(InputBox("EntrelaEdad:","Edad"))
Fecha=Cdate(InputBox("EntralaFecha:","Fecha"))

WithActiveCell
.Value=Nombre
.Offset(0,1).Value=Ciudad
.Offset(0,2).Value=Edad
.Offset(0,3).value=fecha
EndWith

ActiveCell.Offset(1,0).Activate
Nombre=InputBox("EntreelNombre(ReturnparaTerminar):","Nombre")

Loop

EndSub

Prof. Cesar Apaza CCopa

Pgina 44

Macros en Excel

Cuando se tienen que entrar desde el teclado conjuntos de valores, algunos programadores y
usuariosprefieren la frmula de que el programa pregunte si se desean entrar ms datos, la tpica
pregunta DeseaIntroducir ms datos ?,sielusuariocontestaS,elprogramavuelveaejecutar
las instruccionescorrespondientes a la entrada de datos, si contesta queno sefinaliza el proceso,
observecomoquedaranuestrobucledeentradadedatosconestesistema.

Mas_datos=vbYes
DoWhileMas_Datos=vbYes

Nombre=InputBox("EntreelNombre(ReturnparaTerminar):","Nombre")
Ciudad=InputBox("EntrelaCiudad:","Ciudad")
Edad=Val(InputBox("EntrelaEdad:","Edad"))
Fecha=Cdate(InputBox("EntralaFecha:","Fecha"))

WithActiveCell
.Value=Nombre
.Offset(0,1).Value=Ciudad
.Offset(0,2).Value=Edad
.Offset(0,3).value=fecha
EndWith

ActiveCell.Offset(1,0).Activate

Preguntaralusuariosideseaentrarotroregistro.
Mas_datos=MsgBox("Otroregistro?",vbYesNo+vbQuestion,"Entradadedatos")

Loop

**Observequeesnecesarialalneaanterioralbucle Mas_datos = vbYes, para que cuando se evale la


condicinporvezprimeraestasecumplayseejecutenlassentenciasdedentro del bucle, Mas_datos
esuna variabledetipo Integer.Vealaseccinsiguientedondeseestudiaunavariantedelaestructura
DoWhilequeesmsadecuadaparaestetipodesituaciones.

Prof. Cesar Apaza CCopa

Pgina 45

Macros en Excel

EstructuraDo..LoopWhile.

El funcionamiento de esta estructura repetitivaessimilaralaanteriorsalvoquelacondicin se evala al


final, la inmediata consecuencia de esto es que las instrucciones del cuerpo del bucle se ejecutaran al
menosunavez. Observe que para nuestra estructura de entrada de datos vista en elltimo apartado de
laseccinanteriorestaestructuraesmsconveniente,almenosmselegante,sivamosaentrardatos,al
menosunoentraremos,portantolasinstruccionesdelcuerpodelbuclesedebenejecutaralmenosuna
vez,luegoyadecidiremossiserepitenono.

Do
Nombre=InputBox("EntreelNombre(ReturnparaTerminar):","Nombre")
Ciudad=InputBox("EntrelaCiudad:","Ciudad")
Edad=Val(InputBox("EntrelaEdad:","Edad"))
Fecha=Cdate(InputBox("EntralaFecha:","Fecha"))

WithActiveCell
.Value=Nombre
.Offset(0,1).Value=Ciudad
.Offset(0,2).Value=Edad
.Offset(0,3).value=fecha
EndWith

ActiveCell.Offset(1,0).Activate

Mas_datos=MsgBox("Otroregistro?",vbYesNo+vbQuestion,"Entradadedatos")

MientrasMas_Datos=vbYes
LoopWhileMas_Datos=vbYes

ObservequeenestecasonoesnecesariolalneaMas_Datos=vbYesantesde Doparaforzarla
entradaenelbucleyaquelacondicinvaalfinal.

EstructuraDo..LoopUntil(Hacer..Hastaquesecumplalacondicin).

Es otra estructura que evala la condicin al final observe que la interpretacin es distinta ya que el
buclese va repitiendo HASTAquesecumplelacondicin, no MIENTRAS se cumple la condicin. Cual
delosdosutilizar,pues,nosesorprenda,laqueentiendamejorolegustems.

La entrada de datos con este bucle


quedara
Do
Nombre=InputBox("EntreelNombre(ReturnparaTerminar):","Nombre")
Ciudad=InputBox("EntrelaCiudad:","Ciudad")
Edad=Val(InputBox("EntrelaEdad:","Edad")
Fecha=Cdate("InputBox("EntralaFecha:","Fecha")

WithActiveCell
.Value=Nombre
.Offset(0,1).Value=Ciudad
.Offset(0,2).Value=Edad
.Offset(0,3).value=fecha
EndWith

ActiveCell.Offset(1,0).Activate

Mas_datos=MsgBox("Otroregistro?",vbYesNo+vbQuestion,"Entradadedatos")

Prof. Cesar Apaza CCopa

Pgina 46

Macros en Excel

HastaqueMas_DatosseaigualavbNo
LoopUntilMas_Datos=vbNo

Prof. Cesar Apaza CCopa

Pgina 47

Macros en Excel

EstructuraForEach.

Estebucleseutilizabsicamenteparaejecutarungrupodesentenciasconloselementosdeuna
coleccinounamatriz(prontoveremoslosquees).Recuerdequeunacoleccinesunconjuntode
objetos,hojas,rangos,etc.Veaelejemplosiguientequeseutilizaparacambiarlosnombresdelashojas
deunlibrodetrabajo.

Ejemplo29.

Programaquepreguntaelnombreparacadahojadeunlibrodetrabajo,sinoseponenombreala
hoja,quedaelquetiene.

SubEjemplo_29()

DimNuevo_NombreAsString
DimHojaAsWorkSheet

ParacadahojadelconjuntoWorkSheets
ForEachHojaInWorkSheets
Nuevo_Nombre=InputBox("NombredelaHoja:"&Hoja.Name,"NombrarHojas")
IfNueva_Nombre<>""Then
Hoja.Name=Nuevo_nombre

Endi f
Next

EndSub

**HojavareferenciandocadaunadelashojasdelconjuntoWorkSheetsacadapasodebucle.

Ejemplo30.

EntrarvaloresparalasceldasdelrangoA1:B10delahojaActiva.

SubEjemplo_30()

DimRAsRange

ParacadaceldadelrangoA1:B10delahojaactiva
ForEachRinActiveSheet.Range("A1:B10")
R.Value=InputBox("Entrarvalorparalacelda"&R.Address,"Entradadevalores")
Next

EndSub

**ObservequesehadeclaradounavariabletipoRange,estetipodedatos,comopuedeimaginaryha
vistoenelejemplosirveparaguardarRangosdeunaomscasillas,estasvariablespuedenluegoutilizar
todaslaspropiedadesymtodospropiosdelosObjetosRange.Tengaencuentaquelaasignacindelas
varaibles que sirven para guardar o referenciar objetos (Range, WorkSheet, etc.) deben inicializarse
muchasvecesatravsdelainstruccinSET,estoseestudiarenotrocaptulo.

Prof. Cesar Apaza CCopa

Pgina 48

Macros en Excel

Procedimientosyfunciones.

Sedefinecomoprocedimientoi/ofuncinaunbloquedecdigoquerealizaalgunatarea.Hastaahora,
hemos construido los programas utilizando un nico procedimiento, pero a medida que los programas
(y los problemas) crecen se va haciendo necesaria la inclusin de ms procedimientos. Podra
fcilmentecaer en la tentacin de utilizar, como hasta ahora, un nico procedimiento por programa
pero se darcuentarpidamentedequeestemtodonoesnadaprcticoyaquegrandesbloquesde
cdigoimplicanmayorcomplicacindelmismo,repeticindesentenciasyloqueesmsgrave,mayores
problemasdeseguimientoalahoradedepurarerrores,ampliarfuncionalidadesoincluirmodificaciones.

La filosofa de utilizar procedimientos es la antigua frmula del "divide y vencers", es decir, con los
procedimientos podremos tratar cada problema o tarea de forma ms o menos aislada de forma
queconstruiremoselprogramapasoapasoevitandotenerqueresolver o controlar mltiples cosas a la
vez.Cadatarealarealizarunprocedimiento,siestatareaimplicalaejecucindeotrastareas,cada
unaseimplementarysolucionarensucorrespondienteprocedimientodemaneraquecadaunohaga
unacosaconcreta.As,losdiferentespasosquesedebenejecutarparaqueunprogramahagaalgo,
quedaranbiendefinidos cada uno en su correspondiente procedimiento, si el programa falla, fallar
a partir de unprocedimientoydeestaformapodremoslocalizarelerrormsrpidamente.

Los procedimientos son tambin un eficaz mecanismo para evitar la repeticin de cdigo en un mismo
programaeinclusoendiferentesprogramas.Suponemosquehabrintuidoquehaymuchastareasque
serepiten en casi todos los programas, veremos como los procedimientos que ejecutan estas
tareas sepuedenincluirenunmdulodeformaqueesteseaexportableaotrosprogramasydeesta
maneraganartiempoque,comodiceeltpico,esprecioso.

Definirunprocedimiento.

Yalohemoshechounascuantasveces,peroahvadenuevo.

SubNombre_Procedimento

Sentencias.

EndSub.

Llamaraunprocedimiento.

ParallamarunprocedimientodesdeotroseutilizalainstruccinCallNombre_Procedimiento.

SubP_Uno

Sentencias.
.
CallP_Dos
.
Sentencias
.
End Sub

Las secuencias del procedimiento P_Uno se ejecutan hasta llegar a la lnea CallP_Dos, entonces se salta
al procedimiento P_Dos, se ejecutan todas las sentencias de este procedimiento y el programa
continuaejecutndoseenelprocedimientoP_UnoapartirdelasentenciaquesigueaCallP_Dos.

Prof. Cesar Apaza CCopa

Pgina 49

Macros en Excel

Ejemplo32.

Es el mismo programa que el visto en el ejemplo 29 pero el cdigo que salta casilla hasta que se
encuentraunavacaseimplementaenunprocedimientollamado,Saltar_Celdas_Llenas. Observe que
paraentrarvaloressehasustituidoDoWhile..LoopporDo..LoopWhile.

SubEjemplo_32()

DimNombreAsString
DimCiudadAsString
DimEdadAsInteger
DimfechaAsDate

'LlamadaalafuncinSaltar_Celdas_Llenas,elprogramasaltaaquaejecutarlas
'instruccionesdeesteprocedimientoyluegovuelveparacontinuarlaejecucinapartirdela
'instruccinDo
CallSaltar_Celdas_Llenas

Do
Nombre=InputBox("EntreelNombre(ReturnparaTerminar):","Nombre")
Ciudad=InputBox("EntrelaCiudad:","Ciudad")
Edad=Val(InputBox("EntrelaEdad:","Edad"))
Fecha=Cdate(InputBox("EntralaFecha:","Fecha"))

WithActiveCell
.Value=Nombre
.Offset(0,1).Value=Ciudad
.Offset(0,2).Value=Edad
.Offset(0,3).value=fecha
EndWith

ActiveCell.Offset(1,0).Activate

Mas_datos=MsgBox("Otroregistro?",vbYesNo+vbQuestion,"Entradadedatos")

LoopWhileMas_Datos=vbYes

EndSub

'Funcinquesaltaceldasdeunamismacolumna.Sirveparaencontrarla primeraceldavacadela
'columna
SubSaltar_Celdad_Llenas()

WorkSheets("Hoja1").Activate
ActiveSheet.Range("A1").Activate

DoWhilenotIsEmpty(ActiveCell)
ActiveCell.Offset(1,0).Activate
Loop

EndSub

Prof. Cesar Apaza CCopa

Pgina 50

Macros en Excel

Generalizarunafuncin.

Observe que para saltar un rango de casillas llenas slo necesitar llamar a la funcin
Saltar_Celdas_Llenas, pero, siempreycuandoesterangoestenunahojallamada"Hoja1"yempieceen
la casilla A1, el procedimiento es pocoprctico ya que su mbito de funcionamiento es limitado. En la
siguienteseccinmodificaremoselprocedimientodemaneraquesirvapararecorrerunrangoque
empieceencualquiercasilladecualquierhoja.

Parmetros.

Losparmetrossonelmecanismoporelcualunprocedimientopuedepasarlevaloresaotroydeesta
forma condicionar, moldear, etc. las acciones que ejecuta. El procedimiento llamado gana entonces
enflexibilidad.Lasintaxisdellamadadeunprocedimientoeslasiguiente,
CallProcedimiento(Parmetro1,Parmetro2,...,
ParmetroN)Losparmetrospuedenservaloresovariables.

Lasintaxisparaelprocedimientollamadoeslasiguiente,

SubProcedimiento(Parmetro1asTipo,Parmetro2AsTipo,...,Parmetro3AsTipo)

Observequeaqu losparmetrosson variablesquerecibirnlosvalores, evidentemente debe


habercoincidenciadetipo.Porejemplo,sielprimerparmetroesunavariabletipoInteger,elprimer
valorqueseledebepasaralprocedimientocuandosellamatambinhadeserdetipoInteger(recuerde
que puedeserunvalordirectamenteounavariable).

Ejemplo33.

Elmismoprogramaqueenelejemplo32peroahoralafuncinSaltar_Celdas_Llenastienedos
parmetrosHojayCasilla_Inicialquerecibenrespectivamentelahojadondeestelrangoarecorreryla
casillainicialdelrango.

SubEjemplo_33()

DimNombreAsString
DimCiudadAsString
DimEdadAsInteger
DimfechaAsDate

'LlamadaalafuncinSaltar_Celdas_Llenas,observarquemediantedosparmetrosse
'Alprocedimientoenquehojaestelrangoasaltaryenlacasilladondedebeempezar.
CallSaltar_Celdas_Llenas("Hoja1","A1")
Do
Nombre=InputBox("EntreelNombre(ReturnparaTerminar):","Nombre")
Ciudad=InputBox("EntrelaCiudad:","Ciudad")
Edad=Val(InputBox("EntrelaEdad:","Edad"))
Fecha=Cdate(InputBox("EntrelaFecha:","Fecha"))

WithActiveCell
.Value=Nombre
.Offset(0,1).Value=Ciudad
.Offset(0,2).Value=Edad
.Offset(0,3).value=fecha
EndWith

ActiveCell.Offset(1,0).Activate

Prof. Cesar Apaza CCopa

Pgina 51

Macros en Excel

Mas_datos=MsgBox("Otroregistro?",vbYesNo+vbQuestion,"Entradadedatos")

LoopWhileMas_Datos=vbYes

EndSub

'
'ProcedimientoSaltar_Celdas_Llenas.
'Sirvepara Saltarceldasllenasdeunacolumnahastaencontrarunavacaqueseconvierteenactiva
'Parmetros:
'
Hoja:Hojadondeestelrangoasaltar.
'
Casilla_Inicial:CasillaInicialdelacolumna
SubSaltar_Celdas_Llenas(HojaAsString,Casilla_InicialAsString)

WorkSheets(Hoja).Activate
ActiveSheet.Range(Casilla_Inicial).Activate

DoWhilenotIsEmpty(ActiveCell)
ActiveCell.Offset(1,0).Activate
Loop

EndSub

ObservequeahoraelprocedimientoSaltar_Celdas_Llenassirvepararecorrercualquierrango
encualquierhoja.

Observequealprocedimientoselepasandosvaloresdirectamente,recuerde,yestoesquizslo
mshabitual,quetambinpuedenpasarsevariables,porejemplo.

SubEjemplo_33
.
.
DimHojaAsString
DimCasilla_InicialAsString

Hoja=InputBox("Enquehojaestlabasededatos:","EntrarNombredeHoja")
Casilla_Inicial=InputBox("Enquecasillacomienzalabasededatos","CasillaInicial")

EndSub

'Observequelosparmetrossondosvariablescuyovalorsehaentradodesdetecladoen
'lasdosinstruccionesInputBoxanteriores.
CallSaltar_Celdas_Llenas(Hoja,Casilla_Inicial)
.
.

Prof. Cesar Apaza CCopa

Pgina 52

Macros en Excel

VariableslocalesyvariablesGlobales.

El mbito de una variable declarada dentro de una funcin es la propia funcin, es decir no podr
utilizares fuera de dicha funcin. As, el siguiente programa que debera sumar las cinco filas siguientes a
partirdelacasillaactivayguardarelresultadoenlasextaesincorrecto.

SubAlguna_Cosa()
.
.
.
CallSumar_Cinco_Siguientes
ActiveCell.Offset(6,0).Value=Suma
.
.
EndSub

SubSumar_Cinco_Siguientes()

DimiAsInteger
DimSumaAsSingle

Suma=0
Fori=1To5
Suma=Suma+ActiveCell.Offset(i,0).Value
Nexti

EndSub

Es incorrecto porque tanto las variable i como la variable Suma estn declaradas dentro del procedimiento
Sumar_Cinco_Siguientesconsecuentemente,sumbitodeaccinesesteprocedimiento.Portanto,la
instruccinActiveCell.Offset(6,0).Value = Suma del procedimiento Alguna_Cosa, generara un error (con
Option Explicit activado) ya que la variableSuma noestdeclaradodentro de l. Si piensa en declarar la
variable Suma dentro del procedimiento Hacer_Algo, no solucionar nada porque esta ser local a dicho
procedimiento, en este caso tendra dos variables llamadas Suma pero cada una de ellas local a su
propioprocedimientoyconsecuentementeconelmbitodeaccinrestringidoaellos.

Unasolucin,queanosotrosnonosgusta,seriadeclararsumacomovariableglobal.Unavariable
globalsedeclarafueradetodoslosprocedimientosyesreconocidaportodoslosprocedimientosdel
mdulo,

OptionExplicit

'Sumaesunavariableglobalreconocidaportodoslosprocedimientosdelmdulo.
DimSumaAsSingle

SubAlguna_Cosa()
.
CallSumar_Cinco_Siguientes
ActiveCell.Offset(6,0).Value=Suma
.
EndSub

SubSumar_Cinco_Siguientes()

DimiAsInteger

Suma=0
Fori=1To5
Suma=Suma+ActiveCell.Offset(i,0).Value
Nexti

Prof. Cesar Apaza CCopa

Pgina 53

Macros en Excel

EndSub

Prof. Cesar Apaza CCopa

Pgina 54

Macros en Excel

Lasvariablesglobalessonperfectasenciertaocasiones,paraestecasoseriamejordeclararSumaen
lafuncinHacer_AlgoypasarlacomoparmetroalprocedimientoSumar_Cinco_Siguientes.

SubAlguna_Cosa()

EndSub

DimSumaAsSingle
.
.
'LlamadaalafuncinSumar_Cinco_SiguientespasndolelavariableSuma
CallSumar_Cinco_Siguientes(Suma)
ActiveCell.Offset(6,0).Value=Suma
.
.

SubSumar_Cinco_Siguientes(SAsSingle)

DimiAsInteger

Suma=0
Fori=1To5
S=S+ActiveCell.Offset(i,0).Value
Nexti

EndSub

Esto le funcionaria porque la variable parmetro S (y se le ha cambiado el nombre adrede) de


Sumar_Cinco_Siguientes es la variable Suma declaradaenHacer_Algo.Funcionarporqueenvisual
basic, a menos que se indique lo contrario, el paso de parmetros es por referencia, vea la
siguienteseccin.

Pasoporreferenciaypasoporvalor.

No entraremos en detalles sobre como funciona el paso de parmetros por valor y el paso de
parmetrospor referencia, slo indicar que el paso por valor significa que la variable parmetro del
procedimientorecibe el valor de la variable (o directamente el valor) de su parmetro correspondiente
de la instruccinde llamada y en el paso por referencia, la variable parmetro del procedimiento es
la misma que suparmetro correspondiente de la instruccin de llamada, es decir, la declarada en el
procedimientodesdeelquesehacelallamada.Pordefecto, y siempre que en la instruccin de llamada se
utilicen variables, lasllamadas son por referencia. Si desea que el paso de parmetros sea por valor,
debe anteponer a lavariableparmetrolapalabrareservada ByVal,porejemplo,

SubSaltar_Celdas_Llenas(ByValHojaAsString,ByValCasilla_InicialAsString)

Aunqueloeleganteyefectivoporrazonesdememoriaseriapasarsiemprequeseaposibleporvalor,es
poco habitual que as se haga en visual basic, seguramente por comodidad. Como suponemos que
harcomo la mayora, es decir, pasar por referencia, tenga cuidado con los (indeseables) efectos
laterales.Copieyejecuteesteprogramaydescubrirquesonlosefectoslaterales.

Prof. Cesar Apaza CCopa

Pgina 55

Macros en Excel

EjemploEfecto_Lateral.

Antes de copiar el programa, active una hojaenblancoypongavaloresdel1al15distribuidosdela


forma siguiente, en el rango A1:A5 valores del 1 al 5, en el rango B1:B5 valores del 6 al 10, en el rango
C1:C5valoresdel11al15.

El siguiente programa debe recorrer cada una de tres las columnas de valores, sumarlos y poner el
resultadoenlasfilas6decadacolumna.Entonces,segnlosvaloresquehaentradoencadaunadelas
columnas,cuandohayaacabadolaejecucindelprogramadebehaberlossiguientesresultados,A6=
15,B6=40, C6=65. Para llevar a cabo la suma de los valores de cada columna se llama a la
funcinRecorrer_Sumar tresveces,unaparacadacolumna,estafuncinrecibeenelparmetroF el
valor de lafila donde debe empezar a sumar, sobre el parmetro C el valor de la columnaasumar
ysobreelparmetroQlacantidaddefilasquehaderecorrer.

ElprogramautilizalapropiedadCellsparareferenciarlasfilasycolumnasdelosrangos.Observe
atentamentelosvaloresqueircogiendolavariableFilayaqueestaserlaquesufraelefecto
lateral.

SubEfecto_Lateral()

DimFilaAsInteger

Fila=1

CallRecorrer_Sumar(Fila,1,5) 'ColumnaA
CallRecorrer_Sumar(Fila,2,5) 'ColumnaB
CallRecorrer_Sumar(Fila,3,5) 'ColumnaC

EndSub

SubRecorrer_Sumar(FAsInteger,CAsInteger,QAsInteger)

DimiAsInteger
DimTotalAsInteger

Total=0
Fori=1ToQ
Total=Total+ActiveSheet.Cells(F,C).Value
F=F+1'OJOconestaasignacin,recuerdequeFeslavariableFiladeclaradaen
'elprocedimientoEfecto_Lateral
Nexti
ActiveSheet.Cells(F,C)=Total

EndSub

Cuando ejecute el programa se producir la salida siguiente, en A6 habr un 15, hasta aqu todo
correcto,peroobservequeenlasegundacolumnaapareceun0enB12yenlatercera columna aparece
un 0 enC18, veamos que ha pasado. La primera vez que se llama la funcin, la variable F vale 1 ya que
este es elvalor que tiene su parmetrocorrespondiente (Fila)enlainstruccinCall. Observe que
F se vaincrementando una unidad a cada paso de bucle For, RECUERDE que F es realmente la
variable Filadeclarada en el procedimiento Efecto_Lateral, por tanto cuandofinalizael
procedimientoRecorrer_Sumary vuelve el control al procedimientoEfecto_Lateral Fila vale 6,yesteesel
valor que sepasaraRecorrer_Sumalasegundavezquesellama,apartirdeahtodoirmalyaquese
empezarelrecorridodefilasporla6.Unadelassolucionesaesteproblemaparahacerquecadavezquese
llameRecorrer_Sumar la variable Frecibaelvalor1,esutilizarunpasoporvalor,esdecirqueFreciba
elvalor deFila, no que sea la variableFila, observe que entonces, siFnoeslavariableFila,cuando
incrementeF no se incrementar Fila, esta siempre conservar el valor 1. Para hacer que F sea un
parmetro por valor, simplemente ponga la palabraByValantes deF en la declaracin del procedimiento.

Prof. Cesar Apaza CCopa

Pgina 56

Macros en Excel

Vuelvaaejecutarelprograma,vercomoahorafuncionacorrectamente.

Prof. Cesar Apaza CCopa

Pgina 57

Macros en Excel

Insistimos de nuevo en que tenga cuidado con estas cosas. Al menos ahora ya est sobre aviso, cuando
unprogramano haga loque ha previsto una de lascosas que deber repasar es el paso de parmetros a los
procedimientos.

** Para acabar, observe que en muchas ocasiones le hemos indicado que en el paso por referencia
lavariabledelprocedimientollamadoeslavariabledeclaradaenelprocedimientoquellama.Eneste
ltimoejemplo, le hemos dicho que Feralavariable Fila, pues bien, esto no es cierto Fila es una variable y
Fesotravariable,ahoraeslgicoquesepregunteporquentoncesF acta como si fuera Fila, este
esuntemaquenoentraenelmbitodeestemanual,sialgunavezprogramaenCyllegaaltema
delospunteros entender que es lo que sucede realmente en el paso por parmetro y en el paso por
valor.Si yaconocelospunterosdeCoPascalentoncesyahabrintuidoqueelpasoporvaloren
nuestroejemploequivaldraa,

Recorrer_Fila(F,C,Q);

voidRecorrer_Fila(intF,intC,intQ)Y
unpasoporreferenciaa
Recorrer_Fila(&F,C,Q);

VoidRecorrer_Fila(int*F,intC,intQ)

Prof. Cesar Apaza CCopa

Pgina 58

Macros en Excel

Funciones.

Unafuncineslomismoqueunprocedimientoconlasalvedadqueestedevuelveunvaloral
procedimiento o funcin que lo llama. Vea el siguiente ejemplo, es una funcin muy sencilla ya que
simplementesumadosnmerosydevuelveelresultado.

Ejemplo34.

Funcinquedevuelvelasumadedosvaloresqueselepasancomoparmetros.Observelas
diferentesformasencomosellamalafuncin.

SubEjemplo_34()

DimxAsInteger
Dimn1AsInteger,n2AsInteger

X=Suma(5,5)

n1=Val(InputBox("Entrarunnmero:","Entrada"))
n2=Val(InputBox("Entrarotronmero:","Entrada"))
X=suma(n1,n2)
ActiveCell.Value=Suma(ActiveSheet.Range("A1").Value,ActiveSheet.Range("A2").Value)

X=Suma(5,4)+Suma(n1,n2)

EndSub

FunctionSuma(V1AsInteger,V2AsInteger)AsInteger

DimTotalAsInteger

Total=V1+V2

Suma=Total

EndFunction

Observelasintaxisdelacabeceradefuncin,

FunctionSuma(V1AsInteger,V2AsInteger)AsInteger

Laestructurageneralseria,

FunctionNombre_Funcion(par1AsTipo,par2AsTipo,...,parN AsTipo)AsTipo.

Lasintaxisessimilaralacabeceradeunprocedimiento,sloqueunafuncintienetipo,estotienesu
lgica, ya que una funcin devuelve un valor, ese valor ser de un tipo determinado. As, en nuestro
ejemplodeFunctionSuma, esta funcin es de tipo Integer,odichodeotramanera,lafuncinejecuta
sussentenciasydevuelveunvalorhaciaelprocedimientoolafuncinquelallam,el valor devuelto se
estableceigualandoelnombredelafuncinaalgo,

Prof. Cesar Apaza CCopa

Pgina 59

Macros en Excel

Nombre_Funcin=....
Enelejemplode FunctionSuma,
Suma=Total

Observe tambin la sintaxis de la llamada a la funcin, en el ejemplo hemos utilizado unas cuantas formas
dellamarla,loquedebetenersiemprepresenteesqueencualquierexpresinaritmticaodeclculo,el
ordenadorrealizaunmnimodedosoperaciones,unadeclculoyotradeasignacin.Porejemplo,

A=B+C

ElordenadorprimerocalculaelresultadodesumarB+CluegoasignaeseresultadoalavariableA.En
cualquierllamadaaunafuncin,cojamosporcaso,

X=suma(n1,n2)

PrimeroseejecutantodaslassentenciasdelafuncinSuma,luegoseasignaelclculodelafuncinala
variableX.Deotrovistazoalafuncindeejemployvealoquerealizacadasentenciaenlaquesellama
alafuncinSuma.

Veamos a continuacin unos cuantos ejemplos de funciones. Antes recordarle que todo lo referente
a parmetros por valor y referencia, variables locales y globales, etc. que estudiamos en los
procedimientoseslomismoparalasfunciones.

Ejemplo35.

Funcin que devuelve la direccin de la primera celda vaca de un rango. La funcin es de tipo String ya
que devuelve la casilla en laforma"FilaColumna", porejemplo "A10".Utilizaremos la propiedad
Addressdelobjetorange,estapropiedaddevuelveunstringquecontienelareferencia"FilaColumna"de
unacasillaorangodecasillas.Enelcasodeunrangodevuelve,

"FilaColumna_Inicial:FilaColumna_Final",porejemplo"A1:C10"

SubEjemplo_35()

DimCasillaAsString

Casilla=Casilla_Vacia("A1")

......
EndSub

Prof. Cesar Apaza CCopa

Pgina 60

Macros en Excel

'FuncinCasilla_VaciadeTipoString
'Sirvepara Recorrerlasfilasdeunacolumnahastaencontrarunavaca.
'Parmetros:
'
Casilla_Inicio:Casilladondedebeempezarabuscar.
'Devuelve Unstringquecontienelareferenciadelaprimeracasilla
FunctionCasilla_Vacia(Casilla_InicioAsString)AsString
ActiveSheet.Range(Casilla_Inicio).Activate

DoWhileNotIsEmpty(ActiveCell)
ActiveCell.Offset(1,0).Activate
Loop

Casilla_Vacia=ActiveCell.Address
EndFunction

Ejemplo36.

Similaralanterior.Eslatpicabsquedasecuencialdeunvalorenunrangodecasillas,enestafuncin
solo se avanzar a travs de una fila.La funcin devuelve la direccin (address) de la casilla donde est el
valorbuscado,encasoqueelvalornoestenelrangodefilas,devuelveunacadenavaca("").

SubEjemplo_36()
DimCasillaAsString
Casilla=Buscar_Valor("A1",25)

'Sivalornoencontrado
IfCasilla=""Then
.....
Else'Valorencontrado
....
Endi f

EndSub
'FuncinBuscardeTipoString
'Sirvepara Recorrerlasfilasdeunacolumnahastaencontrarelvalorbuscadoounadevaca.
'Parmetros:
'
Casilla_Inicial:Casilladondedebeempezarabuscar.
'
Valor_Buscado:Valorquesedebeencontrar
'Devuelve Unstringquecontienelareferenciadelacasilladondesehaencontradoelvalor.
'
Tambinpuededevolver""encasoqueelvalorbuscadonoest.
FunctionBuscar(Casilla_InicialAsString,Valor_BuscadoAsInteger)AsString

ActiveSheet.Range(Casilla_Inicial).Activate

'MientrascasillanovacaYvalordecasilladiferentealbuscado
DoWhileNotIsEmpty(ActiveCell)AndActiveCell.Value<>Valor_Buscado
ActiveCell.Offset(1,0).Activate
Loop

'SilacasilladondesehadetenidolabsquedaNOESTVACAesquesehaencontrado
'elvalor.
If NotIsEmpty(ActiveCell) Then
Buscar=ActiveCell.Address'Devolverlacasilladondesehaencontradoelvalor
Else'Lacasilla estvaca,NOsehaencontradoelvalorbuscado
Buscar=""'Devolverunacademavaca
Endi f

EndFunction

Pgina 50

Macros en Excel

Ejemplo36.

Similaralanterior.Bsquedasecuencialdeunvalorenunrangodecasillas,enestafuncin se avanzar a
travsdefilasycolumnas.Lafuncindevuelveladireccin(address)delacasilladondeestelvalor
buscado,encasoqueelvalornoestenelrango,devuelveunacadenavaca("").

SubEjemplo_36()

DimCasillaAsString

Casilla=Buscar_Valor("A1",25)

IfCasilla=""Then
.....
Else

....
Endi f

EndSub

FunctionBuscar(Casilla_InicialAsString,Valor_BuscadoAsInteger)AsString

DimIncremento_ColumnaAsInteger
DimContinuarAsBoolean

ActiveSheet.Range(Casilla_Inicial).Activate

Continuar=True
DoWhileContinuar
Incremento_Columna=0
'Buscarelvalorporlascolumnashastaencontrarlooencontrarunaceldavaca.
DoWhileNotIsEmpty(ActiveCell.Offset(0,Incremento_Columna)And
ActiveCell.Offset(0,Incremento_Columna.Value<>Valor_Buscado
'Siguientecolumna
Incremento_Columna=Incremento_Columna+1

Loop
'Sinoestvacalacasillaentoncespararlabsqueda,sehaencontradoelvalor
If NotIsEmpty(ActiveCell.OffSet(0,Incremento_Columna))Then
Continuar=False
Else'Lacasillaestvaca,nosehaencontradoelvalor
ActiveCell.Offset(1,0).Activate'Saltaraunanuevafila
IfIsEmpty(ActiveCell)Then'Silacasilladelanuevafilaestvaca
Continuar=False'Pararlabsqueda,nohaymscasillaarecorrer

Endi f
Endi f

Loop
'SilacasilladondesehadetenidolabsquedaNOESTVACAesquesehaencontrado
'elvalor.
IfNotIsEmpty(ActiveCell)Then
Buscar=ActiveCell(0,Incremento_Columna).Address'Devolverlacasilladondese
'haencontradoelvalor

Else'Lacasilla estvaca,NOsehaencontradoelvalorbuscado
Buscar=""'Devolverunacademavaca
Endi f

EndFunction

Pgina 51

Macros en Excel

LaclusulaPrivate.

Puede anteponer la clusula private a todos los procedimientos y funciones que sean llamados slo
desdeel mismo mdulo, es una forma de ahorrar memoria y hacer que el programa corra un poco ms
rpido. Sinecesita llamar un procedimiento o funcin desde otro mdulo, nunca debe precederlo por
la clusulaprivate, recuerde que esta clusula restringe el mbito de utilizacin de un procedimiento
a su propiomdulo.Supongamoselejemplosiguiente.

'Mdulo1

SubGeneral
....
EndSub

PrivateSubPrivado
....
EndSub

'Mdulo2

SubProcedimiento_de_modulo2

'Estoescorrecto.LlamaalprocedimientoGeneraldefinidoenMdulo1
CallGeneral

'Estonoescorrecto.LlamaalprocedimientoPrivadodefinidoenMdulo1,este
' procedimientovaprecedidoprolaclusulaPrivate,portantoslopuedeserllamado
'desdeprocedimientosdesupropiomdulo
CallPrivado

EndSub

Pgina 52

Macros en Excel

Vamos a ver a continuacin tres ejemplos ms sobre funciones. Es importante que los cree en un libro
detrabajo nuevo y los ponga en un mismomdulo, al final del captulo utilizaremos las opciones de
exportar e importar mdulos de procedimientos y funciones. En todos los ejemplos ver el procedimiento
Procedimiento_Llamador, es para mostrar de que forma se debe llamar al procedimiento o funcin. Los
procedimientosimplementadosson,porllamarlodealgunamanera,detipogeneral,esdecir,son
procedimientosquepodrutilizarenmuchasaplicaciones.

Ejemplo37.

Procedimiento que abre un cuador MsgBox y muestra el texto que se le paso como
parmetro.

SubProcedimiento_Llamador()

EndSub

.
.
CallmAviso("Estoeselmensajedeaviso","EstoeselTtulo")
.
.

'ProcedimientomAviso
'Funcin MostrarelcuadrodefuncinMsgBox,coneliconoinformacinyelbotnOK(Aceptar).
'Seutilizaparamostraravisos.
'Parmetros:
'Texto=Textoquemuestraelcuadro
'Titulo=Ttulodelcuadro
'

SubmAviso(TextoAsString,TituloAsString)

MsgBoxPrompt:=Texto,Buttons:=vbOKOnly+vbInformation,Title:=Titulo

EndSub

Ejemplo38.

Funcintiporange quedevuelveunrango.ObservecomolafuncinseigualaaunavariabletipoRange,
recuerde que con esta variable podr acceder a todas las propiedades e invocar todos los mtodos
propiosdelosobjetosRange.Enesteejemploenconcretoseutilizanlas variables para Copiar un grupo
de celdasdeunrangohaciaotro,seutilizanlosmtodosCopyyPastedelobjetoRange.

SubProcedimiento_Llamador()

DimRango_OrigenAsRange
DimRango_DestinoAsRange

SetRango_Origen=Coger_Rango(A1,5,5)
Rango_Origen.Copy

SetRango_Destino=Coger_Rango(G1,5,5)
Rango_Destino.PastePasteSpecial:=xlPasteAll

EndSub

Pgina 53

Macros en Excel

'Funcinquedevuelveunrangoa unavariabledeestetipo
'Parmetros
'Casilla=casillainicialdelrango
'Filas=nmero'defilas
'Columnas=nmerodecolumnasdelrango
FunctionCoger_Rango(CasillaAsString,FilasAsInteger,ColumnasAsInteger)AsRange

DimCasilla_FinalAsString
ActiveSheet.Range(Casilla).Activate
ActiveCell.Cells(Filas,Columnas).ActivateCasilla_Final=
ActiveCell.AddressActiveSheet.Range(Casilla&":"&
Casilla_Final).Select
SetCoger_Rango=ActiveSheet.Range(Casilla&":"&Casilla_FInal)

EndFunction

Ejemplo39.

Funcin para comprobar el tipo de datos. Es una funcin de comprobacin que se puede utilizar
para validar los datos que se entran desde un cuadro InputBox o desde los cuadros de texto de
formularios. LafuncinesdetipoBooleano,devuelveTrue(cierto)oFalseenfuncindesieldato
pasadoescorrecto.En esta funcin se evalan slo datos numricos y datos tipo Fecha, puede
ampliarla para que secompruebenmstipos.

SubProcedimiento_Llamador()

DimCantidadAsInteger
DimFechaAsDate
DimDatosAsString
.
.
Datos=InputBox("EntrarunaCantidad:","Entrar")
IfNotComprobar_Tipo(Datos,"N")Then
mAviso("Losdatosintroducidonosonnumricos","Error")
Else

Cantidad=Val(Datos)
.
.
EndIf
.
.
Datos=InputBox("EntrarFecha","Entrar")
IfNotComprobar_Tipo(Datos,"F")Then
mAviso("Losfechaintroducidanoescorrecta","Error")
E Else
n
d

S EndIf
u .
b .
Pgina 54

Macros en Excel

Fecha=
Val(Datos)
.
.

Pgina 55

Macros en Excel

'Funcinqueevalasieltipodedatosqueselepasansoncorrectosono.Sisoncorrectosdevuelve
' TRUE,encasocontrariodevuelveFALSE
'Parmetros
'
Valor=valorquesedebecomprobar,detipoString
'
Tipo=tipoacomprobar,"N">Numrico,"F",tipofecha

FunctionComprobar_Tipo(ValorAsString,TipoAsString)AsBoolean

DimValidoAsBoolean

Valido=True

SelectCaseTipo
'Compruebasiesunvalornumricovlido
Case"N"
IfNotIsNumeric(Valor)Then
Valido=False
EndIf

'Compruebasiesunvalorfechavlido
Case"F"
IfNotIsDate(Valor)Then
Valido=False
EndIf

EndSelect

Comprobar_Tipo=Valido

EndFunction

ImportaryExportarmdulos.

Losltimostresejemplosquehemosvisto,comolehemosindicado,sonprocedimientosquepuedenser
utilizados en multitud de ocasiones o situaciones, seria interesante tenerlos disponibles en cualquiera
delas hojas que confeccionemos. Podra pensar en utilizar las opciones de copiar y pegar para
pasarprocedimientos de una hoja a otra, es un mtodo totalmente vlido y efectivo, pero le
proponemos acontinuacinotromtodoms"profesional",porllamarlo de otra manera, e igual
deefectivo. Estemtodo consiste en guardar los procedimientos de un mdulo en un archivo
aparte, es decir,independiente de cualquier hoja de clculo, luego, cuando en una nueva hoja
necesiteestas funciones,solodeberimportarestearchivoparaincorporarlo.

Exportarunmdulo.Guardarunmduloenunarchivo.

Comoejemplo,abralahojadondepusolostresltimosprocedimientos.

1. Pasealeditordevisualbasicyactiveelmduloaexportar.
2. ActiveopcindelabarrademensArchivo/Exportararchivo.Apareceuncuadrodedilogo.
3. EncuadrodeedicinNombredeArchivo,tecleeelnombreparaelarchivodondeseguardarel
mdulo,porejemplo"General.Bas",observeque.BASeslaextensindeestosarchivos.
4. PulsesobreelbotnGuardar.

Pgina 56

Macros en Excel

Importarunmdulo.

Siestsiguiendoelejemplo,cierretodoslosarchivosdeExcelyabraunonuevo.

1. ActiveeleditorVisualBasic.
2. ActiveopcindelabarrademensArchivo/ImportarArchivo.Apareceuncuadrodedilogo.
3. SeleccioneenlalistaBuscaren:lacarpetadondetieneubicadoelarchivoaimportar(la
carpetadondeestGeneral.Bassiestsiguiendoelejemplo).
4. Unavezlocalizadalacarpeta,seleccioneelarchivoaimportar(General.Basenelejemplo)ypulse
sobreAbrir.

Observecomoenlaventanadeproyectosehaincorporadounnuevomduloquecontienetodos
losprocedimientosyfuncionesdelarchivoimportado.

Terminamos aqu el tema de procedimientos y funciones, djenos insistir de nuevo en que es muy
impor tante que construya sus programas utilizando todas las ventajas que le ofrece la
programacin modular. Como ltimo consejo, agrupe todas las funciones que usted considere de
utilizacin general enunoodosmdulosyluegoutilicelasopcionesdeimportacinyexportacinpara
incorporarlosasusprogramas.

Pgina 57

Macros en Excel

Lagrabadorademacros.

MicrosoftExcelllevaincluidaunautilidadquesirvepararegistraraccionesquesellevanacaboenun
librodetrabajoyregistrarlasenformademacro.Podemosaprovecharestautilidadparagenerar
cdigoengorroso por su sintaxis un tanto complicada de recordar, adems de ahorrar tiempo. Casi
siempredespusdeberemosmodificarloparaadaptarloanuestrosprogramas,sinembargoeso
resultarsumamente sencillo. Vea el ejemplo siguiente que sirve para poner bordes al rango de celdas de
A1 a G6,observeloscomentariosparasaberquebordesseponenydndeseponen.

Ejemplo1.

PonerbordesalrangoquevadeA1aG6.
SubPoner_Bordes()

'SeleccionarelrangoA1:G6
Range("A1:G6").Select

'Nohaybordediagonalhaciaabajo
Selection.Borders(xlDiagonalDown).LineStyle=xlNone

'Nohaybordediagonalhaciaarriba
Selection.Borders(xlDiagonalUp).LineStyle=xlNone

'Bordeizquierdodelaseleccn
WithSelection.Borders(xlEdgeLeft)
.LineStyle=xlContinuous
.Weight=xlMedium
.ColorIndex=xlAutomatic
EndWith

'Estilodelineacontinuo
'AnchodelneaMedio
'Colordelneaautomtico(negro)

'Bordesuperiordelaseleccin
WithSelection.Borders(xlEdgeTop)
.LineStyle=xlContinuous
.Weight=xlMedium
.ColorIndex=xlAutomatic
EndWith

'Bordeinferiordelaseleccin
WithSelection.Borders(xlEdgeBottom)
.LineStyle=xlContinuous
.Weight=xlMedium
.ColorIndex=xlAutomatic
EndWith

'Bordederechodelaseleccin
WithSelection.Borders(xlEdgeRight)
.LineStyle=xlContinuous
.Weight=xlMedium
.ColorIndex=xlAutomatic
EndWith

'Bordesverticalesinterioresdelaseleccin
WithSelection.Borders(xlInsideVertical)
.LineStyle=xlContinuous
.Weight=xlThin
'AnchoSimple.
.ColorIndex=xlAutomatic

Pgina 58

Macros en Excel

EndWith

Pgina 59

Macros en Excel

'Nohaybordeshoriontalesinterioresenlaseleccin
Selection.Borders(xlInsideHorizontal).LineStyle=xlNone

'SeleccionarrangoA1:G1
Range("A1:G1").Select

'Nohaybordediagonalhaciaarriba
Selection.Borders(xlDiagonalDown).LineStyle=xlNone

'Nohaybordediagonalhaciaarriba
Selection.Borders(xlDiagonalUp).LineStyle=xlNone

'Bordeiquierdodelaseleccin
WithSelection.Borders(xlEdgeLeft)
.LineStyle=xlContinuous
.Weight=xlMedium
.ColorIndex=xlAutomatic
EndWith

'Bordesuperiordelaseleccin
WithSelection.Borders(xlEdgeTop)
.LineStyle=xlContinuous
.Weight=xlMedium
.ColorIndex=xlAutomatic
EndWith

'Bordeinferiordelaseleccin
WithSelection.Borders(xlEdgeBottom)
.LineStyle=xlDouble
.Weight=xlThick
.ColorIndex=xlAutomatic
EndWith

'Doblelnea

'Bordederechodelaseleccin
WithSelection.Borders(xlEdgeRight)
.LineStyle=xlContinuous
.Weight=xlMedium
.ColorIndex=xlAutomatic
EndWith

EndSub

Pgina 60

Macros en Excel

Suponemosqueelprocedimientoanteriorleparecerabrumador,nosepreocupe,leexplicamosa
continuacincomolohemoshechoyverquelonicoquedebehacersonlospasossobrelahojade
clculo,elgrabadordemacrosseocupadelresto.

1. Activelagrabadorademacros.Herramientas/Macro/Gravarnuevamacro.Aparecelaventana
siguiente.

2. EnNombredeMacro,pongaPoner_Lneas.EnGuardarMacroen,dejelaopcinLibroActivo.
EnDescripcin,ponga,macroparabordesaunrangodeceldas.

3. PulsesobreelbotnAceptar.

4. Ejecutelospasossiguientes.Sonparaponerlosbordes

4.1SeleccioneelrangoA1:G6.
4.2ActiveOpcinFormato/Celdas.SeleccionefichaBordes.
4.3Pongalneaalrededordelaseleccn
4.3.1 EncuadroEstilos,seleccionelapenltimaoantepenltimalnea.
4.3.2 Pulsesobreelbotnquerepresentauncuadrado.

4.4Pongalaslneasverticales.

4.4.1
4.4.2

Seleccionedelcuadroestilolaltimalneadelaprimeracolumna.
Pulsesobreelbotnquerepresentalaslneasinterioresdelaseleccin(el
situadoenelcentrodelalneainferiordebotones).

4.PulsesobreelbotnAceptar.

5. SeleccioneelrangoA1:G1

6. ActivedenuevolaopcinFormato/CeldasyseleccionelafichaBordes.

7. Pongalneainferiordoble.

7.1 SeleccionedelcuadroEstilolaltimalneadelasegundacolumna.
7.2 Pulsesobreelbotnquerepresentalalneainferiordelaseleccin.

8. PulsesobreelbotnAceptar.

9. DetengalagrabadoradeMacrospulsandosobreelbotnobien
Herramientas/Macros/DetenerGrabacin.

a1active

YYaest.AhoraabraelEditordeVisualBasicycompruebecomolagrabadorahahechotodoeltrabajo
prousted.Ahorayaslonosquedamodificarlamacrodeformaqueesteformatodebordessea
aplicableacualquierrango.Veaelejemplosiguiente.

Pgina 61

Macros en Excel

Ejemplo2.

En este ejemplo modificaremos la macro de manera que sirva para dar ese formato a cualquier rango de
lahoja.Observeenesteejemplosimplementepasamoscomoparmetroelrangoaformateardemanera
quelacabeceradelprocedimientoquedaria.

'ProcedimientoPoner_Bordes.
'Procedimientoqueponebordesaunrango.Concretamenteloencierraenuncuadrado,leponelneas
'verticalesyponeunadoblelneainferiorenlaprimerafila.
'Parmetros:
'
Nombre_Hoja:Nombredelahojadondeestelrango.
'
Rango_Total:Rangoalqueseleaplicaelformato.
'
Rango_Primera_Fila:Rangodelaprimerafilaalquesedebeaplicardoblelneainferior.

SubPoner_Bordes(Nombre_HojaAsString,Rango_TotalAsString,Rango_Primera_FilaAsString)

'Seleccionamoslahojaenlaqueseencuantraenrango
WorkSheets(Nombre_Hoja).Activate

'Seleccionamosenrango
ActiveSheet.Range(Rango_Total).Select

'Hacemoscuadroylneasverticales.
.......
.......

'Seleccindelaprimerafila
ActiveSheet.Range(Primera_Fila).Select

'Hacemoslneainferiordoble

.........

EndSub

Pgina 62

Macros en Excel

Ejemplo3.

Refinamiento de la macro del ejemplo anterior. En este ejemplo todava perfeccionaremos ms la


macrodel ejercicio anterior. Sobre todo en lo referente a los parmetros.Bsicamente cambiaremos el
tipo deparmetros, as en lugar del nombre de la hoja pasaremos el nmero y en lugar de los
parmetrosRango_Total y Rango_Primera_Fila, simplemente pasaremos el rango de la casilla inicial, la
macro seencargar de seleccionar todas las casillas adyacentes y de buscar la primera fila. En esta
macro ademsse han incluido funcionalidades como borrar los formatos antes de aplicar las lneas,
ajustarelanchodelascolumnas,etc.Lealoscomentariosparaverquehacecadaseccindelamacro.

ObservelapropiedadCurrentRegiondelobjetoRange,estapropiedaddevuelveelrangodelascasillas
llenasadyacentesaunadada.PorejemploimagineunahojaconelrangoA1:B10llenodevalores,la
instruccin

ActiveSheet.Range("A1").CurrentRegion.Select

SeleccionariaelrangocorrespondienteaA1:B10.

'FuncinPoner_Lneas_Seleccin.
'Estafuncinsirveparaponerbordesaunrango. Ponecuadroalrango,separalascolumnascon
'unalniayponedoblelneainferiorenla'primerafila.
'
'Parmetros:
'
Num_Hoja=Nmerodehojadondeestelrangoaformatear.
'
Casilla=Casillainicial(superiorizquierda)delrangoaformatear

SubPoner_Lineas_Seleccion(Numero_HojaAsInteger,CasillaAsString)

DimxAsInteger
DimCasilla_InicialAsString
DimCasilla_FInalAsString

Worksheets(Numero_Hoja).Activate
ActiveSheet.Range(Casilla).Activate

'Seleccionarelrangodeceldasconvaloresadyacentesalaactiva
ActiveCell.CurrentRegion.Select

'Borrarlosbordesactualesdelaseleccinactuales
WithSelection
.Borders(xlDiagonalDown).LineStyle=xlNone
.Borders(xlDiagonalUp).LineStyle=xlNone
.Borders(xlEdgeLeft).LineStyle=xlNone
.Borders(xlEdgeTop).LineStyle=xlNone
.Borders(xlEdgeBottom).LineStyle=xlNone
.Borders(xlEdgeRight).LineStyle=xlNone
.Borders(xlInsideVertical).LineStyle=xlNone
.Borders(xlInsideHorizontal).LineStyle=xlNone
EndWith

'Lineasdelrecuadro

WithSelection.Borders(xlEdgeLeft)
.LineStyle=xlContinuous
.Weight=xlMedium
.ColorIndex=xlAutomatic
EndWith

Pgina 63

Macros en Excel

WithSelection.Borders(xlEdgeTop)
.LineStyle=xlContinuous
.Weight=xlMedium
.ColorIndex=xlAutomatic
EndWith

WithSelection.Borders(xlEdgeBottom)
.LineStyle=xlContinuous
.Weight=xlMedium
.ColorIndex=xlAutomatic
EndWith

WithSelection.Borders(xlEdgeRight)
.LineStyle=xlContinuous
.Weight=xlMedium
.ColorIndex=xlAutomatic
EndWith

'Linieasverticalesinteriores,sienel
'rangohaymsdeunacolumna.
IfSelection.Columns.Count>1Then
WithSelection.Borders(xlInsideVertical)
.LineStyle=xlContinuous
.Weight=xlThin
.ColorIndex=xlAutomatic
EndWith
EndIf

'Ajustaranchodecolumnas
Selection.Columns.AutoFit

'Lneadobleinferiordeprimerafila
'PAraesteprocesoseseleccionalacasillainicialpasadaalamacro,luegosebusca
'laltimacasillacondatos.Seconstruyeunrangocombinandolasdireccionesdeambas
'casillasyseutilizaelobjetoRangejuntoconelmtodoSelectparahacerlaseleccin
'
'
RANGE(Inicial:Final).Select

'Seleccionarprimeracasilla
ActiveSheet.Range(Casilla).Select

'Buscarprimeracasillavaciademismafilarecorriendolascolumnas
x=0
DoWhileNotIsEmpty(ActiveCell.Offset(0,x))
x=x+1
Loop

'RecogerlasdireccionesdelacasillainicialYlacasillafinal,esdecirlasreferencias
'FilaColumna(A1,A2,....)
Casilla_Inicial=ActiveCell.Address
Casilla_FInal=ActiveCell.Offset(0,x1).Address

Pgina 64

Macros en Excel

'Seleccionarelrangodelafila.Observarlaconcatenacindelascadenasde
'Casilla_Inicialycasilla_finalquerepresentanlasdireccionesdelrangoaseleccionar
ActiveSheet.Range(Casilla_Inicial&":"&Casilla_FInal).Select

'Ponerdoblelnea
WithSelection.Borders(xlEdgeBottom)
.LineStyle=xlDouble
.Weight=xlThick
.ColorIndex=xlAutomatic
EndWith

ActiveSheet.Range(Casilla).Activate

EndSub

Bueno,estesegundoejemplo,unpocomssofisticadoessloparaqueveahastaquepuntose
puederefinar una macro. Primero construimos una macro con la grabadoraqueponiaformatoaun
rangodecasillas que siempre era el mismo, despus modificamos esta macro de manera que el rango
de casillasquepudieraformatearfueracualquiera,comotercerpaso,ademsdeconseguirlomismo
quelasegundaversin pero con menos parmetros le hemos aadido nuevas funcionalidades como
ajustar el ancho delas celdas, borrar los formatos previos, etc. Y esta macro todavia podra refinarse
ms, poner color defondoalaprimerafila,ponercoloralosdatosnumricos,etc. Lo que
intentamosdecirlees queaprovechealmximolautilidaddelagrabadorademacros,tengaperoen
cuentaquecasisiempretendrque aadir cdigo usted mismo si quiera ampliar la funcionalidad de
la macro, sobretodo si quiereaplicarleciertageneralidad.

Pgina 65

Macros en Excel

Vea el siguiente ejemplo, sirve para representar grficamente un rango de valores. La macro se ha
hechodeformasimilaralaanterior,esdecir,unavezactivadalagrabadorademacrossehanseguido
todoslospasos necesarios para disear el grfico, luego se han cambiado las referencias a hojas y
rangos porvariablesquesecolocancomoparmetrosdelprocedimientoparaasdotarledegeneralidad.

'ProcedimientoGrafico.
'Procedimientoquerepresentagrficamentelosvaloresdeunrango.
'Parmetros:
'
Hoja_Datos:Hojadondeestelrangodevalores.
'
Rango_Datos:Rangodevaloresarepresentargrficamente.
'
Titulo:Tituloparaelgrfico.
'
Eje_X:TtuloparaelejeX
'
Eje_Y:TtuloparaelejeY

SubGrafico(Hoja_DatosAsString,Rango_DatosAsString,TituloAsString,Eje_XAsString,Eje_Y
AsString)

'Aadirelgrfico
Charts.Add

'Tipodegrfico>xlColumnClustered (Columnasagrupadas)
ActiveChart.ChartType=xlColumnClustered

'Definirelorigendedatosyrepresentarlasseries(PlotBy)porfilas(xlRows)
ActiveChart.SetSourceDataSource:=Sheets(Hoja_Datos).Range(Rango_Datos),PlotBy:=_
xlRows

'Elgrficodebeponerseenunahojanueva
ActiveChart.LocationWhere:=xlLocationAsNewSheet

WithActiveChart
'Tienettulo
.HasTitle=True
'Ponerttulo
.ChartTitle.Characters.Text="VentasdeFrutas"
'TienettuloparaelejeX
.Axes(xlCategory,xlPrimary).HasTitle=True
'TtuloparaelejeX
.Axes(xlCategory,xlPrimary).AxisTitle.Characters.Text="Meses"
'TienettuloparaelejeYprincipal
.Axes(xlValue,xlPrimary).HasTitle=True
'TtuloparaelejeYprincipal
.Axes(xlValue,xlPrimary).AxisTitle.Characters.Text="Cantidades"
EndWith

'PonerlneasdedivisinparaelejedecategoriasX(horizontales)
WithActiveChart.Axes(xlCategory)
'PonerLineasdedivisinprimarias
.HasMajorGridlines=True
'Noponerlineasdedivisinsecundarias
.HasMinorGridlines=False
EndWith

Pgina 66

Macros en Excel

'PonerlneasdedivisinparaelejeY(verticales)
WithActiveChart.Axes(xlValue)
.HasMajorGridlines=True
.HasMinorGridlines=False
EndWith

'Tieneleyenda
ActiveChart.HasLegend=True

'Seleccionarleyenda
ActiveChart.Legend.Select

'Situarlaleyendaenlaparteinferior
Selection.Position=xlBottom

ActiveChart.ApplyDataLabelsType:=xlDataLabelsShowNone,LegendKey:=False
EndSub

Parafinalizar,seguroquecuandoutilicelagrabadoraapareceranmuchaspropiedadesymtodos
que desconoce, slo debe hacer clic sobre estas propiedades o mtodos y pulsar F1,
automticamente seactivarlaayudasobreesapropiedadomtodoconcreto.

InsertarfuncionesdeMicrosoftExceldesdeVisualBasic.

Copie el siguiente procedimiento y ejectelo. Es un procedimiento que sencillamente va pidiendo


nmeros y los va colocando en las celdas de la columna A partir de A1, al final coloca la funcin
=SUMAparasumarlosvaloresintroducidosylafuncin=PROMEDIOparahacerelpromediodelos
mismosvalores.

SubSumar()

DimValorAsInteger
DimCasilla_InicialAsString
DimCasilla_FinalAsString

'HaceractivalacasillaA1delahojaactiva
ActiveSheet.Range("A1").Activate
Do
'Entrarunvaloryconvertirloanumrico
Valor=Val(InputBox("Entrarunvalor","Entrada"))

'Sielvaloresdistintode0
IfValor<>0Then
'Guardarelvalorenlacasillaactiva
ActiveCell.Value=Valor
'Haceractivalacasilladelafilasiguiente
ActiveCell.Offset(1,0).Activate
EndIf
LoopUntilValor=0

Pgina 67

Macros en Excel

'Establecerlacasillainicialdelrangoasumar
Casilla_Inicial="A1"

'Establecerlacasillafinaldelrangoasumar.
'Cogerladireccindelacasillaactiva,laltima
Casilla_Final=ActiveCell.Address

ActiveCell.Offset(1,0).Activate

'PonerenlacasillaactivalafuncinSUMA
ActiveCell.Formula="=Suma("&Casilla_Inicial&":"&Casilla_Final&")"
ActiveCell.Offset(1,0).Activate
'Ponerenlacasillaactivalafuncinpromedio
ActiveCell.Formula="=Promedio("&Casilla_Inicial&":"&Casilla_Final&")"

EndSub

Una vez haya ejecutadolamacro,observequeenlasceldasdondesehancolocadorespectivamentelas


funciones=SUMA,=PROMEDIOapareceNOMBRE?(esposiblequeaparezca####,enescasoamplela
columna), esto significaque Excel noreconoce elnombre delafuncin, queno existe.Sinembargo,
estas funciones si existen y funcionan perfectamente cuando se teclean directamente sobre la hoja
declculo,sepreguntarelporqucuandosecolocandesdeunamacronofuncionan.Puesresultaque
paraquecualquierfuncindeExcel insertadadesdeunamacroNOdeerrordebeponerseconsu
nombreenIngls,latraduccinsehaceluegodeformaautomtica.Esdecirenlamacrodebeponerla
eninglsyluegocuandoestaseinserteenlahojaaparecerconsunomenclaturaenelidiomaquecorresponda.

Modifiqueelprocedimientodelejemployenlugardeponer

ActiveCell.Formula="=Suma("&Casilla_Inicial&":"&Casilla_Final&")"
Ponga
ActiveCell.Formula="=Sum("&Casilla_Inicial&":"&Casilla_Final&")"Y
ahora,enlugarde
ActiveCell.Formula="=Promedio("&Casilla_Inicial&":"&Casilla_Final&")"
Ponga
ActiveCell.Formula="=Average("&Casilla_Inicial&":"&Casilla_Final&")"

Ejecutelamacroycompruebequeahoratodofuncionacorrectamente.Observequeen lahoja,las
funcionessehaninsertadoconsunombrecorrectosegnelidioma,esdecirSUMAyPROMEDIO.

Pgina 68

Macros en Excel

Acontinuacinleexplicaremoscomopuedeaveriguarelnombredecualquierfuncinen
ingls.Utilizaremoslagrabadorademacros.Comoejemploobtendremoselnombredelas
funcin
=PROMEDIO.Deberseguirlosmismospasosparaobtenerelnombredecualquierfuncin.

1. Activelagrabadorademacros.

2. Vayaaunacasillacualquiera,C1porejemploytecleelafuncintalcomoloharaensuidioma.Por
ejemplo,ponga=PROMEDIO(A1:A10)oelnombredecualquierotrafuncinExcel.

3. Detengalaejecucindelamacro.

4. Editelamacroyobserveelnombrequesehapuesto,yaslodebeapuntrseloypasarloasu
procedimiento.Esposiblequelafuncinqueveatengaunanomenclaturaquelesuenerarayes
quelagrabadorademacrosutilizareferenciastipoRC(rowcolumn)

Pgina 69

Macros en Excel

DeteccindeErroresyDepuracindeprogramas.

Amedidaquelosprogramasvancreciendolaprobabilidaddecometererrorestambin vacreciendo.
Loserroresseclasificannormalmenteentrescategoras.

Errores en tiempo de compilacin. Son los tpicos errores que impiden hacer funcionar el programa
debido, por ejemplo, a errores de sintaxis en las instrucciones, llamadas a funciones que no existen
ollamadasconeltipooelnmerodeparmetrosincorrectos,etc.Estetipodeerroresnodan
demasiadosproblemas,primeroporqueelcompiladoravisadedondesehanproducidoyluegoporque
simplementerevisandolasintaxissesolucionanrpidamente.

Erroresentiempodeejecucin. Estos errores se producen por una mala programacin del cdigo al no
haberprevistodeterminadoscasosconcretosoespeciales,comoporejemplointentarabrirunarchivoque
noexiste,imprimirsincomprobar que la impresora est conectada, definir mal la dimensin de un array
eintentaraccederamiembrosquenoexisten,etc.Cuandoseproduceestetipodeerroressedetienela
ejecucin 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,
estudiaremos estetipoderutinasunpocomsadelante.

Erroresdefuncin. Son los ms complicados de detectar ya que ni se detectan en la fase deejecucin,ni


provocanladetencindelprograma,sondebidosalaincorrectaprogramacindealgnprocesoycomo
resultado se obtienen datos errneos. Errores de este tipo son clculos mal hechos, bucles
infinitos,devolucindevaloresincorrectos,etc.Comonilosdetectaelcompilador,niprovocanla
interrupcindelprogramadebenrevisarseamano,yclaro,sielprogramaesextensoytratamuchos
datos,sudeteccinpuede resultar dificultosa. Visual Basic, y todos los entornos de programacin
incorporanherramientasparafacilitarladeteccindeestetipodeerrores,sonlasherramientasde
depuracin.Antesdecomenzar
adescribircomofuncionanestasherramientas,lerecomendamos,unavezms,quemodularicesu
programautilizandoprocedimientoscortosquerealicentrabajosconcretosyprecisos,deestaforma
conseguir,ademsdequeelprogramaquedemseleganteyenunfuturoseamssencillomodificarlo,
evitareltenerquerevisargrandesbloquesdecdigoparadetectarerroresdeestetipo.

Herramientas dedepuracin.

Como se acaba de indicar, estas herramientas son muy tiles a la hora de testear paso a paso
elfuncionamientodelprogramaydetectarlosprocesosqueprovocanunmalfuncionamientodelmismo.

Copielosdatossiguientes enlaprimerahojadeunlibrodetrabajo,estosdatossernutilizadosporlas
funcionesqueutilizaremosparaexplicarelfuncionamientodelasherramientasdedepuracin.

1
2
3
4
5
6
7
8
9
10
11
12

Enero

Febrero

Marzo

Abril

Mayo

Junio

3406

3336

3135

2402

4345

4891

2
3
4
5
6
7
8
9
10

2754
3646
2546
3805
2709
2248
2906
3827
3897

2807
3704
4275
3533
4509
4293
4530
3538
4052

3945
3140
4370
4409
3153
3171
3336
3748
4189

4780
3236
3193
3227
4894
3834
4770
4800
3132

3352
2640
2710
3458
4801
3596
2212
3869
4016

3946
2052
2670
4917
3454
3258
4141
4896
3593

Pgina 70

Macros en Excel

Copieelcdigosiguiente,eselqueutilizaremosparaestudiaryverejemplossobrelasherramientasde
depuracin. La primera (Sub Prueba) recorre los datos de las columnashastaencontrar unavaca,esta
funcin va llamando a Recorrer_Columna, sirve para recorrer las filas de una columna hasta encontrar
una vaca, va sumando los valores que encuentra en las filas y va contando cuantas hay de llenas, al
finalllamaa la funcin Clculos, esta funcin coloca en respectivas casilla, la suma de los valores de
lacolumna,lacantidaddeceldasllenasquehaencontrado,ylamedia.Unavezhayacopiadolas
funcionesejectelas para comprobar su correcto funcionamiento antes deprocederalestudiodelas
herramientasdedepuracin.

SubPrueba()
Worksheets(1).Range("B2").Activate
'Recorrerlascasillasdeunafilahastaqueseencuentreunavaca
DoWhileNotIsEmpty(ActiveCell)

CallRecorrer_Columna
ActiveCell.Offset(0,1).Activate

Loop

EndSub

PrivateSubRecorrer_Columna()

DimSuma_ColumnaAsLong 'Sumadelosvaloresdelacolumna
DimMayor_Que_CeroAsInteger'Contarcasillasconvaloresmayoresquecero
DimDesp_FilaAsInteger'IncrementodeFila

Suma_Columna=0
Mayor_Que_Cero=0
Desp_Fila=0

'Recorrerlasfilasdeunacolumnahastaqueseencuentreunavaca
DoWhileNotIsEmpty(ActiveCell.Offset(Desp_Fila,0))

IfActiveCell.Offset(Desp_Fila,0).Value>0Then
Suma_Columna=Suma_Columna+ActiveCell.Offset(Desp_Fila,o).Value
Mayor_Que_Cero=Mayor_Que_Cero+1
EndIf

Desp_Fila=Desp_Fila+1

Loop

CallCalcular(Suma_Columna,Mayor_Que_Cero,Desp_Fila)

EndSub

PrivateSubCalcular(SumaAsLong,QAsInteger,FAsInteger)
ActiveCell.Offset(F+2,0).Value=Suma
ActiveCell.Offset(F+3,0).Value=Q
ActiveCell.Offset(F+4,0).Value=Suma/Q

EndSub

Pgina 71

Macros en Excel

Activelabarradedepuracinparaverlosbotonesqueseutilizarnenlasseccionesqueseexplican
acontinuacin(Ver/BarrasdeHerramientas/Depuracin).

ModoEjecucinpasoapasoporinstrucciones.

El modo paso a paso permite la ejecucin del programa instruccin por instruccin, de esta forma es
posibleverqueelfuncionamientodelprogramaeselcorrecto,esdecirquelaejecucindeinstrucciones
sigue los pasos que se haban previsto. Para ejecutar un procedimiento paso a paso, slo debe ir
pulsando sobre el botn
, activar la opcin de men Depuracin /Paso a Paso por
Instrucciones oirpulsandolateclaF8,queseguramenteeslomscmodo.

Ejemplo.

1. Site el cursor dentro del procedimiento


Prueba.
2. Vaya pulsando la tecla F8yvercomoseejecutaejecutaunasolainstruccinporcadapulsacin.
Puede ir alternando con la hoja de clculo para ver que es lo que ocurre cada vez que se ejecuta
unainstruccin.

Cuandoestejecutandopasoapasopuedeutilizarlosbotonessiguientesparallevaracabo
determinadasacciones.

Sirveparadetenerlaejecucindelprograma.

Sirveparaejecutarelrestodelprograma.
Sirveparaejecutartodounprocedimiento.Cuandoenlaejecucindeunprocedimiento,sellega
a una lnea que llama aotro procedimiento o funcin, pulsando este botn se puede provocar la
ejecucindetodoelcdigodeestafuncinparaluegocontinuarconelmodopasoapaso.

Ejemplo.

1. SiteelcursordentrodelprocedimientoPrueba.
2. Vayaejecutandopasoapasohastalalnea

CallRecorrer_Columna

3. En este punto pulse el botn


,observecomoseejecutatodaelprocedimiento
Recorrer_Columnapara luego continuar con la ejecucin normal de Paso a Paso. Para activar esta
opcin,tambinpuedeactivar la opcin Depuracin/ Paso a paso por procedimientos, o bien
pulsarlacombinacinMAY+F8.

Sirveparaejecutartodaslasinstruccionesdelprocedimientoactivoyvolver(oterminar).

Ejemplo.

1. SiteelcursordentrodelprocedimientoPrueba.
2. Vayaejecutadopasoapasohastalainstruccin

Mayor_Que_Cero=Mayor_Que_Cero+1

YadentrodelprocedimientoRecorrer_Columna.

Pgina 72

Macros en Excel

3. Pulsesobreelbotn
vercomoseterminalaejecucindeesteprocedimientoysevuelveal
procedimientoPruebaparacontinuarconlaejecucinpasoapaso.Paraactivarestaopcin,
tambinpuedelaopcinDepuracin/Pasoapasoparasalir,obienpulsarlacombinacin
CONTROL+MAY+F8.

ElmodoInterrupcin.

En programas largos resulta fastidioso tener que ejecutarlos paso a paso, sobretodo si sabemos que
elerror se produce en una parte avanzada del programa. El modo interrupcin, permite la ejecucin
delprograma hasta una instruccin determinada para, a partir de esta, ejecutar paso a paso y as
poderdetectarelerror.

Definirpuntosdeinterrupcin.

1. Siteelcursorsobrelainstruccinenlacualdebedetenerseelprogramaparacontinuarpasoa
paso.
2. Pulsesobreelbotn
. Tambin puede activar la opcin Depuracin/ Alternar punto de
interrupcin,pulsarlateclaF9obienhacerunclicenlaparteizquierdadelaventanadelmdulo
(lafranjaverticalencolorgris).

Paradesactivarunpuntodeinterrupcinsigalosmismospasos.

Solucionarloserrores.

Todo lo dicho anteriormente no servira de gran cosa si no fuera posible revisar los valores que las
variablesvancogiendoamedidaquevamosavanzandoosinotuviramosocasindeevaluarlas
expresionesdelprograma.Enlassiguientesseccionesveremoscomollevaracaboestasacciones.

Inspeccionesrpidasdevariables.

Estasopcionessirvenpararevisarelvalordelasvariablesamedidaquesevaejecutandoelprograma.
Paraverlosvaloresquevantomandolasvariablesesconveniente tener visible la Ventana de
inspeccin,paraactivarlaVer/VentanadeInspeccinopulsesobreelbotn

Aadirunavariablealaventanadeinspeccin.

Aunquenoesnecesarioestarejecutandoelprogramaenmodopasoapaso,esconveniente.

1. Seleccionelavariablequedeseeaadiralaventanahaciendounclicsobreella.
,tambinpuedeactivar Depuracin/ Inspeccin rpidaopulsarla
2. Pulsesobreelbotn
combinacin MaY+F9.Apareceuncuadrodedilogodondesemuestraelvaloractualdela
variable.Sinoestejecutandoelprogramapasoapaso,aparecerelvalorFueradeContexto.
3. PulsesobreelbotnAgregarparaaadirlavariablealaventanadeinspeccin.

Debetenerencuentaquepararevisarlasvariableslasexpresionesquelesasignanvaloresdeben
deejecutarsealmenosunavez.

Pgina 73

Macros en Excel

Ejemplo.

1. Siteunpuntodeinterrupcinenlalnea.

Mayor_Que_Cero=Mayor_Que_Cero+1

2. Ejecuteelprograma,cuandoestesedetengaenelpuntodeinterrupcin,siteelcursorsobre
lavariableSuma_Columna(puedeponerloencualquierparte).

3. Pulsesobreelbotn.
4. PulsesobreelbotnAgregarparaquelavariableseinserteenlaventanaInspecciones.

RepitalospasosanterioresparalasvariablesMayor_Que_CeroyDesp_Fila

5. Vayaejecutandoelprogramapasoapasoyobservecomovacambiandoelvalordelasvariables
enlaventanadeinspeccin.

Recuerdequepuedeagregarunavariablealaventanadeinspeccinaunquenoest
ejecutandoelprograma.

**Suponemosqueyasehabrdadocuentaquecuandoejecutaelprogramapasoapaso,
sisitaelpunteroderatnsobreunavariable,semuestraelvalordelamisma.

BorrarunavariabledelaventanadeInspeccin.

SlodebeseleccionarlaenlaventanadeinspeccinypulsarsobrelateclaSUPR.

Modificarelvalordeunavariableentiempodeejecucin.

Avecesresultainteresantecambiarelvalordealgunavariablecuandoseestejecutandoel
programa,paraverqueocurresicogedeterminadosvalores,paraterminarunbucle,etc.

Ejemplo.

1. Site un punto de interrupcin en la


lnea.

Mayor_Que_Cero=Mayor_Que_Cero+1

2. Agreguealaventanadeinspeccin(sinoest)lavariableSuma_Columna.
3. Ejecuteelprograma,aldetenerse,observeenlaVentanadeInspeccinquelavariable
Suma_Columnatieneunvalorqueahoracambiaremos.
4. HagadobleclicsobreelvalordeSuma_Columnadentrodelaventanadeinspeccin.
5. Borreelvalorquetiene,cmbieloporotroypulseENTER.
6. Ahora puede continuar con la ejecucin normal del
programa.

ExpresionesdeRevisin.

AdemsdepermitiraadirunavariableoexpresindentrodelaVentanaInmediato,una Expresin de
Revisinpermiteinterrumpirlaejecucindelprogramacuandounavariablecogedeterminadovalor.
Piense que muchas veces un programa deja de funcionar, o funciona mal cuando una variable
cogedeterminados valores. Con una expresin de revisin, podremos detener la ejecucin del
programacuandounavariablecontienedeterminadovalor(apartiededeterminadovalor),luego,

Pgina 74

Macros en Excel

podremoscontinuarconlaejecucinpasoapasoparaverqueocurreapartirdeestepunto.

Pgina 75

Macros en Excel

Ejemplo.

En el ejemplo que veremos a continuacin, haremos que el programa se interrumpa cuando la


variable
Suma_Columnaalcanceunvalorsuperiora30000.

1. SiteelcursorsobreelnombredelavariableSuma_Columna,puedeescogercualquier
posicindondeaparecelavariable.
2. ActivelaopcinDepuracin/AgregarInspeccin.Apareceelsiguientecuadrodedilogo,

Expresin:Variableoexpresinquesedeseaevaluar.

Procedimiento:Aqusedescribeelprocedimientodondedebeevaluarselavariable,estosignifica
queelmbitodecomprobacindelavariableesslodentrodeesteprocedimiento.Imagineque
tienedosomsprocedimientosdondeutilizaunavariableconelmismonombre,obienquetiene
unavariableglobal,aquseindicaenqueprocedimientodebehacerselaevaluacin.

Mdulo. Lo mismo que en apartado procedimiento pero a nivel


mdulo.

Expresinde inspeccin.Activandoestaopcin,indicamosquelonicoquedeseamoshaceres
incluirlavariableoexpresindentrodelaventanadeexpresin.

Mododeinterrupcincuandoelvalorseaverdadero. Indicamos que cuando la expresin


indicadaencuadrodetextoExpresin:seacierta,debedetenerseelprograma.

Modo de interrupcin cuando el valor cambie. El programa se detendr cuando la expresin


cambiedevalor.

Para nuestro ejemplo rellene con los datos


siguientes.

Expresin:Suma_Columna>30000
Procedimiento:Recorrer_Columna
Mdulo: Mdulo1(ocomosellamesumdulo).
ActiveMododeinterrupcincuandoelvalorseaverdadero.

3. PulsesobrebotnAceptar.

Pgina 76

Macros en Excel

Ejecuteelprograma.ObservequeelprogramaseinterrumpecuandoSuma_Columna coge un valor


superior a 30000, a partir de este podramos continuar con la ejecucin paso a paso y ver
comoevolucionaelvalordelavariableovariables.

Pgina 77

Macros en Excel

LaVentanaInmediato.

Es otra forma de inspeccionar variables cuando el programa est en modo interrupcin (ejecutndose
pasoa paso), pero adems, ofrece la posibilidad de cambiar valores de las variables e incluso ejecutar o evaluar
expresiones.Paraverelvalordeunavariableenlaventanainmediatodebeanteponerleun?yluego
pulsarEnter.

ParaactivarlaventanaInmediato,activeopcinVer/Inmediato,opulselacombinacinCONTROL+G.

Ejemplo.

En el siguiente ejemplo, utilizaremos la ventana Inmediato para ver el valor de las variables
Suma_Columna, Mayor_Que_CeroyDesp_Fila. Tambin cambiaremos el valor de una de ellas y
comprobaremosunaexpresin.

1. ActivelaventanadeInmediato.Ver/VentanaInmediato.
2. Site un punto de interrupcin en la
instruccin

CallCalcular(Suma_Columna,Mayor_Que_Cero,Desp_Fila)

3. Ejecuteelprograma,estedebedetenersecuandolleguealainstruccinindicadaenpaso
2.
4. Entre en la ventana inmediato, haga las pruebas
siguientes.

Escriba
?Suma_Columna
?Mayor_Que_Cero
?Desp_Fila

Pruebelaexpresinsiguiente.Enestecasoconcretosolosirveparaverqueesunaposibilidad.

X=Suma_Columna /Mayor_Que_Cero
?X

Paraterminar,cambiaremoselvalordelavariableSuma_Columnaycontinuaremosla
ejecucinnormaldelprograma.

Suma_Columna=2350000

5. Quite el punto de interrupcin y termine la ejecucin del


programa.

LainstruccinDebug.Print.

Estainstruccin,queseutilizadirectamentesobreelcdigodelprograma,permitevertodoslosvalores
quehaidocogiendounavariableoexpresindurantelaejecucindelprograma.Losvaloressemostrarn
en la ventanaInmediatounavezfinalizadoelprograma.Estaexpresinresultatilenunafaseavanzada
dedepuracinyaquepermiteirviendolaevolucindeunavariableoexpresinsinnecesidaddeponer
puntosdeinterrupcin.Evidentementecuandoelprograma estlistodebendesacarse.

Ejemplo.

MediantelainstruccinDebug.PrintveremoslaevolucindelavariableSuma_Columna.

Pgina 78

Macros en Excel

1. Siteelcursordespusdelainstruccin

Suma_Columna=Suma_Columna+ActiveCell.Offset(Desp_Fila,0).Value

Escriba:Debug.Print"DentrodelBucle:"&Suma_Columna.

Pgina 79

Macros en Excel

2. SiteelcursordespusdelainstruccinLoopyescriba

Debug.Print"

FueradelBucle:"&Suma_Columna.

3. Ejecute el programa (sin puntos de


interrupcin).

Una vez terminada la ejecucin, observe loque hay escrito en la ventana inmediato. A veces, resulta
interesante controlar en que pasos la variable ha ido cogiendo determinados valores, para hacer
estodeberndeclararselascorrespondientesvariablesquehaganlasfuncionesdecontador.

Ejemplo.

Haremos lo mismo que en el ejemplo anterior pero indicando los pasos de bucle y las llamadas al
procedimientoRecorrer_Columna.

DeclareanivelglobalalvariableContar_LlamadasdetipoInteger.

DeclaredentrodelProcedimientoRecorrer_ColumnalavariablePasos_De_Bucledetipo
Integer.

Inicialicea1lavariableContar_LlamadasdentrodelafuncinPrueba,hgaloantesdela
instruccinDoWhile.

DebajodelainstruccinActiveCell.Offset(0,1).Activateponga
Contar_Llamadas=Contar_Llamadas+1

Inicialicea1lavariablePasos_De_BucledentrodelprocedimientoRecorrer_Columna,hgalo
antesdelainstruccinDoWhile.

DebajodelainstruccinDesp_Fila=Desp_Fila+1,ponga
Pasos_De_Bucle=Pasos_De_Bucle+1

CambielasexpresionesDebug.Printpor,

Debug.Print"PasodeBucle:"&Paso_De_Bucle&"Suma_Columna="&
Suma_Columna

Debug.Print"
Suma_Columna

Llamada:"&Contar_Llamadas&"Suma_Columna="&

EjecuteelprogramayobservelasalidaenlaventanaInmediato.

Por supuesto cuando el programa est terminado y comprobado deber quitar todas las
instrucciones
Debug.Print

Y con esto terminamos el tema de la depuracin. Insistimos en la importancia de estas herramientas


nosloalahoradelocalizarerroresde programacin sino tambin a la hora de comprobar la evolucin
delprograma cuando se dan determinadas condiciones. Djenos acabar el tema insistiendo de nuevo
enlaimportanciaquemodularicesusprogramas,observequesilohace,tambinleresultar
muchomssencillodetectarerroresdeprogramacin.

Pgina 80

Macros en Excel

ErroresdeEjecucin.

Esimposibleexcluirdeltodoloserroresenlosprogramas.Siadems,ycomoesdedesear,elprograma
ser utilizado por usuarios que no han tenido nada que ver en el proceso de desarrollo e implementacin
posiblemente (seguramente) se producirn errores debido a su incorrecta utilizacin. Estos errores son
losque se deben prevenir. Errores de este tipo son, por ejemplo, intentar acceder a un archivo
inexistente,entrar valores incorrectos a travs de un cuadro de dilogo o formulario (datos tipo String
cuando se requieren nmeros,...). Tambin entraran en este tipo de errores aquellos casos
excepcionalespero quedeben ser previstos por el programador, como por ejemplo que se llene la
unidad de disco, que laimpresorasequedesinpapel(esteyanoestanexcepcional),etc.

VisualBasicylamayoradelenguajesdeprogramacinpermitenimplementarrutinasdetratamientode
errores cuya finalidad es interceptar determinados tipo de errores que se producen en tiempo de
ejecucin. La finalidad de estas rutinas es que el programa no se detenga, o al menos si se detiene,
informar sobre laposible causa del error e intentar controlarlo de alguna forma. Estudiaremos a
continuacin como serealizaestoenvisualbasic.

Copieelmdulosiguiente,serelqueutilizaremosenlosejemplos.Esunsimpleprocedimientoque
pidedosvaloresalusuario,lossumaylosguardaenlaceldaA1deHoja2.

OptionExplicit

SubPrueba()

Dimn1AsInteger
Dimn2AsInteger
DimtotalAsInteger

n1=InputBox("Entrarunvalor","Entrada")
n2=InputBox("Entrarotrovalor","Entrada")

total=n1+n2

Worksheets("Hoja2").Range("A1").Value=total

EndSub

Pgina 81

Macros en Excel

Rutinasdetratamientodeerrores.

Generalmenteunarutinadetratamientodeerroresreaccionaantecasosesperadosporelprogramador.
Enel ejemplo que nos ocupa, podra ser que el usuario entrara caracteres en lugar de nmeros por lo
queelprogramageneraraelerrorsiguiente.

Mediante una rutina de tratamiento de errores informaremos del error que se ha producido y
direccionaremos la ejecucin del programa hacia donde interese. En visual basic el tratamiento de
erroreses una parte normal de la ejecucin del programa. Lainstruccinparaeltratamientodeerrores
es ON ERROR GOTO lnea, lnea es una etiqueta o marca de lnea que indica hacia donde debe
dirigirse elprograma en caso de error. El formato general de un procedimiento o funcin donde se
implementaunarutinadetratamientodeerroreseslasiguiente.

Subprueba()

OnErrorGOTOTratar_errores

'Instruccionesdelprocedimiento

ExitSub'Salirdelprocedimiento

Tratar_Errores:
'Instruccionesdetratamientodeerror

EndSub.

Con On Error GOTOTratar_Errores, indicamos al programa que en caso que se produzca un error en
tiempodeejecucinvayaaejecutarlaslneasquesiguenalaetiquetaomarcadelnea Tratar_Errores.
ObservequeantesdelaetiquetaTratar_Errores hay la instruccin Exit Sub, sirve para que si el
procedimientosehadesarrolladocorrectamente,salgaenesepunto,tengaencuentaquesinosepusiera
estalnealaejecucincontinuarasecuencialmenteyseejecutaranlaslneasdelarutinaTratar_Errores.
Silarutinadetratamiento de errores se implementa en una funcin debe poner Exit Functionen lugar de
ExitSub.

Pgina 82

Macros en Excel

Escribircdigodetratamientodeerrores.

Enesteprimerejemploharemosalgomuysimple,mostrarinformacinsobreeltipodeerrorqueseha
producido y detener la ejecucin del programa. Vale, esto es lo que hace ya Visual Basic sin necesidad de
implementarnada,peronosservirparaintroducirelobjetoErr.

ElobjetoErr.

Siempre que se produce un error en tiempo de ejecucin Visual Basic genera (o dispara como dicen
algunos autores) un objeto tipoErr, estudiaremos dos propiedades de este objeto Numbery Description.
Number es un nmero indicativo sobre el tipo de error que se ha producido, dicho de otra forma,
cuandovisual basic dispara un objeto Err en tiempo de ejecucin, podemos revisar su propiedad
Number parasaberqueesloquehacausadoelerror.Descriptiones el mensaje asociado al nmero de
error y es una cadena de texto que describe brevemente el error. Ahora en nuestro ejemplo,
implementaremos una rutinade error que muestre el nmero de error y su descripcin, insistimos que es lo
que hace visual basic por sislo, pero luego veremos como gracias al nmero de error podremos
determinar la causa del error y controlar la ejecucin del programa como ms convenga. El
procedimiento quedara de la siguientemanera.

SubPrueba()

OnErrorGoToTratar_Errores

Dimn1AsInteger
Dimn2AsInteger
DimtotalAsInteger

n1=InputBox("Entrarunvalor","Entrada")
n2=InputBox("Entrarotrovalor","Entrada")

total=n1+n2

Worksheets("Hoja2").Range("A1").Value=total

ExitSub

Tratar_Errores:

MsgBox("NmerodeError:"&Err.Number&Chr(13)&"Descripcin:"&Err.Description)

EndSub

EjecuteelprocedimientoanteriorycuandoselepidaelprimernmeroentreelTexto"Hola".Observe
que como se ha producido un error, el programa salta hacia la rutina de tratamiento de errores y
muestraelnmerodeerrorysudescripcinasociada.

Continuarelprogramadespusdelaejecucindelarutinadetratamientodeerrores.

En la mayora de los casos, las rutinas de tratamiento de errores son para que el programa no se
detenga.Elprocesohabitualcuandoseproduceelerrorestratardecorregirloycontinuarlaej
ecucin delprograma. La continuacin del programa se consigue mediante la instruccin Resume. Esta
instruccinda tres posibilidades,Ejecutarotravezlainstruccinquehacausadoelerror,continuar por la
instruccinsiguientealaquehacausadoelerrorodirigirlaejecucinhaciaunalneamarcadaconunaetiqueta.

Pgina 83

Macros en Excel

Resume. Ejecutar de nuevo la instruccin que ha causado el


error.

Esto,ennuestrocaso,seravolverapreguntardenuevoelvalor.Larutinadetratamiento
deerroresquedara.

Tratar_Errores:

MsgBox("NmerodeError:"&Err.Number&Chr(13)&"Descripcin:"&
Err.Description)
Resume

Podramoscambiarelmensajequeveelusuarioparahacerlomscompresivo.La
rutinaquedara.

Tratar_Errores:

MsgBox("Debeentrarunvalornumrico")
Resume

Resume Next. Continuar el programa por la instruccin siguiente a la que ha causado el


error.

Tratar_Errores:

MsgBox("Debeentrarunvalornumrico")
ResumeNext

Enestecasoelprogramainformaradelacausadelerrorperocontinuaralaejecucinporla
lneasiguientealaquehacausadoelerror.Noesunabuenasolucinparaestecasoperolos
hayenlosqueeslamejor.

ResumeETIQUETA.ContinuarporlainstruccinquesiguealaETIQUETA.

Haremosqueelprogramavuelvaalprincipiocuandoseproduzcaunerror.Paraellodebemosponeruna
etiqueta o marca de lnea mediante la cual indicaremos en que punto debe continuar la ejecucin
delprograma.ObservequehemospuestolaetiquetaInicio:alprincipiodelprocedimiento.Evidentemente
nosiempretienequeempezardesdeelprincipio,puededirigirselaejecucinhaciadondemsconvenga.

SubPrueba()

OnErrorGoToTratar_Errores

Dimn1AsInteger
Dimn2AsInteger
DimtotalAsInteger

Inicio: 'Aquvuelveelprogramasiseproduceunerror

n1=InputBox("Entrarunvalor","Entrada")
n2=InputBox("Entrarotrovalor","Entrada")

total=n1+n2

Worksheets("Hoja2").Range("A1").Value=total

Pgina 84

Macros en Excel

ExitSub

Pgina 85

Macros en Excel

Tratar_Errores:

MsgBox("Debeentrarunvalornumrico")
ResumeInicio

EndSub

Llegados a este punto ya sabemos como controlar errores simples y como redirigir la ejecucin del
programa. Ahora, pruebe lo siguiente, ejecute el programa y cuando se le pida el primer valor, ponga
50000.

Efectivamente,seproduceunerror,50000noesunvalorvlidoparadatostipoInteger,recuerdequeel
rango para los datos tipo Integer es de32768 a 32767. Observe que la rutina continua tratando el error
ypidiendodenuevolosdatos, peroelmensajequever el usuario continuar siendo "Debe entrar un
valor numrico ", cosa que seguramente le dejar perplejo. Con esto hemos pretendido que vea que
puede haberms de una causa que provoque error, consecuentemente las rutinas de tratamiento de
errores debernprevenirmsdeunerror.Enestenuevocasoelerrorloproduceundesbordamiento,
cuyo nmero deerror es el 6. Suponemos que ahora ya se habr dado cuenta de la importancia del
nmero de error yaqueestenospermitirtratardentrodelarutinadiferentescasosdeerrorconlainstruccin
SelectCase.

Nuestroejemploquedara.
SubPrueba()
OnErrorGoToTratar_Errores

Dimn1AsInteger
Dimn2AsInteger
DimtotalAsInteger

n1=InputBox("Entrarelprimervalor","Entrada")
n2=InputBox("Entrarelsegundovalor","Entrada")

total=n1+n2

Worksheets("Hoja2").Range("A1").Value=total

ExitSub

Tratar_Errores:

SelectCaseErr.Number
Case13:
MsgBox("Debeintroducirvaloresnumricos")
Case6:
MsgBox("Elvaloresdemasiadograndeodemasiadopequeo. "&_
"Elnmero"debeestarcomprendidoentre32768y32767")
EndSelect
Resume

EndSub

Se estar preguntando si todava se pueden producir ms errores. La respuesta es que por supuesto que s
,porejemplo,vayaalprocedimientoypruebeponerHoja22enlugardeHoja2enWorkSheets(..).
Recomendamosqueterminesiemprelarutinadeerroresconuncaseelsedelaformasiguiente,

Pgina 86

Macros en Excel

Tratar_Errores:
SelectCaseErr.Number
Case13:
MsgBox("Debeintroducirvaloresnumricos")
Case6:
MsgBox("Elvaloresdemasiadograndeodemasiadopequeo."&_
Elnmerodebeestarcomprendidoentre32768y32767")
CaseElse
MsgBox("Errornoprevisto.Llamealresponsablefacilitandola"&_
"informacinquesigue"&Chr(13)&"NmerodeError:"&_
Err.Number&Chr(13)&"Descripcin:"&Err.Description)
ExitSub'Oloquesea

EndSelect
Resume'Oloquesea

Esdecir,siseproducecualquierotroerrornoprevisto,seinformaalusuarioqueaviseaquien
procedainformandodelnmerodeerrorysudescripcin.

...No se vayan todava, an hay ms. La cosa se complica cuando en un programa se definen mltiples
procedimientos y funciones, cada una de ellas puede tratar sus propios errores, pero Qu pasa si el
error se provoca debido a los valores que pasa la funcin que llama ? o Cmo continuar la ejecucin fuera del
procedimiento?,esdecirenelprocedimientoquellamaalquehaprovocadoelerror.Copielos
procedimientossiguientesmedianteloscualesestudiaremosdiferentescasos.

SubPrueba()

OnErrorGoToTratar_Errores

Dimn1AsInteger
Dimn2AsInteger
DimTotalAsInteger

n1=InputBox("Entrarelprimervalor","Entrada")
n2=InputBox("Entrarelsegundovalor","Entrada")

CallPoner_Calculo(n1,n2,2)

ExitSub

Tratar_Errores:
SelectCaseErr.Number
Case13:
MsgBox("Debeintroducirvaloresnumricos")
Case6:
MsgBox("Elvaloresdemasiadograndeodemasiadopequeo."&_
Elnmerodebeestarcomprendidoentre32768y32767")
CaseElse
MsgBox("Errornoprevisto.Llamealresponsablefacilitandola"&_
"informacinquesigue"&Chr(13)&"NmerodeError:"&_
Err.Number&Chr(13)&"Descripcin:"&Err.Description)
ExitSub'Oloquesea

EndSelect
Resume'Oloquesea

Pgina 87

Macros en Excel

EndSub

Pgina 88

Macros en Excel

PrivateSubPoner_Calculo(n1AsInteger,n2AsInteger,Numero_HojaAsInteger)

DimTotalAsInteger

Total=n1+n2

Worksheets(Numero_Hoja).Range("A1").Value=Total

EndSub

Una vez entrados los valores en el procedimientoPrueba se llama aPoner_Calculo, simplemente suma
losdosvaloresylosasignaaunahojadellibrodetrabajo(observequelahojavieneindicadaporel
parmetroNumero_Hoja).

Observe que el procedimiento Poner_Calculo no tiene rutina de tratamiento de errores, puede pensar
quesi se produce un error dentro de l se detendr el programa, pero no es as. Si se produce un error
dentrodel procedimiento Poner_Calculo el programa pasa a ejecutar la rutina de tratamiento de errores
definidadentro de Prueba, esto algunas veces (pocas) puede ser lo que conviene, pero compruebe
el efectoindeseablequeocurreaqu.

Ejecute el programa e introduzca los valores siguientes n1=25000 y n2=20000, los dos valores entran
dentrodelrangodelosdatosInteger, pero su suma 45000 no, se producir un error de desbordamiento
enla instruccin Total = n1 + n2 del procedimiento Poner_Calculoyseprocedera ejecutar
lasinstrucciones de la rutina de error definida en el procedimiento Prueba; aqu,despus demostrar el
error,se vuelve a ejecutar la instruccin Total =n1+n2 debidoa lainstruccinResume y el programa
entraenun bucle infinito yaquenoesposiblecambiarlosvaloresden1yn2.Lasolucinaques
sencilla,slodebe cambiarResumepor ResumeNextoResumeEtiqueta.Otraposibilidadesimplementar
una rutina de tratamiento de errores dentro del procedimiento Poner_Calculo, o simplemente
desactivar la rutina detratamientodeerroresantesdellamaralprocedimientomediantelasinstruccin OnError
Goto0.

OnErrorGoto0'Desactivareltratamientodeerrores
CallPoner_Calculo(n1,n2,2)

EstoltimoconllevalaconsecuenciaquesiseproduceunerrordentrodelprocedimientoPoner_Calculo
el
programa
se
detendr.

Muchasvecesestetipodeerrores se pueden controlar mejor utilizando una variable global. Esta variable
permitirrecogerelerrorquesehaproducidoenlafuncinparaluegotratarlocuandolaejecucindel
programavuelvaalafuncinllamadora.Observecomoquedaranuestroejemplo.

OptionExplicit

DimgErrorAsInteger 'Variablequerecogernmerosdeerror

SubPrueba()

OnErrorGoToTratar_Errores

Dimn1AsInteger
Dimn2AsInteger
DimTotalAsInteger

n1=InputBox("Entrarelprimervalor","Entrada")
n2=InputBox("Entrarelsegundovalor","Entrada")

Pgina 89

Macros en Excel

CallPoner_Calculo(n1,n2,2)
IfgError<>0Then'SialvolverdelafuncingError<>0>Errordentrodelafuncin
MsgBox("ErrorenlaFuncinPonerClculo."&Chr(13)&gError)
ExitSub'Oloquesea
EndIf

ExitSub

Tratar_Errores:
SelectCaseErr.Number
Case13:
MsgBox("Debeintroducirvaloresnumricos")
Case6:
MsgBox("Elvaloresdemasiadograndeodemasiadopequeo."&_
Elnmerodebeestarcomprendidoentre32768y32767")
CaseElse
MsgBox("Errornoprevisto.Llamealresponsablefacilitandola"&_
"informacinquesigue"&Chr(13)&"NmerodeError:"&_
Err.Number&Chr(13)&"Descripcin:"&Err.Description)
ExitSub'Oloquesea

EndSelect
Resume'Oloquesea

EndSub

PrivateSubPoner_Calculo(n1AsInteger,n2AsInteger,Numero_HojaAsInteger)

OnErrorGoToTratar_Errores2

DimTotalAsInteger

gError=0
Total=n1+n2

Worksheets(Numero_Hoja).Range("A1").Value=Total
ExitSub

Tratar_Errores2:

Error=Err.Number'SihayerrorgErrorrecogeelnmerodeerror

EndSub

El funcionamiento aqu es bastante simple. Se construye una rutina de tratamiento de errores dentro de
lafuncin que simplemente asigna el nmero de error ala variable gError, cuando se devuelve el control al
procedimiento llamador se inspecciona esta variable y si su valor es distinto de 0 se debe tratar el
error(enelejemplosimplementeseterminaelprograma,porsupuestoeltratamientopodrasediferente).

Pgina 90

Macros en Excel

Definirerrorespropios.

Visual Basicincorpora la instruccinError conlaqueesposibledefinirogenerarerrorespropios.Puede


que se est preguntando para que quiere definirse errores propios, dicho de otra forma, para que
provocarerrores propios. Bueno, pues por ejemplo, para un mayor control en programas largos y
complejos,paravalidardatos,yalgunosprocesosms.

Para provocar un error simplemente tiene que utilizar la instruccin Error(Numero_De_Error),


Numero_De_Error debe ser unvalorcomprendidoentre0y65535,esdecirdebeestardentrodelrango
de errores definidos por Visual Basic, ahora bien, utilice siempre valores altos ya que si no, corre el riesgo
demodificarunvaloryaestablecidoporVisualBasic.Lerecomendamosque empiece a partir del valor
65535yvayabajando, estosvalorestanelevadosnuncasernutilizadosporVisualBasic.

Vea el siguiente ejemplo, es un caso en los que puede resultar interesante provocar un error. Es el
ejemploquehemosutilizadoenla seccin,elprogramapidetresvalores,luegollamaalafuncin
Poner_Calculodonde se suman n1 y n2 y el resultado se divide por n3. Observe que se ha definido
una rutina detratamientodeerroresquesegnelerrorquesehayaproducidodentrodelafuncin,
asigna un valor a lavariable globalgError(ahora definida como tipo Long). Cuando el programa vuelve
al procedimientoPrueba se comprueba el valor de gError, si es distinto de 0, se provocar un error
Error(gError), elprograma salta entonces a la rutina de tratamiento de errores definida dentro del
procedimiento dondegracias a los valores de error asignados sabemos quetipodeerrorseha
producidoyenquefuncinoprocedimientoseprodujo.

OptionExplicit

DimgErrorAsLong'Variablequerecogernmerosdeerror

SubPrueba()

OnErrorGoToTratar_Errores

Dimn1AsInteger
Dimn2AsInteger
Dimn3AsInteger
DimTotalAsInteger

n1=InputBox("Entrarelprimervalor","Entrada")n2
=InputBox("Entrarelsegundovalor","Entrada")n3
=InputBox("EntrarelTercervalor","Entrada")

CallPoner_Calculo(n1,n2,n3,25)
IfgError<>0Then'SialvolverdelafuncingError<>0>Errordentrodelafuncin
Error(gError)'GenerarError
EndIf

ExitSub

Pgina 91

Macros en Excel

Tratar_Errores:
SelectCaseErr.Number
Case13:
MsgBox("Debeintroducirvaloresnumricos")
Case6:
MsgBox("Elvaloresdemasiadograndeodemasiadopequeo."&_
"Elnmerodebeestar comprendidoentre32768y
32767")
Case65535:
MsgBox("SeprodujounerrorenlafuncinPonerCalculo."&_
"Nmerodemasiadograndeparaunentero")
Case65534:
MsgBox("SeprodujounerrorenlafuncinPonerCalculo."&_
"Divisinporcero")
Case65533:
MsgBox("SeprodujounerrorenlafuncinPonerCalculo."&_
"NmerodeHojanoexiste")
CaseElse
MsgBox("Errornoprevisto.Llamealresponsablefacilitando"&_
lainformacinquesigue"&Chr(13)&"NmerodeError:"&_
Err.Number&Chr(13)&"Descripcin:"&Err.Description)Exit
Sub'Oloquesea
EndSelect
ResumeNext'Oloquesea

EndSub

PrivateSubPoner_Calculo(n1AsInteger,n2AsInteger,n3AsInteger,Numero_HojaAsInteger)

OnErrorGoToTratar_Errores2

DimTotalAsInteger

gError=0

Total=n1+n2
Total=Total/n3

Worksheets(Numero_Hoja).Range("A1").Value=Total
ExitSub

Tratar_Errores2:

SelectCaseErr.Number
'Valordemasiadogrande
Case6:
gError=65535

'Divisinporcero
Case11:
gError=65534

'Subndicefueradelintervalo(Nmerodehojanoexiste)
Case9:
gError=65533

Pgina 92

Macros en Excel

'OtroError
CaseElse
gError=Err.Number
EndSelect

EndSub

Y con esto terminamos el captulo de depuracin de programas y tratamiento de errores. Utilice


estosmecanismossiemprequesusprogramasvayanaserusadospor otras personas. Con la depuracin
podr,ademsdedetectarerroresmsfcilmente,comprobarcomoelprogramaensituaciones
extremas(ycranos,silohandeutilizardiferentesusuariosseproducirn).Conlasrutinasde
tratamientodeerrorespodr controlar muchos de ellos, y si se produce uno de imprevisto, al menos le
ser ms fcil localizarloosaberlascausasquelohanprovocado.

Finalmenteycomoopininpersonal,siconocelenguajescomoDelphioJavaoalgndatrabajacon
elloscomprobarqueelcontroldeerroresestmuchomejoracabadoqueconVisualbasic.Convisuala
unosiemprelequedalasensacindequealgoquedasuelto,ycosascomolossaltosdeResume
Etiquetadejansiempreciertaintranquilidad.

Controlesdeformularioenlahojadeclculo.

En este tema estudiaremos como insertar controles (botones, cuadros de texto, cuadros de lista,
botonesderadio,etc.)dentrodeunahojadeclculo.Seguramenteesmshabitualutilizarestetipode
controlesdentro de formularios y a travs de ellos gestionar datos de una o varias hojas, sin
embargo resultaconveniente muchas veces incluir directamente estos controles dentro de una misma
hoja, sobre todocuandosloserequiereprocesossimplescomoelegirdatosdeunalistaoactivar
unamacrodesdeunbotn,etc.

Noestudiaremosenprofundidadestoscontroles,simplementeutilizaremoslaspropiedades
mshabituales (concretamente las que necesitemos), dejaremos un estudio ms completo para el tema
delosformularios.

Aplicacindeejemplo.

Paraverelfuncionamientodelosdistintoscontroles,construiremosunapequeaaplicacinquenossirva
para gestionar una pequea tabla de registros, bsicamente extraer datos que cumplan una
determinadacondicin.Lamayoradefuncionesqueaplicaremospuedenhacersedirectamentedesdelas
utilidadesdelmen Datos/ Filtro avanzado que lleva incorporado el propio Excel pero creemos que
ser un buenejemploparaverlasposibilidadesdeloscontroles.

AbrasuaplicacinExcelyactivelahojadeclculoLista7.xls quedebibajarjuntoaestedocumento,en
laprimerahojaestlalistaderegistrosqueutilizaremosenlosejemplosqueveremosacontinuacin.
EnlaHoja2seencuentraralgunosdatosnecesariosparaloscontroles.

Mostrarlabarradeherramientasparacuadrosdecontrol.

Obviamenteparainsertarcontrolesenlahojadeberteneractivadalabarradecontroles.Active
Ver/BarrasdeHerramientas/CuadrodeControles.Deberactivarseunabarracomolasiguiente.

Pgina 93

Macros en Excel

CuadrodetextoyBotn.

Lo primero que haremos es algo muy sencillo, simplemente copiaremos en Hoja2, los datos
correspondientes a los registros de Hoja1 cuyos datos correspondientes a la columna Nombre
coincidancon el que teclearemos en una cuadro de texto que insertaremos en Hoja2. Los datos se
copiaran a partirdelaceldaA16.Elbotnsimplementeservirparainvocarlamacroquecopiarlosdatos.

Insertarelcuadrodetexto.

Slotienequeseleccionarelelemento
delabarradecontrolesydibujarlosobrelahoja(Hoja2
ennuestroejemplo,procurequecojamsomenoselrangocorrespondientealasceldasC2yD2.

Insertarunaetiqueta.
Lasetiquetassirvenbsicamenteparaacompaarloscontrolescontextodescriptivo.Seleccioneel
botn

ydibujeenlahojaelrectnguloparainsertarlaetiqueta,pngaloalladodelcontrolcuadro

detexto.

Pgina 94

Macros en Excel

InsertarunBotn.

Losbotonesseutilizanbsicamenteparainvocarlasmacrosquerealizarnlasacciones.Noesel
nicocontrolquepuedeinvocarmacros,cualquieradeloscontrolespuedeinvocarla,peroeselms
habitual.

Cambiarlaspropiedadesdelosobjetos.

Acontinuacindesplegaremoslaventanadepropiedadesparacambiaralgunasdelosobjetos
acabadosdeincrustar.Debeestarenmododiseo,elbotn

deestaractivado.

CambiareltextodelcontrolLabel.PropiedadCaption.

1. SeleccioneelcontrolEtiqueta.
delabarradecontroles,seactivalaventanadePropiedades.
2. Pulsesobreelbotn
3. EnlapropiedadCaption,cambieneltextoLabel1porDatosaBuscar.
4. Ajustelaposicinyeltamaodelcontrol.

CambiarelnombredelcontrolCuadrodeTexto.PropiedadName.

No es necesario cambiar el nombre de los controles pero si muy conveniente, tenga en cuenta que a
travsde los nombres de un control ser como se refiera a ellos a travs de las macros. Siempre es mejor
llamara un control por un nombre descriptivo que por Text1 o Command1, etc.Al controlcuadrode
textolepondremoselnombreDatos_Buscar.

1. SeleccioneelcontrolCuadrodeTexto.
2. Sinotieneactivadalaventanadepropiedades,actvela.
3. EnlapropiedadName,cambieeltext1porDatos_Buscar.

.Cambielapropiedad CaptindelBotnproCopiarDatosysupropiedad Name porCopiar_Datos


(debeponerelguinbajoyaquelapropiedadNamenopermiteespaciosenblanco).

Establecerlaaccindecopiardatoscuandosepulseelbotn.

A continuacin crearemos la macro que ser invocada cuandosepulseelbotn.Lamacro


simplementedebe buscar en la columna A de la lista de Hoja1 el nombre que coincida con el tecleado en
el cuadro detextoyluegocopiarlohaciaHoja2apartirdelacasillaA16.Lamacrocontrolarquehaya
algoenelcuadrodetexto.Secopiarantodaslascoincidencias,esdecirsihaydosnombresRamnse
copiarnlosdos.Sinohayningunacoincidenciasemostrarunmensajeavisandodeello.

Loseventos.

Cuando se programan controles bien sea directamenteen la hoja como estamos haciendo ahora o
desdeunformulario,debe tener encuentalos eventos.Un evento en cuando ocurre algo sobre un
objeto, enentornos Windows constantemente se estn produciendo eventos. Clicks con el ratn sobre
un control,teclearsobreuncuadrodetexto,etc.provocaneventosquesonrecogidosporelsistema.
Programar unevento significa hacer que se ejecuten determinadas instrucciones cuando ocurra dicho
evento. En el casoque nos ocupa ahora, haremos que las acciones necesarias para copiarlos datosse
ejecuten cuando sehagaunclicsobreelbotnCopiar_Datos. En general, todos los controles son
capaces de capturardiferentes eventos.El sistema de eventos es bastante ms complejo de lo que
estudiaremos aqu, nosotrossimplementetendremos en cuenta que evento debemos elegir para lanzar
Veamos en la siguiente seccin como asociar el cdigo
la ejecucin de determinadocdigo.
necesario para copiar datos cuandoocurreeleventoclick(`pulsarelbotnysoltarlo)sobreelbotn

Pgina 95

Macros en Excel

Copiar_Datos.

Pgina 96

Macros en Excel

EscribircdigoparaeleventoClickdelBotn.

DeberestarenmodoDiseo,asegresequeelbotn

estpulsado.

1. Hagadobleclicksobreelbotn,observequeseactivaautomticamente laventanadeVisualBasicy
apareceunesqueletodefuncin

SubCopiar_Datos_Click()

EndSub

Es lo que se llama procedimiento de evento, es decir, este procedimiento est asociado al


eventoClickdelBotnCopiar_Datos, observe que el procedimiento lleva un nombre compuesto
por elnombredelcontrol"Copiar_Datos",unguinbajoyelnombredelevento"Click",engeneral
todoslosprocedimientosdeeventosenombradeestaforma,

NombreDeControl_NombreDeEvento

Observe la lista de la parte superior derecha, la que tiene el elemento Click. Es la lista de eventos, si
ladespliegaverqueademsdelelementoClickaparecenunoscuantosmsDblClick (DobleClick)
Gotfocus(Coger el foco), etc. todos ellos son eventos programables del control botn, es decir,
podemos incluir cdigo que se ejecutar cuando ocurren dichos eventos. Por otra parte, todos
loscontroles tienen un evento "por defecto", dicho de otra forma, cuando se programa un
evento delcontrolcasisiempreserese.Enelcasodenuestrobotn(ydetodoslosbotones),el
evento pordefecto es Click, observe que lo habitual es que queramos que el cdigo se ejecute
cuandosehaceclick sobre el botn, no cuando este coge el foco o cuando el puntero de ratn pasa
sobre l, etc.Elevento por defecto de un control es el que aparece cuando, en modo diseo, se
hace doble clicsobrel,obviamenteestesepuedecambiar,porelquemsnosconvenga.

2. Teclear el cdigo para llevar a cabo las acciones. Recuerde que lo que se desea hacer es copiar
haciahoja2 todos los nombres que coincidanconelqueestenelcuadrodetexto.Elcdigoser
elquesigue,observeloscomentarios.

OptionExplicit

'Numerodecolumnas(campos)delasqueconstacadaregistro
Const Num_Columnas=6

PrivateSubCopiar_Datos_Click()

Dimr1AsRange,r2AsRange
DimencontradoAsBoolean

'Sielcuadrodetextoestvaco,nosebuscanada
IfLen(Datos_Buscar.Value)=0Then
MsgBox("Nohaydatosquebuscar")

Else
'Borrarlosdatosactuales
Callborrar_datos

'ActivarCasillaA16deHoja2yreferenciarlaconr2,Eslacasilladondesecopiarn
'losdatosencasoqueseencuentren
Worksheets(2).Range("A16").Activate
Setr2=ActiveCell

'ActivarcasillaA2deHoja1yreferenciarlaconr1

Pgina 97

Macros en Excel

Worksheets(1).Acti
vate
Worksheets(1).Rang
e("A2").Activate

Pgina 98

Macros en Excel

'RecorrertodoelrangodedatosdeHoja1
encontrado=False
DoWhileNotIsEmpty(ActiveCell)
'Silacasillaactiva=Datos_Buscados
IfActiveCell.Value=Datos_Buscar.TextThen
encontrado=True
'Referenciarconr1laceldadondeestnosdatos
Setr1=ActiveCell
'Copiarlosdatos
CallCopiar_Datos_Hojas(r1,r2)
'Referenciarconr2lacasilladondesecopiaranlosprximosdatos
Setr2=r2.Offset(1,0)
EndIf
ActiveCell.Offset(1,0).Activate
Loop

Worksheets(2).Activate
IfencontradoThen
MsgBox("DatosCopiados")
Else

MsgBox("Ningunacoincidencia")

EndIf

EndIf

EndSub

'ProcedimientoparaborrarlosdatosdeHoja2sellamaantesdeprocederalanuevacopia
PrivateSubborrar_datos()DimiAsInteger
Worksheets(2).Range("A16").Activate
DoWhileNotIsEmpty(ActiveCell)
Fori=0ToNum_Columnas1
ActiveCell.Offset(0,i).Value=""
Nexti
ActiveCell.Offset(1,0).Activate

Loop

EndSub

'ProcedimientoparacopiarlosdatosdeHoja1aHoja3
'Parmetros.
'
r1=CeldaOrigen
'
r2=CeldaDestino
PrivateSubCopiar_Datos_Hojas(r1AsRange,r2AsRange)

DimiAsInteger
DimDatosAsVariant

'Recorrerlascolumnasdelregistroycopiarceldaacelda
Fori=0ToNum_Columnas1
Datos=r1.Offset(0,i).Value
r2.Offset(0,i).Value=Datos
Nexti

EndSub

Pgina 99

Macros en Excel

CuadrosCombinados(ComboBox)

Con lo hecho hasta ahora podemos extraer de la tabla los registros cuyo nombre coincida con el
tecleado en el cuadro de texto. A continuacin haremos que se pueda escoger el campo, es decir, podremos
extraer coincidencias del Nombre, los Apellidos, la Ciudad, etc. Para ello incluiremos un cuadro
combinado quepermita escoger en que campo o columna tiene que buscarse la coincidencia. La lista,
por supuesto,mostrarlosnombresdelascolumnas.

IncluyauncuadrocombinadoenHoja2ypngalepornombre(propiedadName).Lista_Campos

PropiedadListFillRange.

Con estapropiedaddeberemos definir los elementos que debe mostrar la lista, debe especificarseel
rangoque contiene los elementos a mostrar, el rango debe ser una columna (o dos , o tres, etc.). En
nuestro casoelrangoserJ1:J6deHoja2(Observequeenesterangoestnespecificadoslos
nombresdelascolumnas).

PropiedadLinKedCell.

Enestapropiedaddebeespecificarenqueceldadebecopiarseelelementoseleccionadodelalista.
Enestalistanoutilizaremosestapropiedad.

Cuidadoconestapropiedad,tengaencuentaqueloselementosdelalistasontratadoscomodatosde
tipoStringaunque contenga nmeros o fechas, por lo que en estos casos, a veces ser necesario aplicar
funciones de conversin de datos antes que el dato se copie en la hoja. Por ejemplo, si alguna vez
construye una lista con nmeros ver que el dato seleccionado se alinea a la derecha, si son fechas, no se
muestraconelformatocorrespondiente.

PropiedadListIndex.

Medianteestapropiedadpodremossaberqueelementodelalistaeselseleccionadoporsunmerode
orden.Esdecir,siestseleccionadoelprimero, ListIndex valdr 0, si est seleccionado el segundo valdr
1,etc.Sinohayningnelementoseleccionadovaldr 1.Tengaencuentaqueestapropiedadsloest
disponible en tiempo de ejecucin, es decir la podremos leer mientras est funcionando el programa,
nose puede establecer en modo diseo, observe que no aparece en la ventana propiedades del
cuadrocombinado.

Bien, ya sabemos como funcionan las propiedades que utilizaremos para hacer que se extraigan de la
tabla los elementos que coincidan con el valor del cuadro de texto y cuya columna o campo sea el
seleccionadodelalista,veamoscomoquedarlamacro.

En primer lugar cree un procedimiento llamado Proceder donde deber copiar todo el cdigo que
ahoraestenCopiar_Datos. Debemos hacer esto porque antes de proceder se deben hacer
ciertascomprobaciones que ya iremos viendo conforme avanzamos, por el momento la comprobacin a
hacer esladeversobrequecampoocolumnasedebenbuscarlascoincidenciasconlosdatostecleados
enelcuadrodetexto.LafuncinCopiar_Datosquedardelaformasiguiente.

Pgina 100

Macros en Excel

PrivateSubCopiar_Datos_Click()

DimiAsInteger

'Recogerelelementoseleccionadodelalista
i=Lista_Campos.ListIndex

'Sii<0esquenohayningnelementoseleccionado.
Ifi<0Then
MsgBox("DebeSeleccionaruncampodelalista")

Else
'Llamaraprocederparainiciarlacopia.
CallProceder(i)
EndIf

EndSub

La cabecera de la funcin proceder quedar de la forma


siguiente.

'ProcedimientoProceder
'Inicialacopiadelosdatoscoincidentes
'Parmetros:
'Columna=Elementosseleccionadodelalistaquecoincidirconlacolumnasobrelaquese
' debebuscar
PrivateSubProceder(ColumnaAsInteger)

.....

Ahora, dentro del procedimiento Proceder cambie la


lnea

IfActiveCell.Value=Datos_Buscar.TextThen

Por

IfActiveCell.Offset(0,Columna).Value=Datos_Buscar.TextThen

Explicacindel proceso.Cuandoseseleccionaunelementodelalista,supropiedad ListIndexes igualal


orden que ocupa dicho elemento en la lista, supongamos que escogemosCiudad, ListIndex valdr 2.
EstevalorsepasaaProcederyesrecogidoporelparmetroColumna.Ahoraobservelalnea

IfActiveCell.Offset(0,Columna).Value=Datos_Buscar.TextThen

Es decir la coincidencia con elvalordelcuadrodetextoDatos_Buscar sebuscarespectoalacasillaque


est a la derecha ( offset ) de la activa,tantas columnas como las expresadas por el valor de la variable
Columna. Observe que en este caso la casilla activa siempre corresponde aunadelacolumnaA,sila
variable Columna vale 2 la coincidencia se buscar respecto al valor de la columna C (2 ms hacia la
derecha)yquecoincideconlacolumnacorrespondientealaCiudad.

Pgina 101

Macros en Excel

SegundaLista.

Ahoracrearemosunalistadondeseaposibleescogerlarelacin de comparacin.Hastaahorala
extraccin se realizaba con aquellos elementos iguales al valor entrado en el cuadro de texto
Datos_Buscar,estasegundalistapermitirescogersiloselementosaextraerdebenserIguales,Menores,
Mayores, Menores Iguales o Mayores IgualesqueelvalordeDatos_Buscar. Para ello debe construir una
segundalistaconlaspropiedadessiguientes.

Name=Lista_Comparacin.
ListFillRange=L1:L5Observequeenesterangoestnlosvalorescorrespondientes ala
operacinrelacionalquesedesearealizar(Igual,Menor,etc.)

Obviamente deberemos modificar las funciones para realizar las operaciones con respecto al
elementoseleccionado en el cuadro de lista Lista_Comparacin. Dejaremos el procedimiento Proceder de
la formasiguiente y crearemos una funcin que haga las comparaciones, esta funcin a la que
hemos llamadoComparardevuelvaelvalorTruesielresultadodelacomparacinesCiertoyFalsesiesfalso.

'ProcedimientoProceder
'Inicialacopia delosdatoscoincidentes
'Parmetros:
' Columna=Elementosseleccionadodelalistaquecoincidirconlacolumnasobrelaquesedebe
' buscar
PrivateSubProceder(ColumnaAsInteger)

Dimr1AsRange,r2AsRange
DimencontradoAsBoolean
DimValor_ComparacionAsBoolean

'Sielcuadrodetextoestvaco,nosebuscanada
IfLen(Datos_Buscar.Value)=0Then
MsgBox("Nohaydatosquebuscar")
Else

'Borrarlosdatosactuales
Callborrar_datos

'ActivarCasillaA16deHoja2yreferenciarlaconr2'Eslacasilladondesecopiarn
'losdatos encasoque'seencuentren
Worksheets(2).Range("A16").Activate
Setr2=ActiveCell

'ActivarcasillaA2deHoja1yreferenciarlaconr1
Worksheets(1).Activate
Worksheets(1).Range("A2").Activate

encontrado=False
'RecorrertodoelrangodedatosdeHoja1
DoWhileNotIsEmpty(ActiveCell)

Valor_Comparacion=Comparar(ActiveCell.Offset(0,Columna).Value,_
Datos_Buscar.Value,Lista_Comparacion.ListIndex)

IfValor_Comparacion=TrueThen
encontrado=True
'Referenciarconr1laceldadondeestnosdatos
Setr1=ActiveCell
'Copiarlosdatos
CallCopiar_Datos_Hojas(r1,r2)

Pgina 102

Macros en Excel

'
R
e
f
e
r
e
n
c
i
a
r
c
o
n

r
2

l
a

c
a
s
il
l
a

d
o
n
d
e

s
e

c
o
p
i
a
r
a
n

l
o
s
p
r

x
i
m
o
s
d
a
t
o

Pgina 103

Macros en Excel

Setr2=r2.Offset(1,0)
EndIf
ActiveCell.Offset(1,0).Activate

Loop

Worksheets(2).Activate
IfencontradoThen
MsgBox("DatosCopiados")
Else

MsgBox("Ningunacoincidencia")

EndIf

EndIf

EndSub

'Funcinquecomparadosvaloresconunoperadorrelacional=,>,<,etc.
'LafuncindevuelveTrueoFalseenfuncindelacomparacin.
'Parmetros.
'
Valor1yValor2=Valoresquesecomparan
' Signo=variablequesirveparaescogereloperadorrelacional
'
enfuncindesuvalor,verestructuraSelectCase

PrivateFunctionComparar(Valor1AsVariant,Valor2AsVariant,OperadorAsInteger)AsBoolean

DimqAsBoolean

SelectCaseOperador
Case0:
q=Valor1=Valor2q
Case 1:
=Valor1>Valor2q=
Case 2:
Valor1<Valor2
Case 3:
q=Valor1>=Valor2q
Case4:
=Valor1<=Valor2
EndSelect

Comparar=q

EndFunction

ObservelalneaquellamaalafuncinComparar,

Valor_Comparacion=Comparar(ActiveCell.Offset(0,Columna).Value,_
Datos_Buscar.Value,Lista_Comparacion.ListIndex)

ActiveCell.Offset(0,Columna)sernlosvaloresquesecompararnconelvalordelcuadrode
texto.

Datos_Buscar.valueeselvalordelcuadrodetexto.

Lista_Comparacin.ListIndexdevuelveelndicedelelementoseleccionadodelalista,observe
comoseutilizaestevalorenlaestructuraSelectCasedeCompararparadeterminarque
operadorutilizar.

Pgina 104

Macros en Excel

Perotodoestonofuncionar.

Pruebelosiguiente.

EnelcuadrodetextoescribaMadrid(osimplementeM).
SeleccionedelalistadeCamposCiudad.
SeleccionedelalistadeoperadoresMayor.
PulsesobreelbotnyobservequesecopiantodoslosregistroscuyocampoCiudadsea
superioraMadrid(oalaM).Hastaaqutodocorrecto.

Ahorapruebelosiguiente.

Enelcuadrodetextoescriba100000
SeleccionedelalistadeCamposCantidad.
SeleccionedelalistadeoperadoresMayor.
Pulsesobreelbotnyobservequenosecopianadaapesarqueencantidadhayregistroscon
elvalorsuperiora100000.

Recuerde que los valores de un cuadro de texto son siempre datos tipo String,entonceseneste
casoestarncomparndosevaloresString(losdelcuadrodetexto)convaloresnumricos,(losrecogidos
delacolumna Cantidad). Tenga en cuenta siempre esta circunstancia cuando trabaje con
elementos deformulario.Vealaseccinsiguientedondesesolucionaresteproblemaydepasosever
comoconstruirListaconmsdeunacolumna.

Listasconmsdeunacolumna.

Para solucionar el problemadelapartadoanteriorutilizaremosunasegundacolumnacuyos


elementosindicarneltipodedatosdelcampo.ObserveelrangoK1:K6deHoja2,lasletrassignificanlo
siguienteTcampotipotextoostring,NcampoNumrico,Fcampofecha. Para incluir esta segunda
columna en lalista debercambiarlaspropiedadessiguientes.

ListFillRange,J1:K6
ColumnCount,2(Indicamoselnmerodecolumnasdelalista.
Ademsespecificaremoselanchodecadacolumnamediantelapropiedad,
ColumnWidths,4pt;0ptDebesepararelanchodecadacolumnamedianteunpuntoycoma.
Observequelasegundacolumnanosemostrardebidoaquehemosespecificadoelanchoa
0.

ColumnBound,1significaqueeldatoquerecogerlapropiedadValuecorrespondealelemento
seleccionadodelaprimeracolumna.

Sidesearecogerdatoslelasegundacolumnadeberutilizarlapropiedad
Column(NumerodeColumna,Indicedelelementoseleccionado)
Lascolumnasempiezananumerarseapartirdela0.
La funcinComparary su correspondientellamadaquedarndelaformasiguiente.Observequesehan
incluido variables que recogen los valores de Lista_Comparacin y Lista_Campos, simplemente lo
hemoshechoparaquequedemsclaro.

Pgina 105

Macros en Excel

............
DoWhileNotIsEmpty(ActiveCell)

'RecogerelSignodecomparacin
Signo=Lista_Comparacion.ListIndex
'Recogereltipodedatos
Tipo_Datos=Lista_Campos.Column(1,Columna)

Valor_Comparacion=Comparar(ActiveCell.Offset(0,Columna).Value,_
Datos_Buscar.Value,Signo,Tipo_Datos)

LafuncinComparar.

PrivateFunctionComparar(Valor1AsVariant,Valor2AsVariant,OperadorAsInteger,TipoAs
String)AsBoolean

DimqAsBoolean

'Conversindeltipodedatosdelasvariables
SelectCaseTipo
Case"N":'Convertiranmero
Valor2=Val(Valor2)
Case"F":'ConvertiraFecha
Valor2=CDate(Valor2)
EndSelect

SelectCaseOperador
Case0:
q=Valor1=Valor2q
Case 1:
=Valor1>Valor2q=
Case 2:
Valor1<Valor2
Case 3:
q=Valor1>=Valor2q
Case4:
=Valor1<=Valor2
EndSelect

Comparar=q

EndFunction

Pgina 106

Macros en Excel

ControlNumrico

Inserte un control de nmero y pngale por nombre (propiedad Name )


Numero.

Establezca su propiedad Orientation a fmOrientatiomVertical para que se alinee


verticalmente.

Este control se utiliza normalmente para aumentar y disminuir valores numricos de un cuadro de
texto,aunque por supuesto puede utilizarse para otras funciones. Utilizaremos un control de este
tipo paraaumentar los valores del Cuadro de Texto Datos_Buscar pero slo si el campo
seleccionado deLista_Camposes de tipo numrico.Paraelloactivaremosestecontrolnicamente
cuando el campo seleccionado sea de este tipo. Para activar o desactivar un control se utiliza la
propiedadEnabled,siestatrueelcontrolestaractivadoysinoestardesactivado.

Observequelaaccindeactivarodesactivarelcontroldenmerodeberemoshacerlocuandose
seleccione un elemento de Lista_Campos. Es decir el cdigo deberemos insertarlo en el evento Change
(cambio) deLista_Campos. Haga doble clic sobre el elemento Lista_Campospara desplegar su
procedimientodeevento.Elcdigoparacontrolarlaactivacindelcontroleselquesigue,

PrivateSubLista_Campos_Change()

DimiAsInteger
DimTipo_DatosAsString

i=Lista_Campos.ListIndex

Ifi>=0Then

Tipo_Datos=Lista_Campos.Column(1,i)

IfTipo_Datos="N"Then
Numero.Enabled=True
Else

Numero.Enabled=False
EndIf

EndIf

EndSub

Establecerlosvaloresdelcontroldenmero.

Paraestablecerlosvaloresquepuededevolveruncontroldenmerosedebenmodificarlas
propiedadessiguientes.

Max,estableceelvalormximoquepuedetenerelcontrol.
Min,estableceelvalormnimoquepuedetenerelcontrol.
Smallchange,estableceelincrementoodecrementoparalapropiedadvaluecadavezque
sepulsesobrealgunodelosdosbotones.

Estosvaloressepuedenestablecerentiempodediseo,peroloqueharemosacontinuacin
ser establecerlos en tiempo de ejecucin dependiendo del campo que se seleccione en
Lista_Campos.Estableceremoslosvaloressiguientes.

ParacampoEdad.

Pgina 107

Macros en Excel

Max=99
Min=18
SmallChange=1

Pgina 108

Macros en Excel

Paracampocantidad.

Max=500.000
Min=10.000
SmalChange=1.000

DeberemosmodificarelcdigodelprocedimientodeeventoLista_Campos_Changedelaforma
siguiente.

PrivateSubLista_Campos_Change()

DimiAsInteger
DimTipo_DatosAsString

i=Lista_Campos.ListIndex

Ifi>=0Then

Tipo_Datos=Lista_Campos.Column(1,i)

IfTipo_Datos="N" Then
Numero.Enabled=True
IfLista_Campos.Value="Edad"Then
Numero.Min=18
Numero.Max=99
Numero.SmallChange=1
Datos_Buscar.Value=0
Numero.Value=0
EndIf
IfLista_Campos.Value="Cantidad"Then
Numero.Min=10000
Numero.Max=500000
Numero.SmallChange=1000
Datos_Buscar.Value=0
Numero.Value=0
EndIf

Else

Numero.Enabled=False

EndIf

EndIf

EndSub

YparaterminaryaslodebemoscodificareleventoChangedelcontroldenmeroparaqueel
Cuadrodetextovayaincrementandoodecrementandosuvalorcadavezquesehagaclicsobreel
control.

PrivateSubNumero_Change()
Datos_Buscar.Value=Numero.Value
EndSub

Pgina 109

Macros en Excel

Peroademsdebemoshacerquecuandosecambieelvalordelcuadrodetextotambinsecambieel
delcontroldenmerodeformaquecuandosepulsesobrel, incremente o decremente a partir del
valor quehayenelcuadrodetexto. Si no se hace as, el incremento o decremento se har en funcin
del valor quetengaelcontroldenmeronoelqueestenelcuadrodetexto.Modificaremosel
eventoChange delcuadro de texto. Observe que se controla que slo se ejecute la accin si el
control de nmero estactivado,ademssedebecontrolartambinelvalormximoymnimoque
puedecontenerelcuadrodetexto,sinosehicieraassegeneraraunerroralponer un valor mayor o
menor que los definidos en laspropiedadesMaxyMindelcontroldenmero.

PrivateSubDatos_Buscar_Change()

'Sielnumerodecontrolestactivado
IfNumero.EnabledThen
'NopermitecogervaloressuperioresalapropiedadMax
IfVal(Datos_Buscar.Value)>Numero.MaxThen
MsgBox("Valordemasiadogrande")
Datos_Buscar.Value=Numero.Max
Else

'NopermitecogervaloresinferioresalapropiedadMin
IfVal(Datos_Buscar.Value)<Numero.MinThen
MsgBox("Valordemasiadopequeo")
Datos_Buscar.Value=Numero.Min
Else

Numero.Value=Val(Datos_Buscar.Value)

EndIf

EndIf
EndIf

EndSub

Antes de proceder con el siguiente control djenos remarcar que la programacin de controles
implicaquemuchasvecesunosdependandeotrosporloquedebeserextremadamente
cuidadosoenlaelaboracindelcdigodeloseventos.Observelasltimasoperacionesque
hemosrealizadodebidoalainterdependenciadedoscontroles.

Casillasdeverificacin(CheckBox)

Estoscontrolessesuelenutilizarparaactivarodesactivarlaejecucindedeterminadasacciones.
Casisiempreimplicanunaestructuracondicionalalahoradehaceralgunacosa,

S ilascasillaestactivadaEntonces
Acciones
....
FinSi

A continuacin utilizaremosuna casillade verificacin quesi est activadaprovocar que los datos tipo
texto se conviertan a mayscula antes de copiarse, se utilizar la funcin Ucase. Simplemente se
debercomprobarquelacasillaestactivadaysiloestprocederalaconversin(slosieldatoestipotexto).

Inserteuncontrolcasilladeverificacin.Establezcalassiguientespropiedades.

Name,Mayusculas.
Captin,Maysculas.

Paracomprobarsilacasillaestactivadaonosimplementedebemirarsesupropiedad Value.Sivale
trueesqueestactivada,sinovaldrFalse.

Pgina 110

Macros en Excel

Veacomoquedarelprocedimiento Copiar_Datos_Hojas,observequeademsdecomprobarquela
casilla est activada se utiliza la funcinTypeName para comprobar si los datos que se van a copiarson
del tipo String, si no lo fueran, la funcin Ucase provocara un error. TypeName(Expresin ) devuelve
unacadenaqueindicaeltipodedatosdelaexpresin.

PrivateSubCopiar_Datos_Hojas(r1AsRange,r2AsRange)

DimiAsInteger
DimDatosAsVariant

'recorrerlascolumnasdelregistroycopiarceldaacelda
Fori=0ToNum_Columnas1

'SilacasillaMaysculasestactivadayeltipodedatosesString
IfMayusculas.Value=TrueAndTypeName(r1.Offset(0,i).Value)="String"Then
Datos=UCase(r1.Offset(0,i).Value)

Else
Datos=r1.Offset(0,i).Value
EndIf
r2.Offset(0,i).Value=Datos

Nexti

EndSub

BotonesdeOpcin(OptionButton)

Losbotonesdeopcinseutilizanparaelegirunanicaopcinentreunaserie de ellas, es decir, de


ungrupodeopcionesslopermitirnqueseescojauna.Delamismaformaquelascasillasde
verificacin,casi siempre implican una estructura condicional para comprobar cual de ellas est
activada. El botnactivadotendrsupropiedadValueigualatrue.

Comoejemplodesuutilizacincrearemosdosbotonesdeopcinquesirvanparaquealahorade
copiardatoshacialahoja,secopieslolosvaloresdeNombreyApellidosotodoscomohastaahora.

Incluyadosbotonesdeopcinyestablezcalassiguientes
propiedades.Botn1.
Name,Todo.
Caption,Todo.
Botn2.
Name,Solo_Nombre.
Caption,NombreyApellidos.

Si est activado el primer botn debern copiarse todos los datos mientras que si est activado el
segundosolo secopiarn el Nombrey losApellidos. El procedimiento Copiar_Datos_Hojas quedar de la
formasiguiente.

Pgina 111

Macros en Excel

PrivateSubCopiar_Datos_Hojas(r1AsRange,r2AsRange)

DimiAsInteger
DimDatosAsVariant
DimFinalAsInteger

'SiBotnTodoActivado,secopiantodaslascolumnas
IfTodo.Value=TrueThen
Final=Num_Columnas1
Else'Slosecopianlasdosprimeracolumnas
Final=1
EndIf

'recorrerlascolumnasdelregistroycopiarceldaacelda
Fori=0To Final

'SilacasillaMaysculasestactivadayeltipodedatosesString
IfMayusculas.Value=TrueAndTypeName(r1.Offset(0,i).Value)="String"Then
Datos=UCase(r1.Offset(0,i).Value)
Else

Datos=r1.Offset(0,i).Value
EndIf
r2.Offset(0,i).Value=Datos

Nexti

EndSub

Y aqu terminamos elestudiodecmosepuedenutilizarloscontrolesdeformulariodentrodeuna


hojade clculo. Recordarle para terminar que debe ser extremadamente cuidadoso con el cdigo que
utiliceenlosprocedimientosdeeventosobretodosiloscontrolesseinterrelacionanentreellos.

ElsiguienteListadoincluyetodoelcdigoquesehautilizado.Puedeprobarsufuncionamientocargando
elarchivoLista7_2.xls quedebidescargarsejuntoaestetema.

Pgina 112

Macros en Excel

OptionExplicit

'Numerodecolumnas(campos)delasqueconstacadaregistro
Const Num_Columnas=6

PrivateSubCopiar_Datos_Click()

DimiAsInteger
DimxAsInteger

'Recogerelelementoseleccionadodelalista
i=Lista_Campos.ListIndex

'Sii<0noestseleccionadoningnelemento
Ifi<0Then
MsgBox("DebeSeleccionaruncampodelalista")

Else
x=Lista_Comparacion.ListIndex
Ifx<0Then
MsgBox("DebeSeleccionarunooperadordeComparacin")
Else

'llamaraproceder

CallProceder(i)
EndIf
EndIf

EndSub

'ProcedimientoProceder
'Inicialacopiadelosdatoscoincidentes
'Parmetros:
' Columna=Elementosseleccionadodelalistaquecoincidir
'
conlacolumnasobrelaquesedebebuscar
PrivateSubProceder(ColumnaAsInteger)

Dimr1AsRange,r2AsRange
DimencontradoAsBoolean
DimValor_ComparacionAsBoolean
DimSignoAsInteger
DimTipo_DatosAsString

'Sielcuadrodetextoestvaco,nosebuscanada
IfLen(Datos_Buscar.Value)=0Then
MsgBox("Nohaydatosquebuscar")

Else
'Borrarlosdatosactuales
Callborrar_datos

'ActivarCasillaA16deHoja2yreferenciarlaconr2
'Eslacasilladondesecopiarnlosdatosencasoqueseencuentren
Worksheets(2).Range("A16").Activate
Setr2=ActiveCell

'ActivarcasillaA2deHoja1yreferenciarlaconr1
Worksheets(1).Activate
Worksheets(1).Range("A2").Activate

'RecorrertodoelrangodedatosdeHoja1
encontrado=False

Pgina 113

Macros en Excel

DoWhileNot
IsEmpty(ActiveCell)

Pgina 114

Macros en Excel

'RecogerelSignodecomparacin
Signo=Lista_Comparacion.ListIndex
'recogereltipodedatos
Tipo_Datos=Lista_Campos.Column(1,Columna)

Valor_Comparacion=Comparar(ActiveCell.Offset(0,Columna).Value,_
Datos_Buscar.Value,Signo,Tipo_Datos)

IfValor_Comparacion=TrueThen
encontrado=True
'Referenciarconr1laceldadondeestnosdatos
Setr1=ActiveCell
'Copiarlosdatos
CallCopiar_Datos_Hojas(r1,r2)
'Referenciarconr2lacasilladondesecopiaranlosprximosdatos
Setr2=r2.Offset(1,0)
EndIf
ActiveCell.Offset(1,0).Activate

Loop

Worksheets(2).Activate
IfencontradoThen
MsgBox("DatosCopiados")

Else
MsgBox("Ningunacoincidencia")

EndIf

EndIf

EndSub

'Funcinquecomparadosvaloresconunoperadorrelacional=,>,<,etc.
'LafuncindevuelveTrueoFalseenfuncindelacomparacin.
'Parmetros.
' Valor1yValor2=Valoresquesecomparan
' Signo=variablequesirveparaescogereloperadorrelacional
'
enfuncindesuvalor,verestructuraSelectCase

PrivateFunctionComparar(Valor1AsVariant,Valor2AsVariant,OperadorAsInteger,TipoAs
String)AsBoolean

DimqAsBoolean

SelectCaseTipo
Case"N":'Convertiranmero
Valor2=Val(Valor2)
Case"F":'ConvertiraFecha
Valor2=CDate(Valor2)
EndSelect

SelectCaseOperador
Case0:
q=Valor1=Valor2q
Case1:
=Valor1>Valor2q=
Case2:
Pgina 115

Macros en Excel

V
a
l
o
r
1

<

V
a
l
o
r
2

Pgina 116

Macros en Excel

Case3:

q=Valor1>=Valor2q

Case4:
=Valor1<=Valor2
EndSelect
Comparar=q
EndFunction

'ProcedimientoparaborrarlosdatosdeHoja2sellamaantesdeprocederalanuevacopia
PrivateSubborrar_datos()DimiAsInteger
Worksheets(2).Range("A16").Activate
DoWhileNotIsEmpty(ActiveCell)
Fori=0ToNum_Columnas1
ActiveCell.Offset(0,i).Value=""
Nexti
ActiveCell.Offset(1,0).Activate

Loop

EndSub

'ProcedimientoparacopiarlosdatosdeHoja1aHoja3
'Parmetros.
' r1=CeldaOrigen
' r2=CeldaDestino

PrivateSubCopiar_Datos_Hojas(r1AsRange,r2AsRange)

DimiAsInteger
DimDatosAsVariant
DimFinalAsInteger

'SiBotnTodoActivado,secopiantodaslascolumnas
IfTodo.Value=TrueThen
Final=Num_Columnas1
Else'Slosecopianlasdosprimeracolumnas
Final=1
EndIf

'recorrerlascolumnasdelregistroycopiarceldaacelda
Fori=0To Final

'SilacasillaMaysculasestactivadayeltipodedatosesString
IfMayusculas.Value=TrueAndTypeName(r1.Offset(0,i).Value)="String"Then
Datos=UCase(r1.Offset(0,i).Value)

Else
Datos=r1.Offset(0,i).Value
EndIf
r2.Offset(0,i).Value=Datos

Nexti

EndSub

Pgina 117

Macros en Excel

PrivateSubDatos_Buscar_Change()

'Sielnumerodecontrolestactivado
IfNumero.EnabledThen
'NopermitecogervaloressuperioresalapropiedadMax
IfVal(Datos_Buscar.Value)>Numero.MaxThen
MsgBox("Valordemasiadogrande")
Datos_Buscar.Value=Numero.Max
Else

'NopermitecogervaloresinferioresalapropiedadMin
IfVal(Datos_Buscar.Value)<Numero.MinThen
MsgBox("Valordemasiadopequeo")
Datos_Buscar.Value=Numero.Min
Else

Numero.Value=Val(Datos_Buscar.Value)

EndIf

EndIf
EndIf

EndSub

PrivateSubLista_Campos_Change()

DimiAsInteger
DimTipo_DatosAsString

i=Lista_Campos.ListIndex

Ifi>=0Then

Tipo_Datos=Lista_Campos.Column(1,i)

IfTipo_Datos="N" Then
Numero.Enabled=True
IfLista_Campos.Value="Edad"Then
Numero.Min=18
Numero.Max=99
Numero.SmallChange=1
Datos_Buscar.Value=0
Numero.Value=0
EndIf
IfLista_Campos.Value="Cantidad"Then
Numero.Min=10000
Numero.Max=500000
Numero.SmallChange=1000
Datos_Buscar.Value=0
Numero.Value=0
EndIf

Else

Numero.Enabled=False

EndIf

EndIf

Pgina 118

Macros en Excel

EndSub

PrvateSub Numero_ChangeQ

DatosBuscar.Value=Numero.Value
EndSub

Pgina 119

You might also like