IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

VB 6 et antérieur Discussion :

Requete SQL multi tables


Sujet :

VB 6 et antérieur

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    119
    Détails du profil
    Informations personnelles :
    Localisation : France, Gironde (Aquitaine)

    Informations forums :
    Inscription : Juin 2008
    Messages : 119
    Points : 50
    Points
    50
    Par défaut Requete SQL multi tables
    Bonjour a tous,

    Je suis actuellement entrain de développer une application en VB6. Le but de mon application est d'ouvrir un fichier .txt pour les insérer dans ma base de données Access 2003 (En quelque sorte je dév une Moulinette).

    J'arrive a récupérer des données de mon fichier .Txt et les afficher dans un MsgBox. Cependant lorsque je veux insérer des données dans une table, j'y arrive, mais lorsque je veux insérer des données dans plusieurs tables (en l'occurrence 3) j'ai l'erreur suivante:

    Erreur d'éxecution '-2147467259 (80004005)
    "Vous ne pouvez pas ajouter ou modifier un enregistrement car l'enregistrement associé est requis dans las table 'Employés'

    J'ai regarder sur la toile mais je n'ai rien trouvé. C'est la raison pour laquelle je viens vous voir.

    Pour précision, je suis débutant en vb6 (Mon application est ma première en vb6).

    Voici mon code qui appel la fonction "importMSA":
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    Private Sub btnTraiterMSA_Click()
        If tbBDD.Text = "Choisir la base de données" Then
            MsgBox ("Veuillez sélectionner une base de données avant de vouloir traiter le fichier MSA ")
        Else
            Call importMSA
        End If
    End Sub
    et voici ma code d'import:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
     
    Sub importMSA()
        Dim nomFichierMSA As String
        Dim numFichier As Integer
        Dim vFin As Boolean
        Dim vNum As Integer    
        Dim vLigne As String
        Dim vMessage As String
        Dim vNomFichier As String
     
        Dim cnct As New ADODB.Connection
     
        nomFichierMSA = tbMSA.Text  'chemin du fichier .txt
        numFichier = FreeFile 	'Génère un descripteur de fichier libre, Définit un numéro de fichier libre
        Open nomFichierMSA For Input As numFichier 'Ouvre le fichier (en mode lecture)
        vNum = 1
        vFin = False
     
        While Not EOF(numFichier)                                       'Vérifie si la fin du fichier a été atteinte
            vFin = False
            While Not EOF(numFichier) And Not vFin
                Line Input #numFichier, vLigne                          'Lit une ligne
                If Mid(vLigne, 60, 2) = "10" Then                       '59 est la position du caractère qui marque le début de la partie à extraire
                    nomPrenom = Mid(vLigne, 62, 25)                     'et 2 correspond au nombre de caractères à renvoyer
                    numSS = Mid(vLigne, 39, 13)
                    MsgBox numSS & " " & nomPrenom
     
                        cnct.Open "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & tbBDD.Text & ";" ' Connexion à la base de donnée
                        cnct.Execute "INSERT INTO Employés (numSS, nom) VALUES ('" & Mid(vLigne, 39, 13) & "', '" & Mid(vLigne, 62, 25) & "')"
                        cnct.Close
                        Set cnct = Nothing 'Pour être sur que la connexion est bien fermé
                End If
                If Mid(vLigne, 60, 2) = "20" Then
                    brutMSA = Mid(vLigne, 88, 11)
                    vDate = Mid(vLigne, 52, 8)
                    'MsgBox vDate & " " & brutMSA
     
                        cnct.Open "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & tbBDD.Text & ";" ' Connexion à la base de donnée
                        cnct.Execute "INSERT INTO Salaires (dateSalaire, brutMSA) VALUES ('" & Mid(vLigne, 52, 8) & "', '" & Mid(vLigne, 88, 11) & "')"
                        cnct.Close
                        Set cnct = Nothing 'Pour être sur que la connexion est bien fermé
                End If
                If Mid(vLigne, 60, 2) = "30" Then
                    codeTypeCotisation = Mid(vLigne, 62, 5)
                    montant = Mid(vLigne, 87, 12)
                    'MsgBox codeTypeCotisation & " " & montant
     
                        cnct.Open "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & tbBDD.Text & ";" ' Connexion à la base de donnée
                        cnct.Execute "INSERT INTO Cotisations (typeCotisation, montant) VALUES ('" & Mid(vLigne, 62, 5) & "', '" & Mid(vLigne, 87, 12) & "')"
                        cnct.Close
                        Set cnct = Nothing 'Pour être sur que la connexion est bien fermé
                End If
           Wend
        Wend
        Close #numFichier 'Ferme le fichier
        MsgBox "Opération términée"
    End Sub
    Et L'erreur se situe au niveau de la ligne:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    cnct.Execute "INSERT INTO Salaires (dateSalaire, brutMSA) VALUES ('" & Mid(vLigne, 52, 8) & "', '" & Mid(vLigne, 88, 11) & "')"
    Merci pour votre aide, car je ne vois pas comment faire. J'espère avoir était assez claire.
    Cordialement.

  2. #2
    Membre averti
    Profil pro
    Inscrit en
    Août 2006
    Messages
    243
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 243
    Points : 328
    Points
    328
    Par défaut
    Après avoir effectué ton insert dans "Employés", tu dois récupérer l'ID de l'employé que tu viens de créer et ensuite l'utiliser dans ton insert sur le salaire.

    Le mieux dans ton cas est d'utiliser un recordset pour faire tes inserts plutôt que des execute.
    1. > employes
    2. ouvrir un rs avec un select
    3. addnew & update
    4. récupérer l'ID
      > salaires
    5. ouvrir un rs avec un select
    6. addnew (en utilisant l'ID récupéré en 3) & update

    Sans connaitre ton schema de base, il y a des chances que ta table Cotisations ait une clef externe sur employé et/ou salaire. Dans ce cas, à toi de récupérer le ou les ID selon le même principe.

    Sinon, quelques remarques sur ton code :
    1. dim...as new... : jamais !
      - Quand tu fait ça, dans le déroulement de ton code si ton instance n'a pas été créé, vb l'instanciera sans rien dire.
      - a chaque fois que tu utilise ton instance dans ton code, VB regarde si l'objet est instancié ou non (cf 1).
      - il faut faire dim...as... puis set ...= new ...
    2. ne ouvrir/fermer ta connexion à chaque insert c'est consommateur de temps/ressources. Il faut plutôt faire quelque chose comme :
      - ouverture fichier
      - ouverture connexion si il y a quelque chose à traiter
      - boucler sur la lecture du fichier & insertion employé, salaire, cotisation
      - fermeture connexion
      - fermeture fichier
    3. je ne comprends pas ta variable VFIN : elle est toujours à faux et EOF(numFichier) suffit pour sortir de la boucle dès que le fichier est fermé.
    4. tes deux while not EOF(numFichier) sont inutiles : l'interne suffit (lié au point précédent).
    5. ne jamais utiliser ce que tu viens de lire pour directement faire un insert.
      Si par exemple, ton employé s'appelle <D'estaing>, ta requête ne va pas apprécier du tout .
      Avant d'utiliser ces valeurs, tu dois t'assurer qu'il n'y a pas de ', ", ?, *, etc...S'il y en a, tu dois mettre en place un système de remplacement (le plus simple est de les remplacer par un espace)
      Par principe, il ne faut jamais faire confiance à des données qui viennent de l'extérieur (valeurs nulles, absurdes, chaine alors que tu attend un nombre, caractères interdits/non visibles, etc...) et pas beaucoup plus à celles que tu génère toi-même

  3. #3
    Membre du Club
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    119
    Détails du profil
    Informations personnelles :
    Localisation : France, Gironde (Aquitaine)

    Informations forums :
    Inscription : Juin 2008
    Messages : 119
    Points : 50
    Points
    50
    Par défaut
    Merci pour ta réponse "250rgv".

    Je vais tester tous ce que tu m'as dis. Par contre pour les requêtes SQL, comme tu viens de me dire, ma requête échoue car il y a un nom qui a une apostrophe. Donc requête qui échoue. Ainsi je veux faire une requête SQL paramétré pour éviter le plantage mais je ne connais pas la syntaxe.
    J'ai regardé sur le net, mais je ne trouve pas. Peux-tu m'indiquer la synthaxe.

    De plus, je ne comprends pas ce que tu veux dire par :
    1. > employes
    2. ouvrir un rs avec un select
    3. addnew & update
    4. récupérer l'ID
    > salaires
    5. ouvrir un rs avec un select
    6. addnew (en utilisant l'ID récupéré en 3) & update

    Je viens de refaire ma connection avec un recordset mais j'ai une erreur qui est la suivante:

    ERREUR '3704':
    Cette opération n'est pas autorisé si l'objet est fermé.

    L'erreur se trouve sur mon rst.Close

    Cordialement.

  4. #4
    Membre averti
    Profil pro
    Inscrit en
    Août 2006
    Messages
    243
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 243
    Points : 328
    Points
    328
    Par défaut
    Voici un exemple de code (fait avec notepad ET NON TESTE/FONCTIONNEL !!!)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
     
    Dim rsEmploye As ADODB.Recordset
    Dim rsSalaire As ADODB.Recordset
    dim sql as string
    Dim CType As ADODB.CursorTypeEnum
    Dim LType As ADODB.LockTypeEnum
    Dim CLocation As ADODB.CursorLocationEnum
    dim IDEmploye 'je ne connais le type de la clef primaire de ta table employé
     
    Set rsEmploye = New ADODB.Recordset
    with rsEmploye
    	' A toi de définir tes bonnes valeurs pour CType,LType,CLocation avant de les utiliser 
    	'(je ne me souviens plus des valeurs par défaut si lors de l'instanciation d'un recordset, voir la doc ADO)
    	.CursorLocation = CLocation
    	.CursorType = CType
    	.LockType = LType
    	Set .ActiveConnection = cnct 'ton instance de ADODB.Connection
    	.Open "...." 'ta requête sql, par exemple, sql="select * from employés"
    end with
     
    Set rsSalaire = New ADODB.Recordset
    with rsSalaire
    	' A toi de définir tes bonnes valeurs pour CType,LType,CLocation avant de les utiliser 
    	'(je ne me souviens plus des valeurs par défaut si lors de l'instanciation d'un recordset
    	.CursorLocation = CLocation
    	.CursorType = CType
    	.LockType = LType
    	Set .ActiveConnection = cnct 'ton instance de ADODB.Connection
    	.Open "...." 'ta requête sql, par exemple, sql="select * from salaires"
    end with
     
    While Not EOF(numFichier)
    	...
    	with rsEmploye
    		.addnew
    		.fields("numSS").value=...
    		.fields("nom").value=...
    		.update
    		IDEmploye=.fields("ID").value 'si ta clef primaire s'appelle ID. A toi de voir selon ton schéma de base de données
    	end with
     
    	with rsSalaire
    		.addnew
    		.fields("IDEmploye").value=...'si ta clef externe s'appelle IDEmploye. A toi de voir selon ton schéma de base de données
    		.fields("dateSalaire").value=...
    		.fields("brutMSA").value=...
    		.update
    	end with
    	etc...
    	....
    Wend
    rsrsEmploye.close
    rsSalaire.close
    Trois derniers conseils :
    1. NE JAMAIS utiliser de caractères avec des accents ou autres caractères de ce genre dans des noms de table ou de colonne ! Idem pour les espaces.
      Même si ton "SGBD" actuel le permet, peut-être un jour devras-tu en changer et tu ne sais pas si ce sera le cas avec le "prochain".
    2. Utilise des transactions (regarde dans la doc de ADO pour des exemples)
    3. La doc. ADO est ton amie

  5. #5
    Membre du Club
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    119
    Détails du profil
    Informations personnelles :
    Localisation : France, Gironde (Aquitaine)

    Informations forums :
    Inscription : Juin 2008
    Messages : 119
    Points : 50
    Points
    50
    Par défaut
    Merci pour ton aide.

    Je vais prendre (du moins essayer ^^) en considération toutes les informations que tu m'as donné.

    En tout cas, encore un grand merci pour ton générosité.

    Je vais tester tous sa et je te tiendrais au courant.

    Cordialement.

  6. #6
    Membre du Club
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    119
    Détails du profil
    Informations personnelles :
    Localisation : France, Gironde (Aquitaine)

    Informations forums :
    Inscription : Juin 2008
    Messages : 119
    Points : 50
    Points
    50
    Par défaut
    Je reviens a la charge ^^
    J'ai essayé de faire des modifications dans mon appli en suivant le code que tu m'avais donné. Mais pour être honnête je ne comprends pas tous.

    Ma question est: Pourquoi on déclare les recordset avant la lecture du fichier et non dans la lecture du fichier (cad dans la boucle While Not EOF (numFichier))?
    Car si les RecordSet sont déclarés avant la boucle. Je ne peux pas mettre mes conditions? Parceque la requete SQL se situe dans l'initialisation du record?
    J'ai essayer mais je ne comprends pas tout..

    Voici le "nouveau" code:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
     
    Sub importMSA2()
     
    Dim rstEmploye As ADODB.Recordset
    Dim rstSalaire As ADODB.Recordset
    Dim rstCotisation As ADODB.Recordset
    Dim CType As ADODB.CursorTypeEnum
    Dim LType As ADODB.LockTypeEnum
    Dim CLocation As ADODB.CursorLocationEnum
    Dim Cnct As ADODB.Connection
     
     
    Dim IDEmploye As Integer
    Dim nomFichierMSA As String
    Dim numFichier As Integer
    Dim vNum As Integer
    Dim id As Integer
    Dim sql As String
     
    Set rstEmploye = New ADODB.Recordset
    With rstEmploye
        CType = adOpenStatic
        LType = adLockOptimistic
        CLocation = adUseClient
        .CursorLocation = CLocation
        .CursorType = CType
        .LockType = LType
        Set .ActiveConnection = Cnct 'instance de ADODB.Connection
        .Open "INSERT INTO Employes (numSS, nom) VALUES ('" & Mid(vLigne, 39, 13) & "', '" & Mid(vLigne, 62, 25) & "')" 'ta requête sql, par exemple, sql="select * from employés"
    End With
     
    Set rstSalaire = New ADODB.Recordset
    With rstSalaire
        CType = adOpenStatic
        LType = adLockOptimistic
        CLocation = adUseClient
        .CursorLocation = CLocation
        .CursorType = CType
        .LockType = LType
        Set .ActiveConnection = Cnct ' instance de ADODB.Connection
        .Open "SELECT idEmploye FROM Employe WHERE " 'Requête sql
    End With
     
    Set rstCotisation = New ADODB.Recordset
    With rstCotisation
        CType = adOpenStatic
        LType = adLockOptimistic
        CLocation = adUseClient
        .CursorLocation = CLocation
        .CursorType = CType
        .LockType = LType
        Set .ActiveConnection = Cnct
        .Open "INSERT INTO Cotisations (typeCotisation, montant) VALUES ('" & Mid(vLigne, 62, 5) & "','" & Mid(vLigne, 87, 12) & "')"
    End With
     
    nomFichierMSA = tbMSA.Text                      'chemin du fichier .txt
    numFichier = FreeFile                           'Génère un descripteur de fichier libre, Définit un numéro de fichier libre
    Open nomFichierMSA For Input As numFichier      'Ouvre le fichier (en mode lecture)
    'vNum = 1
    While Not EOF(numFichier)
        Line Input #numFichier, vLigne              'Lit une ligne
        Set Cnct = New ADODB.Connection
        Cnct.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & tbBDD.Text & ";"
        Cnct.Open
        If Mid(vLigne, 60, 2) = "10" Then
            vNomPrenom = Mid(vLigne, 62, 25)
            vNumSS = Mid(vLigne, 39, 13)
            MsgBox numSS & " " & nomPrenom
            With rstEmploye
                .AddNew
                .Fields("numSS").Value = Mid(vLigne, 39, 13)
                .Fields("nom").Value = Mid(vLigne, 62, 25)
                .Update
                IDEmploye = .Fields("idEmploye").Value
            End With
        End If
        If Mid(vLigne, 60, 2) = "20" Then
            brutMSA = Mid(vLigne, 88, 11)
            vDate = Mid(vLigne, 52, 8)
            MsgBox vDate & " " & brutMSA
            With rstSalaire
                .AddNew
                .fields("idEmploye").value=...
                .Fields("dateSalaire").Value = Mid(vLigne, 52, 8)
                .Fields("brutMSA").Value = Mid(vLigne, 88, 11)
                .Update
                IDSalaire = .Fields("idSalaire").Value
            End With
        End If
        If Mid(vLigne, 60, 2) = "30" Then
            codeTypeCotisation = Mid(vLigne, 62, 5)
            montant = Mid(vLigne, 87, 12)
            MsgBox codeTypeCotisation & " " & montant
            With rstCotisation
                .AddNew
                .Fields("typeCotisation").Value = Mid(vLigne, 62, 5)
                .Fields("montant").Value = Mid(vLigne, 87, 12)
                .Update
            End With
        End If
    Wend
    rstEmploye.Close
    rstSalaire.Close
    rstCotisation.Close
    Cnct.Close
    Set Cnct = Nothing 'Pour être sur que la connexion est bien fermé
    Set rstEmploye = Nothing
    Set rstSalaire = Nothing
    Set rstCotisation = Nothing
    End Sub
    Cordialement.

  7. #7
    Membre expert
    Avatar de Delbeke
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    2 675
    Détails du profil
    Informations personnelles :
    Âge : 70
    Localisation : France

    Informations forums :
    Inscription : Juillet 2006
    Messages : 2 675
    Points : 3 696
    Points
    3 696
    Par défaut
    Pour être plus clair

    Le message
    Vous ne pouvez pas ajouter ou modifier un enregistrement car l'enregistrement associé est requis dans las table 'Employés'
    est declenché par le moteur de la base de données car une régle (dite de relation d'intégrité référentielle) dit qu' on ne peut pas enregister dans la table salaire un enregistrement concernant un employé non existant dans la table Employés.

  8. #8
    Membre du Club
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    119
    Détails du profil
    Informations personnelles :
    Localisation : France, Gironde (Aquitaine)

    Informations forums :
    Inscription : Juin 2008
    Messages : 119
    Points : 50
    Points
    50
    Par défaut
    Merci pour votre réponse, même si 250rgv me l'avait déja dit.
    Le probléme n'est pas celui la. mais plutot dans la facon de procéder. Car j'ai chercher sur le net (autres forums ou tuto) mais je ne trouve rien sur mon cas. Meme si je sais qu'il n'y aura jamais mon cas a 100%, mais quelque chose qui s'en rapproche:

    C'est à dire:
    - Connexion avec BDD access
    - Lecture fichier txt
    - Insertion des données du fichier Txt dans la BDD Access
    avec recordset, sql insert, select Id etc...

    Mais je continue a chercher. Merci pour vos infos, sa me permet d'avancer.
    Cordialement.

  9. #9
    Membre averti
    Profil pro
    Inscrit en
    Août 2006
    Messages
    243
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 243
    Points : 328
    Points
    328
    Par défaut
    Pour ton dernier post, on ne s'est pas compris :

    voila comment je vois ton code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
     
    Sub importMSA2()
     
     ' déclaration des tes variables
    ...
    ' ouverture de ton  fichier en entrée
    ...
     
    if Not EOF(numFichier) then
    	' instanciation et ouverture de ta connexion
    	...
    	Set rstEmploye = New ADODB.Recordset
    	With rstEmploye
    		...
    		.Open "select * from Employes"
    	End With
     
    	Set rstSalaire = New ADODB.Recordset
    	With rstSalaire
    		...
    		.Open "SELECT * from salaires"
    	End With
     
    	Set rstCotisation = New ADODB.Recordset
    	With rstCotisation
    		...
    		.Open "select * from Cotisations"
    	End With
    end if
    While Not EOF(numFichier)
        Line Input #numFichier, vLigne              'Lit une ligne
        If Mid(vLigne, 60, 2) = "10" Then
    			...
        End If
        If Mid(vLigne, 60, 2) = "20" Then
    			...
    			With rstSalaire
    				.AddNew					
    				.fields("idEmploye").value=IDEmploye
    				...
    				.Update
    			End With
        End If
        If Mid(vLigne, 60, 2) = "30" Then
    			...
    			Question : Tu n'a  pas de lien entre les cotisations & les enregistrements que tu viens d'insérer ? pe, une cotisation n'est pas lié à un salaire ou un employé ?
        End If
    Wend
    if not (Cnct is nothing) then
    	rstEmploye.Close
    	rstSalaire.Close
    	rstCotisation.Close
    	Cnct.Close
    	Set rstEmploye = Nothing
    	Set rstSalaire = Nothing
    	Set rstCotisation = Nothing
    	Set Cnct = Nothing 'Pour être sur que l'instance de ta connexion est bien "libérée" (ce qui est différend de "fermée", la fermeture se faisant via le close)
    end if
    End Sub
    En fait, j'ai l'impression que tu t'est lancé dans l'accès à une base de donnée sans en maitriser les bases théoriques.
    Tu devrais poser ton clavier, chercher un tutorial comme celui-ci et commencer par là, tout s'éclaircira ensuite.

    Bon courage,

  10. #10
    Membre du Club
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    119
    Détails du profil
    Informations personnelles :
    Localisation : France, Gironde (Aquitaine)

    Informations forums :
    Inscription : Juin 2008
    Messages : 119
    Points : 50
    Points
    50
    Par défaut
    Merci pour tous.
    Pour t'expliquer, je suis en stage et on me demande de developper en VB. Chose que je n'ai jamais faite.

    Normalement je développe en C# et pour etre honnéte je suis un peu perdu. Car la connexion en C#, je sais faire (meme si je ne suis pas un maître en la matiére, mais je me débrouille).

    Je vais éplucher tous sa. Merci

    Pour répondre a ta question (dans le code):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    If Mid(vLigne, 60, 2) = "30" Then
    			...
    			Question : Tu n'a  pas de lien entre les cotisations & les enregistrements que tu viens d'insérer ? pe, une cotisation n'est pas lié à un salaire ou un employé ?
        End If
    J'ai bien un lien entre la table Salaire et cotisation.
    La structure de la BDD Access est la suivante:

    Employe lien vers Salaire lien vers Cotisation.
    (Avec l'id qui migre)

    Employe: idEmploye, numSS etc.
    Salaire: idSalaire, idEmploye, etc..
    Cotisation: idCotisation, idSalaire, etc..

  11. #11
    Membre averti
    Profil pro
    Inscrit en
    Août 2006
    Messages
    243
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 243
    Points : 328
    Points
    328
    Par défaut
    Tu devras donc récupérer l'ID de l'enreg. ajouté dans ta table salaires & l'insérer dans ta table cotisations.

  12. #12
    Membre du Club
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    119
    Détails du profil
    Informations personnelles :
    Localisation : France, Gironde (Aquitaine)

    Informations forums :
    Inscription : Juin 2008
    Messages : 119
    Points : 50
    Points
    50
    Par défaut
    Bonjour 250rgv,

    Merci pour cette info.

    Je reviens vers toi, car j'ai un petit soucis (pour changer ^^).
    J'ai modifié mon code avec le code que tu m'as passé hier. Voici le nouveau code:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
     
    Sub importMSA2()
     
     ' déclaration des variables
    Dim rstEmploye As ADODB.Recordset
    Dim rstSalaire As ADODB.Recordset
    Dim rstCotisation As ADODB.Recordset
    Dim CType As ADODB.CursorTypeEnum
    Dim LType As ADODB.LockTypeEnum
    Dim CLocation As ADODB.CursorLocationEnum
    Dim Cnct As ADODB.Connection
     
     
    Dim IDEmploye As Integer
    Dim IDSalaire As Integer
    Dim nomFichierMSA As String
    Dim numFichier As Integer
    Dim vNum As Integer
    Dim id As Integer
    Dim sql As String
     
     
    ' ouverture du fichier en entrée
    nomFichierMSA = tbMSA.Text
    numFichier = FreeFile                           'Génère un descripteur de fichier libre, Définit un numéro de fichier libre
    Open nomFichierMSA For Input As numFichier      'Ouvre le fichier (en mode lecture)
     
    If Not EOF(numFichier) Then
        ' instanciation et ouverture de ta connexion
        Set Cnct = New ADODB.Connection
        Cnct.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & tbBDD.Text & ";"
        Cnct.Open
        Line Input #numFichier, vLigne
     
        Set rstEmploye = New ADODB.Recordset
        With rstEmploye
            CType = adOpenStatic
            LType = adLockOptimistic
            CLocation = adUseClient
            .CursorLocation = CLocation
            .CursorType = CType
            .LockType = LType
            Set .ActiveConnection = Cnct 'instance de ADODB.Connection
            .Open "SELECT * FROM Employes"
        End With
     
        Set rstSalaire = New ADODB.Recordset
        With rstSalaire
            CType = adOpenStatic
            LType = adLockOptimistic
            CLocation = adUseClient
            .CursorLocation = CLocation
            .CursorType = CType
            .LockType = LType
            Set .ActiveConnection = Cnct ' instance de ADODB.Connection
     
            .Open "SELECT * FROM Salaires"
        End With
     
        Set rstCotisation = New ADODB.Recordset
        With rstCotisation
            CType = adOpenStatic
            LType = adLockOptimistic
            CLocation = adUseClient
            .CursorLocation = CLocation
            .CursorType = CType
            .LockType = LType
            Set .ActiveConnection = Cnct
            .Open "SELECT * FROM Cotisations"
        End With
    End If
    While Not EOF(numFichier)
        Line Input #numFichier, vLigne              'Lit une ligne
        If Mid(vLigne, 60, 2) = "10" Then
            vNomPrenom = Mid(vLigne, 62, 25)
            vNumSS = Mid(vLigne, 39, 13)
            With rstEmploye
                .AddNew
                .Fields("numSS").Value = Mid(vLigne, 39, 13)
                .Fields("nom").Value = Mid(vLigne, 62, 25)
                .Update
                IDEmploye = .Fields("idEmploye").Value
            End With
        End If
        If Mid(vLigne, 60, 2) = "20" Then
            brutMSA = Mid(vLigne, 88, 11)
            vDate = Mid(vLigne, 52, 8)
            With rstSalaire
                .AddNew
                .Fields("idEmploye").Value = IDEmploye
                .Fields("dateSalaire").Value = Mid(vLigne, 52, 8)
                .Fields("brutMSA").Value = Mid(vLigne, 88, 11)
                .Update
                IDSalaire = .Fields("idSalaire").Value
            End With
        End If
        If Mid(vLigne, 60, 2) = "30" Then
            codeTypeCotisation = Mid(vLigne, 62, 5)
            montant = Mid(vLigne, 87, 12)
            With rstCotisation
                .AddNew
                .Fields("idSalaire").Value = IDSalaire
                .Fields("typeCotisation").Value = Mid(vLigne, 62, 5)
                .Fields("montant").Value = Mid(vLigne, 87, 12)
                .Update
            End With
        End If
    Wend
    If Not (Cnct Is Nothing) Then
        rstEmploye.Close
        rstSalaire.Close
        rstCotisation.Close
        Cnct.Close
        Set rstEmploye = Nothing
        Set rstSalaire = Nothing
        Set rstCotisation = Nothing
        Set Cnct = Nothing 'Pour être sur que l'instance de ta connexion est bien "libérée" (ce qui est différent de "fermée", la fermeture se faisant via le close)
    End If
    MsgBox "Opération términée"
    End Sub
    Avec ce code: mon insertion marche très bien pour une personne (J'ai crée un fichier test avec une personne (Meme structure que l'original)), les trois tables (Employes, Salaires et cotisations) .
    Par contre, si j'essaye d'insérer le fichier qui contient tous les employés sa ne marche pas.

    J'ai toujours l'erreur suivante : "Vous ne pouvez pas ajouter ou modifier un enregistrement car l'enregistrement associé est requis dans la table Employés." Et je suppose que sa me fera la meme erreur pour la table cotisation (même sur).

    JE ne vois pas comment contourner ce probléme. Même si tu m'as expliqué qu'il fallait que je récupere l'id Employé et l'id Salaire. Cependant, je ne vois pas du tout.

    En tous cas, merci beaucoup.
    Cordialement

  13. #13
    Membre averti
    Profil pro
    Inscrit en
    Août 2006
    Messages
    243
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 243
    Points : 328
    Points
    328
    Par défaut
    Je n'ai pas utilisé Acces depuis quelques années, mais il y a des chances que cela vienne des propriété CursorLocation de tes recordsets.
    Pour récupérer un champ qui est modifié par le serveur (auto-incrément, trigger, etc...), il faut que les recordset soient ouverts avec CursorLocation=adUseServeur.

    A ce propos, il faut que tes champs IDEmployé/IDSalaire/etc... soient définis en auto-incrément. Sinon, à toi de gérer manuellement leur incrément.

    Un point annexe : comme pour chaque recordset, tu utilise les mêmes valeurs pour CType,LType & CLocation, c'est inutile de redéfinir leurs valeurs systématiquement. Soit tu ne le fait qu'une fois (et tous les recordsets sont traités de la même manière), soit tu utilise directement les valeurs d'enum voulues lors de l'ouverture (.CursorType =adOpenStatic, etc..).

    Maintenant, je me répète mais, pose ton clavier et documente toi (bases de données et ADO). Cela ira beaucoup mieux après.

  14. #14
    Membre du Club
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    119
    Détails du profil
    Informations personnelles :
    Localisation : France, Gironde (Aquitaine)

    Informations forums :
    Inscription : Juin 2008
    Messages : 119
    Points : 50
    Points
    50
    Par défaut
    J'ai changé la propriété des .cursorLocation et toujours la même erreur.

    Sinon mes champs IDEmployé/IDSalaire/etc... sont bien définis en auto-incrément.

    Et je vais lacher mon clavier, comme tu me le préconise. Le problème, c'est que je dois faire un rapport a mon maitre de stage a 13h. Dumoins, je dois le terminer.

    Enfin bref.
    En tous cas, merci pour ton aide. Qui ma était précieuse.

    Cordialement.

  15. #15
    Membre du Club
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    119
    Détails du profil
    Informations personnelles :
    Localisation : France, Gironde (Aquitaine)

    Informations forums :
    Inscription : Juin 2008
    Messages : 119
    Points : 50
    Points
    50
    Par défaut
    Donc après de longue heures de recherche sur mon problème. Je n'ai toujours rien trouver.

    Pouvez-vous m'aiguiller (ou me donner un petit indice) sur le fait que mon recordset ne prend pas en compte l'insertion d'un nouveau employé dans ma table Employe.

    Sa marche pour une personne. Mais si mon fichier txt contient plusieurs employés, mon script plante et me dit :

    Erreur d'éxecution (80040e21): Vous ne pouvez pas ajouter ou modifier un enregistrement car l'enregistrement associé est requis dans la table 'Employé'.
    Erreur sur la ligne suivante:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    If Mid(vLigne, 60, 2) = "20" Then
            brutMSA = Mid(vLigne, 88, 11)
            vDate = Mid(vLigne, 52, 8)
            With rstSalaire
                .AddNew
                .Fields("idEmploye").Value = IDEmploye
                .Fields("dateSalaire").Value = Mid(vLigne, 52, 8)
                .Fields("brutMSA").Value = Mid(vLigne, 88, 11)
                .Update '<--- VOICI LA LIGNE QUI POSE PROBLEME
                IDSalaire = .Fields("idSalaire").Value
            End With
        End If
    Si vous avez une idée sur mon problème, je suis preneur.

    Cordialement.

  16. #16
    Membre du Club
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    119
    Détails du profil
    Informations personnelles :
    Localisation : France, Gironde (Aquitaine)

    Informations forums :
    Inscription : Juin 2008
    Messages : 119
    Points : 50
    Points
    50
    Par défaut
    Je reviens vers vous pour vous dire que le code marche.

    J'ai du faire une erreur lors de la création de mon fichier test (c'était dans le but de diminuer le nombre d'enregistrement pour tester).

    Donc avec le "vrai" fichier, sa marche.

    Donc je remercie 250rgv. Merci beaucoup pour ton aide.

    Cordialement.
    JE met le post en résolu.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [Debutant] Requête SQL Multi-Tables
    Par Superbretzel dans le forum Requêtes et SQL.
    Réponses: 1
    Dernier message: 16/02/2008, 11h47
  2. Requete SQL : 2 tables + count
    Par vichenze dans le forum Langage SQL
    Réponses: 7
    Dernier message: 21/08/2007, 10h28
  3. requete DELETE multi-tables
    Par Diwann dans le forum SQL
    Réponses: 10
    Dernier message: 23/02/2007, 17h38
  4. Requete SQL sur table dbase et date du jour
    Par Jean-François PETIT dans le forum Bases de données
    Réponses: 5
    Dernier message: 29/03/2005, 09h31
  5. requete sql mutlis tables
    Par tommath dans le forum Langage SQL
    Réponses: 12
    Dernier message: 30/08/2004, 09h54

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo