Méthodes pour importer fichier csv dans access via winform

Morgane_43 Messages postés 5 Statut Membre -  
 Utilisateur anonyme -

Bonjour à tous, 

Je travaille actuellement sur un petit projet de récolte de données. J'ai développé un formulaire winform via vb. 
L'opérateur doit pouvoir créer un code projet et rattacher un fichier .csv. celui ci doit s'importer dans ma base de données dans la table donnees.  


Au début, je suis partie sur un import du fichier.csv dans un datagridview puis un ajout dans ma table donnees de ma base de données grâce à un Oledbcommand(INSERT INTO).

Cela fonctionne bien, mais comme il s'agit d'une boucle, dès l'instant où mon fichier est volumineux, cela met beaucoup de temps à s'importer dans ma table access. 
Je me demandais si vous aviez d'autres pistes pour faire cela ? 

Dans access j'utilise un doCmd import spreadsheet ou transfer text mais je ne crois pas qu'il y ait d'équivalence sous winform. 

Par avance merci beaucoup :) 
 


Windows / Chrome 110.0.0.0

4 réponses

  1. yg_be Messages postés 23437 Date d'inscription   Statut Contributeur Dernière intervention   Ambassadeur 1 588
     

    Je ne connais pas comment vb/winform peut interagir avec une base de données.  Je suppose que tu fais un INSERT par groupe d'enregistrements, pas un par enregistrement.

    J'ai l'impression qu'il serait plus efficace de faire cela en VBA, à partir de Excel ou de Access.

    0
  2. Utilisateur anonyme
     

    Bonjour 

    est ce que l'affichage des données sur la Winform est nécessaire (par exemple pour choisir quelles lignes doivent être importées, etc...)

    Si NON alors importer directement chaque ligne du csv devrait te faire gagner beaucoup de temps.

    Si OUI as tu chargé tes données dans une collection d'objets métier ou as tu "stocké" les infos dans le datagridview (cette 2eme solution est à éviter, notamment parce que longue)


    0
  3. Morgane_43 Messages postés 5 Statut Membre
     

    Bonjour à vous deux, 

    Merci beaucoup pour vos retours. 

    yg_be : Effectivement, utiliser excel directement avec access aurait été plus simple mais en réalité ce formulaire fait partie d'une application globale et ne peut pas être détaché du winform. Le but étant d'avoir une seule application pour tout. 

    Whismeril, L'affichage n'est absolument pas nécessaire car le but est d'importer toutes les lignes. Il n'y a aucun traitement à  faire dessus. 

    Je vous met mon code d'import de mon fichier puis de maj de la table pour que ce soit plus parlant. 

    Importer chaque ligne, ce n'est pas ce que je fais actuellement ?


    Je vais regarder du côté des collections d'objets métier (que je connais très peu, j'avoue). 

    Private Sub PictureBoxJoindre_Click(sender As Object, e As EventArgs) Handles PictureBoxJoindre.Click
    'J'ai une image "joindre"pour joindre mon fichier
    
            If OpenFileDialogfichier.ShowDialog = DialogResult.OK Then
                Dim titre As String
                titre = NomFichier.Text
                Fichierjoint.Text = OpenFileDialogfichier.FileName
    
                Dim source As String
                source = Fichierjoint.Text
                Dim dat As DataSet
                dat = New DataSet
                Using Conn As OleDbConnection = New OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & source & ";Extended Properties=""Excel 8.0;HDR=Yes;IMEX=1""")
                    Using Adap As OleDbDataAdapter = New OleDbDataAdapter("SELECT*FROM[Feuil1$]", Conn)
                        Adap.Fill(dat)
                        DataGridViewphicus.DataSource = dat.Tables(0)
                        Labelfichier.Visible = True
                    End Using
                End Using
            End If
    
        End Sub
    	
    'Ici j'ai donc mon datagridview de rempli avec mes infos 
    
    	 Private Sub PictureBoxSave_Click(sender As Object, e As EventArgs) Handles PictureBoxSave.Click
    	  Dim var As Integer
                    var = DataGridViewphicus.RowCount - 2
    				
    For i As Integer = 0 To var
                           Using Co As OleDbConnection = New OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=L:********.accdb")
                                Co.Open()
    Using cdm As OleDbCommand = New OleDbCommand("INSERT INTO T_Donnees ([*],[**],[***],[****],[*****],[*******],[*********]) VALUES (@*,@**,1,[@***],@****,@*******,@*********)", Co)
    cdm.Parameters.AddWithValue("@*", DataGridViewphicus.Rows(i).Cells(17).Value)
    cdm.Parameters.AddWithValue("@**", DataGridViewphicus.Rows(i).Cells(1).Value)
    cdm.Parameters.AddWithValue("@****", DataGridViewphicus.Rows(i).Cells(8).Value)
    cdm.Parameters.AddWithValue("@*****", DataGridViewphicus.Rows(i).Cells(7).Value)                                                               
    cdm.Parameters.AddWithValue("@******",DataGridViewphicus.Rows(i).Cells(44).Value)
    cdm.Parameters.AddWithValue("@*********", DataGridViewphicus.Rows(i).Cells(45).Value)
                                 
                                    cdm.ExecuteNonQuery()
                                    Co.Close()
                                End Using
                            End Using
                        Next i
                    End If
    	End Sub

    Encore merci pour votre aide

    0
    1. yg_be Messages postés 23437 Date d'inscription   Statut Contributeur Dernière intervention   1 588
       

      Pour accélérer l'exécution, il faudrait sortir de la boucle les instructions de création, ouverture et fermeture de la connexion Co.

      peut-être (je ne sais pas à quoi sert "using" ni surtout end using):

      Using Co As OleDbConnection = New OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=L:********.accdb")
      Co.Open()
      For i As Integer = 0 To var
      Using cdm As OleDbCommand = New OleDbCommand("INSERT INTO T_Donnees ([*],[**],[***],[****],[*****],[*******],[*********]) VALUES (@*,@**,1,[@***],@****,@*******,@*********)", Co)
      cdm.Parameters.AddWithValue("@*", DataGridViewphicus.Rows(i).Cells(17).Value)
      cdm.Parameters.AddWithValue("@**", DataGridViewphicus.Rows(i).Cells(1).Value)
      cdm.Parameters.AddWithValue("@****", DataGridViewphicus.Rows(i).Cells(8).Value)
      cdm.Parameters.AddWithValue("@*****", DataGridViewphicus.Rows(i).Cells(7).Value)                                                               
      cdm.Parameters.AddWithValue("@******",DataGridViewphicus.Rows(i).Cells(44).Value)
      cdm.Parameters.AddWithValue("@*********", DataGridViewphicus.Rows(i).Cells(45).Value)
      cdm.ExecuteNonQuery()
      End Using
      Next i
      Co.Close()
      End Using
      0
  4. Utilisateur anonyme
     

    Tout d'abord, il y a des années que je n'ai pas travaillé avec Access et je ne me souviens pas de l'avoir fait de cette manière.


    C'est bien un fichier csv que tu ouvres ou un fichier Excel?

    Parce que ça

     Using Conn As OleDbConnection = New OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & source & ";Extended Properties=""Excel 8.0;HDR=Yes;IMEX=1""")
                    Using Adap As OleDbDataAdapter = New OleDbDataAdapter("SELECT*FROM[Feuil1$]", Conn)
                        Adap.Fill(dat)
                        DataGridViewphicus.DataSource = dat.Tables(0)
                        Labelfichier.Visible = True
                    End Using
                End Using

    ça fait plus penser à Excel.

    Un csv c'est un fichier texte, y'a pas besoin de lancer une armada de Dataset, d'OleDbConnection et d'OleDbDataAdapter pour l'ouvrir.

    La classe File et sa méthode ReadAllLine suffit amplement.

    De plus, dans un csv, il n'y a que du texte (des string, pas de int, de double de bool, de datetime etc...), donc cela tend à faire penser que l'insertion dans Access n'a pas besoin de données typées (bien que cela soit possible).

    Et dans ce cas, il n'y aurait même pas besoin de classe métier intermédiaire, juste découpé chaque ligne du csv et mettre les "morceaux" dans la requette.

    Mais si c'est Excel et que les données sont typées, il sera peut-être nécessaire d'avoir une classe métier.

    Ensuite, cette boucle


    Quand j'étais petit, la mer Morte n'était que malade.
    George Burns


    0