Sin duda una de las cuestiones más tediosas de Excel es el momento en que queremos Ocultar o Mostrar varias hojas a la vez.. entonces nos damos cuenta que el estándar de Excel únicamente nos permite realizar la acción hoja a hoja!!!...
Algo a mejorar por Microsoft ;-)
La propuesta de hoy es construir un UserForm (formluario de usuario) que gestione fácilmente esta acción múltiple de ocultar/mostrar.
Emplearé un código muy práctico (algo largo) ya expuesto en el blog (ver) que nos habilita la operación simplemente arrastrando los elementos...
Comenzaremos creando un Userform al que he llamado 'frmOcultarMostrar'.
Este formulario tiene los siguientes controles:
Dos ListBox: ListVisible y ListOcultas.
Dos etiquetas
Un Botón: CmdCerrar
El formulario tendría un diseño similar a este:
Insertamos el siguiente código dentro de la ventana de código del UserForm desde el editor de VB:
Basta ejecutar o lanzar el formulario y arrastrar hojas de un ListBox a otro...
El código tiene un control de error para evitar que todas las hojas queden ocultas... lo que es imposible para Excel.
Es un código un poco largo, pero la funcionalidad y los eventos:
_MouseMove
_BeforeDropOrPaste
y
_BeforeDragOver
se deben repetir para ambos ListBox, ya que el arrastrar de una posición a otra debe estar configurada...
Algo a mejorar por Microsoft ;-)
La propuesta de hoy es construir un UserForm (formluario de usuario) que gestione fácilmente esta acción múltiple de ocultar/mostrar.
Emplearé un código muy práctico (algo largo) ya expuesto en el blog (ver) que nos habilita la operación simplemente arrastrando los elementos...
Comenzaremos creando un Userform al que he llamado 'frmOcultarMostrar'.
Este formulario tiene los siguientes controles:
Dos ListBox: ListVisible y ListOcultas.
Dos etiquetas
Un Botón: CmdCerrar
El formulario tendría un diseño similar a este:
Insertamos el siguiente código dentro de la ventana de código del UserForm desde el editor de VB:
Dim matrizHojas() As Boolean
Private Sub UserForm_Initialize()
ReDim matrizHojas(Sheets.Count)
'limpiamos los ListBox del formulario
Me.ListVisible.Clear
Me.ListOcultas.Clear
'recorremos todas las hojas del libro
For i = 1 To Sheets.Count
'llenamos nuestra Array con TRUE o FALSE
matrizHojas(i) = Sheets(i).Visible
If matrizHojas(i) = True Then
'si es visible lo cargamos en el ListBox de 'hojas visibles'
Me.ListVisible.AddItem Sheets(i).Name
Else
'si NO es visible lo cargamos en el ListBox de 'hojas ocultas'
Me.ListOcultas.AddItem Sheets(i).Name
End If
Next i
End Sub
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Private Sub ListOcultas_BeforeDragOver(ByVal Cancel As MSForms.ReturnBoolean, ByVal Data As _
MSForms.DataObject, ByVal x As Single, _
ByVal Y As Single, ByVal DragState As Long, _
ByVal Effect As MSForms.ReturnEffect, ByVal Shift As Integer)
'este evento se produce cuando se está ejecutando una operación de arrastrar y colocar.
Cancel = True
Effect = 1
End Sub
Private Sub ListVisible_BeforeDragOver(ByVal Cancel As MSForms.ReturnBoolean, ByVal Data As _
MSForms.DataObject, ByVal x As Single, _
ByVal Y As Single, ByVal DragState As Long, _
ByVal Effect As MSForms.ReturnEffect, ByVal Shift As Integer)
'este evento se produce cuando se está ejecutando una operación de arrastrar y colocar.
Cancel = True
Effect = 1
End Sub
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Private Sub ListOcultas_BeforeDropOrPaste(ByVal Cancel As MSForms.ReturnBoolean, _
ByVal Action As Long, ByVal Data As MSForms.DataObject, ByVal x As Single, _
ByVal Y As Single, ByVal Effect As MSForms.ReturnEffect, ByVal Shift As Integer)
'este otro evento se produce cuando el usuario está a punto de colocar o pegar datos en un objeto.
Cancel = True
Effect = 1
Dim iIndex As Long, col As Integer
With ListVisible
'determinamos cuál ha sido el elemento seleccionado
iIndex = ListVisible.ListIndex
'añadimos un elemento al ListBox de destino...
ListOcultas.AddItem .List(iIndex, 0), 0
'incorporamos los valores de las diferentes columnas
'desde el ListBox de origen al ListBox destino
For col = 1 To ListVisible.ColumnCount - 1
ListOcultas.List(0, col) = .List(iIndex, col)
Next col
End With
End Sub
Private Sub ListVisible_BeforeDropOrPaste(ByVal Cancel As MSForms.ReturnBoolean, _
ByVal Action As Long, ByVal Data As MSForms.DataObject, ByVal x As Single, _
ByVal Y As Single, ByVal Effect As MSForms.ReturnEffect, ByVal Shift As Integer)
'este otro evento se produce cuando el usuario está a punto de colocar o pegar datos en un objeto.
Cancel = True
Effect = 1
Dim iIndex As Long, col As Integer
With ListOcultas
'determinamos cuál ha sido el elemento seleccionado
iIndex = ListOcultas.ListIndex
'añadimos un elemento al ListBox de destino...
ListVisible.AddItem .List(iIndex, 0), 0
'incorporamos los valores de las diferentes columnas
'desde el ListBox de origen al ListBox destino
For col = 1 To ListOcultas.ColumnCount - 1
ListVisible.List(0, col) = .List(iIndex, col)
Next col
End With
End Sub
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Private Sub ListVisible_MouseMove(ByVal Button As Integer, _
ByVal Shift As Integer, ByVal x As Single, ByVal Y As Single)
'este evento se produce cuando el usuario mueve el mouse...
Dim MyDataObject As DataObject
If Button = 1 Then
Set MyDataObject = New DataObject
Dim Effect As Integer
'Con el método .SetText copiamos una cadena de texto al objeto DataObject...
MyDataObject.SetText ListVisible.Value
'el método .StartDrag da inicio a una operación de arrastrar y colocar para un objeto DataObject.
Effect = MyDataObject.StartDrag
End If
For i = 0 To ListVisible.ListCount - 1
If ListVisible.Selected(i) = True Then
For j = 1 To Sheets.Count
If Sheets(j).Name = ListVisible.List(i) Then
matrizHojas(j) = False
On Error GoTo finaliza
Sheets(j).Visible = False
End If
Next j
End If
Next i
'refrescamos situación....
ActualizaFormulario
Exit Sub
finaliza:
'controlamos que siempre quede al menos una hoja visible...
If ListVisible.ListCount = 1 Then
MsgBox "No se pueden ocultar todas las hojas.." & vbCrLf & "Siempre debe quedar al menos una visible"
ActualizaFormulario
Exit Sub
End If
End Sub
Private Sub ListOcultas_MouseMove(ByVal Button As Integer, _
ByVal Shift As Integer, ByVal x As Single, ByVal Y As Single)
'este evento se produce cuando el usuario mueve el mouse...
Dim MyDataObject As DataObject
If Button = 1 Then
Set MyDataObject = New DataObject
Dim Effect As Integer
'Con el método .SetText copiamos una cadena de texto al objeto DataObject...
MyDataObject.SetText ListOcultas.Value
'el método .StartDrag da inicio a una operación de arrastrar y colocar para un objeto DataObject.
Effect = MyDataObject.StartDrag
End If
For i = 0 To ListOcultas.ListCount - 1
If ListOcultas.Selected(i) = True Then
For j = 1 To Sheets.Count
If Sheets(j).Name = ListOcultas.List(i) Then
matrizHojas(j) = True
Sheets(j).Visible = True
End If
Next j
End If
Next i
'refrescamos situación....
ActualizaFormulario
End Sub
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Sub ActualizaFormulario()
'limpiamos los ListBox del formulario
Me.ListVisible.Clear
Me.ListOcultas.Clear
'recorremos todas las hojas del libro
For i = 1 To Sheets.Count
'llenamos nuestra Array con TRUE o FALSE
matrizHojas(i) = Sheets(i).Visible
If matrizHojas(i) Then
'si es visible lo cargamos en el ListBox de 'hojas visibles'
Me.ListVisible.AddItem Sheets(i).Name
Else
'si NO es visible lo cargamos en el ListBox de 'hojas ocultas'
Me.ListOcultas.AddItem Sheets(i).Name
End If
Next i
End Sub
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Private Sub CmdCerrar_Click()
Unload Me
End SubBasta ejecutar o lanzar el formulario y arrastrar hojas de un ListBox a otro...
El código tiene un control de error para evitar que todas las hojas queden ocultas... lo que es imposible para Excel.
Es un código un poco largo, pero la funcionalidad y los eventos:
_MouseMove
_BeforeDropOrPaste
y
_BeforeDragOver
se deben repetir para ambos ListBox, ya que el arrastrar de una posición a otra debe estar configurada...




No hay comentarios:
Publicar un comentario
Nota: solo los miembros de este blog pueden publicar comentarios.