Bonjour à tous.

J'ai actuellement ce code qui marche :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
 
Sub getCashFlow()
 
Dim k As Integer
Dim l As Integer
Dim m As Integer
Dim n As Integer
 
l = InputBox("Veuillez saisir la valeur de la première ligne de biditem", "Sélection de la plage de calcul", "XX") 'Selection de la PREMIERE ligne de biditem de la liste à traiter
k = InputBox("Veuillez saisir la valeur de la dernière ligne de biditem", "Sélection de la plage de calcul", "XX") 'Selection de la DERNIERE ligne de biditem de la liste à traiter
m = InputBox("Veuillez saisir la valeur de la première colonne du calendrier", "Sélection de la plage de calcul", "XX") 'Selection de la PREMIERE colonne du calendrier
n = InputBox("Veuillez saisir la valeur de la dernière colonne du calendrier", "Sélection de la plage de calcul", "XX") 'Selection de la DERNIERE colonne du calendrier
 
 
For i = l To k
 
        If Cells(i, 16).Value <> 0 Then 'Si MODIFY<> 0, faire tourner getCalendar puis getPrice
            Range(Cells(i, m), Cells(i, n)).ClearContents 'Supprimer données de la ligne
            For j = m To n  'PUIS faire tourner getCalendar puis getPrice sur la ligne
            Call getCalendar(i, j)
            Call getPrice(i, j)
            Next j
 
 
        Else 'Sinon, aucune action
            For j = m To n
            Cells(i, j) = Cells(i, j)
            Next j
 
        End If
 
 
Next i
 
End Sub 'Fin du programme
 
 
Sub getCalendar(i As Integer, j As Integer)
 
'Regarde si la date de la cellule sélectionnée est comprise entre la date de début et la date de fin du biditem de la même ligne. Si oui, attribution d'un "x" ou d'un "o"; si non, aucune action
 
        If Cells(12, j).Value >= WorksheetFunction.Min(Cells(i, 9).Value, Cells(i, 10).Value) And Cells(12, j).Value <= WorksheetFunction.Max(Cells(i, 9).Value, Cells(i, 10).Value) Then 'VERIFIER que cette ligne utilise bien les colonnes "START DATE" et "FINISH DATE")
            If Cells(i, 15).Value = "A" Then f = 2 'Vérifier que l'on regarde avec la valeur de CALENDAR UPDATE !
            If Cells(i, 15).Value = "B" Then f = 3 'Vérifier que l'on regarde avec la valeur de CALENDAR UPDATE !
            If Cells(i, 15).Value = "C" Then f = 4 'Vérifier que l'on regarde avec la valeur de CALENDAR UPDATE !  'différentes valeurs de f à màj'
            Cells(i, j).Value = Application.VLookup(Cells(12, j), Sheets("Calendar").Range("D6:G370"), f, True) 'vérifier limite du tableau pour le vlookup
 
 
        Else: Cells(i, j).Value = Cells(i, j).Value
 
        End If
 
 
End Sub
 
 
 
 
 
Sub getPrice(i As Integer, j As Integer)
'Regarde si la date de la cellule sélectionnée est comprise entre la date de début et la date de fin du biditem de la même ligne ET que la cellule sélectionnée ne contient pas "x". Si oui, attribution du daily price; si non, aucune action
 
        If Cells(12, j).Value >= WorksheetFunction.Min(Cells(i, 9).Value, Cells(i, 10).Value) And Cells(12, j).Value <= WorksheetFunction.Max(Cells(i, 9).Value, Cells(i, 10).Value) And Cells(i, j).Value <> "x" Then 'VERIFIER que cette ligne utilise bien les colonnes "START DATE" et "FINISH DATE")
        Cells(i, j).Value = Cells(i, 18).Value 'VERIFIER que cette ligne renvoie bien à la colonne "Daily Price"'
 
        Else: Cells(i, j).Value = Cells(i, j).Value
 
        End If
 
End Sub


Le problème de ce code est qu'il est trop lent. En effet, dans mon cas, m=20 et n=2576. Donc dix lignes prennent genre plus de 1 minutes (et je dois en traiter beauuuuucoup plus à terme)

Ma question est : puis-je faire en sorte que mon programme ne parcourt PAS les 2556 colonnes pour chaque ligne ?

Je pensais passer par une fonction "For Each ... in Range" mais je ne maîtrise pas bien cette fonction.

Serait-il possible d'écrire quelque chose comme :

1)

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
 
 
Set myRange = Sheets("BidItem Cost Details").Range(Cells(12, m), Cells(12, n))
For Each cell In myRange
If cell.Value > Sheets("BidItem Cost Details").Min(Cells(i, 10).Value, Cells(i, 11).Value) And cell.Value < Sheets("BidItem Cost Details").Max(Cells(i, 10).Value, Cells(i, 11).Value)) Then

puis faire tourner getCalendar et getPrice pour les cellules (de la ième ligne) dans l'intervalle.
Mais cela sera-t-il plus rapide ?



2) Faire un Range qui varie à chaque ligne (définit par les bornes de "Start Date" et "Finish Date") ? Mais je ne sais pas si c'est possible avec ce type d'objet.

Par exemple :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
 
 
For i = l To k
 
        If Cells(i, 16).Value <> 0 Then 
            Range(Cells(i, m), Cells(i, n)).ClearContents 'Supprimer données de la ligne
            Set myRange = (Min(Cells(i, 10).Value, Cells(i, 11).Value), Max(Cells(i, 10).Value, Cells(i, 11).Value))
            For Each cell in myRange
 
             'PUIS faire tourner getCalendar puis getPrice sur la i-ème ligne et les colonnes des "cell" en question

Je vous joins le fichier en espérant que vous y voyez plus clair !

Un grand merci à tous les courageux qui auront pris le temps de me lire et de se pencher sur la question !
Très bonne journée,
Jean-Etienne.


TempFile.xlsm