Private Enum EventosMaquinaIn
    EVENTO_AVERIA = -1
    EVENTO_ENTRADA = 0
    EVENTO_PARADA = 1
    EVENTO_MARCHA = 2
    EVENTO_REDUCE_VELOCIDAD = 3
End Enum
 
 
Private Type LineaSalida
    id As Long
    Inicio As Date
    Fin As Date
    Duracion As Integer
    ' eventoEspecificado as string
    Evento As String  ' se toman de la  matriz EventosMaquinaOut
    Maquina As String
    Motivo As String
End Type
 
' nótese que las cadenas se hacen coincidir en índices con EventosMaquinaIn
'  los valores se generan al crear la clase: ver Class_Initialize
Private EventosMaquinaOut(-1 To 3) As String
 
Private s_LinAnterior As LineaSalida
Private p_FicheroEntrada As String
Private p_FicheroSalida As String
 
Private s_cursorEntrada As Long
Private s_CursorSalida As Long
 
Private s_TamañoEntrada As Long
Private s_Id As Long
Private s_Maquina As String
 
 
Public Event Procesando()
Public Event Terminado()
Public Event ParoError()
 
 
Public Property Get FicheroSalida() As String
    FicheroSalida = p_FicheroSalida
End Property
 
Public Property Get FicheroEntrada() As String
    FicheroEntrada = p_FicheroEntrada
End Property
 
 
' esto debería invocarse cuando se arranca el programa antes de ejecutarse nada
'  para hacer esas cosas que sólo ocurrirán una única vez al principio.
Public Function InicializarProceso() As Boolean
    ' leemos de un fichero estado.txt
    '   si no existe se crea.
    '  pero si ya existe leemos
    '   donde quedamos la vez anterior, esto es si quedó un fichero sin terminar (suponiendo que esto interese)
    
    ' si estamos interesados en devolver algún estado devolvemos true, o false según convenga o cambiamos el tipo de devolución
    '  si queremos devolver otro tipo de dato.
    
    ' si deseamos decidir si empezar, o resetear el archivo de estado previo, deberíamos establecer un parámetro a la función.
    
    ' antes de devolver nos aseguramos de ver y asignar laos valores para las variables:
    '  p_ficheroentrada y p_ficherosalida
    
    InicializarProceso = True
End Function
 
Public Function Procesar()
    Dim Texto() As String
    Dim Lineas As Long
    
    ' si existe p_ficheroEntrada luego
         s_TamañoEntrada = FileLen(p_FicheroEntrada)
    '     si tamaño del fichero es mayor que p_cursorentrada luego (se ha escrito nuevo contenido)
    '
    '       (continuamos con la lectura, esto es en el siguiente apartado)
    '     el tamaño es el mismo  ' nada que procesar, se está esperando a que la máquina realice operaciones o  está terminado ?
    '         (necesitamos saber cuando un fichero está terminado: ¿ obbsstop indica esto ?)
    '         si sabemos que está terminado luego (debemos buscar el siguiente fichero)
    '             localizado = llamar a función: BuscarSiguienteEntrada
    '             si localizado False luego  (  no hay ficheros de entrada pendientes)
    '                 raiseevent Terminado
    '                 exit function
    '             fin condición: localizar siguiente fichero
    '         si sabemos que no está  terminado (debemos esperar)
    '             raiseevent Terminado
    '             exit function
    '         fin condicion: de lo que sabemos
    '     fin condicion: Tamaño no varía
    ' no existe fichero entrada
    '     localizado = llamar a función: BuscarSiguienteEntrada
    '     si localizado False luego  (  no hay ficheros de entrada pendientes)
    '           raiseevent Terminado
    '           exit function
    '     fin condición: localizar siguiente fichero
    ' fin condicion: existe fichero entrada
    
    
     Texto = TomarContenidoFicheroEntrada(Lineas) ' ( llamar a función tomar contenido de fichero de entrada)
     If Lineas < 1 Then ' -1= (ocurrió un error), 0=  se leyó el fichero pero parece que no contiene texto  ????
        RaiseEvent Terminado
        Exit Function
    Else     ' lineas es mayor que (hay líneas que procesar)
        Call ConvertirLineas(Texto) '    llamamos a otra función para tratar las líneas (sólo por claridad y sencillez de modificar las funciones)
        RaiseEvent Terminado
    End If ' fin condición hay líneas de texto leídas
End Function
 
 
' localiza el siguiente fichero que genera la máquina para ser procesado
Private Function BuscarSiguienteEntrada() As Boolean
    ' si localiza un ficheo
    '    p_ficheroentrada= ElficheroEncontrado
    '    s_cursorentrada= 1
    '    cerramos ficherosalida
    '    s_cursorSalida=1
    '    creamos y abrimos nuevoFichero de salida
    '    p_Ficherosalida = ElNuevoficherosalida ' elegir el nombre y la ruta, supuestamente basado en el nombre y ruta del de entrada
    '
    '    s_Maquina= "fiber-1" ' se supone que tú debes saber como obtener este dato.
    '
    '    devuelve True
    ' no localiza un nuevo fichero (quizás la máquina esté parada, o está en medio  de un largo proceso y no escribe hasta el ´termino)
    '    Devolver false
    ' fin condicion: localizar fichero
End Function
 
Private Function TomarContenidoFicheroEntrada(ByRef Lineas As Long) As String()
 
    ' abrimos el fichero
    ' posicionamos el crusor
    ' leemos hasta el final del archivo
    ' Troceamos el texto en líneas
    ' Devolvemos el texto
    
    Dim ff As Integer
    Dim Texto As String
    Dim txt() As String
    
    On Local Error GoTo ErrorTomar
    
    Texto = String(s_TamañoEntrada - p_cursorentrada + 1, " ")
    ff = FreeFile
    Open p_FicheroEntrada For Binary As #ff
        Get #ff, p_cursorentrada, Texto
    Close #ff
    
    Texto = Trim$(Texto)
    If Texto <> "" Then
        If InStr(1, Texto, vbCrLf) > 0 Then
            txt = Split(Texto, vbCrLf)
            Texto = ""  ' liberamos memoria
            Lineas = UBound(txt) + 1
            TomarContenidoFicheroEntrada = txt
            Erase txt  ' liberamos memoria
        Else
            Lineas = 1
            redim txt(0 to 0)
            Txt(0)=texto 
           TomarContenidoFicheroEntrada = txt
            Texto=""
            erase txt
        End If
    Else
        Lineas = 0
    End If
    Exit Function
    
ErrorTomar:
    Close #ff
    RaiseEvent ParoError
    'MsgBox "Error al leer fichero de entrada: " & vbCrLf & _
    'Err.Number & "  " & Err.Description, vbCritical
    
    Lineas = -1
End Function
 
 
 
Private Sub ConvertirLineas(ByRef Lineas() As String)
    ' iniciamos bucle
    '     procesamos línea a línea
    '     eventuualmente según la cantidad de parámetros de cada línea debe procesarse aparte
    ' terminamos bucle
    
    ' abrimos fichero de salida
    '     posicionamos el cursor de salida
    '     escribimos contenido
    ' cerramos fichero de salida
    
    Dim k As Long, n As Long
    Dim Salida() As LineaSalida
    Dim Linea() As String
    Dim txt As String
    
    ReDim Salida(-1 To UBound(Lineas))  ' ojo: insertamos la línea usada la última vez del proceso anterior como la línea -1
    Salida(-1) = s_LinAnterior
    
    For k = 0 To UBound(Lineas)
        Linea = Split(Lineas(k), " ") ' el divisor es un espacio
        
        Salida(k).Maquina = s_Maquina ' se supone que al cargar el fichero siguiente se obtiene ese valor que presumiblemente es constante para el mismo fichero.
        
        Salida(k).id = Salida(k - 1).id + 1
        Salida(k).Fin = Replace(Linea(0), ".", "-") & " " & Linea(1) '
        Salida(k).Inicio = Salida(k - 1).Fin
        Salida(k).Duracion = DateDiff("s", Salida(k).Fin, Salida(k).Inicio)
        
        ' importante: al guardar el fichero en modo binario, resulta ilegible si abrimos luego el archivo para leerlo, si queremos
        '  que sea legible (a la vista) debemos hacerque todos los campos de la estructura sean cadenas de texto
        ' entonces deberíamos declarar al menos 2 datos de fecha a nivel de la función
        
        ' por ejemplo:
        ' estas 3 líneas iría antes del bucle
        '   Dim Ini As Date, Fin As Date, id As Long
        '   id = Val(Salida(-1).id)
        '   fin= salida(-1).Fin
        ' estas líneas irían dentro del bucle sustituyendo a las previas
        '   Ini = Fin
        '   Fin = Replace(Linea(0), ".", "-") & " " & Linea(1)
        '   Salida(k).Duracion = CStr(DateDiff("s", Fin, Ini))
        '   Salida(k).Fin = CStr(Fin)
        '   Salida(k).Inicio = CStr(Ini)
        '   id = id + 1
        '   Salida(k).id = CStr(id)
        
        
        ' estos datos se supone que tienes que interpretar las constantes que aparecen en las líneas
        '  podrían meterse enuna enumeración o no con y una matriz asociada con ello nos podríamos ahorramos el select case en algunos casos
        Select Case Trim$(Linea(2))
            Case "MESSAGE"
                Salida(k).Evento = "?"
                Salida(k).Motivo = "?"
            Case "COMMENT"
                Salida(k).Evento = "?"
                Salida(k).Motivo = "?"
            Case "MATERIALFP"
                Salida(k).Evento = "?"
                Salida(k).Motivo = "?"
            ' más casos
                'Salida(k).Evento = "?"
                'Salida(k).Motivo = "?"
            ' ................
        End Select
    Next
    s_LinAnterior = Lineas(UBound(Lineas))
    
    Erase Lineas ' liberamos memoria
    redim preserve Salida(0 to ubound(salida)) ' eliminamos la línea previa -1 que añadimosprevio al bucle.    
 
    ' qué queremos hacer con las salida ???.
    ' si sólo lo queremos escribir a fichero
        
    ' escribiendo en modo binario (ilegible a la vista).
    Open p_FicheroSalida For Binary As #ff
        'Loc(ff) = s_CursorSalida
        'Put #ff, , Salida
        Put #ff, s_CursorSalida, Salida  ' tiene la ventaja de que escribe estructuras, matrices y matrices de estructura con 1 sola línea.
        s_CursorSalida = Seek(ff)
    Close #ff
    
    ' alternativamente puedes escribirlo como texto y usando un bucle (es totalmente legible a la vista)
    Open p_FicheroSalida For Output As #ff
        Loc(ff) = s_CursorSalida
        With Salida(k)
            For k = 0 To UBound(Salida)
                Print #ff, .id, .Inicio, .Fin, .Duracion, .Evento, .Maquina, .Motivo
            Next
        End With
        s_CursorSalida = Seek(ff)
    Close #ff
    Erase Salida ' liberamos memoria
End Sub
 
 
Private Sub Class_Initialize()
    EventosMaquinaOut(-1) = "AVERIA"
    EventosMaquinaOut(0) = "ENTRADA"
    EventosMaquinaOut(1) = "PARADA"
    EventosMaquinaOut(2) = "MARCHA"
    EventosMaquinaOut(3) = "VELOCIDAD REDUCIDA"
End Sub