J'ai beaucoup entendu parler de l'horreur compréhensible de l'utilisation .Select
dans Excel VBA, mais je ne sais pas comment éviter de l'utiliser. Je trouve que mon code serait plus réutilisable si je pouvais utiliser des variables au lieu de Select
fonctions. Cependant, je ne sais pas comment faire référence à des choses (comme les ActiveCell
etc.) si je ne les utilise pas Select
.
J'ai trouvé cet article sur les gammes et cet exemple sur les avantages de ne pas utiliser select mais je ne trouve rien sur la façon dont ?
Select
et / ouActiveSheet
etc etc est complètement inévitable. Voici un exemple que j'ai trouvé: stackoverflow.com/questions/22796286/….Select / .Selection
nécessaire.Réponses:
Quelques exemples pour éviter de sélectionner
Utiliser
Dim
des variables 'dSet
la variable à la plage requise. Il existe de nombreuses façons de faire référence à une plage unicellulaireou une gamme multicellulaire
Vous pouvez utiliser le raccourci vers la
Evaluate
méthode, mais cela est moins efficace et devrait généralement être évité dans le code de production.Tous les exemples ci-dessus se réfèrent aux cellules de la feuille active . À moins que vous ne souhaitiez spécifiquement travailler qu'avec la feuille active, il est préférable de réduire également une
Worksheet
variableSi vous ne voulez travailler avec la
ActiveSheet
, pour plus de clarté , il est préférable d'être explicite. Mais attention, certainesWorksheet
méthodes modifient la feuille active.Encore une fois, cela fait référence au classeur actif . À moins que vous ne vouliez spécifiquement travailler qu'avec
ActiveWorkbook
ouThisWorkbook
, il est préférable de réduire également uneWorkbook
variable.Si vous ne voulez travailler avec la
ActiveWorkbook
, pour plus de clarté , il est préférable d'être explicite. Mais attention, de nombreusesWorkBook
méthodes modifient le livre actif.Vous pouvez également utiliser l'
ThisWorkbook
objet pour faire référence au livre contenant le code en cours d'exécution.Un (mauvais) morceau de code courant consiste à ouvrir un livre, à obtenir des données puis à refermer
C'est mauvais:
Et ce serait mieux comme:
Passez des plages à vos
Sub
s etFunction
s en tant que variables de plageVous devez également appliquer des méthodes (telles que
Find
etCopy
) aux variablesSi vous effectuez une boucle sur une plage de cellules, il est souvent préférable (plus rapide) de copier d'abord les valeurs de la plage dans un tableau de variantes et de boucler sur celle-ci.
Ceci est un petit avant-goût de ce qui est possible.
la source
rng1(12, 12)
coin supérieur gauche ... par exemple, cela fonctionnera même si rng1 a été défini sur[A1:A10]
seulement.Range
comme ceci:ActiveSheet.[a1:a4]
ouws.[b6]
.variant
variable ne nécessite pasSet
jusqu'à ce que vous lui affectiez un objet. Par exemple,Dim x: x = 1
est correct, maisDim x: x = Sheets("Sheet1")
génère Erreur 438. Cependant , juste Confondre / clarifierDim x: x = Range("A1")
va pas créer une erreur. Pourquoi? ... parce que la valeur de l'objet est assignée à la variable, pas une référence à l'objet lui-même (car c'est l'équivalent deDim x: x = Range("A1").Value
)Deux raisons principales pour lesquelles
.Select
/.Activate
/Selection
/Activecell
/Activesheet
/Activeworkbook
etc ... devraient être évitéesComment l'évitons-nous?
1) Travailler directement avec les objets concernés
Considérez ce code
Ce code peut également s'écrire
2) Si nécessaire, déclarez vos variables. Le même code ci-dessus peut être écrit comme
la source
Sheets(2).[C10:D12].Value = Sheets(1).[A1:B3].Value
.Activate
pour passer à la feuille d'origine, utilisez simplementApplication.Goto
Un petit point important que j'ajouterai à toutes les excellentes réponses données ci-dessus:
La plus grande chose que vous puissiez faire pour éviter d'utiliser Select est probablement d'utiliser autant que possible des plages nommées (combinées avec des noms de variables significatifs) dans votre code VBA . Ce point a été mentionné ci-dessus, mais passé sous silence un peu; cependant, il mérite une attention particulière.
Voici quelques raisons supplémentaires pour utiliser librement les plages nommées, même si je suis sûr que je pourrais y penser davantage.
Les plages nommées facilitent la lecture et la compréhension de votre code.
Exemple:
Il est assez évident de savoir ce
Months
queMonthlySales
contiennent les plages nommées et ce que fait la procédure.Pourquoi est-ce important? En partie parce qu'il est plus facile pour les autres de le comprendre, mais même si vous êtes la seule personne qui verra ou utilisera votre code, vous devez toujours utiliser des plages nommées et de bons noms de variables car VOUS OUBLIEREZ ce que vous vouliez faire avec. un an plus tard, et vous perdrez 30 minutes à découvrir ce que fait votre code.
Les plages nommées garantissent que vos macros ne se cassent pas lorsque (pas si!) La configuration de la feuille de calcul change.
Considérez, si l'exemple ci-dessus avait été écrit comme ceci:
Ce code fonctionnera très bien au début - c'est jusqu'à ce que vous ou un futur utilisateur décide "gee wiz, je pense que je vais ajouter une nouvelle colonne avec l'année dans la colonne
A
!", Ou mettre une colonne de dépenses entre les mois et colonnes de vente ou ajoutez un en-tête à chaque colonne. Maintenant, votre code est cassé. Et parce que vous avez utilisé des noms de variables terribles, il vous faudra beaucoup plus de temps pour comprendre comment le réparer qu'il ne le faudrait.Si vous aviez utilisé des plages nommées pour commencer, les colonnes
Months
etSales
pourraient être déplacées tout ce que vous voulez, et votre code continuera de fonctionner correctement.la source
Je vais donner la réponse courte puisque tout le monde a donné la longue.
Vous obtiendrez .select et .activate chaque fois que vous enregistrez des macros et les réutilisez. Lorsque vous sélectionnez une cellule ou une feuille, cela la rend simplement active. À partir de ce moment, chaque fois que vous utilisez des références non qualifiées, comme
Range.Value
elles utilisent simplement la cellule et la feuille actives. Cela peut également être problématique si vous ne regardez pas où votre code est placé ou si un utilisateur clique sur le classeur.Ainsi, vous pouvez éliminer ces problèmes en référençant directement vos cellules. Ce qui va:
Ou vous pourriez
Il existe différentes combinaisons de ces méthodes, mais ce serait l'idée générale exprimée le plus rapidement possible pour des gens impatients comme moi.
la source
Bien que je ne puisse penser à rien d'autre qu'à une poignée de situations isolées
.Select
qui seraient un meilleur choix que le référencement cellulaire direct, je voudrais défendreSelection
et souligner qu'il ne devrait pas être rejeté pour les mêmes raisons qui.Select
devraient être évitées.Il y a des moments où avoir des sous-routines de macro courtes et rapides affectées à des combinaisons de touches de raccourci disponibles en appuyant sur quelques touches permet de gagner beaucoup de temps. Être en mesure de sélectionner un groupe de cellules pour appliquer le code opérationnel sur Works fonctionne à merveille lorsqu'il s'agit de données empochées qui ne sont pas conformes à un format de données à l'échelle de la feuille de calcul. De la même manière que vous pouvez sélectionner un groupe de cellules et appliquer un changement de format, la sélection d'un groupe de cellules pour exécuter un code de macro spécial peut être un gain de temps majeur.
Exemples de sous-cadre basé sur la sélection:
Le code réel à traiter peut être n'importe quoi, d'une seule ligne à plusieurs modules. J'ai utilisé cette méthode pour lancer des routines de longue durée sur une sélection irrégulière de cellules contenant les noms de fichiers des classeurs externes.
En bref, ne le jetez pas en
Selection
raison de son association étroite avec.Select
etActiveCell
. En tant que propriété de feuille de calcul, elle a de nombreuses autres fonctions.(Oui, je sais que cette question concernait
.Select
, non,Selection
mais je voulais supprimer toute idée fausse que les codeurs VBA novices pourraient inférer.)la source
Selection
peut être n'importe quoi dans la feuille de calcul, il pourrait donc aussi bien tester d'abord le type de l'objet avant de l'affecter à une variable puisque vous l'avez explicitement déclaré commeRange
.Veuillez noter que dans ce qui suit, je compare l'approche Select (celle que l'OP veut éviter), avec l'approche Range (et c'est la réponse à la question). Alors n'arrêtez pas de lire lorsque vous voyez le premier Select.
Cela dépend vraiment de ce que vous essayez de faire. Quoi qu'il en soit, un exemple simple pourrait être utile. Supposons que vous souhaitiez définir la valeur de la cellule active sur "foo". En utilisant ActiveCell, vous écririez quelque chose comme ceci:
Si vous souhaitez l'utiliser pour une cellule qui n'est pas active, par exemple pour "B2", vous devez d'abord la sélectionner, comme ceci:
À l'aide des plages, vous pouvez écrire une macro plus générique qui peut être utilisée pour définir la valeur de n'importe quelle cellule de votre choix:
Ensuite, vous pouvez réécrire Macro2 comme:
Et Macro1 comme:
J'espère que cela aide à clarifier un peu les choses.
la source
Éviter
Select
etActivate
c'est le mouvement qui vous rend un peu meilleur développeur VBA. En général,Select
etActivate
sont utilisés lorsqu'une macro est enregistrée, laParent
feuille de calcul ou la plage est donc toujours considérée comme active.Voici comment vous pouvez éviter
Select
etActivate
dans les cas suivants:Ajouter une nouvelle feuille de calcul et copier une cellule dessus:
De (code généré avec l'enregistreur de macros):
À:
Lorsque vous souhaitez copier une plage entre des feuilles de calcul:
De:
À:
Utilisation de plages nommées fantaisistes
Vous pouvez y accéder avec
[]
, ce qui est vraiment beau, par rapport à l'inverse. Vérifie toi-même:L'exemple ci-dessus ressemblerait à ceci:
Ne pas copier des valeurs, mais les prendre
Habituellement, si vous le souhaitez
select
, vous copiez probablement quelque chose. Si vous êtes uniquement intéressé par les valeurs, c'est une bonne option pour éviter de sélectionner:Range("B1:B6").Value = Range("A1:A6").Value
Essayez toujours de référencer la feuille de calcul également
C’est probablement l’erreur la plus courante vba. Chaque fois que vous copiez des plages, la feuille de calcul n'est parfois pas référencée et VBA considère donc la mauvaise feuille comme la feuille ActiveWorksheet.
Puis-je vraiment jamais utiliser
.Select
ou.Activate
pour quoi que ce soit?.Activate
et.Select
c'est quand vous voulez vous assurer qu'une feuille de calcul spécifique est sélectionnée pour des raisons visuelles. Par exemple, que votre Excel s'ouvrirait toujours avec la feuille de calcul de couverture sélectionnée en premier, sans tenir compte de la feuille ActiveSheet lorsque le fichier a été fermé.Ainsi, quelque chose comme le code ci-dessous est absolument OK:
Un autre bon exemple est lorsque vous devez exporter toutes les feuilles dans un seul fichier PDF, comme mentionné dans ce cas - Comment éviter les instructions select / active dans VBA dans cet exemple?
Lorsqu'une commande fonctionne uniquement avec
ActiveWindow
comme ActiveWindow.Zoom ou ActiveWindow.FreezePanesla source
.Select
- ainsi que mon travail - peut être trouvé sur Comment écrire des informations identiques sur toutes les feuilles - @Vityata :).FillAcrossSheets
, donc c'est quelque part entre les deux (au moins dans mon idée de la taxonomie VBA)Indiquez toujours le classeur, la feuille de calcul et la cellule / plage.
Par exemple:
Parce que les utilisateurs finaux cliquent toujours sur les boutons et dès que le focus se déplace hors du classeur, le code veut travailler, puis les choses vont complètement mal.
Et n'utilisez jamais l'index d'un classeur.
Vous ne savez pas quels autres classeurs seront ouverts lorsque l'utilisateur exécutera votre code.
la source
Ces méthodes sont plutôt stigmatisées, prenant ainsi la tête de @Vityata et @Jeeped pour dessiner une ligne dans le sable:
Pourquoi ne pas appeler
.Activate
,.Select
,Selection
,ActiveSomething
méthodes / propriétésFondamentalement, car ils sont appelés principalement pour gérer les entrées utilisateur via l'interface utilisateur de l'application. Puisqu'il s'agit des méthodes appelées lorsque l'utilisateur manipule des objets via l'interface utilisateur, ce sont celles enregistrées par le macro-enregistreur, et c'est pourquoi les appeler est soit fragile soit redondant dans la plupart des situations: vous n'avez pas à sélectionner un objet de façon à effectuer une action avec
Selection
juste après.Cependant, cette définition règle les situations sur lesquelles elles sont appelées:
Quand appeler
.Activate
,.Select
,.Selection
,.ActiveSomething
méthodes / propriétésFondamentalement, lorsque vous vous attendez à ce que l' utilisateur final joue un rôle dans l'exécution.
Si vous développez et attendez de l'utilisateur qu'il choisisse les instances d'objet à gérer par votre code, alors
.Selection
ou.ActiveObject
sont appropriées.D'autre part,
.Select
et.Activate
sont utiles lorsque vous pouvez déduire la prochaine action de l'utilisateur et que vous souhaitez que votre code guide l'utilisateur, lui permettant éventuellement de gagner du temps et des clics de souris. Par exemple, si votre code vient de créer une toute nouvelle instance d'un graphique ou une mise à jour, l'utilisateur peut vouloir le vérifier, et vous pouvez l'appeler.Activate
ou sa feuille pour lui faire gagner du temps; ou si vous savez que l'utilisateur devra mettre à jour certaines valeurs de plage, vous pouvez sélectionner cette plage par programmation.la source
L'utilisation
.select
à mon humble avis vient de personnes qui, comme moi, ont commencé à apprendre VBA par nécessité en enregistrant des macros, puis en modifiant le code sans s'en rendre compte.select
et par la suite, ceselection
n'est qu'un intermédiaire inutile..select
peut être évité, comme beaucoup l'ont déjà posté, en travaillant directement avec les objets déjà existants, ce qui permet divers référencements indirects comme calculer i et j de manière complexe puis éditer la cellule (i, j), etc.Sinon, il n'y a rien de mal implicitement avec
.select
lui-même et vous pouvez facilement trouver des utilisations, par exemple, j'ai une feuille de calcul que je remplis avec la date, active la macro qui fait de la magie avec elle et l'exporte dans un format acceptable sur une feuille séparée, qui , cependant, nécessite des entrées manuelles finales (imprévisibles) dans une cellule adjacente. Voici donc le moment.select
qui me permet d'économiser le mouvement et le clic supplémentaires de la souris.la source
Réponse rapide:
Pour éviter d'utiliser la
.Select
méthode, vous pouvez définir une variable égale à la propriété souhaitée.► Par exemple, si vous voulez que la valeur soit dans,
Cell A1
vous pouvez définir une variable égale à la propriété value de cette cellule.valOne = Range("A1").Value
► Par exemple, si vous voulez le nom de code de «Sheet3», vous pouvez définir une variable égale à la propriété de nom de code de cette feuille de calcul.
valTwo = Sheets("Sheet3").Codename
J'espère que ça aide. Faites moi savoir si vous avez des questions.
la source
J'ai remarqué qu'aucune de ces réponses ne mentionne la propriété .Offset . Cela peut également être utilisé pour éviter d'utiliser l'
Select
action lors de la manipulation de certaines cellules, en particulier en référence à une cellule sélectionnée (comme l'OP le mentionneActiveCell
).Voici quelques exemples.
Je suppose également que "ActiveCell" est J4 .
ActiveCell.Offset(2, 0).Value = 12
J6
à une valeur de 12ActiveCell.Offset(0,1).Copy ActiveCell.Offset(,2)
k4
àL4
.i4
ActiveCell.Offset(, -1).EntireColumn.ClearContents
Cela ne veut pas dire qu'elles sont "meilleures" que les options ci-dessus, mais simplement une liste d'alternatives.
la source
Travailler avec la fonctionnalité .Parent. Cet exemple montre comment la définition d'une seule référence myRng permet un accès dynamique à l'ensemble de l'environnement sans .Select, .Activate, .Activecell, .ActiveWorkbook, .ActiveSheet, etc. (Il n'y a pas de fonctionnalité générique .Child)
la source
La principale raison de ne jamais utiliser Select ou Activesheet est que la plupart des gens auront au moins un autre couple de classeurs ouverts (parfois des dizaines) lorsqu'ils exécutent votre macro, et s'ils cliquent loin de votre feuille pendant que votre macro s'exécute et cliquent sur un autre livre qu'ils ont ouvert, puis la «feuille active» change, et le classeur cible pour une commande «Sélectionner» non qualifiée change également.
Au mieux, votre macro se bloquera, au pire vous pourriez finir par écrire des valeurs ou changer des cellules dans le mauvais classeur sans aucun moyen de les "annuler".
J'ai une règle d'or simple que je suis: ajouter des variables nommées "wb" et "ws" pour un objet Workbook et un objet Worksheet et toujours les utiliser pour faire référence à mon livre de macro. Si je dois faire référence à plusieurs livres ou plusieurs feuilles, j'ajoute plusieurs variables.
par exemple
La commande "Set wb = ThisWorkbook" est absolument essentielle. "ThisWorkbook" est une valeur spéciale dans Excel, et cela signifie le classeur à partir duquel votre code VBA s'exécute actuellement . Un raccourci très utile pour définir votre variable de classeur avec.
Après l'avoir fait en haut de votre Sub, leur utilisation ne pourrait pas être plus simple, il suffit de les utiliser partout où vous utiliseriez "Sélection":
Donc, pour changer la valeur de la cellule "A1" dans "Sortie" en "Bonjour", au lieu de:
Nous pouvons maintenant le faire:
Ce qui est non seulement beaucoup plus fiable et moins susceptible de se bloquer si l'utilisateur travaille avec plusieurs feuilles de calcul, il est également beaucoup plus court, plus rapide et plus facile à écrire.
En prime, si vous nommez toujours vos variables "wb" et "ws", vous pouvez copier et coller du code d'un livre à un autre et cela fonctionnera généralement avec le moins de changements nécessaires, le cas échéant.
la source
ThisWorkbook
... Je ne suis pas sûr que votre commentaire soit exact.Il s'agit d'un exemple qui effacera le contenu de la cellule "A1" (ou plus si le type de sélection est xllastcell, etc.). Tout cela sans avoir à sélectionner les cellules.
J'espère que ça aidera quelqu'un.
la source
Workbook(WorkbookName).Worksheets(WorksheetName).Range("A1").ClearContents
qui est une ligne et non deux, et fonctionne en fait sans sélectionner les cellules.