web-dev-qa-db-fra.com

Appliquer une formule n fois sans utiliser VBA?

J'ai les cellules suivantes:

A1:

justsometext

B1:

3

C1:

=DOSOMETHING(A1)

Je veux appliquer la formule dans C1 n fois (n étant 3, la valeur dans B1), donc dans ce cas, cela voudrait dire:

C1:

=DOSOMETHING(DOSOMETHING(DOSOMETHING(A1)))

Est-il possible de le faire sans macro, peut-être en utilisant des formules de tableau?

METTRE À JOUR:

Le nombre de répétitions ne sera pas toujours 3, mais changera dans le temps et/ou différera d'une ligne à l'autre.

Voici un exemple simple de ce à quoi il devrait ressembler:

Screenshot of example worksheet

Veuillez noter que la solution devrait fonctionner pour toutes les formules , et pas seulement pour ajouter une chaîne constante comme dans l'exemple.

6
Scripter22

Ensuite, j'utiliserais = Value & REPT("_checked", NoOfExecutions).

Si vous avez toujours besoin de faire des choses comme celle de l'exemple (concaténation de chaînes), cela fonctionne plutôt bien.

Si vous devez utiliser d'autres formules, voici ce à quoi je peux penser:

  • nous séparons la fonction que vous devez utiliser: débutant (tout ce qui doit précéder l'argument principal) et fin (tout ce qui suit l'argument, y compris les arguments supplémentaires). Par exemple, si nous utilisons la fonction LEFT(value, 2), LEFT( ira au début, , 2) à la fin.

  • nous construisons la formule sous forme de texte avec concaténation et REPT. En vous référant à l'exemple de l'image, la formule de la cellule C6 sera: = "=" &REPT($B$2,B6) & $A6 & REPT($B$3,$B6)

  • Ensuite, vous devez copier la cellule et la coller en tant que valeurs dans la cellule D6; Cliquez ensuite sur la formule dans la barre de formule et appuyez sur la touche Entrée de votre clavier.

C'est quelques étapes mais cela évite VBA.

Example Picture

5
VFor

Non, désolé, cela n’est pas possible dans le cas général pour aucune formule et sa mise à jour automatique. Sans utiliser VBA, c'est.

Cependant, cela peut être effectué pour un très petit nombre de formules spécifiques (comme la concaténation d'une chaîne constante). Cela peut également être fait, mais avec une mise à jour manuelle, pour un certain ensemble de formules, comme le montre astucieusement la réponse de VFor .

Le plus proche d'une solution générale consiste à réorganiser les cellules, à incorporer la formule DOSOMETHING dans une formule d'encapsulation spéciale et à utiliser des colonnes auxiliaires.

Pour votre exemple de feuille de calcul fourni:

Worksheet screenshot showing OP example

Réorganisez comme ceci:

Worksheet screenshot showing rearrangement

Entrez la formule suivante dans D2 et ctrl-entrez/copiez-collez/remplissez en bas et à droite/remplissez automatiquement dans le reste des colonnes du tableau:

=IF(COLUMN()-COLUMN($C2)>$A2,"§",C2&"_checked")

Entrez la formule suivante dans B2 et ctrl-enter/copier/coller/remplir/descendre/remplir automatiquement dans le reste de la colonne du tableau:

=INDEX(C2:INDEX(2:2,1,COLUMNS(2:2)),MATCH("§",C2:INDEX(2:2,1,COLUMNS(2:2)),0)-1)


Notez que le nombre de colonnes auxiliaires requis est la valeur maximale autorisée de n plus un. S'il n'y en a pas assez pour une valeur entrée, une erreur s'ensuit:

Worksheet screenshot showing error

Explication:

La formule d'emballage généralisée pour les colonnes d'assistance est la suivante:

=IF(COLUMN()-COLUMN($C2)>$A2,"§",DOSOMETHING(C2))

DOSOMETHING(C2) est une formule quelconque basée uniquement sur C2 (par exemple, LEFT(C2,LEN(C2)-1) qui supprime progressivement le dernier caractère).

La formule d'emballage fonctionne en opérant sur la cellule à gauche, "imbriquant" ainsi les formules plus loin à droite dans la ligne correspondante.

La partie IF(COLUMN()-COLUMN($C2)>$A2,"§", utilise les index de colonne pour décompter le nombre de fois où la formule DOSOMETHING est imbriquée et une fois que le nombre de fois spécifié dans la colonne A est atteinte, elle génère des chaînes de terminaison. Ces chaînes ne doivent pas nécessairement être §. Ils doivent simplement être quelque chose qui ne sera jamais le résultat de l'évaluation d'un nombre quelconque de formules imbriquées pour une variable Value admissible.


La formule Result semble plus délicate. Cependant, les parties C2:INDEX(2:2, 1, COLUMNS(2:2)) sont simplement la sous-plage de la ligne 2 située à droite de la colonne Result.

La formule est donc essentiellement la même que:

=INDEX(2:2,MATCH("§",2:2,0)-1)

ce qui le rend plus facile à comprendre.

(Notez que cette formule fonctionne réellement si les calculs itératifs sont activés.)

En regardant cette formule plus simple, il est clair que la formule retourne le résultat de la fonction DOSOMETHING imbriquée à n niveaux.

4
robinCTS

Pour appliquer une formule dans la cellule `C1 'n Nombre de fois où vous devez appliquer une itération.

enter image description here

Comment ça marche:

  1. Cliquez sur Fichier , Option puis Formule .
  2. Rechercher Activez la case à cocher Calcul itératif et cochez-la simplement.
  3. Pour Itérations maximales , écrivez la valeur, par exemple 5.
  4. Écrivez cette formule dans la cellule C1

=B1+C1

Vous trouvez qu'Excel calcule la formule dans C1 cinq fois.

Vous pouvez définir une nouvelle valeur autant de fois que nécessaire, en suivant les étapes à partir de 1 to 3..

0
Rajesh S

Cela peut être fait via les fonctions Evaluer et Rept.

L’évaluation ne peut être appelée que via le gestionnaire de noms, voir
évalue la fonction . Evalute évalue une chaîne en tant que formule. Ainsi, tout ce qui peut être construit en tant que chaîne peut être utilisé en tant que formule.

  • Appuyez sur Ctrl + F3, appuyez sur Nouveau ...

  • Dans le champ Nom, nommez votre fonction (par exemple, répéteur).

  • Dans le champ Référence, écrivez votre formule en utilisant Rept: = Evaluate (rept ("péché (", b2) & a2 & rept (")", b2))

  • et dans votre cellule, vous utilisez = Répéteur et spécifiez le nombre de répétitions dans B2 et le paramètre dans A2

C'est un peu délicat, donc une formule définie par l'utilisateur dans VBA pourrait être plus facile

0
Stefan

Cela peut sembler un peu fou, mais c'est un hack qui pourrait aider.

Supposons que la colonne A contient toutes les valeurs de texte et que la colonne B présente le nombre d'itérations souhaité. Supposons également qu'il existe une valeur maximale pour la colonne B, telle que 4, par souci d'explication. Si vous ne pouvez pas avoir une valeur maximale pour la colonne B, cela ne fonctionnera pas.

Tout d'abord, ajoutez une ligne en haut qui porte les numéros 1 à 4 en haut des colonnes C, D, E et F. Dans la cellule C2, insérez une formule comme celle-ci: =IF(C$1=$B2,DOSOMETHING(A2),"") (pour la dernière partie de cette formule, inscrivez ,"") si vous travaillez avec des chaînes, et ,0) si vous travaillez avec des nombres).

Puis dans D2, mettez =IF(C$1=$B2,DOSOMETHING(DOSOMETHING(A2)),""). Et ainsi de suite pour E2 et F2. Maintenant, si vous copiez les cellules C2 - F2 et les collez dans les colonnes C - F, vous obtiendrez cette matrice étrange où tout est vide (ou zéro) à l’exception des colonnes où vous avez la valeur souhaitée en fonction du nombre d’itérations. dans la colonne B.

Maintenant, pour la dernière colonne (la colonne G dans mon exemple), concaténez (ou sommez, si vous utilisez des nombres) les quatre colonnes précédentes pour obtenir l’ensemble de valeurs dont vous avez besoin dans une colonne. Masquez éventuellement les quatre colonnes de calcul.

Comme ça:

enter image description here

0
Todd Wilcox

Je pense que cela est possible dans le cas général (avec récursion)!

Nous devons essentiellement configurer un système dans lequel une cellule de compteur (avec une référence à elle-même) compte jusqu'au nombre d'appels de fonction et chaque fois que le nombre change, la fonction est exécutée à nouveau.

Maintenant, pour que ce soit plus clair, j'utilise des formules de table. Ma table ressemble à ceci au début:

enter image description here

La première étape consiste à créer le compteur - la colonne Current State contient cette

=IFS(
    resetSwitch,
    [@[Counter Initial State]],
    [@[Current State]] >= [@[Count To]],
    [@[Current State]],
    TRUE,
    [@[Current State]] + 1
)

Qui lit

Si le paramètre resetSwitch a la valeur True, passez à l'état initial, sinon continuez à augmenter la valeur de cette cellule jusqu'à atteindre la valeur finale ([@[Count To]]).

Maintenant, pour déterminer s’il faut appliquer la formule (dans la colonne Recursor), nous devons savoir si le compteur est en augmentation (Current State <Count To), si oui, nous appliquons la formule. Une façon de procéder consiste à obtenir l'état précédent du compteur. Si ce dernier est différent de l'état actuel, le compteur augmente, sinon il a atteint sa valeur finale.

La colonne Previous State contient

=IFS(
    [@[Current State]] = [@[Counter Initial State]],
    [@[Counter Initial State]],
    [@[Current State]] < [@[Count To]],
    [@[Current State]],
    AND(
        [@[Count To]] = [@[Current State]],
        [@[Previous State]] < [@[Current State]] - 1
    ),
    [@[Previous State]] + 1,
    TRUE,
    [@[Count To]]
)

Ce qui se lit:

Si le compteur est à l'état initial, il doit l'avoir été auparavant. Si le compteur est actuellement inférieur à sa valeur finale, son état précédent était inférieur de un à son état actuel. Si le compteur est à son état final et que la valeur actuelle de l'état précédent ne l'est pas, l'état précédent devrait toujours être en augmentation. Si la valeur actuelle de l'état précédent est la valeur finale, le compteur est stable dans son état final

Cela prend un état d'esprit non-Excel pour comprendre, je pense, mais je crois que cela fonctionne. Previous State est essentiellement une itération derrière Current State (comme son nom l'indique)

Enfin, nous devons appliquer la formule à chaque fois que l'état précédent <> indique l'état actuel du compteur (le compteur augmente actuellement). Cela donne la formule en Recursor

=IFS(
    resetSwitch,
    [@[Reursor Initial State]],
    [@[Previous State]] < [@[Current State]],
    [@Recursor] & "_checked",
    TRUE,
    [@Recursor]
)

Où ici la formule à appliquer n fois est [@Recursor] & "_checked", mais pourrait être toute f([@Recursor]).

Définir resetSwitch sur FALSE fait tout fonctionner, ce qui entraîne

After clicking

0
Greedo