[VBA-Access] Problème dans une boucle for

Salut !
J'ai un petit problème avec ma boucle for :)

Je sélectionne d'abord tout les ID avec cette requête :

strSQL = "SELECT lIDAsset FROM tblAsset" ''' On sélectionne les ID de la table
Set rstTest = dbTestForm.OpenRecordset(strSQL) ''' On mets le résultats dans un recordset
Ensuite, je le passe dans ma boucle
For Each lIDAsset In rstTest

Jusque là, rien de mauvais, si ?

Pourtant j'ai une erreur :

Run-Time error 3251 : Operation is not supported for this type of object

Que faire ?

Merci :)
Configuration: Windows XP
Internet Explorer 7.0

18 réponses

  • Votes
  • Date
  • Date décroissante
  1. salut, j sui pas sur,mais j pense qu'il vous demande de declarer vos variables avant de proceder a l'affectation,en tous cas vous avez un erreur de type qq part
    1. La variable est déclarée plus haut :

      Dim rstTest As DAO.Recordset

      N'est-ce pas bon ?
      1. Salut,
        Ne peux tu pas faire une boucle while à la place..?
        Tu fais :

        While rstTest.EOF <> True
        ..............
        ..............
        ..............
        rst.MoveNext
        Wend

        Ainsi tu parcours ton recordset, ligne après ligne.

        @+
        1. tu fais d progarammation en vb,non?
          si je me souvien bien,tu n'aurais pas besoin d'utiliser des variables ,.juste fais la connexion avec votre base ,par la suite deplacé le table a traiter dans votre form(feuille) sous forme des grilles ......... et a la fin tu utilise des fonction predifinis pour la navigation dans votre base,............................................donc tout est definit ,pas besoin d variable pour parcourir les recordset

          .............................. . ......................................
          bnechance
          1. Salut BassHero816, HelloMoto1.

            Dit moi BassHero, ta fonction parcourt-elle la tableau horizontalement ou verticalement ? Dans mon cas ce serait verticalement. Hors après la première occurence il ne trouve plus rien dans la boucle grace a ta méthode :/

            Quand a HelloMoto, je ne passe pas par une feuille excel, si c'est ca que tu veux dire ... ?

            en tout cas, merci :)
            1. Cette fonction parcourt le tableau verticalement, chaque ligne contient un enregistrement de chaque champ.
              Personnellement, c'est ce que j'utilise à chaque fois.

              Par contre, je suis incapable de te dire comment parcourir tous les enregistrements, champ par champ.

              @+
              1. La resultat de ma requête se présente sous cette forme :

                http://img528.imageshack.us/img528/7757/exempleag9.jpg

                :(
                1. Oui, et bien dans ce cas ce que je t'ai donné va parcourir tes IIdAsset de 1 jusqu'à 40. Tu n'as plus qu'à marquer l'opération que tu souhaites effectuer sur chaque IIdAsset dans la boucle While, juste avant le rsTest.MoveNext, qui te permet de passer à l'IIdAsset suivant.
                  1. C'est bien ce que j'ai fait, pourtant j'ai la runtime error 9 :/

                    (Et l'erreur se produit sur une requête d'insertion, ca n'a peut-être pas à voir avec la boucle en fait ... Mais je penses car j'avais eu la même erreur sur la boucle while que j'avais faite avant de passer au for )

                    Je te donnes le code, au cas où !

                    While rstTest.EOF <> True
                    ''' Pour chaque entrée existante
                        
                        strSQL2 = "SELECT lIDAsset, sAssetTag, sLoginID FROM tblAsset WHERE lIDAsset = " & rstTest(0) & ""
                        Set rstTest2 = dbTestForm.OpenRecordset(strSQL2) ''' On sélectionne les données qui nous intéressent
                        
                        If Not IsEmpty("rstTest2") Then ''' Si L'entrée n'est pas vide
                            
                            Tag = rstTest2(1) ''' Alors la variable tag prend la valeur se sAssetTag sous la forme Marque~Type~Modèle~Numéro de série.INI
                            Test = Split("" & Tag & "", "~") ''' ou encore Marque~Type~Numéro de série.INI, Ensuite on sépare ces valeurs
                            Limite = UBound(Test) ''' On compte le nombres de variable (3 ou 4)
                            If Limite = 3 Then ''' Si il y en a 4 (0,1,2 et 3)
                                
                                SN = Split("" & Test(3) & "", ".") ''' On enlève le .INI après le numéro de série
                                
                                DoCmd.SetWarnings False '''On enlève les alertes access pour pas avoir "voulez vous ajouter une ligne dans la table tblPC" a chaque enregistrement (et avec 700 enregistrement c'est bien chiant ^^)
                                strSQL4 = "Select sValue FROM tblSystem WHERE sItem = '_LoginIDRight' AND lIDAsset = " & rstTest(0) & ""
                                Set rstTest4 = dbTestForm.OpenRecordset(strSQL4)
                                strSQL5 = "Select sValue FROM tblSystem WHERE sItem = 'Full Name' AND lIDAsset = " & rstTest(0) & ""
                                Set rstTest5 = dbTestForm.OpenRecordset(strSQL5)
                                strSQL6 = "Select sValue FROM tblSystem WHERE sItem = '_ComputerName'AND lIDAsset = " & rstTest(0) & ""
                                Set rstTest6 = dbTestForm.OpenRecordset(strSQL6)
                                strSQL7 = "Select sValue FROM tblSystem WHERE sItem = 'IP Address' AND lIDAsset = " & rstTest(0) & ""
                                Set rstTest7 = dbTestForm.OpenRecordset(strSQL7)
                                strSQL8 = "Select sValue FROM tblSystem WHERE sItem = 'OS Name' AND lIDAsset = " & rstTest(0) & ""
                                Set rstTest8 = dbTestForm.OpenRecordset(strSQL8)
                                strSQL9 = "Select sValue FROM tblSystem WHERE sItem = 'OS Version' AND lIDAsset = " & rstTest(0) & ""
                                Set rstTest9 = dbTestForm.OpenRecordset(strSQL9)
                                strSQL10 = "Select sValue FROM tblSystem WHERE sItem = 'Service Pack' AND lIDAsset = " & rstTest(0) & ""
                                Set rstTest10 = dbTestForm.OpenRecordset(strSQL10)
                                strSQL11 = "Select sValue FROM tblSystem WHERE sItem = 'Total RAM' AND lIDAsset = " & rstTest(0) & ""
                                Set rstTest11 = dbTestForm.OpenRecordset(strSQL11)
                                
                                ANTIPOSTROPHE = Split("" & rstTest11(0) & "", "'")
                                DoCmd.RunSQL ("INSERT INTO tblPC(IDAsset, Shortname, Marque, Type, Modele, Serial_Number, Laptop_Desktop, Computer_Name, Full_Name, IP, Localisation, total_RAM, OS_Name, OS_Version, Service_Pack) VALUES('" & rstTest(0) & "', '" & rstTest2(2) & "', '" & Test(0) & "', '" & Test(1) & "', '" & Test(2) & "', '" & SN(0) & "', 'D', '" & rstTest6(0) & "', '" & rstTest5(0) & "', '" & rstTest7(0) & "', 'SRC', '" & ANTIPOSTROPHE(0) & ANTIPOSTROPHE(1) & "', '" & rstTest8(0) & "', '" & rstTest9(0) & "', '" & rstTest10(0) & "');") ''' Ensuite on insère toutes les données
                                DoCmd.SetWarnings True ''' Et on réactive les alertes Access
                                
                                Final = Test(0)
                                Final2 = Test(1)
                                Final3 = Test(2)
                                Final4 = Test(3)
                                
                                Debug.Print Final ''' On affiche ici les résultats, juste histoire d'être sur
                                Debug.Print Final2
                                Debug.Print Final3
                                Debug.Print Final4
                            
                            Else ''' Si il y en a 3 (0,1 et 2)
                                
                                SN = Split("" & Test(2) & "", ".") ''' On enlève encore le .INI (même principe hein)
                                
                                DoCmd.SetWarnings False
                                strSQL3 = "INSERT INTO tblPC(IDAsset, Shortname, Marque, Type, Serial_Number) Values('" & rstTest2(0) & "', '" & rstTest2(2) & "', '" & Test(0) & "', '" & Test(1) & "', '" & SN(0) & "')"
                                DoCmd.RunSQL strSQL3 '''On insère
                                
                                DoCmd.SetWarnings True
                                
                                Final = Test(0) '''On teste
                                Final2 = Test(1)
                                Final3 = Test(2)
                                
                                Debug.Print Final
                                Debug.Print Final2
                                Debug.Print Final3
                                
                            End If ''' Fin du If Limite = 3 pour vérifier le nombre de valeurs
                        End If ''' Fin du If Not IsEmpty("rstTest2") Pour vérifier si il  y avait qqc a faire
                    rstTest.MoveNext
                    Wend
                    1. Normalement cette méthode fonctionne. Regarde si tu n'as pas fait une erreur sur une aurte requête (d'insertion).
                      Ou affiche moi un bout de ton code pour que je voies.
                      1. C'est fait au dessus, si tu veux le reste (y'a pas grand chose a part 2 requêtes SQL et les déclarations).

                        Par contre, tu m'excusera pour les noms de variables qui sont, je sais, pas claire du tout !

                        Je suis en train de modifier ca je te redonne le code modifié après
                        1. Visiblement, il manque un ";" à la fin de ta requête d'insertion strSQL3, juste avant l'apostrophe. Je ne sais pas si c'est une erreur de copier-coller ou si c'est ce qui cause ton erreur. Dis moi...
                          1. Si tu as du courage :)
                            Voilà tout le code !
                            J'ai modifié les noms des variables, pour que ce soit plus clair :

                            Ah aussi, ne tient pas compte du Else, il n'est pas à jour :p
                            Sub Instertion_split()
                            
                            Dim rstIDAsset As Recordset ''' Va récupérer les ID de tblAsset
                            Dim rstDataAsset As Recordset ''' Va récupérer les données de tblAsset
                            Dim rstRight As Recordset '''
                            Dim rstName As Recordset '''         R     D
                            Dim rstComputerName As Recordset ''' E  D  O
                            Dim rstIP As Recordset   '''         C  E  N
                            Dim rstOSName As Recordset '''       U  S  N
                            Dim rstOSVers As Recordset '''       P     E
                            Dim rstSP As Recordset '''                 E
                            Dim rstRAM As Recordset '''                S
                            Dim dbTestForm As Database ''' nom de la db
                            Dim strSQL_ID As String ''' Va récupérer les ID de tblAsset
                            Dim strSQL_DataAsset As String ''' Va récupérer les données de tblAsset
                            Dim strSQL_Insert As String ''' Va inclure les données dans tblPC
                            Dim strSQL_Right As String ''' Va récupérer les droits dans tblSystem
                            Dim strSQL_Name As String ''' Va récupérer les noms dans tblSystem
                            Dim strSQL_ComputerName As String ''' Va récupérer les computername dans tblSystem
                            Dim strSQL_IP As String ''' Va récupérer les IP Adress dans tblSystem
                            Dim strSQL_OSName As String ''' Va récupérer les OS Name dans tblSystem
                            Dim strSQL_OSVers As String ''' Va récupérer les OS Version dans tblSystem
                            Dim strSQL_SP As String ''' Va récupérer les versions Service Pack dans tblSystem
                            Dim strSQL_RAM As String ''' Va récupérer les rams total du pc dans tblSystem
                            Dim SN As Variant ''' Récupère le numéro de série sans le .INI
                            Dim Tag As String ''' Récupère le sAssetTag non splitté
                            Dim Final As String ''' Réupère la Marque
                            Dim Final2 As String ''' Récupère le Type ou le Modèle
                            Dim Final3 As String ''' Récupère le Modèle ou le numéro de série
                            Dim Final4 As String ''' Récupère le numéro de série
                            Dim Limite As Integer ''' Sert à la condition pour savoir si il y a 3 ou 4 valeurs différentes après les split() !
                            
                            Set dbTestForm = CurrentDb ''' Sélection de la base de donnée courante
                            
                                strSQL = "SELECT lIDAsset FROM tblAsset" ''' On sélectionne les ID de la table
                                Set rstIDAsset = dbTestForm.OpenRecordset(strSQL) ''' On mets le résultats dans un recordset
                                
                                CurrentDb.Execute "DELETE * FROM tblPC;" ''' Ensuite, on supprime tout de la table actuelle
                            
                            
                            While rstIDAsset.EOF <> True
                            ''' Pour chaque entrée existante
                                
                                strSQL2 = "SELECT lIDAsset, sAssetTag, sLoginID FROM tblAsset WHERE lIDAsset = " & rstIDAsset(0) & ""
                                Set rstDataAsset = dbTestForm.OpenRecordset(strSQL2) ''' On sélectionne les données qui nous intéressent
                                
                                If Not IsEmpty("rstDataAsset") Then ''' Si L'entrée n'est pas vide
                                    
                                    Tag = rstDataAsset(1) ''' Alors la variable tag prend la valeur se sAssetTag sous la forme Marque~Type~Modèle~Numéro de série.INI
                                    Test = Split("" & Tag & "", "~") ''' ou encore Marque~Type~Numéro de série.INI, Ensuite on sépare ces valeurs
                                    Limite = UBound(Test) ''' On compte le nombres de variable (3 ou 4)
                                    If Limite = 3 Then ''' Si il y en a 4 (0,1,2 et 3)
                                        
                                        SN = Split("" & Test(3) & "", ".") ''' On enlève le .INI après le numéro de série
                                        
                                        DoCmd.SetWarnings False '''On enlève les alertes access pour pas avoir "voulez vous ajouter une ligne dans la table tblPC" a chaque enregistrement (et avec 700 enregistrement c'est bien chiant ^^)
                                        strSQL_Right = "Select sValue FROM tblSystem WHERE sItem = '_LoginIDRight' AND lIDAsset = " & rstIDAsset(0) & ""
                                        Set rstRight = dbTestForm.OpenRecordset(strSQL_Right)
                                        strSQL_Name = "Select sValue FROM tblSystem WHERE sItem = 'Full Name' AND lIDAsset = " & rstIDAsset(0) & ""
                                        Set rstName = dbTestForm.OpenRecordset(strSQL_Name)
                                        strSQL_ComputerName = "Select sValue FROM tblSystem WHERE sItem = '_ComputerName'AND lIDAsset = " & rstIDAsset(0) & ""
                                        Set rstComputerName = dbTestForm.OpenRecordset(strSQL_ComputerName)
                                        strSQL_IP = "Select sValue FROM tblSystem WHERE sItem = 'IP Address' AND lIDAsset = " & rstIDAsset(0) & ""
                                        Set rstIP = dbTestForm.OpenRecordset(strSQL_IP)
                                        strSQL_OSName = "Select sValue FROM tblSystem WHERE sItem = 'OS Name' AND lIDAsset = " & rstIDAsset(0) & ""
                                        Set rstOSName = dbTestForm.OpenRecordset(strSQL_OSName)
                                        strSQL_OSVers = "Select sValue FROM tblSystem WHERE sItem = 'OS Version' AND lIDAsset = " & rstIDAsset(0) & ""
                                        Set rstOSVers = dbTestForm.OpenRecordset(strSQL_OSVers)
                                        strSQL_SP = "Select sValue FROM tblSystem WHERE sItem = 'Service Pack' AND lIDAsset = " & rstIDAsset(0) & ""
                                        Set rstSP = dbTestForm.OpenRecordset(strSQL_SP)
                                        strSQL_RAM = "Select sValue FROM tblSystem WHERE sItem = 'Total RAM' AND lIDAsset = " & rstIDAsset(0) & ""
                                        Set rstRAM = dbTestForm.OpenRecordset(strSQL_RAM)
                                        
                                        ANTIPOSTROPHE = Split("" & rstRAM(0) & "", "'")
                            
                            /!\ ERREUR ICI /!\
                            
                                        DoCmd.RunSQL ("INSERT INTO tblPC(IDAsset, Shortname, Marque, Type, Modele, Serial_Number, Laptop_Desktop, Computer_Name, Full_Name, IP, Localisation, total_RAM, OS_Name, OS_Version, Service_Pack) VALUES('" & rstIDAsset(0) & "', '" & rstDataAsset(2) & "', '" & rstDataAsset(0) & "', '" & rstDataAsset(1) & "', '" & rstDataAsset(2) & "', '" & SN(0) & "', 'D', '" & rstComputerName(0) & "', '" & rstName(0) & "', '" & rstIP(0) & "', 'SRC', '" & ANTIPOSTROPHE(0) & ANTIPOSTROPHE(1) & "', '" & rstOSName(0) & "', '" & rstOSVers(0) & "', '" & rstSP(0) & "');") ''' Ensuite on insère toutes les données
                            
                            /!\
                                        DoCmd.SetWarnings True ''' Et on réactive les alertes Access
                                        
                                        Final = Test(0)
                                        Final2 = Test(1)
                                        Final3 = Test(2)
                                        Final4 = Test(3)
                                        
                                        Debug.Print Final ''' On affiche ici les résultats, juste histoire d'être sur
                                        Debug.Print Final2
                                        Debug.Print Final3
                                        Debug.Print Final4
                                    
                                    Else ''' Si il y en a 3 (0,1 et 2)
                                        
                                        SN = Split("" & Test(2) & "", ".") ''' On enlève encore le .INI (même principe hein)
                                        
                                        DoCmd.SetWarnings False
                                        strSQL3 = "INSERT INTO tblPC(IDAsset, Shortname, Marque, Type, Serial_Number) Values('" & rstIDAsset(0) & "', '" & rstDataAsset(2) & "', '" & Test(0) & "', '" & Test(1) & "', '" & SN(0) & "');"
                                        DoCmd.RunSQL strSQL3 '''On insère
                                        
                                        DoCmd.SetWarnings True
                                        
                                        Final = Test(0) '''On teste
                                        Final2 = Test(1)
                                        Final3 = Test(2)
                                        
                                        Debug.Print Final
                                        Debug.Print Final2
                                        Debug.Print Final3
                                        
                                    End If ''' Fin du If Limite = 3 pour vérifier le nombre de valeurs
                                End If ''' Fin du If Not IsEmpty("rstDataAsset") Pour vérifier si il  y avait qqc a faire
                            rstIDAsset.MoveNext
                            Wend
                            ''' Fin de la boucle for, on passe a la prochaine entrée
                            
                            End Sub
                            


                            J'ai indiqué la ligne d'erreur ...

                            J'ai rajouté le ; aussi !

                            Merci :)
                            1. Me revoilà, excuse moi :)

                              l'erreur : Runtime Error '9' : Subscript out of range
                              1. Ah j'ai trouvé ! si je retire la ligne juste au dessus,
                                ANTIPOSTROPHE = Split("" & rstRAM(0) & "", "'")

                                Ca marche ...

                                Maintenant je l'ai remise et ca marche toujours ...
                                Mais j'ai un autre problème (simple)

                                Lors d'un instertion, quelqu'un à un nom avec un apostrophe dedans :
                                (Ex : Machin d'truc)
                                Et ca fait foirer toute ma requête :(

                                N'aurais-tu pas une solution ?
                                1. J'ai déja eu ce problème, mais je ne me souviens plus comment je l'ai contourné.
                                  Essaie d'entourer ta variable d'autres cotes, ou de l'entourer avec des guillemets, ou des trucs de ce genre là.

                                  Sinon il existe la fonction replace. Tu fais :

                                  INSERT INTO ma_table VALUES ( ' & replace (nom_de_ma_variable, " ' ", " ") & ' .......) WHERE .... ;

                                  Je ne te garantis pas le résultat, mais il est toujours bon d'essayer.

                                  @+