Problématique VBA

Bonjour,

Je suis nouveau dans le VBA, je souhaiterai comprendre le fonctionnement des tableaux.

En essayant de récupérer des valeurs pour les enregistrer dans un tableau. J'ai un message d'erreur qui s'affiche.

Il s'agit d'une feuille possédant deux colonnes et 4 champs sur chacune d'elles.

Merci par avance pour votre aide.

Private Sub CommandButton2_Click()

Dim vartabl(2) As String
i As Integer
ligne As Integer
nbligne As Integer
nbligne = 1
Do While Cells(nbligne, 1).Value <> ""
nbligne = nbligne + 1
Loop

For ligne = 1 To nbligne

vartabl(0) = Cells(ligne, 1).Value
vartabl(1) = Cells(ligne, 2).Value

For i = 1 To 2
Cells(ligne, i + 11).Value = vartabl(i)

Next i
Next ligne

End Sub

Bonjour rams123456 ,

Afin de mieux comprendre ta demande, un fichier serait le bienvenue pour que l'on puisse avoir une base de travail.

A 1er vue tu dimensionnes, ta variable vartabl(2) sans "option base 1" donc déjà tu disposes de 3 emplacements ( 0, 1 et 2 ) car sans la ligne "option base 1", tes tableaux démarre à la valeur "0". Donc si tu souhaite que 2 éléments dans ton tableau, tu peux indiquer comme ceci : vartabl(1) qui prendra pour valeur : vartabl(0) & vartabl(1)

Ensuite que vaut nbligne, car si celui ci est supérieur aux éléments du tableau, tu vas venir écraser à chaque fois la valeur précédentes.

Bonjour,

il faut corriger les déclaration,

Dim vartabl(2) As String
Dim i As Integer
Dim ligne As Integer
Dim nbligne As Integer
Dim nbligne = 1

Bonjour i20100,

J'avais pas vu celle là , effectivement sa marchera moins bien

Bonjour,

quelques explications en commentaire dans le code :

Private Sub CommandButton2_Click()

    'dans la déclaration, les variables doivent être précédées de "Dim" ou "Static"
    '"Public" étant interdit à l'intérieur d'une procédure ou fonction
    Dim vartabl(2) As String
    Dim I As Integer
    Dim ligne As Integer
    Dim nbligne As Integer

'    nbligne = 1

'    Do While Cells(nbligne, 1).Value <> ""
'        nbligne = nbligne + 1
'    Loop

    'avantageusement remplacé par :
    nbligne = Cells(Rows.Count, 1).End(xlUp).Row

    For ligne = 1 To nbligne

        vartabl(0) = Cells(ligne, 1).Value
        vartabl(1) = Cells(ligne, 2).Value

        For I = 0 To 1 'en base 0 !

            Cells(ligne, I + 11).Value = vartabl(I)

        Next I

    Next ligne

End Sub

Avec un tableau à deux dimensions :

Sub CommandButton2_Click()

    Dim Tbl()
    Dim Lig As Integer
    Dim I As Integer

    Lig = Cells(Rows.Count, 1).End(xlUp).Row

    ReDim Tbl(1 To 2, 1 To Lig)

    For I = 1 To Lig

        Tbl(1, I) = Cells(I, 1).Value
        Tbl(2, I) = Cells(I, 2).Value

    Next I

    For I = 1 To UBound(Tbl, 2)

        Cells(I, 11).Value = Tbl(1, I)
        Cells(I, 12).Value = Tbl(2, I)

    Next I

End Sub

Bonjour,

Un complément :

Ton tableau est déclaré en type String, assure toi donc d'y stocker des valeurs au format String :

vartabl(0) = CStr(Cells(ligne, 1).Value)

PS : merci de préciser la ligne surlignée dans l'éditeur VBA lorsque l’erreur se présente.

Bonjour Pedro22,

ça ce n'est pas trop important car le compilateur adapte de façon implicite par contre, les objets vont faire planter le code si on cherche à les attribuer à un String :

Sub Test()

    Dim Tbl(1 To 5) As String
    Dim Cel As Range
    Dim S As Shape
    Dim I As Integer

    Tbl(1) = 123456789
    Tbl(2) = 123456789.456789
    Tbl(3) = #5/3/2019#
    Tbl(4) = 0.123456
    Tbl(5) = Val("543210 avec ces quelques mots")

    For I = 1 To UBound(Tbl)

        Debug.Print TypeName(Tbl(I)); " --- "; Tbl(I)

    Next I

    On Error Resume Next
    Tbl(4) = S
    If Err.Number <> 0 Then Debug.Print "Erreur avec l'objet Shape !": Err.Clear

    Tbl(5) = Cel '<--- là par contre il y aura plantage car impossible de transformer un objet en String !
    If Err.Number <> 0 Then Debug.Print "Erreur avec l'objet Range !"

End Sub

Bonjour tout le monde,

Je vous remercie pour l'ensemble des réponses et pour la rapidité et vos commentaires sur le code.

Tout fonctionne et j'ai pu optimiser mon code en ajoutant une boucle permettant de vérifier si la valeur est vide ne rien faire et si elle contient quelle chose la stocker dans vartabl.

Voici le résultat final :

Option Explicit
Private Sub CommandButton2_Click()

Dim vartabl(1) As String
Dim I As Integer
Dim ligne As Integer
Dim nbligne As Integer
Dim compteur_non_vide As Integer

'   nbligne = 1
'
'   Do While Worksheets("tableau").Cells(nbligne, 1).Value <> ""
'       nbligne = nbligne + 1
'   Loop

'Rows.count --> le nombre de ligne --> pour la colonne 1 End(xlup).row --> pour repérer la dernière ligne pleine
nbligne = Cells(Rows.Count, 1).End(xlUp).Row
compteur_non_vide = 0

'Parcourir toutes les lignes du tableau
For ligne = 1 To nbligne
' Si la valeur contient un champ vide alors ne rien faire
    If IsEmpty(Cells(ligne, 1).Value) = True Then

    'Aucune action

' Sinon effectuer cette action
    Else
        compteur_non_vide = compteur_non_vide + 1
' Stocker dans vartabl s'il existe quelque chose
        vartabl(0) = Cells(ligne, 1).Value
        vartabl(1) = Cells(ligne, 2).Value

'Coller dans I+10 les valeurs de vartabl
        For I = 0 To 1
            Cells(compteur_non_vide, I + 10).Value = vartabl(I)
        Next I
    End If

Next ligne
MsgBox ("fin")
End Sub

Bonne journée

Bonjour,

Cet extrait peut être simplifié :

If IsEmpty(Cells(ligne, 1).Value) = True Then
    'Aucune action
' Sinon effectuer cette action
Else
'...
End If

IsEmpty() renvoie true ou false, donc inutile de contrôler que true = true. Ensuite, pas besoin de mettre une condition pour ne rien faire. Voilà donc comment tu peux écrire ça :

If Not IsEmpty(Cells(ligne, 1)) Then
'...
End If

Merci

Merci

De rien, pense à indiquer que ton sujet est résolu, si c'est bien le cas !

J'ai une question svp, si je souhaite remplacer les cellules par un tableau c'est possible ? Parcourir directement le tableau et non les cellules ?

J'ai une question svp, si je souhaite remplacer les cellules par un tableau c'est possible ? Parcourir directement le tableau et non les cellules ?

Peux-tu être plus précis ? Je ne vois pas à quoi tu fais référence...

Bonjour,

Comme ceci ?

Sub Test()

    Dim Tbl
    Dim I As Integer

    Tbl = Range("A1:B" & Cells(Rows.Count, 1).End(xlUp).Row) 'mets le Range dans le tableau

    For I = 1 To UBound(Tbl, 1)

        Cells(I, 11).Value = Tbl(I, 1)
        Cells(I, 12).Value = Tbl(I, 2)

    Next I

End Sub

Bonjour,

Oui c'est bien ca mais on me dit qu'il est impossible d'affecter a un tableau

Private Sub CommandButton2_Click()

Dim vartabl(1) As String
Dim I As Integer
Dim ligne As Integer
Dim nbligne As Integer
Dim compteur_non_vide As Integer

'   nbligne = 1
'
'   Do While Worksheets("tableau").Cells(nbligne, 1).Value <> ""
'       nbligne = nbligne + 1
'   Loop

'Rows.count --> le nombre de ligne --> pour la colonne 1 End(xlup).row --> pour repérer la dernière ligne pleine
nbligne = Cells(Rows.Count, 1).End(xlUp).Row

compteur_non_vide = 0

'Stocker les valeurs du tableau et ensuite faire appel aux indices
vartabl = Range("A1:B" & Cells(Rows.Count, 1).End(xlUp).Row)
'Parcourir toutes les lignes du tableau
For ligne = 1 To nbligne
' Si la valeur contient un champ vide alors ne rien faire
    If Not IsEmpty(Cells(ligne, 1)) Then

    'Aucune action

' Sinon effectuer cette action

        compteur_non_vide = compteur_non_vide + 1
' Stocker dans vartabl s'il existe quelque chose
        vartabl(0) = Cells(ligne, 1).Value
        vartabl(1) = Cells(ligne, 2).Value
'Coller dans I+10 les valeurs de vartabl
        For I = 0 To UBound(vartabl, 1)
            Cells(compteur_non_vide, I + 10).Value = vartabl(I)
        Next I
    End If

Next ligne
MsgBox ("fin")
End Sub

Par contre si je mes vartabl = Range("A1:B" & Cells(Rows.Count, 1).End(xlUp).Row) en commentaire tout fonctionne donc je pense ce n'est pas necessaire

Quand tu affectes un Range à un tableau, ce dernier doit être de type Variant que tu peux déclarer indifféremment :

Dim T 'type par défaut
'ou :
Dim T As Variant

et ne doit pas être dimensionné.

Petite précision, par défaut, la base des tableau est en base 0 (si pas précisé en tête de module avec "Option Base 1") mais pas pour les tableaux à qui on a affecter un Range, dans ce cas, la base est 1 :

Ceci va générer une erreur même si toutes les valeurs du Range sont de type String :

Dim T As String
T = Range("A1:B20")

Ceci fonctionne :

Dim T
T = Range("A1:B20")

pour accéder au tableau, voici les deux extrémités (cellule la plus en haut et à gauche et cellule la plus en bas et à droite) :

Dim T
T = Range("A1:B20")
MsgBox T(1, 1) 'première cellule en haut à gauche (donc, A1)
MsgBox T(UBound(T, 1), UBound(T, 2)) 'dernière cellule en bas à droite (et bien c'est B20)

Il est possible d'affecter un tableau dimensionné à un Range mais pas le contraire, c'est bête mais c'est comme ça !

Sub Test()

    Dim T() As String
    Dim I As Integer
    Dim J As Integer

    ReDim T(1 To Range("A1:B20").Rows.Count, 1 To Range("A1:B20").Columns.Count)

    For I = 1 To Range("A1:B20").Rows.Count: For J = 1 To Range("A1:B20").Columns.Count

            T(I, J) = Range("A1:B20").Cells(I, J).Value

    Next J, I

    Range("D1:E20").Value = T

End Sub

:

et comme le tableau a été au préalable dimensionné, tu peux utiliser les dimensions pour les boucles :

Sub Test()

    Dim T() As String
    Dim I As Integer
    Dim J As Integer

    ReDim T(1 To Range("A1:B20").Rows.Count, 1 To Range("A1:B20").Columns.Count)

    For I = 1 To UBound(T, 1): For J = 1 To UBound(T, 2)

            T(I, J) = Range("A1:B20").Cells(I, J).Value

    Next J, I

    Range("D1:E20").Value = T

End Sub

Bonjour,

Je vous remercie.

Private Sub CommandButton1_Click()

' Déclaration d'un tableau

    Dim T() As String
    'Déclaration pour le nombre de ligne
    Dim I As Integer
    'Déclaration pour le nombre de colonne
    Dim J As Integer

    'redimensionner le tableau en prennant toutes les lignes et colonnes de la plage A1 vers B20
    ReDim T(1 To Range("A1:B20").Rows.Count, 1 To Range("A1:B20").Columns.Count)

    'Compter le nombre de ligne et récuperer la dernière ligne pleine
    'nbligne = Cells(Rows.Count, 1).End(xlUp).Row

    ' Compter toutes les lignes et colonnes de la plage
    For I = 1 To Range("A1:B20").Rows.Count: For J = 1 To Range("A1:B20").Columns.Count

'Retirer toutes les lignes vides de la plage D à E
'For I = 1 To Worksheets("tableau").Count
Worksheets("tableau").Range("D1:E20").SpecialCells(xlCellTypeBlanks).EntireRow.Delete
'Le tableau T stocke comme valeur les lignes et colonne de la plage
            T(I, J) = Range("A1:B20").Cells(I, J).Value

    Next J, I

    Range("D1:E20").Value = T

End Sub

Cependant, j'ai un autre petit problème lorsque j'exécute mon code en ayant ajouter d'autre ligne après une séparation tout ce supprime.

Je pense que les lignes vides se supprime suite au redim, comment puis je mettre un redim preserve et supprimer les lignes vides sans tout supprimer ?

Merci d'avance !!!

Bonjour,

Il y à trois façons de dimensionner un tableau, dans la déclaration de la variable :

Dim Tbl(1 To 10)

après avoir déclaré le tableau et juste avant de l'utiliser :

'le tableau étant déclaré, on le redimensionne par la suite
Dim Tbl()
'...
'...
ReDim Tbl(1 To 10)

Le dimensionnement est fait au fur et à mesure et "Preserve" permet justement de préserver ce que contient déjà le tableau :

'à une dimensions...
I = I + 1
ReDim Preserve Tbl(1 To I)

'Attention, dans un tableau à plusieurs dimensions, seule la dernière peut être modifiée !
'à deux dimensions...
I = I + 1
ReDim Preserve Tbl(1 To 3, 1 To I) '1 to 3 ne peut être modifiée !
'...
'à trois dimensions...
I = I + 1
ReDim Preserve Tbl(1 To 3, 1 To 5, 1 To I) '1 to 3 et 1 to 5 ne peuvent être modifiées !
'au delà de trois dimensions ça devient très difficile à gérer car on a pas de représentation visuelle facile de ce que ça peut représenter
Rechercher des sujets similaires à "problematique vba"