Quisiera que uno de los códigos de mi libro excel se ejecute al abrir el libro, pero solo la primera vez que se abra el libro; osea, que la segunda vez que yo abra este libro, la macro ya no se ejecute. Pero si este libro se abre en otro pc se vuelva a ejecutar la macro (también una sola vez). ¿Es posible?
Respuesta de santiagomf
1
1
santiagomf, Más de 35 años en la informática y más de 20 trabajando con...
Lo que no hay duda es que siempre tendrás que ejecutar el evento 'Workbook_Open'. La primera vez completo y las restantes se cancelará tras comprobar que ya se ejecutó completo. Se me ocurren 2 formas: 1) Guardar en la propia hoja de cálculo algún identificador del ordenador usado. 2) Generar un fichero en alguna carpeta determinada y verificar si existe o no al entrar. Empecemos por el primero. Si cada ordenador que usas tiene un nombre distinto, podrías utilizar "environ("COMPUTERNAME")" para escribirlo en una página oculta y consultar si existe cuando abras la hoja de cálculo. El código podría ser algo así: Option Explicit Private Sub Workbook_Open() If Not snPrimeraEjecucion() Then Exit Sub ' Aquí vendría tu código... ' ... ' ... ' ... IncluirOrdenadorListaEjecuciones ' Para que no se vuelva a ejecutar End Sub Private Function snPrimeraEjecucion() As Boolean Dim paginaActiva As String Dim nHoja As Integer Dim i As Integer Dim miNombre As String ' Nombre del ordenador miNombre = Environ("COMPUTERNAME") ' Comprobamos si existe la página "PAGINA_OCULTA". Si no, la creamos paginaActiva = ActiveSheet.Name On Error Resume Next nHoja = Sheets("PAGINA_OCULTA").Index If Err = 75 Then Sheets.Add ActiveSheet.Name = "PAGINA_OCULTA" Sheets(paginaActiva).Activate Sheets("PAGINA_OCULTA").Hidden = True Else If Err <> 0 Then MsgBox "Error desconocido al buscar la 'PAGINA_OCULTA'." & vbCrLf & Error$ On Error GoTo 0 Exit Sub End If End If On Error GoTo 0 ' Ya sabemos que existe la página. Ahora comprobaremos si el nombre está ' en esa página o no i = 1 Do While Sheets("PAGINA_OCULTA").Cells(i, 1) <> "" If Sheets("PAGINA_OCULTA").Cells(i, 1) = miNombre Then ' No es la primera vez. snPrimeraEjecucion = False Exit Function End If i = i + 1 Loop snPrimeraEjecucion = True End Function Private Sub incluirOrdenadorListaEjecuciones() Dim i As Integer Dim miNombre As String ' Nombre del ordenador miNombre = Environ("COMPUTERNAME") i = 1 Do While Sheets("PAGINA_OCULTA").Cells(i, 1) <> "" i = i + 1 Loop Sheets("PAGINA_OCULTA").Cells(i, 1) = miNombre End Sub En caso de usar la segunda opción, generarías un fichero (supongamos que se llame ejecutado.txt) en una carpeta determinada y, al principio del código comprobarías si existe ese fichero. Para crear el fichero en la carpeta temporal, por ejemplo, pondrías: dim nf as integer nf=freefile open environ("TEMP") & "\ejecutado.txt" for output as nf close nf Al inicio comprobarías si existe el fichero if snExisteFichero(environ("TEMP") & "\ejecutado.txt") then exit sub La función snExisteFichero() la podrías definir así: Function snExisteFichero(ByVal nomFich As String) As Boolean Dim d As String On Error Resume Next d = Dir$(nomFich) If Err <> 0 Then d = "" On Error GoTo 0 snExisteFichero = (d <> "") End Function El problema de esta opción es que te borren el fichero, en cuyo caso se volvería a ejecutar la macro. Bueno, espero no haberte liado mucho y que te guste alguna de las soluciones.