Bueno, contestando a mi propia pregunta, no es posible que un archivo sea eliminado por una macro contenida en el propio archivo. La lógica es la siguiente, todo el código que se ejecuta desde el Módulo de un archivo deja de ejecutarse cuando el archivo es cerrado, y un archivo abierto no puede ser eliminado, así que al incluir cualquier línea de código VBA después de una línea que cierre el archivo desde el cual se está ejecutando una macro, resultará en la interrupción automática e inmediata del código.La respuesta parace ser la correcta, pero esto no quiere decir que no se pueda encontrar una solución alternativa.
Mis primeras ideas pasaron por enviar comandos a la consola de comandos. Hice algunas pruebas con el comando "at", que permite programar tareas a horas especificadas. Sin embargo, los resultados no fueron los esperados.
Otra idea que no probé podría ser la de tener un libro alternativo con una macro que se ejecute con "ontime" pasados unos segundos después de cerrar el archivo que se quiere eliminar y lo elimine. Sin embargo, esto puede resultar un poco más complicado que la solución que planteo, que me parece es eficiente y sencilla.
Como bien lo dice hugotron, "no es posible que un archivo sea eliminado por una macro contenida en el propio archivo". Esto no quiere decir que no podamos eliminarlos desde otro lado, como otro libro o, en este caso, un VBScript que se crea en tiempo de ejecución dentro de la misma macro, se ejecuta, espera a que el libro se cierre y lo borra. El código, ampliamente comentado, es el siguiente:
' El siguiente procedimiento crea un archivo .vbs que
' se ejecuta antes de cerrar el libro.
' Dicho script, una vez ejecutado, espera el tiempo indicado
' en la constante TIEMPO_ESPERA_CIERRE_ARCHIVO_SEG para luego
' pasar a eliminar el archivo una vez se encuentre cerrado.
' Al final siempre quedará como residuo el vbScript que sólo
' contiene tres líneas de código y el archivo que contenga
' este código se habrá borrado.
' Creado por: Mauricio Robayo, AKA mjrofra
' http://excelpatas.blogspot.com/2011/09/archivo-que-se-elimina-si-mismo.html
' 7 de septiembre de 2011
Sub Matarme_con_VBscript()
' Variable que almacena la ruta y el nombre
' del archivo .vbs que va a borrar este archivo.
Dim VBScript As String
' Tiempo, en segundos, que se va a dar de
' espera mientras se cierra el archivo.
' Es necesario dar un tiempo de espera para
' asegurarse de que el archivo ha sido cerrado.
' Si el script se ejecuta con el archivo
' abierto, no se podrá borrar el archivo.
' En este caso, el tiempo de espera es de 2 segundos.
Const TIEMPO_ESPERA_CIERRE_ARCHIVO_SEG = 2
' Si el archivo ha sido grabado por el usuario, tendrá una ruta.
' De lo contrario, la ruta se encontrará vacia y no será
' necesario borrar el archivo depués de cerrarlo pues ya
' no existirá.
If ThisWorkbook.Path <> vbNullString Then
' Almacena la ruta y el nombre que se la va a dar al script.
' En este caso se usa la carpeta temporales, para evitar
' dejar rastros evidentes:
VBScript = VBA.Environ$("Temp") & Application.PathSeparator & "MatarLibro.vbs"
' Crea el VBScript para borrar este archivo
Open VBScript For Output As #1
Print #1, "Set obj = CreateObject(""Scripting.FileSystemObject"")"
Print #1, "WScript.sleep " & TIEMPO_ESPERA_CIERRE_ARCHIVO_SEG * 1000
Print #1, "obj.DeleteFile """ & ThisWorkbook.FullName & """"
Close #1
' Ejecuta el VBScript para borrar este archivo
Shell "cmd /c " & VBScript
End If
' Cierra el libro sin guardar cambios.
ThisWorkbook.Close False
End Sub
Esta macro deberá ser llamada cuando se quiera borrar el archivo que la contiene. La macro creará un archivo vbscript (.vbs) que se ejecutará inmediatamente, esperará unos segundos (los que se le indiquen) a que cierre el archivo y luego pasará a eliminarlo sin dejar rastro.
Bien, ¿pero eso para qué serviría?
ResponderSuprimirPor si tienes archivos secretos del gobierno y tienes que destruirlos a lo James Bond, o solo como divertimento y para ver hasta donde se puede llegar con la programacion, o ninguna de las dos anteriores...
ResponderSuprimirHace rato existe por un internet un código para hacer lo mismo, no sé quien es el autor:
ResponderSuprimirSub Suicida()
With ThisWorkbook
Application.DisplayAlerts = False
If .Path <> vbNullString Then
.ChangeFileAccess xlReadOnly
Kill .FullName
End If
ThisWorkbook.Close SaveChanges:=False
End With
End Sub