Aide sur fonction tableau

Bonjour tout le monde !

je reviens vers vous concernant un autre sujet.

je viens de découvrir il y à quelques jours, la fonction "tableau" en vba. fonction que je trouve d'ailleurs très pratique....

jusqu'à 2 variantes "tout va bien", mais au delà tout se complique.

j'ai donc besoin de mettre en mémoire une plage de cellules comprises entre la ligne 25 à 61 step 1 se trouvant sur les colonnes 10 à 175 en step 15 et tout ça sur un nombre d'onglet non défini...

je pense ne pas être trop loin de la vérité mais les les boucles For me donne un peu de fil à retordre.

je vous joins le code ci-dessous à savoir que mon erreur(Erreur d'execution '9: L'indice n'appartient pas à la sélection.) se situe juste après le

ReDim Preserve etage(n, j - 1)

Pourriez-vous s'il vous plais m'aiguiller un peu...

(LE CODE SE TROUVE DANS L'ONGLET 1 DU CLASSEUR PLANNING)

Merci par avance

Sub etage()
'NOM ETAGE
Dim ws As Workbook
Dim etage() As Variant
Dim j As Variant
Dim k As Integer
Dim l As Integer
Dim n As Integer
Set ws = Workbooks("SYNOPTIQUE.xlsm")
For j = 1 To Sheets.Count
n = 0
    For k = 10 To 175 Step 15
        For l = 25 To 61
        ReDim Preserve etage(n, j - 1)
        etage(n, j - 1) = ws.Worksheets(j).cells(l, k)
        Debug.Print etage(n, j - 1)
        n = n + 1
        Next
    n = n + 36
    Next
Next
End Sub
13synoptique.xlsm (236.48 Ko)
16planning-octo.zip (277.40 Ko)

Bonjour,

Il vous faut dimensionner n (en fonction de k et l) dès le départ car seule la dernière dimension (J dans votre cas) du tableau peut varier avec Preserve.

Salut Charly,
Salut Kergresse,

comme je vois l'affaire, le nombre de Sheets est facilement calculable, le nombre de lignes fixe (25-61) et le nombre de colonnes itou (10-175 step 15 = 12 colonnes)

ReDim Etage(iSheet, 37, 12)

Je me trompe ?


A+

Bonjour,

Si la matrice doit être utilisée en dehors de la procédure, il faut la déclarer a minima Private voire Public si utilisation dans un autre module ou userform.

Le nom de la matrice ne doit pas porter le nom d'une procédure.

Avoir une variable tableau portant sur la totalité des onglets la rend difficilement exploitable, il faudrait mieux travailler onglet par onglet.

Option Explicit

Public MatriceEtage() As Variant, IndexN As Integer

Sub etage()
'NOM ETAGE
Dim WB As Workbook
Dim J As Integer, K As Integer, L As Integer, N As Integer

    Set WB = Workbooks("SYNOPTIQUE.xlsm")
    N = (12 * 37) - 1
    For J = 1 To Sheets.Count
        IndexN = 0
        ReDim Preserve MatriceEtage(N, J - 1)
        For K = 10 To 175 Step 15
            For L = 25 To 61
                MatriceEtage(IndexN, J - 1) = WB.Worksheets(J).Cells(L, K)
                Debug.Print MatriceEtage(IndexN, J - 1)
                IndexN = IndexN + 1
            Next L
        Next K
    Next J

    Set WB = Nothing

End Sub

Merci Messieurs Kergresse et Curulis pour votre précieuse aide !

ça marche parfaitement !

Du coup, vous l'avez compris, j'ai une macro de ce type à réaliser pour récupérer et stocker des informations sur:

Les chantiers (1 onglet par chantier)

Le nombre de bâtiments par/chantiers

Les noms et nombres d'étages par /bâtiments/chantiers (macros sur cette page)

les dates par/étages/bâtiments/chantiers

Du coup, préconisez vous de créer un module par type de macro dans le classeur synoptique ? Et comment appeler par la suite chaque tableau pour les comparer dans des formules... On ma parlé de requête SQL est-ce la solution la plus simple ?

Et M. Kergresse quand vous me dîtes :

"Avoir une variable tableau portant sur la totalité des onglets la rend difficilement exploitable, il faudrait mieux travailler onglet par onglet."

Dois je créer une macro par onglet (chantier) OU est-ce que la rotation des onglets dans la deuxième dimension du tableau suffit-elle ?

Merci encore pour le temps que vous avez bien voulu m'accorder !

Bonne journée !

Inutile de créer une macro par onglet, il faut rendre la procédure paramétrable :

Option Explicit

Public MatriceEtage() As Variant, IndexK As Integer, IndexL As Integer

Sub Test()

Dim I As Integer

    For I = 1 To Sheets.Count
        Erase MatriceEtage
        Etage2 Sheets(I)
        ' Suite du traitement
        '.....
    Next I

End Sub

Sub Etage2(ByVal Sh As Worksheet)

Dim J As Integer, K As Integer, L As Integer

    With Sh
         IndexK = 0: IndexL = 0
         ReDim MatriceEtage(36, 11)
         For K = 10 To 175 Step 15
             For L = 25 To 61
                    MatriceEtage(IndexL, IndexK) = .Cells(L, K)
                    'Debug.Print MatriceEtage(IndexL, IndexK)
                    IndexL = IndexL + 1
                    If IndexL = 37 Then
                       IndexK = IndexK + 1
                       IndexL = 0
                    End If
             Next L
         Next K

    End With

End Sub

Merci pour votre retour.

Si je comprends bien, vous déclarer dans "Sub Etage2" la macro type puis dans "Sub Test" vous faites tourner dans chaque onglet la macro type(SubEtage2).

Par contre j'ai 2 questions:

la commande "Etage2 Sheets(I) suffit ? ( pas de beoin de set ... ou autre chose ?)

" 'suite du traitement" signifie que c'est à cette endroit que je peux développer mes comparaisons entre tableaux ?

ex: If PlanningChantier Sheets(J) = Chantier Sheets(I) Then

If PlanningBatiment Sheets(J) = Batiment Sheets(I) Then

If PlanningEtage Sheets(J) = Etage2 Sheets(I) Then

vrai: ...........

Else if Next J

End if

End if

End if

PALOMABAT ARDC
NOM DE L'AFFAIREPALOMA
BAT A
03/01/2022RDC
17/01/2022R+1
31/01/2022R+2
14/02/2022R+3
28/02/2022R+4

Merci encore !

C'est mieux d'instancier une variable Worksheet car vous bénéficiez de l'intellisens (Un point derrière la variable et vous avez accès aux propriétés, méthodes, événements possibles pour l'objet, ce qui est très facilitant). Ne pas oublier de supprimer la variable lorsque vous n'en avez plus besoin : Set Sh = Nothing.

ok merci encore de m'avoir accorder votre temps, j'essaye tout ça et je vous ferez un retour du code au cas où ça pourrait servir à quelqu'un...

Bonne journée

Bonjour M. Kergresse

Je reviens vous concernant la syntaxe du début d'un développement de formule... J'ai essayé de suivre vos conseils, l'enregistrement de mes tableaux se passe bien et j'arrive enfin ce soir à ma première formule.... Mais comme je m'y attendez, ça ne fonctionne pas ! J'ai essayé d'adapter votre code fournis hier à 08h56 mais rien n'y fait. Et je ne sais plus par où commencer, j'ai tester mes tableaux avec un debugprint, ca fonctionne. J'ai relevé avec attention la position dans les tableaux des différents éléments pour que les comparaisons coïncides. Mais là après une longue journée je coince

Auriez vous la gentillesse de m'aiguiller une nouvelle fois ?

Option Explicit
Public MatricePlanning() As Variant, IndexA As Integer, IndexB As Integer, IndexC As Integer, IndexD As Integer, IndexE As Integer, IndexF As Integer, IndexG As Integer, IndexH As Integer, IndexI As Integer, IndexJ As Integer, IndexK As Integer, IndexL As Integer, IndexM As Integer, IndexN As Integer, IndexO As Integer, IndexP As Integer, IndexQ As Integer, IndexR As Integer, IndexS As Integer, IndexT As Integer

Sub ChantierPlanning(ByVal Sh As Worksheet)
Dim wp As Workbook
Dim Worksheets As Worksheet
Dim A As Integer
Dim B As Integer
'Dim IndexA As Integer
'Dim IndexB As Integer
Dim ChantierPlanning() As Variant
'Dim I As Integer, A As Integer, B As Integer, N As Integer
'Set wp = Workbooks("PLANNING-OCTO+.xlsm")
    With Sh
        'SEMAINE 1
        IndexA = 0: IndexB = 0
        ReDim ChantierPlanning(9, 24)
        For A = 1 To 37 Step 9
            For B = 5 To 14 Step 1
                ChantierPlanning(IndexB, IndexA) = wp.Worksheets(2).Cells(B, A) '.Cells(B, A)
                'Debug.Print ChantierPlanning(IndexB, IndexA)
                IndexB = IndexB + 1
                If IndexB = 10 Then
                    IndexA = IndexA + 1
                    IndexB = 0
                End If
            Next B
        Next A
        'SEMAINE 2
        IndexA = 5: IndexB = 0
        ReDim ChantierPlanning(9, 24)
        For A = 1 To 37 Step 9
            For B = 23 To 32 Step 1
                ChantierPlanning(IndexB, IndexA) = wp.Worksheets(2).Cells(B, A) '.Cells(B, A)
                'Debug.Print ChantierPlanning(IndexB, IndexA)
                IndexB = IndexB + 1
                If IndexB = 10 Then
                    IndexA = IndexA + 1
                    IndexB = 0
                End If
            Next B
        Next A
        'SEMAINE 3
        IndexA = 10: IndexB = 0
        ReDim ChantierPlanning(9, 24)
        For A = 1 To 37 Step 9
            For B = 41 To 50 Step 1
                ChantierPlanning(IndexB, IndexA) = wp.Worksheets(2).Cells(B, A) '.Cells(B, A)
                'Debug.Print ChantierPlanning(IndexB, IndexA)
                IndexB = IndexB + 1
                If IndexB = 10 Then
                    IndexA = IndexA + 1
                    IndexB = 0
                End If
            Next B
        Next A
        'SEMAINE 4
        IndexA = 15: IndexB = 0
        ReDim ChantierPlanning(9, 24)
        For A = 1 To 37 Step 9
            For B = 59 To 68 Step 1
                ChantierPlanning(IndexB, IndexA) = wp.Worksheets(2).Cells(B, A) '.Cells(B, A)
                'Debug.Print ChantierPlanning(IndexB, IndexA)
                IndexB = IndexB + 1
                If IndexB = 10 Then
                    IndexA = IndexA + 1
                    IndexB = 0
                End If
            Next B
        Next A
        'SEMAINE 5
        IndexA = 20: IndexB = 0
        ReDim ChantierPlanning(9, 24)
        For A = 1 To 37 Step 9
            For B = 77 To 86 Step 1
                ChantierPlanning(IndexB, IndexA) = wp.Worksheets(2).Cells(B, A) '.Cells(B, A)
                'Debug.Print ChantierPlanning(IndexB, IndexA)
                IndexB = IndexB + 1
                If IndexB = 10 Then
                    IndexA = IndexA + 1
                    IndexB = 0
                End If
            Next B
        Next A
    End With
End Sub

Sub chantier()
'NOM CHANTIER
Dim ws As Workbook
Dim As Integer
Set ws = Workbooks("SYNOPTIQUE.xlsm")
    For J = 1 To Sheets.Count
    ReDim Preserve MatriceChantier(J)
    MatriceChantier(J - 1) = ws.Worksheets(J).Cells(6, 2)
    'Debug.Print MatriceChantier(J - 1)
    Next
Set ws = Nothing
End Sub

Sub test()
Dim wp As Workbook
Dim ws As Workbook
Dim I As Integer
Dim J As Integer
Dim ChantierPlanning As Variant
Dim MatriceChantier As Variant

Set wp = Workbooks("PLANNING-OCTO+.xlsm")
Set ws = Workbooks("SYNOPTIQUE.xlsm")

    For I = 1 To Sheets.Count
        For J = 1 To Sheets.Count
            If wp.ChantierPlanning().Sheets(I).Value = "PALOMA" Then  'MatriceChantier().ws.Worksheets(J).Value Then
            ChantierPlanning.wp.Sheets(I).Cells(5, 4).Text = "VICTOIRE"
            End If
        Next J
    Next I
Set ws = Nothing
Set wp = Nothing

Pourriez-vous expliquer plus dans le détail ce que vous devez faire une fois une variable tableau chargée ?

Bonjour,

Je souhaite comparer différents TABLEAUX qui appartiennent aux classeurs PLANNING-OCTO+.xlsm et SYNOPTIQUE..xlm:

Le tableau SYNOPTIQUE rassemble les différents chantier de ma société(1chantier par onglet):

1) Le Nom du chantier en B6

2)Les noms des bâtiments en J23 / Y23 .... (Le nombre de bâtiment varie selon les chantiers)

3)Les Etages de chaque bâtiment en RANGE(J25,J61) .....

4)Les Dates de livraisons de ces étages en RANGE(I23,I61)....

5)Le Chiffre d'Affaire de ces étages en RANGE(I68,I102)...

6)Un Chiffre représentant un temps de production par étage en RANGE(O68,O102)....

Le tableau PLANNING rassemble toutes les dates sur 15 mois + onglet SOURCE concernant LES DATES DE CONGES, LES COEFF de capacité de production/jour et un nombre de jour pour la mise en production avant la date de livraison:

7) Date du jour en A1 / J1....

8) Noms des chantiers en RANGE(A5,A14).....

9)Noms des bâtiments en RANGE(B5,B14)....

10)Noms des étages en RANGE(C5,C14)....

11)Chiffre d'affaire par Etages en RANGE(D5,D14)...

12)Temps de production estimé en RANGE(E5,E14)...

13)Dates de livraisons estimés en RANGE(H5,H14)...

14)Temps de Production Total par Jour en C16/L16...

Je souhaiterai donc:

Si 4) = 7) -intervalle B5-B6(onglet source)

ET Si 14)<intervalle B4-B5(onglet source)

FAUX = 7) + 1

VRAI=

8) =1)

9)=2)

10)=3)

11)=5)

12)=6)

13)=4)

Bien sûr je ne voudrais pas abuser de votre temps et donc j'ai commencer par une petite formule toute "simple" :

Si 8) = PALOMA

alors

ChantierPlanning.wp.Sheets(I).Cells(5, 4).Text = "VICTOIRE"

Mais ma syntaxe n'est pas malheureusement pas bonne.

Je vous glisse également les fichiers car je pense que copier le code ici chargerai un peu trop ce post.

Le 1) se trouve dans le module1 de SYNOPTIQUE

Le 2) se trouve dans le module2 de SYNOPTIQUE

Le 3) se trouve dans le module3 de SYNOPTIQUE

Le 4) se trouve dans le module4 de SYNOPTIQUE

Le 5) se trouve dans le module5 de SYNOPTIQUE

Le 6) se trouve dans le module6 de SYNOPTIQUE

Le 7) se trouve dans le module1 de PLANNING

Le 8) se trouve dans le module2 de PLANNING

Le 9) se trouve dans le module3 de PLANNING

Le 10) se trouve dans le module4 de PLANNING

Le 11) se trouve dans le module5 de PLANNING

Le 12) se trouve dans le module6 de PLANNING

Le 13) se trouve dans le module7 de PLANNING

Le 14) se trouve dans le module9 de PLANNING

Merci encore

Cordialement

21planning-octo.zip (288.94 Ko)
21synoptique.xlsm (228.20 Ko)

Ne perdez pas votre temps je viens de comprendre mon erreur !

Merci !

Du coup je reviens quand même.

J'ai enfin fini (je cois) les tableaux et grâce à vous, les variables sur les onglets sont effectivement beaucoup plus compréhensibles !

Maintenant je voudrais faire fonctionner mes tableaux ensemble:

_ Dois-je transposer mes tableaux qui sont actuellement en mode "SUB" en mode "FUNCTION" ?

_ Et comment se passe la syntaxe de ces formules en intégrant des modules externes ?

Je vous joins mes 2 classeurs que j'ai remis à jour aujourd'hui par rapport à mon post de ce matin.

Si vous voulez en savoir plus, je veux réaliser des IF imbriqués comme décrit ce matin.

Merci et bonne soirée

10planning-octo.zip (306.33 Ko)
6synoptique.xlsm (227.97 Ko)

Bonjour,

Désolé, mais je ne pige pas ce qu'il y a à faire.

Une fois que vous avez chargé la première variable tableau, que faites-vous après dans vos deux fichiers ?

Bonjour,

je souhaiterai comparer les contenus des variables tableau sous la forme d'une fonction IF:

par exemple:

If Module4 = Module 1

alors ....

Est-ce que excel va exécuter le Sub du Module 4 et du Module 1 pour vérifier si dans un des emplacements du Module 1 il retrouve la même information.

En l'occurrence il s'agit d'une date donc je veux que par exemple que le LUNDI 2 JANVIER 2023 (emplacement MatricePlanDatJ(0,0))soit comparer avec MatriceSynoDate() et que si il retrouve la même date il me valide le IF en vrai. ce qui emmènera un autre IF imbriqué pour comparer deux autres matrice ensemble pour validé ou non le IF etc...

Merci encore

Désolé, je n'ai sans doute pas le niveau pour vous répondre.

Merci quand même !

Bonjour,

Si je peux me permettre... Je pense que tu n'as pas complètement digéré l'utilisation des tableaux (Array).

Ce qui n'est pas vraiment étonnant car cela demande une très bonne capacité d'abstraction.

Aussi je vais essayer d'être le plus clair possible pour te dire ce que j'ai compris de l'examen de tes classeurs.

D'abord sur la syntaxe :

Dans ce qui suit j'utilise exclusivement la notion d'Array pour nommer ou parler d'une Matrice.

Par suite mes matrices sont toutes baptisées ArrPlanBatTruc, ArrCalTub... etc...

Plus rarement, en admettant que ce soit nécessaire, si je devais créer une matrice de 20 éléments je la baptiserai (déclarerai...)

Dim TiD(19)

Ainsi au lieu de déclarer 20 index (indexA, indexB...) c'est TiD(1), TiD(2) qui prendrait en charge l'indexation...

Sur l'ergonomie des feuilles et des Array : Il est bien plus facile d'utiliser des Array de tableaux que des Array de damiers.

Surtout quand il s'agit de calendriers... C'est pourquoi ce type de calendrier est bien peu pratique à l'utilisation !

Mébon... On est bien obligé de faire avec ce qu'on a :

Sur la déclaration de tes tableaux :

Il vaut mieux éviter les Redim, ce qui est pénalisant en terme d'optimisation. Donc une déclaration "sèche" est préférable.

Ainsi pour DateJour vous auriez pu faire :

Sub DatJour(ByVal Ws As Worksheet)
Dim Arr
    With Ws
        Arr = .Range("A1:AS88").Value
    End With
End Sub

Toujours en admettant que ce soit indispensable. Hein... Vous me suivez ?

Pourquoi cette dernière réflexion ?

Parce que on peux considérer un classeur et ses feuilles comme un tableau 3D dont :

La première dimension est l'index de Feuille

La deuxième l'index de ligne

La troisième l'index de colonne...

A cet égard si le but est de faire des comparaisons de feuille à feuilles

Il est très simple de faire un array parmi les cellules de ces feuilles et de comparer toutes les cellules A5 de ces feuilles ou toutes les cellules B8 par exemple.

Ainsi plutôt que de charger tous les calendriers (16) ce qui reste possible (ne me faites pas dire ce que n'ai pas dit) il peut s'avérer préférable de charger toutes les cellules A16 de chaque journée, de chaque mois éventuellement....

Mais à mon avis il me semble illusoire d'espérer charger tous les calendriers en bloc et de faire vos tripatouillages la dedans en espérant y retrouver vos petits... Vous m'objecterez (et vous aurez sans doute raison) que je n'ai sans doute pas des capacités d'abstraction suffisante (Vu mon grand âge, mes connexions neuronales sont en net déclin...)

Mébon...

Comme Eric, je n'ai pas trop compris dans vos explications sur ce que vous voulez faire comme comparaison.

Aussi je commencerai par faire un tableau Cible des éléments que vous voulez comparer

Ex : tous les A16, A34, 52... J16,34,52... et les autres...

ou : tous les C16, C34,...

Puis remplir ce tableau critères de comparaison par critère de comparaison successivement, plutôt que ArrCal par ArrCal

Vous ferez simplement un ArrCellWS plus petit (16 éléments) pour tous les A16 de chaque feuille puis le même 16 éléments pour tous les A34

au pire 80 éléments pour les 5 jours...

=> Préalablement, moi personnellement pour gagner du temps dans l'analyse (vu l'état de mes neurones...) j'aurais seulement transposé tous vos calendriers en quinconce en calendrier vertical (ou horizontal) afin d'avoir un ciblage plus facile dans l'analyse...

Sur un calendrier de ce type je prendrais peut être le risque de charger tous les calendriers en mémoire, avant de faire un tableau de comparaison. Et encore je ne suis pas certain...

Mébon... Encore une fois, vous pouvez toujours essayer de considérer tous vos Array de feuilles comme des éléments d'un Array 3D, mais les mecs qui jonglent avec des Array à plus de 2 dimensions ne sont pas légion sur les forums. Habituellement ce genre de gymnastique intellectuelle est plutôt réservée à des gens qui savent ou ils mettent les pieds...

Sans méchant sous-entendu !

Heu... Bon finalement je ne sais pas si j'ai été suffisamment clair !

A+

Merci beaucoup M. Galopin !

Je vais tout d'abord digérer tout ça, car je vous avoues, qu'à ma première lecture, au vu de mon niveau, je n'ai pas tout assimilé...

Par contre en ce qui concerne le tableau de planning je peux le modifier si besoin. Mais je dois quand même rendre tout ça lisible pour mes collègues...

Peut-être devrais-je dans un premier temps réaliser une BD dans un onglet caché pour que le code soit plus "pratique". Puis, aller afficher dans un second tableau plus esthétiquement adapté les informations résultantes de mes macros...

A méditer ! Je planche là-dessus et si je peux me permettre, une fois que j'aurais compris votre science, je reviendrai vers vous !

Merci encore !

Rechercher des sujets similaires à "aide fonction tableau"