alberto-moyano   21-12-2023, 02:15
#1
Hola gente, estoy intentando insertar un archivo CSV a una de las tablas de mi base de datos, antes de poder hacer el insert en SQLite necesito normalizar algunas de las cabeceras del archivo CSV que obtengo por exportación desde otro programa, el código que escribí es el sigueinte

Código:
Public Sub menuBIBingresar_Click()

  Dialog.Title = "Seleccionar archivo CSV con bibliografía"
  Dialog.Filter = ["*.csv", "Archivos de texto CSV"]
  Dialog.AutoExt = True
  Dialog.Path = User.Home & "/"
  Dialog.ShowHidden = False

  If Dialog.OpenFile() Then

    Dim rutaArchivo As String = Dialog.Filename ' Obtener la ruta del archivo seleccionado

    Dim reemplazos As String[][] ' Función que incorpora las referencias

    ' Defino los reemplazos
    reemplazos = [["BibliographyType", "NuevoNombre1"], ["ISBN", "NuevoNombre2"]]

    ' Llama a la función y obtengo la línea modificada
    Dim lineaModificada As String = ModificarNombresDeColumnas(rutaArchivo, reemplazos)

    ' Guardar la línea modificada
    Dim nuevoArchivo As String = rutaArchivo

    GuardarEnArchivo(nuevoArchivo, lineaModificada)
  End If

End

' Función para realizar la secuencia de reemplazos
Public Function ModificarNombresDeColumnas(archivo As String, reemplazos As String[][]) As String

  Dim miArchivo As File

  miArchivo = Open archivo For Read Write

  Dim linea As String = miArchivo.ReadLine

  miArchivo.Close

  ' Realiza los reemplazos de nombres
  Dim r As String[]
  For Each r In reemplazos
    linea = Replace(linea, r[0], r[1])
  Next

  Return linea

End

' Función para guardar en un archivo
Public Sub GuardarEnArchivo(archivo As String, contenido As String)

  Dim miArchivo As File

  miArchivo = Open archivo For Output

  ' Escribe el contenido en el archivo
  Print miArchivo, contenido

  ' Cierra el archivo
  miArchivo.Close

End

No obtengo ningún error del ide, pero tampoco el resultado buscado, no me queda claro si me estoy equivocando al escribir el cambio (piso sobre el mismo archivo) o si directamente no estoy haciendo los reemplazos.

¿Donde me estoy equivocando?

Gracias de antemano
cogier   21-12-2023, 18:07
#2
Para cambiar las cabeceras en un archivo CSV lo haría así: -

Código:
Public Sub Form_Open()
  
  Dim sFile As String = User.Home &/ "miCSV.csv"
  Dim rutaArchivo As String[] = Split(File.Load(sFile), gb.NewLine, "", True)
  Dim iLoop As Integer
  
  For iLoop = 0 To rutaArchivo.Max
    rutaArchivo[iLoop] = Replace(rutaArchivo[iLoop], "BibliographyType", "NuevoNombre1")
    rutaArchivo[iLoop] = Replace(rutaArchivo[iLoop], "ISBN", "NuevoNombre2")
  Next
  
  Kill sFile
  File.Save(sFile, rutaArchivo.Join(gb.NewLine))
  
End
alberto-moyano   22-12-2023, 01:04
#3
Gracias Cogier, lo pruebo y comento.

Funciona perfecto, hice unos cambios, el código quedo así

Código:
Public Sub btnImportar_Click()

  Dim sFile As String = File.Dir(txtORIGEN.Text) &/ File.Name(txtORIGEN.Text)
  Dim rutaArchivo As String[] = Split(File.Load(sFile), gb.NewLine, "", True)
  Dim iLoop As Integer

  'acá van todas las conversiones para JabRef y Zotero
  For iLoop = 0 To rutaArchivo.Max
    rutaArchivo[iLoop] = Replace(rutaArchivo[iLoop], "Identifier", "citationKey")
    rutaArchivo[iLoop] = Replace(rutaArchivo[iLoop], "Year", "yearY")
  Next

  Kill sFile
  File.Save(sFile, rutaArchivo.Join(gb.NewLine))

  'acá viene el INSERT a SQLite

  Me.Close

End
Última modificación: 22-12-2023, 06:15 por alberto-moyano.
tincho   27-12-2023, 23:38
#4
Hola Alberto.
Hago algunos comentarios a tu código.
Partiendo de la base que los archivos CSV tienen el encabezado en la primera fila, no veo la utilidad de recorrer todas las filas para reemplazar los nombres de las columnas.
Luego tampoco veo necesario alterar el archivo existente con File.Save....
También tenes que tener en cuenta para el insert si tenes un campo Serial (el id autoincremental por ejemplo) porque en ese caso la sentencia de insert cambia un poco.
Para finalizar, también podes usar un insert sin el nombre de los campos, solo basta que acomodes los datos en el mismo orden en que están en la tabla

Te propongo esta función que te devolvería una sentencia SQL con la que podrías insertar en la table, mediante:
Código:
[code]
Public Function Import(f As String, sTab As String, Optional t As String = "\t") As String

  Dim oRep As Collection = ["Year": "yearY", "Identifier": "citationKey"]
  Dim aLines As String[]
  Dim n As Integer
  Dim aHead As String[]
  Dim aData As String[]
  Dim aHead2 As String[]
  Dim h As String
  Dim sql As String = ""

  If Exist(f) Then ' Comprobación de existencia
    If Lower(File.Ext()) = "csv" Then ' si existe ¿Es del tipo CSV?
      aLines = Split(File.Load(f), gb.NewLine)
      If aLines.Count > 1 Then 'tiene mas de una fila
        aHead = Split(aLines[0], t)
        For Each h In aHead
          aHead2.Add(IIf(oRep.Exist(h), oRep[h], h))
        Next

        For n = 1 To aLines.Max
          aData = Split(aLines[n], t)
          sql &= "INSERT INTO " & sTab & " (" & aHead2.Join(", ") & ") VALUES (" & aData.Join(", ") & ");\n"
        Next
      Endif
    Endif
  Endif

  Return sql

End

Saludos.

1 Saludo.
alberto-moyano   29-12-2023, 01:09
#5
Hola Tincho, voy a trabajar sobre tu propuesta, pero algunas cuestiones --si te entendí bien-- no son los escenarios que planteas.

1. el archivo csv que obtengo por exportación desde JabRef, utiliza en la cabecera nombres diferentes a como estoy llamando a esas columnas en mi tabla, de ahí en renombrar las cabeceras.
2. el orden también es diferente y además vienen columnas que no utilizo y no vienen columnas que yo tengo en mi tabla.
3. si, tengo un id autoincremental.
4. el separador de campos es el punto y coma, ya que la coma es utilizada dentro del campo title en algunos títulos (por ejemplo: A las palabras se las lleva el viento, lo escrito queda).

Saludos
  
Usuarios navegando en este tema: 3 invitado(s)
Powered By MyBB, © 2002-2024 MyBB Group.
Made with by Curves UI.