Buscar y eliminar una imagen especifica en hoja excel

Estoy estancado con un formulario que edita y elimina datos
El tema es el siguiente. Necesito borrar una fila de registro completo de una base de datos de Alumnos del colegio, con su imagen inclusive (una pequeña imagen del alumno asociado a ese registro).
El tema es que me posiciono bien en la fila del registro, borro el registro pero la imagen sigue ahi.
Me doy cuenta que el tema pasa por identificar la imagen y el tipo al que corresponde. Consulte este vinculo y otros
http://www.todoexpertos.com/categor%C3%ADas/tecnolog%C3%ADa-e-internet/software-y-aplicaciones/microsoft-excel/respuestas/1851030/macro-eliminar-im%C3%A1genes
En el botón "eliminar" tengo este código
Private Sub BtnEliminarRegistro_Click()
sino = MsgBox("¿Deseas eliminar este registro?", vbYesNo, "Confirmar")
If sino = vbYes Then
EntireRow.Delete
img.Delete
End Sub
Previo a ello había declarado la variable "img" como Shape (Public img As Shapes)
Y en el botón "buscar" de ese mismo formulario, había "set"eado la variable "img" si encontraba el registro. Aclaro que el botón "buscar" se activa antes de "eliminar".
Set img = ActiveSheet.Pictures.Insert(rutaimagen).Select
La ruta de la imagen la guardo en la variable "rutaimagen" tomada de la celda contigua a la misma
Pero se ve que algo desconozco y estoy haciéndolo mal, pues me salta falla y en el depurador "img" se muestra como vacío.

2 Respuestas

Respuesta
1

Si entiendo bien tu problema está en la identificación de la imagen a borrar. Cuando insertas la imagen ésta pasa a estar dentro de la hoja y no requiere mas de la ruta. Si cambias el nombre del fichero en la carpeta de Windows verás que sigue estando accesible dentro del Excel. Es porque has guardado el objeto como imagen en la hoja.

Guardar objetos imagen en la propia hoja puede no ser una buena idea porque además de que engordan el fichero de tamaño, se pierden las referencias. Es mejor guardar los archivos en una carpeta y la ruta+nombre del fichero en Excel y cargar la imagen solo cuando sea necesario.

En todo caso cuando cargas imágenes o bien mantienes la referencia (Excel va dando número consecutivo a la imagen) o mejor le das un nombre (propiedad Name). Cuando vas a borrar usas la referencia o el nombre para indicar cual imagen quieres borrar. Pero no puedes hacer un set img basado en la ruta excepto para insertarla. Como te digo tienes que hacerlo basado en un nombre, si se lo has dado previamente cuando la insertaste o en el orden en que la insertaste (el número consecutivo que te da Excel). Ojo con el número, porque si borras y vuelves a insertar posiblemente la cuenta siga desde el último salvo que hayas cerrado Excel entre medias. Es decir no tienes garantía de que no haya huecos o imágenes insertadas posteriormente tengan números menores. Además otras shapes pueden estar intercaladas.

Puedes hacer una comprobación y es recorrer todas la colección de shapes escribiendo su nombre en celdas consecutivas, cambiando el tamaño o cualquier otra propiedad con un bucle del tipo:

Sub test_shapes()
Dim s As Shape
For Each s In ThisWorkbook.ActiveSheet.Shapes
 MsgBox ("Imagen: " & s.ID & " " & s.Name)
Next s
End Sub

Este pequeño código te va mostrando un cuadro de diálogo con los id y nombre de las shapes de la hoja activa. Es un poco pesado si tienes muchas pero creo que da una idea de lo que hacer. Además siempre puedes cambiarlo para que los escriba en una columna de la hoja.

Gracias por tu pronta respuesta, la verdad que al no tener acceso a manuales que expliquen bien estos temas uno va aprendiendo al paso y con la ayuda de expertos como ustedes, otra vez gracias.

Me queda claro el punto de que es mas conveniente usar la ruta externa de la imagen, de todas maneras al no ser muchos chicos mi base no es muy grande. Siendo este el caso como podría hacer para dar nombre a un shape cuando introduzco la imagen?

Serias tan amable de explicarme. Gracias

En general todos los objetos tienen la propiedad ".Name." Por ejemplo el código anterior modificado cambia el nombre a "Foto"+ número.

Sub test_shapes()
Dim s As Shape
Dim i as Integer
i=1
For Each s In ThisWorkbook.ActiveSheet.Shapes
s.Name = "Foto" & str(i)
i=i+1
 MsgBox ("Imagen: " & s.ID & " " & s.Name)
Next s
End Sub

Así que tras generarlo cambia esa propiedad a lo que quieras. También lo puedes hacer a mano si te pones en modo diseño (icono con un cartabón y una regla) en la pestaña Developer. Pinchas con el botón derecho la foto y eliges ver propiedades. La propiedad Name suele ser la primera con lo cual solo tienes que editar su valor a mano.

Respuesta
1

Si por que estas intentando eliminar una instancia del objeto y no el objeto, debes eliminar el shape.

Cada shape cuenta con un indice shape(1), shape(2) etc

Identifica el indice y elimina el shape

Sheets(1).Shapes(1).Delete

Elimina el shape indice 1 de la hoja 1

Gracias por responder tan prontamente.

Mi problema es justamente ese, que no se como identificar el shape asociado al registro.

Me explico; tengo una serie de +/- 100 registros correspondientes a unos 100 alumnos los cuales, en ocasiones, tengo que eliminar porque egresan u otra causa, a otros modificar sus datos o añadir la imagen faltante de algún alumno cuya foto quedo pendiente.

Esta parte, la de agregar y editar la hago bien. El tema es que cuando tengo que eliminar, Como te imaginaras, los shapes, en la medida que se van agregando, eliminando o cambiando por otras fotos, van modificando su numero de shape de forma aleatoria. No se si me explico

La pregunta seria, ¿Como podría hacer para que la imagen ubicada en una determinada fila se borre junto con la fila sin conocer su indice?, porque digo esto, porque muy probablemente no sepa cual es el numero de shape que le corresponda en virtud de los cambios de imágenes y otras faltantes. El único dato cierto es que esa imagen corresponde a una única fila y que al lado de esa imagen tengo una celda que tiene guardada la ruta de origen y el nombre de la foto.

Gracias y muy amable por disponer de tu tiempo y atención.

ve probando distintos indices shapes(1).select shapes(2).select... etc

Añade tu respuesta

Haz clic para o

Más respuestas relacionadas