4 votes

Erreur d'exécution de la fonction VBA Excel 1004 : Erreur définie par l'application ou par l'objet

J'essaie d'apprendre les fonctions dans le but de simplifier et de réutiliser le code chaque fois que cela est nécessaire.

J'ai commencé par transformer un élément que j'utilise assez souvent en une fonction : renvoyer la valeur entière de la dernière colonne non vide d'une feuille de calcul.

Function FindLastDataLine(strColName As String) As Long
    FindLastDataLine = Range(strColName).Offset(Rows.Count - 1, 0).End(xlUp).Row
End Function

Sub PracticeMacro()
    intItemCount = FindLastDataLine("A:A")
    MsgBox ("There are " & intItemCount & " rows of data in column A.")
End Sub

Lorsque je l'exécute, je reçois l'erreur d'exécution '1004' "Application-defined or object-defined error" qui, selon une définition utile, est "la faute de quelqu'un d'autre" pour ne pas citer tout à fait textuellement.

Où est-ce que je pourrais me tromper ?

4voto

Breakthrough Points 33693

Pourquoi votre méthode ne fonctionne pas : Il y a deux raisons à cela. La première, lorsque vous mettez Rows.Count il n'y a pas de référence pour Rows - il s'agit d'une propriété d'un Range . Pour le corriger, il suffit de référencer la même plage que celle que vous avez déjà (il suffit de l'ajouter avant d'appeler Rows.Count comme ça :

Function FindLastDataLine(strColName As String) As Long
    FindLastDataLine = Range(strColName).Offset(Range(strColName).Rows.Count - 1, 0).End(xlUp).Row
End Function

La deuxième raison est que vous utilisez Offset . Offset déplace littéralement un Range par la façon dont vous le dites. Vous ne voulez pas déplacer toute la plage de cellules, mais trouver la dernière cellule de la plage. Vous pouvez le faire assez simplement en modifiant Offset à Cells en supprimant l'initiale Range() (puisque nous allons choisir une cellule), et en changeant 0 à la colonne que vous voulez. Cependant, comme vous passez la colonne en tant que "A:A" ce n'est pas possible, il faut donc le remplacer par Range(strColName).Column comme suit :

Function FindLastDataLine(strColName As String) As Long
    FindLastDataLine = Cells(Range(strColName).Rows.Count, Range(strColName).Column).End(xlUp).Row
End Function

Une meilleure solution : la solution suivante fonctionnera sur toutes les versions récentes de MS Office (2003, 2007 et 2010), et traitera les erreurs. Vous l'appelez en passant soit la lettre de la colonne, soit le numéro de la colonne :

Function GetLastDataRow(col As Variant) As Long
    GetLastDataRow = -1
    If (IsNumeric(col) And col >= 1) Or Len(col) <= 2 Then
        On Error Resume Next
        GetLastDataRow = _
            Cells(Cells(1, col).EntireColumn.Rows.Count, col).End(xlUp).Row
        On Error GoTo 0
    End If
End Function

Voici comment vous pouvez appeler cette fonction et quelques exemples de résultats. Supposons que la feuille entière soit vide, à l'exception de quelques données aléatoires entrées dans les cellules B1 à B8 y B10 ( B9 est laissé en blanc). Notez que vous ne saisissez pas la colonne en tant que plage, mais plutôt la lettre de la colonne. o le numéro de la colonne (les valeurs invalides renvoient -1) :

GetLastDataRow(1)         =  1    GetLastDataRow("A")       =  1
GetLastDataRow(2)         = 10    GetLastDataRow("B")       = 10
GetLastDataRow("AX")      =  1    GetLastDataRow("A:X")     = -1
GetLastDataRow("Oops...") = -1    GetLastDataRow(200)       =  1

À titre de remarque technique, si le Cells échoue, il est supposé que l'entrée n'était pas valide, et la fonction renvoie donc -1. Je vous invite à utiliser cette pratique (renvoyer des valeurs invalides si l'entrée n'est pas valide) dans vos fonctions, cela vous aidera grandement à éviter les erreurs à l'avenir.

Le principe est le suivant : il trouve la dernière ligne possible dans une colonne donnée (cela dépend de votre version de MS Office), puis utilise la fonction End pour trouver la dernière cellule de cette colonne contenant des données.


Voici une version alternative qui renvoie 0 si toutes les cellules de cette colonne sont vides :

Function GetLastDataRow(col As Variant) As Long
    GetLastDataRow = -1
    If (IsNumeric(col) And col >= 1) Or Len(col) <= 2 Then
        On Error Resume Next
        If IsEmpty(Cells(Cells(1, col).EntireColumn.Rows.Count, col).End(xlUp).Value) Then
            GetLastDataRow = 0
        Else
            GetLastDataRow = _
                Cells(Cells(1, col).EntireColumn.Rows.Count, col).End(xlUp).Row
        End If
        On Error GoTo 0
    End If
End Function

Exemple de sortie :

GetLastDataRow(1)         =  0    GetLastDataRow("A")       =  0
GetLastDataRow(2)         = 10    GetLastDataRow("B")       = 10
GetLastDataRow("AX")      =  0    GetLastDataRow("A:X")     = -1
GetLastDataRow("Oops...") = -1    GetLastDataRow(200)       =  0

1voto

beakr Points 33

Vous avez écrit "Renvoyer la valeur entière de la dernière ligne non-blanche dans une feuille de calcul". Mais il semble que vous essayez d'obtenir la dernière ligne non-blanche dans une colonne particulière d'une feuille de calcul.

Si vous changez votre fonction en ceci, je pense que cela fonctionnera :

Function FindLastDataLine(strColName As String) As Long
    FindLastDataLine = ActiveSheet.Cells(ActiveSheet.Rows.Count, strColName).End(xlUp).Row
End Function

1voto

George Points 90

Cela ne résoudra peut-être pas votre erreur, mais renverra le ItemCount dans la fourchette...

Function FindLastDataLine(strColName As String) As Long
    FindLastDataLine = Evaluate("COUNTA(" & strColName & ")")
End Function

Sub PracticeMacro()
    intItemCount = FindLastDataLine("A:A")
    MsgBox ("There are " & intItemCount & " rows of data in column A.")
End Sub

Remarquez qu'il existe d'autres façons d'appeler cette fonction Excel COUNTA...

0voto

Lance Roberts Points 8483

Essayez :

FindLastDataLine = _
     Range(strColName).Offset(ActiveSheet.Rows.Count - 1, 0).End(xlUp).Row

Rows est une propriété.

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X