1
votes

Fonction Excel VBA pour déterminer le numéro de ligne

J'ai construit une fonction pour déterminer la première ligne dans laquelle les données existent. Lorsque j'appelle les données, j'obtiens une erreur indiquant l'objet requis. Comment contourner cette erreur et est-ce le meilleur moyen d'atteindre mon objectif? TYIA!

Function startrow(firstroww)
Dim strRow As String
Dim firstrow As Range

Range("ab1").Select
strRow = Selection.Value

If strRow <> "" Then
firstroww = 1
Else
Range("ab1").Activate
Selection.End(xlDown).Select
firstroww = ActiveCell.Row()
End If
End Function

Sub rename()

Dim strOldType As String
Dim correctrow As Long
Dim a As Range

Set a = startrow(correctrow)

Range("s" & a).Select
strOldType = Selection.Value
End Sub


8 commentaires

Bienvenue. Veuillez afficher le message d'erreur réel et la ligne de code à l'origine. Avez-vous lu VBA identifie les première et dernière lignes contenant des données ou tout autre article traitant de la recherche de la première ligne avec du contenu. On s'attend à ce que vous fassiez vos propres recherches, et si ces autres messages ne s'appliquent pas à votre situation, alors au moins "... gardez une trace de ce que vous trouvez. Même si vous ne trouvez pas de réponse utile ailleurs sur le site , y compris des liens vers des questions connexes qui n'ont pas aidé peut aider les autres à comprendre en quoi votre question est différente des autres. "


Copie possible de VBA identifie les premières et dernières lignes avec des données


Vous n'avez pas attribué de valeur à correctrow , mais vous l'utilisez pour définir une plage. Ensuite, vous utilisez une plage dans une chaîne pour une adresse de cellule. Quoi??? Vous devez savoir quels types de données vous utilisez dans quel contexte.


utilisez WorksheetFunction.CountA (), comme illustré ci-dessous: Dim row As Range Dim sheet As Worksheet Set sheet = ActiveSheet For i = 1 To sheet.UsedRange.Rows.Count Set row = sheet.Rows (i) If WorksheetFunction. CountA (row) = 0 Then MsgBox "row" & i & "is empty" End If Next i Vous pouvez l'adopter pour définir la plage ou pour définir la valeur de retour de la fonction. Évitez d'utiliser Select .


@skkakkar pourquoi ne pas ajouter cela comme solution au lieu d'un commentaire? Ensuite, vous pouvez réellement le lire


@urdearboy Je ne sais pas si OP veut une fonction ou un sous-marin. Son approche semble déroutante. Il commence avec Sub ets avec End Function. Un autre code suggéré par moi est approprié pour Sub, mais pour le rendre fonctionnel, il devra peut-être être peaufiné, ce que je ne pourrai peut-être pas faire davantage pour le moment.


Si vous regardez de plus près, il y a en effet un sous complet et une fonction. Je vais éditer sa question et les séparer en conséquence afin que ce soit clair @skkakkar


Merci Tedinoz et skkakkar pour la contribution! Cela m'a permis d'aller dans la bonne direction. teylyn c'est la première fois que j'utilise vba et je n'ai aucune formation formelle. Je suis sûr que je commets une sorte de blasphème alors je m'excuse


4 Réponses :


0
votes

Vous pouvez essayer une fonction comme celle-ci. Vous devrez passer une plage dans la fonction comme indiqué ci-dessous dans Sub Test () .

La fonction personnalisée peut trouver la première cellule utilisée ci-dessous à partir de n'importe quel point de départ.

Sub Test()

MsgBox FR(Range("A1"))

End Sub

Option Explicit

Function FR(Start As Range) As Long

Select Case Start
    Case <> ""
        FR = Start.Row
    Case Else
        FR = Start.End(xlDown).Row
End Select

End Function

 entrez la description de l'image ici


2 commentaires

Merci pour l'exemple simple. Le problème que j'ai, c'est au cas où le premier enregistrement se trouverait sur la première ligne.


Je n'ai pas pu le faire fonctionner mais quand j'ai changé votre première déclaration de cas de Case "*" à Case est <> "" cela a fonctionné! Merci beaucoup pour votre aide!



0
votes
  • N'essayez pas d'utiliser Select dans une fonction.
  • Utilisez Set pour attribuer un objet de plage. N'utilisez pas Set pour attribuer un numéro à une variable.
  • Décidez si vous voulez un numéro de ligne ou un objet de plage. Vous rebondissez entre les deux sans tenir compte du résultat.
  • Code corrigé:

    Sub rename()
    
        Dim strOldType As String
        Dim correctrow As Long
        Dim a As LONG     '<~~ correction
    
        correctrow = 1     '<~~ correction
        a = startrow(correctrow)     '<~~ correction
    
        strOldType = Range("s" & a).Value
    
    End Sub
    
    Function startrow(firstroww)
    
        if Range("ab" & firstrow) <> "" then     '<~~ correction
            startrow = firstrow
        else
            startrow = Range("ab" & firstrow).end(xldown).row
        end if
    
    End Function
    

1 commentaires

Je tamise d'abord la fonction, mais j'ai ensuite continué à obtenir l'erreur "Method Range of object '_Gobal failed". J'apprécie d'essayer de m'aider à comprendre ce que j'ai fait de mal avec mon code existant. Cela m'aide à apprendre



0
votes

Première cellule de la fonction de colonne

On suppose que vous recherchez une fonction VBA à utiliser dans Excel pour calculer la première ligne non vide d'une colonne (spécifiée par une plage).

Fonctionnalités

  • La méthode Volatile marque une fonction définie par l'utilisateur comme volatile. UNE la fonction volatile doit être recalculée chaque fois que le calcul se produit dans toutes les cellules de la feuille de calcul. Une fonction non volatile est recalculée uniquement lorsque les variables d'entrée changent (Aide VBA).
  • Au moins par souci d'exactitude, vous devez utiliser IsEmpty au lieu de "" pour la raison, par exemple si la cellule de la ligne résultante contient une formule qui donne la valeur "", elle sera ignorée.
  • La version de la méthode Find utilise la méthode Find pour calculer la première ligne, qui est plus sûre que la version finale, par ex. si vous entrez une valeur dans la première cellule du colonne c'est-à-dire que le résultat est 1 et que vous masquez la première ligne, le résultat de la version finale ne sera pas 1.
  • La formule peut être insérée dans la même colonne que SelectRange Colonne. Dans certains cas, la version Fin n'afficherait pas le bon résultat ou créez une référence circulaire. Par conséquent, ThisCell est utilisé dans la version End et 0 est renvoyé si aucune valeur n'a été trouvée dans la colonne SelectRange .

Version de la méthode de recherche

=FirstRowEnd(AB1)
=FirstRowEnd(AB20)
=FirstRowEnd(AB17:AH234)

Méthode de recherche

Au lieu de

Function FirstRowEnd(SelectRange As Range) As Long

    Application.Volatile

    Dim FirstCell As Range

    If Application.ThisCell.Column = SelectRange.Column Then Exit Function

    If Not IsEmpty(SelectRange.Cells(1)) Then
        FirstRowEnd = 1
      Else
        Set FirstCell = Cells(1, SelectRange.Column).End(xlDown)
        FirstRowEnd = FirstCell.Row
        If FirstRowEnd = Rows.Count And IsEmpty(FirstCell) Then
            FirstRowEnd = 0
        End If
    End If

End Function

vous pouvez utiliser

=FirstRowFind(AB1)
=FirstRowFind(AB20)
=FirstRowFind(AB17:AH234)

ou

Set FirstCell = .Find(What:="*", After:=.Cells(.Cells.Count), _
        LookIn:=xlFormulas, LookAt:=xlWhole, _
        SearchOrder:=xlByColumns, SearchDirection:=xlNext)

Les paramètres pour les arguments LookAt (sans importance dans ce cas) et SearchDirection (la valeur par défaut est Next ) peuvent être omis, mais comme je n'ai pas trouvé de différence d'efficacité, je n'ai pas 't.

Utilisation dans Excel

Pour la colonne AB:

Set FirstCell = .Find("*", .Cells(.Cells.Count), _
        xlFormulas, xlWhole, xlByColumns, xlNext)

Version finale (non recommandée)

Set FirstCell = .Find("*", .Cells(.Cells.Count), -4123, 1, 2, 1)

Utilisation dans Excel

Pour la colonne AB code >:

Function FirstRowFind(SelectRange As Range) As Long

    Application.Volatile

    Dim FirstCell As Range

    With Columns(SelectRange.Column)
        Set FirstCell = .Find("*", .Cells(.Cells.Count), -4123, 1, 2, 1)
    End With

    If Not FirstCell Is Nothing Then
        FirstRowFind = FirstCell.Row
    End If

End Function

0 commentaires

0
votes

Vous pouvez utiliser ceci:

ActiveSheet.UsedRange.Row
ActiveSheet.UsedRange.Column

L'objet UsedRange est le plus grand rectangle couvrant toutes les cellules non vides.


2 commentaires

Cela ne fonctionne pas car j'ai généralement une sorte d'en-tête non pertinente pour mon ensemble de données à quelques lignes au-dessus de l'ensemble de données.


Eh bien, dans ce cas, seule la méthode End est utile. Si votre structure de données est cohérente, les choses seraient beaucoup plus faciles.