Saltar al contenido

Sincronizacion para eventos entre archivos mediante archivos auxiliares


verzulsan

Recommended Posts

publicado

En el post 10 de este hilo, teneis los dos archivos con la solucion al problema que se plantea abajo y ademas un video donde se explica como han de montarse los archivos para que funcionen correctamente a traves de la red.

Ir al POST 10

Hola, Hacia tiempo que no me encontraba con un problema que no se ni por donde cogerlo.

- Tengo un libro que se guarda cada 15 segundos con "thisworkbook.save", el libro ejecuta una macro infinita y debe estár siempre funcionando.

- El libro está compartido en red, dicho libro es copiado desde otros equipos cada X segundos a traves de la red.

Todo el montaje funciona aparentemente bien y puede estár horas funcionando como debería, pero cada X horas (aleatorio), la macro del libro se detiene por un problema de "Error al guardar".

El error no es error como tal, sino que abre una ventanita de explorer de esas que dice "Donde desea guardar el archivo" y le diga donde le diga no me deja guardarlo. Incluso parando la macro e intentando guardarlo manual ya no me deja guardarlo.

En el directorio donde está el archivo, aparece ademas un archivo sin extension con un nombre hexadecimal tipo "D28C1000", investigando un poco me he dado cuenta de que dicho archivo se crea cada vez que se guarda un libro e inmediatamente despues es eliminado. En el caso de error que ocurre 1 vez cada 2000 a 5000 guardados, el archivito "D28C1000" no se elimina, en lugar de eso, aparecen 2 archivos de excel abiertos, uno es el original y otro es el clon con nombre raro "D28C1000". La unica manera de que la macro vuelva a funcionar es cerrando el libro sin guardar cambios (ya que no te deja), luego abrir de nuevo y vuelta a la cuenta atras del inesperado fallo :S

Esta es de las pocas veces que estoy totalmente perdido en la captura de un error, generalmente se por donde buscar informacion al respecto pero en este caso ni idea. Cualquier ayuda u orientacion seria muy agradecida.

Saludos

--- Mensaje unido automáticamente ---

Siguiendo con la investigacion, parece que aqui dejan algo claro el foco del problema:

http://forums.techarena.in/windows-software/1376796.htm

Cito:

When you save an existing file in Excel' date=' Excel creates a temporary file in the destination folder that you specify in the Save As dialog box. The temporary file contains the whole contents of your workbook. If Excel successfully saves the temporary file, the temporary file is renamed with the file name you specify in the Save As dialog box.

This process of saving files makes sure that the original file is not damaged. The original file is useful if the save operation is not successful.

When Excel saves a file, Excel follow these steps:

Excel creates a randomly named temporary file (for example, Cedd4100 with no file name extension) in the destination folder that you specified in the Save As dialog box. The whole workbook is written to the temporary file.

If changes are being saved to an existing file, Excel deletes the original file.

Excel renames the temporary file. Excel gives the temporary file the file name that you specified (such as Book1.xls) in the Save As dialog box.

Important Points About Saving

After Excel creates and saves the temporary file, all the changes are written to the temporary file.

If Excel cannot delete the existing file, you receive an error message. The original file and the temporary file both remain in the destination folder.

If Excel can delete the existing file, but Excel cannot rename the temporary file, you receive an error message. Only the temporary file remains in the destination folder.

If Excel saves a new file for the first time, Excel does not create a temporary file. Excel saves the file with the file name that you specified in the Save As dialog box.[/quote']

Voy a seguir haciendo pruebas con un archivo excel de gran tamaño 40 megas que tarda aproximadamente 20 segundos en guardarse en donde puede verse claramente la existencia del archivo temporal antes de que sea eliminado.

Iré poniendo por aquí los resultados. Por ahora ya voy barajando una idea que consistiría en una comunicacion de ambos libros preguntandose mutuamente sobre su disponibilidad, pero aun quedan pruebas.

publicado

Re: Problema al guardar un libro y con Thisworkbook.save

Segun los resultados de las pruebas, parece que existe una probabilidad del 0,18% de que en el momento en que el libro de macros esté autoguardandose, reciba al mismo tiempo una petición de copia a traves de la red, y un 0.35% de que en el momento de autoguardar, esté siendo copiado a traves de la red.

Idea para la solucion: Crear unas reglas de comunicacion entre el archivo de macros infinita y el solicitante de la copia.

Bueno, creo que lo siguiente va a funcionar:

Pruebas 2: Creando comunicacion artificial entre dos ficheros

-=Guardando el archivo=-

===================

(Libro compartido en red desde servidor que ejecuta macros infinita)

- Paso 1: (Justo antes de guardar) Pregunta si existe en el directorio raiz el archivo "EstoyCopiando.txt",

Caso Existe: Repetir paso 1 hasta que no exista el archivo, Caso NO Existe, pasar al paso 2.

- Paso2: Se creará un archivo temporal vacio tipo TXT con el nombre "Guardando.txt" en el directorio raiz.

- Paso3: El archivo se guarda. (Tarda X segundos / Milisegundos)

- Paso4: (Justo despues de guardar) Se elimina el archivo "Guardando.txt".

-=Realizando peticion de copia desde archivo normal=-

=======================================

(Libro que realiza peticiones de copia sobre el archivo de macros)

- Paso 1: (Justo antes de copiar) Pregunta si existe en el directorio raiz el archivo "Guardando.txt";

Caso Existe: Repetir paso 1 hasta que no exista el archivo, Caso NO Existe, pasar al paso 2.

- Paso2: Se crea un archivo temporal vacio tipo TXT con el nombre "EstoyCopiando.txt" en el directorio raiz.

- Paso3: El archivo se copia. (Tarda "Y" segundos)

- Paso4: (Justo despues de haber copiado) El archivo NO compartido, eliminará el archivo "EstoyCopiando.txt". (Dejando libre al archivo compartido para que se pueda autoguardar)

Cuando termine de implementar esto os comento y dejaré los resultados. Me esperaré varios dias para dar el tema como solucionado puesto que para que sea exitosa la operacion, debe mantenerse estable sin fallos durante al menos dos dias.

Un saludo

publicado

Re: Problema al guardar un libro y con Thisworkbook.save

Bueno, ya tengo el codigo listo y funcionando, por ahora no se ha parado y hace exactamente lo que indicaba en el anterior post. Siguiendo los consejos de Gerson, pongo a continuacion el codigo que he usado para sincronizar los archivos a la hora de copiar y guardar.

El único codigo que no he puesto es el de la funcion "IsFileInUse" ya que está sacada de internet, dejo aqui el link directo: IsFileInUse

.

Al final del post están 2 archivos adjuntos de muestra (Con el codigo algo modificado) y un video tutorial que explica paso a paso como deben usarse estos dos archivos, podeis adaptarlo a vuestras necesidades.

Funcion de Auto Guardar para el libro de macros compartido:

Option Explicit
Sub GuardarLibroActualAntiFallos()
Dim ThisDirectorio As String
Dim bResult As IsFileResults

ThisDirectorio = ThisWorkbook.Path & "\"

'Creamos el archivo "Guardando.txt" en el directorio actual, no importa que se _
esté copiando nuestro archivo en este momento debido a que esperaremos que dejen _
de copiar y al mismo tiempo indicamos a todos los demas intentos de copiado que _
esperen por que van a guardarse los cambios. Los otros libros esperarán a que _
el archivo "Guardando.txt" deje de existir, los que actualmente estan copiando _
terminarán el proceso.
Call CrearArchivo(ThisDirectorio, "Guardando.txt")

'Esperamos a que el archivo "Copiando.txt" desaparezca
bResult = IsFileInUse(ThisDirectorio & "Copiando.txt")
Do While (bResult <> FILE_DOESNT_EXIST)
bResult = IsFileInUse(ThisDirectorio & "Copiando.txt")
If bResult <> FILE_DOESNT_EXIST Then WaitMilisec (100)
Loop
Stop

'Guardamos el archivo actual
ThisWorkbook.Save
Call WaitMilisec(100)
Stop

'Eliminamos el archivo auxiliar y nos aseguramos de ello
bResult = IsFileInUse(ThisDirectorio & "Guardando.txt")
Do While (bResult <> FILE_DOESNT_EXIST)
Call EliminarArchivo(ThisDirectorio, "Guardando.txt")
bResult = IsFileInUse(ThisDirectorio & "Guardando.txt")
If bResult <> FILE_DOESNT_EXIST Then WaitMilisec (100)
Loop
End Sub[/CODE]

Funcion de Copiar para el libro que realiza la peticion de copia al libro de macros compartido.

[CODE]Option Explicit

Sub CopiarLibroFuentesDB()
Dim CarpetaOrigen As String
Dim CarpetaDestino As String
Dim ArchivoOrigen As String
Dim ArchivoDestino As String
Dim bResult As IsFileResults

CarpetaOrigen = "\\192.168.1.136\ControladorEspia\"
ArchivoOrigen = "AutoBot Controlador V.2.3.xls"

CarpetaDestino = ThisWorkbook.Path & "\"
ArchivoDestino = "FuentesDB.xls"

'Creamos la carpeta "Copiando.txt" en la ruta destino, esto dejará, no importa _
que se esté grabando el archivo origen en ese momento ya que este proceso se _
esperará hasta que el archivo origen termine de guardar, escuchando a "Guardando.txt"
Call CrearArchivo(CarpetaOrigen, "Copiando.txt")

'Esperamos a que el archivo "Guardando.txt" desaparezca
bResult = IsFileInUse(CarpetaOrigen & "Guardando.txt")
Do While (bResult <> FILE_DOESNT_EXIST)
bResult = IsFileInUse(CarpetaOrigen & "Guardando.txt")
WaitMilisec (100)
Loop

'Copiamos el archivo origen en el archivo destino
Call EliminarArchivo(CarpetaDestino, "FuentesDB.xls")
Call CopyFile(CarpetaOrigen & ArchivoOrigen, CarpetaDestino & ArchivoDestino)

'Esperamos a que el archivo destino haya sido creado completamente para volver _
a permitir al archivo origen que siga guardando.
bResult = IsFileInUse(CarpetaDestino & "FuentesDB.xls")
Do While (bResult <> FILE_FREE)
bResult = IsFileInUse(CarpetaDestino & "FuentesDB.xls")
If bResult <> FILE_FREE Then WaitMilisec (100)
Loop

'Eliminamos el archivo auxiliar y nos aseguramos de ello
bResult = IsFileInUse(CarpetaOrigen & "Copiando.txt")
Do While (bResult <> FILE_DOESNT_EXIST)
Call EliminarArchivo(CarpetaOrigen, "Copiando.txt")
bResult = IsFileInUse(ArchivoDestino)
If bResult <> FILE_DOESNT_EXIST Then WaitMilisec (100)
Loop
End Sub[/CODE]

===================================================

Funciones auxiliares usadas para las dos funciones principales de arriba

===================================================

Esperar milisegundos

[CODE]Public Declare Function GetTickCount Lib "kernel32" () As Long

Public Function WaitMilisec(Retardo As Long)
Dim TimeINI As Long
Dim TimeFIN As Long
Dim TimeDif As Long

TimeINI = GetTickCount

Do While (TimeDif < Retardo)
TimeFIN = GetTickCount
TimeDif = TimeFIN - TimeINI
DoEvents
Loop
End Function[/CODE]

Crear Archivo:

[CODE]Public Function CrearArchivo(Ruta As String, Nombre As String) As Boolean
Dim bResult As IsFileResults
Dim ArchivoTemp As String

On Error GoTo ErrorCrearArchivo

ArchivoTemp = Ruta & Nombre
bResult = IsFileInUse(ArchivoTemp)
Do While (bResult = FILE_DOESNT_EXIST)
Open "" & ArchivoTemp & "" For Output As #1
Close #1
DoEvents
bResult = IsFileInUse(ArchivoTemp)
Loop
CrearArchivo = True
Exit Function
ErrorCrearArchivo:
Close #1
CrearArchivo = False
End Function[/CODE]

Eliminar archivo:

[CODE]Public Function EliminarArchivo(Ruta As String, Nombre As String) As Boolean
On Error GoTo ErrorEliminarArchivo
Kill Ruta & Nombre

Exit Function
ErrorEliminarArchivo:
EliminarArchivo = False
End Function[/CODE]

Copiar Arhivo

[CODE]Sub CopyFile(SourceFile As String, DestFile As String)
'---------------------------------------------------------------
' Proceso: Copia un archivo de una ubicacion cualquiera (incluso de red) a otra
' Entradas: 2 strings (ruta&nombre archivo a copiar, ruta&nombre archivo a crear)
' Salidas: Ninguna, no devuelve errores de ningun tipo, es un caso especial ya _
que no interesa ningun tipo de error, si lo encuentra lo copia, sino, se ignora.
' Poscondiciones: 'Dependiendo del sistema operativo, será necesario modificar el codigo por uno de estos: _
CopyString = "COMMAND.COM /C COPY " & SourceFile & _
'Cualquier otro _
CopyString = "CMD.EXE /C COPY " & SourceFile &
'---------------------------------------------------------------
On Error GoTo ErrorCopyFile
Dim CopyString As String
SourceFile = Chr(34) & SourceFile & Chr(34)
DestFile = Chr(34) & DestFile & Chr(34)
CopyString = "CMD.EXE /C COPY " & SourceFile & _
" " & DestFile

Call Shell(CopyString, 0)
Exit Sub
ErrorCopyFile:
End Sub[/CODE]

Abajo, el libro del servidor con macro infinita y el archivo que copia el libro del servidor para actualiar sus datos.

Quizas es algo lioso de entender por lo que ahi os dejo un video donde se puede como se montan estos dos archivos

http://www.youtube.com/watch?v=lNO4tzBYxhw

.

Un saludo!

ArchivoExplorador.zip

Libro Visor.zip

Invitado jorgetchake
publicado

Re: Problema al guardar un libro y con Thisworkbook.save

Estimado Versulzan

Tienes un problema muy sofisticado para mi nivel,.... pero,... lo primero que me vino a la mente es sobre el reloj del PC,... si tu grabación es de xxx segundos,....

que pasa si durante ella cambia la fecha del PC??????

No lo sé,... pero me imagino que el sistema debe hacer algunas cositas que tal vez choque con tu grabación.

Amigo,... discúlpame por distraerte,... pero lo comenté por las dudas.

Cordiales saludos.

publicado

Re: Problema al guardar un libro y con Thisworkbook.save

Hola Jorge,

Antes dije mal lo de los 15 segundos. Lo que hace es guardar tras la reproduccion de una macro que dura aproximadamente 15 segundos, no se guia por la fecha del ordenador.

No hay nada que disculpar, te agradezco la ayuda.

El error al guardar se sigue produciendo, por lo que hay algo que se me está escapando. Seguiré investigando a ver que sale de todo esto.

Saludos

publicado

Re: Problema al guardar un libro y con Thisworkbook.save

Hola,

La macro de comunicacion entre archivos si que funciona, los errores que se producian ayer eran debidos a que el archivo "Guardando.txt" y "Copiando.txt" los generaba en el mismo directorio compartido y habia un conflicto a la hora de hacer multiples peticiones de lectura y escritura mediante macros.

La solucion ha sido hacer que estos 2 archivos se creen en una carpeta compartida vacia y ahora no se para.

No hace falta esperar 2 dias para saber que no se va a parar, no ha dado ningun fallo en 15 horas seguidas.

Un saludo a todos y podeis dar este tema por solucionado y moverlo a macros.

publicado

Re: Problema al guardar un libro y con Thisworkbook.save

Hola verzulsan

Excelente idea y trabajada solución.

Yo personalmente lo pasaría al foro ideas y aportes.

Un saludo desde Vitoria

publicado

Re: Problema al guardar un libro y con Thisworkbook.save

Hola ioyama,

Gracias por el cumplido, me alegro que te haya gustado.

Me parece bien la idea de pasarlo al foro de ideas y aportes, muévelo si puedes aunque, el título habría que cambiarlo por algo así como "Comunicación y actualización dinámica entre libros abiertos con cola de espera" o algo parecido.

Cuando tenga un ratejo libre, crearé unos archivos excel de ejemplo para que cualquiera pueda ver el funcionamiento en tiempo real, es bastante curioso ver como en una carpeta vacía compartida en red (o no compartida) van apareciendo y desapareciendo archivos de texto, se aprecia el comportamiento de como el que quiere copiar se espera a que el otro termine de guardar y viceversa. El comportamiento me ha recordado bastante al de Una pila FIFO (First In First Out).

Un saludo amigo

EDIT: En realidad se puede aplicar para una comunicacion de sincronizacion para diferentes actividades entre archivos, por lo que el tema podria ser, "Sincronizacion para eventos entre diferentes archivos mediante archivos auxiliares temporales de comunicacion"

publicado

Hola verzulsan

Movido y .... quedo a la espera de ese ejemplo.

Un saludo desde Vitoria

P.S. Por cierto, enhorabuena por el ascenso (veremos si hay suerte para el Alavés que está en ello .....)

publicado

Buenas ioyama,

Aquí te dejo dos archivos excel de ejemplo, el libro del servidor con macro infinita y el archivo que copia el libro del servidor para actualiar sus datos.

No se si será muy lioso de entender, de todas formas, ahi os dejo un video donde se puede como se montan estos dos archivos

http://www.youtube.com/watch?v=lNO4tzBYxhw

.
P.S. Por cierto, enhorabuena por el ascenso (veremos si hay suerte para el Alavés que está en ello .....)

Gracias y Dios te oiga amigo mio :rolleyes:

Libro Visor.zip

ArchivoExplorador.zip

publicado

Hola Sr.Betis:

No he entendido casi nada de este aporte, pero si ioyama dice que es bueno, me lo guardo para cuando me haga mayor.

Enhorabuena por el ascenso, sin el Betis en primera, Sevilla no tiene "algo especial".

Saludos a todos

publicado

Acabo de terminar por fin de subir el video a youtube, 10 minutos para grabar, mas de 1 hora para procesarse y subirse... no se como la gente sube tantos videos..., no sé que le habrá pasado a la calidad, será que aun lo está procesando. De todas formas, ponedlo a 480 de resolucion, quizas en unas horas se verá mejor como ya me ha pasado otras veces.

http://www.youtube.com/watch?v=lNO4tzBYxhw

Amigo Antoni, mira el video que acabo de subir que quizas ahí se entienda mejor, es menos lioso de lo que parece, (si tienes paciencia claro..., son 10 min).

Enhorabuena por el ascenso, sin el Betis en primera, Sevilla no tiene "algo especial".

Gracias!, Sevilla es mas especial con el Betis en primera :P

PS: Edito mensaje anterior con los archivos para incrustar el video.

Archivado

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

×
×
  • 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.