Saltar al contenido

Vba. problemas con lista validación dependiente


Recommended Posts

publicado

Buenos días foreros:

Estoy teniendo problemas con una lista de validación dependiente.

Como sabeis las listas de validación tienen un problema, si pegamos encima de las celdas con validación, esta desaparece.

Como solución he utilizado VBA, al evento worksheet_change le he pedido que cree de nuevo la validación y funciona rodeando con un circulo rojo los datos pegados que no cumplen la validación.

Hasta aquí todo funciona correctamente.

El problema lo tengo cuando la lista de validación es dependiente y la aplico a un rango , por ejemplo b2:b100

Si creas la lista de validación dependiente en Excel ,no hay problemas; pero si la creo en VBA me da error 1004.

upload_2014-5-29_20-38-52-png.3911

EN VBA:

With r_car.Validation

.Delete

.Add Type:=xlValidateList, AlertStyle:=xlValidAlertStop, Operator:= _

xlBetween, Formula1:="=indirecto($a2)" 'da problemas error 1004

...

Espero haberme explicado.

Alguna idea?

Gracias por adelantado.

Un saludo a todos

Adjunto archivo.

Ejemplo problemas validación.rar

publicado

Hola @[uSER=162094]jmgcc[/uSER].

Hay algunas cosas qué comentar:

1. El error se produce porque en VBA, las fórmulas deben introducirse en Inglés, así tengas el Excel en español. En el ejemplo, la fórmula que debes introducir es

"=indirect($A2)"[/CODE]

2. Cuando declaras una variable, debes tener cuidado con ésto:

[CODE]Dim r_veh, r_car As Range[/CODE]

Puesto que [b][i]r_car[/i][/b] lo defines como un Objeto Rango, mientras que [b][i]r_veh[/i][/b] no lo estás definiendo como rango, sino como tipo Variant. La manera correcta de definirlo sería:

[CODE]Dim r_veh as Range, r_car As Range[/CODE]

ó

[CODE]Dim r_veh as Range
Dim r_car As Range[/CODE]

Esto en sí no genera error, pero lo que haces es ocupar más memoria de la que necesitas para una variable. La Variable Variant puede ser cualquier cosa, por ende, es la que más memoria ocupa.

Lo mismo para:

[CODE]Dim tabla, datos As Worksheet[/CODE]

Debería ser:

[CODE]Dim tabla as Worksheet, datos As Worksheet[/CODE]

Comentas!

Espero haberte ayudado, Dios te bendiga!

publicado

Hola johnmpl,

Gracias por tu respuesta.

Conozco como funcionan las variables y la memoria que reservan, pero desconocía lo que me comentas sobre la declaración.

No sé de donde había sacado que con comas funcionaba como si fuera un "array". GRACIAS POR LA ACLARACIÓN.

Cosas de aprender solo, a veces se tienen fallos de base.

Respecto a

Formula1:="=indirecto($a2)"[/CODE]

En las 200 versiones que había hecho

Ya había probado

[CODE]"= indirect($a2)"[/CODE]

incluso había probado con un bucle del tipo for each que recorra el rango con

[CODE]"= indirect($a" & variablefila &")"[/CODE]

Algo estaba haciendo mal porque ahora funciona perfectamente.

Gracias de nuevo johnmpl, un placer seguir aprendiendo.

Saludos a todos

Archivado

Este tema está ahora archivado y está cerrado a más respuestas.

  • 109 ¿Te parecen útiles los tips de las funciones? (ver tema completo)

    1. 1. ¿Te parecen útiles los tips de las funciones?


      • No
      • Ni me he fijado en ellos

  • Ayúdanos a mejorar la comunidad

    • Donaciones recibidas este mes: 0.00 EUR
      Objetivo: 130.00 EUR
  • Archivos

  • Estadísticas de descargas

    • Archivos
      187
    • Comentarios
      97
    • Revisiones
      29

    Más información sobre "Un juego del Rabino en Excel"
    Última descarga
    Por pegones1

    2    1

  • Crear macros Excel

  • Mensajes

    • 'Opción 1 Sub FiltrarSKUPorFecha(): Application.ScreenUpdating = False Dim ultimaFila As Long, fila As Long Dim diccionarioSKU As Object Dim listaEliminar As Object Dim fechaActual As String, fechaSiguiente As String Dim f As Variant With Sheets("Consolidado") ultimaFila = .Cells(.Rows.Count, 1).End(xlUp).Row ' Crear diccionarios para comparar SKU y almacenar filas a eliminar Set diccionarioSKU = CreateObject("Scripting.Dictionary") Set listaEliminar = CreateObject("Scripting.Dictionary") ' Recorrer desde la primera fila hasta la penúltima For fila = 2 To ultimaFila - 1 fechaActual = .Cells(fila, 1).Value fechaSiguiente = .Cells(fila + 1, 1).Value ' Solo comparar la fecha actual con la siguiente (inmediatamente superior) If fechaActual <> fechaSiguiente Then diccionarioSKU.RemoveAll ' Limpiar el diccionario antes de llenarlo ' Guardar los SKU de la fecha siguiente (solo de la siguiente) For f = fila + 1 To ultimaFila If .Cells(f, 1).Value <> fechaSiguiente Then Exit For diccionarioSKU(.Cells(f, 2).Value) = 1 Next f ' Revisar los SKU de la fecha actual y marcar los que deben eliminarse For f = fila To 2 Step -1 If .Cells(f, 1).Value <> fechaActual Then Exit For ' Solo eliminar si el SKU no está en la fecha siguiente If Not diccionarioSKU.exists(.Cells(f, 2).Value) Then listaEliminar(f) = 1 ' Marcar fila para eliminar después End If Next f ' Ya no es necesario seguir buscando después de comparar la primera y la siguiente fecha Exit For End If Next fila ' Eliminar las filas marcadas sin afectar el bucle principal For Each f In listaEliminar.keys .Rows(f).Delete Next End With MsgBox "Completado correctamente.", vbInformation End Sub 'Opción 2 Sub FiltrarSKUPorFecha1(): Application.ScreenUpdating = False Dim ultimaFila As Long, fila As Long Dim listaEliminar As Collection Dim fechaActual As String, fechaSiguiente As String Dim f As Variant, i As Long Dim SKUExiste As Boolean With Sheets("Consolidado") ultimaFila = .Cells(.Rows.Count, 1).End(xlUp).Row ' Inicializar la colección para marcar las filas a eliminar Set listaEliminar = New Collection ' Recorrer desde la primera fila hasta la penúltima For fila = 2 To ultimaFila - 1 fechaActual = .Cells(fila, 1).Value fechaSiguiente = .Cells(fila + 1, 1).Value ' Solo comparar la fecha actual con la siguiente (inmediatamente superior) If fechaActual <> fechaSiguiente Then ' Revisar los SKU de la fecha actual y marcar los que deben eliminarse For f = fila To 2 Step -1 If .Cells(f, 1).Value <> fechaActual Then Exit For ' Comprobar si el SKU está en la fecha siguiente SKUExiste = False For i = fila + 1 To ultimaFila If .Cells(i, 1).Value <> fechaSiguiente Then Exit For If .Cells(i, 2).Value = .Cells(f, 2).Value Then SKUExiste = True Exit For End If Next i ' Si el SKU no se encuentra en la fecha siguiente, marcar para eliminar If Not SKUExiste Then listaEliminar.Add f ' Marcar fila para eliminar después End If Next f ' Ya no es necesario seguir buscando después de comparar la primera y la siguiente fecha Exit For End If Next fila ' Eliminar las filas marcadas sin afectar el bucle principal For Each f In listaEliminar .Rows(f).Delete Next f End With MsgBox "Completado correctamente.", vbInformation End Sub   TABLA ELIMINAR.xlsm
    • Hola a ambos, Comparto lo que dice el maestro Victor, no está clara la consulta en cuanto a las definiciones, si tuviera que deducir las piezas son el resultado de la multiplicación posterior a los gramos, como los ejemplos son botanas es posible que sean cajas por piezas. Si es el caso, una opción es convertir ese texto a una operación matemática después de extraerlo. Para esto se puede definir una función de EVALUAR que no siempre esta disponible pero se puede mandar llamar en la definición de los nombres. Por otro lado hay múltiples "p" que estorban un poco, (Principe ChocoBlanco EmpBco 12p 126g FLOW MLA) así que yo recomendaría definir nombres y segmentar las funciones, no es complicado aunque tal vez requiera un poco de experiencia del usuario si quiere editar en lo futuro. Tal vez con eso sería suficiente dando un resultado similar a lo siguiente:
  • Visualizado recientemente

    • No hay usuarios registrado para ver esta página.
×
×
  • Crear nuevo...

Información importante

Echa un vistazo a nuestra política de cookies para ayudarte a tener una mejor experiencia de navegación. Puedes ajustar aquí la configuración. Pulsa el botón Aceptar, si estás de acuerdo.