optimisation flux logistique aller retour flotte camion excel

pdsaudrey

XLDnaute Nouveau
Bonjour à tous,

J'ai une BDD avec des flux de convoyage sur 2015. Je cherche à quantifier le levier d'optimisation suivant:
1. optimiser les aller - retour sur l'ensemble de périmètre. Ex: un convoyage Paris Marseille avec un fournisseur A, et le même jour un Marseille - Paris. Identifier de part la date du convoyage et les points d'enlèvement et de destination la possibilité de réaliser des retours avec le même fournisseur.
Je n'ai aucune idée de comment procéder. J'ai fait des concatener / recherchev simples mais l'info est peu robuste et je retrouve des doublons. Help pleaaaase:eek:
Je vous joins mon fichier simplifié. Merci d'avaaaaaance pour votre aide.
 

Pièces jointes

  • ALLER RETOUR.xlsx
    75.1 KB · Affichages: 175

pdsaudrey

XLDnaute Nouveau
Re : optimisation flux logistique aller retour flotte camion excel

Re-salut Bernard,

J'ai "joué" un peu avec le fichier et j'ai détecté quelques anomalies. Ex. Recherche A/R même jour CP=5 chiffres. Desfois il me rends 71 lignes et desfois 41 lignes. Par ailleurs, j'obtiens moins de ligne en faisant une recherche +/- 1 jour avec CP=2 chiffres qu'en faisant CP=5 chiffres et même jour, ce qui me semble surprenant.

Sais tu à quoi sont dû ces problèmes?

Cordialement
 

CBernardT

XLDnaute Barbatruc
Re : optimisation flux logistique aller retour flotte camion excel

Bonsoir,

Je viens de tester les anomalies que tu as observées :
1- Avec diff de 1 jour et CP à 2 j'ai 71 résultats.
2- avec diff de 1 jour et CP à 5 j'ai 46 résultats.
Résultats normal car il y a plus de convoyage entre deux départements qu'entre deux communes.
J'ai toujours les mêmes résultats avec les mêmes critères.
3- Il ne peut y avoir de critère -1 uniquement 1 et plus.
Donc tout marche parfaitement sur ma bécane.

Pour le fichier avec plus de critères de sélection, cogite bien la chose et poste le classeur tel qu'il devra être au final ainsi que les critères de sélection que tu envisages. Je changerai le code afin d'adapter la macro aux nouvelles conditions.
 

pdsaudrey

XLDnaute Nouveau
Re : optimisation flux logistique aller retour flotte camion excel

Bonsoir,

Je viens de tester les anomalies que tu as observées :
1- Avec diff de 1 jour et CP à 2 j'ai 71 résultats.
2- avec diff de 1 jour et CP à 5 j'ai 46 résultats.
Résultats normal car il y a plus de convoyage entre deux départements qu'entre deux communes.
J'ai toujours les mêmes résultats avec les mêmes critères.
3- Il ne peut y avoir de critère -1 uniquement 1 et plus.
Donc tout marche parfaitement sur ma bécane.

Pour le fichier avec plus de critères de sélection, cogite bien la chose et poste le classeur tel qu'il devra être au final ainsi que les critères de sélection que tu envisages. Je changerai le code afin d'adapter la macro aux nouvelles conditions.

Bonsoir Barnard. Je te joins le fichier actualisé. Pour reprendre, j'ai deux analyses:
1- quantifier les opportunités d'aller retour pour une même date, et par type de convoyage (carrossier, interne ou externe).
2- quantifier les opportunités de mutualiser le convoi de plusieurs véhicules sur un même porteur.
Voici les critères qu'il faudrait intégrer:
recherche 1- date, code postal à 2 ou 5 chiffres, le type de convoyage (carrossier, interne ou externe)
recherche 2 - date +/- x jours (1 voir 2 jours), si un regroupement est faisable ou pas (dernière colonnes), et prendre en compte qu'un porteur peut regrouper jusqu'à max. 5 véhicules (c'est un exemple, il faudrait laisser ce champs ouvert).

Il faudra que j'ajoute beaucoup de lignes car le pouvait pas envoyer les 45,000 lignes de BDD ici donc stp autant que la macro couvre xxxxxxxx lignes Excel. Je crois que j'ai tout repris. MERCiiii
 

Pièces jointes

  • Classeur1.xls
    134 KB · Affichages: 69
  • Classeur1.xls
    134 KB · Affichages: 66

klin89

XLDnaute Accro
Re : optimisation flux logistique aller retour flotte camion excel

Bonjour à tous, :)

Comme l'exercice m'nteressait, je me suis attaché à regrouper pour une même date les itinéraires Aller et Retour.
Je me suis appuyé sur le fichier du post #1
Restitution en Feuil2 :
VB:
Option Explicit

Sub Regroupement()
Dim i As Long, n As Long, aller As String, retour As String
Dim dico As Object, e
    Set dico = CreateObject("Scripting.Dictionary")
    dico.CompareMode = 1
    With Sheets("Feuil1")
        With .Range("a1").CurrentRegion
            For i = 2 To .Rows.Count
                aller = Join$(Array(.Rows(i).Cells(1), .Rows(i).Cells(3), .Rows(i).Cells(6)), Chr(2))
                retour = Join$(Array(.Rows(i).Cells(1), .Rows(i).Cells(6), .Rows(i).Cells(3)), Chr(2))
                If Not dico.exists(aller) Then
                    Set dico(aller) = Union(.Rows(1), .Rows(i))
                    If aller <> retour Then
                        Set dico(retour) = Nothing
                    End If
                Else
                    If dico(aller) Is Nothing Then
                        Set dico(retour) = Union(dico(retour), .Rows(i))
                    Else
                        Set dico(aller) = Union(dico(aller), .Rows(i))
                    End If
                End If
            Next
        End With
    End With
    Application.ScreenUpdating = False
    'restitution
    With Sheets("Feuil2")
        .Cells.Clear
        For Each e In dico
            If Not dico(e) Is Nothing Then
                n = n + 1
                dico(e).Copy .Cells(n, 1)
                With .Cells(n, 1).CurrentRegion
                    n = n + .Rows.Count
                End With
            End If
        Next
        .Cells.EntireColumn.AutoFit
        .Activate
    End With
    Application.CutCopyMode = False
    Application.ScreenUpdating = True
    Set dico = Nothing
End Sub
Tu peux aussi remplacer ces 2 lignes
VB:
aller = Join$(Array(.Rows(i).Cells(1), .Rows(i).Cells(3), .Rows(i).Cells(6)), Chr(2))
retour = Join$(Array(.Rows(i).Cells(1), .Rows(i).Cells(6), .Rows(i).Cells(3)), Chr(2))
par celles-ci
VB:
aller = Join$(Array(.Rows(i).Cells(3), .Rows(i).Cells(6)), Chr(2))
retour = Join$(Array(.Rows(i).Cells(6), .Rows(i).Cells(3)), Chr(2))

Edit : sur plusieurs milliers de lignes, la durée d'exécution peut être un peu longue.
klin89
 

Pièces jointes

  • Aller_Retour.xls
    214 KB · Affichages: 83
Dernière édition:

CBernardT

XLDnaute Barbatruc
Re : optimisation flux logistique aller retour flotte camion excel

Bonjour à tous,

Prise en compte du nouveau fichier et adaptation de la macro à la nouvelle base de données.

A vérifier, si cela correspond aux conditions du post 1 je poursuivrai ensuite sur la mise en place des deux processus de sélection aller-retour du projet :

1- quantifier les opportunités d'aller retour pour une même date, et par type de convoyage (carrossier, interne ou externe).
2- quantifier les opportunités de mutualiser le convoi de plusieurs véhicules sur un même porteur.
Voici les critères qu'il faudrait intégrer:
recherche 1- date, code postal à 2 ou 5 chiffres, le type de convoyage (carrossier, interne ou externe)
recherche 2 - date +/- x jours (1 voir 2 jours), si un regroupement est faisable ou pas (dernière colonnes), et prendre en compte qu'un porteur peut regrouper jusqu'à max. 5 véhicules (c'est un exemple, il faudrait laisser ce champs ouvert).
 

Pièces jointes

  • Optimisation-flux-logistique-aller-retour-flotte-camion-V3.xlsm
    222.6 KB · Affichages: 55

klin89

XLDnaute Accro
Re : optimisation flux logistique aller retour flotte camion excel

Re pdsaudrey, :)

Toujours avec le fichier du post #1
J'ai amélioré la présentation :
J'ai ajouté des titres et on distingue mieux le regroupement par dates des différents convoyages.
VB:
Option Explicit

Sub test1()
Dim dico As Object, i As Long, n As Long, txt1 As String, txt2 As String, e, s
    Set dico = CreateObject("Scripting.Dictionary")
    dico.CompareMode = 1
    With Sheets("Feuil1").Range("a1").CurrentRegion
        For i = 2 To .Rows.Count
            txt1 = Join$(Array(.Cells(i, 3), .Cells(i, 6)), " - ")
            txt2 = Join$(Array(.Cells(i, 6), .Cells(i, 3)), " - ")
            If Not dico.exists(txt1) Then
                Set dico(txt1) = CreateObject("Scripting.Dictionary")
                dico(txt1).CompareMode = 1
                If txt1 <> txt2 Then
                    Set dico(txt2) = Nothing
                End If
                If Not dico(txt1).exists(.Cells(i, 1).Value) Then
                    Set dico(txt1)(.Cells(i, 1).Value) = .Rows(1)
                End If
                Set dico(txt1)(.Cells(i, 1).Value) = Union(dico(txt1)(.Cells(i, 1).Value), .Rows(i))
            Else
                If dico(txt1) Is Nothing Then
                    If Not dico(txt2).exists(.Cells(i, 1).Value) Then
                        Set dico(txt2)(.Cells(i, 1).Value) = .Rows(i)
                    Else
                        Set dico(txt2)(.Cells(i, 1).Value) = Union(dico(txt2)(.Cells(i, 1).Value), .Rows(i))
                    End If
                Else
                    If Not dico(txt1).exists(.Cells(i, 1).Value) Then
                        Set dico(txt1)(.Cells(i, 1).Value) = .Rows(i)
                    Else
                        Set dico(txt1)(.Cells(i, 1).Value) = Union(dico(txt1)(.Cells(i, 1).Value), .Rows(i))
                    End If
                End If
            End If
        Next
        Application.ScreenUpdating = False
        'restitution
        With Sheets("Feuil2")
            .Cells.Clear
            For Each e In dico
                If Not dico(e) Is Nothing Then
                    n = .Cells(.Cells.Rows.Count, "A").End(xlUp).Row + 3
                    If n = 4 Then n = 1
                    With .Cells(n, 1).Resize(, 7)
                        .Merge
                        .HorizontalAlignment = xlCenter
                        .Value = UCase(e)
                        .Font.Size = 16
                    End With
                    n = .Cells(.Cells.Rows.Count, "A").End(xlUp).Row + 1
                    For Each s In dico(e)
                        dico(e)(s).Copy .Cells(n, 1)
                        n = .Cells(.Cells.Rows.Count, "A").End(xlUp).Row + 2
                    Next
                End If
            Next
            .Cells.EntireColumn.AutoFit
            With .UsedRange.Rows
                .SpecialCells(4).RowHeight = 9
                .SpecialCells(2).RowHeight = 18
            End With
            .Activate
        End With
        Application.CutCopyMode = False
        Application.ScreenUpdating = True
        Set dico = Nothing
    End With
End Sub
klin89
 

Pièces jointes

  • Aller_RetourV1.xls
    284.5 KB · Affichages: 73
Dernière édition:

klin89

XLDnaute Accro
Re : optimisation flux logistique aller retour flotte camion excel

Bonsoir à tous, :)

Pour ceux qui aiment tripoter les dictionnaires, j'ai réécrit la procédure précédente.
La variable tableau w vient remplacer l'objet range comme élément associé aux clés du dictionnaire.
En plaçant un espion sur w, on comprend mieux le cheminement du code.

C'est peut-être plus clair ainsi, enfin c'est mon avis. :p
Pour la restitution, je n'emploie plus la méthode Copy et donc n'ai pas soigné la mise en forme.
VB:
Option Explicit

Sub test2()
Dim a, w(), e, s, i As Long, j As Long, n As Long
Dim dico As Object, txt1 As String, txt2 As String
    Set dico = CreateObject("Scripting.Dictionary")
    dico.CompareMode = 1
    a = Sheets("Feuil1").Range("a1").CurrentRegion.Value
    For i = 2 To UBound(a, 1)
        txt1 = Join$(Array(a(i, 3), a(i, 6)), " - ")
        txt2 = Join$(Array(a(i, 6), a(i, 3)), " - ")
        If Not dico.exists(txt1) Then
            Set dico(txt1) = CreateObject("Scripting.Dictionary")
            dico(txt1).CompareMode = 1
            If txt1 <> txt2 Then
                Set dico(txt2) = Nothing
            End If
            If Not dico(txt1).exists(a(i, 1)) Then
                ReDim w(1 To UBound(a, 2), 1 To 2)
                For j = 1 To UBound(a, 2)
                    w(j, UBound(w, 2) - 1) = a(1, j)
                    w(j, UBound(w, 2)) = a(i, j)
                Next
                dico(txt1)(a(i, 1)) = w
                'équivalence du code précédent
                'Set dico(txt1)(.Cells(i, 1).Value) = Union(.Rows(1), .Rows(i))
            End If
        Else
            If dico(txt1) Is Nothing Then
                If Not dico(txt2).exists(a(i, 1)) Then
                    ReDim w(1 To UBound(a, 2), 1 To 1)
                    For j = 1 To UBound(a, 2)
                        w(j, UBound(w, 2)) = a(i, j)
                    Next
                    dico(txt2)(a(i, 1)) = w
                    'équivalence du code précédent
                    'Set dico(txt2)(.Cells(i, 1).Value) = .Rows(i)
                Else
                    w = dico(txt2)(a(i, 1))
                    ReDim Preserve w(1 To UBound(w, 1), 1 To UBound(w, 2) + 1)
                    For j = 1 To UBound(a, 2)
                        w(j, UBound(w, 2)) = a(i, j)
                    Next
                    dico(txt2)(a(i, 1)) = w
                    'équivalence du code précédent
                    'Set dico(txt2)(.Cells(i, 1).Value) = Union(dico(txt2)(.Cells(i, 1).Value), .Rows(i))
                End If
            Else
                If Not dico(txt1).exists(a(i, 1)) Then
                    ReDim w(1 To UBound(a, 2), 1 To 1)
                    For j = 1 To UBound(a, 2)
                        w(j, UBound(w, 2)) = a(i, j)
                    Next
                    dico(txt1)(a(i, 1)) = w
                    'équivalence du code précédent
                    'Set dico(txt1)(.Cells(i, 1).Value) = .Rows(i)
                Else
                    w = dico(txt1)(a(i, 1))
                    ReDim Preserve w(1 To UBound(w, 1), 1 To UBound(w, 2) + 1)
                    For j = 1 To UBound(a, 2)
                        w(j, UBound(w, 2)) = a(i, j)
                    Next
                    dico(txt1)(a(i, 1)) = w
                    'équivalence du code précédent
                    'Set dico(txt1)(.Cells(i, 1).Value) = Union(dico(txt1)(.Cells(i, 1).Value), .Rows(i))
                End If
            End If
        End If
    Next
    Application.ScreenUpdating = False
    'restitution
    With Sheets("Feuil2")
        .Cells.Clear
        For Each e In dico
            If Not dico(e) Is Nothing Then
                n = .Cells(.Cells.Rows.Count, "A").End(xlUp).Row + 3
                If n = 4 Then n = 1
                With .Cells(n, 1).Resize(, 7)
                    .Merge
                    .HorizontalAlignment = xlCenter
                    .Value = UCase(e)
                    .Font.Size = 16
                End With
                n = .Cells(.Cells.Rows.Count, "A").End(xlUp).Row + 1
                For Each s In dico(e)
                    w = dico(e)(s)
                    .Cells(n, 1).Resize(UBound(w, 2), UBound(w, 1)).FormulaLocal = _
                    Application.Transpose(w)
                    n = .Cells(.Cells.Rows.Count, "A").End(xlUp).Row + 2
                Next
            End If
        Next
        .Cells.EntireColumn.AutoFit
        With .UsedRange.Rows
            .SpecialCells(4).RowHeight = 9
            .SpecialCells(2).RowHeight = 18
        End With
        .Activate
    End With
    Application.ScreenUpdating = True
    Set dico = Nothing
End Sub
 
Dernière édition:

Statistiques des forums

Discussions
312 493
Messages
2 088 956
Membres
103 990
dernier inscrit
lamiadebz