Access et VB

alkashee -  
 Ben -
Bonjour,

Voila mon souci, je voudrais a partir d'une variable issue d'un formulaire faire une requete sur une table afin d'avoir un résultat qui sera soit un enregistrement soit rien. Voici le code que j'ai réussi a faire avec de l'aide:

##############

Dim echange As String

C_sous_reseau.Value = O1.Value & "." & O2.Value & "." & (Int(O3.Value / 4) * 4) & "." & "0"
echange = C_sous_reseau.Value


Dim rs As DAO.Recordset
Set rs = CurrentDb.Openrecordset("SELECT * FROM [T_Sous_réseaux COMETE] WHERE [T_Sous_réseaux COMETE].SSres =' & echange & '")

Do Until Not rs.EOF
MsgBox rs!Num & " et " & rs!SSres <----- Ca bloque ici
rs.MoveNext
Loop

###############

Il me retourne un message d'erreur en me disant qu'il n'y a aucun enregistrement. Pourtant j'ai fait en sorte de mettre quelque chose qui me retourne une valeur ^^
Une idée ?

Merci d'avance ;)
A voir également:

21 réponses

Polux31 Messages postés 6917 Date d'inscription   Statut Membre Dernière intervention   1 204
 
voilà ce que j'ai fait.

Il faut créer un module et tu le nommes, par exemple : ModBdd et tu colles le codes ci dessous

'
' Module générique d'une connexion
' à une base de données Access
'
' Renseigner la constante privée myPathBd
' Renseigner la constante privée mybd (nom de la base)
'
'@ Author : Polux31 - 2007
'

Option Explicit

Dim cnnADO As New ADODB.Connection ' Pour la connection à la base de données
Dim cmdAdo As New ADODB.Command ' Pour la commande à la base de données
Dim RScnx As New ADODB.Recordset ' Pour recevoir le résultat de la commande
Dim NbEnr As Integer ' Pour recevoir le nombre d'enregistrement du recordset
Dim Connect As String ' pour recevoir le nom de la connection

Private Const myPathBd = "c:\MonRepertoireTest\" ' Chemin d'accès au répertoire la base de données
Private Const mybd = "bd\mabaseTest.mdb" ' nom du dossier et de la base

Public Function getConnect() As String
getConnect = Connect
End Function

Public Sub setNbEnr(ByVal str As Integer)
NbEnr = str
End Sub

Public Function getNbEnr() As Integer
getNbEnr = NbEnr
End Function

Public Function InitBdd() ' ouverture de la base donnée
Dim CnxStrg As String ' Variable qui reçois la chaine de connection

If cnnADO.State = adStateOpen Then
cnnADO.Close
End If

CnxStrg = "Provider=Microsoft.Jet.OLEDB.4.0;" _
& "Data Source=" & myPathBd & mybd

cnnADO.ConnectionString = CnxStrg
cnnADO.CursorLocation = adUseClient

On Error Resume Next
cnnADO.Open

If Err <> 0 Then
' MsgBox "Erreur de connection : [" & CnxStrg & "]"
Connect = "Erreur de connection : \\" & mybd
Exit Function
Else
Connect = "Connection à la base : \\" & mybd
End If

End Function

' Fonction générique pour le passage d'une requête à la base de données, reçois la requete et le recordset, retourne un booléen
Public Function OpenRecordset(ByVal requete As String, ByRef RS As ADODB.Recordset) As Boolean

Call setNbEnr(0) 'initialise le nb d'enregistrement
If RS.State = adStateOpen Then ' test le statut de la base
RS.Close
End If

On Error Resume Next
RS.Open requete, ModBdd.cnnADO, , , adCmdText 'Envoi du recordset
Call setNbEnr(RS.RecordCount) ' Nombre de record

If Err.Number <> 0 Then
OuvrirRecordset = False 'La transaction n'est pas réalisée, retourne False
Exit Function
End If

RS.MoveFirst ' Positionnement sur le premier enregistrement du RecordSet
OuvrirRecordset = True ' La transaction a été réalisée, retourne True

End Function

'Fonction qui déplace le curseur vers l'enregistrement précédent
Public Function RSLirePrecedent(ByRef RS As ADODB.Recordset) As Boolean

On Error Resume Next
RS.MovePrevious 'l'occurence précédente
If RS.BOF Then 'vérifie si l'on est pas déjà sur le premier enregistrement
RSLirePrecedent = False
Exit Function 'si on est sur le premier on sort de la fonction
End If

If Err <> 0 Then
RSLirePrecedent = False
Exit Function
End If

RSLirePrecedent = True

End Function

'Fonction qui déplace le curseur vers l'enregistrement suivant
Public Function RSLireSuivant(ByRef RS As ADODB.Recordset) As Boolean

On Error Resume Next
RS.MoveNext 'l'occurence suivante
If RS.EOF Then 'vérifie si l'on est pas déjà sur le dernier enregistrement
RSLireSuivant = False
Exit Function 'si oui on sort
End If

If Err <> 0 Then
RSLireSuivant = False
Exit Function
End If

RSLireSuivant = True

End Function

'Fonction qui déplace le curseur sur le premier enregistrement
Public Function RSLirePremier(ByRef RS As ADODB.Recordset) As Boolean

On Error Resume Next
RS.MoveFirst 'première occurence
If Err <> 0 Then
RSLirePremier = False
Exit Function
End If

RSLirePremier = True

End Function

'Fonction qui déplace le curseur sur le dernier enregistrement
Public Function RSLireDernier(ByRef RS As ADODB.Recordset) As Boolean

On Error Resume Next
RS.MoveLast 'dernière occurence
If Err <> 0 Then
RSLireDernier = False
Exit Function
End If

RSLireDernier = True

End Function

'====\\========

Ensuite pour pouvoir utiliser ces fonctions depuis un formulaire ou d'un module:

Public Sub OuvrirRequete()
Dim vrai As Boolean
Dim Query As String
Dim Rs As ADOBC.RecordSet
Dim echange As String
Dim strNum As Variant
Dim strSSres As Variant

With FrmTest
echange = .O1.Value & "." & .O2.Value & "." & (Int(.O3.Value / 4) * 4) & "." & "0"
End With

On Error Resume Next
Query = "SELECT Num, SSres FROM T_Sous_réseaux COMETE WHERE SSres =' " & echange & " ' "
Set Rs = New ADODB.RecordSet

vrai = ModBdd.OpenRecordset(Query, Rs)
If vrai = False then
MsgBox "Erreur: la requête [" & Query & "] n'a pas abouti",,"Message Application"
Exit Sub
Else
strNum = Rs.Fields(0).value
strSSres = Rs.Fields(1).value
MsgBox strNum & " et " & strSSres
End If

End Sub
==//====

J'ai testé ça rapidement avec VB6 et une base Access, ça marche.

Bon courage

:o)
2
alkashee
 
Ca a rien fait de neuf, il bloque toujours plus bas :/ Question bête; pourquoi je peux pas afficher le contenu de rs dans une msgBox ?
(je précise, je n'y connais absolument rien en VB)
0
alkashee
 
Do Until Not rs.EOF
strNum = rs("Num").Value <----------- Cha bloque ici
strSSres = rs("SSres").Value
MsgBox strNum & " et "
rs.MoveNext
Loop

Comme je n'y connais rien en VB, je n'ai aucun contrôle ou idée de comment faire, ca m'enerve :@ Ca me parait un poilcompliqué en plus :/
0
alkashee
 
Je suis peut être parti dans la mauvaise direction, je vais exprimer mon besoin:

J'ai un formulaire dans lequel les users mettent leur adresse IP, et duquel après un tour de passe-passe, me sors le sous réseau afférent dans une variable (echange). Apartir de cette donnée, je voudrais faire une requete sur une table contenant une liste de sous-réseaux afin de sortir celui qui correspond, et sortir ce résultat dans un bo formulaire ( ca je sais faire)

En gros ce qui me bloque actuellement c'est la requête a faire depuis la variable et de ressortir ca dans un formulaire.

J'espère avoir été plus clair^^
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
alkashee
 
Ma base est en local, sur le poste sur lequel je suis actuellement. Après pour les référence de drivers j'ai bien mis ADO et DAO (les deux dans le doute lol). Mon but final est d'en faire un outil distribuable dans mon service :)
0
alkashee
 
miciiiiiiiii :)
0
alkashee
 
Ca bloque dès le début en surlignant ca : Dim Rs As ADOBC.Recordset et en disant "type défini par l'utilisateur non défini" :'(:'(:'(

Et quelle est la différence entre les deux constante du début, je pige pas, sachant que la base est sur mon disque dans un dossier :/
0
simo
 
b soir
j vex voir commnt fait la rlation entre le vb 6 et un base d donnée
0
sourire45
 
Bonjour


Voila mon soucis :

G une base Access créer sous 97 et je dois l utiliser avec VBA 6.3

Je voudrais savoir comment faire la connection a la base de données car mon fichier plante :

Voila mon code :

Sub COdispatcher()

Dim colCOd As Integer 'N° de la colonne pour la feuille COdispatcher
Dim ligdmh As Integer 'N° de la colonne pour la feuille FamilleCO
Dim i As Integer
Dim a As String

colCOd = 3
While (Not (IsEmpty(Worksheets("COdispatcher").Cells(8, colCOd))))
'Entrée des heures + Msg si la famille existe pas
i = 8
While (Not (IsEmpty(Worksheets("COdispatcher").Cells(i, colCOd))))
Worksheets("COdispatcher").Cells(i, colCOd + 1).ClearContents
ligdmh = 7
While (Not (IsEmpty(Worksheets("familleRequete").Cells(ligdmh, 3))) And Worksheets("familleRequete").Cells(ligdmh, 3) <> Worksheets("COdispatcher").Cells(i, colCOd))
ligdmh = ligdmh + 1
Wend
If (Not (IsEmpty(Worksheets("familleRequete").Cells(ligdmh, 3)))) Then
Worksheets("COdispatcher").Cells(i, colCOd + 1) = Worksheets("familleRequete").Cells(ligdmh, 4)
Else
MsgBox ("ATTENTION La famille " & Worksheets("COdispatcher").Cells(i, colCOd) & " n'existe pas")
End If
i = i + 1
Wend

'Requete pour le CO

a = "select sum(" & Range("Parametre!E11") & ") from " & Range("Parametre!D7") & " where " & Range("Parametre!D11") & " like '" & Worksheets("COdispatcher").Cells(7, colCOd) & "';"

Sheets("COdispatcher").Select

With ActiveSheet.QueryTables.Add(Connection:= _
"ODBC;DSN=MS Access 97 Database;DBQ=" & Range("Parametre!D6") & ";DefaultDir="chemin";DriverId=281;FIL", _
Destination:=Worksheets("COdispatcher").Cells(7, colCOd + 2), Sql:=a) 'emplacement du resultat

.Sql = a
.FieldNames = False 'Nom des champs de la BD
.RefreshStyle = xldeleteEntireRows ' Pour l insertion des nouvelles données
.RowNumbers = False
.FillAdjacentFormulas = False
.RefreshOnFileOpen = False
.HasAutoFormat = False 'surement a laisser
.BackgroundQuery = True
.TablesOnlyFromHTML = True
.Refresh BackgroundQuery:=False
.SavePassword = True
.SaveData = True
End With

'Calcul de la somme
Worksheets("COdispatcher").Cells(7, colCOd + 1) = "=SUM(R[1]C:R[65000]C)"

'Calcul des Heures / Famille
i = 8
While (Not (IsEmpty(Worksheets("COdispatcher").Cells(i, colCOd))))
Worksheets("Codispatcher").Cells(i, colCOd + 2) = "=R[-" & i - 8 + 1 & "]C* RC[-1]/R[-" & i - 8 + 1 & "]C[-1]"
i = i + 1
Wend
colCOd = colCOd + 3
Wend
End Sub




Est ce que l appel de la connection a la base de données se fait de cette façon???
j en peu plus ca fait une semaine que je cherche!!!!!

Merci pour tout
0
Ben
 
Bonjour je me permet de m'immisser :D

Je suis actuellement en train de travailler sur la sécurisation de bases de données Access, plus pécisement sur une gestion des utilisateurs, et ce via Visual Basic.

J'ai créé 5 tables (forms "name & ID" + users "name & ID" + profiles "name & ID" + tbl_User_Profile_Map "qui affili un user à un profile (1 ou 2) et enfin tbl_Frm_Profile_Map "qui affili un form à des droits specifiques").

J'aimerais savoir ce que vous pensez du code (pas terminé) ainsi qu'une solution pour que je puisse créer un module qui contient la fonction principale afin de pouvoir simplement la requetter via chaque formulaires des bases de donées et non la réécrire à chaque fois. Donc comment créer mon module et comment l'appeler ???

Je ne connais pas grand-chose en programmation pour être honnete, donc n'hesitez pas à m'envoyé vos idées de code etc. Votre aide m'aiderait énormément UN GRAND MERCI A TOUS.

Ben
0
Ben
 
Envoyé moi un mail pour me répondre et je vous enverrez le code puis nous discuterons.

Merci beaucoup !
0
blux Messages postés 27120 Date d'inscription   Statut Modérateur Dernière intervention   3 359 > Ben
 
Déjà, on ne connait pas ton adresse, donc pour envoyer un mail, pas facile.

Ensuite, si tu mets ton mail au su et au vu de tous, tu t'exposes à être spammé

Pour finir, on n'aime pas les dépannages personnels ici, un problème doit être exposé et résolu au yeux de toutes et tous, pour qu'il serve à la communauté.
0
Ben
 
Je pense que tous ceux qui écrivent ici, écrivent afin de résoudre des problèmes qu'ils rencontrent, donc personnels... Je ne vois donc pas pourquoi le mien serais un "dépannage perso" :D

Enfin, désolé pour tout ça alors et oui tu as raison un peu risqué de mettre mon adresse ici...

Voiçi mon code: Mon problème est que je voudrais créer un module et faire appel à ce dernier via les codes des tables composant la base de données mais je n'y arrive pas, je ne sais pas trop comment coder ça… Et c'est vrai que si ça peut être utile à d'autre naviguant par là, tant mieux !

Option Compare Database

Private Sub Form_Load()
oProfileID = DLookup("[PROFILE_ID]", "tbl_Users", "[USER_NAME]= '" & Environ("USERNAME") & "'")
oFormID = DLookup("[Form_ID]", "tbl_Forms", "[Form_Name]= '" & Me.Name & "'")

If Not IsNull(oFormID) And Not IsNull(oProfileID) Then

'Create a query to retrieve roles

Dim sQuery As String
Dim oRs As DAO.Recordset
sQuery = "Select * From tbl_Frm_Profile_Map " & _
" Where Form_ID = " & oFormID & _
" And PROFILE_ID = " & oProfileID

'Create and Iterate over a recordset
Set oRs = CurrentDb.OpenRecordset(sQuery)

If Not oRs.EOF Then
While Not oRs.EOF

'Apply rights on the current form
Me.Form.AllowAdditions = oRs("Allow_Insert_YN")
Me.Form.AllowDeletions = oRs("Allow_Delete_YN")
Me.Form.AllowEdits = oRs("Allow_Update_YN")

oRs.MoveNext
Wend

'Custom rights

'Hidden if profile ID = 2
If oProfileID = 1 Then
Me.btnTest.Visible = False
End If

Else
'The current user is not granted on this form !
End If
oRs.Close

Else
'the user or the form is not stored on the database
End If

End Sub
0
blux Messages postés 27120 Date d'inscription   Statut Modérateur Dernière intervention   3 359
 
Mon problème est que je voudrais créer un module
Que devra faire ce module ?

et faire appel à ce dernier via les codes des tables composant la base de données
Une table ne peut pas appeler un module, donc il devra être appelé lors d'une action se produisant sur un objet de la base : formulaire, bouton, liste déroulante...
0
Ben
 
Bonjour Blux,

Merci de me répondre aussi vite..

Alors mon module (ou ma fonction), sera tirer du code que j'ai posté, cette fonction devra comme tu peux le voir, récuperer l'ID de l'utilisateur avec la fonction Environ("USERNAME")(dans ma table user 1, 2, 3 ou4 etc...), tester si l'utilisateur est connu dans la table avec un recordset, puis récupérer le profile (dans ma table profile 1=admin, 2=user) puis selon ce profile affilié des droit à la table en cours.
J'ai aussi créé 2 table "mapping" afin d'affilier un ID de user à un ID de profile et une autre pour affilié l'ID de profile récuperé à chaque ID des forms de la base et attribué des droits différents pour chaque forms (J'aimerais dans l'ideal pouvoir cacher des boutons (delete, insert...) selon le form et le user et son profile mais je ne sais pas trop comment faire et par rapport à mon code ce qu'il me reste... :( )

J'aimerais donc éviter de recopier mon code final mais créer un module et faire appel à ce module quand j'en ai besoin.

Je sais pas si je suis bien clair Blux...
0
blux Messages postés 27120 Date d'inscription   Statut Modérateur Dernière intervention   3 359
 
Vu que c'est quelque chose que tu vas appeler une seule fois au lancement de l'application, je ne vois pas pourquoi on devrait en faire un module, tout le code peut (et doit) se mettre sur l'ouverture du formulaire principal.
0
Ben
 
Je ne comprends pas, car comme lorsqu'on load un form, ne pourrait-on pas mettre une commande en tout début de code qui ferait tout ce que decrit mon code ?

Si je créais un module "TestPermissions" qui fait tout ce que j'ai décris précedement, est ce que je pourrais tout simplement pas l'appeler en debut de chaque form avec une commande du type Public Function TestPermissions(ByVal FormName As String) ?
0
blux Messages postés 27120 Date d'inscription   Statut Modérateur Dernière intervention   3 359 > Ben
 
Si, tu peux, mais ça ne va pas être facile car comme tu viens de le faire remarquer, tu veux bosser en formulaires multiples.

Le problème d'une procédure appelée à chaque load de formulaire va se poser en terme d'objets ouverts : pour pouvoir modifier les propriétés d'un objet (formulaire, bouton, liste...), il faut qu'il soit ouvert, or ce que tu souhaites, c'est une procédure unique appelée à chaque chargement, mais dans celle-ci, tu vas référencer des actions à faire qui ne seront pas forcément sur le form que tu es en train de charger, d'où erreur.

Le mieux, dans ce cas, serait de travailler avec un formulaire unique, mais avec des onglets. On aurait donc une procédure unique appelée au load du form qui masquerait/démasquerait les onglets,les boutons... et modifierait les actions possibles dans les onglets.
0
Ben
 
En fait, je vois tout à fait ce que tu veux dire, mais grace au code que tu as vu, si on place la commande y faisant appel, à l'ouverture de chaque form, selon le profile_ID reconnu, des droits devront être accordés sur le form actuel (avec "acform") quel que soit le nombre de forms non ??????? Car chaque form dans ma table de form, aura un ID et dans mon autre table selon l'ID récuperer au chargement autorise ou non des fonction sur ce form ???? Vois-tu ? DIS MOI QUE C'EST POSSIBLE :D !!!
0
blux Messages postés 27120 Date d'inscription   Statut Modérateur Dernière intervention   3 359
 
Oui, c'est possible, mais te faudra décrire tous les formulaires et penser aux autres contrôles (boutons, listes...) si tu veux y faire référence...
0
Ben > blux Messages postés 27120 Date d'inscription   Statut Modérateur Dernière intervention  
 
Oui, c'est exactement ce que je voulais faire, je décris ça dans ma table de mapping c'est ça ?
En fait, cette table contient form_name, form_ID puis ensuite 3 ccritère "allow" à cocher pour les boutons delete insert et update... Donc ici pas de souçi..

Mais est ce que tu pourrais me dire ce que tu penses de mon code et que faudrait-il de plus afin d'arriver à ma fonction finale ? Comment coder ma procédure ?
0
blux Messages postés 27120 Date d'inscription   Statut Modérateur Dernière intervention   3 359 > Ben
 
Tu peux faire un truc comme ça, mais c'est lourdingue et mal sécurisé, pourquoi créer une table de correspondance objet/profil ?

Tout le monde peut voir ce qu'il y a dans les tables, lorsque tu mets ça en code, tu peux masquer le VBA avec un fichier .mde.

Mais est ce que tu pourrais me dire ce que tu penses de mon code et que faudrait-il de plus afin d'arriver à ma fonction finale ?
Ton code à l'air de se tenir, mais je n'ai pas été voir dans le détail...

Comment coder ma procédure ?
Tu crées un module, tu y recopies ton code en le transformant en fonction et tu l'appelles au load du form...
0
Ben > blux Messages postés 27120 Date d'inscription   Statut Modérateur Dernière intervention  
 
Oui Blux ! C'est exactement ce que je voulais faire ! Après le code final, cacher le code en passant d'un fichier .mdb en .mde ;-)

Pourrais-tu si tu le veux bien jetter un oeil sur mon code, me dire ce qui ne va pas ou quoi ajouter ?...

Et pour ma procédure, tu as tout à fait compris ce que je voulais faire, mais je ne sais ni comment le transformer en fonction ni comment l'appeler au load des forms, là est mon souçis :-( ????? Aurais du un petit bout de code à me montrer ?

Quels argument paramétrés dans le module (Function TestPermission(??? As ???, ??? As ???) As ???)...

Merci Blux
0
blux Messages postés 27120 Date d'inscription   Statut Modérateur Dernière intervention   3 359 > Ben
 
Pourrais-tu si tu le veux bien jetter un oeil sur mon code, me dire ce qui ne va pas ou quoi ajouter ?...
A partir du moment où ça me semble correct, je ne vais pas passer du temps à inspecter chaque ligne, le 'ce qui ne va pas' se verra à l'exécution...

Pour le transformer en fonction, il faut simplement le recopier dans un module en l'encadrant avec sub function(...) et end function.

Les paramètres passés à la fonction ne devraient être que le nom du user et le formulaire sur lequel on doit agir.
0
Polux31 Messages postés 6917 Date d'inscription   Statut Membre Dernière intervention   1 204
 
bonjour,

D'un premier coup d'oeil, il me semble que la syntaxe de Openrecordset n'est pas correcte.

Set rs = CurrentDb.Openrecordset("SELECT * FROM [T_Sous_réseaux COMETE] WHERE [T_Sous_réseaux COMETE].SSres =' " & echange & " ' ")

teste ça.

;o)
-1
Polux31 Messages postés 6917 Date d'inscription   Statut Membre Dernière intervention   1 204
 
je ne sais pas, je n'ai jamais fait comme ça ...

Essais de mettre le résultat du recordset dans des variables :

Dim strNum As Variant // je prends un type variant ne sachant pas le type
Dim strSSres As Variant

blablabla ...

Do Until Not rs.EOF
strNum = rs("Num").value
strSSres = rs("SSres").value
MsgBox strNum & " et " strSSres
rs.MoveNext
Loop
-1
Polux31 Messages postés 6917 Date d'inscription   Statut Membre Dernière intervention   1 204
 
tu codes en VBA sur Access ou avec VB6 ?
-1
alkashee
 
Euh je pense VB 6.3, c'est ce que le "?" me dit
0
Polux31 Messages postés 6917 Date d'inscription   Statut Membre Dernière intervention   1 204
 
La première constante définie le répertoire, la deuxième le nom de ma base. En principe je ne fais pas comme ça, j'ai fait ça un peu à l'arrache, je passe le chemin et le nom en paramètre à la fonction. Dans mon exemple ma base se trouve : " C:\MonRepertoireTest\bd\mabaseTest.mdb.

Pour le message d'erreur, il y a une coquille : c'est Dim Rs As ADODB.RecordSet
dsl
-1
Polux31 Messages postés 6917 Date d'inscription   Statut Membre Dernière intervention   1 204
 
as tu testé la connexion à ta base ? as-tu pensé à ajouter la bonne référence de driver ?
-2