Code VBA pour report de données d'une année vers une autre [Résolu]

Signaler
-
Messages postés
1
Date d'inscription
jeudi 21 janvier 2021
Statut
Membre
Dernière intervention
21 janvier 2021
-
Bonjour à tous,

J'ai un petit soucis avec ma base de donnée Access (Access 2003), et je vais avoir besoin d'aide...

Tous les ans je dois reporter des interventions préventive d'une année sur une autre, selon la périodicité.

J'ai une table qui s'appelle "planning préventif" avec les champs suivants

N° BTP
Semaine interv (avec cadencement de plusieurs semaine pour certains BTP)
Année interv
soldé interv
date de fin du BTP

J'ai une requête "Report preventif" (avec les mêmes champs que la table "planning préventif") afin de pouvoir reporter tous les BTP sur les années suivantes selon leurs périodicités.

Le code VBA ci-dessous ne fonctionne pas très bien, car il ne reporte pas tous cadencements... certains passe dans les mailles du filet et je ne sais pas pourquoi !

Au lieu de reporter 2314 cadencement au total, il n'en reporte que 1706, ce qui fait une différence de 608.


Option Compare Database
Option Explicit

Private Sub CmdReportBTP_Click()
Dim db As Database
Dim rsScan As DAO.Recordset
Dim rsPlan As DAO.Recordset
Dim machine As String
Dim annee As Integer
Dim semaines() As Integer
Dim numeros() As Integer
Dim i As Integer
Dim anneeReport As Integer

anneeReport = InputBox("Saisir l'année de report :")

Set db = CurrentDb
Set rsScan = db.OpenRecordset("report_preventif", dbOpenSnapshot)
Set rsPlan = db.OpenRecordset("Planning preventif", dbOpenDynaset)
i = 1
If rsScan.BOF = True And rsScan.EOF = True Then
MsgBox "Aucun enregistrement", vbCritical
Exit Sub
End If

machine = rsScan.Fields("code machine").Value
annee = rsScan.Fields("année interv").Value

Do While rsScan.EOF = False

If rsScan.Fields("code machine").Value = machine And rsScan.Fields("année interv").Value = annee Then
If annee <= anneeReport Then
rsPlan.AddNew
rsPlan.Fields("N° BTP").Value = rsScan.Fields("N° BTP").Value
rsPlan.Fields("Semaine interv").Value = rsScan.Fields("Semaine interv").Value
rsPlan.Fields("année interv").Value = annee + rsScan.Fields("périodicité").Value
rsPlan.Fields("soldée interv").Value = False
rsPlan.Update
End If
annee = rsScan.Fields("année interv").Value
End If

rsScan.MoveNext
'Ajouter le test si on est pas en EOF
If Not rsScan.EOF Then
If rsScan.Fields("code machine").Value <> machine Then annee = rsScan.Fields("année interv").Value
machine = rsScan.Fields("code machine").Value

End If
Loop
rsScan.Close
rsPlan.Close
Set rsScan = Nothing
Set rsPlan = Nothing

MsgBox "Report des BTP effectué avec succès"

End Sub


Voila! Est-ce que quelqu'un pourrais éventuellement m'aider à résoudre ce petit problème, car moi avec mon petit niveaux je n'y arriverai pas...

Merci d'avance à tous et bonne année !

11 réponses

Messages postés
15806
Date d'inscription
dimanche 25 novembre 2007
Statut
Membre
Dernière intervention
16 juin 2021
1 502
Bonjour,

Mettre un point d'arret sue cette ligne:

If rsScan.Fields("code machine").Value = machine And rsScan.Fields("année interv").Value = annee Then

Verifiez le contenu des variables precedent cette ligne.
Pour verifier, passez le curseur souris sur les variables
Si ok, appuyez sur la touche F8 pour faire derouler le code ligne par ligne en verifiant a chaque fois le contenu de vos variables
Bonjour f894009,

Merci pour ton commentaire et désolé, pour ma réponse tardive... autres soucis à régler...

Aussi, j'ai oublié de préciser que j'ai une table "preventif" avec les champs suivants :

Code machine
Année interv
Semaine interv
N° BTP
périodicité

J'ai déjà réalisé plusieurs fois des arrêts sur cette lignes, et les variables "machine" et "annee" recopie bien les bonnes valeurs.

Mais certaines lignes sont ignorées ! et je n'arrive pas à trouver la cause !

Est-ce un couac dans le code ou est-ce la requête "Report preventif" ?

Merci pour ton aide :)
Messages postés
16044
Date d'inscription
lundi 9 juin 2008
Statut
Contributeur
Dernière intervention
16 juin 2021
867
bonjour, nous as-tu dit combien de lignes étaient affichées quand tu ouvrais la requête "Report preventif" ?
Bonjour yg_be,

12627 lignes
Messages postés
16044
Date d'inscription
lundi 9 juin 2008
Statut
Contributeur
Dernière intervention
16 juin 2021
867
voilà ce que je retiens de ton code:
anneeReport = InputBox("Saisir l'année de report :")
Set rsScan = db.OpenRecordset("report_preventif", dbOpenSnapshot)
Set rsPlan = db.OpenRecordset("Planning preventif", dbOpenDynaset)
machine = rsScan.Fields("code machine").Value
annee = rsScan.Fields("année interv").Value
Do While rsScan.EOF = False
	If rsScan.Fields("code machine").Value = machine And rsScan.Fields("année interv").Value = annee Then
		If annee <= anneeReport Then
			rsPlan.AddNew
		End If
		annee = rsScan.Fields("année interv").Value
	End If
	rsScan.MoveNext
	If Not rsScan.EOF Then
		If rsScan.Fields("code machine").Value <> machine Then annee = rsScan.Fields("année interv").Value
		machine = rsScan.Fields("code machine").Value
	End If
Loop


je crois deviner que la requete report_preventif classe les données par machine puis par année.
si je comprends ton code, il ne traite pas, pour chaque machine, le premier enregistrement de chaque année, sauf pour la première année.
ton code me semble particulièrement maladroit.
entr'autres, pourquoi tester "rsScan.Fields("code machine").Value = machine", je pense qu'il est toujours vrai.
Messages postés
16044
Date d'inscription
lundi 9 juin 2008
Statut
Contributeur
Dernière intervention
16 juin 2021
867
peux-tu utiliser les balises de code quand tu partages to code:https://codes-sources.commentcamarche.net/faq/11288-les-balises-de-code
Option Compare Database
Option Explicit

Private Sub CmdReportBTP_Click()
Dim db As Database
Dim rsScan As DAO.Recordset
Dim rsPlan As DAO.Recordset
Dim machine As String
Dim annee As Integer
Dim semaines() As Integer
Dim numeros() As Integer
Dim i As Integer
Dim anneeReport As Integer

anneeReport = InputBox("Saisir l'année de report :")

Set db = CurrentDb
Set rsScan = db.OpenRecordset("report_preventif", dbOpenSnapshot)
Set rsPlan = db.OpenRecordset("Planning preventif", dbOpenDynaset)
i = 1
If rsScan.BOF = True And rsScan.EOF = True Then
    MsgBox "Aucun enregistrement", vbCritical
    Exit Sub
End If

machine = rsScan.Fields("code machine").Value
annee = rsScan.Fields("année interv").Value

Do While rsScan.EOF = False
    
    If rsScan.Fields("code machine").Value = machine And rsScan.Fields("année interv").Value = annee Then
        If annee <= anneeReport Then
            rsPlan.AddNew
            rsPlan.Fields("N° BTP").Value = rsScan.Fields("N° BTP").Value
            rsPlan.Fields("Semaine interv").Value = rsScan.Fields("Semaine interv").Value
            rsPlan.Fields("année interv").Value = annee + rsScan.Fields("périodicité").Value
            rsPlan.Fields("soldée interv").Value = False
            rsPlan.Update
        End If
        annee = rsScan.Fields("année interv").Value
    End If
    
    rsScan.MoveNext
    'Ajouter le test si on est pas en EOF
    If Not rsScan.EOF Then
        If rsScan.Fields("code machine").Value <> machine Then annee = rsScan.Fields("année interv").Value
        machine = rsScan.Fields("code machine").Value
        
    End If
Loop
rsScan.Close
rsPlan.Close
Set rsScan = Nothing
Set rsPlan = Nothing

MsgBox "Report des BTP effectué avec succès"

End Sub
Bonjour à tous,

yg_be à raison, le code se perd...

J'aimerais mieux expliquer mon besoin...

Ci-dessous le contenu de chaque table et de la requête report_preventif :

Champs de la table "préventif"
Date Création, Date en cours, Semaine Calculée, Travaux à effectuer, Code machine, Temps théorique, Activé, unitée, Sous organe, Libellé, N° BTP, périodicité, Type d'intervention, Organisation


Champs de la table "Planning preventif"
N° BTP, Semaine interv, Année interv, soldée interv, date de fin du BTP


Champs de la requête "report_preventif"
N° BTP, Semaine interv, Année interv (table planning preventif)
Code machine, périodicité, Activé (table préventif)


Requête "report_preventif"
SELECT [Planning preventif].[N° BTP], préventif.[Code machine], [Planning preventif].[Semaine interv], [Planning preventif].[Année interv], préventif.périodicité
FROM préventif INNER JOIN [Planning preventif] ON préventif.[N° BTP] = [Planning preventif].[N° BTP]
WHERE (((préventif.Activé)=Yes))
ORDER BY [Planning preventif].[N° BTP], [Planning preventif].[Semaine interv] DESC , [Planning preventif].[Année interv] DESC;


Je besoin d'aller chercher les infos de la table "Planning preventif" et "préventif" pour la périodicité (1, 2, 3, 4, 5 ans, ...)
et lors de l'insertion dans la table "Planning preventif" prendre en compte la périodicité et l'additionner à l'année 2020.

Ex:

Planning Preventif initiale

N° BTP, Semaine interv, Année interv, soldée interv, date de fin du BTP
7, 31, 2020, -1, 28/07/2020 (périodicité 1ans)
8, 31, 2020, -1, 29/07/2020 (périodicité 2ans)


Planning Preventif après report

N° BTP, Semaine interv, Année interv, soldée interv, date de fin du BTP
7, 31, 2020, -1, 28/07/2020 (périodicité 1ans)
7, 31, 2020, -1, 28/07/2021
8, 31, 2020, -1, 29/07/2020 (périodicité 2ans)
8, 31, 2020, -1, 29/07/2022


Voila! j'espère m'être fait comprendre, ce n'est pas évident à expliquer... en théorie c'est simple! mais pas à mettre en oeuvre...

Merci pour votre aide :)
Messages postés
16044
Date d'inscription
lundi 9 juin 2008
Statut
Contributeur
Dernière intervention
16 juin 2021
867
ton exemple est incomplet: tu ne nous montres pas les données issues de la requête "report_preventif"
Messages postés
16044
Date d'inscription
lundi 9 juin 2008
Statut
Contributeur
Dernière intervention
16 juin 2021
867
N° BTP est-il la clé primaire dans la table "préventif"?
Ops !



Exemple de résultat de la requête "report_preventif"
Code machine, Année interv, Semaine interv, N° BTP, périodicité
ACCOMP07, 2020, 4, 798, 1
ACCOMP07, 2020, 15, 1242, 1

Merci :)
Messages postés
16044
Date d'inscription
lundi 9 juin 2008
Statut
Contributeur
Dernière intervention
16 juin 2021
867
dans ton exemple "Planning Preventif après report", je suis étonné que le champ "Année interv" soit partout 2020.
le champ "date de fin du BTP" est-il un champ calculé?

il ne peux jamais y avoir deux codes machine pour un n°BTP?

si je vois bien, ton exemple est incomplet, ce ne sont pas partout les mêmes n°BTP.
un exemple, cela ne se fait pas en sortant quelques lignes au hasard dans chaque table.

si tu ne peux ni expliquer la théorie, ni montrer des exemples utiles, je ne vois pas trop comment t'aider.
Messages postés
16044
Date d'inscription
lundi 9 juin 2008
Statut
Contributeur
Dernière intervention
16 juin 2021
867
essayons autrement.
la requête suivante te donne-t'elle exactement tous les enregistrements à ajouter dans la table "planning préventif": le bon nombre d'enregistrements avec les bonnes informations?

SELECT [Planning preventif].[N° BTP], [Planning preventif].[Semaine interv], 
[Planning preventif].[Année interv] + préventif.périodicité
FROM préventif INNER JOIN [Planning preventif] 
ON préventif.[N° BTP] = [Planning preventif].[N° BTP]
WHERE (((préventif.Activé)=Yes)) and [Planning preventif].[Année interv] = 2020
ORDER BY [Planning preventif].[N° BTP], [Planning preventif].[Semaine interv] ;
Concernant les année 2020... La plupart des BTP sont remporté tous les ans, en 2021 j'en aurais au tant quand 2020. Après selon la périodicité certaines interventions sont reporté sur d'autres années (ex: si le champ "périodicité" est égal à 2.. Le résultat sera 2022 et non 2020).

Le champ date de fin du BTP est renseigné le jour de l'intervention par le tech en validant la case à cocher correspondant au champ soldée interv de la table "planning preventif."

Concernant le fonctionnement...
Une machine peut avoir plusieurs n° de BTP du à des travaux différents.
Un n° de BTP peut avoir plusieurs "semaine interv" du au cadencement (ex: tous les 6 mois)

Concernant la requête "report_preventif" elle foncionne très bien, elle renvoie bien toutes les bonnes informations.

La difficulté se trouve ensuite, car il faut prendre toutes les lignes, additionné les périodicités aux années et les reporter sur la table "planning preventif"

Voilà je pense t'avoir tous dis :)
Messages postés
16044
Date d'inscription
lundi 9 juin 2008
Statut
Contributeur
Dernière intervention
16 juin 2021
867 > tech40
regarde l'exemple que tu as donné pour "Planning Preventif après report", et explique pourquoi il y a 2020 pour les quatre enregistrements.
explique aussi comment tu détermines les valeurs de "date de fin du BTP" pour les enregistrements ajoutés.

N° BTP est-il la clé primaire dans la table "préventif"?
Ops ! Désolé !

J'ai mal informé le résultat attendu (le fameux copier-coller) :)

N° BTP, Semaine interv, Année interv, soldée interv, date de fin du BTP
7, 31, 2020, -1, 28/07/2020 (périodicité 1ans)
7, 31, 2021, 0
8, 31, 2020, -1, 29/07/2020 (périodicité 2ans)
8, 31, 2022, 0

pour les les valeurs de "date de fin du BTP" pour les enregistrements ajoutés doivent être à zéro, car on ne c'est pas encore la date de la future intervention.

Oui, n° BTP est bien la clé primaire dans la table "préventif" (avec NuméroAuto).
Messages postés
16044
Date d'inscription
lundi 9 juin 2008
Statut
Contributeur
Dernière intervention
16 juin 2021
867 > @tech
tu as plusieurs enregistrements pour le même BTP, la même semaine et la même année?
l'option "unique" doit être mise sur la combinaison des trois.

aucun texte accompagnant le numéro d'erreur?
>
Messages postés
16044
Date d'inscription
lundi 9 juin 2008
Statut
Contributeur
Dernière intervention
16 juin 2021

Je pense que oui, il y a du avoir des doublons les années précédentes...
J'ai bien réalisé la combinaison des trois mais sans l'option unique.

Il vas falloir que j'aille à la chasse au doublons, mais je ne c'est pas trop encore... comment je vais m'y prendre !

Sinon aucun texte accompagnant le numéro d'erreur.
Messages postés
16044
Date d'inscription
lundi 9 juin 2008
Statut
Contributeur
Dernière intervention
16 juin 2021
867 > @tech
il manque un + dan la ligne 9 du code, cela doit être:
    + " [Planning preventif].[Année interv] + préventif.périodicité, False " _    
>
Messages postés
16044
Date d'inscription
lundi 9 juin 2008
Statut
Contributeur
Dernière intervention
16 juin 2021

Super ! Cool !

c'était bien ça il manquait le + du coup le code fonctionne bien, et la table "planning preventif" à bien les nouvelles infos.

Manque plus que les doublons..
Messages postés
16044
Date d'inscription
lundi 9 juin 2008
Statut
Contributeur
Dernière intervention
16 juin 2021
867 > @tech
moi je chercherais les doublons ainsi:
SELECT count(*) as ndoublons ,[N° BTP], [Semaine interv], [Année interv]
FROM  [Planning preventif] 
GROUP BY [N° BTP], [Semaine interv], [Année interv]
HAVING count(*) > 1 ;   
Ouuuuao! Tu es trop fort !

Mois j'ai exporté sur Excel, et appliqué 2 formules...

Toi une petite requête et le tour est joué !

Je m'incline... ;)

Avec les 2 méthodes, je trouve le même résultat.

J'ai éliminer les doublons, et réussi enfin mettre l'index unique sur la table.

Par contre, maintenant j'ai l'erreur 3022 (risque de doublons) lorsque je lance le code.
Messages postés
16044
Date d'inscription
lundi 9 juin 2008
Statut
Contributeur
Dernière intervention
16 juin 2021
867
si tu relances le code une deuxième fois pour la même année, c'est normal, non, que cela soit refusé avec "risque de doublons", non?
>
Messages postés
16044
Date d'inscription
lundi 9 juin 2008
Statut
Contributeur
Dernière intervention
16 juin 2021

J'ai bien vérifier les données, je reprend toujours une sauvegarde pour refaire les test.
La sauvegarde na plus de doublons dans la table et à le code qui fonctionne bien.
Dès que je met la table avec l'option unique , là ça ne marche plus

Mais pour info!
j'ai déjà certaines ligne pour 2021, 2022, 2023, suite au périodicité des années antérieures.
ex: 2019 avec une périodicité de 2 ans = 2021
Je pense que il doit y avoir des doublons dans les années futures...
Du coup j'ai bien trouvé plusieurs doublons sue les années à venir.

Le code marche super bien ! tu es trop fort !

Si on compare le code précédent avec le tiens y a pas photo ! (pourquoi faire simple... si on peut faire compliqué)

Je ne ç'est pas comment te remercier !

Merci beaucoup pour ton aide yg_be :)
Messages postés
16044
Date d'inscription
lundi 9 juin 2008
Statut
Contributeur
Dernière intervention
16 juin 2021
867
avec plaisir!

pourras-tu marquer la discussion comme résolue?
Messages postés
1
Date d'inscription
jeudi 21 janvier 2021
Statut
Membre
Dernière intervention
21 janvier 2021

Oui bien sûr !

Mais je n'ai pas l'option "marquer comme résolu" sur le site, j'ai essayé via mon email, mais ça ne fonctionne pas non plus.

Au moins j'aurais essayé.

Merci encore pour ton aide