miércoles, 31 de julio de 2024

84 - Cómo llamar a otros libros para compartir información.

En esta entrada veremos cómo llamar a los libros cuando necesitamos invocar su nombre desde una macro, ya sea para capturar  información o enviarla a otros libros.


La macro se encuentra en el libro Ventas. Desde el libro Pedido se trae información a éste libro activo y también al libro de Taller. Como segundo paso también moveremos datos entre diferentes hojas del libro Ventas.

En el código siguiente solo dejaré las instrucciones de declaración de variables y un pase como ejemplo. El pegado puede ser como en el ejemplo, 'Paste Special', solo 'Paste' o cualquier otro tipo de pegado como los vistos en el video Nº 71 de mi canal.

Macro ubicada en un módulo del libro VENTAS (libro activo).

NOTA: En el video, la ruta de los libros se toma a partir del libro Ventas, el que contiene la macro. Pero en caso de que se encuentre, por ejemplo, en otro disco (Ej.1) o en un servidor (Ej.2), las instrucciones serían de este modo:

Ejemplo 1:
          ruta = "D:\AL_TRABAJO_2023\Javi_Prueba_IMAGENES\Datos\"
          nbreLibro = "Consultas Julio.xlsm"
          Workbooks.Open (ruta & nbreLibro)

Ejemplo 2: 
          ruta = "\\EMPRESA\Sucursal1\Depto.Pedidos\Marketing y ventas\"
          nbreLibro = "Consultas Julio.xlsm"
          Workbooks.Open (ruta & nbreLibro)

Sub Registra_Pedido()
Dim libV As Workbook, libP As Workbook, libT As Workbook
Dim hoV As Worksheet, hoP As Worksheet
Dim hoE As Worksheet
Dim ini As Integer    'filas en hoja Ventas
Dim sFila As Integer  'fila en hoja Entregas
Dim ruta As String
Dim nbreLibro As String
Application.ScreenUpdating = False
'libro y hoja de Ventas
Set libV = ActiveWorkbook
Set hoV = libV.Sheets("Control de Ventas")
    'se deja la hoja desprotegida y sin filtros
    With hoV                      
        .Select
        .Unprotect
        If .FilterMode = True Then .ShowAllData
        
'se establece primera fila libre para el registro
        ini = .Range("B" & Rows.Count).End(xlUp).Row + 1 
    End With              
'libro y hoja de origen (Pedido)
ruta = ThisWorkbook.Path & "/"

'*** CONTROLAR QUE EXISTA LA CARPETA Y EL LIBRO
    On Error Resume Next
    midire = ThisWorkbook.Path & "/PEDIDOS REGISTRADOS"
    'si la carpeta existe la guarda como ruta
    If Dir(midire, vbDirectory) = "" Then
        MsgBox "No se encuentra la subcarpeta de Pedidos. El proceso se cancela."
        Exit Sub
    End If
    'se solicita el nombre del Pedido a registrar 
    '(ver en el módulo 1 otras maneras de obtener ese nbre.)
    nbreLibro = InputBox("Ingresa el nro de Pedido para registrar en el libro de Ventas.")
    If Dir(midire & "/" & nbreLibro) = "" Then
        MsgBox "No se encuentra el libro de Pedidos. El proceso se cancela."
        Exit Sub
    End If
    On Error GoTo 0
'*******

Workbooks.Open (ruta & "PEDIDOS REGISTRADOS/" & nbreLibro)    
Set libP = ActiveWorkbook
Set hoP = libP.Sheets("Pedido")

'libro y hoja de destino (Taller)
On Error GoTo sinLibroTaller
Workbooks.Open (ruta & "Libro TALLER.xlsm")
Set libT = ActiveWorkbook
On Error GoTo 0
MsgBox "A continuación se procederá a pasar la información del Pedido al Sistema de Ventas.", , "INFORMACIÓN"

'-------------- PASA de LIBRO PEDIDOS a LIBRO VENTAS ------------
libP.Activate
hoP.Select
'pase de campos
hoV.Range("H" & ini) = Range("C7")
hoV.Range("I" & ini) = Range("E7")

'------INSERTA HOJA EN TALLER y se registran campos del PEDIDO--
'rango de la hoja Pedido que será copiado en la nueva hoja de Taller
Range("A66:J160").Copy
libT.Activate
'se agrega una nueva hoja en el libro Taller que se acaba de activar
Sheets.Add After:=Sheets(Sheets.Count)
'el rango se pega a partir de A3 con un pegado especial.
Range("A3").Select
Selection.PasteSpecial Paste:=xlPasteColumnWidths, Operation:=xlNone, _
    SkipBlanks:=False, Transpose:=False
ActiveSheet.Paste
'se copìan otros rangos. AHORA LA HOJA ACTIVA ES LA NUEVA DE TALLER
'se indica el origen anteponiendo el objeto 'hoP'
hoP.Range("A24:C32,F24:J32").Copy Destination:=ActiveSheet.[L2]
'se asigna un nombre a la nueva hoja de Taller
ActiveSheet.Name = hoP.Range("C7")
ActiveWorkbook.Save     'guarda y cierra libro Taller
ActiveWorkbook.Close

'------------- Se cierra libro Pedidos quedando activo el libro Ventas    ---------
libP.Close True   

'------------- PASA DATOS DESDE VENTAS A HOJA auxiliar del mismo libro ---
libV.Activate
Set hoE = libV.Sheets("Entregas")
With hoE
    .Select
    .Unprotect
End With
    'se busca el fin de la tabla, agregando otra fila y redimensionando la misma.
    Set tablax = hoE.ListObjects(1)
    sFila = tablax.Range.Columns(1).Cells.Find("*", SearchOrder:=xlByRows, SearchDirection:=xlPrevious).Row + 1
    sFila = sFila + 1
    miRango = .Range(Cells(6, 2), Cells(sFila, 10)).Address
    tablax.Resize Range(miRango)
    'pase de datos a la nueva fila
    Range("B" & sFila) = hoV.Range("A" & ini)
    Range("D" & sFila) = hoV.Range("E" & ini)
    Range("D" & sFila).NumberFormat = "m/d/yyyy"
    Range("B" & sFila).Select
ActiveSheet.Protect , DrawingObjects:=True, Contents:=True, Scenarios:=True _
        , AllowFormattingCells:=True, AllowFormattingColumns:=True, _
        AllowFormattingRows:=True, AllowSorting:=True, AllowFiltering:=True
'-----------------------------------------------------------------------------------------
'se selecciona la 1ra.hoja de Ventas dejando seleccionada la fila del registro
hoV.Select 
ActiveSheet.Range("A" & ini).Select
ActiveSheet.Protect , DrawingObjects:=True, Contents:=True, Scenarios:=True _
        , AllowFormattingCells:=True, AllowFormattingColumns:=True, _
        AllowFormattingRows:=True, AllowSorting:=True, AllowFiltering:=True
'ActiveWorkbook.Save            'opcional
MsgBox "Fin del proceso de captura del Pedido.", , "Información"
Exit Sub

sinLibroTaller:
    MsgBox "No se encontró el libro Taller en la carpeta activa. El proceso se cancela."
End Sub


Ver video Nº 84 desde aquí.

Descargar el libro de ejemplo desde aquí


miércoles, 17 de julio de 2024

83 - El Administrador de Nombres y sus múltiples usos.

Es una de las herramientas más útiles a la hora de trabajar con validación de datos, listas desplegables, Tablas y Macros. Veremos a continuación sus principales usos.

CASO 1: cuando una misma lista (con nro. fijo de elementos) será utilizada en 1 o varias hojas con celdas con validación de datos. O en formularios, en algún control desplegable. El típico caso es el de los meses del año o días de semana.
Muchos usuarios colocan la lista en la primera hoja donde la van a utilizar. Y en las celdas con validación, en el campo Origen colocan ese rango. O a veces colocan allí la lista de elementos separados con punto y coma.
El problema surge cuando necesitamos utilizar esa lista de meses o días en otras hojas y tenemos que repetir el rango o recordar en qué hoja se encuentra ya creada.



SOLUCIÓN: seleccionar el rango (en este ejemplo desde Enero a Diciembre) y desde el menú Fórmulas, Administrador de nombres, asignar un Nombre (por ej: Meses), en el campo Ámbito' optar por 'Libro' y en el campo 'Se refiere a' introducir o seleccionar la hoja y el rango ocupado por esa lista.

Luego en cada celda con validación de datos ( o en los desplegables de algún Userform) donde se requiere mostrar la lista para seleccionar algún elemento, la opción será colocar ese nombre como se muestra en la imagen siguiente:



CASO 2: una lista dinámica que será utilizada en varias hojas con celdas con validación de datos (o controles desplegables en un Userform). El caso típico son las listas de Conceptos que pueden irse incrementando.  


SOLUCIÓN: Seleccionar una celda de la lista y desde el Administrador de nombres, Nuevo. Asignar un nombre, Ambito = Libro y en el campo 'Se refiere a' colocar la siguiente fórmula: 

=DESREF(Listas!$B$16;0;0;CONTARA(Listas!$B$16:$B$200;1);-1)

Argumentos del ejemplo: nombre de la hoja que contiene a la lista (Listas!), la celda del primer elemento ($B$16) y la celda hasta donde puede llegar el total de elementos ($B$200)




CASO 3: cuando una columna de una hoja se utilice para mostrar en desplegables. Aquí la lista también será dinámica, es decir que a medida que se agreguen datos a la hoja se irá incrementando el nro. de elementos que se mostrará en los desplegables. El caso típico son las hojas 'Base' como lista de Productos, Clientes u otras bases del sistema.

SOLUCIÓN: Si se trata de una hoja en formato de rango, seleccionar la columna y utilizar la función DESREF tal como vimos en el Caso 2, permitiendo así el agregado de elementos en esa columna indicando un máximo de filas (en exceso) que se considere que puede llegar a tener la base. 

=DESREF(Clientes!$B$4;0;0;CONTARA(Clientes!$B$4:$B$20000;1);-1)

Si se trata de una hoja en formato Tabla, en el campo 'Se refiere a' colocar solamente el nombre de la Tabla y la columna. Aquí no es necesario utilizar la función DESREF.
=nbre_tabla[nbre_columna]



CASO 4: Uso de listas dependientes. Es decir, cuando según la selección en una lista será la lista que se mostrará en otro desplegable. Y así tantas listas como desplegables se encuentre en la hoja o en un formulario.
Algunos usos: 
  1. Categoría de conceptos, Subcategoría.
  2. Lista de países, provincias, departamentos, localidades.
  3. Listado de carpetas, subcarpetas, archivos (se puede considerar varios niveles de subcarpetas)
  4. Lista de Personal: Planta o Sucursal, Área de trabajo, Nivel o categoría, Nombre.
SOLUCIONES: habrá que crear listas y a cada una de ellas asignarles un nombre y un rango de valores. Ese rango puede ser fijo o dinámico (en este caso con el uso de la función DESREF.). Es necesario que cada lista tenga por nombre el elemento de donde proviene.

Para el pto.1: En la siguiente imagen vemos que tenemos varias listas de Conceptos. Al momento de registrar un pago vamos a elegir una categoría y según esa selección se nos mostrará la lista de subcategorías.



NOTA: Como en este caso el nombre creado como 'Conceptos' corresponde a celdas de una fila y no de columna, no es posible asignarlo en la propiedad RowSource del primer control ComboBox6. Sino que se tendrá que rellenar mediante programación al momento de Inicializar el formulario. 

Private Sub UserForm_Initialize()

For Each ct In Range("Conceptos")      'nombre del rango entre comillas

    ComboBox6.AddItem ct.Text

Next ct

'el resto de las instrucciones para este evento


Y para el segundo control desplegable, de Subcategorías, estas serán las instrucciones, donde la propiedad RowSource toma como rango el texto del control anterior.

Private Sub ComboBox6_AfterUpdate()

If ComboBox6 = "" Then

       ComboBox7.RowSource = "": ComboBox7.Clear    

Else

       ComboBox7.RowSource = "=" & Trim(ComboBox6.Text)

End If

End Sub


Para el pto.2:  Para la siguiente imagen se crearon las siguientes listas: 
  • PAISES
  • Argentina, Bolivia y el resto de países. 
  • Cordoba, Misiones y el resto de provincias por cada país.
  • Punilla, Calamuchita y el resto de departamentos por cada provincia.
  • Cosquín, La Falda y el resto de localidades por cada departamento.

NOTA: Como el rango 'Paises' se encuentra en una columna (y no en fila como en el ejemplo anterior), aquí sí es posible establecer, desde el modo diseño, la propiedad RowSource del primer desplegable (PAIS)


Y para el resto de los controles seguimos el ejemplo del punto anterior, con los eventos Change o AfterUpdate. O como en el libro que se puede descargar (ver enlace al pie) donde utilicé el evento Enter.

IMPORTANTE: si se van a utilizar varias listas en el libro, recomiendo utilizar una hoja para contenerlas y así encontrarlas a todas en un mismo lugar.


Descargar libro de ejemplo desde aquí.

Ver video Nº 83 desde aquí.










sábado, 22 de junio de 2024

82 - Mostrar un rango Excel en un control de Imagen de un Userform

 Siguiendo con el tema iniciado en el VIDEO Nº 81, aquí veremos como subir esa imagen creada de un rango filtrado de una hoja Excel, a un control Image de un Userform.
Nuestro libro contará con una hoja de datos (en el ejemplo corresponde a una Tabla) y un Userform.
En un módulo tendremos la subrutina que llamará a ese formulario. Puede ser asignada a un botón o ser llamada desde el menú Desarrollador/Programador.

Sub llamaUF()

Range("B4").Select

'se quita el posible autofiltro, mostrando la tabla completa.

If ActiveSheet.FilterMode = True Then ActiveSheet.ShowAllData

UserForm1.Show

End Sub

El formulario de registro, además de los controles necesarios para esa tarea, contará con un control Image (para mostrar la imagen del rango filtrado) y un control ComboBox desde donde seleccionaremos el criterio a filtrar. 

Al abrir el Userform, en el evento Initialize ejecutaremos unas instrucciones para obtener la lista de criterios sin duplicados y ordenada. En este ejemplo se trata de la columna C (segunda columna de la Tabla de datos).

Private Sub UserForm_Initialize()

'armar lista única de la col c

Call ListaValoresUnicos

'rellenar el combobox

For i = 5 To Range("M" & Rows.Count).End(xlUp).Row

    ComboBox1.AddItem Range("M" & i)

Next i

End Sub


Sub ListaValoresUnicos()     'para la hoja Lista1 con la Tabla4

'se pasa la col C a un rango auxiliar y se le quitan los duplicados

Range("Tabla4[[CALIBRE]]").Copy Destination:=[M5]

ActiveSheet.Range("$M$5:$M$" & Range("M" & Rows.Count).End(xlUp).Row).RemoveDuplicates Columns:=1, Header:=xlNo

'se ordena el rango auxiliar para presentarlo en el desplegable

ActiveWorkbook.Worksheets("Lista1").Sort.SortFields.Clear

x = Range("M" & Rows.Count).End(xlUp).Row

ActiveWorkbook.Worksheets("Lista1").Range("M5:M" & x).Sort _

    Key1:=Range("M5:M" & x), Order1:=xlAscending, Header:=xlGuess

End Sub

En el evento Click del ComboBox ejecutaremos la macro principal, la de la Creación y Exportación de la imagen. Se filtrará la hoja por el criterio seleccionado, se tomará una captura o imagen del rango obtenido y la guardará como archivo de imagen 'jpg' en una subcarpeta (en el mismo directorio que el libro activo). A continuación se establece la propiedad Picture del control Image con la ruta y nombre del archivo de imagen guardado.

Private Sub ComboBox1_Click()

If ComboBox1.Value = "" Then Exit Sub

'se filtra la col C de la hoja activa

ActiveSheet.ListObjects(1).Range.AutoFilter Field:=2, Criteria1:=ComboBox1.Text

'se exporta el rango como imagen

Call exportaImagen(ComboBox1.Text, ActiveSheet.Name)

'se indica la misma ruta y nombre de archivo que se usaron en la macro de exportación

ruta = ThisWorkbook.Path & "/IMG/"

archi = ComboBox1.Text & ".jpg"             'no se permite png

'se sube la imagen al control Image1

With Image1

    .Picture = LoadPicture(ruta & archi)

    .PictureSizeMode = fmPictureSizeModeClip           'ver * 

    .PictureAlignment = fmPictureAlignmentTopLeft

End With

End Sub


* Las propiedades de ubicación pueden ser establecidas desde el modo diseño

   


La macro exportaImagen se encuentra en la entrada del tema anterior


También se puede descargar libro desde aquí o solicitarlo a mi correo de Gmail.


Acceso al VIDEO Nº 82 desde aquí.



domingo, 9 de junio de 2024

80 - Grabar Macros en Word y en Excel.

Utilizamos la Grabadora de macros para obtener instrucciones que no recordamos o desconocemos al intentar realizar alguna tarea repetitiva. Luego mediante VBA podemos ajustar y completar ese código obtenido.

Pueden seguir el paso a paso para grabar una macro en Word, y luego asignarle un atajo de teclado, desde el VIDEO Nº 80 de mi canal... o pueden continuar la lectura aquí.

Viendo las dificultades que presenta en Word la segunda tarea, o sea asignar el atajo de teclado, lo que hacemos es grabar una segunda macro para ejecutar la primera

Y aquí utilizaremos al instrucción: Application.Run que ya hemos visto en la entrada del VIDEO Nº 75.

Entonces, primero grabaremos la macro que necesitamos ejecutar en un documento Word de manera repetitiva. En el ejemplo solo ingresamos unos títulos y le damos formato a algunas líneas de texto.

Para llamar a la grabadora podemos optar por el botón que se encuentra en la barra de estado (al pie de la ventana, al igual que en Excel) o desde el menú Vista, Macros, Grabar Macro.

En la ventana que se nos presenta ingresamos un nombre para la macro, seleccionamos dónde se ubicará (en el libro activo o en la Plantilla Normal si la vamos a utilizar en otros libros) y colocamos alguna descripción del contenido de la macro.

Al presionar el botón ‘Teclado’ se nos abrirá la siguiente ventana, donde vamos a controlar que tengamos seleccionado el proyecto o la plantilla Normal según sea nuestra decisión.

En el recuadro no escribiremos nada sino que allí presionaremos la combinación de teclas que hemos seleccionado. En mi caso: CTRL y la tecla W.

Recién entonces se nos mostrarán esas teclas en el recuadro. Presionamos ‘Asignar’ para que se vuelque en el recuadro ‘Teclas Activas’.

NOTA: si elegimos alguna tecla que es de uso de la aplicación se nos mostrará la combinación CTRL+Mayúsc+la letra. Y así tendrá que ser ejecutado este atajo.

Al aceptar ya tendremos la grabadora activada y comenzaremos a realizar todos los pasos que queremos automatizar.

Al detener la grabadora encontraremos en un módulo el código generado. A partir de allí tendremos que pulir un poco y ajustar seguramente algunas referencias.

Pero es muy posible que la macro no grabe todos los pasos…. Solo nos servirá para conocer la sintaxis de algunas instrucciones, pero nada más.

Entonces, ¿cómo podemos asignar un atajo de teclado a una macro ya guardada? Vamos a recurrir a la siguiente solución.

Ya tendremos en un módulo del Editor una macro guardada, un código completo para toda nuestra tarea. Teniendo la precaución de colocar como una primera instrucción, un mensaje de confirmación… ya veremos el porqué (*).

A continuación grabaremos una nueva macro tal como en los pasos anteriores, asignándole un atajo de teclado. Y la tarea que vamos a grabar será ejecutar esta macro (rangos_excel_word).

 (*) Y ahora, cuando se ejecute, la primera instrucción que encuentra es la de confirmación, lo que nos permite ‘Cancelar’ el proceso ‘rangos_excel_word’  y detener nuestra macro de grabación.

Entonces en un módulo encontraremos la instrucción de llamada (la única línea que nos interesa recuperar, el resto lo borramos).


Esta será la macro que ejecutaremos con atajo de teclado llamando a la del proceso principal.

Es recomendable colocar en el mismo código el atajo de teclado. 

 

Acceso al VIDEO Nº 80 desde aquí.

 

jueves, 6 de junio de 2024

81 - Guardar rangos de Excel como Imagen.

 Cuando tenemos que enviar información parcial de alguna hoja, por ejemplo filtrada por Productos, o por Clientes, generalmente guardamos la hoja filtrada y la exportamos.

Aquí vamos a crear el informe como imagen. Sin necesidad de enviar la hoja filtrada sino solamente en un archivo jpg o png.

Para esto contamos con una hoja auxiliar (opcional) y el programa creará una carpeta (si aún no la tenemos) en el mismo directorio donde se encuentra nuestro libro.

Tanto el nombre de la subcarpeta, su ubicación y la extensión del archivo de imagen son argumentos opcionales que pueden ser modificados.

En el ejemplo del libro que se encuentra para descargar, el nombre para el archivo de imagen lo ingresará el usuario mediante un InputBox. Aquí, otra opción podría ser que se tome como 'nombre' el criterio filtrado (nombre del producto o nombre del cliente para este ejemplo).

Como esta macro puede ser utilizada para 2 procesos diferentes, es que tendré 2 llamadas: copiaRango para guardar imágenes en una subcarpeta y llamaUF para enviar un rango a un control de imagen de un Userform (se tratará en el próximo video).

* Traducción y adaptación de la macro del sitio: www.thespreadsheetguru.com

Sub guardaImagen()

nbreArchivo = InputBox("Ingrese el nombre para el archivo de imagen."

If nbreArchivo = "" Then MsgBox "Se canceló el proceso.": Exit Sub

nbreHoja = ActiveSheet.Name

Call exportaImagen(nbreArchivo, nbreHoja)

End Sub


Sub exportaImagen(nombre, hoja)

Dim hoL As Worksheet

Dim hoX As Worksheet

Dim rutaIMG As String

Dim nbreArchImg As String

 

' Establecer referencias a las 2 hojas de trabajo

Set hoL = ThisWorkbook.Sheets(hoja)

Set hoX = ThisWorkbook.Sheets("Hoja1")

Application.ScreenUpdating = False

 

' Obtener la ruta de la carpeta "IMG"     'Ajustar nombre

rutaIMG = ThisWorkbook.Path & "\IMG\"

' Crear la carpeta "IMG" si no existe

If Dir(rutaIMG, vbDirectory) = "" Then

    MkDir rutaIMG  'crear la subcarpeta

End If

'ruta y nombre completo para la imagen

nbreArchImg = rutaIMG & nombre & ".png"      'JPG

 

' Limpiar la hoja auxiliar

hoX.Activate

hoX.Cells.Delete

 

' Definir el rango de la imagen filtrada en la hoja activa

x = hoL.Range("B" & Rows.Count).End(xlUp).Row

If x <= 4 Then MsgBox "No hay datos filtrados.": Exit Sub

rgo = hoL.Range("B4:I" & x).Address

hoL.Range(rgo).CopyPicture Format:=xlPicture

' Pegar la imagen en la hoja "Hoja1" en el rango A1

hoX.Range("A1").PasteSpecial


'luego del pegado el objeto queda seleccionado. Se lo guarda en una variable 

    Set miShape = Selection

'se agrega un objeto chart con las dimensiones del rango

    Set miChart = hoX.ChartObjects.Add(Left:=miShape.Left, Top:=miShape.Top, Width:=miShape.Width, Height:=miShape.Height)

'el objeto seleccionado se pega en el chart y ese objeto se exporta

    miShape.Copy

    miChart.Select

    ActiveChart.Paste

'se guarda la imagen en la subcarpeta

ActiveSheet.ChartObjects(1).Activate

ActiveChart.Export Filename:=nbreArchImg, FilterName:="png"    'JPG

 

'eliminar los objetos agregados en la hoja 1

ActiveSheet.Shapes(1).Delete

ActiveChart.ChartArea.Select

ActiveChart.Parent.Delete

Selection.Delete

 

'se quita el filtro a la lista.

With hoL

    .Select

    .Unprotect

    If .FilterMode = True Then .ShowAllData

    .Protect DrawingObjects:=True, Contents:=True, Scenarios:=True _

        , AllowFiltering:=True

    .[E4].Select

End With

MsgBox "Fin del proceso."

End Sub


Acceso al VIDEO Nº 81 desde aquí.

Descargar libro desde aquí o solicitarlo a mi correo de Gmail.


domingo, 28 de abril de 2024

79 - Filtrar con criterio en otra hoja.

Generalmente seleccionamos, desde las columnas de una hoja de datos, el elemento buscado. O dejamos en alguna celda el criterio a buscar y con una macro se filtra la hoja.

La propuesta que presento aquí está pensada para cuando tenemos listas: de Alumnos, Cuentas de clientes o proveedores, Productos y tantas otras, donde guardamos el nombre y su código.

Y donde las hojas de Movimientos de cuentas solo cuentan con la columna de Código, lo que dificulta la búsqueda de algún registro. 


Entonces vamos a recurrir a una macro que se ejecutará desde la hoja de la Lista. En este ejemplo se utilizó el evento BeforeDoubleClick, aunque bien podría ser ejecutada desde un botón o el menú Desarrollador/Programador, Macros.

En el Editor de Macros seleccionamos la hoja Listado y allí colocaremos estas instrucciones:

Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean)

'llamamos a la macro de filtrado

Call filtro_Total

End Sub

Y la macro llamada 'filtro_Total' la colocaremos en un módulo:

Sub filtro_Total()   

'macro única para uso en los 2 modelos de hoja: rango o tabla

'acotamos el rango desde donde podremos hacer doble clic para llamar a la macro

If ActiveCell.Column <> 3 Or ActiveCell.Row < 4 Then Exit Sub

'verificamos si la celda seleccionada tiene contenido

If ActiveCell = "" Then Exit Sub

'se guarda el dato de la celda seleccionada y se pasa a la otra hoja

dato = ActiveCell.Value

Sheets("MOVIMIENTOS").Select   'agregar instrucciones (*)

'quitamos previamente cualquier filtro aplicado

If ActiveSheet.FilterMode = True Then ActiveSheet.ShowAllData

'se evalúa si se trata de una hoja con rango o con Tabla (**)

If ActiveSheet.ListObjects.Count = 0 Then

    'establecer el rango y filtrar por el criterio guardado en la variable

    rgo = [C3].CurrentRegion.Address

    ActiveSheet.Range(rgo).AutoFilter Field:=2, Criteria1:=dato

Else

    'si se conoce en qué col se encuentran las claves, utilizar esta instrucción

    ActiveSheet.ListObjects(1).Range.AutoFilter Field:=2, Criteria1:=dato


    'si no se conoce la ubicación de la col 'claves' utilizar estas otras

     'Ajustar nombre de tabla y el título de columna al modelo

    'colx = ActiveSheet.Range("Tabla1[[CODIGO]]").Column        

    'ActiveSheet.ListObjects(1).Range.AutoFilter Field:=colx - 1, Criteria1:=dato

End If

End Sub


NOTAS ACLARATORIAS:

(*) Para que la macro sea de uso en cualquier hoja del libro, se deben agregar instrucciones para evaluar previamente en qué hoja se filtrará. Por ejemplo: colocando el nombre en alguna celda de la hoja Listado.

Hojita= [E1] 

Sheets(Hojita).Select 



(**) Como intentamos utilizar la misma macro para diferentes formatos de hojas, necesitamos evaluar si la hoja activa tiene un objeto Tabla o no. ListObjects.Count nos devuelve al número de tablas,

(***)  Para trabajar con un solo modelo de hojas, recomiendo mirar el video donde se muestran en módulos diferentes cada una de sus macros (filtra_Rango o filtra_Tabla)


Acceso al VIDEO Nº 79 desde aquí.

Descargar libro desde aquí o solicitarlo a mi correo de Gmail.