You are on page 1of 35

Tcnicas de UserForm avanzadas

Anexo del Manual de Programacin VBA Excel


http://www.ayudaexcel.com

Contenido
Un cuadro de dilogo no modal .................................................................................................... Mo!trar un indicador de progre!o ................................................................................................ " #rear un indicador de progre!o independiente ........................................................................ $ #on!truir el U!er%orm indicador de progre!o independiente .............................................. & #rear lo! procedimiento! de controlador de e'ento! para el indicador de progre!o independiente ....................................................................................................................... & #rear un procedimiento de inicio para un indicador de progre!o independiente ............. (( #mo )unciona el indicador de progre!o independiente ................................................... (( Mo!trar un indicador de progre!o utili*ando un control de pgina m+ltiple......................... (( Modi)icar un U!er%orm para un indicador de progre!o con un control de pgina m+ltiple ............................................................................................................................................. (, -n!ertar el procedimiento UpdateProgre!! para un indicador de progre!o con un control de pgina m+ltiple............................................................................................................... (. Modi)icar el procedimiento para un indicador de progre!o con un control de pgina m+ltiple ............................................................................................................................... (. #mo )unciona un indicador de progre!o con un control de pgina m+ltiple ................... (. Mo!trar un indicador de progre!o !in utili*ar un control de pgina m+ltiple ........................ (. #rear a!i!tente! ........................................................................................................................... ( #on)igurar el control de pgina m+ltiple para el a!i!tente ..................................................... (/ A0adir lo! 1otone! al U!er%orm del a!i!tente ........................................................................ (2 Programar lo! 1otone! del a!i!tente ...................................................................................... (2 Programar dependencia! en un a!i!tente .............................................................................. (" 3eali*ar la tarea con el a!i!tente............................................................................................. (& Emular la )uncin M!gBox ........................................................................................................... ,4 Emulacin de M!gBox: el cdigo MiM!gBox........................................................................... ,4 #mo )unciona la emulacin de M!gBox ................................................................................ ,( Utili*ar la )uncin MiM!gBox en la emulacin de M!gBox ..................................................... ,, Un U!er%orm con controle! de!li*ante! ..................................................................................... ,, Un U!er%orm !in 1arra de t5tulo.................................................................................................. , 6imular una 1arra de herramienta! con un U!er%orm ............................................................... ,/ Un U!er%orm de tama0o a7u!ta1le ............................................................................................. ,"

#ontrolar 'ario! 1otone! de U!er%orm con un controlador de e'ento! .................................... .4 6eleccionar un color en un U!er%orm ......................................................................................... .. Mo!trar un gr)ico en un U!er%orm............................................................................................ . Pa!o! generale! para mo!trar un gr)ico en un U!er%orm ..................................................... ./ 8uardar un gr)ico como archi'o gi)....................................................................................... ./ #am1iar la propiedad Picture del control de imagen ............................................................. ./

Tcnicas de UserForm avanzadas

E!te manual complementa el cap5tulo (( del Manual de Macro! y programacin VBA. A9u5 encontraremo! m! e7emplo! de U!er%orm!. U!ar U!er%orm no modale!. Mo!trar un indicador de progre!o :tre! t;cnica!<. #rear un a!i!tente :una !erie de cuadro! de dilogo interacti'o!<. #rear una )uncin 9ue imita a la )uncin MsgBox de VBA. Permitir a lo! u!uario! mo'er lo! controle! del U!er%orm. #ontrolar 'ario! o17eto! con un !olo controlador de o17eto!. Mo!trar un U!er%orm !in 1arra de titulo. 6imular una 1arra de herramienta! con un U!er%orm. Permitir a lo! u!uario! modi)icar el tama0o de un U!er%orm. #ontrolar 'ario! controle! con un !olo controlador de e'ento!. U!ar un cuadro de dilogo para !eleccionar un color. Mo!trar un gr)ico en un U!er%orm. Mo!trar una ho7a de clculo completa en un U!er%orm. =a mayor5a de e!to! e7emplo! !on m! a'an*ado!> pero todo! !e 1a!an en aplicacione! prctica!. 6in em1argo> inclu!o lo! e7emplo! 9ue no !on tan prctico! mue!tran t;cnica! muy +tile!.

Un cuadro de dilogo no modal


=a mayor5a de lo! cuadro! de dilogo 9ue no! encontramo! con cuadro! de dilogo modale!> 9ue de1emo! hacer de!aparecer de la pantalla ante! de poder reali*ar cual9uier accin con la aplicacin !u1yacente. 6in em1argo> alguno! dilogo! !on no modale!> lo 9ue !igni)ica 9ue el u!uario puede !eguir tra1a7ando en la aplicacin mientra! !e mue!tra el cuadro de dilogo. Para mo!trar un U!er%orm no modal> utili*amo! una in!truccin como la !iguiente: UserForm1.Show vbModeless =a pala1ra vbModeless e! una con!tante integrada 9ue tiene un 'alor de 4. Por lo tanto la !iguiente in!truccin )unciona de )orma id;ntica: UserForm1.Show 0

El !iguiente e7emplo mue!tra un cuadro de dilogo no modal 9ue contiene in)ormacin !o1re la celda acti'a. #uando !e mue!tra el cuadro de dilogo> el u!uario puede mo'er el cur!or de la celda> acti'ar otra! ho7a! y reali*ar otra! accione! con Excel.

=a cla'e e!t en determinar cundo actuali*ar la in)ormacin del cuadro de dilogo. Para ello> el e7emplo !uper'i!a do! e'ento! del li1ro: 6heet6election#hange y 6heetActi'ate. E!to! procedimiento! de control de e'ento! !e encentran en el mdulo de cdigo para el o17eto ?hi!@orA1ooA. =o! procedimiento! de control de e'ento! !on lo! !iguiente!: Private Sub Workbook_SheetSelectionChange _ (ByVal Sh As Object, ByVal Target As Range) Call UpdateBox End Sub Private Sub Workbook_SheetActivate(ByVal Sh As Object) Call UpdateBox End Sub E!to! procedimiento! in'ocan al procedimiento UpdateBox> 9ue !e mue!tra a continuacin: Sub UpdateBox() With UserForm1 ' Nos aseguramos de que hay una hoja activa If TypeName(ActiveSheet) <> "Worksheet" Then .lblFormula.Caption = "N/A" .lblNumFormat.Caption = "N/A" .lblLocked.Caption = "N/A" Exit Sub End If .Caption = "Celda: " & ActiveCell.Address(False, False) ' Formula If ActiveCell.HasFormula Then .lblFormula.Caption = ActiveCell.Formula Else .lblFormula.Caption = "(ninguna)" End If Formato nmero .lblNumFormat.Caption = ActiveCell.NumberFormat Bloqueada

' '

.lblLocked.Caption = ActiveCell.Locked End With End Sub El procedimiento UpdateBox cam1ia el t5tulo del U!er%orm para 9ue mue!tre la direccin de la celda acti'aB de!pu;! actuali*a lo! tre! controle! de eti9ueta :lblFormula> lblNumFormat y lblLocked<. A continuacin !e mue!tran alguno! punto! para ayudar a comprender el )uncionamiento de e!te e7emplo: El U!er%orm no e! modal para 9ue podamo! acceder a la ho7a mientra! !e mue!tra. El cdigo de la parte !uperior del procedimiento !e a!egura de 9ue la ho7a acti'a e! una ho7a de tra1a7o. 6i la ho7a no e! una ho7a de tra1a7o> !e a!igna a lo! controle! de eti9ueta el texto C/A. El li1ro !uper'i!a la celda acti'a u!ando un 'e'ento 6electionD#hange :9ue !e encuentra en el mdulo de cdigo de ?hi!@orA1ooA<. =a in)ormacin !e mue!tra en lo! controle! de eti9ueta del U!er%orm. El !iguiente di1u7o mue!tra una 'er!in mucho m! !o)i!ticada de e!te e7emplo. E!ta 'er!in contiene un poco m! de in)ormacin adicional acerca de la celda !eleccionada. =o! u!uario! 'eterano! de Excel notarn la! !imilitude! con la 'entana -n)o :una )uncin 9ue )ue eliminada de Excel hace 'ario! a0o!<.

A continuacin !e mue!tran alguno! punto! cla'e de e!ta 'er!in m! !o)i!ticada. El U!er%orm tiene una ca!illa de 'eri)icacin :Actualizar automticamente<. #uando e!ta ca!illa de 'eri)icacin e!t acti'ada> el U!er%orm !e actuali*a automticamente. #uando no lo e!t> el u!uario puede pul!ar el 1otn Actualizar para actuali*ar la in)ormacin. El li1ro utili*a un mdulo de cla!e para !uper'i!ar do! e'ento! para todo! lo! li1ro! a1ierto!: el e'ento SheetSelectionChange y el e'ento SheetActivate.

#omo re!ultado> el cdigo 9ue mue!tra la in)ormacin de la celda !e e7ecuta automticamente cada 'e* 9ue !e producen e!ta! accione! en cual9uier li1ro :!uponiendo 9ue la opcin Actuali*ar automticamente e!t acti'a<. Alguna! accione! :como cam1iar el )ormato num;rico de la celda< no de!encadenan ninguna de e!ta! accione!. Por lo tanto> el U!er%orm tam1i;n contiene un 1otn Actualizar. El recuento 9ue !e mue!tra para el campo de precedente! y dependiente! de la celda incluye +nicamente la! celda! de la ho7a acti'a. E!to e! una limitacin de la! propiedade! Precedents y Dependents. #omo la longitud de la in)ormacin 'ariar> !e utili*a cdigo VBA para modi)icar el tama0o de la! eti9ueta! y e!paciarla! 'erticalmente :y tam1i;n para cam1iar la altura del U!er%orm !i e! nece!ario<.

Mostrar un indicador de progreso


Una de la! nece!idade! m! comune! de lo! programadore! de Excel tiene 9ue 'er con lo! indicadore! de progre!o. Un indicador de progre!o e! un gr)ico parecido a un termmetro 9ue mue!tra el progre!o de una tarea> como una macro> 9ue tarde mucho en e7ecutar!e. =a creacin de un indicador de progre!o e! una tarea relati'amente !encilla. En e!ta !eccin !e mue!tra cmo crear tre! tipo! de indicadore! de progre!o para: Una macro 9ue no !e inicia mediante un U!er%orm :un indicador de progre!o independiente<. Una macro iniciada por un U!er%orm. En e!te ca!o> el U!er%orm u!a el control de pgina m+ltiple> 9ue mue!tra un indicador de progre!o mientra! !e e!t e7ecutando la macro. Una macro iniciada por un U!er%orm. En e!te ca!o> !e aumenta la altura del U!er%orm y el indicador de progre!o aparece en la parte in)erior del cuadro. Para utili*ar un indicador de progre!o tenemo! 9ue poder :de alguna manera< calcular cunto tardar la macro en completar !u tra1a7o. E!to !e puede hacer de 'aria! )orma!> dependiendo de la macro. Por e7emplo> !i la macro e!cri1e dato! en celda! :y !a1emo! el n+mero de celda! 9ue !e 'an a e!cri1ir<> 1a!ta con e!cri1ir cdigo 9ue calcule el porcenta7e completado. -nclu!o !i no podemo! calcular de )orma prece!a el proce!o de una macro> e! una 1uena idea indicar al u!uario 9ue la macro toda'5a e!t en e7ecucin. Un indicador de progre!o ralenti*ar un poco la macro de1ido al e!)uer*o extra de tener 9ue actuali*arla. 6i la rapide* e! a1!olutamente crucial en nue!tro li1ro> 9ui*! !ea me7or renunciar al indicador de progre!o.

Mostrar el progreso en la barra de estado Un modo !imple de mo!trer el progre!o de una macro e! utili*ar la 1arra de e!tado de Excel. =a 'enta7a e! 9ue e! muy )cil de programar. 6in em1argo> el incon'eniente e! 9ue la mayor5a de lo! u!uario! no e!tn aco!tum1rado! a mirar la 1arra de e!tado y pre)erir5an algo m! 'i!ual. Para e!cri1ir texto en la 1arra de e!tado> utili*amo! una in!truccin como ;!ta: Application.StatusBar = Por favor, espere Por !upue!to> !e puede actuali*ar la 1arra de e!tado mientra! progre!a la macro. Por e7emplo> !i tenemo! una 'aria1le llamada Pct 9ue prepre!enta el porcenta7e completado> podemo! e!cri1ir cdigo 9ue peridicamente e7ecute una in!truccin como e!ta: Application.StatusBar = "Procesando... " & Pct & "% _ completado." #uando la macro )inali*a> !e de'uel'e la 1arra de e!tado a !u e!tado normal con la !iguiente declaracin: Application.StatusBar = False 6i no re!ta1lecemo! la 1arra de e!tado> continuar mo!trndo!e el men!a7e )inal.

Crear un indicador de progreso independiente


E!ta !eccin de!cri1e cmo con)igurar un indicador de progre!o independiente :e! decir> 9ue no comien*a mo!trando un U!er%orm< para mo!trar el progre!o de una macro. =a macro !implemente de7a la ho7a en 1lanco y e!cri1e ,4.444 n+mero! al a*ar en un rango de celda!. Sub GenerateRandomNumbers() ' Inserta nmeros al azar en la hoja activa Dim Counter As Integer Const RowMax As Integer = 500 Const ColMax As Integer = 40 Dim r As Integer, c As Integer Dim PctDone As Single If TypeName(ActiveSheet) <> "Worksheet" Then Exit Sub Cells.Clear Counter = 1 For r = 1 To RowMax For c = 1 To ColMax Cells(r, c) = Int(Rnd * 1000) Counter = Counter + 1 Next c PctDone = Counter / (RowMax * ColMax) Call UpdateProgress(PctDone) Next r Unload UserForm1 End Sub

Ee!pu;! de reali*ar una! poca! modi)icacione! en la macro> 9ue 'eremo! en la !iguiente !eccin> el U!er%orm mo!trar !u progre!o.

Construir el UserForm indicador de progreso independiente 6eguiremo! e!to! pa!o! para crear el U!er%orm 9ue !e utili*ar para mo!trar el progre!o de la tarea: (. -n!ertamo! un nue'o U!er%orm y cam1iamo! !u propiedad Caption a Progreso. ,. A0adimo! un control de macro y lo! llamamo! MarcoProgreso. .. A0adimo! un control de eti9ueta dentro del marco y lo llamamo! LabelProgress. Eliminamo! el t5tulo de la eti9ueta y hacemo! 9ue !u color de )ondo :BackColor< !ea ro7o. El tama0o de la eti9ueta y !u colocacin no !on importante! por el momento. . A0adimo! otra eti9ueta !o1re el marco para de!cri1ir 9u; e!t pa!ando :opcional<. /. #on)iguramo! el U!er%orm y lo! controle! para 9ue apare*can como en el di1u7o.

Por !upue!to> podemo! aplicar cual9uier otro tipo de )ormato a lo! controle!. Por e7emplo> !e puede cam1iar la propiedad SpecialEffect del control de marco 9ue aparece en el di1u7o anterior. Crear los procedimientos de controlador de eventos para el indicador de progreso independiente En e!te ca!o> el truco con!i!te en e7ecutar un procedimiento automticamente cuando !e mue!tra el U!er%orm. Una manera de hacerlo e! utili*ar el e'ento Initialize. 6in em1argo> e!te e'ento tiene lugar ante! de 9ue el U!er%orm !e mue!tre realmente> por lo 9ue

no no! re!ulta +til. Por otro lado> el e'ento Activate !e de!encadena cuando !e mue!tra el U!er%orm> por lo 9ue e! per)ecto para e!ta aplicacin. -n!ertamo! el !iguiente procedimiento en la 'entana de cdigo del U!er%orm. E!te procedimiento !implemente in'oca a un procedimiento llamado GenerateRandomNumbers cuando !e mue!tra el U!er%orm. E!te procedimiento> 9ue !e almacena en un mdulo VBA> e! la macro 9ue !e e7ecuta realmente mientra! !e mue!tra el indicador de progre!o. Private Sub UserForm_Activate() Call GenerateRandomNumbers End Sub A continuacin !e mue!tra el procedimiento GenerateRandomNumbers> 9ue 'imo! anteriormente> con alguna! modi)icacione!. F1!er'amo! 9ue el cdigo adicional reali*a un !eguimiento del progre!o y lo almacena en una 'aria1le llamada PctDone. Sub GenerateRandomNumbers() ' Inserta nmeros al azar en la hoja activa Dim Counter As Integer Const RowMax As Integer = 500 Const ColMax As Integer = 40 Dim r As Integer, c As Integer Dim PctDone As Single If TypeName(ActiveSheet) <> "Worksheet" Then Exit Sub Cells.Clear Counter = 1 For r = 1 To RowMax For c = 1 To ColMax Cells(r, c) = Int(Rnd * 1000) Counter = Counter + 1 Next c PctDone = Counter / (RowMax * ColMax) Call UpdateProgress(PctDone) Next r Unload UserForm1 End Sub El procedimiento GenerateRandomNumbers contiene do! 1ucle!. Eentro del 1ucle central hay una llamada al procedimiento UpdateProgress. E!te procedimiento toma un argumento: la 'aria1le PctDone> 9ue repre!enta el progre!o de la macro. PctDone tendr un 'alor entre 0 y 100. Sub UpdateProgress(Pct) With UserForm1 .FrameProgress.Caption = Format(Pct, "0%") .LabelProgress.Width = Pct * (.FrameProgress. _ Width - 10) .Repaint End With End Sub

Crear un procedimiento de inicio para un indicador de progreso independiente ?odo lo 9ue )alta e! un procedimiento 9ue mue!tre el U!er%orm. -ntroducimo! el !iguiente procedimiento en un mdulo VBA: Sub ShowUserForm() With UserForm1 .LabelProgress.BackColor = ActiveWorkbook.Theme. _ ThemeColorScheme.Colors(msoThemeAccent1) .LabelProgress.Width = 0 .Show End With End Sub Cmo funciona el indicador de progreso independiente #uando e7ecutamo! el procedimiento ShowUserForm> !e e!ta1lece 9ue la anchura del o17eto Label !ea 0. Ee!pu;!> el m;todo Show del o17eto UserForm1 mue!tra el U!er%orm :9ue e! el indicador de progre!o<. #uando !e mue!tra el U!er%orm> !e de!encadena !u e'ento Activate> lo 9ue e7ecuta el procedimiento GenerateRandomNumbers. E!te procedimiento contiene el cdigo 9ue in'oca al procedimiento UpdateProgress cada 'e* 9ue el contador de la 'aria1le del 1ucle r !e actuali*a. F1!er'amo! 9ue el procedimiento UpdateProgress utili*a el m;todo Repaint del o17eto U!er%orm. 6in e!ta in!truccin> no !e actuali*ar5an lo! cam1io! de la eti9ueta. Ante! de 9ue )inalice el procedimiento> la +ltima declaracin de!carga el U!er%orm. Para per!onali*ar e!ta t;cnica> tendremo! 9ue a'eriguar cmo determinar el porcenta7e completado y a!ignr!elo a la 'aria1le PctDone. E!to 'ariar dependiendo de la aplicacin. 6i el cdigo !e e7ecuta en un 1ucle :como en e!te e7emplo<> determinar el porcenta7e completado e! !encillo. 6i el cdigo no e!t en un 1ucle> 9ui*! tengamo! 9ue calcular el progre!o completado en 'ario! punto! del cdigo.

Mostrar un indicador de progreso utilizando un control de pgina mltiple


En el e7emplo anterior> la macro no e!ta1a iniciada por un U!er%orm. En mucho! ca!o!> una macro 9ue tarda mucho en e7ecutar!e !e inicia cuando el u!uario hace clic en el 1otn Aceptar de un U!er%orm. =a t;cnica de!crita en e!ta !eccin !er una !olucin m! adecuada y pre!upone lo !iguiente: El proyecto e!t completo y !in errore!. El proyecto utili*a un U!er%orm :!in controle! de pgina m+ltiple< para iniciar una macro 9ue tarda mucho en e7ecutar!e. Gay un modo de calcular el progre!o de la macro. #omo en el e7emplo pre'io> ;!te introduce n+mero! aleatorio! en una ho7a. =a di)erencia e! 9ue e!ta aplicacin contiene un U!er%orm donde el u!uario puede e!peci)icar la cantidad de )ila! y columna! en la! 9ue in!ertar lo! n+mero! aleatorio!.

Modificar un UserForm para un indicador de progreso con un control de pgina mltiple E!te pa!o pre!upone 9ue exi!te un U!er%orm completamente con)igurado. A0adiremo! un control de pgina m+ltiple. =a primera pgina del control de pgina m+ltiple contendr todo! lo! controle! originale!. =a !egunda contendr lo! controle! 9ue mue!tran el indicador de progre!o. #uando la macro comience a e7ecutar!e> el cdigo VBA cam1iar la propiedad Value del control de pgina m+ltiple. E!to ocultar e)ecti'amente lo! controle! originale! y mo!trar el indicador de progre!o. El primer paro e! a0adir un control de pgina m+ltiple a un U!er%orm. A continuacin> mo'emo! todo! lo! controle! del U!er%orm y lo! copiamo! en la pgina ( del control de pgina m+ltiple. El !iguiente pa!o e! acti'ar la pgina , y con)igurarla como la 9ue !e puede 'er en el !iguiente di1u7o. E! 1!icamente la mi!ma com1inacin de controle! utili*ado! en el e7emplo de la !eccin anterior.

(. A0adimo! un control de marco y lo llamamo! FrameProgress. ,. A0adimo! un control de eti9ueta y lo llamamo! LabelProgress. Eliminamo! el t5tulo de la eti9ueta y hacemo! 9ue !u )ondo !e a de color ro7o. .. A0adimo! otra eti9ueta para de!cri1ir 9u; e!t pa!ando :opcional<. . El !iguiente pa!o e! acti'ar el control de pgina m+ltiple :no una pgina del control< y a!ignar a !u propiedad Style el 'alor 2 fbTabStyleNone :e!to ocultar la! eti9ueta!<. El modo m! )cil de !eleccionar el control de pgina m+ltiple e! utili*ar la li!ta de!plega1le de la 'entana Propiedades. Pro1a1lemente tendremo! 9ue a7u!tar el tama0o del control de pgina m+ltiple para tener en cuenta 9ue la! eti9ueta! no e!tn 'i!i1le!.

Insertar el procedimiento UpdateProgress para un indicador de progreso con un control de pgina mltiple -n!ertamo! el !iguiente procedimiento en el mdulo de cdigo del U!er%orm: Sub UpdateProgress(Pct) With UserForm1 .FrameProgress.Caption = Format(Pct, "0%") .LabelProgress.Width = Pct * (.FrameProgress. _ Width - 10) End With DoEvents End Sub E!te procedimiento !e in'oca de!de la macro 9ue !e e7ecuta cuando el u!uario hace clic en el 1otn Aceptar> y reali*a la actuali*acin del indicador de progre!o. Modificar el procedimiento para un indicador de progreso con un control de pgina mltiple ?endremo! 9ue modi)icar el procedimiento 9ue !e e7ecuta cuando el u!uario hace clic en el 1otn Aceptar :el procedimiento de control del e'ento Click para el 1otn> llamado OK_Click<. En primer lugar> in!ertamo! la !iguiente in!truccin en la parte !uperior del procedimiento: MultiPage1.Value = 1 E!ta in!truccin acti'a la pgina , del control de pgina m+ltiple :la pgina 9ue mue!tra el indicador de progre!o<. En el !iguiente pa!o> todo depender mucho m! del programador. Hui*! haya 9ue e!cri1ir cdigo 9ue calcule el porcenta7e completado y a!igne e!te 'alor a una 'aria1le llamada PctDone. E!te clculo !e reali*ar dentro de un 1ucle. Ee!pu;! !e in!ertar la !iguiente in!truccin> actuali*ando el indicador de progre!o: Call UpdateProgress(PctDone) Cmo funciona un indicador de progreso con un control de pgina mltiple E!ta t;cnica e! muy !encilla y> como hemo! 'i!to> !lo u!a un U!er%orm. El cdigo intercam1ia pgina! del control de pgina m+ltiple y con'ierte un cuadro de dilogo normal en un indicador de progre!o. #omo en la! )icha! de la pgina m+ltiple e!tn oculta!> ni !i9uiera !e parece a un control de pgina m+ltiple.

Mostrar un indicador de progreso sin utilizar un control de pgina mltiple


El e7emplo de e!ta !eccin e! !imilar al e7emplo de la anterior. 6in em1argo> e!ta t;cnica e! m! !imple por9ue no utili*a un control de pgina m+ltiple. En lugar de e!o> el indicador de progre!o !e almacena en la parte in)erior del U!er%orm :pero !e reduce la altura del U!er%orm de )orma 9ue lo! controle! del indicador de progre!o no !ean 'i!i1le!<. #uando hay 9ue mo!trar el indicador de progre!o> !e incrementa la altura del U!er%orm> lo 9ue hace 9ue !e 'ea el indicador de progre!o.

El di1u7o !iguiente mue!tra el U!er%orm en el editor de Vi!ual Ba!ic. =a propiedad Height del U!er%orm e! 172. 6in em1argo> ante! de 9ue apare*ca> el 'alor de Height cam1ia a 124 :lo 9ue !igni)ica 9ue lo! controle! del indicador de progre!o no e!tn 'i!i1le! para el u!uario<. #uando el u!uario hace clic en Aceptar> el cdigo VBA cam1ia la propiedad Height a 172 utili*ando la !iguiente in!truccin: Me.Height = 172

Crear asistentes
Mucha! aplicacione! incorporan a!i!tente! para ayudar a lo! u!uario! en alguna operacin. El a!i!tente para importar texto de Excel e! un 1uen e7emplo. Un a!i!tente e! 1!icamente una !erie de cuadro! de dilogo 9ue !olicitan in)ormacin del u!uario. A menudo> la! eleccione! del u!uario en lo! primero! cuadro! de dilogo in)luyen en lo! contenido! de lo! !iguiente!

cuadro! de dilogo. En la mayor5a de lo! a!i!tente!> el u!uario puede a'an*ar o retroceder en la !ecuencia de cuadro! de dilogo o hacer clic en el 1otn %inali*ar para aceptar todo! lo! 'alore! predeterminado!. Por !upue!to> podemo! crear a!i!tente! utili*ando VBA y !erie! de U!er%orm!. 6in em1argo> el modo m! e)iciente de crear un a!i!tente e! utili*ar un +nico U!er%orm y un control de pgina m+ltiple con la! )icha! oculta!. El !iguiente di1u7o mue!tra un e7emplo de un !imple a!i!tente de cuatro pa!o! 9ue con!ta de un +nico U!er%orm 9ue contiene un control de pgina m+ltiple. #ada pa!o del a!i!tente mue!tra una pgina di)erente del control de pgina m+ltiple.

Configurar el control de pgina mltiple para el asistente


#omen*amo! con un nue'o U!er%orm y a0adimo! un control de pgina m+ltiple. Por de)ecto> e!te control contiene do! pgina. Gacemo! clic con el 1otn derecho del ratn en la )icha de la pgina m+ltiple e in!ertamo! !u)iciente! pgina! nue'a! para controlar el a!i!tente :una pgina por cada pa!o del a!i!tente<. El e7emplo 9ue le mo!tramo! e! un a!i!tente de cuatro pa!o!> de modo 9ue el control de pgina m+ltiple tendr cuatro pgina!. =o! nom1re! de la! )icha! de la pgina m+ltiple no !on importante!. =a propiedad 6tyle del control tendr un 'alor )inal de 2 fmTabStyleNone. Mientra! tra1a7amo! con el U!er%orm 9uerremo! mantener la! )icha! 'i!i1le! para hacer m! )cil acceder a la! di)erente! pgina!.

A continuacin> a0adimo! lo! controle! de!eado! para cada pgina del control de pgina m+ltiple. Por !upue!to> e!to 'ariar dependiendo de la aplicacin. Puede 9ue tengamo! 9ue cam1iar el tama0o del control de pgina m+ltiple mientra! tra1a7amo! para tener e!pacio para lo! controle!.

Aadir los botones al UserForm del asistente


A continuacin a0adiremo! lo! 1otone! 9ue controlen el progre!o del a!i!tente. E!to! 1otone! !e colocan )uera del control de pgina m+ltiple por9ue !e u!an mienta! !e mue!tra cual9uiera de la! pgina!. =a mayor5a de lo! a!i!tente! tienen cuatro 1otone!: Cancelar: #ancela el a!i!tente. Anterior: Vuele al pa!o pre'io. Eurante el Pa!o ( del a!i!tente> e!te 1otn de1e e!tar de!ha1ilitado. Siguiente: A'an*a al !iguiente pa!o. Eurante el +ltimo pa!o> e!te 1otn de1e e!tar de!ha1ilitado. Finalizar: %inali*a el a!i!tente. En el e7emplo> e!to! 1otone! de comando !e llaman CancelButton> BackButton> NextButton y FinishButton. En alguno! ca!o!> el u!uario puede hacer clic en el 1otn Finalizar en cual9uier momento y aceptar lo! 'alore! predeterminado! para a9uello! elemento! 9ue el u!uario no ha de)inido. En otro! ca!o!> el a!i!tente nece!ita una re!pue!ta del u!uario para alguno! elemento!. En e!e ca!o> el 1otn Finalizar !e de!ha1ilita ha!ta 9ue !e realicen toda! la! entrada! nece!aria!.

Programar los botones del asistente


#ada uno de lo! cuatro 1otone! del a!i!tente nece!ita un procedimiento para controlar !u e'ento Click. A continuacin !e mue!tra el control de e'ento! para CancelButton. E!te procedimiento utili*a una )uncin MsgBox para 'eri)icar 9ue el u!uario 9uiere !alir realmente. 6i el u!uario hace clic en el 1otn 65> el U!er%orm !e de!carga !in tomar ninguna accin. Por !upue!to> e!te tipo de compro1acin e! opcional. Private Sub CancelButton_Click() Dim Msg As String Dim Ans As Integer Msg = "Cancelar el asistente?" Ans = MsgBox(Msg, vbQuestion + vbYesNo, APPNAME) If Ans = vbYes Then Unload Me End Sub =o! procedimiento! de control de e'ento! para lo! 1otone! Atrs y Siguiente !on lo! !iguiente!: Private Sub BackButton_Click() MultiPage1.Value = MultiPage1.Value - 1 UpdateControls End Sub Private Sub NextButton_Click() MultiPage1.Value = MultiPage1.Value + 1 UpdateControls End Sub

E!to! do! procedimiento! !on muy !imple!. #am1ian la propiedad Value del control de pgina m+ltiple y de!pu;! in'ocan a otro procedimiento llamado UpdateControls :9ue !e mue!tra a continuacin<. El procedimiento UpdateControls !e encarga de ha1ilitar y de!ha1ilitar lo! controle! BackButton y NextButton. Sub UpdateControls() Select Case MultiPage1.Value Case 0 BackButton.Enabled = False NextButton.Enabled = True Case MultiPage1.Pages.Count - 1 BackButton.Enabled = True NextButton.Enabled = False Case Else BackButton.Enabled = True NextButton.Enabled = True End Select ' Actualiza el ttulo Me.Caption = APPNAME & " Paso " _ & MultiPage1.Value + 1 & " de " _ & MultiPage1.Pages.Count

El campo Nombre es obligatorio If tbName.Text = "" Then FinishButton.Enabled = False Else FinishButton.Enabled = True End If End Sub El procedimiento cam1ia el t5tulo del U!er%orm para mo!trar el pa!o en el 9ue !e encuentra y el n+mero total de pa!o!. APPNAME e! una con!tante p+1lica de)inida en Module(. A continuacin> examina el campo del nom1re de la primera pgina :un cuadro de texto llamado tbName <. E!te e! un campo nece!ario> de modo 9ue no !e puede hacer clic en el 1otn %inali*ar. 6i el cuadro de texto e!t 'ac5o> !e de!ha1ilita FinishButtonB en ca!o contrario> !e ha1ilita.

'

Programar dependencias en un asistente


En la mayor5a de lo! a!i!tente!> una re!pue!ta del u!uario en un determinado pa!o puede a)ectar a lo 9ue !e mue!tra en el !iguiente pa!o. =o! 1otone! de opcin para la 'aloracin de un producto !lo e!tarn 'i!i1le! !i el u!uario indica un determinado producto. A e)ecto! de programacin> e!to !e con!igue !uper'i!ando el e'ento Change del control de pgina m+ltiple. #ada 'e* 9ue !e cam1ia el 'alor de la pgina m+ltiple :haciendo clic en lo! 1otone! Atrs o Siguiente<> !e e7ecuta el procedimiento MultiPage1_Change. 6i el control de pgina m+ltiple e!t en la +ltima )icha :Pa!o <> el procedimiento examina lo! 'alore! de lo! controle! de ca!illa de 'eri)icacin del pa!o . y reali*a lo! a7u!te! apropiado! en el pa!o . En e!te e7emplo> el cdigo utili*a do! matrice! de controle!> uno para lo! controle! de ca!illa de 'eri)icacin :pa!o .< y otro para lo! controle! de marco :pa!o <. El cdigo utili*a un 1ucle ForINext para ocultar lo! controle! de lo! producto! 9ue no !e utili*an y a7u!ta !u po!icin

'ertical. 6i ninguna de la! ca!illa! de 'eri)icacin del pa!o . e!t marcada> !e ocultan todo! lo! elemento! del pa!o excepto un cuadro de texto 9ue mue!tra Ga* clic en %inali*ar para !alir :!i no !e introdu7o un nom1re en el pa!o(< o 6e re9uiere un nom1re para el pa!o ( :!i no !e introdu7o un nom1re en el pa!o (<. El procedimiento MultiPage1_Change aparece a continuacin: Private Dim Dim Dim Dim ' ' Sub MultiPage1_Change() TopPos As Integer FSpace As Integer AtLeastOne As Boolean i As Integer

Actualizar pgina de puntuaciones If MultiPage1.Value = 3 Then Crea un array con casillas de verificacin Dim ProdCB(1 To 3) As MSForms.CheckBox Set ProdCB(1) = cbExcel Set ProdCB(2) = cbWord Set ProdCB(3) = cbAccess Crea un array con controles de marco Dim ProdFrame(1 To 3) As MSForms.Frame Set ProdFrame(1) = FrameExcel Set ProdFrame(2) = FrameWord Set ProdFrame(3) = FrameAccess TopPos = 22 FSpace = 8 AtLeastOne = False

'

'

Bucle por todos los productos For i = 1 To 3 If ProdCB(i) Then ProdFrame(i).Visible = True ProdFrame(i).Top = TopPos TopPos = TopPos + ProdFrame(i).Height + _ FSpace AtLeastOne = True Else ProdFrame(i).Visible = False End If Next i No usa productos? If AtLeastOne Then lblHeadings.Visible = True Image4.Visible = True lblFinishMsg.Visible = False Else lblHeadings.Visible = False Image4.Visible = False lblFinishMsg.Visible = True If tbName = "" Then lblFinishMsg.Caption = _ "Se requiere un nombre para el paso 1."

'

Else lblFinishMsg.Caption = _ "Haz clic en Finalizar para salir." End If End If End If End Sub

ealizar la tarea con el asistente


#uando el u!uario hace clic en el 1otn %inali*ar> el a!i!tente reali*a !u tarea: tran!)erir la in)ormacin de!de el U!er%orm a la !iguiente )ila 'ac5a de la ho7a. E!te procedimiento> llamado FinishButton_Click> e! muy claro. #omien*a determinando la !iguiente )ila 'ac5a de la ho7a y a!ignando a e!te 'alor una 'aria1le :r<. El re!to del procedimiento !implemente tra!lada lo! 'alore! de lo! controle! e introduce dato! en la ho7a. Private Sub FinishButton_Click() Dim r As Long r = Application.WorksheetFunction. _ CountA(Range("A:A")) + 1 ' Insertar el nombre Cells(r, 1) = tbName.Text Insertar el sexo Select Case True Case obMale: Cells(r, 2) = "Masculino" Case obFemale: Cells(r, 2) = "Femenino" Case obNoAnswer: Cells(r, 2) = "Desconocido" End Select Insertar Cells(r, Cells(r, Cells(r, productos 3) = cbExcel 4) = cbWord 5) = cbAccess

'

'

'

Insertar puntuaciones If obExcel1 Then Cells(r, 6) = "" If obExcel2 Then Cells(r, 6) = 0 If obExcel3 Then Cells(r, 6) = 1 If obExcel4 Then Cells(r, 6) = 2 If obWord1 Then Cells(r, 7) = "" If obWord2 Then Cells(r, 7) = 0 If obWord3 Then Cells(r, 7) = 1 If obWord4 Then Cells(r, 7) = 2 If obAccess1 Then Cells(r, 8) = "" If obAccess2 Then Cells(r, 8) = 0 If obAccess3 Then Cells(r, 8) = 1 If obAccess4 Then Cells(r, 8) = 2 Unload Me

End Sub

?ra! pro1ar el a!i!tente y compro1ar 9ue todo parece )uncionar correctamente> podemo! e!ta1lecer el 'alor para la propiedad 6tyle del control de pgina m+ltiple a 2 fmTabStyleNone.

!mular la funcin Msg"o#


=a )uncin MsgBox de VBA e! un poco di)erente por9ue> a di)erencia de la mayor5a de la! )uncione!> mue!tra un cuadro de dilogo. Pero> al igual 9ue la! dem! )uncione!> tam1i;n de'uel'e un 'alor: un n+mero entero 9ue repre!enta en 9u; 1otn hi*o clic el u!uario. E!te e7emplo e!tudia una )uncin per!onali*ada 9ue emula la )uncin MsgBox de VBA. Al principio> crear tal )uncin puede parecer 1a!tante )cil> pero no e! del todo cierto. =a )uncin MsgBox e! extraordinariamente 'er!til gracia! a lo! argumento! 9ue acepta. Por tanto> crear una )uncin 9ue emule MsgBox no e! una tarea )cil. =a cla'e de e!te e7ercicio no e! crear una )uncin alternati'a 9ue mue!tre men!a7e!. =a cla'e e! mo!trar cmo de!arrollar una )uncin relati'amente comple7a 9ue tam1i;n incorpora un U!er%orm. 6in em1argo> a alguna! per!ona! le! puede gu!tar la idea de !er capace! de per!onali*ar !u! men!a7e!. En e!e ca!o> de!cu1rirn 9ue e!ta )uncin e! muy )cil de per!onali*ar. Por e7emplo> pueden cam1iar la! )uente!> lo! colore!> el 1otn de texto y elemento! !imilare!. Gemo! llamado a e!ta )uncin 9ue emula a MsgBox MiMsgbox. =a emulacin no e! per)ecta. MiMsgBox tiene la! !iguiente! limitacione!: Co admite el argumento Helpfile :9ue a0ade un 1otn Ayuda> el cual> cuando !e hace clic !o1re ;l> a1re un archi'o de ayuda<. Co admite el argumento Context :9ue e!peci)ica la identidad del contexto para el archi'o de ayuda<. Co admite la opcin de !i!tema modal> 9ue detiene todo! lo! proce!o! de @indow! ha!ta 9ue !e re!ponde al cuadro de dilogo. =a !intaxi! pata MiMsgBox e!: MiMsgBox (mensaje [, botones] [, ttulo]) E!ta !intaxi! e! exactamente igual 9ue la !intaxi! de MsgBox> excepto 9ue no utili*a lo! do! +ltimo! argumento! opcionale! :Helpfile y Context<. MsgBox tam1i;n utili*a la! mi!ma! con!tante! prede)inida! 9ue MsgBox: '1FAFnly> '1Hue!tion> '1Ee)aultButton( y !imilare!.

!mulacin de Msg"o#$ el cdigo MiMsg"o#


=a )uncin MiMsgBox u!a un U!er%orm llamado MyMsgBoxForm. =a )uncin en !5 mi!ma> 9ue !e mue!tra a continuacin> e! muy corta. =a mayor parte del tra1a7o !e hace en el procedimiento UserForm_Initialize.

Function MiMsgBox(ByVal prompt As String, _ Optional ByVal buttons As Integer, _ Optional ByVal title As String) As Integer Prompt1 = prompt Buttons1 = buttons Title1 = title MiMsgBoxForm.Show MiMsgBox = UserClick End Function A continuacin !e mue!tra el cdigo utili*ado para e7ecutar la )uncin: prompt = "Est a punto de formatear su disco duro." prompt = prompt & vbCrLf & vbCrLf & "Desea continuar?" buttons = vbQuestion + vbYesNo title = "Existe un problema" Ans = MiMsgBox(prompt, buttons, title)

Por !upue!to> e!te e7emplo no 1orrar nue!tro di!co duro.

Cmo funciona la emulacin de Msg"o#


Gay 9ue de!tacar el u!o de cuatro 'aria1le! Public. =a! tre! primera! :Prompt1> Buttons1 y Title1< repre!entan lo! argumento! 9ue !e pa!an a la )uncin. =a otra 'aria1le :UserClick< repre!enta lo! 'alore! de'uelto! por la )uncin. El procedimiento UserForm_Initialize nece!ita un modo de o1tener e!ta in)ormacin y en'iarla de nue'o a la )uncin> y la +nica )orma de hacer e!to e! utili*ar la 'aria1le Public. El U!er%orm 9ue aparece a continuacin contiene cuatro controle! de imagen :uno para cada uno de lo! po!i1le! icono!<> tre! controle! de 1otn de comando y un control de cuadro de texto.

El cdigo del procedimiento UserForm_Initialize examina lo! argumento! y hace lo !iguiente: Eetermina 9u; imagen :!i la hay< !e mo!trar :y oculta la! otra!<. Eetermina 9u; 1otn :o 1otone!< !e mue!tra :y oculta lo! otro!<.

Eetermina 9u; 1otn e! el 1otn predeterminado. #entra lo! 1otone! en el cuadro de dilogo. Eetermina lo! t5tulo! de lo! 1otone! de comando. Eetermina la po!icin del texto dentro del cuadro de dilogo. Eetermina el ancho del cuadro de dilogo :utili*a una llamada AP- para o1tener la re!olucin del '5deo<. Eetermina la altura 9ue de1e tener el cuadro de dilogo. Mue!tra el U!er%orm. 6e incluyen otro! tre! procedimiento! de control de e'ento! :uno para cada 1otn de comando<. E!ta! rutina! determinan en 9u; 1otn !e hi*o clic y de'uel'en un 'alor para la )uncin a!ignando un 'alor a la 'aria1le UserClick. -nterpretar el !egundo argumento :buttons< e! un poco m! complicado. E!te argumento puede e!tar )ormado por 'aria! con!tante! a0adida! 7unta!. Por e7emplo> el !egundo argumento puede !er algo a!5: vbYesNoCancel + vbQuestion + vbDefaultButton3 E!te argumento crea un MsgBox con tre! 1otone! :S> No y Cancelar<> mue!tra el icono de pregunta y hace 9ue el tercer 1otn !ea el 1otn predeterminado. El argumento real e! / " :. J ., J /(,<. El o17eti'o era o1tener tre! )ragmento! de in)ormacin a partir de un +nico n+mero. =a !olucin implica con'ertir el argumento en un n+mero 1inario y de!pu;! examinar lo! 1it! e!pec5)ico!. Por e7emplo> el e9ui'alente 1inario de / " e! (444(444((. =o! d5gito! 1inario! de a 2 determinan la imagen 9ue !e mue!tra> lo! d5gito! de $ a (4 determinan 9u; 1otone! mo!trar y lo! d5gito! de ( y , determinan 9u; 1otn e! el 1otn predeterminado.

Utilizar la funcin MiMsg"o# en la emulacin de Msg"o#


Para utili*ar e!ta )uncin en nue!tro! propio! proyecto!> exportamo! el mdulo MiMsgBoxMod y el U!er%orm MyMsgBoxForm. A continuacin> importamo! e!to! do! archi'o! al proyecto. Ee!pu;! podremo! utili*ar la )uncin MiMsgBox en nue!tro cdigo como lo har5amo! con la )uncin MsgBox.

Un UserForm con controles deslizantes


A pe!ar de la! reducida! aplicacione! prctica! de e!ta t;cnica> el e7emplo de e!ta !eccin no! ayudar a comprender lo! e'ento! relacionado! con el ratn. El U!er%orm 9ue !e mue!tra a continuacin contiene tre! controle! de imagen. El u!uario puede utili*ar el ratn para arra!trar la! imgene! por el cuadro de dilogo.

#ada uno de lo! tre! controle! de imagen tiene do! procedimiento! de e'ento! a!ociado!: MouseDown y MouseMove. El procedimiento de e'ento para el control Image1 !e mue!tra a continuacin :lo! dem! controle! de imagen !on id;ntico! a e!te> excepto por el nom1re de cada control<: Private Sub Image1_MouseDown(ByVal Button As Integer, _ ByVal Shift As Integer, ByVal X As Single, ByVal _ Y As Single) ' Posicin de inicio cuando se presiona el botn OldX = X OldY = Y Image1.ZOrder 0 End Sub Private Sub Image1_MouseMove(ByVal Button As Integer, _ ByVal Shift As Integer, ByVal X As Single, ByVal _ Y As Single) ' Mueve la imagen If Button = 1 Then Image1.Left = Image1.Left + (X - OldX) Image1.Top = Image1.Top + (Y - OldY) End If End Sub

#uando !e hace clic con el 1otn del ratn> tiene lugar el e'ento MouseDown> y !e guardan la! po!icione! K e L del cur!or. 6e utili*an do! 'aria1le! p+1lica! para hacer un !eguimiento de la po!icin original de lo! controle!: OldX y OldY. E!te procedimiento tam1i;n modi)ica la propiedad ZOrder> 9ue coloca la imagen !o1re la! otra!.

#uando !e mue'e el ratn> el e'ento MouseMove ocurre repetidamente. El procedimiento del e'ento comprue1a el 1otn del ratn. 6i el argumento Button e! 1> !igni)ica 9ue el 1otn i*9uierdo del ratn e!t pre!ionado. En e!te ca!o> el control de imagen !e mue'e en relacin a !u antigua po!icin. ?am1i;n> o1!er'amo! 9ue el cur!or cam1ia cuando e!t !o1re la imagen. E!to !e de1e a 9ue la propiedad MousePointer e! 15 fmMousePointSizeAll. E!te e!tilo de cur!or !e utili*a com+nmente para indicar 9ue algo !e puede mo'er.

Un UserForm sin barra de t%tulo


Excel no o)rece ninguna manera de mo!trar directamente un U!er%orm !in 1arra de t5tulo. Pero e!te reto e! po!i1le con la llamada de alguna! nue'a! )uncione! AP-. El !iguiente di1u7o mue!tra un U!er%orm !in 1arra de t5tulo.

Ftro e7emplo de U!er%orm !in 1arra de t5tulo !e o)rece en el di1u7o !iguiente. E!te cuadro de dilogo contiene un control de imagen y un control de 1otn de comando. Para mo!trar un U!er%orm !in 1arra de t5tulo nece!itamo! cuadro )uncione! AP-: GetWindowLong> SetWindowLong> DrawMenuBar> y FindWindowA. El procedimiento UserForm_Initialize in'oca e!ta! )uncione!: Private Sub UserForm_Initialize() Dim lngWindow As Long, lFrmHdl As Long lFrmHdl = FindWindowA(vbNullString, Me.Caption) lngWindow = GetWindowLong(lFrmHdl, GWL_STYLE) lngWindow = lngWindow And (Not WS_CAPTION) Call SetWindowLong(lFrmHdl, GWL_STYLE, lngWindow) Call DrawMenuBar(lFrmHdl) End Sub

Un pro1lema de no mo!trar la 1arra de t5tulo> e! 9ue el u!uario no tiene )orma de cam1iar la po!icin del cuadro de dilogo. =a !olucin e! utili*ar lo! e'ento! MouseDown y MouseMove> de!crito! en la !eccin anterior.

&imular una barra de 'erramientas con un UserForm


=a creacin de 1arra! de herramienta! en la! 'er!ione! anteriore! a Excel ,44" era relati'amente )cil. #on Excel ,44" e! impo!i1le. Para !er exacto!> e! po!i1le crear una 1arra de herramienta! per!onali*ada con VBA> pero Excel ,44" ignora mucha! de la! in!truccione! VBA. En Excel ,44"> toda! la! 1arra! de herramienta! per!onali*ada! !e mue!tran en el grupo Barras personalizadas> de la )icha Complementos. E!ta! 1arra! de herramienta! no !e pueden mo'er> cam1iar de tama0o> ni acoplar. E!ta !eccin de!cri1e cmo crear una 1arra de herramienta! alternati'a: un U!er%orm no modal 9ue !imula una 1arra de herramienta! )lotante. El !iguiente di1u7o mue!tra un U!er%orm 9ue puede !u!tituir a una 1arra de herramienta!. El U!er%orm contiene ocho controle! de imagen> y cada uno de ello! e7ecuta una macro.

Al 'er> en el editor de Vi!ual Ba!ic> el U!er%orm en modo Ei!e0o> podremo! o1!er'ar 9ue: =o! controle! no e!tn alineado! El U!er%orm no e! el tama0o )inal. El tama0o de la 1arra de t5tulo e! e!tndar. El cdigo VBA !e encarga de la apariencia. Alinea lo! controle! y a7u!ta la imagen del U!er%orm para 9ue no !e malga!te ning+n e!pacio> adem!> el cdigo emplea )uncione! AP- de @indow! para reducir el tama0o de la 1arra de t5tulo> 7u!to como una 1arra de herramienta! de 'erdad. Para hacer 9ue el U!er%orm !e pare*ca toda'5a m! a una 1arra de herramienta!> e!ta1leceremo! la propiedad ControlTipText de cada control de imagen. E!to har 9ue !e mue!tre in)ormacin !o1re la herramienta !imilar a la de una 1arra de herramienta! cada 'e* 9ue pa!emo! el cur!or !o1re e!e control. 6i a1rimo! el archi'o corre!pondiente a e!te e7emplo> de lo! ad7unto! al manual> tam1i;n o1!er'aremo! 9ue la! imgene! cam1ian ligeramente cuando pa!amo! el cur!or !o1re ella!. E!to e! por9ue cada control de imagen tiene a!ociado un controlador de e'ento! MouseMove 9ue cam1ia la propiedad SpecialEffect. E!te e! el controlador de e'ento! MouseMove de Image1 :lo! dem! !on id;ntico!<. Private Sub Image1_MouseMove(ByVal Button As Integer, _ ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single) Call NoRaise Image1.SpecialEffect = fmSpecialEffectRaised End Sub

E!te procedimiento in'oca al procedimiento NoRaise> 9ue de!acti'a el e)ecto e!pecial de relie'e de cada control. Private Sub NoRaise() Dim ctl As Control For Each ctl In Controls ctl.SpecialEffect = fmSpecialEffectFlat Next ctl End Sub

El e)ecto )inal e! 9ue el u!uario con!igue cierta in)ormacin 'i!ual cuando el cur!or pa!a !o1re el control> como !uceder5a con una 1arra de herramienta! de 'erdad. 6in em1argo> e!to e! todo lo 9ue da de !5 la !imulacin de la 1arra de herramienta!. Co e! po!i1le cam1iar el tama0o del U!er%orm :por e7emplo> hacer 9ue la! imgene! !e mue!tren 'erticalmente en lugar de hori*ontalmente<. L> por !upue!to> tampoco e! po!i1le acoplar nue!tra 1arra de herramienta! a uno de lo! 1orde! de la 'entana de Excel.

Un UserForm de tamao a(ustable


Excel utili*a 'ario! cuadro! de dilogo de tama0o a7u!ta1le. Por e7emplo> puede cam1iar!e el tama0o del cuadro de dilogo Administrador de nombres !i hacemo! clic en la e!9uina in)erior derecha y arra!tramo!. 6i 9ueremo! crear un U!er%orm de tama0o a7u!ta1le> pronto de!cu1riremo! 9ue no hay una )orma de hacerlo directamente. Una !olucin e! recurrir a la! llamada! de la AP- de @indow!. El m;todo )unciona> pero e! complicado de con)igurar. En e!ta !eccin 'eremo! una t;cnica m! !encilla para crear un U!er%orm de tama0o a7u!ta1le. El !iguiente di1u7o mue!tra el U!er%orm de!crito en e!ta !eccin. #ontiene un control de cuadro de li!ta 9ue mue!tra lo! dato! de una ho7a. F1!er'amo! la! 1arra! de de!pla*amiento del cuadro de li!ta. E!to 9uiere decir 9ue hay m! in)ormacin de la 9ue !e puede 'er. ?am1i;n o1!er'amo! la e!9uina in)erior derecha del cuadro de dilogo. Mue!tra un control de tama0o 9ue pro1a1lemente no! re!ulte )amiliar. =a! imgene! 9ue !e mue!tran !on caractere! de la )uente @ingding. Para introducir el carcter en una celda !eleccionamo! en Excel Insertar>Te to>Smbolo. Ee!pu;! lo copiamo! al portapapele! y lo! pegamo! en la propiedad Picture en la 'entana Propiedades. E!ta e! una )orma rpida y !encilla de in!ertar imgene! a lo! controle! de lo! U!er%orm. Al arra!trar la e!9uina in)erior derecha o1!er'amo! 9ue el cuadro de li!ta tam1i;n aumenta o di!minuye !u tama0o 7unto con el del U!er%orm y 9ue el 1otn #errar !e mantiene en la mi!ma po!icin relati'a. Podemo! aumentar el tama0o del U!er%orm ha!ta lo! l5mite! del monitor. Un U!er%orm puede tener un ancho y alto mximo de (,.,$">,/ unidade!. =a altura m5nima e! de ,/."/ unidade! :igual 9ue la altura de la 1arra de t5tulo<> y el ancho m5nimo e! de (4/ unidade!. El truco e!t a9u5 en el control de eti9ueta> 9ue !e agrega al U!er%orm en tiempo de e7ecucin. El control de tama0o en la e!9uina in)erior derecha e! en realidad un control de eti9ueta 9ue mue!tra la letra MFN :carcter (((< de la )uente Marlett :grupo de caractere! ,<. E!te control> llamado objResizer> !e agrega al U!er%orm en el procedimiento UserForm_initialize: Private Sub UserForm_Initialize() ' Agrega el control de tamao al formulario Set objResizer = Me.Controls.Add("Forms.label.1", MResizer, True) With objResizer

With .Font .Name = "Marlett" .Charset = 2 .Size = 16 .Bold = True End With .BackStyle = fmBackStyleTransparent .AutoSize = True .BorderStyle = fmBorderStyleNone .Caption = "o" .MousePointer = fmMousePointerSizeNWSE .ForeColor = RGB(100, 100, 100) .ZOrder .Top = Me.InsideHeight - .Height .Left = Me.InsideWidth - .Width End With End Sub

E!ta t;cnica !e 1a!a en lo! !iguiente! hecho!: El u!uario puede mo'er un control de un U!er%orm> como 'imo! anteriormente. Exi!ten e'ento! 9ue pueden identi)icar lo! mo'imiento! del ratn y la! coordenada! del cur!or. Co! re)erimo! a MouseDown y MouseMove. El cdigo VBA puede cam1iar el tama0o de un U!er%orm en tiempo de e7ecucin> pero un u!uario no puede. 6i e!tudiamo! e!to! hecho! de manera creati'a> eremo! 9ue e! po!i1le traducir lo! mo'imiento! del u!uario de un control de eti9ueta en in)ormacin 9ue !e puede utili*ar para a7u!tar el tama0o de un U!er%orm. #uando un u!uario hace clic en el o17eto de eti9ueta objResizer> !e e7ecuta el procedimiento 9ue controla lo! e'ento! objResizer_MouseDown: Private Sub objResizer_MouseDown(ByVal Button As Integer, _ ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single) If Button = 1 Then LeftResizePos = X TopResizePos = Y End If End Sub

E!te procedimiento !e e7ecuta +nicamente !i el 1otn i*9uierdo del ratn e!t pre!ionado :e! decir> el argumento Button e! (< y el cur!or e!t en la eti9ueta objResizer. =a! coordenada! K e L del ratn !e almacenan en la! 'aria1le! de mdulo LeftResizePos y TopResizePos. =o! mo'imiento! po!teriore! del ratn inician el e'ento MouseMove> y el controlador de e'ento! objResizer_MouseMove !e pone en accin. E!ta e! una 'er!in inicial de e!te procedimiento:

Private Sub objResizer_MouseMove(ByVal Button As _ Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single) If Button = 1 Then With objResizer .Move .Left + X - LeftResizePos, .Top + Y TopResizePos Me.Width = Me.Width + X - LeftResizePos Me.Height = Me.Height + Y - TopResizePos .Left = Me.InsideWidth - .Width .Top = Me.InsideHeight - .Height End With End If End Sub

6i e!tudiamo! el cdigo> 'eremo! 9ue la! propiedade! Width y Height !e a7u!tan 1a!ndo!e en el mo'imiento del control de eti9ueta objResizer.

El pro1lema del di1u7o anterior> de!de luego> e! 9ue el otro control del U!er%orm no re!ponde al nue'o tama0o del U!er%orm. Ee1er5a expandir!e el cuadro de li!ta> y de1er5a cam1iar la po!icin del 1otn de comando para 9ue permane*ca en la e!9uina in)erior derecha. E! nece!ario m! cdigo VBA para a7u!tar lo! controle! del U!er%orm cuando !e modi)ica !u tama0o. E!cri1iremo! e!te cdigo nue'o en el procedimiento controlador de e'ento! objResizerMouseMove. =a !iguiente declaracin !e encarga de ello: ' Ajusta el cuadro de lista On Error Resume Next With ListBox1 .Width = Me.Width - 22 .Height = Me.Height - 100 End With On Error GoTo 0

'Ajusta el botn Cerrar With CloseButton .Left = Me.Width - 70 .Top = Me.Height - 54 End With

E!to! do! controle! !e a7u!tan en relacin al tama0o del U!er%orm :e! decir> Me<. Ee!pu;! de in!ertar e!te cdigo nue'o> el cuadro de dilogo )unciona !in pro1lema!. El u!uario lo puede aumentar como nece!ite> y lo! controle! !e a7u!tan al tama0o. =a parte 9ue pre!enta un mayor de!a)5o al crear un cuadro de dilogo de tama0o a7u!ta1le e! lograr 9ue lo! controle! !e a7u!ten. #uando tenemo! m! de uno o do! controle! la! co!a! !e pueden complicar 1a!tante.

Controlar varios botones de UserForm con un controlador de eventos


#ada 1otn de comando de un U!er%orm de1e tener !u propio procedimiento para controlar !u! e'ento!. Por e7emplo> !i tenemo! do! 1otone! de comando> nece!itaremo! al meno! do! procedimiento! de control de e'ento!. Private Sub CommandButton1_Click() ' Aqu va el cdigo End Sub Private Sub CommandButton2_Click() ' Aqu va el cdigo End Sub

En otra! pala1ra!> no !e puede a!ignar una macro para 9ue !e e7ecute cuando !e haga clic en cual9uier 1otn de comando. #ada controlador de e'ento! Click e!t conectado a !u 1otn de comando. 6in em1argo> podemo! hacer 9ue cada controlador de e'ento! llame a otra macro 9ue lo! incluya a todo! en lo! procedimiento! de control de e'ento!> pero tendremo! 9ue pa!ar el argumento 9ue indi9ue en 9u; 1otn !e hi*o clic. En lo! !iguiente! e7emplo!> al hacer clic en #ommandButton( o #ommandButton, !e e7ecuta el procedimiento ButtonClick y el +nico argumento indica al procedimiento ButtonClick en 9u; 1otn !e hi*o clic. Private Sub CommandButton1_Click() Call ButtonClick(1) End Sub Private Sub CommandButton2_Click() Call ButtonClick(2) End Sub

6i !u U!er%orm tiene mucho! 1otone! de comando> con)igurar e!to! procedimiento! de control de e'ento! puede !er muy la1orio!o. Mucha! per!ona! pre)erirn tener un +nico procedimiento 9ue pueda determinar en 9u; 1otn !e hi*o clic y reali*ar la accin apropiada. E!ta !eccin de!cri1e una )orma de eliminar e!ta limitacin utili*ando un mdulo de cla!e para de)inir una nue'a cla!e. =o! !iguiente! pa!o! de!cri1en cmo crear el e7emplo de U!er%orm 9ue !e mue!tra a continuacin:

(. #reamo! el U!er%orm de la )orma ha1itual y a0adimo! 'ario! 1otone! de comando :e!te e7emplo tiene (2 1otone!<. El e7emplo a!ume 9ue el )ormulario !e llama U!er%orm(. ,. -n!ertamo! un mdulo de cla!e en el proyecto :utili*amo! Insertar>M!dulo de clase<> lo llamamo! BtnClass e introducimo! el !iguiente cdigo. ?endremo! 9ue per!onali*ar el procedimiento ButtonGroup_Click.

Private Sub ButtonGroup_Click() Dim Msg As String Msg = "Usted hizo clic en " & ButtonGroup.Name & vbCrLf & vbCrLf Msg = Msg & "Nombre: " & ButtonGroup.Caption & vbCrLf Msg = Msg & "Posicin izquierda: " & ButtonGroup.Left & vbCrLf Msg = Msg & "Posicin superior: " & ButtonGroup.Top MsgBox Msg, vbInformation, ButtonGroup.Name End Sub .. -n!ertamo! un mdulo de VBA e!tndar e introducimo! el !iguiente cdigo. E!ta rutina !implemente mue!tra el U!er%orm.

Sub ShowDialog() UserForm1.Show End Sub

. En el mdulo de cdigo para el U!er%orm> introducimo! el !iguiente procedimiento UserForm_Initialize. E!te procedimiento lo inicia el e'ento Initialize del U!er%orm. F1!er'amo! 9ue el cdigo excluye un 1otn llamado OKButton del grupo de 1otone!. Por lo tanto> hacer clic en el 1otn Aceptar no har 9ue !e e7ecute el procedimiento ButtonGroup_Click.

Private Sub UserForm_Initialize() Dim ButtonCount As Integer Dim ctl As Control Crea los objetos Button ButtonCount = 0 For Each ctl In UserForm1.Controls If TypeName(ctl) = "CommandButton" Then If ctl.Name <> "OKButton" Then 'Omite el _ OkButton ButtonCount = ButtonCount + 1 ReDim Preserve Buttons(1 To ButtonCount) Set Buttons(ButtonCount).ButtonGroup = ctl End If End If Next ctl End Sub ?ra! reali*ar e!to! pa!o!> podemo! e7ecutar el procedimiento ShowDialog para mo!trar el U!er%orm. Gaciendo clic en cual9uiera de lo! 1otone! de comando :excepto en Aceptar< !e e7ecuta el procedimiento ButtonGroup_Click. '

&eleccionar un color en un UserForm


El e7emplo de e!ta !eccin e! una )uncin 9ue mue!tra un cuadro de dilogo :la idea e! !imilar a la )uncin M!gBox> pero un poco m! comple7o<. =a )uncin> llamada 8etA#olor> de'uel'e un 'alor de color: Function GetAColor() As Variant UserForm1.Show GetAColor = ColorValue End Function

Podemo! utili*ar la )uncin GetAColor con una in!truccin como la !iguiente: UserColor = GetAColor ()

E7ecutar e!ta in!truccin mue!tra el U!er%orm. El u!uario !elecciona un color y hace clic en 6eleccionar color. A continuacin> la )uncin a!igna el 'alor del color 9ue ha !eleccionado el u!uario a la 'aria1le UserColor. El !iguiente di1u7o mue!tra el U!er%orm 9ue contiene tre! controle! de 1arra de de!pla*amiento> uno por cada color de la paleta de color del li1ro. El 'alor de cada 1arra de de!pla*amiento 'a de!de 4 a ,//.

El U!er%orm GetAColor tiene otro detalle: recuerda el +ltimo color !eleccionado. #uando la )uncin )inali*a> lo! tre! 'alore! de la 1arra de de!pla*amiento !e almacenan en el regi!tro de @indow!> con el !iguiente cdigo :APPNAME e! una cadena de)inida en Module(<: SaveSetting APPNAME, "Colors", "RedValue", _ ScrollBarRed.Value SaveSetting APPNAME, "Colors", "BlueValue", _ ScrollBarBlue.Value SaveSetting APPNAME, "Colors", "GreenValue", _ ScrollBarGreen.Value

El procedimiento UserForm_initialize recupera e!to! 'alore! y lo! a!igna a la! 1arra! de de!pla*amiento. ScrollBarRed.Value = GetSetting(APPNAME, "Colors", _ "RedValue", 128) ScrollBarGreen.Value = GetSetting(APPNAME, "Colors", _ "GreenValue", 128) ScrollBarBlue.Value = GetSetting(APPNAME, "Colors", _ "BlueValue", 128) El +ltimo argumento de la )uncin GetSetting e! el 'alor predeterminado> 9ue !e utili*ar en ca!o de no encontrar la cla'e del regi!tro. En e!te ca!o> cada color predeterminado !er (,$> lo 9ue genera una tonalidad de gri!. =a! )uncione! SaveSetting y GetSetting !iempre utili*an e!ta cla'e del regi!tro: GOELD#U33EC?DU6E3P6o)twareQVB and VBA Program 6etting!P

Mostrar un grfico en un UserForm


#urio!amente> no hay una )orma directa de mo!trar un gr)ico en un U!er%orm. Por !upue!to> podemo! copiar el gr)ico y pegarlo en la propiedad Picture de un control de imagen> pero e!to crea una imagen e!ttica del gr)ico y no mo!trar ning+n cam1io 9ue realicemo! en ;l. E!ta !eccin de!cri1e cmo mo!trar un gr)ico en un U!er%orm. El !iguiente di1u7o mue!tra un U!er%orm con un gr)ico 9ue !e mue!tra como un o17eto de imagen. El gr)ico en realidad !e encuentra en una ho7a y el U!er%orm !iempre mue!tra el gr)ico actual. E!ta t;cnica )unciona copiando el gr)ico a un archi'o de gr)ico! temporal y de!pu;!> con la )uncin LoadPicture> e!peci)icamo! el archi'o temporal de la propiedad Picture del control de imagen.

Pasos generales para mostrar un grfico en un UserForm


Para mo!trar un gr)ico en un U!er%orm> !eguimo! e!to! pa!o! generale!: (. #reamo! un gr)ico de la )orma ha1itual. ,. -n!ertamo! un U!er%orm y a0adimo! un control de imagen. .. E!cri1imo! cdigo de VBA para guardar el gr)ico como archi'o gi) y luego a!ignamo! el archi'o gi) a la propiedad Picture del control de imagen. Para ello tenemo! 9ue utili*ar la )uncin de VBA LoadPicture. . A0adimo! otro! elemento! em1ellecedore! a nue!tro gu!to. Por e7emplo> el U!er%orm del archi'o de la demo!tracin contiene controle! 9ue no! permiten cam1iar el tipo de gr)ico. Alternati'amente> podemo! e!cri1ir cdigo para mo!trar 'ario! gr)ico!.

)uardar un grfico como arc'ivo gif


El !iguiente cdigo mue!tra cmo crear un archi'o gi) llamado temp.gi)< a partir de un gr)ico :en e!te ca!o> el primer o17eto gr)ico de una ho7a llamada Eato!<. Set currentChart = Sheets("Datos").ChartObjects(1).Chart Fname = Application.DefaultFilePath & Application.PathSeparator & "temp.gif" CurrentChart.Export Filename:=Fname, FilterName:="GIF"

Cambiar la propiedad Picture del control de imagen


6i el control de imagen del U!er%orm !e llama -mage(> la !iguiente in!truccin carga la imagen :repre!entada por la 'aria1le Fname< en el control de imagen: Image1.Picture = LoadPicture(Fname)

6i de!ea o1tener m! e7emplo! de U!er%orm! o aprender otra! t;cnica! con VBA le in'itamo! a 'i!itar nue!tra we1> http://www.ayudaexcel.com> donde encontrar la coleccin m! completa de e7emplo! con VBA> plantilla!> manuale!> truco! y academia! donde !e imparten cur!o! de Excel.

You might also like