Académique Documents
Professionnel Documents
Culture Documents
v1.1 - marc.lemaire@iupge.u-cergy.fr
3 octobre 2005
1 TD 1 : initiation VBA
1.1 exercice 1 : puissances de 2
Affichage des puissances de 2 en décimal et en hexadécimal jusqu’à 230 , avec et sans l’opérateur puissance
(i.e. en écrivant une fonction de calcul de la puissance).
Remarque : les positions sont relatives et correspondent aux décalages (offset ) en ligne et en colonne.
fonction tp1_afficher_puissances
début
entier i, p
pour i <- 0 à 30
p <- 2 ^ i ’ à remplacer ultérieurement par p <- power(2, i)
afficher (i) en position (i+1, 0)
afficher (p) en position (i+1, 1)
afficher (p) en position (i+1, 2) et en hexa
fin pour
fin
1
1.3 exercice 3 : numéro INSEE
Remarque : la fonction “extraireCaractères” permet l’extraction partielle d’une chaı̂ne de caractères, à partir
d’une position, de n caractères. Les positions commencent à 1.
fonction decomposerNumeroINSEE
debut
string numeroINSEE
string caracteristiques
saisir (numeroINSEE)
si verifierClef(numeroINSEE) = true alors
afficher ("clef vérifiée avec succés")
caractèristiques <- analyserINSEE (numeroINSEE)
afficher (caractéristiques)
sinon
afficher ("erreur de numéro INSEE")
fin si
fin
2 TP 1 : initiation VBA
Sont présentés dans cette partie des exemples de solution (code VBA) aux exercices de TP.
2
’ TP1 : affichage des puissances de 2
’ L3 SPI - Algo et VBA
’ ml v1.3 - 28 / 09 / 2005
resultat = 1
For i = 1 To puissance
resultat = resultat * valeur
Next i
power = resultat
End Function
3
Dim lig As Integer
Dim col As Integer
With Application.ActiveWorkbook.Worksheets("Feuil2")
.Range(title) = "Table ASCII"
End Sub
’ fonction principale de saisie et de vérification d’un numéro INSEE, et d’affichage des resultats de l’
Public Sub verifCodeINSEE()
code = InputBox("valeur du code INSEE (15 chiffre) : ", " verification numero Secu ")
4
message = traitement(code)
MsgBox message, vbOKOnly + vbInformation, " code INSEE traite "
End If
End If
End Sub
numero = CDec(Left$(codeINSEE, 13)) ’ les 13 premiers chiffres constituent le numero, on peut aussi
While numero >= (97 * MULTIPLE) ’ on traite l’operateur modulo par une boucle...
numero = numero - (97 * MULTIPLE) ’ ... car l’utilisation de l’operateur modulo directement (num
Wend
If (97 - (numero Mod 97)) = clef Then
clefValide = True
Else
clefValide = False
End If
verifClef = clefValide
End Function
sexe = Left$(codeINSEE, 1)
Select Case sexe
Case 1
msg = " vous etes un homme " & vbCrLf
Case 2
msg = " vous etes une femme " & vbCrLf
Case Else
’ do Nothing : cas particulier pour les numéros temporaires
End Select
departementNaissance = Mid$(codeINSEE, 6, 2)
msg = msg + " dans le departement : " & departementNaissance & vbCrLf
5
traitement = msg
End Function
3 TD 2 : calendrier
3.1 année bissextile
fonction estBissextile (entier annee)
debut
booleen bissextile <- false
si (annee modulo 4 = 0 et annee modulo 100 6= 0) ou (annee modulo 400 = 0) alors
bisextile <- true
fin si
retourner bisextile
fin
// les 3 tableaux ci-dessous sont utilisés par l’ensemble des fonctions : ils peuvent ^
etre déclarés
String[ ] nomsJours <- { "lundi", "mardi", "mercredi", "jeudi", "vendredi", "samedi", "dimanche"
String[ ] nomsMois <- { "janvier", "février", "mars", "avril", "mai", "juin", "juillet", "ao^ut",
entier[ ] nbJoursMensuel <- { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
fonction afficherCalendrierAnnuel
debut
entier annee <- 2005 // on peut aussi saisir l’annee
entier numJourAnnuel <- 1
entier numSemaine <- 1
entier mois, jour
date tmp
si (estBissextile(annee)) alors
nbJoursMensuel[1] <- 29
fin si
afficher (annee)
pour (mois <- 1 a 12)
afficher(nomsMois[mois - 1]
fin pour
pour mois <- 1 a 12
pour jour <- 1 a nbJoursMensuel[mois - 1]
afficher(numJourAnnuel)
tmp <- creerDate(jour, mois, annee)
afficher(nomsJour[weekDayNumber(tmp) - 1])
afficher(jour)
si (weekDayNumber(tmp) = 1) alors // si c’est un lundi
afficher(numSemaine)
numSemaine <- numSemaine + 1
fin si
numJourAnnuel <- numJourAnnuel + 1
fin pour
// réinitialiser les décalages pour l’affichage en colonnes
fin pour
6
fin
si (estBissextile(annee)) alors
nbJoursMensuel[1] <- 29
fin si
afficher nomsMois[mois - 1]
pour jour <- 1 a 7
afficher nomsJours[jour - 1]
fin pour
pour jour <- 1 a nbJoursMensuel[mois - 1]
afficher(jour) en position ligne et colonne // du lundi (1) au dimanche (7)
colonne <- colonne + 1
si colonne > 7 alors
ligne <- ligne + 1
colonne <- 1
fin si
fin pour
fin
4 TP 2 : calendrier
Attribute VB_Name = "Module1"
’ TP2 : module de gestion d’un calendrier
’ ml v 1.1 - 01 / 10 / 2005
7
Dim numSemaine As Integer
Const NBCOLS = 4 ’ nombre de colonnes consacrees a chaque mois
’ initialisation des variables du module : ces insructions doivent obligatoirement etre dans une pro
nbJours = Array(31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31)
If isAnneeBissextile(annee) Then
nbJours(1) = 29
End If
nomsJours = Array("lundi", "mardi", "mercredi", "jeudi", "vendredi", "samedi", "dimanche")
nomsMois = Array("janvier", "février", "mars", "avril", "mai", "juin", "juillet", "ao^
ut", "septembre
’ le calendrier annuel
Application.ActiveWorkbook.ActiveSheet.Name = annee
For mois = 1 To 12
’ on affiche le nom du mois pour les NBCOLS colonnes
’ NB : la seletion multiple de cellule pour une fusion (merge) n’est pas tres simple...
Application.ActiveWorkbook.ActiveSheet.Range("A2:D2").Offset(-1, (mois - 1) * NBCOLS).Select
Selection.Merge
Selection.Borders.Color = RGB(&HFF, &H0, &H0)
Selection.Borders.Weight = xlMedium
Selection.HorizontalAlignment = xlCenter
Selection.Font.Bold = True
Selection.Font.Size = 15
Selection.Formula = nomsMois(mois - 1)
’ on affiche le nom des jours, leur numero dans le mois et leur numero dans l’annee
’ on affiche egalement le numero de semaine
For jour = 1 To nbJours(mois - 1)
Application.ActiveWorkbook.ActiveSheet.Range("A2").Offset(jour, (mois - 1) * NBCOLS) = numer
Application.ActiveWorkbook.ActiveSheet.Range("A2").Offset(jour, (mois - 1) * NBCOLS + 1) = n
Application.ActiveWorkbook.ActiveSheet.Range("A2").Offset(jour, (mois - 1) * NBCOLS + 2) = D
If (WeekDay(DateSerial(annee, mois, jour), vbMonday) = 1) Then ’ si c’est un lundi
Application.ActiveWorkbook.ActiveSheet.Range("A2").Offset(jour, (mois - 1) * NBCOLS + 3)
numSemaine = numSemaine + 1
End If
’ on grise les samedi et les dimanche
If (WeekDay(DateSerial(annee, mois, jour), vbMonday) = 6 Or WeekDay(DateSerial(annee, mois,
Application.ActiveWorkbook.ActiveSheet.Range("A2:D2").Offset(jour, (mois - 1) * NBCOLS).
End If
numeroJourAnnee = numeroJourAnnee + 1
Next jour
’ on optimise la largeur des colonnes pour une lecture a l’ecran plus facile
Application.ActiveWorkbook.ActiveSheet.Columns("A:BZ").EntireColumn.AutoFit
Next mois
End Sub
8
’ une annee est bissextile si elle est multiple de 4 sauf les annee seculaires non multiples de 400
’ 1600 et 2000 sont bissextile ; 1700, 1800, 1900 et 2100 ne sont pas bissextiles
Dim bissextile As Boolean
bissextile = False
If (annee Mod 4 = 0 And annee Mod 100 <> 0) Or annee Mod 400 = 0 Then
bissextile = True
End If
isAnneeBissextile = bissextile
End Function
’ cree une feuille de calcul supplementaire dans le classeur courant et affiche le mois
’ @param mois : le numero du mois a afficher
’ @param annee : l’annee du mois a afficher
Private Sub creerMois(mois As Integer, annee As Integer)
Dim feuille As Worksheet ’ la nouvelle feuille cree pour le mois traite
Dim last As Worksheet ’ la derniere feuille du classeur
Dim colonne As Integer
Dim ligne As Integer
Dim numFeuille As Integer ’ le numero de la derniere feuille du classeur
Const titre = "B2:H2" ’ la position du titre (le nom du mois)
Const start = "B4" ’ la position de depart du contenu
numFeuille = Application.ActiveWorkbook.Worksheets.Count
Set last = Application.ActiveWorkbook.Worksheets(numFeuille)
’ titre (nom du mois) sur la feuille avec plein de decorations pour le titre ;-)
With feuille
.Range(titre).Select
With Selection
.MergeCells = True
.HorizontalAlignment = xlCenter
.Font.Bold = True
.Font.Size = 17
.Cells.Borders.Weight = 3
.Cells.Borders.Color = RGB(&HFF, &HFF, &H0)
.Interior.Color = RGB(&H0, &HFF, &H0)
.Font.Color = RGB(&HFF, &H0, &H0)
.Formula = nomsMois(mois - 1) & " " & annee
End With
End With
9
’ on grise les samedi et les dimanche
If (WeekDay(DateSerial(annee, mois, jour), vbMonday) = 6 Or WeekDay(DateSerial(annee, mois, jour
feuille.Range(start).Offset(ligne, colonne).Interior.Color = RGB(&HD0, &HD0, &HD0)
End If
colonne = colonne + 1
If WeekDay(DateSerial(annee, mois, jour), vbMonday) = 7 Then
colonne = 0
ligne = ligne + 1
End If
jour = jour + 1
Wend
End Sub
10
sinon
si tab[milieu] = val
trouve <- vrai
sinon
si tab[milieu] > val alors
trouve <- rechercheDichotomiqueRecursive(tab, val, debut, milieu - 1)
sinon
trouve <- rechercheDichotomiqueRecursive(tab, val, milieu + 1, fin)
fin si
fin si
fin si
retourner trouve
fin
Dim tabEntiers(0 To NBELTS - 1) As Long ’ il est preferable de gerer les indices manuellement
’ car tabEntiers(MAX) contient MAX + 1 valeurs ...
Dim searchedValue As Long
Dim founded As Boolean
Dim tstart As Single
Dim tstop As Single
Dim i As Long
initSortedTab tabEntiers ’ rappel pour les procedures, il n_y a pas de parentheses lors de l’appel .
11
clearSheet (3) ’ numero de la feuille Excel pour l’affichage
Call afficheTab(tabEntiers, 3) ’ numero de la feuille Excel pour l’affichage
’ on recherchera sur le m^
eme tableau quel que soit l’algorithme
Debug.Print " tableau pre-trie cree ... "
’ 10000 recherches dichotomiques (SANS recursivite) d’une valeur quelconque sur le meme tableau
tstart = Timer ’ on lance le chronometre
For i = 1 To 10000
searchedValue = Rnd * tabEntiers(UBound(tabEntiers))
founded = rechercherDichotomique(tabEntiers, searchedValue) ’ on recherche
Next i
tstop = Timer ’ on arrete le chronometre
Debug.Print " 10000 Dichotomic searches (WITHOUT recursivity) elapsed time = " & tstop - tstart & "
End Sub
’ =====================================================================
’ definition des différentes fonctions (et procédures)
Randomize
tabToInit(0) = Rnd * 10
For i = 1 To UBound(tabToInit)
tabToInit(i) = tabToInit(i - 1) + Rnd * 10 ’ Rnd renvoie une valeur comprise entre 0 et 1
Next i
End Sub
Const MAXIMUM = 10000 ’ nombre maximum d’elements affiches dans une feuille
Dim i As Long
Dim lig As Integer ’ les lignes d’une feuille (de 1 a 65536)
Dim col As Integer ’ les colonnes d’une feuille (de A à IV)
Dim maxCells As Integer
12
lig = 0
col = 0
If (UBound(tableau) > MAXIMUM) Then
maxCells = MAXIMUM
Else
maxCells = UBound(tableau)
End If
’ calul de la taille d’un tableau, puisque cette fonction ne semble pas integree a VB...
Function tabLength(ByRef tableau() As Long) As Long
Application.ActiveWorkbook.Worksheets(numFeuille).Activate
Cells.Select
Selection.Clear ’ ou ClearContents
Range("A1").Select
End Sub
trouve = False
For i = 0 To UBound(tableau)
If tableau(i) = valeur Then
trouve = True
Exit For
End If
Next i
sequentialSearch = trouve
End Function
trouve = False
13
trouve = True
Else
If fin > debut Then ’ soit fin = debut = milieu => deja teste, soit fin < debut donc la vale
If valeur > tableau(milieu) Then ’ on recherche a droite (partie haute)
trouve = dichotomicSearch(tableau, valeur, milieu + 1, fin)
Else ’ valeur < tableau(milieu) et on recherche a gauche (partie basse)
trouve = dichotomicSearch(tableau, valeur, debut, milieu - 1)
End If
End If
End If
dichotomicSearch = trouve
End Function
debut = 0
fin = UBound(tableau)
trouve = False
Do
milieu = (debut + fin) / 2
If (tableau(milieu) = valeur) Then
trouve = True
Else
If tableau(milieu) = valeur Then
fin = milieu - 1
Else
debut = milieu + 1
End If
End If
Loop While (trouve = False And fin >= debut)
rechercherDichotomique = trouve
End Function
14
fin selon
tab <- creerTableau(tailleTab)
selon(caseACocher) // les différents cas ne sont pas exclusifs
cas majuscules
pour i <- 0 a 25
tab[nbElts + i] <- ’A’ + i // 0x41 + i
fin pour
nbElts <- nbElts + 26
cas minuscules
pour i <- 0 a 25
tab[nbElts + i] <- ’a’ + i // 0x61 + i
fin pour
nbElts <- nbElts + 26
cas chiffres
pour i <- 0 a 9
tab[nbElts + i] <- ’0’ + i // 0x30 + i
fin pour
nbElts <- nbElts + 10
cas special
tab[nbElts] <- caractere(boutonRadio)
nbElts <- nbElts + 1
fin selon
retourner tab
fin
15
FrmMotPasse.Height = 210
Else
FrmMotPasse.Height = 155
End If
End Sub
16
Next i
End If
If ChkChiffres = True Then
’ les 10 chiffres
For i = 0 To 9
tabCar = tabCar & Chr(&H30 + i)
Next i
End If
If ChkCarSpecial = True Then
’ le caractère spécial
If optDiese.Value = True Then
tabCar = tabCar & "#"
End If
If optDollar.Value = True Then
tabCar = tabCar & "$"
End If
If optExclamation.Value = True Then
tabCar = tabCar & "!"
End If
If optParagraphe.Value = True Then
tabCar = tabCar & " "
End If
If optAmp.Value = True Then
tabCar = tabCar & "&"
End If
End If
’ Debug.Print tabCar
Randomize
melanger tabCar
For i = 1 To TxtNbCar
indice = 1 + Rnd * (Len(tabCar) - 1) ’ dans une chaine de caracteres, les indices commencent a 1
password = password & Mid$(tabCar, indice, 1)
Debug.Print indice
Next i
calculerMotDePasse = password
End Function
17