[VBA] Conserver les valeurs d'une fonction

10 réponses
Avatar
HD
Bonjour,

En vba, j'ai crée une nouvelle fonction que j'utilise dans mes feuilles de
calcul...

Public Function Moncalcul(Cpt1 As String, Optional nCpt2 As String)
On Error Resume Next
Application.Volatile
~ mes calculs...
End function

J'utilise donc cette fonction par exemple comme ici:
=Moncalcul(701;702)
qui par exemple va me ressortir en résultat : 12
Je voudrais que sous certaines conditions, que ma fonction ne se recalcule
pas mais conserve sa valeur même si l'on appui sur F9 pour forcer le
recalcul... Le souci est que si je rajoute dans ma fonction:
if sheets("toto").range('"A1") = 0 then exit function
alors moncalcul prend la valeur 0 et toutes mes cellules où je fais
référence à cette fonction ont alors la fonction qui renvoi 0...

Y'a-t-il un moyen de courcircuiter le recalcul de fonction vba ? sans
courcircuiter pour autant le recacul de valeurs dans les cellules (style =
A1 + A2)...

Merci d'avance pour votre aide
--
@+
HD

10 réponses

Avatar
LSteph
Bonjour,

amha la réponse serait probablement dans une solution à adopter dans
le
~ mes calculs...


en remplacement et au regard du besoin qui te pousserait à mettre
ce if sheets("toto").range('"A1") = 0 then exit function

Mais qui selon les informations actuelles dans le fil demeure un
mystère!?.......

@bientôt.

--
lSteph

On 14 sep, 15:40, "HD" wrote:
Bonjour,

En vba, j'ai crée une nouvelle fonction que j'utilise dans mes feuilles de
calcul...

Public Function Moncalcul(Cpt1 As String, Optional nCpt2 As String)
On Error Resume Next
    Application.Volatile
 ~ mes calculs...
End function

J'utilise donc cette fonction par exemple comme ici:
=Moncalcul(701;702)
qui par exemple va me ressortir en résultat : 12
Je voudrais que sous certaines conditions, que ma fonction ne se recalcul e
pas mais conserve sa valeur même si l'on appui sur F9 pour forcer le
recalcul... Le souci est que si je rajoute dans ma fonction:
if sheets("toto").range('"A1") = 0 then exit function
alors moncalcul prend la valeur 0 et toutes mes cellules où je fais
référence à cette fonction ont alors la fonction qui renvoi 0...

Y'a-t-il un moyen de courcircuiter le recalcul de fonction vba ? sans
courcircuiter pour autant le recacul de valeurs dans les cellules (style =
A1 + A2)...

Merci d'avance pour votre aide
--
@+
HD


Avatar
michdenis
Bonjour HD,

Pourquoi ne pas expliquer ce que tu tentes de faire ? Il y
a peut-être plus d'une manière d'arriver à une solution acceptable !



"HD" a écrit dans le message de groupe de discussion :
h8lh4v$l48$
Bonjour,

En vba, j'ai crée une nouvelle fonction que j'utilise dans mes feuilles de
calcul...

Public Function Moncalcul(Cpt1 As String, Optional nCpt2 As String)
On Error Resume Next
Application.Volatile
~ mes calculs...
End function

J'utilise donc cette fonction par exemple comme ici:
=Moncalcul(701;702)
qui par exemple va me ressortir en résultat : 12
Je voudrais que sous certaines conditions, que ma fonction ne se recalcule
pas mais conserve sa valeur même si l'on appui sur F9 pour forcer le
recalcul... Le souci est que si je rajoute dans ma fonction:
if sheets("toto").range('"A1") = 0 then exit function
alors moncalcul prend la valeur 0 et toutes mes cellules où je fais
référence à cette fonction ont alors la fonction qui renvoi 0...

Y'a-t-il un moyen de courcircuiter le recalcul de fonction vba ? sans
courcircuiter pour autant le recacul de valeurs dans les cellules (style A1 + A2)...

Merci d'avance pour votre aide
--
@+
HD
Avatar
HD
Alors en fait... je colle des données sur une feuille A.

A partir de ces données, j'ai ma fonction Moncalcul qui va récupérer
certaines données de cette feuille, suivant certains critères, pour les
cumuler.

Tant que la feuille A n'a pas eû ses données de modifiées inutile de
recalculer les fonctions Moncalcul... Or, à chaque recalcul du classeur ces
fonctions sont recalculées... ce qui prend pas mal de temps.

J'ai mis un indicateur de modification sur une feuillle et je voudrais que
les fonctions Moncalcul ne soient recalculées que si cet indicateur est sur
1.

En fait si cet indicateur est à 1, la fonction doit être volatile, si elle
n'est pas à 1 alors elle ne doit pas être recalculée et ne doit pas être
volatile... Mais mon souci est que si une cellule fait référence à cette
fonction et à une valeur ou une cellule alors la fonction n'est certe pas
recalculée maus retourne 0...

Exemple:
Si l'application n'est pas volatile alors si j'ai dans une cellule
"=Moncalcul(a;b)" avec comme valeur retournée 10120 alors j'aurais bien
encore cette valeur...
Mais si j'ai dans une cellule "=Moncalcul(a;b)+10" avec comme résultat 10130
(avant recalcul) alors le résultat de Moncalcul sera 0 et j'aurais comme
valeur dans la cellule 10...

@+
HD
Avatar
LSteph
ou alors selon ton besoin, au lieu d'appuyer sur F9 et mettre une
fonction
Conditionner le renvoi du résultat et non d'une formule par macro...
pour chaque cellule selon le rapport qu'il y aurait avec toto!A1

On 14 sep, 15:51, LSteph wrote:
Bonjour,

amha la réponse serait probablement dans une  solution à adopter da ns
le>  ~ mes calculs...

en remplacement et au regard du besoin qui te pousserait à mettre
ce if sheets("toto").range('"A1") = 0 then exit function

Mais qui selon les informations actuelles dans le fil demeure un
mystère!?.......

@bientôt.

--
lSteph

On 14 sep, 15:40, "HD" wrote:



> Bonjour,

> En vba, j'ai crée une nouvelle fonction que j'utilise dans mes feuill es de
> calcul...

> Public Function Moncalcul(Cpt1 As String, Optional nCpt2 As String)
> On Error Resume Next
>     Application.Volatile
>  ~ mes calculs...
> End function

> J'utilise donc cette fonction par exemple comme ici:
> =Moncalcul(701;702)
> qui par exemple va me ressortir en résultat : 12
> Je voudrais que sous certaines conditions, que ma fonction ne se recalc ule
> pas mais conserve sa valeur même si l'on appui sur F9 pour forcer le
> recalcul... Le souci est que si je rajoute dans ma fonction:
> if sheets("toto").range('"A1") = 0 then exit function
> alors moncalcul prend la valeur 0 et toutes mes cellules où je fais
> référence à cette fonction ont alors la fonction qui renvoi 0...

> Y'a-t-il un moyen de courcircuiter le recalcul de fonction vba ? sans
> courcircuiter pour autant le recacul de valeurs dans les cellules (styl e =
> A1 + A2)...

> Merci d'avance pour votre aide
> --
> @+
> HD- Masquer le texte des messages précédents -

- Afficher le texte des messages précédents -


Avatar
HD
Voilà un exemple de ce que j'ai :

Public Function Moncalcul(Cpt1 As String, Cpt2 As String)
On Error Resume Next
Dim i As Long
i = 1

If Sheets("Param").Range("A1").Value = 0 Then 'Indicateur de recalcul
Exit Function
Else
Moncalcul = 0
Application.Volatile
End If

Do
If Sheets("MaFeuilledeDonnées").Cells(i, 1).Value = Cpt1 Then
Moncalcul = Moncalcul + Sheets("MaFeuilledeDonnées").Cells(i,
2).Value
End If
If Sheets("MaFeuilledeDonnées").Cells(i, 1).Value = Cpt2 Then
Moncalcul = Moncalcul + Sheets("MaFeuilledeDonnées").Cells(i,
3).Value
End If
i = i + 1
Loop Until Sheets("MaFeuilledeDonnées").Cells(i, 1).Value = ""
End Function

Avec une cellule avec !
=Moncalcul(a;b)
si j'ai d'origine 1020 en résultat... Je voudrais pouvoir faire un recalcul
du classeur tout en conservant cette valeur sans avoir à la recalculer...
pour éviter une perte de temps...
mais si j'ai dans une cellule :
=Moncalcul(a;b)+10
qui me donne 1030 en résultat... alors si je recalcul le classeur, Moncalcul
va me ressortir 0 en résultat et j'aurais alors dans ma cellule la valeur
10... d'où problème... :-(

@+
HD
Avatar
LSteph
Bonjour,

(C'est pratiquement la même chose en plus long mais sans en dire
davantage sur le moncalcul de "certaines données").

Malgré tout si l'on suit tes explications:
Hyp.0
a priori si les données n'ont pas été modifiées et qu'elle sont
recalculées ce qui suppose donc que tu laisses le calcul
s'opèrer et que tu ne pose pas d'exit function

Pourquoi la fonction moncalcul ne continuerait-elle pas à donner le
bon résultat qu'elle donnait déjà avant?

Hyp.1
les données ont été modifiées, la fonction renvoie le résultat qu 'elle
doit!

...???

--
lSteph


On 14 sep, 16:13, "HD" wrote:
Alors en fait... je colle des données sur une feuille A.

A partir de ces données, j'ai ma fonction Moncalcul qui va récupére r
certaines données de cette feuille, suivant certains critères, pour l es
cumuler.

Tant que la feuille A n'a pas eû ses données de modifiées inutile d e
recalculer les fonctions Moncalcul... Or, à chaque recalcul du classeur ces
fonctions sont recalculées... ce qui prend pas mal de temps.

J'ai mis un indicateur de modification sur une feuillle et je voudrais qu e
les fonctions Moncalcul ne soient recalculées que si cet indicateur est sur
1.

En fait si cet indicateur est à 1, la fonction doit être volatile, si elle
n'est pas à 1 alors elle ne doit pas être recalculée et ne doit pas être
volatile... Mais mon souci est que si une cellule fait référence à cette
fonction et à une valeur ou une cellule alors la fonction n'est certe p as
recalculée maus retourne 0...

Exemple:
Si l'application n'est pas volatile alors si j'ai dans une cellule
"=Moncalcul(a;b)" avec comme valeur retournée 10120 alors j'aurais bi en
encore cette valeur...
Mais si j'ai dans une cellule "=Moncalcul(a;b)+10" avec comme résulta t 10130
(avant recalcul) alors le résultat de Moncalcul sera 0 et j'aurais comm e
valeur dans la cellule 10...

@+
HD


Avatar
michdenis
A ) Tu enlèves "Volatile" de ces fonctions et lorsque tu désires
les calculer, tu utilises le raccourci clavier F9

B ) Au lieu d'utiliser des constantes comme paramètre de tes fonctions,
si tu pouvais utiliser des paramètres comme étant des adresses de
cellules où se trouvent tes données, ta fonction se recalculerait seulement
lorsque tu modifies l'une de ces cellules...
Public Function Moncalcul(Cpt1 As Range , Cpt2 As Range)

C ) les autres alternatives, ça relève plus à d'une usine au gaz !



"HD" a écrit dans le message de groupe de discussion :
h8ljhb$lsu$
Voilà un exemple de ce que j'ai :

Public Function Moncalcul(Cpt1 As String, Cpt2 As String)
On Error Resume Next
Dim i As Long
i = 1

If Sheets("Param").Range("A1").Value = 0 Then 'Indicateur de recalcul
Exit Function
Else
Moncalcul = 0
Application.Volatile
End If

Do
If Sheets("MaFeuilledeDonnées").Cells(i, 1).Value = Cpt1 Then
Moncalcul = Moncalcul + Sheets("MaFeuilledeDonnées").Cells(i,
2).Value
End If
If Sheets("MaFeuilledeDonnées").Cells(i, 1).Value = Cpt2 Then
Moncalcul = Moncalcul + Sheets("MaFeuilledeDonnées").Cells(i,
3).Value
End If
i = i + 1
Loop Until Sheets("MaFeuilledeDonnées").Cells(i, 1).Value = ""
End Function

Avec une cellule avec !
=Moncalcul(a;b)
si j'ai d'origine 1020 en résultat... Je voudrais pouvoir faire un recalcul
du classeur tout en conservant cette valeur sans avoir à la recalculer...
pour éviter une perte de temps...
mais si j'ai dans une cellule :
=Moncalcul(a;b)+10
qui me donne 1030 en résultat... alors si je recalcul le classeur, Moncalcul
va me ressortir 0 en résultat et j'aurais alors dans ma cellule la valeur
10... d'où problème... :-(

@+
HD
Avatar
LSteph
...dans ce cas enlève le calcul automatique dans Outils Option, le
Volatile de ta fonction
tu appuieras sur F9 lorsque tu veux recalculer.

et à la limite déclenche une Sub à la place de la fonction pour
mettre le bon résultat dans la cellule.

--
lSteph

On 14 sep, 16:21, "HD" wrote:
Voilà un exemple de ce que j'ai :

Public Function Moncalcul(Cpt1 As String, Cpt2 As String)
On Error Resume Next
    Dim i As Long
    i = 1

    If Sheets("Param").Range("A1").Value = 0 Then 'Indicateur de re calcul
        Exit Function
    Else
        Moncalcul = 0
        Application.Volatile
    End If

    Do
        If Sheets("MaFeuilledeDonnées").Cells(i, 1).Value = C pt1 Then
            Moncalcul = Moncalcul + Sheets("MaFeuilledeDonn ées").Cells(i,
2).Value
        End If
        If  Sheets("MaFeuilledeDonnées").Cells(i, 1).Value = Cpt2 Then
            Moncalcul = Moncalcul + Sheets("MaFeuilledeDonn ées").Cells(i,
3).Value
        End If
        i = i + 1
    Loop Until Sheets("MaFeuilledeDonnées").Cells(i, 1).Value = " "
End Function

Avec une cellule avec !
=Moncalcul(a;b)
si j'ai d'origine 1020 en résultat... Je voudrais pouvoir faire un reca lcul
du classeur tout en conservant cette valeur sans avoir à la recalculer. ..
pour éviter une perte de temps...
mais si j'ai dans une cellule :
=Moncalcul(a;b)+10
qui me donne 1030 en résultat... alors si je recalcul le classeur, Monc alcul
va me ressortir 0 en résultat et j'aurais alors dans ma cellule la vale ur
10... d'où problème... :-(

@+
HD


Avatar
HD
> Hyp.0
a priori si les données n'ont pas été modifiées et qu'elle sont
recalculées ce qui suppose donc que tu laisses le calcul
s'opèrer et que tu ne pose pas d'exit function
Pourquoi la fonction moncalcul ne continuerait-elle pas à donner le
bon résultat qu'elle donnait déjà avant?


Elle redonne le bon résultat... mais je voudrais justement courcircuiter ce
recalcul de fonctions perso (ce que les anglo-saxons nomme UDF) pour gagner
du temps (le classeur peut mettre 1 à 5 minutes à recalculer ces
fonctions)... car si les données de la feuille d'origine n'ont pas été
modifiées il n'y aurait alors pas de raison de recalculer ces UDF... par
contre, les données des autres feuilles qui peuvent être utilisées dans une
formule peuvent nécessiter le recalcul de cette formule... Exemple:
Si la feuille de données n'a pas vue ses données de modifiées alors inutile
de recalculer une cellule dont la formule serait:
= Moncalcul(1;10)
Mais si, dans les même conditions j'ai en formule :
= Moncalcul(1;10) + A1
il est possible que la valeur de A1 ai changé et il faut alors recalculer
A1... Le souci est que si la cellule en question est recalculée c'est alors
l'ensemble de la formule qui sera recalculée et avec les conditions que j'ai
mis dans ma fonction le résultat obtenu est la valeur de A1... et je n'ai
alors pas Moncalcul de recalculé...

P.S: on a du mal à se comprendre... et c'est vrai que le souci que j'ai
n'est pas facile à expliquer lol

@+
HD
Avatar
HD
>A ) Tu enlèves "Volatile" de ces fonctions et lorsque tu désires
les calculer, tu utilises le raccourci clavier F9
B ) Au lieu d'utiliser des constantes comme paramètre de tes fonctions,
si tu pouvais utiliser des paramètres comme étant des adresses de
cellules où se trouvent tes données, ta fonction se recalculerait
seulement
lorsque tu modifies l'une de ces cellules...
Public Function Moncalcul(Cpt1 As Range , Cpt2 As Range)



Ok.... J'ai viré tout les "Volatile" de mes fonctions... et... j'ai ajouté
dans mes fonctions une adresse de cellule (indicateur de modification)...
j'ai dû pour celà changer mes formules (en passant par un Ctrl+h pour aller
plus vite)... et au final effectivement ça roule !!!
(à un moment donné j'ai du m'embrouyer en laissant des "volatile" sur
certaines fonctions ce qui fait que j'avais l'impression que ce n'était pas
efficace...)

Je voulais éviter de modifier les formules (car je peux en avoir un gros
paquet... et je voulais les utiliser telles quelles car j'ai réalisé du vba
pour compenser la migration prochaine d'un logiciel (où l'ancien logiciel
utilisait de l'OLE pour transmettre les données via une macro complémentaire
liée)... mais je serais obligé de passer par un minimum de modifications...

C'est donc probablement la meilleure solution...

En tout cas, un grand MERCI à vous deux lol

@+
HD