web-dev-qa-db-fra.com

Comment trouver du texte dans une colonne et enregistrer le numéro de la ligne là où il a été trouvé - Excel VBA

J'ai la colonne suivante (colonne A) nommée projet (la colonne de lignes affiche simplement le numéro de ligne):

rows    project
1       14
2       15
3       16
4       17
5       18
6       19
7       ProjTemp
8       ProjTemp
9       ProjTemp

J'ai une boîte de message d'entrée où l'utilisateur écrit le nouveau nom du projet que je veux insérer juste après le dernier. Ex: le projet 20 sera inséré juste après le projet 19 et avant le premier "ProjTemp".

Ma théorie était de localiser le numéro de ligne du premier "ProjTemp" puis d'insérer une nouvelle ligne où le projet est 20.

J'essayais d'utiliser la fonction Rechercher mais j'obtiens une erreur de débordement (je suis sûr de l'obtenir car il trouve 3 chaînes "ProjTemp" et j'essaie de le définir sur un paramètre):

Dim FindRow as Range

with WB.Sheets("ECM Overview")
    Set FindRow = .Range("A:A").Find(What:="ProjTemp", _
                        After:=.Cells(.Cells.Count), _
                        LookIn:=xlValues, _
                        LookAt:=xlWhole, _
                        SearchOrder:=xlByRows, _
                        MatchCase:=False)
end with

Comment puis-je coder cela afin de ne trouver que le numéro de ligne du poing "ProjTemp"? Y a-t-il une meilleure façon de faire cela, peut-être une boucle?

Merci, toute aide sera appréciée!

11
Kristina

Je ne connais pas vraiment tous ces paramètres de la méthode Find; mais en le raccourcissant, ce qui suit fonctionne pour moi:

With WB.Sheets("ECM Overview")
    Set FindRow = .Range("A:A").Find(What:="ProjTemp", LookIn:=xlValues)
End With

Et si vous avez uniquement besoin du numéro de ligne, vous pouvez l'utiliser après:

Dim FindRowNumber As Long
.....
FindRowNumber = FindRow.Row
20
mango
Dim FindRow as Range

Set FindRow = Range("A:A").Find(What:="ProjTemp", _' This is what you are searching for
                   After:=.Cells(.Cells.Count), _ ' This is saying after the last cell in the_
                                                  ' column i.e. the first
                   LookIn:=xlValues, _ ' this says look in the values of the cell not the formula
                   LookAt:=xlWhole, _ ' This look s for EXACT ENTIRE MATCH
                   SearchOrder:=xlByRows, _ 'This look down the column row by row 
                                            'Larger Ranges with multiple columns can be set to 
                                            ' look column by column then down 
                   MatchCase:=False) ' this says that the search is not case sensitive

If Not FindRow  Is Nothing Then ' if findrow is something (Prevents Errors)
    FirstRow = FindRow.Row      ' set FirstRow to the first time a match is found
End If

Si vous souhaitez en avoir d'autres, vous pouvez utiliser: 

Do Until FindRow Is Nothing
    Set FindRow = Range("A:A").FindNext(after:=FindRow)
    If FindRow.row = FirstRow Then
        Exit Do
    Else ' Do what you'd like with the additional rows here.

    End If
Loop
7
user2140261

Vous pouvez également utiliser une boucle, conserver le numéro de ligne (le compteur doit être le numéro de ligne) et arrêter la boucle lorsque vous trouvez le premier "ProjTemp" .
Ensuite, cela devrait ressembler à ceci: 

Sub find()
    Dim i As Integer
    Dim firstTime As Integer
    Dim bNotFound As Boolean

    i = 1
    bNotFound = True

      Do While bNotFound
        If Cells(i, 2).Value = "ProjTemp" Then
            firstTime = i
            bNotFound = false
        End If
        i = i + 1
    Loop
End Sub
2
j0chn

Quelques commentaires: 

  1. Étant donné que la position de recherche est importante, vous devez spécifier le point de départ de la recherche. J'utilise ws.[a1] et xlNext ci-dessous pour que ma recherche commence dans A2 de la feuille spécifiée. 
  2. Certains des arguments Finds, y compris lookat, utilisent les paramètres de recherche précédents. Vous devez donc toujours spécifier xlWhole ou xlPart pour correspondre à tout ou partie d'une chaîne, respectivement.
  3. Vous pouvez faire tout ce que vous voulez - y compris insérer une ligne et inviter l'utilisateur à saisir une nouvelle valeur (mon code suggérera 20 si la valeur précédente était 19) sans utiliser Select ou Activate

code suggéré

Sub FindEm()
Dim Wb As Workbook
Dim ws As Worksheet
Dim rng1 As Range
Set Wb = ThisWorkbook
Set ws = Wb.Sheets("ECM Overview")
Set rng1 = ws.Range("A:A").Find("ProjTemp", ws.[a1], xlValues, xlWhole, , xlNext)
If Not rng1 Is Nothing Then
rng1.EntireRow.Insert
rng1.Offset(-1, 0).Value = Application.InputBox("Please enter data", "User Data Entry", rng1.Offset(-2, 0) + 1, , , , , 1)
Else
MsgBox "ProjTemp not found", vbCritical
End If
End Sub
1
brettdj

Recherchez "projtemp", puis vérifiez si la précédente est une entrée numérique (comme 19,18..etc ..) si tel est le cas, puis indiquez le numéro de ligne de ce projet ...

et si ce n'est pas le cas, vérifiez à nouveau que l'entrée précédente correspond à projtemp ou à une entrée numérique ...

0
sonny