Code VBA pour report de données d'une année vers une autre

Résolu/Fermé
@tech - Modifié le 11 janv. 2021 à 22:28
tech40 Messages postés 1 Date d'inscription jeudi 21 janvier 2021 Statut Membre Dernière intervention 21 janvier 2021 - 21 janv. 2021 à 15:41
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 !
A voir également:

11 réponses

f894009 Messages postés 17185 Date d'inscription dimanche 25 novembre 2007 Statut Membre Dernière intervention 15 avril 2024 1 701
12 janv. 2021 à 08:12
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
1
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 :)
0
yg_be Messages postés 22720 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 23 avril 2024 1 476
17 janv. 2021 à 23:19
bonjour, nous as-tu dit combien de lignes étaient affichées quand tu ouvrais la requête "Report preventif" ?
0
Bonjour yg_be,

12627 lignes
0
yg_be Messages postés 22720 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 23 avril 2024 1 476
17 janv. 2021 à 23:47
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.
0
yg_be Messages postés 22720 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 23 avril 2024 1 476
17 janv. 2021 à 23:20
peux-tu utiliser les balises de code quand tu partages to code:https://codes-sources.commentcamarche.net/faq/11288-les-balises-de-code
0
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
0

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

Posez votre question
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 :)
0
yg_be Messages postés 22720 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 23 avril 2024 1 476
19 janv. 2021 à 15:49
ton exemple est incomplet: tu ne nous montres pas les données issues de la requête "report_preventif"
0
yg_be Messages postés 22720 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 23 avril 2024 1 476
19 janv. 2021 à 16:45
N° BTP est-il la clé primaire dans la table "préventif"?
0
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 :)
0
yg_be Messages postés 22720 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 23 avril 2024 1 476
19 janv. 2021 à 16:24
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.
0
yg_be Messages postés 22720 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 23 avril 2024 1 476
19 janv. 2021 à 16:37
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] ;
0
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 :)
0
yg_be Messages postés 22720 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 23 avril 2024 1 476 > tech40
19 janv. 2021 à 17:31
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"?
0
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).
0
yg_be Messages postés 22720 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 23 avril 2024 1 476
19 janv. 2021 à 19:42
peux-tu répondre à la question en #12?
0
@tech > yg_be Messages postés 22720 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 23 avril 2024
Modifié le 19 janv. 2021 à 20:27
Question en #12?

Est-ce para rapport au code que j'ai posté ?
Dim i As Integer

Ce n'est pas moi qui est codé cette application, j'essaye de corriger quelques anomalies...

Pour moi cette ligne ne sert à rien, je pense que la personne qui l'as codé a du vouloir l'utiliser et à oublier de l'effacer !

comme pour la ligne 20
i = 1
0
yg_be Messages postés 22720 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 23 avril 2024 1 476 > @tech
19 janv. 2021 à 20:58
peux-tu répondre à la question que j'ai posée dans mon message #12?
0
@tech > yg_be Messages postés 22720 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 23 avril 2024
19 janv. 2021 à 21:53
Oui, la requête fonctionne très bien !
Ce sont bien tous les enregistrements à ajouter dans la table "planning préventif".
0
yg_be Messages postés 22720 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 23 avril 2024 1 476 > @tech
19 janv. 2021 à 21:58
alors tu peux utiliser ceci, je pense, pour faire le report:
INSERT INTO [Planning preventif] 
        ([N° BTP], [Semaine interv], [Année interv], [soldée interv] )
SELECT [Planning preventif].[N° BTP], [Planning preventif].[Semaine interv], 
[Planning preventif].[Année interv] + préventif.périodicité, False
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] ; 
0
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.
0
yg_be Messages postés 22720 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 23 avril 2024 1 476
20 janv. 2021 à 20:25
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?
0
@tech > yg_be Messages postés 22720 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 23 avril 2024
20 janv. 2021 à 21:47
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...
0
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 :)
0
yg_be Messages postés 22720 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 23 avril 2024 1 476
21 janv. 2021 à 11:12
avec plaisir!

pourras-tu marquer la discussion comme résolue?
0
tech40 Messages postés 1 Date d'inscription jeudi 21 janvier 2021 Statut Membre Dernière intervention 21 janvier 2021
21 janv. 2021 à 15:41
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
0