Saltar al contenido

Buscar en archivo de texto y devolver


Recommended Posts

publicado

Sé que con un archivo adjunto todo sería más fácil, pero en estos momentos no lo tengo conmigo....

Tengo un archivo de texto que contiene caracteres de ancho fijo y un rango de celdas en un libro de Excel que contiene valores

Mi deseo (que no consigo encontrar la forma de hacerlo) es crear una macro que busque en el archivo de texto todas las líneas que comienzan por la palabra "FORCE", compruebe si los caracteres de esa linea contenidos entre las posiciones 8 y 17 coinciden con el valor de alguna celda del rango en la hoja y, si coinciden, copie toda la línea del archivo de texto en un archivo nuevo .dat.

Si tenéis una respuesta rápida, lo agradeceré.

Saludos

publicado

Hola Sergio:

En principio se me ocurre una posible solución: Pasa el archivo de texto a una hoja de excel y luego filtra la primera columna con la palabra "FORCE" y posteriormente filtra la posicion 8 y 17 con los datos de las celdas pertinentes. Todo esto lo podrias hacer manualmente pero grabando todos los pasos con la grabadora de macros y despues se puede perfeccionar esa misma macro para eliminar las lineas inutiles o inoperantes.

Sin ejemplo es lo primero que se me ocurre, espero que te haya ayudado u orientado.

Andrés

publicado

pepafg, se trata de archivos te texto de hasta 20 gb con millones de líneas (no exagero). Lo que estaba buscando es un proceso que fuese relativamente rápido. Había pensado en introducir en una matriz los textos a comparar, es decir, las posiciones de la 8 a la 17 del archivo de texto, y los valores del rango de celdas de la hoja, pero no sé por qué, me aparecen errores.

publicado

Buenas, Sergio

He creado este pequeño código y parece que funciona.

Obviamente, se deberían configurar rutas, valores, etc....pero bueno, como idea....


Sub prueba_leer()
ruta = ThisWorkbook.Path & "\"
Archivo = Dir(ruta & "*.txt")
Set obj_FSO = CreateObject("Scripting.FileSystemObject")

'Creamos un archivo con el método CreateTextFile
Set nuevoarchivo = obj_FSO.CreateTextFile(ruta & "Resultado.dat", True)

Open [Archivo] For Input As #1
Do Until EOF(1)
Line Input #1, linea
If Left(linea, 5) = "FORCE" Then
If Mid(linea, 8, 10) = Range("a1").Value Then
nuevoarchivo.WriteLine linea
End If
End If
Loop
nuevoarchivo.Close
Close #1
End Sub
[/CODE]

Un saludo,

Tese

publicado

Algo así había pensado yo, pero no me serviría....

El rango en la hoja de cálculo está compuesto de 23 celdas más o menos. Si el archivo de texto, que tiene un millón de líneas, debe leerse 23 veces, imagina el tiempo que puede tardar en leer 23 millones de líneas....

Te agradezco la respuesta, pero necesitaría algo más rápido.

publicado

Pues quizás se pueda combinar con un bucle que chequee cada uno de esos valores de las 23 celdas, que previamente se hubieran incluido en un Array.

Un saludo,

Tese

publicado

Vamos a ver, Sergio, si con un par de modificaciones al primer código que he propuesto se consigue algo.


Sub prueba_leer()

For Each valor In Range("a1:a23")
cadena = valor & "," & cadena
Next valor

ruta = ThisWorkbook.Path & "\"
Archivo = Dir(ruta & "*.txt")
Set obj_FSO = CreateObject("Scripting.FileSystemObject")

'Creamos un archivo con el método CreateTextFile
Set nuevoarchivo = obj_FSO.CreateTextFile(ruta & "Resultado.dat", True)

Open ruta & Archivo For Input As #1
Do Until EOF(1)
Line Input #1, linea
If Left(linea, 5) = "FORCE" Then
If InStr(1, cadena, Mid(linea, 8, 10)) > 0 Then
nuevoarchivo.WriteLine linea
End If
End If
Loop
nuevoarchivo.Close
Close #1

End Sub[/CODE]

He creado una cadena con los valores y después utilizo InStr para que realice la comparacion de los caracteres 8 a 17 de la línea para ver si esta en dicha cadena.

Un saludo,

Tese

publicado

pepafg, el problema sería que no siempre van a ser 23 datos los que buscar.

tese, tu solución acelera mucho la macro, pero creo que se podría acelerar más.

gracias a los dos por vuestras propuestas.

publicado
pepafg, el problema sería que no siempre van a ser 23 datos los que buscar.

tese, tu solución acelera mucho la macro, pero creo que se podría acelerar más.

gracias a los dos por vuestras propuestas.

amigo Sergio, de verdad que sería de mucha ayuda por lo menos tener una muestra de los datos, la solución que propone el amigo tese1969 se ve muy buena, dificilmente creo que se pueda mejorar a menos que tengamos información sobre los datos a procesar para ver si se puede buscar otra solución, pero bueno, si no se puede subir una muestra ni modo, suerte

publicado

Bueno, Sergio y compañía.....al menos no vamos a peor....:friendly_wink:

Quizás y esto es algo que desconozco, se podría usar una especie de ".Find" y su correspondiente ".Findnext" a lo largo del archivo de texto para ir saltando aquellas líneas que no tengan "FORCE" y ese sería el ahorro.

Mejor realizar la comprobación del "Instr" sobre pongamos 150.000 líneas con "FORCE" que pasar por 1.000.000 de líneas.

Por si sirve como idea para seguir acelerando la ejecución.

Un saludo,

Tese

Archivado

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

  • 109 ¿Te parecen útiles los tips de las funciones? (ver tema completo)

    1. 1. ¿Te parecen útiles los tips de las funciones?


      • No
      • Ni me he fijado en ellos

  • Ayúdanos a mejorar la comunidad

    • Donaciones recibidas este mes: 0.00 EUR
      Objetivo: 130.00 EUR
  • Archivos

  • Estadísticas de descargas

    • Archivos
      188
    • Comentarios
      98
    • Revisiones
      29

    Más información sobre "Cambios en el Control Horario"
    Última descarga
    Por pegones1

    4    1

  • Crear macros Excel

  • Mensajes

    • Hola, veo que tienes 365, así que esta forma funcionará   Almacen.xlsx
    • Buenos días  @LeandroA espero estes bien Tengo un caso idéntico al planteado en la siguiente pregunta: Sin embargo, a diferencia de quien planteo originalmente la pregunta al correr el código no obtengo ningún resultado podrían ayudarme a resolver este inconveniente y que al hacer click en el Botón Guardar (CommandButton3) del Formulario RCS (frmrcs) el archivo pdf quede configurado con orientación vertical, márgenes superior, inferior, derecho e izquierdo = 1 y en página tamaño carta. Si acaso influye uso Microsoft Excel LTSC MSO (versión 2209 Compilación16.0.1.15629.20200) de 64 bits Mucho le sabre agradecer la ayuda que me pueda dar  RCS PRUEBA - copia.xlsm
    • @JSDJSDCon gusto mi estimado Para la opción 1: Sub Surtirhastadondealcanse() Dim ws As Worksheet Set ws = ThisWorkbook.Sheets(1) Dim filaInicio As Integer: filaInicio = 4 Dim filaFin As Integer: filaFin = 7 Dim colInventario As Integer: colInventario = 2 Dim colSolicitudesInicio As Integer: colSolicitudesInicio = 4 ' Columna C Dim colResultadoInicio As Integer: colResultadoInicio = 9 ' Columna I Dim colTotalSurtido As Integer: colTotalSurtido = 12 ' Columna L Dim colFinalInventario As Integer: colFinalInventario = 13 ' Columna M Dim numClientes As Integer: numClientes = 3 Dim fila As Integer, i As Integer For fila = filaInicio To filaFin Dim inventario As Double inventario = Val(ws.Cells(fila, colInventario).Value) Dim solicitudes(1 To 3) As Double Dim surtido(1 To 3) As Variant Dim totalSurtido As Double: totalSurtido = 0 ' Leer solicitudes For i = 1 To numClientes If IsNumeric(ws.Cells(fila, colSolicitudesInicio + i - 1).Value) Then solicitudes(i) = CDbl(ws.Cells(fila, colSolicitudesInicio + i - 1).Value) Else solicitudes(i) = 0 End If surtido(i) = "POR FALTA STOCK" Next i ' Surtir de acuerdo al inventario disponible For i = 1 To numClientes If solicitudes(i) > 0 Then If inventario >= solicitudes(i) Then surtido(i) = solicitudes(i) inventario = inventario - solicitudes(i) totalSurtido = totalSurtido + solicitudes(i) ElseIf inventario > 0 Then surtido(i) = inventario totalSurtido = totalSurtido + inventario inventario = 0 Else surtido(i) = "POR FALTA STOCK" End If End If Next i ' Escribir resultados en las columnas correspondientes para cada cliente For i = 1 To numClientes With ws.Cells(fila, colResultadoInicio + i - 1) If surtido(i) = "POR FALTA STOCK" Then .Value = surtido(i) .Font.Color = vbRed Else .Value = surtido(i) .Font.Color = vbBlack End If End With Next i ' Escribir total surtido y existencia final ws.Cells(fila, colTotalSurtido).Value = totalSurtido ws.Cells(fila, colFinalInventario).Value = inventario Next fila MsgBox "Resultado surtido cargado con éxito...", vbInformation End Sub Para la opción 2:   Sub surtirenpartesiguales() Dim ws As Worksheet Set ws = ThisWorkbook.Sheets(1) Dim filaInicio As Integer: filaInicio = 13 Dim filaFin As Integer: filaFin = 16 Dim colInventario As Integer: colInventario = 2 Dim colSolicitudesInicio As Integer: colSolicitudesInicio = 4 ' Columna C Dim colResultadoInicio As Integer: colResultadoInicio = 9 ' Columna I Dim colTotalSurtido As Integer: colTotalSurtido = 12 ' Columna L Dim colFinalInventario As Integer: colFinalInventario = 13 ' Columna M Dim numClientes As Integer: numClientes = 3 Dim fila As Integer, i As Integer For fila = filaInicio To filaFin Dim inventario As Double inventario = Val(ws.Cells(fila, colInventario).Value) Dim solicitudes(1 To 3) As Double Dim surtido(1 To 3) As Variant Dim totalSurtido As Double: totalSurtido = 0 Dim totalPedido As Double: totalPedido = 0 ' Leer solicitudes For i = 1 To numClientes If IsNumeric(ws.Cells(fila, colSolicitudesInicio + i - 1).Value) Then solicitudes(i) = CDbl(ws.Cells(fila, colSolicitudesInicio + i - 1).Value) totalPedido = totalPedido + solicitudes(i) Else solicitudes(i) = 0 End If surtido(i) = 0 Next i ' Si hay suficiente inventario, surtir lo que el cliente pide If inventario >= totalPedido Then For i = 1 To numClientes If solicitudes(i) > 0 And inventario >= solicitudes(i) Then surtido(i) = solicitudes(i) inventario = inventario - solicitudes(i) totalSurtido = totalSurtido + solicitudes(i) End If Next i Else ' Reparto base igualitario Dim baseSurtido As Long baseSurtido = Int(inventario / numClientes) For i = 1 To numClientes If solicitudes(i) > 0 Then If solicitudes(i) <= baseSurtido Then surtido(i) = solicitudes(i) inventario = inventario - solicitudes(i) totalSurtido = totalSurtido + solicitudes(i) Else surtido(i) = baseSurtido inventario = inventario - baseSurtido totalSurtido = totalSurtido + baseSurtido End If End If Next i ' Repartir sobrante restante uno por uno, respetando lo pedido Do While inventario > 0 For i = 1 To numClientes If surtido(i) < solicitudes(i) Then surtido(i) = surtido(i) + 1 totalSurtido = totalSurtido + 1 inventario = inventario - 1 If inventario = 0 Then Exit For End If Next i Loop End If ' Escribir resultados en las columnas correspondientes para cada cliente For i = 1 To numClientes With ws.Cells(fila, colResultadoInicio + i - 1) If surtido(i) = 0 Then .Value = "POR FALTA STOCK" .Font.Color = vbRed Else .Value = surtido(i) .Font.Color = vbBlack End If End With Next i ' Escribir total surtido y existencia final ws.Cells(fila, colTotalSurtido).Value = totalSurtido ws.Cells(fila, colFinalInventario).Value = inventario Next fila MsgBox "Resultado surtido cargado con éxito...", vbInformation End Sub Saludos, Diego
    • Buenos dias.  Estoy trabajando en una hoja para poder llevar un control de un pequeño almacén.  Tengo un pedido con varias líneas y "lotes" y necesito sacar las ubicaciones que coincidan con la referencia y lote que pone en el pedido. El problema viene cuando tengo la misma referencia y mismo lote en ubicaciones diferentes y necesito sacar la información en columnas diferentes. No se si  me he explicado bien, pero creo que con el ejemplo adjunto se entiende mejor. Agradecería mucho si me pudieran ayudar  Libro1.xlsx
    • Exelente solución mil gracias 
  • Visualizado recientemente

    • No hay usuarios registrado para ver esta página.
×
×
  • 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.