SQL et Access

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

  • Votes
  • Date
  • Date décroissante
  1. 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. 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 ?
  2. 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. 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. Modérateur
        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. Modérateur
          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.
          1. 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 !!!!
            1. 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 ?
              1. Modérateur
                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 ;-)
            2. 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
              1. D'accord pour te donner des tuyaux. Quel est ton niveau de connaissance en VBA ?
                1. 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...
                  1. Il y a des Erreurs dans le message 10...

                    je vais essayer de comprendre....
                    1. 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 !
                      1. 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 !
                        1. Modérateur
                          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