Bon tuto VBA, ou aide pour macro dans excel

Résolu
renisaac Messages postés 2073 Statut Contributeur -  
renisaac Messages postés 2073 Statut Contributeur -
Bonjour,

Pour ma boite, un labo, je dois refaire une feuille de calcul excel, que je veux automatiser le plus possible. Certaines choses que je veux faires semblent possible que par une macro. Le probleme est que mon experience en programation se resume a 1/2 de cours donne par notre IT ou j'ai pas tout compris, et la lecture de ce tuto : http://www.gaboly.com/VBA/index.html

Le premier probleme est un tableau que je veux faire a partir d'un autre, en ne prenant que certaine cellule. J'ai des donnee sur un tableau (appellont le tableau 1) plus de 100 lignes, 25 colonne. Je veux un tableau (tableau 2) 6 lignes 3 colonnes, les lignes etant determinee lorsque une des colonne du tableau 1 change. Il faut alors prendre les valeurs des colonnes 3, 7 et 10 dans la ligne -1.

le second probleme, j'ai un graphe log-log resistivite vs saturation, les donnees sont toutes calculee a partir de mesures. parfois, on ne mesure pas la resistivite, j'ai donc des lignes avec seulement la saturation. Excel voit ces cellules vide comme =0, et donc me bloque et m'envois balader. A partir de ce tableau, on utilise aussi =LINEST(LOG(M11:M120),LOG(N11:N120),0,1) qui n'aime pas les cellules vides Comment faire pour qu'il n'en tienne pas compte. Un simple =IF(ISNUMBER(N11),N11,"") ne suffit pas.

Je cherche principalement le tuto qui me presentera les fonctions le plus utile pour ce genre de probleme, mais si qq'un est capable de me pondre et me l'expliquer brievement, je suis aussi prenneur.

Merci ne fusse que de m'avoir lu jusqu'ici.

Renisaac

Configuration: Windows XP
Internet Explorer 7.0

17 réponses

  1. renisaac Messages postés 2073 Statut Contributeur 139
     
    Bonjour Lyd,

    Je viens enfin de regarder ton site, et il y l'air ultra-complet. Il me faudra sans doute un peu de temps pour m'y retrouver, mais au moins j'aurais mes réponses sans emmerder tout le monde ici. Merci beaucoup.

    Je mettrai résolu quand j'aurai mieux vu le site.

    Renisaac
    7
  2. eriiic Messages postés 24581 Date d'inscription   Statut Contributeur Dernière intervention   7 281
     
    Bonsoir,

    j'aurais mes réponses sans emmerder tout le monde ici
    Bé non, t'emmerde personne ici.
    Donc à moins que ne veuille en profiter pour progresser tout seul sur excel n'hésite pas à poser des questions.
    Juste un truc à savoir, si ce n'est pas une simple question, c'est qu'on aime bien avoir un classeur exemple avec des explications claires de ton besoin, ça évite tout un tas d'échanges pour fournir une réponse adaptée à ton cas.
    Pour ça tu peux utiliser cijoint.fr pour déposer un fichier et coller ici le lien fourni.
    eric
    0
  3. renisaac Messages postés 2073 Statut Contributeur 139
     
    re-bonjour,

    t'inquiète Éric, je vais quand même t'embêter... mais entre temps, j'ai eu le temps d'assimiler suffisamment pour savoir poser ma question de façon efficace.

    Je me suis penche uniquement sur mon problème n 1. Pour l'instant je cale sur un simple test : lorsque la cellule AC 57 <>0, appliquer toute une procédure, sinon, vérifier AC58 Pour ce faire, j'ai essaye un if then else, avec une boucle en do loop while comme conseille sur le site de lyd, mais ça foire visiblement quelque part, il ne descend jamais de cellules.

    Dans la même macro, je pense devoir initialiser le range avant de faire le premier test, mais je ne sais pas comment faire.

    Le fichier en question est sur cijoint.fr : http://www.cijoint.fr/cjlink.php?file=cj200809/cijLrqx6E4.xls

    la première macro est celle sur laquelle je travail. la seconde, est un enregistrement de macro, pour avoir une idée du langage. Les commentaires dans le code sont en mauvais anglais.

    Toutes les contributions sont les bienvenue!

    Renisaac

    P.S. si quelqu'un peu me dire pourquoi la réponse de Lyd a été effacée, avant que je ne remette le même excellent lien?
    0
  4. eriiic Messages postés 24581 Date d'inscription   Statut Contributeur Dernière intervention   7 281
     
    Bonsoir,

    J'ai commencé à regarder un peu...
    Déjà pas besoin d'activer une cellule pour la tester (lire, écrire,...)
    Vu que ta feuille est activée tu peux écrire
    If [AC57].Value <> 0 Then
    et pour ta boucle tout dépend si tu dois faire le traitement sur toutes les cellules <>0 ou seulement la 1ère.

    Si 1 fois ta boucle pourrait être qcq chose comme :
            j = 0
            Do Until fini
                If [AC57].Offset(j, 0).Value <> 0 Then
                  ' ton traitement
                  fini = True
                Else
                    j = j + 1
                End If
            Loop
    0
  5. Vous n’avez pas trouvé la réponse que vous recherchez ?

    Posez votre question
  6. renisaac Messages postés 2073 Statut Contributeur 139
     
    re-

    Toutes! et ou cela devient rigolo, c'est dans le tableau, les lignes sélectionnées se suivront pour faire un graphe.

    Je regarderai ta boucle depuis le boulot, sans doute fin de matinée, début d'aprem.

    Renisaac
    0
  7. renisaac Messages postés 2073 Statut Contributeur 139
     
    re-

    Ta boucle fonctionne bien, et je pense l'avoir adpate pour passer au suivant (je fais 1000 boucle, mais pas grave, ai verifie, pas trop long)

    Do Until fini
    If [AC57].Offset(j, 0).Value <> 0 Then
    'mon traitement

    If j < 1000 Then
    j = j + 1
    Else
    fini = True

    End If
    Else
    If j < 1000 Then
    j = j + 1
    Else
    fini = True

    End If

    End If

    Loop


    le probleme, la premiere ligne du traitement est

    ActiveCell.Offset(0, -20).Select

    et la il bug, ca ma cellule n'est pas active.

    Une idee?

    Renisaac
    0
  8. Utilisateur anonyme
     
    Bonjour,

    Votre code optimisé !

        fini = False
        Do Until fini
            If ( [AC57].Offset(j, -20).Value <> 0 ) Then
                'mon traitement
            End If
            If j < 1000 Then
                j = j + 1
            Else
                fini = True
            End If
        Loop
    


    Lupin
    0
  9. renisaac Messages postés 2073 Statut Contributeur 139
     
    Merci Lupin, optimisation adoptee!

    mais j'ai toujours mon bug a la premiere instruction. :

    Do Until fini
                    If [AC57].Offset(j, 0).Value <> 0 Then
    
                            'copy PC in Pc tab, plot(2)
                        =>  ActiveCell.Offset(0, -20).Select
                            ActiveCell.Copy
                            Worksheets("FRI Plot (2)").Activate
                            'will have to select good line
                            Range("Q12").Select
                            Selection.PasteSpecial Paste:=xlValues, Operation:=xlNone, SkipBlanks:=False, Transpose:=False
                
                            Worksheets("fri").Activate
                            ActiveCell.Offset(0, 10).Select 'this work to select the good next cells
                            'make active 2 cells
                            Application.CutCopyMode = False
                            Selection.Copy
                            Worksheets("FRI Plot (2)").Activate
                            'select good line
                            Range("M12:N12").Select
                            Selection.PasteSpecial Paste:=xlValues, Operation:=xlNone, SkipBlanks:=False, Transpose:=False
                                                            
                    End If
                    If j < 1000 Then
                        j = j + 1
                    Else
                           fini = True
                                                                                    
                    End If
                Loop

    l
    le message est :
    Run-time error '1004' : Application-defined or object defined error


    Lupin, eric, ou quelqu'un d'autre a une meilleur idee que mon IT? (donc n'importe quel idee, car lui n'en a pas :(
    le fichier en question est toujours sur cijoints : http://www.cijoint.fr/cjlink.php?file=cj200809/cijLrqx6E4.xls

    Merci d'avance

    Renisaac
    0
  10. eriiic Messages postés 24581 Date d'inscription   Statut Contributeur Dernière intervention   7 281
     
    Bonjour,

    ta référence n'est plus activecell mais [AC57].Offset(j, 0)
    Donc met [AC57].Offset(j, -20).select

    Mais si c'est juste pour recopier une valeur (sans la mise en forme ni la formule) met directement :
    Worksheets("FRI Plot (2)").Range("Q12").value = [AC57].Offset(j, -20).value
    c'est plus court.

    eric
    0
  11. renisaac Messages postés 2073 Statut Contributeur 139
     
    Youpie! grâce a vous, j'ai fini la première partie!

    pour info, le code :

    Option Explicit
    Sub MakePcTable()
        'first step, copy fri value from fri sheet to friplot(2) sheet
        Dim j As Integer
        Dim finished As Boolean
        Dim k As Integer
            j = 1
            finished = False
            k = 0
            Worksheets("fri").Activate
            'check if AC 58 value <> 0, if yes, copy the fri value to the tab, if no, check next cell
                Do Until finished
                    If [AC58].Offset(j, 0).Value <> 0 Then
                            Worksheets("FRI Plot (2)").Range("Q12").Offset(k, 0).Value = [AC58].Offset(j - 1, -20).Value 'copy Pc value
                            Worksheets("FRI Plot (2)").Range("M12").Offset(k, 0).Value = [AC58].Offset(j - 1, -10).Value 'copy RI value
                            Worksheets("FRI Plot (2)").Range("N12").Offset(k, 0).Value = [AC58].Offset(j - 1, -9).Value 'copy Sw value
                            k = k + 1
                    End If
                    If j < 172 Then
                        j = j + 1
                    Else
                           finished = True
                                                                                    
                    End If
                Loop
        
        
        'second step, adapt the resistivity index calculation
        Worksheets("FRI Plot (2)").Activate
        '=LINEST(LOG(M12:M17);LOG(N12:N17);0;1) the excel fonction I want to use, but with a range (M11:M11+k+1)
        'WorksheetFunction.LINEST(WorksheetFunction.Log.range("M12;M17);WorksheetFunction.LOG(N12:N17);0;1)
        
    
    End Sub
    


    Comme vous voyez, je dois sélectionner les cellules non vide du tableau juste crée pour les utiliser dans une fonction excel. Je pense utiliser la variable k avant qu'elle ne s'efface, mais je ne sais pas encore comment décrire un range de longueur variable.

    Je viens de mettre sur cijoints le fichier mis a jours : http://www.cijoint.fr/cjlink.php?file=cj200809/cijL916S3j.xls

    Merci beaucoup Éric et Lupin

    Renisaac
    0
  12. eriiic Messages postés 24581 Date d'inscription   Statut Contributeur Dernière intervention   7 281
     
    Et bien tu vois, ça prend forme ;-)
    Juste un petit truc mais peut-être fais exprès :
    Au début tu voulais tester AC57 (d'ailleurs on se demande pourquoi pas AC56 puisque les valeurs démarrent ici mais ça doit être normal je pense), là tu es passé à AC58 mais en plus avec un offset initial de 1 (j=1) ce qui donne AC59 comme 1ère cellule testée.
    eric

    edit :
    dans range("A1:B8") "A1:B8" est une chaine que tu peux fabriquer avec dees variables chaines et/ou numériques.
    ex:
    lig1=12
    range("A1:B" & lig1).select => range("A1:B12").select
    et pour addresser les cellules tu as aussi :
    ligne =3
    colonne=5
    cells(ligne,colonne).select
    0
  13. renisaac Messages postés 2073 Statut Contributeur 139
     
    Bonjour, bonsoir,

    Bon, desole, je n'ai de nouveau pas eu le temps de continuer sur cette macro, et comme c'est parti, je ne pourrais bosser dessus que 1/2 hr maximum aujourd'hui. Le week-end etant bien remplis, je m'y remettrai lundi au boulot.

    Eric, je tiens tes commentaires au chaud pour les appliquer lundi.

    Renmisaac
    0
  14. Utilisateur anonyme
     
    Bonjour,

    J'ai fait une petite erreur :

    fini = False
        Do Until fini
            If ( [AC57].Offset(j, -20).Value <> 0 ) Then
                'mon traitement
            End If
            If j < 1000 Then
                j = j + 1
            Else
                fini = True
            End If
        Loop
    


    devrait se lire :

    fini = False
        Do Until Not(fini)
            If ( [AC57].Offset(j, -20).Value <> 0 ) Then
                'mon traitement
            End If
            If j < 1000 Then
                j = j + 1
            Else
                fini = True
            End If
        Loop
    


    où encore :

    fini = True
        Do Until fini
            If ( [AC57].Offset(j, -20).Value <> 0 ) Then
                'mon traitement
            End If
            If j < 1000 Then
                j = j + 1
            Else
                fini = False
            End If
        Loop
    

    Lupin
    0
    1. eriiic Messages postés 24581 Date d'inscription   Statut Contributeur Dernière intervention   7 281
       
      Bonsoir lupin,

      tu es sûr ? until = jusqu'à ce que ..., non ?
      Pour moi c'était bon
      eric
      0
  15. Utilisateur anonyme
     
    re :

    Très pertinent ériiic, merci du rappel :-)

    j'ai testé et effectivement, je l'ai transcrit à l'envers :-(

    Sub TEST1()
    
        Dim Fini As Boolean, j As Integer
        
        Fini = True
        Do Until Not (Fini)
            MsgBox Fini
            If j < 10 Then
                j = j + 1
            Else
                Fini = False
            End If
        Loop
    
    End Sub
    '
    
    Sub TEST2()
    
        Dim Fini As Boolean, j As Integer
        
        Fini = False
        Do Until (Fini)
            MsgBox Fini
            If j < 10 Then
                j = j + 1
            Else
                Fini = True
            End If
        Loop
    
    End Sub
    


    Lupin
    0
  16. renisaac Messages postés 2073 Statut Contributeur 139
     
    rebonjour,

    Je confirme que la premiere version fonctionne bien, Merci Lupin.

    Eric, je n'arrive pas a utiliser le "&" correctement :

    Sub Macro2()
    '
    ' Macro2 Macro
    ' Macro recorded 9/29/2008 by isaac
    '
    Dim k As Integer
    k = 6
    '
        Worksheets("FRI Plot (2)").Activate
        '=LINEST(LOG(M12:M17);LOG(N12:N17);0;1) the excel fonction I want to use, but with a range(M11:M11+k+1)
        Range("O1").Select
        ActiveCell.Formula = "=LINEST(LOG(M11:M11 & k),LOG(N11:N11 & k),0,1)"
        ActiveSheet.ChartObjects("Chart 1").Activate
        ActiveChart.SeriesCollection(1).Select
        ActiveChart.SeriesCollection(1).Values = "='FRI Plot (2)'!R11C13:R11 & kC13"
        ActiveChart.SeriesCollection(1).XValues = "='FRI Plot (2)'!R11C14:R11 & kC14"
    
    End Sub


    le k variera dans la premiere partie de la macro.

    Eric, Lupin, ou encore quelqu'un d'autre, pouvez-vous me donner encore des bons conseils?

    Renisaac
    0
  17. renisaac Messages postés 2073 Statut Contributeur 139
     
    ok, deja resolut, un collegue a pu m'aider.

    La solution :

        'second step, adapt the resistivity index calculation
        Worksheets("FRI Plot (2)").Activate
        '=LINEST(LOG(M12:M17);LOG(N12:N17);0;1) the excel fonction I want to use, but with a range (M11:M11+k+1)
        Range("O1").Select
        ActiveCell.Formula = "=LINEST(LOG(M11:M" & 11 + k & "),LOG(N11:N" & 11 + k & "),0,1)"
        ActiveSheet.ChartObjects("Chart 1").Activate
        ActiveChart.SeriesCollection(1).Select
        ActiveChart.SeriesCollection(1).Values = "='FRI Plot (2)'!R11C13:R" & 11 + k & "C13"
        ActiveChart.SeriesCollection(1).XValues = "='FRI Plot (2)'!R11C14:R" & 11 + k & "C14"


    le secret etait dans le bon usage des "

    Merci quand meme de m'avoir lu.

    maintenant yaka achever ma feuille de calcul. Je reviendrai peut-etre plus tard avec d'auitres questions.

    encore merci

    Renisaac
    0