Simplification et systémisation fonction VBA
Dernière réponse : dans Programmation
Bonjour,
j'ai un petit problème de programmation avec VBA (pour Arena). Il s'agit d'une
fonction testant les possibilités de mettre des outils dans un buffer en temps
masqué (pour un magasin d'outil de machine).
Le but est de remplir un tableau nommé Buffer_use() avec des 0 et des 1, sachant
que les 1 correspondent à la possibilité de réaliser le placement en temps
masqué. Pour cela, j'ai créer une fonction qui compare le temps de déplacement
du bras pour mettre les outils dans le buffer avec le temps de coupe de
l'opération actuelle. Ces données sont respectivement dans des tableaux nommés
Temps_Deplac() et Temps_Op(). n_tools est le nombre d'opération dans la gamme.
La fonction que j'ai réalisé fonctionne pour un buffer ayant 4 positions (elle
peut donc placer jusqu'à 4 outils dans le buffer a la suite).
Néanmoins, le nombre de positions du buffer est variable. Pouvez-vous m'aider à
transformer cette fonction pour que cela soit prit en compte ? ( J'ai pensé à
faire une fonction récursive mais je ne m'en sors pas).
Voici la fonction telle qu'elle est actuellement :
Merci d'avance.
Schnapz.
j'ai un petit problème de programmation avec VBA (pour Arena). Il s'agit d'une
fonction testant les possibilités de mettre des outils dans un buffer en temps
masqué (pour un magasin d'outil de machine).
Le but est de remplir un tableau nommé Buffer_use() avec des 0 et des 1, sachant
que les 1 correspondent à la possibilité de réaliser le placement en temps
masqué. Pour cela, j'ai créer une fonction qui compare le temps de déplacement
du bras pour mettre les outils dans le buffer avec le temps de coupe de
l'opération actuelle. Ces données sont respectivement dans des tableaux nommés
Temps_Deplac() et Temps_Op(). n_tools est le nombre d'opération dans la gamme.
La fonction que j'ai réalisé fonctionne pour un buffer ayant 4 positions (elle
peut donc placer jusqu'à 4 outils dans le buffer a la suite).
Néanmoins, le nombre de positions du buffer est variable. Pouvez-vous m'aider à
transformer cette fonction pour que cela soit prit en compte ? ( J'ai pensé à
faire une fonction récursive mais je ne m'en sors pas).
Voici la fonction telle qu'elle est actuellement :
buffer_v = 0
counter = 1
Do Until counter = n_tools
If counter + 1 <= n_tools Then
If Temps_Deplac(counter + 1) < Temps_Op(counter) Then
Buffer_Use(counter + 1) = 1
buffer_v = 1
If counter + 2 <= n_tools Then
If Temps_Deplac(counter + 2) + Temps_Deplac(counter + 1) <
Temps_Op(counter) Then
Buffer_Use(counter + 2) = 1
buffer_v = 2
If counter + 3 <= n_tools Then
If Temps_Deplac(counter + 3) + Temps_Deplac(counter + 2)
+ Temps_Deplac(counter + 1) < Temps_Op(counter) Then
Buffer_Use(counter + 3) = 1
buffer_v = 3
If counter + 4 <= n_tools Then
If Temps_Deplac(counter + 4) +
Temps_Deplac(counter + 3) + Temps_Deplac(counter + 2) + Temps_Deplac(counter +
1) < Temps_Op(counter) Then
Buffer_Use(counter + 4) = 1
buffer_v = 4
End If
End If
End If
End If
End If
End If
End If
End If
counter = counter + buffer_v + 1
buffer_v = 0
If counter >= n_tools Then GoTo Nextstep
Loop
Nextstep:
Merci d'avance.
Schnapz.
Autres pages sur : simplification systemisation fonction vba
Lassé par la pub ? Créez un compte
Meilleure solution
Citation :
Après est-ce que l'ensemble fait quelque chose de logique ... Ca c'est mon problème.
Euh..... à te lire tout à l'heure, je pensais que ce n'était pas du tout résolu. L'est-ce ?
(Si oui, clique sur le bouton "Élire meilleure réponse" de la moins mauvaise réponse
)Sinon, s'il ne te manque que la borne 4, tu devrais t'en sortir tout seul
Pour l'arrêt dès qu'on a dépassé, aussi. Mais je te donne une bonne (on peut toujours faire mieux) façon de faire :
Dim tdc As Integer ' // Temps_Deplac_Cumulé Dim position As Integer Dim i As Integer buffer_v = 0 counter = 1 Do Until counter > n_tools For position = 1 To 4 ' // A toi de voir If counter + position > n_tools Then Exit For tdc = 0 For i = 0 To position - 1 tdc = tdc + Temps_Deplac(counter + i) Next If counter + position <= n_tools And tdc < Temps_Op(counter) Then Buffer_Use(counter + position) = 1 buffer_v = position End If Next counter = counter + buffer_v + 1 buffer_v = 0 If counter >= n_tools Then Exit Do Loop
Je n'ai fais qu'ajouter la ligne 9. On sort de la boucle et on se retrouve donc à la ligne 20.
---------------------------
Observe toutefois la ligne 7, j'ai mis une inégalité. NE JAMAIS METTRE D'EGALITE.
Ben pourquoi ? Imagine pour une raison ou une autre, que ton code, dans un cas extrême ou par effet de bord, fasse déborder (tiens, c'est la même racine que effet de bord, justement) ta borne..... Hop, boucle infinie, bug, etc.
Les programmeurs en C l'ont bien compris :
La condition est toujours une inégalité.
for (i=1; i<=4; i++)
Je regarde un peu ton code et je me fais les réflexions suivantes.
Il faut virer le GoTo, c'est comme ça. C'est non négociable.
Ensuite, deux If qui se suivent, c'est une clause de trop.
Enfin, une boucle Until avec deux bornes connues, ça me paraît louche. (à voir)
Ça donne :
Comme je préfère y voir mieux, je sors les tests imbriqués. Ça manquera d'efficacité, mais ce sera plus visible :
Bon, du premier coup d'oeil, j'ai envie de mettre une boucle pour cumuler les Temps_Deplac. COmme les quatre blocs se reseemblent, je les assemble (
). Ça donne :
Qu'en penses-tu ?
Te poses-tu toujours la question des 4 positions ?
Il faut virer le GoTo, c'est comme ça. C'est non négociable.
Ensuite, deux If qui se suivent, c'est une clause de trop.
Enfin, une boucle Until avec deux bornes connues, ça me paraît louche. (à voir)
Ça donne :
buffer_v = 0 counter = 1 Do Until counter = n_tools If counter + 1 <= n_tools And Temps_Deplac(counter + 1) < Temps_Op(counter) Then Buffer_Use(counter + 1) = 1 buffer_v = 1 If counter + 2 <= n_tools And Temps_Deplac(counter + 2) + Temps_Deplac(counter + 1) < Temps_Op(counter) Then Buffer_Use(counter + 2) = 1 buffer_v = 2 If counter + 3 <= n_tools And Temps_Deplac(counter + 3) + Temps_Deplac(counter + 2) + Temps_Deplac(counter + 1) < Temps_Op(counter) Then Buffer_Use(counter + 3) = 1 buffer_v = 3 If counter + 4 <= n_tools And Temps_Deplac(counter + 4) + Temps_Deplac(counter + 3) + Temps_Deplac(counter + 2) + Temps_Deplac(counter + 1) < Temps_Op(counter) Then Buffer_Use(counter + 4) = 1 buffer_v = 4 End If End If End If End If counter = counter + buffer_v + 1 buffer_v = 0 If counter >= n_tools Then Exit Do Loop
Comme je préfère y voir mieux, je sors les tests imbriqués. Ça manquera d'efficacité, mais ce sera plus visible :
buffer_v = 0 counter = 1 Do Until counter = n_tools If counter + 1 <= n_tools And Temps_Deplac(counter + 1) < Temps_Op(counter) Then Buffer_Use(counter + 1) = 1 buffer_v = 1 End If If counter + 2 <= n_tools And Temps_Deplac(counter + 2) + Temps_Deplac(counter + 1) < Temps_Op(counter) Then Buffer_Use(counter + 2) = 1 buffer_v = 2 End If If counter + 3 <= n_tools And Temps_Deplac(counter + 3) + Temps_Deplac(counter + 2) + Temps_Deplac(counter + 1) < Temps_Op(counter) Then Buffer_Use(counter + 3) = 1 buffer_v = 3 End If If counter + 4 <= n_tools And Temps_Deplac(counter + 4) + Temps_Deplac(counter + 3) + Temps_Deplac(counter + 2) + Temps_Deplac(counter + 1) < Temps_Op(counter) Then Buffer_Use(counter + 4) = 1 buffer_v = 4 End If counter = counter + buffer_v + 1 buffer_v = 0 If counter >= n_tools Then Exit Do Loop
Bon, du premier coup d'oeil, j'ai envie de mettre une boucle pour cumuler les Temps_Deplac. COmme les quatre blocs se reseemblent, je les assemble (
). Ça donne :
Dim tdc As Integer ' // Temps_Deplac_Cumulé Dim position As Integer Dim i As Integer buffer_v = 0 counter = 1 Do Until counter = n_tools For position = 1 To 4 tdc = 0 For i = 0 To position - 1 tdc = tdc + Temps_Deplac(counter + i) Next If counter + position <= n_tools And tdc < Temps_Op(counter) Then Buffer_Use(counter + position) = 1 buffer_v = position End If Next counter = counter + buffer_v + 1 buffer_v = 0 If counter >= n_tools Then Exit Do Loop
Qu'en penses-tu ?
Te poses-tu toujours la question des 4 positions ?
Merci pour cette réponse très constructive
Je viens de tester avec ton code. Cela marche jusqu'à ce que Temps_Deplac(counter + i) sorte du tableau. Il faut donc que je rajoute une condition pour pas que counter+i dépasse n_tools (et non pas seulement n_tools).
Sinon j'ai l'impression que ton code fais la somme de 4 cases automatiquement puis compare si le temps est inférieur. Or le but serait de comparer le premier élément, puis le premier + le deuxième, puis on rajoute le troisième, etc jusqu'à ce que la somme soit supérieure.
Est-ce ce qui est réalisé ? Car je ne sais pas trop l'effet du Next en ligne 13.
Je viens de tester avec ton code. Cela marche jusqu'à ce que Temps_Deplac(counter + i) sorte du tableau. Il faut donc que je rajoute une condition pour pas que counter+i dépasse n_tools (et non pas seulement n_tools).
Sinon j'ai l'impression que ton code fais la somme de 4 cases automatiquement puis compare si le temps est inférieur. Or le but serait de comparer le premier élément, puis le premier + le deuxième, puis on rajoute le troisième, etc jusqu'à ce que la somme soit supérieure.
Est-ce ce qui est réalisé ? Car je ne sais pas trop l'effet du Next en ligne 13.
Oui, il faut sans doute vérifier les bornes mieux que je ne le faisais.
M'enfin, il y a deux boucles For imbriquées. Donc la première itère de 1 à 4, l'autre dépend de la première. Regarde bien les lignes 11 à 13.
En fait, je dois ne pas bien comprendre la problématique. Je me fie trop à ton code.
Essaie d'expliquer un peu mieux ton problème, sans te (nous) perdre avec trop de détails.
Mieux, c'est-à-dire au sens "mathématique".
M'enfin, il y a deux boucles For imbriquées. Donc la première itère de 1 à 4, l'autre dépend de la première. Regarde bien les lignes 11 à 13.
En fait, je dois ne pas bien comprendre la problématique. Je me fie trop à ton code.
Essaie d'expliquer un peu mieux ton problème, sans te (nous) perdre avec trop de détails.
Mieux, c'est-à-dire au sens "mathématique".
Alors le problème vu simplement :
Parcourir un tableau (Temps_Deplac) dans l'ordre en additionnant les valeurs des cases jusqu'à ce que la somme soit le plus proche mais toujours inférieure à une case d'un autre tableau (Temps_op). Lorsque que l'on atteint cette limite, on repars dans chaque tableau à la case suivante de la dernière utilisée. En même temps on remplit un autre tableau (Buffer_Use) avec des 1 pour chaque élément du tableau Temps_Deplac qui a été utilisé dans la somme.
En rajoutant la condition pour éviter de sortir du tableau, et en ayant remplacé le 4 par une variable d'entrée, il me semble que ça marche
Après est-ce que l'ensemble fait quelque chose de logique ... Ca c'est mon problème.
Merci zeb tu m'as bien aidé sur ce coup-là. Mais peut-être que j'aurai d'autres problèmes sous peu donc je dis pas au revoir si vite
Parcourir un tableau (Temps_Deplac) dans l'ordre en additionnant les valeurs des cases jusqu'à ce que la somme soit le plus proche mais toujours inférieure à une case d'un autre tableau (Temps_op). Lorsque que l'on atteint cette limite, on repars dans chaque tableau à la case suivante de la dernière utilisée. En même temps on remplit un autre tableau (Buffer_Use) avec des 1 pour chaque élément du tableau Temps_Deplac qui a été utilisé dans la somme.
En rajoutant la condition pour éviter de sortir du tableau, et en ayant remplacé le 4 par une variable d'entrée, il me semble que ça marche
Après est-ce que l'ensemble fait quelque chose de logique ... Ca c'est mon problème.
Merci zeb tu m'as bien aidé sur ce coup-là. Mais peut-être que j'aurai d'autres problèmes sous peu donc je dis pas au revoir si vite
Mon programme a l'air stable avec cette solution, je la conserve donc jusqu'à nouvel ordre. Le problème est résolu puisque je sais comment faire en sorte de changer le 4. Il me fallait surtout savoir comment assembler les conditions comme tu l'as fait. Merci beaucoup ! J'ai même corrigé les histoires d'inégalités
Lassé par la pub ? Créez un compte
- Contenus similaires :
- ForumMacro fonction si vba
- ForumExcel fonction vba
- ForumInserer fonction vba
- ForumAppeler une fonction vba
- ForumArguments d'une fonction vba
- ForumFonction vba case
- ForumLancer une fonction en vba excel
- ForumListe fonction vba excel
- ForumUtiliser une fonction sous vba en excel
- ForumPointeur fonction vba excel
- Voir plus