Macro lente : remplacer vide par formule

Acturis

XLDnaute Nouveau
Bonjour à tous,

Je me permet de venir vers vous pour solliciter votre aide. Dans mon fichier excel j'ai besoin, via une macro, de remplacer toutes les cellules vides d'une plage par une formule RechercheV. J'ai construit une macro qui fonctionne (en cherchant sur internet), elle fonctionne, cependant je la trouve très lente car elle tourne environ 2 minutes pour une petite plage de 500 lignes au sein d'une colonne bien spécifique.

Voici le code :

VB:
Sub VPcleaning()
'
'
Sheets("Detailed Assessment").Select
     Dim I As Long
  With Sheets("Detailed Assessment")
  .Activate
    For I = 6 To 505
     If .Cells(I, 19) = "" Then
       .Cells(I, 19).FormulaR1C1 = "=IF(RC[-17]="""","""",VLOOKUP(RC[-17],Data!C[-18]:C[9],28,FALSE))"
     End If
    Next I
  End With

End Sub

Je ne m'y connais pas vraiment en macro. Voyez vous un moyen d’accélérer le processus ?

Le but étant de faire en sorte que si les cellules de la plage (S6;S505), S étant ma colonne 19, et bien le contenu soit automatiquement remplacé par la formule citée dans le code.
Avec mon code je pense que la macro check les cellules une par une, ce qui prend du temps.

Si vous avez un raccourci en tête je suis preneur.

Merci d'avance =)
 

Lone-wolf

XLDnaute Barbatruc
Bonsoir Acturis :), le Forum :)

Ici si possible met la formule
.Cells(5, 19).FormulaR1C1 = "=IF(RC[-17]="""","""",VLOOKUP(RC[-17],Data!C[-18]:C[9],28,FALSE))"

Ensuite
.Cells(5, 19).Copy .Cells(6, 19)
.Range("P6").AutoFill .Range("P6:505"), Type:=xlFillDefault
 

Acturis

XLDnaute Nouveau
Bonsoir Acturis :), le Forum :)

Ici si possible met la formule
.Cells(5, 19).FormulaR1C1 = "=IF(RC[-17]="""","""",VLOOKUP(RC[-17],Data!C[-18]:C[9],28,FALSE))"

Ensuite
.Cells(5, 19).Copy .Cells(6, 19)
.Range("P6").AutoFill .Range("P6:505"), Type:=xlFillDefault

Bonjour Lone-Wolf,
Merci pour ta réponse, en effet la macro est quasi instantanée :). Cependant on a perdu le check sur les cellules vides. En effet je souhaiterais que cette formule ne s'applique que dans les cellules vides de la plage. Tu aurais une idée ?

Voici le code modifié avec ton approche.

VB:
Sub VPcleaning()
'
'
Sheets("Detailed Assessment").Select
Dim I As Long
  With Sheets("Detailed Assessment")
  .Activate
.Cells(506, 19).FormulaR1C1 = "=IF(RC[-17]="""","""",VLOOKUP(RC[-17],Data!C[-18]:C[9],28,FALSE))"
.Cells(506, 19).Copy .Cells(6, 19)
.Range("S6").AutoFill .Range("S6:S505"), Type:=xlFillDefault

End With
    
End Sub

Merci
 

job75

XLDnaute Barbatruc
Bonsoir Acturis, Lone-wolf,
Code:
Sub VPcleaning()
On Error Resume Next 'si aucune SpecialCell
Sheets("Detailed Assessment").[S6:S505].SpecialCells(xlCellTypeBlanks) _
    = "=IF(RC[-17]="""","""",VLOOKUP(RC[-17],Data!C[-18]:C[9],28,FALSE))"
End Sub
A+
 

Acturis

XLDnaute Nouveau
J'ai suivi ton conseil, cela fonctionne mais la macro est vraiment super lente....avec 450 cellules de la plage vides, la macro a tournée 3 minutes.
N'y a t'il pas un moyen de faire comme dans ta première approche, mais en définissant une plage comme cela Range(Premiere cellule de la plage(S6;S505)vide:s505) ? En effet les cellules non vides seront toujours placées au début de la plage, et toutes les autres seront vides...par contre des vides il peut y en avoir 450, 200 ou 30 par exemple.

Dernier code avec tes conseils

VB:
Sub VPcleaning()
'
'
Sheets("Detailed Assessment").Select
Dim I As Long
  With Sheets("Detailed Assessment")
  .Activate
Dim plage As Range, cel As Range
Set plage = .Range("S6:S505")
.Cells(506, 19).FormulaR1C1 = "=IF(RC[-17]="""","""",VLOOKUP(RC[-17],Data!C[-18]:C[9],28,FALSE))"

For Each cel In plage
If cel = vbNullString Then .Cells(506, 19).Copy cel
Next cel
End With
    
End Sub

Merci
 

Acturis

XLDnaute Nouveau
Bonsoir Acturis, Lone-wolf,
Code:
Sub VPcleaning()
On Error Resume Next 'si aucune SpecialCell
Sheets("Detailed Assessment").[S6:S505].SpecialCells(xlCellTypeBlanks) _
    = "=IF(RC[-17]="""","""",VLOOKUP(RC[-17],Data!C[-18]:C[9],28,FALSE))"
End Sub
A+

Merci Job75 pour ta réponse.
Avec ce code la macro fonctionne superbement bien. Le seul petit hic, c'est que j'ai l'impression qu'il ne reconnait pas les cellules vides. Par défaut rien ne se passe, par contre si je sélectionne des cellules vides dans mon onglet et que je clic sur "Suppr", alors là la macro va fonctionner correctement et quasi instantanément. Tu as une idée qui permettrait de corriger cela ?

Merci d'avance
 

Acturis

XLDnaute Nouveau
Après avoir cherché un peu il semblerait que mes cellules ne soient pas vraiment vide mais contiennent du texte ""...même si rien ne s'affiche dans la barre de formule lorsque je sélectionne une cellule apparemment vide.
Cela vient probablement du fait que j'ai une formule de ce type =SI(S2="";"";'Detailed Assessment'!S6)

Existe t-il un moyen de dire dans une formule si, que la cellule doit être vraiment vide au lieu de "" ? ^^
Ou bien contourner le problème dans le code de Job75 ?

Merci
 

Acturis

XLDnaute Nouveau
J'ai essayé ta dernière proposition Lone-wolf et pareil, ça prend beaucoup de temps :/

VB:
Sub VPcleaning()
'
'

Sheets("Detailed Assessment").Select
Dim I As Long
  With Sheets("Detailed Assessment")
  .Activate
  For I = 6 To 505
If .Cells(I, "S") = vbNullString Then .Cells(I, "S") = "=IF(RC[-17]="""","""",VLOOKUP(RC[-17],Data!C[-18]:C[9],28,FALSE))"
Next I

End With
End Sub

L'approche de Job75 est intéressante car c'est vraiment rapide...je suis juste bloqué car les cellules ne sont pas vraiment vide :/ Il n'y aurais pas une astuce à glisser dans son code pour contourner le pb des cellules "" quasi vides ? ^^

VB:
Sub VPcleaning()
On Error Resume Next 'si aucune SpecialCell
Sheets("Detailed Assessment").[S6:S505].SpecialCells(xlCellTypeBlanks) _
    = "=IF(RC[-17]="""","""",VLOOKUP(RC[-17],Data!C[-18]:C[9],28,FALSE))"
End Sub

Merci en tout cas pour votre aide =)
 

job75

XLDnaute Barbatruc
Re,
Le seul petit hic, c'est que j'ai l'impression qu'il ne reconnait pas les cellules vides.
Les cellules ne sont donc pas vides : elles contiennent le texte vide "".

Alors voici 2 solutions, testez-les et dites-nous quelle est la plus rapide chez vous :
Code:
Sub VPcleaning1()
Dim c As Range
With Sheets("Detailed Assessment").[S6:S505]
    For Each c In .Cells
        If CStr(c) = "" Then c = Empty 'efface les textes vides ""
    Next
    On Error Resume Next 'si aucune SpecialCell
    .SpecialCells(xlCellTypeBlanks) = "=IF(RC[-17]="""","""",VLOOKUP(RC[-17],Data!C[-18]:C[9],28,FALSE))"
End With
End Sub

Sub VPcleaning2()
Dim c As Range, plage As Range
With Sheets("Detailed Assessment").[S6:S505]
    For Each c In .Cells
        If CStr(c) = "" Then Set plage = Union(IIf(plage Is Nothing, c, plage), c)
    Next
    If Not plage Is Nothing Then plage = "=IF(RC[-17]="""","""",VLOOKUP(RC[-17],Data!C[-18]:C[9],28,FALSE))"
End With
End Sub
Bonne nuit.
 

job75

XLDnaute Barbatruc
Bonjour Acturis, Lone-wolf, le forum,

La 2ème solution peut prendre beaucoup de temps si la plage est bien plus grande avec plusieurs centaines de plages "vides" disjointes.

Voici une 3ème solution, la meilleure car elle fonctionne dans tous les cas de figure :
Code:
Sub VPcleaning3()
Dim tv, tf, f$, i&
With Sheets("Detailed Assessment")
    If .FilterMode Then .ShowAllData 'si la feuille est filtrée
    With .[S6:S505] 'à adapter, au moins 2 cellules
        tv = .Value: tf = .FormulaR1C1 'tableaux VBA, plus rapides
        f = "=IF(RC[-17]="""","""",VLOOKUP(RC[-17],Data!C[-18]:C[9],28,FALSE))"
        For i = 1 To UBound(tv)
            If CStr(tv(i, 1)) = "" Then tf(i, 1) = f
        Next
        .FormulaR1C1 = tf 'restitution
    End With
End With
End Sub
Elle est très rapide car elle utilise des tableaux VBA.

Bonne journée.
 

Discussions similaires

Réponses
0
Affichages
154

Statistiques des forums

Discussions
312 248
Messages
2 086 593
Membres
103 248
dernier inscrit
Happycat