[VBA] Petite Question sur les Array's

Petite Question sur les Array's [VBA] - VB/VBA/VBS - Programmation

Marsh Posté le 05-06-2008 à 12:23:09    

Bonjour à tous,
 
J'ai un code comme celui-ci :

Code :
  1. Private Sub GenerationPDF_Click()
  2. Dim WSheet As Worksheet
  3. Dim Zone_Impr()
  4. If Cmb_TBB = "TBB Complet (Indicateurs Mensuels, Trimestriels & Semestriels)" Then
  5.     For Each WSheet In Sheets
  6.         If (Left(WSheet.Name, 2) = "RF" Or Left(WSheet.Name, 2) = "RC" ) Then
  7.            
  8.             ' Redimensionnement de l'Array pour ajouter un nouvel onglet à la séléction
  9.             ReDim Preserve Zone_Impr(UBound(Zone_Impr) + 1)
  10.             ' Ajout du nouvel onglet à la séléction
  11.             Zone_Impr(UBound(Zone_Impr)) = WSheet.Name
  12.            
  13.         End If
  14.     Next
  15.        
  16. End If
  17. End Sub


 
La macro plante sur la ligne...

Code :
  1. ReDim Preserve Zone_Impr(UBound(Zone_Impr) + 1)


 
... me disant que "l'indice n'appartient pas à la séléction" !
 
Pourtant, dans cette ligne, je ne fais qu'ajouter un ligne à mon tableau avant d'insérer la valeur, non ?
 
Merci pour vos réponses,
 
ps : le but est pourtant simple : mettre dans le tableau les feuilles dont le nom commence par RF ou RC en vue de les séléctionner pour une impression en PDF...
 
Encore merci !

Reply

Marsh Posté le 05-06-2008 à 12:23:09   

Reply

Marsh Posté le 05-06-2008 à 13:22:28    

Votre façon de faire est différente de celle que l'on faisait dans ma jeunesse, où l'on définissait un tableau avec une taille déterminée, et ensuite on pouvait éventuellement l'agrandir.
 
Là votre tableau a dès le début une taille indéterminée, et donc je trouve bizarre de faire Redim pour ce genre de tableau. Est-ce que vous pouriez essayer sans le Redim, ou bien pour un autre essai, mettez une taille fixe au tableau au début ?

Reply

Marsh Posté le 05-06-2008 à 13:27:39    

Bonjour,
 
Il me semble que lorsque l'on utilise Redim il ne faut pas faire de Dim avant.
 

Reply

Marsh Posté le 05-06-2008 à 14:27:04    

Merci pour vos réponses...
 
Si je ne fais pas de Dim avant, il me dit que ma variable n'a pas été déclarée...
 
Si je ne met pas le Redim, il va vider le tableau a chaque fois que je vais venir ecrire dedans non ?
 
Et si je mets une taille fixe au tableau, il me dit que j'ai déja défini une taille au tableau au moment ou il passe sur le Redim...
 
Bref, je suis un peu perdu !

Reply

Marsh Posté le 05-06-2008 à 14:44:01    

Une autre idée
Le problème ne viendrait-il pas de :
 
ReDim Preserve Zone_Impr(UBound(Zone_Impr) + 1)
 
Au premier passage de cette ligne Ubound n'a aucune valeur
 
si tu mets un compteur  
cpt=cpt+1
ReDim Preserve Zone_Impr(cpt)
 
et tout ça sans DIM avant

Reply

Marsh Posté le 05-06-2008 à 15:55:50    

si, je mets pas de dim, ca passe pas au lancement : il me dit que "zone_impr" n'a pas été déclaré...
 
Je vais essayer ton truc, mais pour moi, je pensais que UBound(Zone_Impr) = 0, non (au premier passage) ?
 
j'essaie et je reviens !


Message édité par jay-jay69 le 05-06-2008 à 15:56:09
Reply

Marsh Posté le 05-06-2008 à 16:37:29    

bonjour,
pourquoi s'enquiquiner avec un array... utilise une collection :

Code :
  1. Private Sub GenerationPDF_Click()
  2. Dim WS As Worksheet
  3. Dim ZImp As New Collection
  4. If Cmb_TBB = "TBB Complet (Indicateurs Mensuels, Trimestriels & Semestriels)" Then
  5.     For Each WS In Sheets
  6.         If (Left(WS.Name, 2) = "RF" Or Left(WS.Name, 2) = "RC" ) Then
  7.             ' Ajout du nouvel onglet à la séléction
  8.             ZImp.Add WS.Name
  9.         End If
  10.        
  11.     Next
  12. For i = 1 To ZImp.Count
  13. MsgBox ZImp(i)
  14. Next
  15. End If
  16. End Sub


A+
 
Oups... petite correction !


Message édité par galopin01 le 05-06-2008 à 16:40:40
Reply

Marsh Posté le 05-06-2008 à 16:53:52    

Et on peut imprimer une collection comme ca ??
 
Merci en tout cas !!

Reply

Marsh Posté le 05-06-2008 à 17:00:36    

...sinon, pour reprendre la suggestion de pyrof :

Code :
  1. Private Sub GenerationPDF_Click()
  2. Dim WS As Worksheet
  3. Dim ZImp()
  4. If Cmb_TBB = "TBB Complet (Indicateurs Mensuels, Trimestriels & Semestriels)" Then
  5.     For Each WS In Sheets
  6.         If (Left(WS.Name, 2) = "RF" Or Left(WS.Name, 2) = "RC" ) Then
  7.         cpt = cpt + 1
  8.             ' Redimensionnement de l'Array pour ajouter un nouvel onglet à la séléction
  9.             ReDim Preserve ZImp(cpt)
  10.             ' Ajout du nouvel onglet à la séléction
  11.             ZImp(cpt) = WS.Name
  12.          
  13.         End If
  14.     Next
  15. For i = 1 To cpt
  16. MsgBox ZImp(i)
  17. Next
  18. End If
  19. End Sub


A+

Reply

Marsh Posté le 05-06-2008 à 17:12:40    

Pour répondre à la question soulevée initialement, à savoir pourquoi ça plante avec les lignes de code qu'a montrées jay-jay69, c'est simplement parce que ton UBound() ne peut fonctionner qu'avec un tableau dont les dimensions sont initialisées.
 
Or, ton code fait

Dim Zone_Impr()

puis

ReDim Preserve Zone_Impr(UBound(Zone_Impr) + 1)

Donc, quand UBound() est appelée, Zone_Impr() n'a encore aucune dimension et plante.
 
Il faudrait un

ReDim Zone_Impr(0)

entre le Dim et le ReDim(... UBound(...))

Reply

Marsh Posté le 05-06-2008 à 17:12:40   

Reply

Marsh Posté le 05-06-2008 à 17:20:38    

Merci pour toutes vos réponses, je comprends mieux !
 
Un autre probleme se pose :
 

Code :
  1. Private Sub GenerationPDF_Click()
  2. Dim WSheet As Worksheet
  3. Dim Zone_Impr()
  4. Dim cpt As Integer
  5. cpt = 1
  6. If Cmb_TBB = "TBB Complet (Indicateurs Mensuels, Trimestriels & Semestriels)" Then
  7.     For Each WSheet In Sheets
  8.         If (Left(WSheet.Name, 2) = "RF" Or Left(WSheet.Name, 2) = "RC" ) Then
  9.             cpt = cpt + 1
  10.             ' Redimensionnement de l'Array pour ajouter un nouvel onglet à la séléction
  11.             ReDim Preserve Zone_Impr(cpt)
  12.             ' Ajout du nouvel onglet à la séléction
  13.             Zone_Impr(cpt) = WSheet.Name
  14.            
  15.         End If
  16.     Next
  17.    
  18.     Sheets(Zone_Impr).Select
  19.    
  20.     Application.ActivePrinter = "Adobe PDF sur Ne09:"
  21.     ActiveWorkbook.PrintOut Copies:=1, ActivePrinter:="Adobe PDF sur Ne09:", _
  22.         Collate:=True, PrToFileName:="c:\test.pdf"
  23.    
  24.    
  25. End If
  26. End Sub


 
Il ne semble pas aimer la ligne "Sheets(Zone_Impr).Select", alors que tout simplement, je souhaite selectionner les feuilles récupérées dans mon Array...
 

Reply

Marsh Posté le 06-06-2008 à 15:46:35    

Bonjour,
 
Voici une toute autre façon de générer un tableau de valeur
 
 
Sub toto()
 
Dim ar       'Crée une variable
Set ar = CreateObject("Scripting.Dictionary" )
 
For Each feuille In ActiveWorkbook.Sheets
    ar(feuille.Name) = "1"
Next
 
For Each tmp In ar
    cle = tmp
    MsgBox tmp
Next
End Sub
 

Reply

Marsh Posté le 07-06-2008 à 18:04:19    

Modifs code 13 Jun 2008
Salut,après suppression de mes 2 posts précédents pour une meilleure lisibilté
3 remarques :  
   PrToFileName génère un fichier ps ( PostScript ) et non un pdf  
   Le N° d'imprimante Nexy change suivant le PC sur laquelle la macro tourne  
   Il faut prédéfinir soit manuellement ou par programmation pour chaque feuille la zone d'impression
 
Au final qqch qui ressemblera à ceci, à toi de l'adapter à ton contexte
Le titre de ton post devrait être changé


Option Explicit
Dim sNomPortReseau As String
 
Sub Tst2()
Dim sNomFichierPS As String
Dim sNomFichierPDF As String
Dim sNomFichierLog As String
Dim PDFDist As PdfDistiller, PrinterDefault As String
Dim i As Long, Cpt As Long
Dim Ar() As Variant
 
    ZonesImpression
 
    Cpt = 0  
    For i = 1 To ThisWorkbook.Sheets.Count
        If UCase(Left(Sheets(i).Name, 2)) = "RF" Or _
           UCase(Left(Sheets(i).Name, 2)) = "RC" Then
            ReDim Preserve Ar(Cpt)
            Ar(Cpt) = Sheets(i).Name
            Cpt = Cpt + 1
        End If
    Next i
    If Cpt = 0 Then Exit Sub  
 
    PrinterDefault = Application.ActivePrinter
    If Imprimante_AdobePDF Then
        Application.ActivePrinter = sNomPortReseau
    Else
        MsgBox "Pas d'imprimante Adobe PDF sur NeXY ", vbOKOnly + vbCritical, "Achtung"
        Exit Sub
    End If
 
    Application.ScreenUpdating = False
    sNomFichierPS = ThisWorkbook.Path & "\" & "Essai.ps"
    sNomFichierPDF = ThisWorkbook.Path & "\" & "Essai.pdf"
    sNomFichierLog = ThisWorkbook.Path & "\" & "Essai.log"
 
    Sheets(Ar).PrintOut copies:=1, Preview:=False, _
                        ActivePrinter:=sNomPortReseau, PrintToFile:=True, _
                        PrToFileName:=sNomFichierPS
 
    Set PDFDist = New PdfDistiller
    PDFDist.FileToPDF sNomFichierPS, sNomFichierPDF, ""
    Set PDFDist = Nothing
 
    Kill sNomFichierPS
    Kill sNomFichierLog
 
    With Application
        .ScreenUpdating = True
        .ActivePrinter = PrinterDefault
    End With
    Sheets("Feuil1" ).Select
End Sub
 
Private Sub ZonesImpression()
    Sheets("Feuil1" ).PageSetup.PrintArea = "$A$1:$H$33"
    Sheets("Feuil2" ).PageSetup.PrintArea = "$A$1:$H$42"
    Sheets("Feuil3" ).PageSetup.PrintArea = "$A$1:$H$55"
    Sheets("Feuil4" ).PageSetup.PrintArea = "$A$1:$D$8"
    Sheets("Feuil5" ).PageSetup.PrintArea = "$A$1:$F$42"
End Sub
 
Private Function Imprimante_AdobePDF() As Boolean
Dim i As Long
    ' 11 imprimantes réseau
    Imprimante_AdobePDF = False
    For i = 0 To 10
        If i < 10 Then
            sNomPortReseau = "Adobe PDF sur Ne0" & i & ":"
        Else
            sNomPortReseau = "Adobe PDF sur Ne" & i & ":"
        End If
        On Error Resume Next
        Application.ActivePrinter = sNomPortReseau
        If ActivePrinter = sNomPortReseau Then
            Imprimante_AdobePDF = True
            Exit For
        End If
    Next i
End Function


Message édité par kiki29 le 13-06-2008 à 06:23:13
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed