Projet Placement employés

Salut le forum,

Salut les as,

je fais appel à l'équipe avant de jeter mon ordi' par la fenêtre...

Contexte : j'ai un tableau fixe tPerm... invisible!

Pour XDBEO, je réalise un placement d'employés pour assurer des permanences Ouverture-Fermeture dont le nombre est calculé selon le nombre de jours de travail (formules en ligne 46). Il y a 36 conditions à respecter, vous vous en doutez, dont certaines basées sur les couleurs de cellules, précisant les desiderata des employés (orange = pas d'ouverture, jaune =pas de fermeture : rouge : rien du tout).

Une première phase sur les cellules directement a validé le processus et j'ai voulu le faire via tableaux.

  • Comme il faut jouer avec des couleurs, je construis (ligne 100) un nouveau tableau reprenant Nb de permanences à réaliser, couleurs de FONT des employés (les rouges ont quitté l'entreprise) et les codes Interior. ColorIndex de leurs pauses, le tout trié par ordre croissant de permanences à réaliser, capturé dans le tableau tCol. OK...
  • le tableau tTab capture l'horaire proprement dit (ligne 1 à 43). OK...
  • Comme la première tentative de placement est rarement la bonne, j'entame une boucle DO...LOOP UNTIL pour remplir un dernier tableau tPerm que j'initialise avant DO...LOOP en capturant les colonnes [W:X] dans lesquelles il doit s'afficher. OK... enfin, pas tant que ça !

Dans le code, vous verrez une ligne...

'.Range ("C100").Resize(44, 2).Value=tPerm

... qui affiche correctement tPerm en ligne 100.

Dans la boucle DO...LOOP, je dois forcément ERASE tPerm à chaque nouvelle tentative... PLUS RIEN !

Il devient transparent, invisible, n'existe plus...

La boucle ne présente aucune erreur. Que les résultats ne soient pas corrects du premier coup après la modification, je m'en f... mais : où est ce foutu tableau ?

A force de regarder et tester toutes sortes de MsgBox, je deviens chèvre !

Comptant beaucoup sur votre lucidité,

A+

26xdbeo.xlsm (78.86 Ko)

Bonsoir, avec un i sans tréma !

Je n'ai pas tout saisie mais il y a un truc que je ne comprend pas :

        tPerm = .Range(sCol1 & 1).Resize(44, 2).Value                                                  'tableau des permanences pour affichage dans [W:X]
        '.Range ("C100").Resize(44, 2).Value=tPerm
        iRep = CInt(.Range("V50").Value)                                                                'nombre total de permanences à assurer
        .Range("AA1") = ""
        T = Timer
        Do                                                                          'boucle tant que le placement n'est pas correct -> jusque iOK MAX
            iCpt = 0                                                                'compteur de placement effectué
            Erase tPerm

tPerm est rempli par copie de plage et juste après on l'efface...

Le Erase ne devrait-il pas se trouver plus loin dans le code lorsque les différents tests n'aboutissent pas "au résultat" ?

@ bientôt

LouReeD

Salut LouReed,

merci de te pencher sur mes bugs...

Les données de départ de tPerm doivent être effacées pour que le calcul fonctionne puisque celui-ci vérifie l'absence de tel ou tel employé dans les parages pour valider une permanence.

Un employé ne peut pas faire de fermeture un jour si il a déjà été placé en ouverture le lendemain matin.

Garder les anciennes valeurs ne pourrait conduire qu'à des impasses permanentes.

Les données de [W:X] doivent être effacées et le tableau démarrer d'une feuille vierge.

Dommage que je n'ai pas conservé la version-cellules...

A+

Re-LouReed,

la raison de la capture de ce tableau tPerm en [W:X] est d'avoir les mêmes index d'adressage entre tTab et tPerm.

Il est vrai que je pourrais essayer (mais ça me choquerait de ne pas pouvoir utiliser cette solution!) avec un tableau dynamique...

Bonjour à tous,

pour moi, avec tPerm = .Range(sCol1 & 1).Resize(44, 2).Value tu as un tableau dynamique et non pas fixe.

Le Erase libère donc la mémoire.

C'est même étonnant que tu n'aies pas d'erreur sur tPerm(1, 1) = "O P E N"

Tu devrais te servir d'un tableau intermédiaire tmp pour la lecture et définir autrement tPerm, quitte à l'alimenter par une boucle si besoin. Par exemple :

Dim tPerm()
Redim tPerm(1 to ubound(tmp,1),1 to ubound(tmp,2))

Le réinitialiser à chaque fois avec Redim

On bien en calculant le nombre de lignes (qui d'ailleurs à l'air d'être fixe et =44) comme tu n'as pas l'air de te servir de tPerm (l'ex tPerm)

Dans ce cas :

Dim tPerm(1 to 44, 1 to 2) (?) et là tu auras un tableau fixe qui ne partira pas de la mémoire avec le Erase

eric

Salut Eriiic,

merci de joindre à l'équipe Questions pour un Champion !

J'ai essayé comme indiqué.

tPerm(1 To 44, 1 To 2) : il m'indique bien "OPEN-CLOSE" puis plus rien.

Une Msgbox en sortie du bloc de calcul IF ENDIF est transparente, tout pareil et ne s'affiche pas non plus.

Dans le calcul, c'est le Triangle des Bermudes...

A+

puis plus rien

il ne peut t'afficher que ce que tu y as mis, il ne se remplit pas tout seul.

Bonsoir,

il y a une erreur sur :

C'est même étonnant que tu n'aies pas d'erreur surtPerm(1, 1) = "O P E N"

bien vue eriiic !

Pourtant n'est-ce pas une règle en développement de ne pas mettre de On Error Resume Next pour "avoir la main sur tout" ?

@ bientôt

LouReeD

Eriiic,

la version-cellules fonctionnait parfaitement mais, beaucoup trop lente à mon goût, d'où les tableaux.

Le code suivant n'est que la transciption en tableau du même calcul.

                                    For Z = IIf(iTurn = 1, iSpot, 2) To IIf(iTurn = 1, 43, iSpot - 1)
                                        If CInt(tTab(Z, x)) = 1 And _
                                            (CInt(tTab(Z + 1, x)) = 1 Or tTab(Z + 1, x) = "R" Or tTab(Z + 1, x) = "" Or CInt(tTab(Z + 1, x)) = 0) And _
                                            tPerm(Z, IIf(iStart = 1, 1, 2)) = "" And _
                                            tPerm(Z, IIf(iStart = 1, 2, 1)) <> tTab(1, x) And _
                                            tPerm(Z - 1, 1) <> tTab(1, x) And tPerm(Z - 1, 2) <> tTab(1, x) And _
                                            tPerm(Z + 1, 1) <> tTab(1, x) And tPerm(Z + 1, 2) <> tTab(1, x) And _
                                            CInt(tCol(Z + 3, k)) <> 3 And CInt(tCol(Z + 3, k)) <> IIf(iStart = 1, 45, 6) Then
                                                tPerm(Z, IIf(iStart = 1, 1, 2)) = tTab(1, x)
                                                iStop = 1
                                                iCpt = iCpt + 1
                                                Exit For
                                        End If
  • si l'employé travaille = 1 ;
  • si le jour suivant est un jour de travail ou de repos ou cellule vide (bande noire = fermé) ou cellule = 0 (pour éviter une permanence avant un des jours spéciaux d'autres couleurs (condition que j'ai ajoutée) ;
  • si tPerm(même ligne, 1 (fermeture) ou 2 (ouverture) n'est pas encore affecté ;
  • si l'horaire antagoniste même ligne ne LUI a pas déjà été attribué ;
  • si il ne doit pas déjà faire une Perm le jour précédent et le jour suivant ;
  • si sa couleur de cellule n'est pas Orange, jaune ou rouge :
ALORS, on l'affecte à cette permanence.

Dans un tableau vide, il me paraît difficile de ne pas trouver sa place, surtout les premiers servis.

Je crois que je vais dormir un coup. Demain, promenade au grand air avec les chiens : on s'y remet demain après-midi!

Merci de faire tourner vos neurones pour moi : ça repose!

A+

Salut LouReed,

je viens de mettre...

'On Error Resume Next

... sous commentaire : la boucle s'effectue sans erreur!

C'est le Diaaaaable!

A+

curulis57, chez moi ca plante " l'indice n'appartient pas..."

Donc je ne sais que dire, si ce n'est "j'espère que vous avez passé une bonne nuit et une bonne promenade pour vous y remettre cet après midi" !

@ bientôt

LouReeD

Salut LouReed, Eriiic,

je vous remercie de vos réponses qui m'ont obligé à une remise en question de ce que je pensais savoir ou savoir faire!

Eriiic, tu as évidemment raison : tPerm est bien un tableau fixe et Erase ne fonctionne pas ou plutôt, il fonctionne trop bien sur ce genre de variable tableau !

J'utilise souvent Erase... mais, à la réflexion, sur des tableaux dynamiques (des vrais, ceux-là !).

LouReed, utiliser trop tôt On Error Resume Next est vraiment une mauvaise idée et l'ordi', après une nuit à refroidir, me l'a bien rappelé ce matin en provoquant erreur sur erreur quand je voulais afficher une valeur de tPerm dans une MsgBox.

Je rentre à présent dans la boucle où j'ai buté sur d'autres idioties (de ma part). J'étais trop sûr de mon coup.

D'échanger avec vous m'aura, humblement, bien fait progresser !

Je donnerai des nouvelles lorsque j'aurai réglé les soucis restants.

A+

Je crois qu'avec mes travaux, on n'a pas fini de se voir avec un "i" sans tréma !

@ bientôt

LouReeD

Salut Eriiic, LouReed,

grâce à la réflexion suscitée par vos réponses pertinentes, le souci est réglé!

Déclaration du tableau tPerm...

        .Range(sCol1 & 2).Resize(42, 2) = ""                                                            'effacement colonnes [W:X]
        tPerm = .Range(sCol1 & 1).Resize(44, 2).Value                                                   'tableau des permanences pour affichage dans [W:X]

Effacement du tableau tPerm après tentative infructueuse... Erase eût été plus élégant...

                For x = 2 To 43
                    tPerm(x, 1) = ""
                    tPerm(x, 2) = ""
                Next

Sans compter les CInt ôtés de la boucle de calcul qui provoquaient des incompatibilités d'humeur entre variables !

Bref, , heureusement que vous étiez là pour guider l'aveugle!

Un grand merci, les gars!

A+

6xdbeo.xlsm (86.15 Ko)

Bonjour Curulis,

mais tu peux très bien utiliser un tableau fixe.

Erase ne réagit pas pareil sur un tableau fixe ou un dynamique.

Tu peux supprimer :

tPerm = .Range(sCol1 & 1).Resize(44, 2).Value

et

 'réinitialise tPerm
For x = 2 To 43
     tPerm(x, 1) = ""
    tPerm(x, 2) = ""
Next

devenus inutiles.

Puis :

Dim tPerm(1 To 44, 1 To 2)

Et ajoute au début de ton Do :

        Do  
            Erase tPerm: tPerm(1, 1) = "O P E N": tPerm(1, 2) = "C L O S E"

Le gain n'est pas énorme (0.1 s) mais c'est toujours ça de pris, et puis ça alllège le code de quelques lignes.

        Loop Until iOK = 10000 Or iCpt = iRep
        .Range(sCol1 & 1).Resize(44, 2).Value = tPerm

J'ai l'impression que tu as oublié de supprimer la 2nde ligne non ?

eric

Salut Eriiic,

tu as tout a fait raison !

Moi qui adore compresser un code à l'extrême, celui-ci est bien plus élégant... et j'ai mon Erase !

Je m'en vais de ce pas améliorer ma prose...

Merci!

A+

J'avais complété mon post pour alléger encore ton code...

.Range(sCol1 & 1).Resize(44, 2).Value = tPerm

La seconde ligne, Eriiic ?

OK, j'ai vu !

J'ai fait tellement de trucs que j'en perdais la boule !

Merci, Eriiic!

Rechercher des sujets similaires à "projet placement employes"