miércoles, 25 de junio de 2014

Aprovecha el Verano y aprende Excel...

¿Necesitas aprender Excel?, sin duda una buena base te permitirá avanzar en tu trabajo.
Aprende con los mejores: Edición de Cursos de Excel y Macros online con tutor personal de Julio de 2014.


Los cursos de Excel y Macros abiertos para este mes de Julio son:

Curso Excel Avanzado para versiones 2007/2010

(ver más)

Curso Excel Nivel Medio

(ver más)


Curso Tablas dinámicas en Excel

(ver más)

Curso preparación MOS Excel 2010 (Examen 77-882)

(ver más)


Curso Excel Financiero

(ver más)


Curso Macros Iniciación

(ver más)

Curso Macros Medio

(ver más)


Esta nueva edición de Cursos de Excel y macros en modalidad elearning (online) comienzan el día 1 de julio de 2014; y la matrícula estará abierta hasta el día 10.

Excelforo: con la confianza de siempre....estás a tiempo!!

También formación Excel a empresas. Explota los recursos a tu alcance (ver más).


Informarte sin compromiso en cursos@excelforo.com o directamente en www.excelforo.com.

lunes, 23 de junio de 2014

Permutaciones en Excel y Access.

En una entrada anterior vimos cómo conseguir un listado de las combinaciones de varios elementos, respondiendo a una estructura muy concreta...
En la entrada de hoy veremos, rindiendo homenaje a Myrna Larson, su magnífico código VBA que lista las combinaciones o permutaciones en nuestra hoja de Excel.


Es importante conocer las diferencias entre ambos conceptos, por lo que dejaré aquí un par de vínculos a Wikipedia:
Permutaciones (ver)
Combinaciones (ver)
Variaciones (ver)

A modo de resumen, una Permutación es la variación del orden o disposición de los elementos de un conjunto dado; mientras que una Combinación es la variación de número de formas en que se pueden extraer subconjuntos a partir de un conjunto dado, esto es, sin importar el orden o disposición.
Si el orden no importa, es una combinación.
Si el orden sí importa es una permutación.


Como siempre dejo explicaciones más concretas a los especialistas en el tema...

El código propuesto por Myrna (al que he modificado mínimamente para su correcto funcionamiento en Excel 2007 y +), funciona a partir de la indicación dispuesta en la celda A1 (P si deseamos ver las Permutaciones o C si Combinaciones). En A2 introduciremos el subconjunto de elementos que queremos ver (2 si queremos ver subconjuntos de dos elementos, 3 de tres, etc). Y a partir de A3 añadiremos los elementos a Permutar/Combinar.

Permutaciones en Excel y Access.


Para ejecutar la macro de Myrna añadiremos un botón al que hemos asignado la macro llamada: 'ListPermutations'

Incorporaremos el código en un módulo de nuestro Proyecto de VB:

Dim vAllItems As Variant
Dim Buffer() As String
Dim BufferPtr As Long
Dim Results As Worksheet
'
'  Posted by Myrna Larson
'  July 25, 2000
'  Microsoft.Public.Excel.Misc
'  Subject:  Combin

Sub ListPermutations()
  Dim Rng As Range
  Dim PopSize As Long 'Integer
  Dim SetSize As Integer
  Dim Which As String
  Dim N As Double
  Const BufferSize As Long = 4096
  Set Rng = Selection.Columns(1).Cells
  If Rng.Cells.Count = 1 Then
    Set Rng = Range(Rng, Rng.End(xlDown))
  End If
  PopSize = Rng.Cells.CountLarge - 2
  If PopSize < 2 Then GoTo DataError
  SetSize = Rng.Cells(2).Value
  If SetSize > PopSize Then GoTo DataError
  Which = UCase$(Rng.Cells(1).Value)
  Select Case Which
  Case "C"
    N = Application.WorksheetFunction.Combin(PopSize, SetSize)
  Case "P"
    N = Application.WorksheetFunction.Permut(PopSize, SetSize)
  Case Else
    GoTo DataError
  End Select
  If N > Cells.CountLarge Then GoTo DataError
  Application.ScreenUpdating = False
  Set Results = Worksheets.Add
  vAllItems = Rng.Offset(2, 0).Resize(PopSize).Value
  ReDim Buffer(1 To BufferSize) As String
  BufferPtr = 0
  If Which = "C" Then
    AddCombination PopSize, SetSize
  Else
    AddPermutation PopSize, SetSize
  End If
  vAllItems = 0
  Application.ScreenUpdating = True
  Exit Sub

DataError:
  If N = 0 Then
    Which = "Enter your data in a vertical range of at least 4 cells. " _
      & String$(2, 10) _
      & "Top cell must contain the letter C or P, 2nd cell is the number " _
      & "of items in a subset, the cells below are the values from which " _
      & "the subset is to be chosen."
  Else
    Which = "This requires " & Format$(N, "#,##0") & _
      " cells, more than are available on the worksheet!"
  End If
  MsgBox Which, vbOKOnly, "DATA ERROR"
  Exit Sub
End Sub

''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'AddPermutation
Private Sub AddPermutation(Optional PopSize As Long = 0, _
  Optional SetSize As Integer = 0, _
  Optional NextMember As Integer = 0)
Static iPopSize As Integer
Static iSetSize As Integer
Static SetMembers() As Integer
Static Used() As Integer
Dim i As Integer
If PopSize <> 0 Then
  iPopSize = PopSize
  iSetSize = SetSize
  ReDim SetMembers(1 To iSetSize) As Integer
  ReDim Used(1 To iPopSize) As Integer
  NextMember = 1
End If
For i = 1 To iPopSize
  If Used(i) = 0 Then
    SetMembers(NextMember) = i
    If NextMember <> iSetSize Then
      Used(i) = True
      AddPermutation , , NextMember + 1
      Used(i) = False
    Else
      SavePermutation SetMembers()
    End If
  End If
Next i
If NextMember = 1 Then
  SavePermutation SetMembers(), True
  Erase SetMembers
  Erase Used
End If
End Sub

''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'AddCombination
Private Sub AddCombination(Optional PopSize As Long = 0, _
  Optional SetSize As Integer = 0, _
  Optional NextMember As Integer = 0, _
  Optional NextItem As Integer = 0)
Static iPopSize As Integer
Static iSetSize As Integer
Static SetMembers() As Integer
Dim i As Integer
If PopSize <> 0 Then
  iPopSize = PopSize
  iSetSize = SetSize
  ReDim SetMembers(1 To iSetSize) As Integer
  NextMember = 1
  NextItem = 1
End If
For i = NextItem To iPopSize
  SetMembers(NextMember) = i
  If NextMember <> iSetSize Then
    AddCombination , , NextMember + 1, i + 1
  Else
    SavePermutation SetMembers()
  End If
Next i
If NextMember = 1 Then
  SavePermutation SetMembers(), True
  Erase SetMembers
End If
End Sub

''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'SavePermutation
Private Sub SavePermutation(ItemsChosen() As Integer, _
  Optional FlushBuffer As Boolean = False)
Dim i As Integer, sValue As String
Static RowNum As Long, ColNum As Long
If RowNum = 0 Then RowNum = 1
If ColNum = 0 Then ColNum = 1
If FlushBuffer = True Or BufferPtr = UBound(Buffer()) Then
  If BufferPtr > 0 Then
    If (RowNum + BufferPtr - 1) > Rows.Count Then
      RowNum = 1
      ColNum = ColNum + 1
      If ColNum > 256 Then Exit Sub
    End If
    Results.Cells(RowNum, ColNum).Resize(BufferPtr, 1).Value _
      = Application.WorksheetFunction.Transpose(Buffer())
    RowNum = RowNum + BufferPtr
  End If
  BufferPtr = 0
  If FlushBuffer = True Then
    Erase Buffer
    RowNum = 0
    ColNum = 0
    Exit Sub
  Else
    ReDim Buffer(1 To UBound(Buffer))
  End If
End If
'construct the next set
For i = 1 To UBound(ItemsChosen)
  sValue = sValue & ", " & vAllItems(ItemsChosen(i), 1)
Next i
'and save it in the buffer
BufferPtr = BufferPtr + 1
Buffer(BufferPtr) = Mid$(sValue, 3)
End Sub



Si sobre el ejemplo de la imagen anterior Lanzamos la macro, obtendremos un listado como el siguiente:
1, 10, 100
1, 100, 10
10, 1, 100
10, 100, 1
100, 1, 10
100, 10, 1

Como vemos son las Permutaciones de los tres elementos dados {1, 10 , 100} tomados en subconjuntos de tres elementos.


jueves, 19 de junio de 2014

Combinaciones con Access.

Una cuestión recurrente en muchos foros es el tema de listar combinaciones y/o permutaciones a partir de ciertos elementos dados.
En los últimos meses, también a mi blog, han llegado varias cuestiones sobre el tema. En particular me llamó la atención la que muestro seguidamente, ya que aporta un punto diferenciador al estándar de combinaciones/permutaciones...
Esta es la pregunta planteada:

Buenos días, quisiera saber si teniendo varios datos en diferentes casillas y columnas se podría reflejar en Excel todas las posibles combinaciones entre todos. Ejemplo:

Columna
Fila.    A.    B.
1.        1.     2.
2.        3.     4
3.        5.     6

Solución en hoja de Excel:
Columna
Fila.    A.      B
1.        1.      2
2.        1.      4
3.        1.      6
4.        3.      2
5.        3.      4
6.        3.      6
7.        5.      2
8.        5.      4
9.        5.      6



He de decir que en esta ocasión la solución la encontraremos fácilmente en Access, ya que con dos sencillo pasos, obtendremos la solución solicitada por el usuario.
Lo primero, a parte de abrir una base de datos en Access (obvio), será crear una Tabla con dos campos que podría tener el siguiente diseño:

Combinaciones con Access.


El segundo paso es completar nuestra Tabla1 con los datos del usuario:

Combinaciones con Access.



De momento sencillo... El siguiente paso es crucial.
Crearemos una consulta con el siguiente diseño:

Combinaciones con Access.


Estamos listos para ejecutar la consulta y obtener el resultado esperado:

Combinaciones con Access.



La clave del asunto está en la creación de la consulta, donde hemos agregado dos veces la misma Tabla1, y muy importante, sin ninguna relación entre ellas !!!... además, para conseguir el resultado, hemos agregado el campo Datos01 (columna1) de la primera Tabla, y el campo Datos02 (columna2) de la segunda Tabla (la misma Tabla repetida).
Con estas acciones conseguimos 'barajar' los elementos mezclando los del campo1 (Datos01) con los del campo2 (Datos02).

Es fundamental repetir esta configuración exactamente como se indica, un pequeño cambio nos llevará a un resultado diferente...

martes, 17 de junio de 2014

Formatos de ficheros Excel (extensiones) más habituales.

Hablaré hoy de un tema, creo, interesante: Los formatos o extensiones de los ficheros Excel.
Sin duda todos conocemos la extensión .xlsx o la vieja .xls ... pero hay muchas más.

Hoy me centraré en las extensiones más importantes de las versiones de Excel 2007 y superiores.
  • .xlsx (Libro de Excel): Formato de archivo basado en XML predeterminado de Excel 2007 y superior.
    No se pueden almacenar códigos de macros de Microsoft Visual Basic para Aplicaciones (VBA) ni hojas de macro de Office Excel 4.0 (.xlm).
  • .xlsm (Libro de Excel con código VB): Formato de archivo basado en XML y habilitado para macros de Excel Excel 2007 y superior.
    Almacena código de macros de VBA y hojas de macros de Excel 4.0 (.xlm).
  • .xltx (Plantilla): Formato de archivo predeterminado de una plantilla de Excel 2007 y superior.
    No puede almacenar código de macros de VBA ni hojas de macros de Excel 4.0 (.XML).
  • .xltm (Plantilla con código VB): Formato de archivo predeterminado de una plantilla de Excel 2007 y superior.
    Almacena código de macros de VBA u hojas de macros de Excel 4.0 (.XML).
  • .xlam (Complemento de Excel): Complemento basado en XML y habilitado para macros de Excel 2007 y superior. Se trata de un programa complementario que está diseñado para ejecutar un código adicional.
    Admite el uso de proyectos de VBA y hojas de macros de Excel 4.0 (.xlm).
  • .xlw (Libro de Excel 4.0): Formato de archivo de Excel 4.0 que guarda solo hojas de cálculo, hojas de gráfico y hojas de macro.
    Puede abrir un libro en este formato de archivo en Excel, pero no puede guardar un archivo de Excel en este formato.
  • .xlsb (Libro binario de Excel): Formato de archivo binario (BIFF12) de Excel 2007 y superior.
    Se trata de un formato de archivo que se carga y guarda rápidamente para usuarios que buscan la manera más rápida de cargar un archivo de datos.
    Es compatible con proyectos de VBA, hojas de macros de Excel y todas las características nuevas que se usan en Excel 2007, Excel 2010 y Excel 2013. Sin embargo, no se trata de un formato de archivo XML y, por tanto, no es óptimo para obtener acceso a contenido ni manipularlo sin usar Excel 2013, Excel 2010 o Excel 2007, y el modelo de objetos.


Me detendré y comentaré la última de las extensiones listadas, y es que el Libro binario de Excel (.xlsb) fue creado con el objetivo de facilitar el proceso de compresión, guardado, apertura y funcionamiento de ficheros que contiene una gran cantidad de información.

La extensión .xlsb (libro binario) fue implementada a partir de la versión Excel 2007, solucionando el problema de manejo de hojas de cálculo que contenían mucha información, las cuales necesitaban mucho tiempo para abrirse, así como la dificultad que representaba manejar este tipo de ficheros por los frecuentes bloqueos que se producían al utilizarlos.

No todo son beneficios al usar esta extensión, la desventaja de utilizar este tipo de ficheros reside en que a diferencia de los ficheros con extensión .xlsx, estos ficheros no se pueden recuperar parcialmente !!, es decir en el caso de disponer algún documento defectuoso o corrupto no es viable recuperar parte de la información de una manera rápida y eficiente.

En definitiva, y por finalizar, un archivo binario (.xlsb) tiene un sistema de almacenaje de datos nativo de Excel- BIFF12 (Binary Interchange File Format) y no XML. Recordemos que el formato XML es un formato que Ms creo para adaptarse a las exigencias impuestas de código abierto o libre, que en general consume un número muy alto de recursos.

Cuando los archivos son de un tamaño superior a 1Mb o cuando tienen que ejecutar gran cantidad de código y/o muchos registros, los archivos binarios son sensiblemente más rápidos y además, sin pérdida de fidelidad en formatos, código, datos, etcétera.

En una prueba de un Libro habilitado con macros (.xslm) y convertido a Libro binario (.xlsb), pasé de un tamaño del fichero de 14.408 Kb a 6.432 KB !!!, y ninguna diferencia visible en cuanto a formatos, funcionalidades, macros, objetos, etc.).

miércoles, 11 de junio de 2014

Detectar celda con fórmula en Excel.

A través de un foro en el que participo se me planteó cómo detectar si una celda contiene o no una fórmula:
...Yo necesito resaltar de alguna manera si mi celda tiene formula o ya tipee manualmente un número. (tengo espacio como para alojar una formula en celda adyacente y de ahí sacar el formato condicional para A1),...

Lo tendremos muy fácil si trabajamos con Excel 2013, donde existe la función
=ESFORMULA(referencia)
que comprueba si existe una referencia a una celda que contiene una fórmula y devuelve VERDADERO o FALSO.
Siendo:
Referencia: es una referencia a la celda que se desea probar; puede ser una referencia de celda, una fórmula o un nombre que hace referencia a una celda.


Sin embargo esta función no existe en versiones anteriores, así que la solución para Excel 2010 y previas, pasa por el uso de las macrofunciones (ver ejemplo).

Para ello nos basaremos en el ejemplo siguiente, donde:

Detectar celda con fórmula en Excel.


En la imagen vemos cómo la celda B1 NO es una fórmula (es sólo un valor), mientras que el resto de celdas B2:B4 SÍ contienen algún tipo de fórmula...

Para construir nuestra macrofunción que llamaremos, no puede ser de otra forma, EsFormula (cualquier nombre valdrá), nos situaremos en la celda C1 (muy importante).
Crearemos un Nombre definido con el nombre indicado y en la sección 'Se refiere a:' insertaremos la siguiente función:
=INDICAR.CELDA(48;!$B1)+AHORA()*0=1

Detectar celda con fórmula en Excel.


Listo, ya podemos insertar en la celda C1 nuestra función:
=EsFormula
lo que nos devolverá FALSO.
Y al insertarlo en C2, C3 o C4 obtendremos VERDADERO

lunes, 9 de junio de 2014

Reparto acumulado controlado.

En la entrad de hoy explicaré qué fórmula nos servirá para poder distribuir una cantidad siguiendo unos tramos, según el acumulado.
Vemos mejor un ejemplo:

Reparto acumulado controlado.


lo que vemos en la imagen es un importe a distribuir en la celda B1, y en el rango B2:B5 los intervalos de reparto.. esto es, el primer tramo sólo admite hasta 500 (los primeros 500 euros, por ejemplo); el segundo tramo tomará el importe o cantidad desde 501 hasta 1.000; de tal forma que entre el primer y segundo tramo conseguiríamos repartir 1.500 euros.
El tercer tramo el importe de 1.501 hasta 3.000; por tanto si tuviéramos para repartir una cantidad de 2.900 obtendríamos 500 para el primer tramo, 1.000 para el segundo (500 + 1.000) y finalmente para el tercer tramo los últimos 1.400 (500 + 1.000 + 1.400) que completarían los 2.900 a repartir.
El último tramo recogerá los importes excedentes de 3.000. En el caso del ejemplo, a repartir 4.000, vemos que se cubre el primer tramo: 500, el segundo: 1.000 (500 + 1.000), el tercero: 1.500 (500 + 1.000 + 1.500) y parcialmente el cuarto: 1.000 (500 + 1.000 + 1.500 + 1.000 = 4.000 repartidos).


Si la regla de reparto está clara, toca ver la fórmula que nos devuelve estos valores. Así en la celda C2 incluimos (y luego arrastramos hacía abajo):
=MIN(B2;$B$1-SUMA($C$1:C1))


Una parte de la fórmula:
$B$1-SUMA($C$1:C1)
nos devuelve la parte aún no repartida.
Por otro lado tenemos B2 que nos dice el máximo a repartir en el tramo en cuestión...

Si nos quedamos, como indica la fórmula, con el MINimo de ambas cantidades, obtendremos para cada tramo la cantidad correspondiente...

OJO, este ejemplo sólo es válido para cantidades a repartir de hasta 5.000!!

jueves, 5 de junio de 2014

VBA: Cambiar color de la fuente dentro de una celda...

Quizá te preguntes de qué voy a hablar hoy... El asunto es sencillo, mediante un procedimiento Sub vamos a conseguir cambiar el color de la fuente dentro de una celda, pero para caracteres específicos (NO para todos).
Se trata por tanto de conseguir 'remarcar' ciertos caracteres dentro de una celda. Y como una imagen vale más que mil palabras, este es el objetivo y resultado:



Probablemente la idea esté algo más clara ahora...

En un módulo cualquiera de nuestro proyecto de VBA insertamos el siguiente procedimiento:

Sub CambiaFuentePalabra()
'para palabras y Letras.
Dim Rng As Range, celda As Range, posicion As Integer
Dim palabra As String

'rango donde actuamos
Set Rng = Range("B1:B11")
On Error Resume Next
palabra = Application.InputBox(Prompt:="Introduce una palabra o letra", Title:="Para cambiar el color de la fuente de una palabra o letra", Type:=2)
'si se queda vacío salimos del proceso....
If palabra = "" Then Exit Sub

'realizamos la búsqueda para celda del rango
For Each celda In Rng
    'encontramos la posición donde comienza la palabra o letra
     posicion = InStr(1, celda, palabra, vbTextCompare)
        'lanzamos un bucle dentro de cada celda del rango
        'hasta que no encontremos nada
        Do Until posicion = 0
             'cambiamos la Fuente de la palabra o letra a color azul y negrita
             With celda.Characters(posicion, Len(palabra)).Font
                .Color = vbBlue
                .Bold = True
             End With
             'y seguimos buscando en la celda a partir de la última posición encontrada
             posicion = InStr(posicion + 1, celda, palabra, vbTextCompare)
        Loop
Next celda
End Sub



Vemos que el procedimiento es simple, nos pregunta el texto (palabra, letra o caracter) a buscar, y a continuación recorre celda por celda del rango dado (en mi caso B1:B11); y dentro de cada celda realiza un barrido de los caracteres mediante la función de VBA: InStr.

Esta función, bastante empleada, tiene la siguiente sintáxis:
InStr([inicio,] cadena1, cadena2[, comparación])
siendo los argumentos:
inicio (opcional): Expresión numérica que establece la posición inicial para cada búsqueda. Si se omite, la búsqueda comienza en la posición del primer carácter. Si inicio contiene un valor Null, se produce un error. El argumento inicio se requiere si se especifica 'comparación'.
cadena1 (obligatorio): Expresión de cadena en la que se busca.
cadena2 (obligatorio): Expresión de cadena buscada.
comparación (opcional): Especifica el tipo de comparación de cadena. Si compare es Null, ocurre un error. Si se omite 'comparación', el valor Option 'comparación' determina el tipo de comparación, que puede ser:
  1. vbUseCompareOption ó valor -1 := Realiza una comparación con los valores de la instrucción Option 'comparación'.
  2. vbBinaryCompare ó valor 0 := Realiza una comparación binaria.
  3. vbTextCompare o valor 1 := Realiza una comparación textual.
  4. vbDatabaseCompare ó valor 2 := Sólo para Microsoft Access. Realiza una comparación basada en la información en las bases de datos.

lunes, 2 de junio de 2014

VBA: Ocultar y Mostrar los Nombres definidos.

Toca hoy un pequeño procedimiento para ocultar a la vista (o mostrar) los Nombres definidos existentes en nuestro Libro de trabajo.

¿Qué motivo podríamos tener para ocultar a la vista del usuario los Nombres definidos?... bueno, uno muy sencillo, 'proteger' la integridad de nuestros vínculos y referencias frente al usuario del Libro...

Una ventaja de lo que vamos a proponer es que en todo caso los nombres (ocultos o visibles) son plenamente operativos y funcionales, exactamente igual que si estuvieran a la vista!!.


Crearemos un módulo en el Proyecto de VBA en nuestro Editor de VB, donde insertaremos los dos siguientes procedimientos Sub, una que oculta y otro que muestra todos los Nombres definidos del Libro:

Sub MuestraNombres()
'muestra los nombres definidos
Dim n As Name

'recorremos TODOS los Nombres definidos del Libro
For Each n In ThisWorkbook.Names
    'si está oculto lo hace visible....
    If n.Visible = False Then n.Visible = True
Next n
End Sub
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Sub OcultaNombres()
'oculta los nombres definidos
Dim n As Name

'recorremos TODOS los Nombres definidos del Libro
For Each n In ThisWorkbook.Names
    'si está visble lo oculta....
    If n.Visible Then n.Visible = False
Next n
End Sub



Recordemos, aún estando Ocultos los Nombres definidos son funcionales.. es decir, podemos usarlos en nuestras fórmulas, podemos ir a ellos desde el Cuadro de nombres, etc...

Otra sencilla macro que nos permite saber de la existencia de Nombres definidos ocultos consistiría en listar, sobre la Hoja de cálculo, todos los Nombres ocultos.
Para ello creamos el siguiente procedimiento:

Sub ListaNombresOcultos()
'Lista todos los nombres ocultos!!!
Dim n As Name
fila = 1
For Each n In ActiveWorkbook.Names
    'lo listamos en la columna A y B (nombre y Se refiere a:)
    'sólo si está oculto...
    If n.Visible = False Then
        Cells(fila, "A") = n.Name
        Cells(fila, "B") = " " & n.RefersTo
        fila = fila + 1
    End If
Next n
End Sub



Finalmente os propongo un último procedimiento que permita al usuario decidir qué Nombres definidos quiere Ocultar...
En nuestro módulo del Proyecto de VBA incluimos:

Sub Ocultar_Nombres()
'macro para Ocultar Nombres definidos..

'definimos variables
Dim NomDef As Name, Pregunta As String

'recorremos TODOS los Nombres definidos del Libro
For Each NomDef In ActiveWorkbook.Names

    'preguntamos al usuario si quiere ocultarlo
    Pregunta = MsgBox(Prompt:="Ocultar Nombre definido " & Chr(10) & _
        NomDef.Name & "?" & Chr(10) & _
        "que Se refiere a: " & Chr(10) & NomDef.RefersTo, Buttons:=vbYesNo)

    'si la respuesta es Sí, entonces lo ocultamos....
    If Pregunta = vbYes Then NomDef.Visible = False

Next NomDef
End Sub