Código para delimitar texto de informa access 2003

Quien me podría ayudar con un código. Les explicaré... Tengo un informe en access el cual quiero exportar a texto delimitado. Separado por (|). Esto es para que un proveedor de facturación electrónica pueda procesarlo, y me piden que sea texto delimitado. ¿Me podrían ayudar con esto? Les agradecería muchísimo de verdad. Se que con un código VS se puede, porque en access solo exporta en tablas o consultas.
1

1 Respuesta

165.800 pts. Más de 35 años en la informática y más de 20 trabajando...
Podrías incluir el siguiente código (entrar en diseño y pulsar <Alt><F11> para entrar en el editor de Visual Basic), para que te pregunte al cerrar el informe:
Option Compare Database
Option Explicit
Private Sub Report_Close()
    Dim resp As Integer
    ' Preguntamos si se quiere exportar los datos del informe
resp = MsgBox("¿Desea exportar los datos del informe?", vbQuestion + vbYesNo)
    If resp = vbNo Then Exit Sub    ' No quiere. ADIOS
    ' Si viene por aquí es que SI quiere exportarlos. Definimos las variables
    Dim rs As Recordset ' Para ir leyendo los registros del informe
    Dim nf As Integer   ' Número del archivo en el que vamos a escribir
    Dim nombreSalida As String  ' Nombre del fichero de salida que vamos a crear
    Dim linea As String ' Línea que vamos a escribir
    Dim i As Integer    ' Para contar los campos del registro
    Dim txtSQL As String    ' Para copiar el origen de registros del informe
    ' Generamos el nombre que va a tener el fichero de salida
nombreSalida = CurrentDb(). Name
    Do While Right$(nombreSalida, 1) <> "\"
        nombreSalida = Left$(nombreSalida, Len(nombreSalida) - 1)
    Loop
    ' Ahora nombreSalida contiene el nombre de la carpeta en la que está
' nuestra base de datos.
    ' Añadimos el nombre de salida
    nombreSalida = nombreSalida & "ficheroSalida.txt"
    ' Abrimos el fichero para escribir en él
    Close ' Por si hubiera algún fichero abierto
nf = FreeFile
    Open nombreSalida For Output As nf
    ' Para leer los datos de los registros que se están presentando en el formulario
    txtSQL = Me.RecordSource
    Set rs = CurrentDb().OpenRecordset(txtSQL, dbOpenDynaset)
    ' Escribiremos una línea con los nombres de los campos (quitar si se quiere)
    linea = ""
    For i = 0 To rs.Fields.Count - 1
        If linea <> "" Then linea = linea & "|"
        linea = linea & rs.Fields(i).Name
    Next i
    Print #nf, linea
    ' Ahora recorreremos todo el recordset escribiendo sus datos
    If Not rs.EOF Then rs.MoveLast: rs.MoveFirst
    SysCmd acSysCmdInitMeter, "Exportando datos del informe", rs.RecordCount
    Do While Not rs.EOF
        SysCmd acSysCmdUpdateMeter, rs.AbsolutePosition + 1
        DoEvents
        linea = ""
        For i = 0 To rs.Fields.Count - 1
            If linea <> "" Then linea = linea & "|"
            Select Case rs.Fields(i).Type
                Case dbDate: linea = linea & fechaATexto(rs.Fields(i).Value)
                Case dbBoolean: linea = linea & booleanATexto(rs.Fields(i).Value)
                Case dbInteger, dbLong, dbDouble, dbSingle, dbDecimal, _
                     dbNumeric: linea = linea & numeroATexto(rs.Fields(i).Value)
                Case Else: linea = linea & Nz(rs.Fields(i).Value)
            End Select
        Next i
        Print #nf, linea
        rs.MoveNext
    Loop
    rs.Close
    Close nf
    SysCmd acSysCmdClearStatus
    MsgBox "Fichero de salida creado"
End Sub
Function numeroATexto(ByVal valNum As Variant) As String
    numeroATexto = ""
    If IsNull(valNum) Then Exit Function        ' No viene dato
    If Not IsNumeric(valNum) Then Exit Function ' Error: no es un número
    ' Str$ utiliza el punto como separador decimal
    ' Si se quiere usar la coma de separación de decimal usar la
' función format$ en lugar de Str$
    numeroATexto = Trim$(Str$(valNum))
End Function
Function fechaATexto(ByVal valFec As Variant) As String
    fechaATexto = ""
    If IsNull(valFec) Then Exit Function        ' No viene dato
    If Not IsDate(valFec) Then Exit Function ' Error: no es un número
    fechaATexto = Format$(valFec, "yyyymmdd")   ' O el formato que pidan
End Function
Function booleanATexto(ByVal valBol As Integer) As String
    ' Devuelve S si es verdadero o N si es falso (poner los valores que se quiera)
    If valBol Then booleanATexto = "S" Else booleanATexto = "N"
End Function
También lo podrías asignar a un botón que pongas para evitar que te pregunte cada vez que cierres el informe.
Hola que tal,
Muchas gracias por tu pronta respuesta, de verdad estoy muy agradecido. Fíjate que abrí el informe (El cual esta filtrado solo para dar datos ejemplo: el numero de factura -y solo se presentan los datos filtrados)- lo puse en vista de diseño, pulsé Alt+f11 y apareció el editor de visual basic y pegué el código, tal cual como estaba desde donde empieza la declaración hasta el final, pero no sale nada. ¿Hice algo mal?,
Gracias
Hola Santiago,
ya pude insertar bien el código pero hay un pequeño problema, me delimita toda la tabla y no el contenido del informe.
Te explicaré, así es como llamo al informe con datos específicos:
  ([TICKET]=[Forms]![FACTURACION]![Cuadro combinado6])
¿Supongo qué habrá que modificar en el código para que delimite la información filtrada?
"Ticket es el código base para llamara los datos específicos.
Gracias, buen día.
Los datos del informe filtrado (Información de varias tablas) ya viene acomodado los datos en forma lineal no deben aparecer los campos arriba, cada línea es un dato especifico Claro que se los asigné directamente al informe con campos independientes ejemplo:
H1 |martin|Aguilar|calle 44|No 357|9873772|merida|Yucatán|mexico|||
H2 |Lubrimex SA de CV|Calle 60|No 8546|merida|Yucatán|mexico|||97000|
H4 |Bodega Lubrimex SA de CV|Calle 4|No. 147|merida|Yucatán|mexico|Jose Pérez
D| 78545|Balatas delanteras|4562.21|5212.25|897.23|7874.23|3|
S|4562.211|897.23|5459.34|
Así es como debiera aparecer, obviamente en el reporte de access aparece igual en formación idéntica pero sin delimitar.
Saludos cordiales,
Martin
Vamos a modificar el código anterior.
En la segunda línea incluiremos "Dim qd As QueryDef" para definir una nueva consulta temporal. De esta forma accederemos a la tabla de los datos y si hay algún filtro lo aplicaremos directamente sobre la consulta.
En dónde teníamos antes "txtSQL = Me.RecordSource" pondremos lo siguiente:
' Para leer los datos de los registros que se están presentando en el formulario
' crearemos una consulta con la misma selección que el informe
On Error Resume Next
DoCmd.RunSQL "drop table tmpQueryInforme"
On Error GoTo 0
txtSQL = Me.RecordSource
If InStr(UCase$(txtSQL), "SELECT ") = 0 Then txtSQL = "select * from " & txtSQL
Set qd = CurrentDb().CreateQueryDef("tmpQueryInforme", txtSQL)
qd.Close
' La selección ahora la hacemos de la consulta
txtSQL = "select * from tmpQueryInforme"
If Me.Filter <> "" Then txtSQL = txtSQL & " where " & Me.Filter
Con este código se crea la consulta y se aplica el filtro que tenga el informe.
Para terminar, al final del procedimiento, borraremos la consulta que hemos creado poniendo el siguiente código justo antes de la línea "MsgBox "Fichero de salida creado"". El código a incluir es:
On Error Resume Next
DoCmd.RunSQL "drop table tmpQueryInforme"
On Error GoTo 0
Hola Santiago,
Mira puse el código y suprimí lo que me habías recomendado pero me sale error 3131
así es como quedo el código completo.
-----------------------------------
Private Sub Report_Close()
    Dim resp As Integer
    ' Preguntamos si se quiere exportar los datos del informe
resp = MsgBox("¿Desea exportar los datos del informe al txt delimitado?", vbQuestion + vbYesNo)
    If resp = vbNo Then Exit Sub    ' No quiere. ADIOS
    ' Si viene por aquí es que SI quiere exportarlos. Definimos las variables
    Dim rs As Recordset ' Para ir leyendo los registros del informe
    Dim qd As QueryDef  ' Para definir un reporte temporal'
    Dim nf As Integer   ' Número del archivo en el que vamos a escribir
    Dim nombreSalida As String  ' Nombre del fichero de salida que vamos a crear
    Dim linea As String ' Línea que vamos a escribir
    Dim i As Integer    ' Para contar los campos del registro
    Dim txtSQL As String    ' Para copiar el origen de registros del informe
    ' Generamos el nombre que va a tener el fichero de salida
nombreSalida = CurrentDb().Name
    Do While Right$(nombreSalida, 1) <> "\"
        nombreSalida = Left$(nombreSalida, Len(nombreSalida) - 1)
    Loop
    ' Ahora nombreSalida contiene el nombre de la carpeta en la que está
' nuestra base de datos.
    ' Añadimos el nombre de salida
    nombreSalida = nombreSalida & "ficheroSalida.txt"
    ' Abrimos el fichero para escribir en él
    Close ' Por si hubiera algún fichero abierto
nf = FreeFile
    Open nombreSalida For Output As nf
    ' Para leer los datos de los registros que se están presentando en el formulario
' crearemos una consulta con la misma selección que el informe
On Error Resume Next
DoCmd.RunSQL "drop table tmpQueryInforme"
On Error GoTo 0
txtSQL = Me.RecordSource
If InStr(UCase$(txtSQL), "SELECT ") = 0 Then txtSQL = "select * from " & txtSQL
Set qd = CurrentDb().CreateQueryDef("tmpQueryInforme", txtSQL)
qd.Close
' La selección ahora la hacemos de la consulta
txtSQL = "select * from tmpQueryInforme"
If Me.Filter <> "" Then txtSQL = txtSQL & " where " & Me.Filter
On Error Resume Next
DoCmd.RunSQL "drop table tmpQueryInforme"
On Error GoTo 0
End Sub
----------
Está bien o deje pasar algo
Gracias Santiago por tu ayuda ojala y me pudieras corregir
saludos cordiales
Volví a retomer el primer código y el segundo paso por paso y finalmente quedó así:
Option Compare Database
Option Explicit
Private Sub Report_Close()
    Dim resp As Integer
    ' Preguntamos si se quiere exportar los datos del informe
resp = MsgBox("¿Desea exportar los datos del informe?", vbQuestion + vbYesNo)
    If resp = vbNo Then Exit Sub    ' No quiere. ADIOS
    ' Si viene por aquí es que SI quiere exportarlos. Definimos las variables
    Dim rs As Recordset ' Para ir leyendo los registros del informe
    Dim qd As QueryDef  'Para definir una nueva consulta temporal
    Dim nf As Integer   ' Número del archivo en el que vamos a escribir
    Dim nombreSalida As String  ' Nombre del fichero de salida que vamos a crear
    Dim linea As String ' Línea que vamos a escribir
    Dim i As Integer    ' Para contar los campos del registro
    Dim txtSQL As String    ' Para copiar el origen de registros del informe
    ' Generamos el nombre que va a tener el fichero de salida
nombreSalida = CurrentDb().Name
    Do While Right$(nombreSalida, 1) <> "\"
        nombreSalida = Left$(nombreSalida, Len(nombreSalida) - 1)
    Loop
    ' Ahora nombreSalida contiene el nombre de la carpeta en la que está
' nuestra base de datos.
    ' Añadimos el nombre de salida
    nombreSalida = nombreSalida & "ficheroSalida.txt"
    ' Abrimos el fichero para escribir en él
    Close ' Por si hubiera algún fichero abierto
nf = FreeFile
    Open nombreSalida For Output As nf
    ' Para leer los datos de los registros que se están presentando en el formulario
' Para leer los datos de los registros que se están presentando en el formulario
' crearemos una consulta con la misma selección que el informe
On Error Resume Next
DoCmd.RunSQL "drop table tmpQueryInforme"
On Error GoTo 0
txtSQL = Me.RecordSource
If InStr(UCase$(txtSQL), "SELECT ") = 0 Then txtSQL = "select * from " & txtSQL
Set qd = CurrentDb().CreateQueryDef("tmpQueryInforme", txtSQL)
qd.Close
' La selección ahora la hacemos de la consulta
txtSQL = "select * from tmpQueryInforme"
If Me.Filter <> "" Then txtSQL = txtSQL & " where " & Me.Filter
    ' Ahora recorreremos todo el recordset escribiendo sus datos
    If Not rs.EOF Then rs.MoveLast: rs.MoveFirst
    SysCmd acSysCmdInitMeter, "Exportando datos del informe", rs.RecordCount
    Do While Not rs.EOF
        SysCmd acSysCmdUpdateMeter, rs.AbsolutePosition + 1
        DoEvents
        linea = ""
        For i = 0 To rs.Fields.Count - 1
            If linea <> "" Then linea = linea & "|"
            Select Case rs.Fields(i).Type
                Case dbDate: linea = linea & fechaATexto(rs.Fields(i).value)
                Case dbBoolean: linea = linea & booleanATexto(rs.Fields(i).value)
                Case dbInteger, dbLong, dbDouble, dbSingle, dbDecimal, _
                     dbNumeric: linea = linea & numeroATexto(rs.Fields(i).value)
                Case Else: linea = linea & Nz(rs.Fields(i).value)
            End Select
        Next i
        Print #nf, linea
        rs.MoveNext
    Loop
    rs.Close
    Close nf
    SysCmd acSysCmdClearStatus
On Error Resume Next
DoCmd.RunSQL "drop table tmpQueryInforme"
On Error GoTo 0
Y en fecha texto, la cual puse en negrita, después de que sale el msgbox y doy aceptar sale el código y la pakabra en negrita aparece seleccionada FechaAtexto.
El filtro del informe es con la selkeccion de TICKET ( Si es que sirve de algo como referencia)
A ver si consigo explicarme bien.
Para empezar, en lugar de correcciones, te envío al final de esta respuesta el código completo.
Está probado con una base de datos de prueba y no creo que deba fallarte. Si tienes problemas con él, mándame una copia de la base de datos con unos pocos registros (y comprimida) a mi correo electrónico [email protected]
Un saludo
Option Compare Database
Option Explicit
Private Sub Report_Close()
    Dim resp As Integer
    Dim qd As QueryDef
    ' Preguntamos si se quiere exportar los datos del informe
resp = MsgBox("¿Desea exportar los datos del informe?", vbQuestion + vbYesNo)
    If resp = vbNo Then Exit Sub    ' No quiere. ADIOS
    ' Si viene por aquí es que SI quiere exportarlos. Definimos las variables
    Dim rs As Recordset ' Para ir leyendo los registros del informe
    Dim nf As Integer   ' Número del archivo en el que vamos a escribir
    Dim nombreSalida As String  ' Nombre del fichero de salida que vamos a crear
    Dim linea As String ' Línea que vamos a escribir
    Dim i As Integer    ' Para contar los campos del registro
    Dim txtSQL As String    ' Para copiar el origen de registros del informe
    ' Generamos el nombre que va a tener el fichero de salida
nombreSalida = CurrentDb(). Name
    Do While Right$(nombreSalida, 1) <> "\"
        nombreSalida = Left$(nombreSalida, Len(nombreSalida) - 1)
    Loop
    ' Ahora nombreSalida contiene el nombre de la carpeta en la que está
' nuestra base de datos.
    ' Añadimos el nombre de salida
    nombreSalida = nombreSalida & "ficheroSalida.txt"
    ' Abrimos el fichero para escribir en él
    Close ' Por si hubiera algún fichero abierto
nf = FreeFile
    Open nombreSalida For Output As nf
    ' Para leer los datos de los registros que se están presentando en el formulario
    ' Crearemos una consulta con la misma selección que el informe
    On Error Resume Next
    DoCmd.RunSQL "drop table tmpQueryInforme"
    On Error GoTo 0
    txtSQL = Me.RecordSource
    If InStr(UCase$(txtSQL), "SELECT ") = 0 Then txtSQL = "select * from " & txtSQL
    Set qd = CurrentDb().CreateQueryDef("tmpQueryInforme", txtSQL)
    qd.Close
    ' La selección ahora la hacemos de la consulta
    txtSQL = "select * from tmpQueryInforme"
    If Me.Filter <> "" Then txtSQL = txtSQL & " where " & Me.Filter
    Set rs = CurrentDb().OpenRecordset(txtSQL, dbOpenDynaset)
    ' Escribiremos una línea con los nombres de los campos (quitar si se quiere)
    linea = ""
    For i = 0 To rs.Fields.Count - 1
        If linea <> "" Then linea = linea & "|"
        linea = linea & rs.Fields(i).Name
    Next i
    Print #nf, linea
    ' Ahora recorreremos todo el recordset escribiendo sus datos
    If Not rs.EOF Then rs.MoveLast: rs.MoveFirst
    SysCmd acSysCmdInitMeter, "Exportando datos del informe", rs.RecordCount
    Do While Not rs.EOF
        SysCmd acSysCmdUpdateMeter, rs.AbsolutePosition + 1
        DoEvents
        linea = ""
        For i = 0 To rs.Fields.Count - 1
            If linea <> "" Then linea = linea & "|"
            Select Case rs.Fields(i).Type
                Case dbDate: linea = linea & fechaATexto(rs.Fields(i).Value)
                Case dbBoolean: linea = linea & booleanATexto(rs.Fields(i).Value)
                Case dbInteger, dbLong, dbDouble, dbSingle, dbDecimal, _
                     dbNumeric: linea = linea & numeroATexto(rs.Fields(i).Value)
                Case Else: linea = linea & Nz(rs.Fields(i).Value)
            End Select
        Next i
        Print #nf, linea
        rs.MoveNext
    Loop
    rs.Close
    Close nf
    SysCmd acSysCmdClearStatus
    On Error Resume Next
    DoCmd.RunSQL "drop table tmpQueryInforme"
    On Error GoTo 0
    MsgBox "Fichero de salida creado"
End Sub
Function numeroATexto(ByVal valNum As Variant) As String
    numeroATexto = ""
    If IsNull(valNum) Then Exit Function        ' No viene dato
    If Not IsNumeric(valNum) Then Exit Function ' Error: no es un número
    ' Str$ utiliza el punto como separador decimal
    ' Si se quiere usar la coma de separación de decimal usar la
' función format$ en lugar de Str$
    numeroATexto = Trim$(Str$(valNum))
End Function
Function fechaATexto(ByVal valFec As Variant) As String
    fechaATexto = ""
    If IsNull(valFec) Then Exit Function        ' No viene dato
    If Not IsDate(valFec) Then Exit Function ' Error: no es un número
    fechaATexto = Format$(valFec, "yyyymmdd")   ' O el formato que pidan
End Function
Function booleanATexto(ByVal valBol As Integer) As String
    ' Devuelve S si es verdadero o N si es falso (poner los valores que se quiera)
    If valBol Then booleanATexto = "S" Else booleanATexto = "N"
End Function

Añade tu respuesta

Haz clic para o

Más respuestas relacionadas