Bon tuto VBA, ou aide pour macro dans excel
Résolu
renisaac
Messages postés
2051
Date d'inscription
Statut
Contributeur
Dernière intervention
-
renisaac Messages postés 2051 Date d'inscription Statut Contributeur Dernière intervention -
renisaac Messages postés 2051 Date d'inscription Statut Contributeur Dernière intervention -
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
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
A voir également:
- Bon tuto VBA, ou aide pour macro dans excel
- Telecharger macro convertir chiffre en lettre excel - Télécharger - Tableur
- Si ou excel - Guide
- Liste déroulante excel - Guide
- Word et excel gratuit - Guide
- Déplacer colonne excel - Guide
17 réponses
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
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
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
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
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?
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?
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'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
Vous n’avez pas trouvé la réponse que vous recherchez ?
Posez votre question
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
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
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
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
Bonjour,
Votre code optimisé !
Lupin
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
Merci Lupin, optimisation adoptee!
mais j'ai toujours mon bug a la premiere instruction. :
l
le message est :
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
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
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
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
Youpie! grâce a vous, j'ai fini la première partie!
pour info, le code :
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
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
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
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
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
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
Bonjour,
J'ai fait une petite erreur :
devrait se lire :
où encore :
Lupin
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
re :
Très pertinent ériiic, merci du rappel :-)
j'ai testé et effectivement, je l'ai transcrit à l'envers :-(
Lupin
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
rebonjour,
Je confirme que la premiere version fonctionne bien, Merci Lupin.
Eric, je n'arrive pas a utiliser le "&" correctement :
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
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
ok, deja resolut, un collegue a pu m'aider.
La solution :
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
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
re-
J'ai en effet encore un probleme, commencent une autre macro, j'ai recopier la boucle, mais excel ne semble pas se soucier de la condition. Comme la question est differante, j'ai ouvert un nouveau poste la : http://www.commentcamarche.net/forum/affich 8653510 vba excel condition ne semble pas verifier
comme ca je peux cloturer ce poste-ci
Renisaac
J'ai en effet encore un probleme, commencent une autre macro, j'ai recopier la boucle, mais excel ne semble pas se soucier de la condition. Comme la question est differante, j'ai ouvert un nouveau poste la : http://www.commentcamarche.net/forum/affich 8653510 vba excel condition ne semble pas verifier
comme ca je peux cloturer ce poste-ci
Renisaac