SQL et Access

Debora 78 -  
 Debora 78 -
Bonjour,

Je réalise une Migration à partir d'une Base de Données Access.
Pour cela, je crée une table Access ayant la mm structure que ma table Hyperfile (j'utilise WindeV) et j'y stocke les données. Le Problème est que mes données ne sont pas propres, je dois donc faire plusieurs mises à jour sur plusieurs critères.

Exemple :

les champs 1, 2, 3 etc. sont des champs des Tables existantes.
les champs A, B, C etc. sont des champs de la Table que j'ai créé moi même.

Je placer le contenu du Champ 1 dans Champ A si Champ 3 est Null si non le placer dans Champ C. Avec la Requête Ajout je n'ai pas pu le faire. Pour l'instant je fais une requête Ajout et je fais une deuxième requête Mise à Jour.... Vue la quantité des données à Modifier et la possibilité de me Tromper dans le lancement des requêtes je voudrai savoir si il y a un moyen de tout intégrer dans un programme....

PS : je suis débutante alors soyez sympa et ne vous moquez pas de moi.....
Configuration: Windows XP
Firefox 3.5.7

17 réponses

  1. Manugeo
     
    D'accord, alors on va y aller tout doux...

    Pour commencer, tu vas utiliser un objet RecordSet qui, comme son nom l'indique, est un jeu de données.
    Il y a deux méthodes pour utiliser cet objet, et je vais te montrer la méthode DAO.

    Crée un module, puis mets-y le code suivant :

    Public Function Debora()

    Dim Rs As DAO.Recordset 'déclare la variable recordset
    Dim It As Integer 'déclare une variable d'itération

    Set Rs = CurrentDb.OpenRecordset("Users") 'ouvre le recordset

    If Rs.RecordCount > 0 Then 'si le recordset contient des données
    Rs.MoveLast 'se place sur le dernier enregistrement du recordset
    Rs.MoveFirst 'se place sur le premier enregistrement du recordset
    'cette manipulation permet de valider le vrai RecordCount, car celui annoncé est parfois fantaisiste

    For It = 1 To Rs.RecordCount 'Pour chaque enregistrement du Recordset
    'Affiche une partie des données du recordset sous forme de message
    MsgBox Rs("title") & " " & Rs("firstname") & " " & Rs("lastname")
    Rs.MoveNext 'Passe à l'enregistrement suivant
    Next It

    End If
    'quand tu en as marre de voir défiler le truc, tu fais Ctrl+Pause, puis Fin.

    End Function

    A suivre...
    1
    1. Debora 78
       
      Merci beaucoup Manugeo !!!

      Maintenant je sais afficher des données !!!

      Comment les modifier ?? y a t il des doc pour que j'arrête de te déranger ?
      0
  2. Manugeo
     
    Suite...

    Maintenant que t'as vu comment marche un Recordset, on va en ouvrir un un peu plus sérieux, puisque basé sur tes deux tables :

    Remplace le code précédent par celui-ci :

    Public Function Debora()

    Dim Rs As DAO.Recordset
    Dim It As Integer
    Dim StrSQL As String

    StrSQL = "SELECT users.code, users.title, users.lastname, users.firstname, users.company, "
    StrSQL = sqtrsql & "users.firstphone, users.firstmail, users.login, users.hashed_password, "
    StrSQL = StrSQL & "users.created_at, users.updated_at, addresses.street, addresses.street_complement, "
    StrSQL = StrSQL & "addresses.zipcode, addresses.city, addresses.country_code "
    StrSQL = StrSQL & "FROM addresses RIGHT JOIN users ON addresses.id = users.main_address_id;"

    Set Rs = CurrentDb.OpenRecordset(StrSQL)

    If Rs.RecordCount > 0 Then
    Rs.MoveLast
    Rs.MoveFirst

    For It = 1 To Rs.RecordCount
    MsgBox Rs("title") & " " & Rs("firstname") & " " & Rs("lastname") & " " & Rs("city")
    Next It

    End If

    End Function

    Là, le Recordset n'est plus une "copie" de ta table Users, mais contient aussi les données de ta table 'adresses'. C'est ce recordset qui va servir de base à la création de tes données.

    Donc en résumé : dans le premier exemple, tu ouvres un recordset simple equivalent à une table, alors que dans ce deuxième exemple, tu utilises une instruction SQL pour ouvrir ton RecordSet.

    On progresse, non ?
    1
  3. Manugeo
     
    En fait, je pense qu'il y a une erreur de concaténation de l'instruction SQL :

    Chaque ligne doit commencer par StrSQL = StrSQL & "
    Si une ligne a été coupée en deux lors du Copier/Coller, supprime le saut de ligne pour qu'elle soit de nouveau complète.

    si tu n trouves rien, fais la manip' suivante :

    Dans ta page de code, fais Ctrl+G pour afficher la fenêtre de debugage.
    Juste avant la ligne qui plante, ecris
    debug.print StrSQL
    Relance ta procédure.
    L'instruction SQL concaténée va s'écrire dans la fenêtre de debugage. Fais en un Copier/Coller dans ce post.

    Je regarderai ce qui va pas !
    1
  4. blux Messages postés 2049 Date d'inscription   Statut Modérateur Dernière intervention   3 455
     
    C'est là que ça coince :

    StrSQL = sqtrsql & "users.firstphone, users.firstmail, users.login, users.hashed_password, " 

    D'ailleurs, comme la variable n'est pas reconnue, elle n'est pas mise en majuscule.

    Encore une histoire de q...
    1
  5. Vous n’avez pas trouvé la réponse que vous recherchez ?

    Posez votre question
  6. blux Messages postés 2049 Date d'inscription   Statut Modérateur Dernière intervention   3 455
     
    Salut,

    le mieux est de faire une procédure en VBA avec le parcours d'un recordset.

    Si tu le souhaites, donne tous les renseignements qui peuvent être utiles et on verra ce qu'on pourra faire.
    0
  7. Manugeo
     
    Bonjour,
    tes données sont à mettre à jour dans Access ?
    0
  8. Debora 78
     
    Merci pour vos réponses :

    1/ Mes données sont à mettre à jour dans Access.

    2/ Je ne maîtrise pas VBA.

    Alors voici une partie de mon problème :

    j'ai deux Tables Users et Adresses à Regrouper et à Mettre au Propre dans une Table Client avec les champs suivants :

    TABLE USERS :

    id code title lastname firstname company firstphone firstmail login hashed_password main_address_id created_at updated_at active

    TABLE ADRESSES :

    id street street_complement zipcode city country_code created_at updated_at

    La Table Finale est :

    IDClient NuméroInterneClient Société Civilité Nom Prénom Adresse AdresseSuite CodePostal Ville Pays Téléphone Mobile Fax EMail Login Mot de Passe

    La Migration est Simple :

    INSERT INTO client ( NuméroInterneClient, Civilité, Nom, Prénom, Société, Téléphone, EMail, Login, [Mot de Passe], SaisiLe, ModifiéLe, Adresse, AdresseSuite, CodePostal, Ville, Pays )
    SELECT users.code, users.title, users.lastname, users.firstname, users.company, users.firstphone, users.firstmail, users.login, users.hashed_password, users.created_at, users.updated_at, addresses.street, addresses.street_complement, addresses.zipcode, addresses.city, addresses.country_code
    FROM addresses RIGHT JOIN users ON addresses.id = users.main_address_id;

    Voilà les mises à jour que je dois faire

    Mettre Nom dans Société si : Prénom est Null et Civilité ne commence pas par M ou par m

    Mettre Null dans Nom si Société est non null, Prénom non Null et Civilité ne commence pas par M ou par m

    Pour le moment je le fais en trois requêtes....

    Vous l'avez compris, c'est la partie la plus facile du travail à faire.

    Merci beaucoup pour votre aide !!!!
    0
  9. Manugeo
     
    Bonjour,

    D'après la requête SQL que tu as donnée, tu ne fais pas de création ligne à ligne, mais du global pour l'ensemble des enregistrements. Il semble donc que tu fais du One Shot. Alors le problème de lancer 3 requêtes, si c'est fait une bonne fois pour toutes, c'est pas très grave.

    Par contre, si je me trompe, et que tu fais du ligne à ligne, c'est-à-dire que tu indiques à ta requête le users.code à traiter, on peut alors faire une routine VBA qui :

    - Liste les clients dont la ligne doit être crée (ouverture d'un RecordSet),
    - Pour chaque ligne du recordset, on crée la nouvelle ligne en testant :
    - si Prénom est Null ET Left(Civilité,1) <> "m", on met Nom dans Société
    - si Société est non Null ET Prénom non NUll ET Left(Civilité,1) <> "m", on met Null dans Nom

    Est-ce que j'ai bien compris ?
    0
    1. blux Messages postés 2049 Date d'inscription   Statut Modérateur Dernière intervention   3 455
       
      Je pense que les données sont déjà créées, puisqu'elle donne sa requête d'INSERT.

      J'imaginais qu'il fallait regrouper deux tables en une avec certains traitements au passage.

      Ici, la solution la plus simple est bien d'enchainer les requêtes, on ne va pas déranger VBA pour ça ;-)
      0
  10. Debora 78
     
    Merci encore pour Vos réponses,

    mais je voudrai tout de même si vous le voulez bien savoir comment déranger VBA histoire de m'initier un peu... Est ce possible de me guider un peu ?

    Merci encore
    0
  11. Manugeo
     
    D'accord pour te donner des tuyaux. Quel est ton niveau de connaissance en VBA ?
    0
  12. Manugeo
     
    Bon maintenant que ça c'est fait, y'a plus qu'à créer tes données, en appliquant les critères que tu as donné.

    Pour créer les données, on va utiliser un deuxième recordset (on peut aussi le faire via une commande SQL, mais c'est un peu plus complexe à mettre en oeuvre).
    En effet, un RecordSet étant un jeu d'enregistrement, on peut l'utiliser aussi pour ajouter, supprimer ou modifier des données.

    remplace maintenant le code par celui-ci :

    Public Function Debora()

    Dim Rs As DAO.Recordset
    Dim It As Integer
    Dim StrSQL As String
    Dim UserNom As String
    Dim UserCompany As String
    Dim RsClient As DAO.Recordset

    StrSQL = "SELECT users.code, users.title, users.lastname, users.firstname, users.company, "
    StrSQL = sqtrsql & "users.firstphone, users.firstmail, users.login, users.hashed_password, "
    StrSQL = StrSQL & "users.created_at, users.updated_at, addresses.street, addresses.street_complement, "
    StrSQL = StrSQL & "addresses.zipcode, addresses.city, addresses.country_code "
    StrSQL = StrSQL & "FROM addresses RIGHT JOIN users ON addresses.id = users.main_address_id;"

    Set Rs = CurrentDb.OpenRecordset(StrSQL)

    If Rs.RecordCount > 0 Then
    Rs.MoveLast
    Rs.MoveFirst

    For It = 1 To Rs.RecordCount
    'on teste la civilité (en la convertissant en majuscule, pour ne pas différencier m et M
    If left(Format(Rs("title"), ">"), 1) <> "M" Then
    If IsNull(Rs("firstname")) Then
    UserNom = ""
    UserCompany = Rs("Lastname")
    ElseIf Not IsNull(Rs("company")) Then
    UserNom = ""
    UserCompany = Rs("company")
    End If
    Else 'si la civilité commence par m ou M
    UserNom = Rs("LastName")
    UserCompany = Rs("company")
    End If

    'on ouvre un recordset sur la table client pour ajouter l'enregistrement
    Set RsClient = CurrentDb.OpenRecordset("Client")

    With RsClient
    .AddNew
    .Fields("NuméroInterneClient") = Rs("code")
    .Fields("Civilité") = Rs("title")
    .Fields("Nom") = UserNom
    .Fields("Prénom") = Rs("firstname")
    .Fields("société") = UserCompany
    .Fields("Téléphone") = Rs("firstphone")
    .Fields("EMail") = Rs("firstmail")
    .Fields("Login") = Rs("login")
    .Fields("Mot de Passe") = Rs("hashed_password")
    .Fields("SaisiLe") = Rs("created_at")
    .Fields("ModifiéLe") = Rs("updated_at")
    .Fields("Adresse") = Rs("street")
    .Fields("AdresseSuite") = Rs("street_complement")
    .Fields("CodePostal") = Rs("zipcode")
    .Fields("Ville") = Rs("city")
    .Fields("Pays") = Rs("country_code")
    .Update

    End With

    Rs.MoveNext
    Next It

    End If

    Rs.Close
    RsClient.Close

    End Function

    Maintenant, si tu lances cette fonction, tes données vont se créer...
    0
  13. Debora 78
     
    Il y a des Erreurs dans le message 10...

    je vais essayer de comprendre....
    0
  14. Manugeo
     
    sur quelle ligne ça plante ?
    0
    1. Debora 78
       
      Set Rs = CurrentDb.OpenRecordset(StrSQL)
      0
  15. Manugeo
     
    Bien vu Blux !
    C'est ça de taper du code sans pouvoir le tester...
    C'est sûr, le q nous perdra !

    @Debora : Corrige la deuxième ligne 'StrSQL = StrSQL &' et non 'StrSQL = sqtrsql &'
    Désolé pour cette bévue !
    0
  16. Debora 78
     
    Bonjour Bonjour,

    J'espère que vous avez passé un bon Weekend !

    J'ai encore des soucis avec le Code :
    For It = 1 To Rs.RecordCount

    'on teste la civilité (en la convertissant en majuscule, pour ne pas différencier m et M
    If Left(Format(Rs("title"), ">"), 1) <> "M" Then
    If IsNull(Rs("firstname")) Then
    usersNom = ""
    usersCompany = Rs("lastname")
    ElseIf Not IsNull(Rs("company")) Then
    usersNom = ""
    usersCompany = Rs("company")
    End If

    Else 'si la civilité commence par m ou M
    usersNom = Rs("Lastname")
    usersCompany = ""

    End If

    Il me dit mauvaise utilisation de Null... et il pointe sur cette ligne :

    usersCompany = Rs("lastname")

    Merci d'avance !
    0
    1. blux Messages postés 2049 Date d'inscription   Statut Modérateur Dernière intervention   3 455
       
      Ca veut dire que Rs("lastname") est vide.

      Il faudrait donc faire un test supplémentaire :

      if not isnull(Rs("lastname")) then
      usersCompany = Rs("lastname")
      else
      usersCompany = ""
      end if
      0