Beruflich Dokumente
Kultur Dokumente
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
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.
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.
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.
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.
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"
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
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.
1. Siteelcursordentrodelprocedimiento.
2. ActiveopcindelabarrademensEjecutar/EjecutarSubUserform.Tambinpuedehacerclic
sobreelbotn
opulsarlateclaF5.
Paraejecutarelprocedimientodesdelahojadeclculo.
Debeestarenunahoja,noeneleditordeVisualBasic
1. ActiveopcindelabarrademensHerramientas/Macro/Macros.Sedespliegaunaventanaque
muestraunalistadondeeststodaslasmacrosincluidasenellibrodetrabajo.
2. SeleccionelamacrodelalistaypulsesobreelbotnEjecutar.
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
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.
Nmerodecontextoparalaayuda:Nmeroasignadoquecorrespondealidentificadordel
archivodeayuda,sirveparalocalizareltextoquesedebemostrar.Siseespecificaeste
Pgina 8
Macros en Excel
parmetro,debeespecificarseobligatoriamenteelparmetroArchivoAyuda.
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
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.
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
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
16bytes
22bytes+longitud de
cadena
Nmerorequerido por
loselementos
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
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
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).
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
Cdec
Decimal
+/7,9228162514264337593543950335. La menorposicin
paraunnmeroquenoseaceroes
0,0000000000000000000000000001.
CInt
CLng
CSng
Integer
Long
Single
CVar
Variant
CStr
String
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.
Range(Cells(1,1),Cells(8,2)).Value="Hola"
OtraformainteresantedeCellseslasiguiente,
Range("A5:B10").Cells(2,1).Value="Hola"
PondrenlaceldaA6elvalor"Hola",observequeenesteejemplo Cellscomienzaacontarfilasy
columnasapartirdelrangoespecificadoenelobjetoRange.
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
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
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
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.
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".
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
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.
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
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
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.
Pgina 23
Macros en Excel
EstructuraSelectCase.
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
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.
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
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.
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
Pgina 27
Macros en Excel
Imagine queenalgunadelascasillasquesedebenoperarnohubieraningnvalorobiendatos
alfanumricos.Alejecutarlamacroseproducirunerror.Aunque con Visual Basic se puede controlar el
flujodelprogramacuandoseproduceunerrorimprevisto,parasolucionaresteproblemautilizaremos
unafuncindecomprobacinquenosdigasienlascasillasA1yA2hayvaloresadecuados(numricos)
paraproseguirconlaejecucindelamacro,encasocontrariosemostrarunerrorynoseejecutar
ningunadelasoperaciones.
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
Pgina 28
Macros en Excel
EndSelect
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
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.
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.
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.
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
Pgina 33
Macros en Excel
EndIf
EndSub
Pgina 34
Macros en Excel
EstructurasRepetitivas.
Ejemplo20.
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.
Pgina 35
Macros en Excel
EstructurarepetitivaPara(for).
Estaestructurasirvepararepetirlaejecucindeunasentenciaobloquedesentencias,unnmero
definidodeveces.Laestructuraeslasiguiente:
Paravar=Valor_InicialHastaValor_FinalPasoIncrementoHacer
Inicio
Sentencia1
Sentencia2
.
.
SentenciaN
Fin
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
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
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
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
Pgina 38
Macros en Excel
PropiedadOffset.
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"))
Pgina 39
Macros en Excel
ActiveCell.Value=Nota
Pgina 40
Macros en Excel
Media=Media+Nota
Haceractivalacasillasituadaunafilapordebajodelaactual
ActiveCell.Offset(1,0).Activate
NextFila
Media=Media/5
ActiveCell.Value=Media
EndSub
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).
HacerMientras(secumplalacondicin)
Sentencia1
Sentencia2
.
.
SentenciaN
FinHacerMientras
EnVisualBasic
DoWhile(secumplalacondicin)
Sentencia1
Sentencia2
.
.
SentenciaN
Loop
Pgina 41
Macros en Excel
Pgina 42
Macros en Excel
Ejemplo27.
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.
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
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
Pgina 45
Macros en Excel
EstructuraDo..LoopWhile.
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.
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")
Pgina 46
Macros en Excel
HastaqueMas_DatosseaigualavbNo
LoopUntilMas_Datos=vbNo
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.
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.
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
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)
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
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)
.
.
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
Pgina 53
Macros en Excel
EndSub
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
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.
Pgina 55
Macros en Excel
EjemploEfecto_Lateral.
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.
Pgina 56
Macros en Excel
Vuelvaaejecutarelprograma,vercomoahorafuncionacorrectamente.
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)
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,
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
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.
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.
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
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.
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.
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
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.
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.
1. SiteelcursorsobreelnombredelavariableSuma_Columna,puedeescogercualquier
posicindondeaparecelavariable.
2. ActivelaopcinDepuracin/AgregarInspeccin.Apareceelsiguientecuadrodedilogo,
Expresin:Variableoexpresinquesedeseaevaluar.
Procedimiento:Aqusedescribeelprocedimientodondedebeevaluarselavariable,estosignifica
queelmbitodecomprobacindelavariableesslodentrodeesteprocedimiento.Imagineque
tienedosomsprocedimientosdondeutilizaunavariableconelmismonombre,obienquetiene
unavariableglobal,aquseindicaenqueprocedimientodebehacerselaevaluacin.
Expresinde inspeccin.Activandoestaopcin,indicamosquelonicoquedeseamoshaceres
incluirlavariableoexpresindentrodelaventanadeexpresin.
Expresin:Suma_Columna>30000
Procedimiento:Recorrer_Columna
Mdulo: Mdulo1(ocomosellamesumdulo).
ActiveMododeinterrupcincuandoelvalorseaverdadero.
3. PulsesobrebotnAceptar.
Pgina 76
Macros en Excel
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
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.
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
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
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
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.
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
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.
Establecerlaaccindecopiardatoscuandosepulseelbotn.
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
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
'ProcedimientoProceder
'Inicialacopiadelosdatoscoincidentes
'Parmetros:
'Columna=Elementosseleccionadodelalistaquecoincidirconlacolumnasobrelaquese
' debebuscar
PrivateSubProceder(ColumnaAsInteger)
.....
IfActiveCell.Value=Datos_Buscar.TextThen
Por
IfActiveCell.Offset(0,Columna).Value=Datos_Buscar.TextThen
IfActiveCell.Offset(0,Columna).Value=Datos_Buscar.TextThen
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.
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
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)
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
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