excel vba - usuario - Evite sobreescribir conflictos en el libro de trabajo compartido de Excel
formulario de usuario en vba (1)
Algunos antecedentes: construí un libro de trabajo compartido que sufrió muchos conflictos de salvar por parte de personas que agregaban elementos en filas nuevas al mismo tiempo.
El proceso de agregar una nueva fila de información se realiza a través de una macro, por lo que he creado una nueva versión donde la macro guarda el libro de trabajo antes de agregar la información, por lo tanto, se detienen dos conjuntos de datos en la misma fila.
Mi problema: Guardar el archivo realmente está ralentizando la macro porque el archivo es de aproximadamente 2 MB.
Mi pregunta: ¿hay alguna forma de acelerar el proceso de guardado, o tal vez solo actualizar el libro de trabajo con los cambios de otras personas para ahorrar tiempo?
Editar # 1
El macro archivo que actualiza la hoja compartida tiene otro objetivo principal. En base a los datos de un archivo de Excel local, utilizamos la macro para generar un texto estándar para informes.
Según una marca en el libro de trabajo compartido, el usuario verifica si el problema ya se informó o no.
También esta macro es utilizada por 4 o más personas al mismo tiempo, lo que da como resultado el conflicto.
Parece posible (no del todo claro) que evitar que varios usuarios ejecuten la macro al mismo tiempo podría ayudar a prevenir el problema. En base a los comentarios de OP aquí arriba está el código para lograr eso. El código verificará los procesos de Windows para ver si ya se está ejecutando otra instancia de esta macro. Obviamente, este control debería ser lo primero que sucede en el guión del OP.
Option Explicit
Function RunningInstancesOfThisScript()
Dim colProcesses
Dim objProcess
Dim lScriptCount
RunningInstancesOfThisScript = 0
lScriptCount = 0
'' Get list of running processes using WMI
Set colProcesses = GetObject("winmgmts://./root/cimv2").ExecQuery("Select * From Win32_Process")
For Each objProcess in colProcesses
If (Instr(1, objProcess.Commandline, WScript.ScriptFullName, vbTextCompare) <> 0) Then
lScriptCount = lScriptCount + 1
End If
Next
RunningInstancesOfThisScript = lScriptCount
End Function
Function IsThisScriptAlreadyRunning()
Dim lScriptCount
lScriptCount = RunningInstancesOfThisScript()
If (lScriptCount < 1) Then
'' This should not happen. There should be at least one instance, the current one
IsThisScriptAlreadyRunning = False
ElseIf (lScriptCount = 1) Then
'' The current instance is the only one
IsThisScriptAlreadyRunning = False
Else
IsThisScriptAlreadyRunning = True
End If
End Function
If (IsThisScriptAlreadyRunning() = True) Then
MsgBox "Another instance of this script is already running. This instance will now terminate without making any changes. Please try again after a few minutes.", vbExclamation
WScript.Quit
Else
MsgBox "There is no other instance of this script currently running. This instance will now proceed and make the changes needed.", vbInformation
End If
Otra opción es verificar si el archivo de Excel ya está abierto. Para ejecutar el siguiente script, necesitarás reemplazar <FileName>
con un nombre de archivo real.
Option Explicit
Function IsOfficeFileAlreadyOpen(strOfficeFileFullName)
Dim lPos
Dim strLockFileFullName
lPos = InstrRev(strOfficeFileFullName, "/", -1, vbBinaryCompare)
If (lPos = 0) Then
'' Only file name has been given, no path specified. Must be in current folder. Good luck!
strLockFileFullName = "~$" & strOfficeFileFullName
Else
strLockFileFullName = Left(strOfficeFileFullName, lPos) & "~$" & Mid(strOfficeFileFullName, lPos + 1)
End If
IsOfficeFileAlreadyOpen = CreateObject("Scripting.FileSystemObject").FileExists(strLockFileFullName)
End Function
If (IsOfficeFileAlreadyOpen("<FileName>") = True) Then
MsgBox "The file ''" & <FileName> & "'' is already open. Please try again once the file is closed.", vbExclamation
WScript.Quit
Else
'' Open the file first
MsgBox "The file ''" & "<FileName>" & "'' is available and will be processed.", vbInformation
End If
Ambas soluciones son susceptibles a las condiciones de carrera.