Se connecter avec
S'enregistrer | Connectez-vous

Critères pour requête Access 2003

Dernière réponse : dans Programmation

Bonjour,

Je souhaite pouvoir afficher le dernier enregistrement ajouté grâce à une requête paramétrée multitables.

Lorsque dans le champ "critère" de ma requête, j'écris : [N° de BSDD ?]

Une boîte de dialogue s'ouvre, me proposant de renseigner le numéro de bordereau et la requête me renvoie le bon et l'unique résultat.

Peut-on envisager d'automatiser cette phase en indiquant à la requête de ne choisir et de n'afficher que le numéro et les champs du dernier BSDD enregistré.

Sur une requête mono table = aucun problème (en utilisant la fonction "dernier")

mais sur ma requête multi tables, elle me renvoie tous les numéros de la table.

En espérant avoir été suffisamment clair pour vous permettre de m'éclairer

Cordialement,

Autres pages sur : criteres requete access 2003

Lassé par la pub ? Créez un compte

zeb a dit :
Bonjour,

Tu as un problème de VB ou de SQL ?
Ou bien n'utilises-tu ni l'un ni l'autre et te contentes-tu de faire des formulaires avec Access ?


Bonjour Zeb,

Effectivement, je débute sur Access et j'utilise beaucoup l'assistant. cette requête a été conçue en mode création.

Cependant, j'appréhende petit à petit le VBA et le SQL.

S'il est possible grâce à du code VB ou SQL d'obtenir ce que je veux je suis preneur

Cordialement,
Expert Programmation

Pour les formulaires Access, je t'invite à poster (ou as demander à faire déplacer) ton topic dans la cat' Windows. Ce n'est que de l'utilisation d'un logiciel. On s'éloigne fortement de la programmation.

En revanche, les problèmes SQL ont leur place ici. Et on peut t'y aider.

Quel est le code de ta requête ?
Comment le critère "Dernier enregistré" est-il déterminable ? (Un champ "date d'enregistrement" existe-t-il ?)


(Attention, pour publier ton code, utilise la balise [code], conformément au règlement.)

Zeb,

Voici la séquence SQL de ma requête :

  1. SELECT T_sortie.NumBSDD, T_sortie.[Date de sortie], T_prod.Code_Prod, T_prod.NomProd, T_prod.NumRue, T_prod.Voie, T_prod.NomRue, T_prod.CPProd, T_prod.VilleProd, T_prod.TelProd, T_prod.FaxProd, T_prod.MelProd, T_prod.NomContact, T_prod.PrénomContact, T_regroup.Code_reg, T_regroup.NomReg, T_regroup.NumRue, T_regroup.Voie, T_regroup.NomRue, T_regroup.CPReg, T_regroup.VilleReg, T_regroup.TelReg, T_regroup.FaxReg, T_regroup.MelReg, T_regroup.NomContact, T_regroup.PrénomContact, T_coll.Code_coll, T_coll.NomColl, T_coll.NumRue, T_coll.Voie, T_coll.NomRue, T_coll.CPColl, T_coll.VilleColl, T_coll.TelColl, T_coll.FaxColl, T_coll.MelColl, T_coll.NomContact, T_coll.PrénomContact, T_coll.Récépissé, T_coll.Département, T_coll.LimiteVal, T_coll.ModeTransport, T_dechet.NomD, T_dechet.RubriqueD, Sum(T_ent.poids) AS SommeDepoids, T_dechet.Consistance1, T_dechet.Consistance2, T_dechet.Consistance3, T_sortie.QtéEst, T_sortie.QtéRéelle, T_CAP.CAP, T_dechet.CodeDR1, T_dechet.CodeDR2, T_dechet.CodeONU, T_dechet.ADR, T_sortie.TypeCondi, T_sortie.NbColis
  2. FROM T_regroup INNER JOIN ((T_condi INNER JOIN T_Ref_regroup ON T_condi.N°_Condi = T_Ref_regroup.N°_Condi) INNER JOIN (T_prod INNER JOIN (((T_coll INNER JOIN T_dechet ON T_coll.Code_coll = T_dechet.Code_coll) INNER JOIN T_ent ON T_dechet.Code_dechet = T_ent.Code_dechet) INNER JOIN (T_CAP INNER JOIN T_sortie ON T_CAP.Code_dechet = T_sortie.Code_dechet) ON T_dechet.Code_dechet = T_sortie.Code_dechet) ON T_prod.Code_Prod = T_dechet.Code_prod) ON (T_Ref_regroup.Code_Ref_regroup = T_sortie.Code_Ref_regroup) AND (T_Ref_regroup.Code_Ref_regroup = T_ent.Code_Ref_regroup)) ON T_regroup.Code_reg = T_dechet.Code_reg
  3. GROUP BY T_sortie.NumBSDD, T_sortie.[Date de sortie], T_prod.Code_Prod, T_prod.NomProd, T_prod.NumRue, T_prod.Voie, T_prod.NomRue, T_prod.CPProd, T_prod.VilleProd, T_prod.TelProd, T_prod.FaxProd, T_prod.MelProd, T_prod.NomContact, T_prod.PrénomContact, T_regroup.Code_reg, T_regroup.NomReg, T_regroup.NumRue, T_regroup.Voie, T_regroup.NomRue, T_regroup.CPReg, T_regroup.VilleReg, T_regroup.TelReg, T_regroup.FaxReg, T_regroup.MelReg, T_regroup.NomContact, T_regroup.PrénomContact, T_coll.Code_coll, T_coll.NomColl, T_coll.NumRue, T_coll.Voie, T_coll.NomRue, T_coll.CPColl, T_coll.VilleColl, T_coll.TelColl, T_coll.FaxColl, T_coll.MelColl, T_coll.NomContact, T_coll.PrénomContact, T_coll.Récépissé, T_coll.Département, T_coll.LimiteVal, T_coll.ModeTransport, T_dechet.NomD, T_dechet.RubriqueD, T_dechet.Consistance1, T_dechet.Consistance2, T_dechet.Consistance3, T_sortie.QtéEst, T_sortie.QtéRéelle, T_CAP.CAP, T_dechet.CodeDR1, T_dechet.CodeDR2, T_dechet.CodeONU, T_dechet.ADR, T_sortie.TypeCondi, T_sortie.NbColis
  4. ORDER BY T_sortie.NumBSDD DESC;

Il existe un numéro unique [NumBSDD] sur lequel j'aimerai que la requête me renvoie uniquement la ligne du dernier enregistrement ou le numéro le plus élévé (syntaxe du numéro BSDD = F-0110-XXX : 0110 pour janvier 2010)

Cordialement,
Expert Programmation

9 tables, 57 champs dont 56 clauses de regroupements. Non, mais ça va pas, hein ?! Un bon conseil : apprends le SQL et sers-t-en. Le problème, c'est qu'ensuite, tu ne voudras plus utiliser Access.

Il faut que tu trouves un champ sur lequel tu peux prendre le plus grand (date, numéro). Ton numéro BSDD ne peut pas convenir, parce que, par ordre alpha-numérique, Janvier 2011 (0111) est précédent à Février 2010 (0210). La clause ORDER BY n'indique donc pas l'ordre que tu cherches.

Si tu reviens sur la syntaxe de ton numéro BSDD, en inversant le mois et l'année, par exemple, tu pourrais ajouter une clause WHERE à la place de la clause ORDER BY :
  1. WHERE T_sortie.NumBSDD = max( T_sortie.NumBSDD )


Evidemment, le plus élégant est d'avoir un champ [Date d'enregistrement] et de reprendre la même syntaxe.

Si tu prévois de te lancer dans l'étude du SQL et la conception de bases de données, commence par prendre de bonnes habitudes. La colonne REC_DATE (ou toute autre combinaison avec les premières lettres des mots DATE, RECORD ou ENREGISTREMENT) est un grand classique. Tu as remarqué, je n'utilise pas de nom avec des caractères particuliers. Que des lettres, des chiffres et le soulignement. Surtout pas d'espace, ni de lettre accentuée. C'est une autre bonne habitude à prendre. Access le permet, mais c'est une hérésie. J'ai l'habitude d'utiliser des abréviations tirées de l'anglais, pour la concision de cette langue et l'absence d'accent. Si je le conseille, par contre, loin de moi l'idée de l'imposer.

Merci Zeb,

Même pour un néofite, tous ces champs et ces clauses c'est assez effrayant, je te l'accorde !!

Cette requête multitable doit me permettre de fusionner un publipostage avec des infos contenues sur plusieurs tables (est-ce une bonne méthode ??)

Il me fallait une appli rapide à concevoir car utilisable très bien bientôt.

Je compte l'améliorer en utilisant le SQL associé au PHP, est-ce une bonne idée selon toi, sachant que mon application sera dans premier temps utilisée que par moi et sur seul poste. On peut imaginer aprés rendre la base de donnée accessible à d'autres par l'internet.

As tu des conseils (livres, tuto à me conseiller pour apprendre pas à pas le langage SQL?)

Construit-on vraiment les tables de la même manière que sur access ?

Cordialement,

La clause WHERE me renvoie :

"Erreur de syntaxe (opérateur absent) dans l'expréssion 'WHERE T_sortie.NumBSDD = max( T_sortie.NumBSDD )'

???

J'inscris cette clause après toute la séquence dont je t'ai parlé précédemment, non ? et je termine par ";".

Pierre
Expert Programmation

Ce n'est pas au néophyte que cette requête doit faire peur. Celui-ci ne sait pas à quoi s'attendre, alors 50 ou 500 champs, qu'importe.

Non, c'est à l'initié. M'enfin ! As-tu vraiment besoin de tout ça d'un coup ? J'en doute.
Découpe tes besoins en problème simple. Fais des sous-requêtes. Parce que tu as n-1 clauses de regroupement sur 50, je me doute que tu t'es gouré quelque part.

--------------------------------------------------------------

Relis bien ton cours SQL, surtout à la page clauses WHERE et GROUP BY.
Il faut supprimer la clause ORDER BY parce qu'elle ne sert plus à rien, et mettre la clause WHERE avant la clause GROUP BY.

Euh, et si en réfléchissant un peu plus, tu utilisais plutôt au lieu de la clause WHERE, une clause HAVING après la clause GROUP BY...

Zeb,

Merci de l'intérêt que tu as porté à ma demande !!

Je vais repenser et refondre ma requête, malheureusement j'ai vraiment besoin de tous ces champs pour mon publipostage.

Je ne vois pas vraiment comment faire autrement ???

une piste ??

Cordialement,

Pierre

Merci Zeb,

J'ai finalement utilisé ce code :

  1. SELECT TOP 1 T_sortie.NumBSDD, T_sortie.[Date de sortie], T_prod.Code_Prod, T_prod.NomProd, T_prod.CPProd, T_prod.VilleProd, T_prod.TelProd, T_prod.FaxProd, T_prod.MelProd, T_regroup.Code_reg, T_regroup.NomReg, T_regroup.CPReg, T_regroup.VilleReg, T_regroup.TelReg, T_regroup.FaxReg, T_regroup.MelReg, T_coll.Code_coll, T_coll.NomColl, T_coll.CPColl, T_coll.VilleColl, T_coll.TelColl, T_coll.FaxColl, T_coll.MelColl, T_coll.Récépissé, T_coll.Département, T_coll.LimiteVal, T_coll.ModeTransport, T_dechet.NomD, T_dechet.RubriqueD, Sum(T_ent.poids) AS SommeDepoids, T_dechet.Consistance1, T_dechet.Consistance2, T_dechet.Consistance3, T_sortie.QtéEst, T_sortie.QtéRéelle, T_CAP.CAP, T_dechet.CodeDR1, T_dechet.CodeDR2, T_dechet.CodeONU, T_dechet.ADR, T_sortie.TypeCondi, T_sortie.NbColis
  2. FROM T_regroup INNER JOIN ((T_condi INNER JOIN T_Ref_regroup ON T_condi.N°_Condi = T_Ref_regroup.N°_Condi) INNER JOIN (T_prod INNER JOIN (((T_coll INNER JOIN T_dechet ON T_coll.Code_coll = T_dechet.Code_coll) INNER JOIN T_ent ON T_dechet.Code_dechet = T_ent.Code_dechet) INNER JOIN (T_CAP INNER JOIN T_sortie ON T_CAP.Code_dechet = T_sortie.Code_dechet) ON T_dechet.Code_dechet = T_sortie.Code_dechet) ON T_prod.Code_Prod = T_dechet.Code_prod) ON (T_Ref_regroup.Code_Ref_regroup = T_sortie.Code_Ref_regroup) AND (T_Ref_regroup.Code_Ref_regroup = T_ent.Code_Ref_regroup)) ON T_regroup.Code_reg = T_dechet.Code_reg
  3. GROUP BY T_sortie.NumBSDD, T_sortie.[Date de sortie], T_prod.Code_Prod, T_prod.NomProd, T_prod.CPProd, T_prod.VilleProd, T_prod.TelProd, T_prod.FaxProd, T_prod.MelProd, T_regroup.Code_reg, T_regroup.NomReg, T_regroup.CPReg, T_regroup.VilleReg, T_regroup.TelReg, T_regroup.FaxReg, T_regroup.MelReg, T_coll.Code_coll, T_coll.NomColl, T_coll.CPColl, T_coll.VilleColl, T_coll.TelColl, T_coll.FaxColl, T_coll.MelColl, T_coll.Récépissé, T_coll.Département, T_coll.LimiteVal, T_coll.ModeTransport, T_dechet.NomD, T_dechet.RubriqueD, T_dechet.Consistance1, T_dechet.Consistance2, T_dechet.Consistance3, T_sortie.QtéEst, T_sortie.QtéRéelle, T_CAP.CAP, T_dechet.CodeDR1, T_dechet.CodeDR2, T_dechet.CodeONU, T_dechet.ADR, T_sortie.TypeCondi, T_sortie.NbColis, T_prod.NumRue, T_prod.Voie, T_prod.NomRue, T_prod.NomContact, T_prod.PrénomContact, T_regroup.NumRue, T_regroup.Voie, T_regroup.NomRue, T_regroup.NomContact, T_regroup.PrénomContact, T_coll.NumRue, T_coll.Voie, T_coll.NomRue, T_coll.NomContact, T_coll.PrénomContact
  4. ORDER BY T_sortie.NumBSDD DESC;


La clause "SELECT TOP 1" associée à "ORDER BY T_sortie.NumBSDD DESC" fonctionne parfaitement.

Tu ne m'a pas répondu quant à PHP/MySQL, dans mon cas est-ce utile ?

Merci encore, je reviendrais vers toi si j'ai d'autres questions.

Cordialement,

Pierre
Expert Programmation

zeb a dit :
Ton numéro BSDD ne peut pas convenir, parce que, par ordre alpha-numérique, Janvier 2011 (0111) est précédent à Février 2010 (0210). La clause ORDER BY n'indique donc pas l'ordre que tu cherches.


En prenant le premier d'un tri erroné, tu restes dans l'erreur. Je me donne la peine de te proposer des solutions et de les justifier. Tu ne les appliques pas, c'est ton droit. Mais pourquoi t'enfonces-tu dans cette voix que je t'ai dit ne pas être la bonne ? Utilise une clause HAVING.

Bien bien mea culpa !!

Pour que ma numérotation recommence à -001 chaque année, sais-tu comment je pourrais m'y prendre ?

Ci-joint le code de mon Autonumber :
  1. Function AutoNumber( _
  2. ByVal strTable As String, _
  3. ByVal strField As String, _
  4. Optional ByVal strFormat As String = "", _
  5. Optional ByVal intDigits As Integer = 4, _
  6. Optional ByVal dtDate As Date = #1/1/100#)
  7.  
  8. ' Quelques variables...
  9. On Error GoTo AutoNumberErr
  10. Dim varMarkers As Variant, varMark As Variant
  11. Dim strCriteria As String
  12. Dim strNum As String, lngNum As Long, strPart As String
  13.  
  14. ' Quelques retraitements...
  15. If dtDate = #1/1/100# Then dtDate = Now()
  16. strField = "[" & strField & "]"
  17. strFormat = Replace(strFormat, "'", "''")
  18.  
  19. ' Marqueurs à remplacer
  20. varMarkers = Array("YYYY", "YY", "Q", "MM", "WW", "DD")
  21. For Each varMark In varMarkers
  22. ' Formater la date et l'injecter dans le template
  23. strPart = Format(dtDate, varMark, vbMonday, vbFirstFourDays)
  24. strFormat = Replace(strFormat, "[" & varMark & "]", _
  25. Format(strPart, String(Len(varMark), "0")))
  26. Next
  27.  
  28. ' On cherche la valeur maximale déjà employée dans la table
  29. strCriteria = strField & " LIKE '" & strFormat & "*'"
  30. strNum = Nz(DMax(strField, strTable, strCriteria), "")
  31.  
  32. ' On crée le nouveau numéro
  33. lngNum = IIf(strNum = "", 1, Val(Mid(strNum, Len(strFormat) + 1)) + 1)
  34. strFormat = strFormat & Format(lngNum, String(intDigits, "0"))
  35.  
  36. ' Valeur finale
  37. AutoNumber = strFormat
  38. Exit Function
  39.  
  40. AutoNumberErr:
  41. msgbox "Erreur : " & Err.Description, vbCritical
  42. AutoNumber = ""
  43. Exit Function
  44. End Function


Est-ce que :
  1. If Year(Date) > strnum / 100000 Then strnum = Year(Date) * 100000 + 1 Else strnum = strnum+ 1

saurait convenir

Cordialement
Expert Programmation

C'est bien compliqué tout ça !
Est-ce que ceci saurait (*) t'aider à y réfléchir :
  1. Dim num As Long
  2. num = Nz(DMax(champ, table, champ & " LIKE 'F-" & Year(dt) & "-%'"), 0)
  3. AutoNumber = "F-" & Year(dt) & "-" & Format(num, "000")



(*)
Spoiler
Qu'est-ce que ce belgicisme ? T'es Tourangeau ou Wallon ?

Bonjour Zeb,

En fait, la syntaxe associée au champ est la suivante :
  1. Private Sub Form_BeforeUpdate(Cancel As Integer)
  2. If IsNull(Me.[NumBSDD]) Then
  3. Me.[NumBSDD] = AutoNumber("T_sortie", "NumBSDD", "F-[YY][MM]-", 3)
  4. End If
  5. End Sub

La syntaxe de ligne est-elle toujours correcte ?

Je teste ça très vite !!

Mon problème avec le code, c'est de savoir bien le placer !!

Cordialement,

Zeb,

J'ai réussi à automatiser mon publipostage grâce au code qui suit. Cependant, je ne sais pas le paramétrer pour qu'il utilise le numéro de BSDD de l'enregistrement actif comme critère dans la requête sur laquelle le publipostage est basé.
En gros, je suis dans mon formulaire "sortie", sur l'enregistrement N° F-1001-002", j'ai un bouton de commande :
comment peut-il mettre à jour ma requête R_BSDD1 avec comme critère NumBSDD actif (F-1001-002) sans que celà soit visible à l'écran et lancer la fusion seulement sur cet enregistrement ?
waouh !!
le code :
  1. Sub Publipostage_Vers_Imprimante()
  2. Dim wdApp As Word.Application
  3. Dim strCheminDoc As String
  4. Dim strSQL As String
  5.  
  6. ' Chemin du document Word à ouvrir
  7. strCheminDoc = "J:\BSDD_annexes.doc"
  8.  
  9. ' Instruction SQL permettant d'extraire les clients
  10. strSQL = "SELECT * FROM [R_BSDD1]"
  11.  
  12. ' Démarrer Word
  13. Set wdApp = New Word.Application
  14. With wdApp
  15. ' Ouvrir le document de publipostage
  16. .Documents.Open strCheminDoc
  17.  
  18. ' Paramétrer le publipostage
  19. With .ActiveDocument.MailMerge
  20. .OpenDataSource Name:=CurrentProject.FullName, _
  21. SQLStatement:=strSQL, _
  22. ReadOnly:=True
  23.  
  24. ' Diriger le publipostage vers un nouveau document
  25. ' plutôt que vers l'imprimante
  26. .Destination = wdSendToPrinter
  27.  
  28. ' Lancer la fusion
  29. .Execute
  30. End With
  31.  
  32. ' Quitter Word
  33. .Quit SaveChanges:=wdDoNotSaveChanges
  34. End With
  35.  
  36. ' Libérer les objets
  37. Set wdApp = Nothing
  38. End Sub

Spoiler

T'es min coin, hein ??



Expert Programmation

/private: KSD45, regarde mieux mon profil. Euch chuis Picard, nin Tchimi. [:zeb:1]

Pour en revenir à ton problème, il faut ajouter une clause WHERE NumBSDD = à ta requête. J'avoue ne plus connaître suffisamment Access pour te dire quoi faire. Sinon de chercher du coté de CurrentRecord ou de récupérer NumBSDD dans un champ du formulaire.

En effet, j'ai déjà mis une clause HAVING basée sur mon formulaire :

  1. HAVING (((T_sortie.NumBSDD)=[forms]![F_question]![NumBSDD]) AND ((T_ent.[Select])=Yes))


Mon problème c'est pour associer la requête puis le publipostage dans une procédure du type:
quand je clique sur ce bouton, ouvrir le formulaire F_Question, prendre par défaut le NumBSDD de l'enregistrement actif ou entrer un autre numéro, mettre à jour la requête puis lancer la fusion word !!

Cordialement,

Pierre
Lassé par la pub ? Créez un compte