ventanas - ¿Cómo evitar que Excel solicite reabrir un libro de trabajo?
cuando abro un archivo de excel se abre otro en blanco (2)
Hombre ... esto parece fácil pero es difícil. Estuve jugando con cada evento y propiedad de aplicación / libro de ejercicios que pude pensar en mis 7 años de experiencia trabajando con Excel VBA y no pude encontrar nada elegante ... Creo que la respuesta corta es que no hay realmente una solución corta y elegante para este problema (si hay, realmente me gustaría verlo). Esa es la mala noticia.
La buena noticia es que creo que hay formas de evitar el problema ... 1 es un poco más elegante, pero requeriría que replantees algunos de tus métodos y el otro es sucio, pero probablemente un poco más simple.
La manera más elegante implicaría reconsiderar y refactorizar sus métodos ... Creo que la razón por la que nunca me he encontrado con este problema en mi trabajo es que al final de cada uno de mis métodos, el libro de trabajo se queda en un "buen" estado ... o en otras palabras, si hay "limpieza" para hacer, entonces se hace al final de cada método. Si hay un gran rendimiento general en esto, puede considerar establecer un indicador booleano y restringir si se ejecuta al final de cada uno de sus otros métodos. (es decir, runCleanup = ReturnTrueIfCleanupIsNeeded () If (runCleanup = true) Then CleanupMethod () End If)
La manera más sucia implicaría hacer todo el libro de trabajo en sí mismo en una especie de "mutex ad-hoc" por
1) copiar todo el libro de trabajo ( original ) en el evento WorkBookOpen en otro libro de trabajo ( temp ) y usar el método "SaveAs" en la temperatura para colocarlo en una ubicación separada.
2) Almacenar la ruta ( original ).
3) Agregar código al evento abierto de WorkBook que verifica la ( temperatura ) y ya sea A) Se cierra inmediatamente y activa la temperatura o B) Se sobrescribe con ( temp ) y luego usa SaveAs
4) Capture el evento antes de que el usuario guarde el WorkBook y guárdelo tanto en la ubicación original como en la ubicación temporal .
5) En el evento WorkBookClose, ejecute cualquier limpieza que necesite y guarde la temperatura en su ubicación original.
El objetivo de todo esto es dejar de lado la "colisión" que ocurre cuando abres el libro de trabajo dos veces, básicamente, al crear un libro de trabajo temporal cuando lo abres por primera vez y lo guardas en una ubicación diferente (tal vez podrías incluso ocultarlo). el archivo?) se asegura de que cuando el usuario haga clic en el original, no colisione con los datos con los que ya están trabajando en la aplicación. (Por supuesto, esto tiene sus propios problemas / preguntas como "¿Qué pasa si no sé a qué rutas tiene acceso el usuario para guardar la temperatura?" O "¿Qué pasa si el usuario abre el archivo temporal XLS ... pero es por eso que lo llamó el camino de tierra ) "
Sé que es mucho, especialmente si no estás acostumbrado a trabajar con VBA; Si quieres que publique un código para ayudarte con alguno de esos pasos, deja un comentario y lo haré.
Gracias por la interesante pregunta.
Tengo un libro de Excel que contiene una aplicación de VBA. La aplicación guarda los datos que se deben guardar en una base de datos, y el libro de trabajo siempre se cierra sin guardar (configurando ThisWorkbook.Saved = True en BeforeClose).
Tengo el siguiente problema:
El usuario hace doble clic en el libro de trabajo en Windows Explorer, se abre el libro de trabajo.
El usuario hace doble clic por segunda vez en el libro de trabajo en Windows Explorer.
Las solicitudes de Excel indican que "MyWorkbook.xls ya está abierto. Volver a abrir hará que se descarten los cambios que haya realizado. ¿Desea volver a abrir MyWorkbook.xls?"
Si el usuario hace clic en "Sí", el libro de trabajo se vuelve a abrir sin ejecutar el controlador de eventos BeforeClose de la instancia que ya estaba abierta .
Este es un problema en mi aplicación, porque significa que no se ejecuta algún código importante de limpieza en el controlador de eventos BeforeClose.
¿Alguien puede sugerir una solución de VBA para esto? Que podría ser:
Suprimir el mensaje para volver a abrir el libro de trabajo. En lugar de usar silenciosamente la instancia ya abierta.
De alguna manera obtener el BeforeClose o algún otro controlador de eventos para ejecutar en la instancia original antes de que se cierre, por lo que puedo ejecutar mi código de limpieza.
Actualizar:
Esto es Excel 2003.
Puedo eliminar el mensaje no deseado estableciendo "ThisWorkbook.Saved = True" en el controlador de eventos Workbook_SheetChanged (la aplicación VBA es responsable de guardar todos los datos que se deben guardar en una base de datos, por lo que no me importa tener Excel guardando cambios).
Sin embargo, esto no resuelve mi problema: si hago esto, al hacer doble clic en el Libro de trabajo en el explorador vuelvo a abrir silenciosamente el libro de trabajo, pero aún lo hago sin llamar al controlador de eventos "BeforeClose".
Entonces para reformular la pregunta:
- ¿Hay alguna forma de usar VBA para detectar e interceptar un libro de trabajo que se vuelve a abrir de esta manera?
Actualización 2
Al aceptar la respuesta de BKimmel, parece que no hay una forma de VBA para interceptar este evento desde el libro de trabajo.
La solución que implementaré será mover el código de la aplicación a un complemento XLA, que se carga automáticamente (si no está ya cargado) cuando se carga el libro de trabajo. El complemento puede manejar eventos Open y BeforeClose y almacenar la información que necesita para realizar la limpieza.
Puede usar algunos eventos de aplicaciones especiales para administrar cuándo se vuelve a abrir un libro de trabajo y activar manualmente el código Workbook_Close:
Cree un módulo de clase llamado ApplicationController con el siguiente código:
Public WithEvents CApp As Application
Public CurrentWB as Workbook
Private Sub CApp_WorkbookOpen(ByVal wb As Excel.Workbook)
Dim sPathName As String
sPathName = wb.Name
if sPathName = CurrentWB.Name then CallSomeMethod()
End Sub
luego en su evento workbook_load haga algo como:
Public controller as new ApplicationController
Private Sub Workbook_Open()
set controller.CApp = Excel.Application
set controller.CurrentWB = ThisWorkbook
End Sub
ahora, cuando Excel vaya a abrir un nuevo libro, capturará el evento y ejecutará su método de seguridad. Incluso podría evitar que vuelva a abrir el libro si lo desea.