VISUAL BASIC & EXCEL

TP 2

Étude d'une fonction


1. Solutions du TP1
Comme vous l'avez sans doute remarqué, les couleurs utilisées dans ColorIndex sont des nombres entiers compris entre 0 et 53. Voici le tableau des 15 premières couleurs (sur PC):

Code

0

1

2

3

4

5

6

7

Couleur

Sans

Blanc

Noir

Rouge

Vert

Bleu

Jaune

Magenta

Code

8

9

10

11

12

13

14

15

Couleur

Cyan

Brun

Vert foncé

Bleu foncé

Kaki

Violet

Bleu-vert

Gris

1.1. Découpage de l'année en 4 trimestres

Seules quelques procédures sont modifiées :

Sub AfficherTitre()
    For trimestre = 1 To 4       'le calendrier sera imprimé sur 4 pages
	    Cells(1, 9 * trimestre - 8) = "Année " & Année
		Range(Cells(1, 9 * trimestre - 8), Cells(1, 9 * trimestre)).Select
		With Selection            
		   .HorizontalAlignment = xlHAlignCenterAcrossSelection
		   .VerticalAlignment = xlVAlignCenter
		   .Font.Name = Arial
		   .Font.Size = 20
		   .Font.Bold = True
		   .BorderAround Weight:=xlThick
		   .Interior.ColorIndex = 4
		 End With
	Next trimestre
End Sub
Les largeurs des colonnes peuvent être augmentées car on a plus de place. Il faut donc modifier la procédure RéglerLesLargeursDesColonnes :
Sub RéglerLargeurDesColonnes()  'chaque mois occupera 3 colonnes de largeurs 10, 2 et 15
    For c = 1 To 12
        Columns(3 * c - 2).ColumnWidth = 10
        Columns(3 * c - 1).ColumnWidth = 2
        Columns(3 * c).ColumnWidth = 15
    Next c
End Sub

De même, la procédure qui affiche les noms des jours peut être modifiée ainsi :

Sub AfficherJours() 'affichage des jours : jours en toutes lettres + rang du jour
    For m = 1 To 12
        For j = 1 To 31
            ch = Format(j & "/" & m & "/" & Année, "dddd")
            If IsDate(j & "/" & m & "/" & Année) Then
                Cells(2 + j, 3 * m - 2) = ch
                Cells(2 + j, 3 * m - 1) = j
                If (Cells(2 + j, 3 * m - 2) = "samedi") _			(voir remarque ci-dessous)
                   Or (Cells(2 + j, 3 * m - 2) = "dimanche") Then
                    Range(Cells(2 + j, 3 * m - 2), Cells(2 + j, 3 * m)).Select
                    Selection.Interior.ColorIndex = 3
                End If
            End If
        Next j
        Range(Cells(3, 3 * m - 2), Cells(33, 3 * m)).BorderAround Weight:=xlThick
    Next m
End Sub

Une particularité dans le texte ci-dessus , concernant les 2 lignes :

If (Cells(2 + j, 3 * m - 2) = "samedi") _
     Or (Cells(2 + j, 3 * m - 2) = "dimanche") Then

La première des 2 lignes se termine par un tiret de soulignement précédé d'un espace. Ces 2 caractères indiquent que l'instruction se poursuit à la ligne suivante. Ceci permet d'avoir une mise en page plus agréable.

Voici le résultat obtenu :

1.2. Calendrier sur une page.

Il s'agit cette fois, de faire tenir le calendrier sur une seule page. La disposition retenue est le mode portrait avec les 2 semestres l'un au-dessus de l'autre. Plusieurs procédures sont modifiées. On trouvera ci-dessous le détail de ces modifications :

'Macro Calendrier sur 1 page
'Réalisée par P. Rabiller le 9/02/2000

Dim Année  'Déclaration d'une variable "Année" utilisable dans tout le programme

Sub Calendrier()        'programme principal
    SaisirAnnée
    RéglerLargeurDesColonnes
    AfficherTitre
    AfficherNomsMois
    AfficherJours
End Sub

Sub SaisirAnnée()       'demande à l'utilisateur de taper une année
    Année = InputBox("Tapez l'année :", "Calendrier")
End Sub

Sub RéglerLargeurDesColonnes()  'disposition des 2 semestres superposés en mode portrait
    Range(Cells(1, 1), Cells(65, 18)).Select
    Selection.Clear
    For c = 1 To 6
        Columns(3 * c - 2).ColumnWidth = 2
        Columns(3 * c - 1).ColumnWidth = 2
        Columns(3 * c).ColumnWidth = 10
    Next c
End Sub

Sub AfficherTitre()
    Cells(1, 1) = "Année " & Année
    Range(Cells(1, 1), Cells(1, 18)).Select
        With Selection
            .HorizontalAlignment = xlHAlignCenterAcrossSelection
            .VerticalAlignment = xlVAlignCenter
            .Font.Name = Arial
            .Font.Size = 20
            .Font.Bold = True
            .BorderAround Weight:=xlThick
            .Interior.ColorIndex = 4
        End With
End Sub

Sub AfficherNomsMois()  'affichage des noms des 12 mois
    For m = 1 To 12
        ch = Format("1/" & m, "dd mmmm")
        If m < 7 Then
            Cells(2, 3 * m - 2) = Mid(ch, 4, 10)
            Range(Cells(2, 3 * m - 2), Cells(2, 3 * m)).Select
        Else
            Cells(34, 3 * (m - 6) - 2) = Mid(ch, 4, 10)
            Range(Cells(34, 3 * (m - 6) - 2), Cells(34, 3 * (m - 6))).Select
        End If
        With Selection
            .HorizontalAlignment = xlHAlignCenterAcrossSelection
            .VerticalAlignment = xlVAlignCenter
            .Font.Name = Arial
            .Font.Size = 14
            .Font.Bold = True
            .BorderAround Weight:=xlThick
            .Interior.ColorIndex = 15
        End With
    Next m
End Sub

Sub AfficherJours() 'affichage des jours : 1ère lettre + rang du jour
    For m = 1 To 12
        For j = 1 To 31
            ch = Format(j & "/" & m & "/" & Année, "dddd")
            If IsDate(j & "/" & m & "/" & Année) Then
                If m < 7 Then
                    Cells(2 + j, 3 * m - 2) = Mid(ch, 1, 1)
                    Cells(2 + j, 3 * m - 1) = j
                    If (Cells(2 + j, 3 * m - 2) = "s") Or (Cells(2 + j, 3 * m - 2) = "d") Then
                        Range(Cells(2 + j, 3 * m - 2), Cells(2 + j, 3 * m)).Select
                        Selection.Interior.ColorIndex = 3
                    End If
                Else
                    Cells(34 + j, 3 * (m - 6) - 2) = Mid(ch, 1, 1)
                    Cells(34 + j, 3 * (m - 6) - 1) = j
                    If (Cells(34 + j, 3 * (m - 6) - 2) = "s") _
                        Or (Cells(34 + j, 3 * (m - 6) - 2) = "d") Then
                        Range(Cells(34 + j, 3 * (m - 6) - 2), _
                              Cells(34 + j, 3 * (m - 6))).Select
                        Selection.Interior.ColorIndex = 3
                    End If
                End If
            End If
        Next j
        If m < 7 Then
            Range(Cells(2, 3 * m - 2), Cells(33, 3 * m)).BorderAround Weight:=xlThick
        Else
            Range(Cells(34, 3 * (m - 6) - 2), Cells(65, 3 * (m - 6))). _
                  BorderAround Weight:=xlThick
        End If
    Next m
    Range(Cells(3, 1), Cells(33, 18)).Select
        Selection.VerticalAlignment = xlCenter
        Selection.RowHeight = 12
    Range(Cells(35, 1), Cells(65, 18)).Select
        Selection.VerticalAlignment = xlCenter
        Selection.RowHeight = 12
    Rows(2).RowHeight = 19
    Rows(34).RowHeight = 19
End Sub

1.3. Un seul mois choisi par l'utilisateur

'Calendrier avec un seul mois choisi par l'utilisateur
'réalisé par P. Rabiller le 7/02/2001

Dim Année, Mois

Sub CalendrierUnMois()
    Range(Cells(1, 1), Cells(31, 3)).Clear
    SaisirAnneeEtMois
    RéglerTailleDesCellules
    AfficherJours
    AfficherTitre
End Sub

Sub SaisirAnneeEtMois()
    Année = InputBox("Taper l'année : ", "Calendrier")
    Mois = InputBox("Taper le mois (en chiffres) :", "Calendrier")
End Sub

Sub RéglerTailleDesCellules()
    Columns(1).ColumnWidth = 20
    Columns(2).ColumnWidth = 5
    Columns(3).ColumnWidth = 40
    Range(Cells(1, 1), Cells(31, 2)).Select
    With Selection
        .VerticalAlignment = xlCenter
        .Font.Name = "Times new Roman"
        .Font.Size = 14
    End With
    For k = 1 To 31
       Rows(k).RowHeight = 20
    Next
    Cells(1, 1).Select
End Sub

Sub AfficherJours()
    For j = 1 To 31
        ch = Format(j & "/" & Mois & "/" & Année, "dddd")
        If IsDate(j & "/" & Mois & "/" & Année) Then
            Cells(j, 1) = ch
            Cells(j, 2) = j
            Range(Cells(j, 1), Cells(j, 3)).BorderAround Weight:=xlThin
            Range(Cells(j, 1), Cells(j, 3)).Borders(xlInsideVertical).Weight = xlThin
        End If
    Next j
End Sub

Sub AfficherTitre()
    ch = Format(1 & "/" & Mois & "/" & Année, "mmmm yyyy")
    With ActiveSheet.PageSetup
        .CenterHeader = ch
        .CenterHorizontally = True
        .CenterVertically = True
        .Orientation = xlPortrait
    End With
End Sub

2. Étude des valeurs d'une fonction

2.1. Table des valeurs sans programmation

Considérons la fonction f définie sur R par .
On veut obtenir une table de valeurs de f(x) lorsque x décrit un intervalle donné.
Commencer par remplir les premières cellules de la feuille de calcul comme indiqué ci-contre :

Définir un nom, en utilisant la commande Insertion / Nom / Définir pour les cellules B1, B2 et B3 . (on les nommera respectivement Xmin, Xmax et Pas)

Dans la cellule A8, taper la formule : =Xmin
Dans la cellule B8, taper la formule : =Si(A8<>"";A8/(A8^2+1);"") (chacun aura compris la formule)
Il s'agit maintenant de construire la table des valeurs de f(x) losrque x décrit l'intervalle [Xmin, Xmax] .
On peut commencer par recopier vers le bas la formule B8 jusqu'à la la cellule B100 (on prévoit large).
Connaissant le pas et les valeurs extrêmes de l'intervalle, on peut calculer la valeur suivante de x en tapant, dans la cellule A9 la formule : =Si(et(A8<>"";A8+Pas<=Xmax);A8+Pas;"")
Ou bien la formule : =Si(Ligne()-8<=(Xmax-Xmin)/Pas;A8+Pas;"")
Il suffit alors de recopier vers le bas la formule A9 jusqu'à la ligne A100.
Normalement, tout fonctionne correctement : si on change l'une des valeurs Xmin, Xmax ou Pas, toute la feuille est recalculée.

Cependant, l'inconvénient principal, c'est que, si on veut modifier la fonction, il est nécessaire de changer la formule de la cellule B8 et de la recopier vers le bas jusqu'à la ligne 100... Ce qu'il faudrait, c'est avoir une formule dans la cellule B9 du genre : = f(A8) . Voici comment procéder :

2.2. Table des valeurs avec programmation

Afficher l'éditeur de code de visual basic et taper les lignes suivantes :

'Table de valeurs d'une fonction
'réalisée le 11/02/2002 par P. Rabiller

Function f(x)
    f = x / (x * x + 1)
End Function

Sub calculs()
    XMin = Cells(1, 2)
    XMax = Cells(2, 2)
    pas = Cells(3, 2)
    i = 8
    x = XMin
    Do While x <= XMax
        Cells(i, 1) = x
        Cells(i, 2) = f(x)
        x = x + pas
        i = i + 1
    Loop
End Sub

Revenir ensuite à la feuille de calcul et lancer l'exécution de la macro Calculs.
On peut modifier les données introduites par l'utilisateur dans les cellules B1, B2 et B3 pour obtenir une table différente. Inconvénient : les calculs précédents ne sont pas effacés et si la nouvelle table comporte moins de valeurs, les données précédentes restent à l'affichage. De plus, on peut remarquer que les valeurs affichées sont mal formatées. Il serait intéressant que l'utilisateur puisse préciser le nombre de décimales.

2.3. Effacer les données précédentes et afficher dans un format défini par l'utilisateur

Modifier la feuille de calcul en ajoutant une ligne pour saisir le nombre de décimales :

Modifier la procédure Calculs de la façon suivante (la partie modifiée est en caractères italiques) :

Sub calculs()
    XMin = Cells(1, 2)
    XMax = Cells(2, 2)
    pas = Cells(3, 2)
    NbDécimales = Cells(4, 2)
    Range(Cells(8, 1), Cells(100, 2)).Select
    Selection.Clear
    ch = "0."
    For i = 1 To NbDécimales
        ch = ch & "0"				'si NbDécimales=3, alors la chaîne de format sera ch="0.000"
    Next i
    Range(Cells(8, 2), Cells(100, 2)).NumberFormat = ch	'mise en place du format
    i = 8
    x = XMin
    Do While x <= XMax
        Cells(i, 1) = x
        Cells(i, 2) = f(x)
        x = x + pas
        i = i + 1
    Loop
End Sub
2.4. Ajouter un bouton pour lancer l'exécution de la procédure

Choisir dans la barre des boutons, le bouton "Bouton" : .
Si ce bouton n'apparaît pas dans votre barre des boutons, effectuer la commande Affichage/Barre d'outils... et choisir la barre d'outils Formulaire :


Placer le bouton en faisant glisser la souris dans la feuille de calcul :

Dès qu'on lâche le bouton de la souris, on obtient une fenêtre permettant d'affecter à notre bouton une macro (procédure) de notre choix. Nous lui affectons la procédure Calculs :

Nous pouvons modifier le nom du bouton. Pour cela :

Désormais un simple clic sur ce bouton suffit à lancer la procédure Calculs.

3. Exercices

3.1. Cas d'une fonction non définie sur tout l'intervalle [Xmin, Xmax]

Essayer de refaire les calculs avec la fonction f définie par : . La fonction racine carrée s'obtient avec le mot Sqr.
Que se passe-t-il si les valeurs de Xmin et de Xmax débordent de l'intervalle [-1, 1] ?
Comment faut-il modifier l'écriture de la fonction pour que les valeurs négatives de 1-x² ne provoquent pas d'erreur à l'exécution ?

3.2. Cas d'une fonction définie par morceaux

Modifier l'écriture du programme pour permettre l'étude de la fonction f définie par :
si x £-1 : ,
si x > -1 et x £2 :
si x ³3 :

3.3. Calcul de la dérivée

Ajouer une colonne permettant d'obtenir, parallèlement à la table des valeurs de , une table des valeurs de . Plusieurs solutions sont possibles, mais toutes utilisent une approximation pour calculer le nombre dérivé en un point x : »


3.4. Calcul de l'intégrale

Ajouter une cellule qui reçoit une valeur approchée de l'intégrale sur l'intervalle [Xmin, Xmax] (calculée par la méthode des rectangles par exemple). On pourra utiliser la cellule B5 pour recevoir le résultat.
L'intégrale sera calculée à l'aide d'une fonction, tout comme la fonction f et sa dérivée.

3.5. Représentation graphique d'une fonction

Prenons l'exemple de la fonction définie par sur l'intervalle [-4 ; 4]

Pour obtenir directement la courbe représentative de cette fonction :

 

 

 

 

 

 

On obtient alors ceci :

L'inconvénient de ce procédé est que, si on change les bornes Xmin et Xmax ou le pas, le graphique ne couvre pas forcément la totalité de la plage. En effet, la plage sélectionnée correspondant au graphique est toujours la même. Par contre, si on modifie la fonction, le graphique est modifié en conséquence.

Il existe la possibilité d'enregistrer une séquence de commandes sous la forme d'une procédure puis de la modifier pour l'adapter à nos besoins. Une solution sera proposée la prochaine fois....

<< TP précédent      TP suivant >>

Retour à la liste des TP