VBA - Insérer une formule dans une cellule

Résolu
Zefirin -  
 anonymous -
Bien le bonjour,

Je réussi généralement à trouver réponses à mes questions les plus complexes en naviguant mais là je suis dans une impasse.

Je tente d'insérer dans une cellule une formule qui valide si deux autres cellules ne sont pas vide avant d'effectuer un calcul de différence.

Voici la formule:

=SI(estvide(DAPB!B16);"";SI(estvide(Structurel!B16);"";Structurel!B16-DAPB!B16))

Voici le code:

'Identifier les feuilles de données
Set source1 = Sheets(Worksheets.Count).Range("B15")
Set source2 = Sheets(Worksheets.Count).Range("B15:H33")

'insérer la formule dans le tableau
Sheets(Worksheets.Count).Cells("B15").Value = "Formule a insérer"
source1.Copy Destination:=source2

Après plusieurs test, j'ai trouvé que c'est dans la ligne d'insertion de formule que ca plante
J'ai vraiment essayé plusieurs façons d'écrire la formule sans succes:

Doubler les guillemets:
=SI(estvide(DAPB!B16);"""";SI(estvide(Structurel!B16);"""";Structurel!B16-DAPB!B16))

Remplacer le estvide() par un égal:
=SI(DAPB!B16="""";"""";SI(Structurel!B16="""";"""";Structurel!B16-DAPB!B16))

J'ai également testé avec le code ascii des guillemets.

Merci de votre temps

11 réponses

  1. Mike-31 Messages postés 18405 Date d'inscription   Statut Contributeur Dernière intervention   5 147
     
    Salut,

    regarde comme cela

    =SI(ET(DAPB!B16<>"";Structurel!B16<>"");Structurel!B16-DAPB!B16;"")

    ou encore

    =SI(OU(ESTVIDE(DAPB!B16);ESTVIDE(Structurel!B16));"";Structurel!B16-DAPB!B16)

    A+
    Mike-31

    Une période d'échec est un moment rêvé pour semer les graines du savoir.
    1
  2. Utilisateur anonyme
     
    Bonjour,

    Suggestion :

    <code>
    Dim Formule As String

    '"=SI(estvide(DAPB!B16);"";SI(estvide(Structurel!B16);"";Structurel!B16-DAPB!B16))"

    Formule = "=SI(estvide(DAPB!B16);"
    Formule = Formule & """" & """"
    Formule = Formule & ";SI(estvide(Structurel!B16);"
    Formule = Formule & """" & """"
    Formule = Formule & ";Structurel!B16-DAPB!B16))"

    MsgBox Formule

    Cdt

    Lupin
    1
  3. Zefirin
     
    J'ai oublié de préciser que DAPB et Structurel sont les feuilles de référence pour la validation et le calcul.
    On est jamais trop clair en prog...
    0
  4. Paf
     
    bonjour,
    il suffit de remplacer les points virgules par des virgules !!!

    bonne suite
    0
  5. Vous n’avez pas trouvé la réponse que vous recherchez ?

    Posez votre question
  6. Zefirin
     
    Paf 25 mai 2012 à 19:15
    bonjour,
    il suffit de remplacer les points virgules par des virgules !!!


    Les fonctions SI() dans excel prennent des points-virgules pour séparer ses arguments. Il n'acceptent pas les simples virgules.

    Mike-31, j'apprécie ta réponse car en effet ma formule n'était pas optimale.

    Cependant, je pense que je me suis mal exprimé.
    Je sais que la formule fonctionne car je peux la copier/coller tel quel dans mon fichier excel et tout fonctionne.
    Je sais également que mon code fonctionne car je peux remplacer le string de la formule par un mot test tel que "Test" et il va afficher "Test" dans les bonnes cellules.
    Ce qui ne fonctionne pas, c'est que VBA n'est pas en mesure de lire avec succès le string:
    "=SI(estvide(DAPB!B16);"";SI(estvide(Structurel!B16);"";Structurel!B16-DAPB!B16))"

    L'erreur suivante m'est affiché sur la lecture de cette ligne:
    Erreur d'exécution '1004'
    Erreur définie par l'application ou par l'objet
    0
    1. Paf
       
      re bonjour,

      la fonction SI s'écrit avec des points virgules quand on l'écrit directement dans une cellule, mais si on veut passer par VBA, il faut remplacer les points virgules par une virgule!! c'est pas logique (du moins pour moi) mais dans la cellule on retrouve la formule avec ses points virgules!
      il suffit d'essayer

      pour s'en convaincre, enregistrer une macro: outre le nom des fonctions qui passe en anglais, il y a des virgules à la place des points virgules.
      (dans le code, on peut écrire les fonctions en français ça marche aussi )
      Bonne suite
      0
    2. Zefirin
       
      Je viens d'apprendre quelque chose. Merci pour l'explication, ta première réponse me rendait perplexe mais là je comprends.
      0
    3. Utilisateur anonyme
       
      Bonjour,

      si le cas est résolu, il serait souhaitable de le rendre Résolu :-)

      ... sous VBA, la formule reçu en lecture sera composé de virgule
      et réaffecter sous son Type spécifique VBA de cette même formule.

      mais si on effectue un copier/coller de la formule Excel, comme spécifié
      par Paf, il suffit de construire avec des virgules ( code anglais) du
      VBA.

      comme j'ai soulevé dans un autre message,

      https://forums.commentcamarche.net/forum/affich-25249792-vba-copier-formule-dans-colonne-sans-f-rc1c1

      la valeur reçu de VBA pour les propriétés ( FormulaR1C1 ) et ( Value )
      lorsque la cellule contient bien sur une formule :-)

      j'ai déjà fait le test en me basant sur le texte d'aide et un bouquin
      ce que je me rappelle de ma lecture, c'est que la propriété FormulaR1C1 est
      utilisé pour lire la formule qu'on peut affecter dans une variable
      string et de cette variable réaffecter à une autre cellule dans sa propriété ( Value ).

      Cdt

      Lupin
      0
  7. eriiic Messages postés 24581 Date d'inscription   Statut Contributeur Dernière intervention   7 281
     
    Bonjour tout le monde,

    en plus du remplacement des ; par la , je mettrai plutôt :
    Sheets(Worksheets.Count).Cells("B15").formulalocal= "Formule a insérer"
    au lieu de .Value

    Pourquoi , au lieu de ; ?
    En français la , sert de séparateur décimal et n'est pas disponible comme séparateur de liste et d'arguments.
    Les fonctions des feuilles ont été adaptées (d'ailleurs c'est un paramètre modifiable dans le panneau de configuration), vba n'a pas été localisé français et conserve sa ,
    eric
    0
    1. anonymous
       
      Changer la langue du clavier pour FR et tout fonctionnera !
      0
  8. Utilisateur anonyme
     
    Bonjour,

    Je comprends ton point de vue, mais la pratique m'a convaincu
    d'utiliser Value pour recevoir la formule car lorsque je construit
    une formule par VBA, si je tente d'affecter une formule erroné
    à l'une des propriétés Formula, FormulaLocal, FormulaR1C1,
    il y aura Erreur de Typage alors que Value le prend même avec
    l'erreur, puisqu'elle n'existe plus il s'agit simplement d'une
    string.

    Lupin
    0
    1. eriiic Messages postés 24581 Date d'inscription   Statut Contributeur Dernière intervention   7 281
       
      Bonjour,

      Effectivement, il le prend bien comme une formule et non un texte comme je pensais.
      J'ai bien fait d'intervenir, j'aurais appris qcq chose ;-)

      L'avantage de .formulalocal reste de pouvoir copier la formule d'une cellule et de la conserver en français dans vba, et éviter l'enregistreur de macro pour la traduire en anglais.


      eric
      0
  9. Utilisateur anonyme
     
    re:

    Voici les essais que j'ai fait sous Excel XP (2002)

        
    Option Explicit
    
    Sub Macro1()
    '
    ' Macro1 Macro
    ' Macro enregistrée le 2012-05-26 par Lupin
    '
    
    '
    '    ActiveCell.FormulaR1C1 = "=IF(RC[3] > 2,RC[1] * RC[2],2)"
    '    Range("B3").Select
        
        ' Erreur 1004
    '    Range("B4").FormulaLocal = "=IF(E2 > 2,C2 * D2,2)"
        
        ' Erreur 1004
    '    Range("B4").FormulaLocal = "=SI(E2 > 2,C2 * D2,2)"
    
        Range("B4").Value = "=IF(E2 > 2,C2 * D2,2)"
        
        Dim Expression As String
        
        Expression = Range("B4").Formula
        MsgBox Expression
        
    End Sub
    


    La première instruction placé en commentaire est
    fait par l'enregistreur de macro, ce qui est une
    position relative,pas très efficace à mon avis ...

    il suffit de fonctionner comme la première instruction
    qui n'est pas en commentaire. La chaine Expression
    est plus malléable que celle de l'enregistreur. :-)

    Enfin, je n'ai pas tout compris moi non plus, mais sous
    VBA j'ai toujours travaillé avec une affectation sur Value
    et une récupération sur Formula, FormulaLocal, FormulaR1C1

    Cdt

    Lupin
    0
    1. eriiic Messages postés 24581 Date d'inscription   Statut Contributeur Dernière intervention   7 281
       
      Bonjour,

      Je ne procède pas pareil.
      Je copie la formule écrite et testée sur la feuille (=SI(E2 > 2;C2 * D2;2)) et la colle telle que dans le .formulalocal.
      J'ai mes fonctions en français, mes ; restent (pas besoin de les changer en ,), mes références de type A1, et aucune erreur.

      Avec .value il faut quand même traduire les fonctions en anglais (pénalisant pour moi pour les fonctions moins communes sinon on repart sur l'enregistreur) et remplacer les ; par des , sinon #NOM ou erreur 1004

      eric
      0
  10. Utilisateur anonyme
     
    Bonjour,

    étrange, c'est à moi d'apprendre quelque chose :-)

    j'utilise l'enregistreur pour connaitre la traduction
    français anglais, mais je construit ainsi à partir
    de l'instruction en ajoutant un adressage relatif ou
    absolue pour créer la formule sous forme de String.

    je vais essayer ta technique, je suis curieux de savoir
    ce qu'il donneras en lecture sur la propriété FormulaLocal :-)

    Cdt

    Lupin
    0
    1. eriiic Messages postés 24581 Date d'inscription   Statut Contributeur Dernière intervention   7 281
       
      Re,

      j'utilise l'enregistreur pour connaitre la traduction français anglais
      Ce que je faisait avant de découvrir formulalocal ;-)

      eric
      0
  11. ccm81 Messages postés 11033 Statut Membre 2 434
     
    bonjour à tous

    est ce que ce ne serait pas un problème de guillemets, chez moi (je ne sais pas si c'est dû à excel 2003), je dois remplacer les guillemets encadrant une chaine vide par deux chr(34)

    pour obtenir ceci sur la feuille
    =SI(ESTVIDE(Feuil2!A1);"";Feuil2!A1)

    f = "=SI(ESTVIDE(Feuil2!A1);" & Chr(34) & "" & Chr(34) & ";Feuil2!A1)"
    fonctionne

    f = "=SI(ESTVIDE(Feuil2!A1);" & """" & ";Feuil2!A1)"
    ne fonctionne pas

    bonne suite
    0
    1. eriiic Messages postés 24581 Date d'inscription   Statut Contributeur Dernière intervention   7 281
       
      Bonjour,

      On double la " pour qu'elle ne soit pas considérée comme une fin de chaine par vba, mais comme le caractère ".

      f = "=SI(ESTVIDE(Feuil2!A1);" & """" & ";Feuil2!A1)"
      ne marche pas car il faudrait 6 guillemets :
      1" pour le début de chaine, 2"" pour la premiere ", 2 autres " pour la 2nde ", et une dernière pour indiquer la fin de chaine.

      "=SI(ESTVIDE(Feuil2!A1);" & """""" & ";Feuil2!A1)"
      fonctionne.

      que tu peux écrire directement :
      "=SI(ESTVIDE(Feuil2!A1);"""";Feuil2!A1) "
      2 doubles " (donc 4 au total) pour indiquer une double " (tu suis ? ;-) )

      eric



      eric
      0
    2. ccm81 Messages postés 11033 Statut Membre 2 434
       
      merci eric de ces précisions,
      as tu une explication à propos de la différence d'interprétation entre " et chr(34)
      en plus j'ai essayé ça qui marche aussi!
      f = "=SI(ESTVIDE(Feuil2!A1);" & Chr(34) & Chr(34) & ";Feuil2!A1)"
      bonne journée
      0
    3. eriiic Messages postés 24581 Date d'inscription   Statut Contributeur Dernière intervention   7 281
       
      Bonjour,

      Chr(34) ne risque pas d'être interprété comme une fin de chaine, on ne le double pas. Et il n'a pas besoin de " " en début et en fin de chaine.

      Pour avoir un caractère " :
      - soit chr(34)
      - soit "" (pour avoir 1 caractère ") mis entre 2 " de début et de fin de chaine
      c'est à dire : """"

      f = "=SI(ESTVIDE(Feuil2!A1);" & Chr(34) & Chr(34) & ";Feuil2!A1)"
      peut s'écrire :
      f = "=SI(ESTVIDE(Feuil2!A1);" & """" & """" & ";Feuil2!A1)"

      eric
      0
  12. Zefirin
     
    Merci à tous pour votre aide.

    Je ne serais dire qui règla mon problème car je me suis inspiré de toutes vos réponses et maintenant ça fonctionne.

    L'instruction FormulaLocal m'a permis de règler d'autres petites problèmes.

    Bonne journée à tous.
    0