Jai une feuille de calcul Excel composée de deux colonnes, dont lune est remplie de chaînes et lautre est vide. Je voudrais utiliser VBA pour attribuer la valeur des cellules dans la colonne vide en fonction de la valeur de la chaîne adjacente dans lautre colonne.

Dim regexAdmin As Object Set regexAdmin = CreateObject("VBScript.RegExp") regexAdmin.IgnoreCase = True regexAdmin.Pattern = "Admin" Dim i As Integer For i = 1 To 10 "let"s say there is 10 rows Dim j As Integer For j = 1 To 2 If regexAdmin.test(Cells(i, j).Value) Then Cells(i, j + 1).Value = "Exploitation" End If Next j Next i 

Le Le problème est que lorsque vous utilisez cette boucle pour une grande quantité de données, cela prend beaucoup trop de temps à travailler et, la plupart du temps, cela plante simplement Excel.

Est-ce que quelquun connaît une meilleure façon de faire cela?

Réponse

La réponse courte est:

Nutilisez pas , utilisez une formule. En particulier, une combinaison de IF et SEARCH .

=IF(SEARCH($A1,"Admin")>0,"Exploitation","") 

Mais cest une révision de code, alors faisons ça quand même.

  • Regex est lent. Il semble que vous ne lutilisez que pour son insensibilité à la casse. Cela étant, vous pouvez comparer directement les valeurs des cellules en utilisant StrComp avec loption vbTextCompare. ( article utile sur StrComp )

  • i et j sont généralement utilisés pour les compteurs de boucles, mais row et col ont plus de sens dans ce cas.

Voici à quoi cela pourrait ressembler:

Dim row As Integer For row = 1 To 10 "let"s say there is 10 rows Dim col As Integer For col = 1 To 2 If StrComp("Admin",Cells(row, col).Value,vbTextCompare) Then Cells(row, col + 1).Value = "Exploitation" End If Next col Next row 

Réponse

Je pense quune simple comparaison de chaînes serait beaucoup plus rapide que Regex.

Dim pattern as string pattern = "Admin" Dim i As Integer For i = 1 To 10 "let"s say there is 10 rows Dim j As Integer For j = 1 To 2 If Cells(i, j) = pattern Then Cells(i, j + 1) = "Exploitation" End If Next j Next i 

Commentaires

  • Ce code nadresse ‘ aucune comparaison insensible à la casse, mais vous ‘ est correct. Lexpression régulière est exagérée et la comparaison de chaînes est préférée dans ce cas. (Bienvenue dans la révision du code au fait!)

Réponse

Puis-je suggérer une réduction de 50% du temps dexécution /effort?

Dim row As Integer For row = 1 To 10 "let"s say there is 10 rows If StrComp("Admin",Cells(row, 1).Value,vbTextCompare) Then Cells(row, 2).Value = "Exploitation" End If Next row 

Personne na remarqué que lOP parle de « vérifier UNE colonne, écrire dans la NEXT adjacente », vraiment? Pourquoi boucler les colonnes alors? La deuxième passe ne vérifierait quune cellule vide ou une cellule contenant « Exploitation ».

Réponse

Wow. Le simple fait de lire les deux premières lignes ma amené à me demander:

  • Pourquoi la liaison tardive?
  • Pourquoi utiliser une expression régulière?

@ ckuhn203 a déjà abordé la dénomination dans sa réponse, mais je trouve ceci:

Dim i As Integer For i = 1 To 10 "let"s say there is 10 rows 

Transformé en cela:

Dim row As Integer For row = 1 To 10 "let"s say there is 10 rows 

… Na plus besoin du commentaire.


Je voudrais utiliser VBA pour attribuer la valeur des cellules dans la colonne vide en fonction de la valeur de la chaîne adjacente dans lautre colonne.

Je pense que « s [mis | ab] en utilisant VBA: Excel lui-même est très bon pour attribuer des valeurs de cellule basées sur dautres cellules « valeurs.


regexAdmin.Pattern = "Admin" 

Je pense que « s [mis | ab] en utilisant regex: si votre motif est juste un mot simple, vous essayez probablement de tuer un moustique avec un bazooka. Mauvais outil pour t Le travail ici.

Réponse

Chaque fois que vous accédez à lobjet Range, cela doit être fait avec une seule opération de lecture / écriture.

Avant dentrer dans la boucle for, vous devez lire toute la plage avec laquelle vous souhaitez travailler.

data = Range(Cells(1,1), Cells(10,2)).Value 

Vous pouvez maintenant travailler avec les données:

For i = 1 To 10 "let"s say there is 10 rows Dim j As Integer For j = 1 To 2 If regexAdmin.test(data(i, j)) Then data(i, j + 1) = "Exploitation" End If Next j Next i 

Enfin, réécrivez les données pour exceller:

Range(Cells(1,1), Cells(10,2)).Value = data 

Réponse

Dans B1:

=if(upper(A1)="ADMIN","Exploitation","") 

Ensuite, remplissez-le simplement. Ce nest pas sensible à la casse.

Ce remplissage automatique peut être effectué de deux manières, soit de manière interactive dans la feuille de calcul, soit par programmation:

Interactivement : Excel dispose dune fonction de remplissage automatique. Avec B1 sélectionné et cette formule insérée, double-cliquez simplement sur la poignée de recopie, qui est le petit carré dans le coin inférieur droit de la cellule lorsquelle est sélectionnée. Excel copiera intelligemment la formule jusquà la fin de la plage contiguë qui a données. Cela signifie que si A1-A256 contient des données sans espaces, il « se remplira automatiquement à B256. Sinon, sil y a des blancs, faites défiler vers le bas et sélectionnez B256 (ou quelle que soit la fin). Puis Ctrl + Maj + Flèche vers le haut pour sélectionner la plage menant à B1, et Ctrl + D pour la copier vers le bas (pensez à d = idem)

Utilisation de VBA … si vous devez le faire par programme: avec la formule contenant la cellule comme sélection:

Selection.AutoFill Destination:=Range("B1:B19") 

Il existe d autres options disponibles pour le remplissage automatique pour faire quelques trucs sympas.Peut copier une valeur littérale au lieu dune formule, ou également remplir une série basée sur un modèle. Vous pouvez également définir des modèles personnalisés pour quil les reconnaisse, tels que les secteurs dactivité que vous répétez couramment dans les activités ou les villes dans lesquelles vous avez des magasins, etc.

Commentaires

  • Bienvenue à Code Review! Jai complètement manqué que OP navait ‘ pas besoin de rechercher la colonne! ++ La meilleure solution ici.

Réponse

En combinant toutes les autres réponses ensemble, cela rendait insensible à la casse comme le regex dans loriginal, supprimant la nécessité de spécifier le nombre de lignes et de déclarer toutes les variables car Option Explicit évite tant derreurs dans vba

Option Explicit Sub checkForExploit() Dim row As Integer Dim data() As Variant Dim datarange As Range Set datarange = Range("A1:B10") data = datarange.Value For row = 1 To UBound(data, 1) If LCase(data(row, 1)) = "admin" Then data(row, 2) = "Exploitation" End If Next row datarange.Value = data End Sub 

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *