IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)

Cours VB.NET

[ALT-PASTOUCHE]

Il s'agit d'un cours de Visual Basic.Net © de Microsoft complet, pour débutants (pas de prérequis) ou programmeurs voulant passer à la version .net.
Autres contributions du même auteur:
Cours sur Chart permettant d'afficher des graphiques
Pour voir et télécharger LDF: logiciel de compta en Shareware, cliquer ici.
Télécharger un dictionnaire médical gratuit pour Word.

philippe@lasserrelyon.fr

Nouveau : MAJ avec VB 2010, Nouvelles rubriques : en WPF

89 commentaires Donner une note à l´article (5)

Article lu   fois.

L'auteur

Liens sociaux

Viadeo Twitter Facebook Share on Google+   

I. Introduction

Il s'agit d'un cours de Visual Basic.Net © de Microsoft, pour débutants (pas de pré requis) ou de programmeur voulant passer à la version .net.

Le cours est basé sur VB 2005 (Framework 2), VB 2008 (Framework 3.5), VB 2010 (Framework 4).
VB 2003 (Framework 1) est progressivement abandonné, car il contenait des fautes de jeunesse.
Les versions Express (Gratuites) sont privilégiées.

Visual Basic.Net apporte une puissance inégalée et nécessite une rigueur importante, mais il devient vite complexe et technique. La documentation et les livres sont totalement hermétiques pour les novices et rebutent totalement les débutants. Les articles sur le Web sont très techniques et traitent d'emblée de problèmes complexes, ils sont nécessaires, mais pas pour le débutant. J'explique donc dans ce cours, à ma manière, très simplement, comment créer un programme afin de permettre un bon démarrage même à celui qui n'a jamais fait d'informatique.(Je traite des programmes Windows: Windows Forms et WPF mais pas ASP Web).J'encourage par ce cours sans prétention, à développer ses propres programmes.

Soyez un utilisateur actif

  • Retournez les bugs et erreurs et même les fautes d'orthographe. Mon site serait-il parfait ? J'en doute !! Merci de vos critiques.
  • Adressez-moi vos idées, du code original, des infos à mettre sur le site.
  • Ou simplement indiquez-moi que vous avez lu mon cours, cela fait toujours plaisir et m'incite à poursuivre.

Merci à developpez.com, à ses membres qui m'ont aidé (à Guillaume en particulier) à ceux qui m'envoient un petit mot, et à ceux qui me donnent un coup de main.

Cours constamment remis à jour : voir la date de la version en début d'article.

Questions à l'auteur : je ne peux pas répondre à toutes les questions particulières et spécifiques, car je n'ai pas d'expérience poussée dans tous les aspects de VB, et les questions sont très nombreuses, aussi je vous conseille d'utiliser les forums developpez.com

Image non disponible

II-A. Qu'allons-nous étudier ?

Ce cours est un cours de Visual Basic.Net développé par Microsoft.

Nous étudierons principalement : LES APPLICATIONS WINDOWS. (les WindowsForms) et les WPF.

Image non disponible

Les applications WindowsForms et WPF sont des programmes directement exécutables qui utilisent des fenêtres: des programmes de traitement de texte, d'image, de musique, des jeux, de petits utilitaires, des logiciels métiers (médicaux)…

Nous laisserons de côté les applications 'Web' (en ASP qui utilisent les WebForms) et qui permettent de créer des sites Internet, les applications 'console'.

Les versions étudiées sont VB 2005 (Framework 2), VB 2008 (Framework 3.5), VB 2010 (Framework 4).
VB 2003 (Framework 1) est progressivement abandonné, car il contenait des fautes de jeunesse.
Les versions Express (Gratuites) sont privilégiées.

II-B. Quel plan de cours suivrons-nous ?

Nous étudierons donc comment créer une application Windows.

Nous étudierons la notion d'objet, d'événement, d'instruction, procédure et module.(Section III).

Nous étudierons l'IDE ou interface de développement (Section IV).

Nous étudierons le langage Visual Basic (Section V).

Nous verrons les Classes VB (Section VI).

Nous utiliserons 'contrôles' WindowsForms pour créer l'interface utilisateur (Section VII).

Nous découvrirons la manière de créer une application Windows Forms.(Section IX).

Nous utiliserons les WPF pour créer l'interface utilisateur (Section XI).

Nous apprendrons à faire de la programmation objet et à créer une classe (Section XIII.)

Nous verrons comment utiliser les bases de données. (Section XV.)

II-C. Quels logiciels utiliser ?

Historique : il y avait Visual Basic.Net 2003 de Microsoft en 2003 !!

Image non disponible

Il fonctionnait avec le Framework 1.1.

En 2005 il y a eu Visual Basic 2005 de Microsoft et le Framework 2.0.

Ce produit .Net était maintenant mature, l'environnement de développement magique, les quelques points noirs de la version 2003 ont été corrigés.

Image non disponible

En 2008 il y a eu Visual Basic 2008 de Microsoft et le Framework 3.5 qui permettait d'utiliser les WPF.

Image non disponible

En avril 2010 il y a Visual Basic 2010 de Microsoft et le Framework 4.

Image non disponible

VisualStudio (payant) contient Visual Basix C#. Mais il existe aussi la version Visual Basic Express version allégée, mais très bien et GRATUITE, en français.

Est-il possible d'utiliser les éditions Express à des fins commerciales ?
Oui. Il n'y a aucune restriction liée aux licences pour les applications créées à l'aide des éditions Express.
Cette réponse (pour VB express 2008) est indiquée sur le site de Microsoft : http://msdn.microsoft.com/fr-fr/express/default.aspx

Ce cours utilise donc Visual Basic 2005 2008 et 2010 Express.

Si vous débutez, installez et utilisez sans hésitation Visual Basic Express 2010 GRATUIT
Nous abandonnons VB 2003, la première version en Net, qui avait quelques gros défauts.

Où trouver Visual Basic 2010 Express ?
Cliquer sur le lien:
http://www.microsoft.com/express/downloads/ Dans la liste de lien, cliquer sur 'Visual Basic Express 2010'.
Puis dans la liste 'Select language", choisissez"French", une fenêtre pop-up démarre.

Autre gratuit: SharpEditor venant du monde du libre.

Image non disponible
SharpEditor

Voici le site,SharpDevelop le configurer pour qu'il marche en VB (il supporte VB et C#).

II-D. Quelle configuration est nécessaire ?

Pour développer avec Visual Studio 2005 VB 2005 VB 2010.

il faut Windows XP ou 2000 (non vérifié pour VB 2010) ou Vista ou Windows 7 avec au minimum 1 Go de mémoire vive. Un grand écran (vu le nombre de fenêtres) est conseillé.

Les exécutables fonctionnent sous Windows 98 (pour VB 2003), XP (à vérifier pour VB 2008 et 2010), Vista, Windows 7.

II-E. À propos de l'auteur

LASSERRE Philippe est médecin généraliste exerçant en groupe dans le Rhône (à Toussieu), il développe des logiciels depuis des années.

Il n'est pas informaticien.

Il a travaillé avec des ordinateurs :

ZX81, New-Brain, Ti-99, TO7, Vic20, Oric, Apple II, puis PC avec l'aide de Bill.

Il a utilisé le Basic Microsoft, le QuickBasic le Visual Basic de Microsoft ® de la version 1 à la version VB6 et VB.Net, a fait un peu d'assembleur Z80 il y a longtemps.

Il a fait partie de MEDITRA, association de médecins informatisés du Rhône pionnière en la matière à l'époque, il a été cofondateur d'un club d'informatique local (Microzon) où on programmait dur !!

Ensuite il a écrit des logiciels, pour cela outre le côté technique informatique, il a beaucoup travaillé sur le dossier médical informatisé, les plans de soins.

Plein d'idées et de projets, un seul problème : il n'y a que 24 heures dans une journée.

Il est l'Auteur de :

CREEMED, il y a quelques années. C'était un utilitaire pour Medigest ® Dos.

MEDIWIN® distribué par Polytel , écrit en VB6, logiciel de gestion complète de cabinet médical dont il est le coauteur.

Logiciel agréé Sesam-Vitale, très complet, innovant, incluant les notions de "dossier vivant", "procédures de soins" (contenu médical validé par des thèses), travaillant avec la base de médicament BCB de Résip©, contenant le dictionnaire de la SFMG.
Ce logiciel n'est plus développé.

LDF logiciel de comptabilité en Shareware.Télécharger Ici.
Il distribue gratuitement un dictionnaire de termes médicaux pour Word.

Il a créé un site pour son association de plongée sous-marine (EmbellieBulle.fr) sous SPIP.
Il est fana de musique de cinéma de photographie et de voyages.

Vous pouvez envoyer un mail à Mr LASSERRE à l'adresse : lasserre.philippe@wanadoo.fr

III. Principe et structure des programmes

III-A. Les 'Objets'

Image non disponible

VB utilise la notion d'OBJETS'.

Pour bien comprendre ce qu'est un objet, nous allons prendre des exemples dans la vie courante puis nous passerons à des exemples dans Visual Basic.

Image non disponibleVoir la vidéo : au format 'Flash'> ou au format 'Avi' en Visual Basic 2005.

La vidéo (identique à celle du chapitre sur les Classes) contient :

1) Objets, Classes ;

2) Références, espaces de noms (à visionner plus tard).

III-A-1. Dans la vie courante

Ma voiture est un objet, cet objet existe, on peut l'utiliser.

Image non disponible

Ma voiture fait partie de "Les voitures", du type, du genre "Les voitures". "Les voitures" c'est une classe (Class) qui a ses caractéristiques.
"Les voitures" ont une couleur, un moteur…, elles roulent en transportant des passagers…

mais je ne peux pas utiliser "Les voitures", la Classe; pour me déplacer, il faut avoir un objet "voiture".

Avec la Classe je vais créer des Objets.

Pour fabriquer ma voiture, je prends les caractéristiques de la class "Les voitures" (c'est comme un moule, une usine) et je fabrique une voiture, je la nomme 'MaVoiture'.

 
Sélectionnez
Dim MaVoiture As New Lesvoitures

MaVoiture est maintenant un nouvel objet de type 'Les voitures'.

Image non disponible

Class --> Objet

Type 'Les voitures'--> Objet 'Mavoiture'

Un Objet est créé selon un 'modèle' qu'on appelle une Classe.

On dit aussi qu'il faut instancier un objet à partir de la Classe.

'Mavoiture' est une instance de la classe 'Les voitures'.

(On dit aussi une 'occurrence' de la classe).

De manière générale, une classe est une représentation abstraite de quelque chose.
Tandis qu'un objet est un exemple utilisable de ce que représente la classe.

Remarque

Avec la même classe on peut instancier plusieurs Objets.

Propriétés (Attributs)

Prenons MaVoiture.Image non disponible

Elle a des propriétés : une marque, une couleur, une puissance…

Pour indiquer la couleur de ma voiture on utilise la notation :

 
Sélectionnez
MaVoiture.couleur

Syntaxe : Objet.Propriété (Il y a un point entre les 2 mots).

Pour modifier la couleur et avoir une voiture verte on écrit :

 
Sélectionnez
MaVoiture.couleur= "Vert"

Et la voiture devient verte !! Image non disponible

MaVoiture.Phares.Avant indique les phares avant de la voiture.

MaVoiture.Phares.Avant.Allumé indique l'état des phares (Allumé ou non)

Si je fais :

MaVoiture.Phares.Avant.Allumé=True (Vrai) cela allume les phares.

Méthodes

MaVoiture fait des choses : elle roule par exemple.

Pour faire rouler la voiture j'appelle la méthode 'Roule'.

MaVoiture.Roule

Syntaxe : Objet.Méthode (il y a un point entre les 2 mots).

Si c'est possible pour cette méthode je peux indiquer à quelle vitesse la voiture doit rouler :

MaVoiture.Roule(100) 'j'ai ajouté un paramètre.

Le paramètre est un renseignement envoyé avec la méthode.

Il est possible parfois d'indiquer en plus si la voiture doit rouler en marche avant ou en marche arrière.

MaVoiture.Roule(10, Arriere)

Il y a donc 2 manières d'appeler la méthode Roule : avec 1 ou 2 paramètres, on dit que la méthode est surchargée, chaque manière d'appeler la méthode s'appelle 'signature'.

Première signature: MaVoiture.Roule(100)

Seconde signature: MaVoiture.Roule(10, Arriere)

événement

Des événements peuvent survenir sur un objet.

MaVoiture_démarre est un événement, quand la voiture se met en route (si par exemple j'ai fait MaVoiture.Roule(10, Arriere)), cet événement démarre se déclenche automatiquement.

Interface et implémentation

Ce que je vois de l'objet, c'est son interface exemple: la méthode Roule fait partie de l'interface d'une voiture. Par contre ce qui fait rouler physiquement la voiture se nomme implémentation, c'est le moteur, ce n'est ni visible ni accessible.

Si je crée une voiture je vais faire l'implémentation, je vais fabriquer le moteur, mais si je suis simplement utilisateur de l'objet voiture, je vais me contenter d'utiliser l'interface.

Visibilité

Quand un objet est créé, il est visible et utilisable, uniquement dans la zone où il a été défini.

Relation entre Objets

Héritage

Une Classe (un moule) peut hériter d'une autre classe (d'un autre moule).

La classe Voiture hérite de la classe Véhicule, cela veut dire qu'une voiture est un véhicule; la classe voiture aurait les propriétés de la classe Véhicule.

Contenant-contenu

On peut créer une Classe qui contient des Objets, une classe qui se compose d'objets. On parle de composition.

L'objet Voiture contient 4 objets Roue.

On dit que l'objet encapsule le contenu.

Collections

Les collections sont des groupes d'objets semblables qui peuvent être énumérés.

Un parc automobile contient X Voitures, chaque voiture a un numéro d'item:

ParcVoiture.item(1) pour la première Voiture ;

ParcVoiture.item(2) pour la seconde Voiture.

Espace de noms

Un espace de noms regroupe des objets qui appartiennent au même 'domaine'. Cela sert a différencier des objets qui ont même nom, mais ne font pas partie du même domaine. Si je parle de 'Porte' ce terme n'a pas la même signification si je suis dans l'espace de noms 'Composant électronique' (on y trouve des portes logiques) ou l'espace de noms 'Maison'.

Tout cela c'est simpliste, mais voilà, vous avez compris ce qu'est un objet !

III-A-2. Dans Visual Basic.net

Une application Windows se compose de fenêtres (nommées aussi formulaires) dans lesquelles se trouvent des contrôles (bouton, liste, texte…).

Exemple de fenêtre avec 2 boutons, une zone de texte (un label) et une icône :

Image non disponible

Dans une application Windows, il y a aussi des lignes de code utilisant des variables pour faire des calculs.

En Visual Basic.Net tout est objet :

- les fenêtres (on dit les formulaires) ;

- les variables ;

- les contrôles (bouton, liste, image, case à cocher…).

Il faut un moule pour faire un objet. Le moule c'est une Classe.

Le moule va servir à créer un objet,on dit une instance.

On peut créer, instancier une multitude d'objets avec le même moule.

Pour créer, démouler un objet, on utilise les mots-clés Dim et As New.

 
Sélectionnez
Dim objet As New Classe

New est un constructeur.

Exemple : créer une fenêtre (un formulaire) :

Je dessine une fenêtre FormDémarrage (c'est la Classe, le moule)

puis

 
Sélectionnez
Dim F As New FormDémarrage

Crée une fenêtre qui se nomme 'F' à partir du moule, du modèle (FormDémarrage) que j'ai dessiné.

Autre exemple :

 
Sélectionnez
Dim B As New Button

Créer un bouton nommé 'B' avec les attributs habituels des boutons (Class Button)

Troisième exemple

Comment créer une variable nommée Mavariable pouvant contenir un entier (Integer)

 
Sélectionnez
Dim MaVariable As New Integer

Dim MaVariable As Integer 'est correct aussi.

Ici, pour une variable, on remarque que New peut être omis

Tout objet a des propriétés.

On utilise la syntaxe : Objet.Propriété (il y a un point entre les 2 mots).

Si F est une fenêtre, F.BackColor indique la couleur de fond de la fenêtre.

S'il y a un bouton, la couleur de fond du bouton sera :

 
Sélectionnez
Bouton.BackColor

ou

 
Sélectionnez
F.Bouton.BackColor

Noter la syntaxe : la couleur du bouton qui est dans la fenêtre F.

En fait une propriété c'est une sorte de variable.

Comment modifier cette propriété ?

 
Sélectionnez
Bouton.BackColor=Color.Red

'modifie la couleur de fond du bouton

Image non disponible

Autre exemple :

La propriété Visible : si elle a la valeur True (Vraie) l'objet est visible, si elle est à False l'objet n'est pas visible.

 
Sélectionnez
Bouton.Visible=False

fait disparaitre le bouton.

=Ici il y a un bouton invisible !! oui, oui !!

Les objets ont des méthodes parfois.

Une méthode agit sur l'objet ou fait agir l'objet.

Prenons un exemple simplifié.

Les listes (liste déroulante) ont des lignes (Items) et une méthode Clear qui permet de les vider.

Si je veux vider toutes les lignes d'une liste nommée Liste1, je fais :

 
Sélectionnez
Liste1.Items.Clear()

Image non disponible Les propriétés et méthodes se nomment les membres d'un objet.

Certains objets ont des événements.

Reprenons notre bouton. Quand l'utilisateur clique dessus, l'événement Bouton_Click survient.

Ce sont les objets contrôles (bouton, case à cocher…)et les formulaires qui ont des événements.

Interface et implémentation

Ce que je vois de l'objet, c'est son interface (le nom des propriétés, méthodes…) exemple : la méthode Clear fait partie de l'interface d'une ListBox. Par contre le code qui effectue la méthode (celui qui efface physiquement toutes les lignes de la listBox), ce code se nomme implémentation, lui n'est ni visible ni accessible.

Visibilité

Quand un objet est créé, il est visible et utilisable, uniquement dans la partie du programme où il a été défini.

Par exemple habituellement, je peux voir et modifier la couleur d'un bouton uniquement dans le code de la fenêtre ou il est situé.

Pour les variables on parle de portée : la variable peut être locale (Private) ou de portée générale ('Public') visible partout.

Relation 

Héritage

Une Classe (un moule) peut hériter d'une autre classe (d'un autre moule).

La classe Button hérite de la classe Control, cela veut dire qu'un bouton est un contrôle.

Si je crée un bouton, il aura les caractéristiques de la classe Button, mais aussi de la classe Control.

Contenant-contenu

Une Classe peut contenir d'autres classes.

Je peux décider qu'un Objet Rectangle va contenir 4 Objets Point

Collections

Les collections sont des groupes d'objets semblables qui peuvent être énumérés.

Une fenêtre Windows (on dit un 'formulaire' contient une collection nommée 'Controls' composée de tous les objets (boutons, List, texte) contenus dans la fenêtre :

 
Sélectionnez
maFenetre.Controls.item(1)

contient par exemple le premier bouton

 
Sélectionnez
maFenetre.Controls.item(2)

contient par exemple une liste.

En résumé

Une classe est un élément logiciel qui décrit un type de données abstrait. Un type de données abstrait est un ensemble d'objets définis par une liste d'opérations et les propriétés de ces opérations Une classe est un élément logiciel qui décrit les caractéristiques d'un ensemble d'objets. En programmation orientée une classe déclare des propriétés communes à un ensemble d'objets. La classe déclare des attributs représentant l'état des objets et des méthodes représentant leur comportement. Une classe représente donc une catégorie d'objets. Il apparait aussi comme un moule ou une usine à partir de laquelle il est possible de créer des objets. On parle alors d'un objet en tant qu'instance d'une classe (création d'un objet ayant les propriétés de la classe). (www.techno-science.net)

En Visual Basic.net tout est objet.

Les Classes sont des types d'objets.

Pour créer (instancier) un objet à partir d'une Classe, il faut utiliser les mots clé Dim …As New :

 
Sélectionnez
Dim Objet As New Class

Un objet a :

  • des propriétés ;
  • des méthodes ;
  • des événements.

Attention, par abus de langage, on emploie parfois indifféremment les mots 'Classe' et 'Objet', mais il est préférable de ne pas confondre le modèle et l'objet lui-même.

Espace de noms

Les objets sont regroupés dans des bibliothèques d'objets, dans des 'espaces de noms'.

Il faut parfois importer la bibliothèque avant d'utiliser l'objet :

 
Sélectionnez
'Importe l'espace de noms Systel.IO
Imports System.IO

'On peut maintenant utiliser l'objet 'File':
Fl = File.Exists("vessaggi.gif")

Si l'import n'a pas été fait, System.IO.File.Exists() est accepté aussi.

Lexique anglais=>français.

New = Nouveau.

III-B. Programmation événementielle : le premier programme

Nous allons comprendre la programmation événementielle : comment fonctionne Visual Basic.

  • Ce que voit l'utilisateur.
  • Ce qu'a fait le développeur pour arriver à ce résultat.

Voir la vidéo au format 'Flash': Image non disponible ou au format AVI Image non disponible en Visual Basic 2005

III-B-1. Principes de la programmation VB

Le programmeur va dessiner l'interface utilisateur (fenêtre, bouton, liste…), il va ensuite uniquement écrire les actions à effectuer quand certains événements se produisent sur cette interface.

C'est Visual Basic qui va entièrement s'occuper de la gestion des événements.

III-B-2. Exemple : le premier programme

Il affiche 'Bonjour' quand on clique sur un bouton.

Ce n'est pas original : le premier programme, dans tous les cours d'informatique, permet d'afficher 'Bonjour' (ou 'Hello Word').

Que voit l'utilisateur du programme ?

L'utilisateur final, celui qui utilise le logiciel, voit une fenêtre avec un bouton, S'il appuie sur ce bouton il voit s'afficher "Bonjour".

Image non disponible

Que se passe-t-il dans le programme ?

Quand l'utilisateur clique sur le bouton, cela déclenche automatiquement un événement. (Button1_Click), cet événement contient du code qui affiche "Bonjour".

Que doit faire le programmeur pour arriver à ce résultat ?

Pour atteindre ce résultat, le programmeur va dessiner la fenêtre, le bouton, la zone d'affichage du texte (un label) puis il va simplement indiquer dans l'événement Button_Click d'afficher "Bonjour".

Le fait de déterminer la procédure à appeler ou de réaliser l'appel est entièrement pris en charge par VB.

III-B-3. En pratique, que fait le programmeur ?

Image non disponibleVoir la vidéo : au format 'Flash'> ou au format 'Avi' en Visual Basic 2005.

Le programmeur est en mode 'conception' (ou mode Design) : il écrit le programme.

III-B-3-a. Il dessine l'interface utilisateur

(Ce que verra l'utilisateur final, c'est l'interface utilisateur : une fenêtre avec des boutons, des listes, du texte…) :

Image non disponible

Il ouvre un projet : une fenêtre 'Form1' apparait.

Il ajoute un bouton.

Pour cela il utilise la Boite à outils :

Image non disponible

Il clique sur 'Boite à Outils' à gauche, bouton Windows Forms, puis bouton 'Button', il clique dans Form1, déplace le curseur sans lâcher le bouton, puis lâche le bouton de la souris : le dessin d'un bouton apparait.

Pour l'exemple,Il ajoute un label.

Un label est un contrôle qui permet d'afficher un texte.

Comme pour le bouton, il clique sur 'Boite à Outils' à gauche, bouton Windows Forms, bouton 'Label' et met un contrôle label sur la fenêtre.

III-B-3-b. Il écrit le code correspondant aux événements

Il double-clique sur le bouton qu'il a dessiné :

Une fenêtre de conception de code s'ouvre et il apparait :

 
Sélectionnez
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

End Sub

Cela correspond à la procédure événement en rapport avec l'événement 'On a cliqué sur le bouton1'.

Quand le programme fonctionne, quand l'utilisateur du logiciel clique sur le bouton1, le code situé entre Private Sub Button1Click et End Sub est effectué.

Une procédure est un ensemble de lignes de code qui commence par Sub et se termine par End Sub (ou Function…End Function).

Comment indiquer dans cette procédure d'afficher "Bonjour" ?

Le label possède une propriété nommée '.text' qui contient le texte à afficher.

Il faut taper le code qui modifie cette propriété '.text' , qui y met la chaine de caractères "Bonjour":

 
Sélectionnez
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

        Label1.Text = "Bonjour"

End Sub

Cela donne :

Image non disponible

Voilà votre premier programme est écrit.

Comment exécuter ce programme ?

Il est possible de tester immédiatement le programme en mode débogage, sans quitter l'environnement de développement.

Utiliser le menu 'Déboguer' puis 'Démarrer' qui lance l'exécution du programme.

On peut aussi taper sur F5 pour lancer le programme.

Ou plus simplement cliquer sur la flèche :

Image non disponible

C'est plus rapide, lancer l'exécution avec le premier bouton, le second servant à arrêter temporairement l'exécution, le troisième à terminer l'exécution.

En mode exécution

L'utilisateur voit bien une fenêtre avec un bouton, s'il clique dessus, "Bonjour" s'affiche.

Quand le programme est totalement écrit, terminé, testé, il est possible de le compiler et ainsi de créer un fichier exécutable (possédant une extension '.exe') qui fonctionne de manière autonome en dehors de l'environnement de développement.

C'est ce fichier exécutable qui est fourni à l'utilisateur.

Par opposition le code écrit par le programmeur, composé d'instructions Visual Basic, se nomme le code source.

En résumé

Le programmeur utilise des outils de dessin pour construire une interface utilisateur : des fenêtres avec des contrôles dessus: menus, boutons, case à cocher…

VB, pour chaque fenêtre ou pour chaque contrôle, génère une liste d'événements, (événement lié au chargement d'une fenêtre, événement lié au fait de cliquer sur un bouton, événement survenant quand on modifie un texte…).

Il suffit, dans la procédure événement qui nous intéresse, d'écrire le code qui doit être effectué lorsque cet événement survient.

Comme nous l'avons vu le code sert à agir sur l'interface (Afficher un texte, ouvrir une fenêtre, remplir une liste, un tableau), mais il peut aussi effectuer des calculs, évaluer des conditions et prendre des décisions, travailler en boucle de manière répétitive et ainsi effectuer les tâches nécessaires.

III-C. Les instructions, les procédures : les 'Sub', les 'Function'

Qu'est-ce qu'une instruction, une procédure ?

Quelle différence entre les procédures liées aux événements ? Non liées ? :

Les 'Sub', les 'Functions'.

III-C-1. Les instructions

Une instruction est le texte tapé au clavier dans le 'code source' et permettant d'effectuer une opération, une déclaration, une définition.
Elle contient des mots-clés, des opérateurs, des variables, des constantes et des expressions des appels à des fonctions ou des méthodes. On verra cela en détail.

 
Sélectionnez
Dim A As Integer

est une instruction (de déclaration).

 
Sélectionnez
A = 1

est aussi une instruction qui effectue une opération.

C'est habituellement une 'ligne de code exécutable'…

Une instruction est exécutée lorsque le programme marche.

Plusieurs instructions peuvent se suivre sur une même ligne, séparées par ':'

 
Sélectionnez
Dim B As String : B="Bonjour"

Si une ligne est très longue, on peut passer à la ligne grâce à ' _'

(caractère 'Espace' puis caractère "_" puis immédiatement après, passage à la ligne) :

 
Sélectionnez
Dim B, C As String
B = "Bonjour monsieur ": C= _
"le professeur"

est équivalent à :

 
Sélectionnez
Dim B, C As String
B = "Bonjour monsieur ": C= "le professeur"

En VB 2010, après certains mots, il peut y avoir continuation de ligne implicite (plus besoin de _ après la virgule, une parenthèse ouvrante, après & ou { ou = ou +…).

Quand un programme tourne, les instructions sont effectuées ligne après ligne.

 
Sélectionnez
1  Dim B As String 

2  B="Bonjour"

3  Dim A As Integer 

4  A= 3

5  A= A + 1

La ligne 1 est exécutée puis la ligne 2 puis la 3, la 4…

Bien que l'on puisse avoir des numéros de ligne, ils ne sont plus utilisés actuellement et non visibles :

 
Sélectionnez
Dim B As String 

B="Bonjour"

Dim A As Integer 

A= 3

A= A + 1

Pour mettre des commentaires dans un programme, on le fait précéder de ' (on peut aussi utiliser le mot REM en début de ligne).

 
Sélectionnez
'Ceci est un commentaire, 
'Cela n'est pas une instruction.
REM Ceci est aussi un commentaire.

Le commentaire ne sera pas exécuté.

Il peut aussi, à partir de VB 2005 , y avoir des commentaires en XML, ils sont dans ce cas précédés de ''' (3').

Image non disponible

III-C-2. Les procédures

Une procédure est un ensemble d'instructions, de lignes de code, un groupement d'instructions bien définies effectuant une tâche précise.

Les procédures sont bien délimitées.

Il y en a de 2 sortes.

Les procédures Sub

Elles débutent par le mot Sub et se terminent par End Sub.

Les procédures Function

Elles débutent par Function et se terminent par End Function.

Exemple :

 
Sélectionnez
Sub Maprocédure

   A=1

End Sub

Exemple concret d'une procédure : la procédure Button_Click du premier programme. (Celui qui affiche 'Bonjour', elle ne contient qu'une ligne de code. Le mot Sub est précédé de Private, on verra plus loin ce que cela signifie.

Image non disponible

Vous avez vu que l'on peut dessiner l'interface, une fenêtre Form1 par exemple. En mode conception, après avoir dessiné l'interface, on doit avoir accès aux procédures.

Si on double-clique sur la fenêtre, on a accès aux procédures événement liées à cette fenêtre, si on double-clique sur un objet (bouton, case à cocher…), on voit apparaitre les procédures événement de ce contrôle.

Image non disponible

Quand on voit ces procédures, on peut y inclure du code.

Nous allons voir qu'il y a 2 types de procédures : les procédures liées aux événements et celles qui ne sont pas liées.

III-C-3. Procédures liées aux événements

Si on double-clique sur le fond d'une fenêtre (en vb 2010),(celle du programme 'Bonjour') on voit apparaitre les procédures liées à cette fenêtre et aux contrôles contenus dans cette fenêtre :

 
Sélectionnez
Public Class Form1



Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs)  _
Handles MyBase.Load

            Label1.Text = ""   

End Sub

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) _
Handles Button1.Click

        Label1.Text = "Bonjour"

End Sub

End Class

Détaillons :

 
Sélectionnez
Public Class Form1
    
End Class

Ce n'est pas une procédure, mais la 'Classe' définissant la fenêtre.

En VB 2003, il y a une 'région' que vous déroulez, en cliquant sur le petit +, vous pouvez y lire le code permettant de créer la fenêtre, les contrôles… C'est généré automatiquement par VB. (Le chapitre VII-C sur les formulaires explique en détail le code généré par VB, mais c'est un peu complexe pour les débutants pour le moment !!).

En VB 2005 2008 et 2010, cette partie générée par VB n'est pas visible directement.

Il faut comprendre qu'à un formulaire (fenêtre) et aux contrôles qui sont dans ce formulaire correspond du code généré par VB. Ce code (sur lequel vous n'intervenez habituellement pas) permet de créer le formulaire et les contrôles.

Chaque fenêtre a une procédure Form_Load qui est exécutée lorsque la fenêtre est chargée, on y met généralement le code initialisant la feuille.

 
Sélectionnez
Private Sub Form1_Load

End Sub

Il y a bien d'autres procédures liées à la fenêtre.

Dérouler la liste box en haut à gauche de la fenêtre de code, cliquer sur (Form1 events), si vous déroulez maintenant la liste à droite vous aurez tous les événements qui génèrent une procédure :

Load Lors du chargement de la fenêtre ;

Unload Lors du déchargement de la fenêtre ;

Activated Lorsque la fenêtre devient active ;

GotFocus Lorsque la fenêtre prend le focus ;

Resize Lorsque la fenêtre est redimensionnée.

 
Sélectionnez
Private Sub  Button1_Click

End Sub

C'est la procédure liée au bouton et qui contient le code à effectuer quand l'utilisateur clique sur le bouton.

C'est là que l'on écrit le code qui doit s'effectuer lorsque l'utilisateur clique sur le bouton.

De la même manière que pour la fenêtre, vous pouvez voir dans la liste en haut, tous les événements liés aux boutons qui génèrent une procédure :

Click Lorsque l'utilisateur clique sur le bouton ;

DoubleClick Lorsque l'utilisateur double-clique sur le bouton ;

MouseDown 'se déclenche si appui du bouton gauche de la souris ;

MouseUp 'se déclenche si relâchement du bouton gauche de la souris.

On voit donc que le formulaire (la fenêtre) et tous les contrôles d'une application ont chacun des procédures pour chaque événement qui peut survenir.

III-C-4. Procédures non liées

Parfois on a besoin de code qui fait une tâche particulière, qui est utilisé à plusieurs endroits et qui n'est pas liée à un événement.

On crée dans ce cas une procédure indépendante des événements.

Le système des procédures permet aussi de découper un problème complexe en quelques fonctions moins complexes et indépendantes les unes des autres.

Un programme vb est donc composé de procédures dont l'exécution est déclenchée par des événements (ouverture d'une fenêtre, clic sur un bouton…), ces procédures en appellent d'autres qui en appellent d'autres…

Ces procédures sont en fait des sous-programmes : si une ligne appelle une procédure, le programme 'saute' au début de la procédure, il effectue le code de la procédure puis revient juste après la ligne qui avait appelé la procédure et continue les lignes suivantes.

Exemple : plusieurs fois dans le programme j'ai besoin de calculer la surface d'un cercle à partir de son rayon et de l'afficher sur un label.

Plutôt que de retaper dans chaque procédure le code, je peux créer une procédure 'Sub' nommée AfficheSurfaceCercle.

Il suffit ensuite si nécessaire d'appeler la procédure qui effectue le calcul et affiche le résultat puis revient effectuer le code situé après l'appel.

Comment appeler une procédure ?

Avec :

 
Sélectionnez
Call NomdeProcedure()

ou par

 
Sélectionnez
NomdeProcedure()

Call est facultatif.

Noter les parenthèses après le nom de la procédure.

III-C-5. Procédures 'Sub'

Comment créer cette procédure Sub ?

Dans la fenêtre de code, tapez :

 
Sélectionnez
Sub AfficheSurfaceCercle

puis validez. Vous obtenez :

 
Sélectionnez
Sub AfficheSurfaceCercle()

End sub

Le code de la procédure est compris entre le Sub et le End Sub.

Pour que le calcul se fasse, il faut fournir (transmettre de la procédure qui appelle à la procédure Sub) la valeur du rayon.

Pour indiquer que la Sub doit recevoir un paramètre (un argument en VB) ajouter entre les parenthèses :

 
Sélectionnez
Sub AfficheSurfaceCercle( Rayon as Single)

Cela signifie qu'il existe une procédure qui reçoit comme paramètre une variable de type Single (Réel simple précision) contenant le Rayon.

Ajouter le code :

 
Sélectionnez
Label.text =(3.14*Rayon*Rayon).ToString

Que fait cette ligne ?

Elle fait le calcul: '3.14*Rayon*Rayon' ('*' signifie multiplier), on transforme le résultat en chaine de caractères (grâce à '.ToString') que l'on met dans la propriété .text du label : Cela affiche le résultat. (On verra toute cette syntaxe en détail ultérieurement.)

On obtient :

 
Sélectionnez
Sub AfficheSurfaceCercle( Rayon as Single)

    Label.text =(3.14*Rayon*Rayon).ToString

End sub

Comment appeler cette Sub ?

N'importe quelle procédure pourra appeler la Sub AfficheSurfaceCercle en envoyant la valeur du rayon afin d'afficher la surface du cercle dans un label.

Exemple d'appel pour un rayon de 12 :

 
Sélectionnez
AfficheSurfaceCercle(12)

Affiche dans le label : 452.16.

III-C-6. Procédures 'Function'

Parfois on a besoin que la procédure retourne un résultat, un seul, qu'elle donne en retour un résultat à la procédure appelante. Dans ce cas on utilise une Fonction.

Exemple : je veux créer une fonction à qui je fournis un rayon et avoir en retour la surface d'un cercle.

Comment créer cette Function ?

Tapez Function SurfaceCercle puis validez, ajouter (Rayon As Single)

Tapez Return 3.14*Rayon*Rayon

Ce que la fonction doit retourner est après Return (ce que la procédure doit renvoyer à la procédure appelante).

On obtient la fonction complète :

 
Sélectionnez
Function SurfaceCercle( Rayon as Single)

    Return 3.14*Rayon*Rayon

End Function

Comment appeler cette Function ?

Dans la procédure qui appelle, il faut une variable pour récupérer la valeur retournée par la Fonction :

 
Sélectionnez
S= NomdelaFonction()

N'importe quelle procédure pourra appeler la fonction et obtenir le résultat dans la variable S par exemple pour un rayon de 12 :

 
Sélectionnez
Dim S As Single

S=SurfaceCercle(12)

On appelle la fonction SurfaceCercle en envoyant le paramètre '12', ce qui fait qu'à l'entrée de la fonction, Rayon=12, le calcul est effectué et le résultat du calcul (452.16) est retourné grâce à Return. S récupère ce résultat.

Après l'appel de cette fonction, S est égal à 452.16.

Il est possible de spécifier le type retourné par la fonction :

 
Sélectionnez
Function SurfaceCercle( Rayon as Single) As Single

As Single en fin de ligne après () indique que la fonction retourne un Single (un nombre en simple précision). Il faut donc que la variable qui reçoit la valeur retournée (S dans notre exemple) soit aussi un Single.

Il existe une autre manière de retourner le résultat d'une fonction, reprenons l'exemple précédent, on peut écrire :

 
Sélectionnez
Function SurfaceCercle( Rayon as Single)

     SurfaceCercle= 3.14*Rayon*Rayon

     Exit Function

End Function

Ici on utilise le nom de la fonction pour retourner le résultat, avec un signe '='.

Utilisez plutôt la méthode Return.

Exit Function permet aussi de sortir de la fonction, cela a le même effet que Return sauf que Return peut être suivi d'un argument de retour (et pas Exit Function).

III-C-7. Module standard

La Sub AfficheSurfaceCercle affiche le résultat dans le formulaire où elle est située.

Par contre la fonction SurfaceCercle est d'intérêt général, n'importe quelle procédure doit pouvoir l'appeler, de plus elle n'intervient pas sur les contrôles des formulaires et n'est donc pas liée aux formulaires.

On la placera donc dans un module standard qui est un module du programme qui ne contient que du code. (Pas d'interface utilisateur)

Pour créer un module standard Menu Projet>Ajouter un module.

Y mettre les procédures.

III-C-8. Private Public

Avant le mot Sub ou Function on peut ajouter :

Private indiquant que la procédure est accessible uniquement dans le module.

C'est donc une procédure privée.

Les procédures liées aux événements d'une feuille sont privées par défaut.

Public indiquant que la procédure est accessible à partir de toute l'application.

S'il n'y a rien devant Sub la procédure est publique

Exemple :

 
Sélectionnez
Private Function SurfaceCercle( Rayon as Single)

    Return 3.14*Rayon*Rayon

End Function

III-C-9. Remarques

Pour sortir d'une procédure Sub avant la fin, utiliser Exit Sub (Exit Function pour une fonction).

Quand vous appelez une procédure, il faut toujours mettre des parenthèses même s'il n'y a pas de paramètres.

 
Sélectionnez
FrmSplash.ShowDialog ()

Éventuellement on peut faire précéder l'appel du mot-clé Call, mais ce n'est pas obligatoire.

 
Sélectionnez
Call FrmSplash.ShowDialog ()

Nommage

Quand vous créez une procédure utilisez "la casse Pascal" pour créer les noms de routine:

la première lettre de chaque mot est une majuscule (c’est donc une convention).

 
Sélectionnez
Sub CalculTotal()

III-C-10. Lexique anglais=>français

Call = Appel.

Return= Retour.

Private= Privé.

Show= spectacle, exposition.

To show= montrer.

III-D. Les modules

III-D-1. Qu'est-ce qu'un module ?

On a vu qu'un programme est décomposé en modules, chaque module contenant des procédures.

Chaque module correspond physiquement à un fichier '.vb'.

Il existe

  • les modules de formulaire ;
  • les modules standards ;
  • les modules de 'Classe'.

Comment se présentent-ils ?

Image non disponible

Un programme Visual Basic comporte donc :

  • Les 'Modules de Formulaires' contenant :
    - le dessin des fenêtres de l'interface utilisateur (ou formulaire)contenant les contrôles (boutons, listes, zones de texte, cases à cocher…) ;
    - le code qui comprend :
    les procédures liées aux événements de la feuille (Button_Click…),
    les procédures indépendantes des événements. Ce sont des Sub() ou des Function().
    Exemple :

     
    Sélectionnez
    Class Form1        'Nom du Formulaire
    
    Inherits System.Windows.Forms
    
    Public A as String
    
        ……
    
    Private Button1_Click 'Procédure liée à un événementEnd Sub
    
     
    
    Sub MaRoutine         'Procédure indépendante.
    
    End Sub
    
    End Class

    Un programme Visual Basic comporte donc :

  • les modules standards.
    Ils servent de stockage de procédures. Procédures "d'intérêt général".
    Ces procédures sont des Sub() ou des Function() qui peuvent être appelées à partir de n'importe quel endroit (pourvu qu'elles soient 'Public').
    Ils peuvent aussi servir à déclarer les objets ou déclarer les variables 'Public' qui seront utilisées donc accessibles par la totalité du programme.
    Exemple :

     
    Sélectionnez
    Module Module1        'Nom du Module
    
        Public A as String
    
        ……
    
     Sub MaRoutine        'Procédure indépendante
    
     ……
    
     End Sub
    
    End Module

    Un programme Visual Basic comporte donc :

  • les modules de Classe.
    Ils ont vocation à fabriquer des objets, on verra cela plus loin (Chapitre sur la programmation objet).
    Exemple :
 
Sélectionnez
Class MaClasse            'Nom de la Classe

    Public A as String

    ……

End Class

Un programme Visual Basic comporte donc :

On remarque que les Class, formulaires, Modules, Sub, Functions sont délimités par :

une ligne de début comportant le type et le nom du module ;

une ligne de fin contenant End et le Type.

Exemple :

 
Sélectionnez
Module Module1        'Nom du Module.

End Module

 

Sub MaRoutine        'Procédure

 ……

End Sub

III-D-2. Comment créer un module standard

Faire Menu Projet puis Ajouter un module. Donner un nom au module. C'est Module1.vb par défaut.

 
Sélectionnez
Module Module1        'Nom du Module.

End Module

On remarque que le module est bien enregistré dans un fichier '.vb'.

Un module standard ne contient que du code.

Comment ajouter une Sub dans un module Standard ?

Taper Sub Calcul puis valider, cela donne :

 
Sélectionnez
Sub Calcul()

End Sub

Remarque Les Sub, Functions et Modules sont utilisés dans un type de programmation dite 'procédurale' où on découpe le code. Il existe un autre type de programmation dit 'Objet' ou on crée et on utilise des Objets, on verra cela plus tard.

III-D-3. Lexique anglais=>français

Return = Retour.

III-E. Notion de programmation 'procédurale' et de programmation 'objet'

Il y a deux manières de travailler en VB.NET.

  • En programmation 'Procédurale'
    Chaque problème est décomposé en 'Fonctions'(Les Subs et Fonctions).
    La programmation structurée découpe les problèmes en fonctions (Sub et Function). Ce découpage s'il est systématiquement employé aboutit à la programmation fonctionnelle qui consiste en un emboîtement de fonctions que l'on peut voir comme des "boites noires" que l'on peut imbriquer les unes dans les autres. Chaque fonction contient du code VB qui permet d'effectuer le travail dévolu à la fonction.
    Ces fonctions sont stockées dans des modules standards (ou dans les modules de formulaire).
    Dans une application en programmation 'procédurale' il y a habituellement :
    des modules de formulaires ;
    des modules standard contenant des Sub et Function.
    N. B. j'utilisais, dans la précédente version du cours, le terme de programmation 'fonctionnelle' pour une programmation utilisant des Sub et Fonction. Dans Wikipedia la programmation fonctionnelle c'est autre chose aussi je parle maintenant de programmation 'procédurale'…
  • En programmation 'Objet'
    On verra cela plus tard : on crée ses propres objets dans des modules de Classe, on utilise les membres (Propriétés et méthodes) de ces objets pour programmer.
    Dans une application en programmation 'Objet' il y a habituellement :
    des modules de formulaires ;
    des modules de classe permettant de créer des Objets.
    Grâce aux Classes (qui contiennent le code), on crée des objets.
    Ensuite on utilise les propriétés et méthodes des objets.

De toute façon, dans les 2 cas, que se soit dans des Sub ou des Classes, on utilise du code Visual Basic.

La mode est à la programmation Objet !!

IV. Environnement de développement : les EDI/IDE

IV-A. IDE Visual Studio 2008 (Microsoft)

C'est l'Integrated Development Environment (IDE): Environnement de développement intégré de Visual Basic Express 2008 de Microsoft. Il permet de dessiner l'interface (les fenêtres, les boutons, List, Image…) et d'écrire le code VB. Chez nous, on peut aussi dire EDI (Environnement de Développement Intégré).

L'IDE de Visual Basic 2008 est identique à celle de VB 2005, bien meilleur que celle de VB 2003 et l'Édition Express' (version légère par rapport à Visual Studio) est GRATUITE. Donc pas d'hésitation, chargez et utilisez VB Express 2008.

Charger sur ce lien VB Express 2008

Pour la version française, dans le cadre bleu 'Visual Basic Edition Express' dérouler la liste et choisir 'French' puis 'Download'.

Vous pouvez voir une vidéo sur l'IDE 2005 (c'est la même que pour la version 2008).

Image non disponibleVoir la vidéo : au format 'Flash'> ou au format 'Avi' en Visual Basic 2005.

(En flash, il y a un arrêt au milieu : patientez. En Avi ne pas tenir compte des avertissements qui déclarent que le fichier n'est pas valide).

Fenêtre Projet

Quand on lance VB.net 2008, on ouvre l'IDE dans laquelle la fenêtre centrale charge la page du centre de développement Visual Basic de MSDN (site Microsoft), il faut être connecté à Internet.

Image non disponible

En cliquant sur le bouton 'flèche verte' en haut à droite, on affiche la Page de démarrage "Start Page" qui permet d'ouvrir un projet existant Ouvrir (Recent Projects ou Open dans la version anglaise) ou de créer un nouveau projet :Créer (Create dans la version anglaise).

Image non disponible

On constate que les diverses fenêtres sont accessibles par des onglets. L'IDE de VB 2008 diffère peu de celui de VB 2005.

Pour créer un nouveau projet Visual Basic, il faut choisir 'Créer' à gauche ou passer par le menu 'Fichier' puis 'Nouveau' puis 'Projet' . La fenêtre suivante s'ouvre :

Image non disponible

On a le choix à partir de VB 2008 de créer l'interface utilisateur : en Windowsforms (basé sur GDI+), interface habituelle, bien connue ou en WPF interface vectorielle élaborée n'existant pas avant VB 2008.

IV-A-1. Interface 'Windows Forms'

Choisir l'icône 'Application Windows forms', puis donner un nom au projet, enfin valider sur 'OK'.

(Le chemin de l'emplacement du projet n'est pas modifiable ici, il est par défaut ' C:\Documents and Settings\Nom Utilisateur\Mes documents\Visual Studio 2008\ Projects\MonProjet'.)

On remarque qu'on aurait pu choisir 'Application WPF', on y reviendra.

Dans un nouveau projet, créer ou ajouter une fenêtre 'WinForm'.

Pour ajouter une fenêtre (un formulaire) Menu Project, Ajouter un formulaire Windows ( 'Add a WindowsForms' en version anglaise ) :

Image non disponible

Cliquer sur Windows Form, une fenêtre (un formulaire) Form2 vide apparait (Form1 était le nom du premier formulaire).

Il y a des fenêtres toutes faites pour accélérer le travail (les templates) comme les 'Écrans de démarrage' les 'Formulaire Explorateur'…

Designer

La zone de travail se trouve au centre de l'écran : c'est l'onglet Form1.vb[Design] ci-dessous qui donne donc accès au dessin de la feuille (du formulaire), on peut ajouter des contrôles, modifier la taille de ces contrôles…

Image non disponible

On peut passer en mode 'Multidocument Mdi' (comme en VB6) au lieu du mode 'Onglet'.

(Passer par le menu 'Outils' puis 'Options…' puis bouton 'Multidocument (Mdi)'.)

Image non disponible

On obtient un mode multidocument avec plusieurs fenêtres.

Image non disponible

Exemple en mode Mdi montrant les 3 types de modules.

Image non disponible

À noter que si on utilise le menu 'Projet' puis 'Ajouter…' cela permet d'ajouter un formulaire, un module standard, un module de Classe.

Voir les procédures.

L'onglet Form1.vb donne accès aux procédures liées à Form1.

Image non disponible

On peut 'taper' du code dans les procédures.

La liste déroulante de gauche donne la liste des objets, celle de droite, les événements correspondants à cet objet.

Il est possible en double-cliquant dans le formulaire ou un contrôle de se retrouver directement dans le code de la procédure correspondant à cet objet.

Ici on voit la procédure Button1_Click liée au Button1 de la fenêtre de Design.

Ajouter des contrôles au formulaire 'Winform'

Ajouter un bouton par exemple :

Cliquer sur Boite à outils (Toolbox) à gauche, les contrôles apparaissent tous ou classés par ordre alphabétique.

Image non disponible

Cliquer sur 'Button' dans la boite à outils, cliquer dans la Form, déplacer le curseur sans lâcher le bouton, puis lâcher : un bouton apparait.

Image non disponible

Modifier les propriétés d'un contrôle ou du formulaire.

Quand un formulaire ou un contrôle est sélectionné dans la fenêtre Design, ses propriétés sont accessibles dans la fenêtre de 'Propriétés' (Properties) à droite en bas : ici ce sont les propriétés du contrôle 'Button1' qui sont visibles (Text, Location…) on peut modifier directement les valeurs.

Image non disponible

En bas de la fenêtre propriétés, il y a une explication succincte de la propriété sélectionnée (si elle n'apparait pas, clic droit sur la propriété puis dans le menu 'Description').

Exemple

Si au niveau de la ligne 'Text' des propriétés du bouton, j'efface 'Button1' et que je tape 'OK', dans le designer, le texte écrit sur le bouton deviendra 'OK'.

Le déplacement des contrôles ou l'accès aux principales tâches est facile.

La croix à gauche permet de déplacer le contrôle, la petite flèche à droite permet d'ouvrir un menu qui donne accès aux tâches les plus fréquentes.

Image non disponible

L'alignement automatique des contrôles

Si on modifie la taille ou l'emplacement d'un contrôle, VB signale par un trait bleu que le contrôle modifié et le contrôle voisin sont alignés :

Image non disponible

Renommer un nom : modification automatique

On nomme cela 'Refactoring': cliquer sur une variable, puis bouton droit, dans le menu cliquer sur 'Renommer'. Modifier le nom de la variable, valider. Dans toute la Classe la variable est renommée.

Voir tous les composants d'un projet

Pour cela il faut utiliser la fenêtre Explorateur de solutions en haut à droite, elle permet de voir et d'avoir accès au contenu du projet (pour voir tous les fichiers, il faut cliquer sur le deuxième bouton en haut) : gridview est le nom du programme.

Image non disponible

MyProjet : double-cliquer dessus, vous ouvrirez la fenêtre 'propriétés du projet'.

Références qui contient les dll chargées. Pour atteindre les références, on peut aussi passer par le menu 'Projet' puis 'Propriétés' ou double-cliquer sur 'MyProjet' puis choisir l'onglet 'Références'.

Form1.vb est un formulaire (une fenêtre). Les formulaires, modules de classe ou standard sont tous des '.vb' Il suffit de double-cliquer dessus pour les ouvrir.

Si on ouvre la sous-liste de Form1.vb (en cliquant sur le '+'), on voit :

Form1.Designer.vb (qui montre le code qui crée le formulaire, on n'a pas à y toucher) ;

Form1.resx (le fichier de ressources).

Il suffit de cliquer sur la ligne Form1 dans l'explorateur de solution pour voir apparaitre la Form1 dans la fenêtre principale.

Si on clique sur un espace de noms dans la liste Références, cela montre l'arborescence des Classes.

Tester son logiciel

On peut tester le projet grâce à :Image non disponible lancer l'exécution avec le premier bouton (mode 'Run', le second servant à arrêter temporairement l'exécution (mode 'Debug'), le troisième à terminer l'exécution (Retour au mode 'Design' ou 'Conception').

Quand on est en arrêt temporaire en mode 'Debug', la ligne courante, celle qui va être effectuée, est en jaune :

Image non disponible

Si on tape la touche F10 (exécution pas à pas), la ligne 'Label1.Text=i.ToString' est traitée et la position courante passe à la ligne en dessous.

En mode Debug, on peut modifier une ligne et poursuivre le programme qui tiendra compte de la modification (sauf pour les déclarations). On parle d''Edit and continue'.

La sauvegarde du projet se fait comme dans tous les logiciels en cliquant sur l'icône du paquet de disquettes.

On peut compiler le programme pour créer un exécutable par le menu Générer ('Build'). Le code présent dans l'IDE est le code source, après compilation le fichier exécutable contient du code exécutable.

Projet

Dans la terminologie VB, un projet est une application en cours de développement.

Une 'solution' (Team Project) regroupe un ou plusieurs projets (c'est un groupe de projets). Il n'y en a pas dans la version express.

En VB express on parle donc uniquement de projet, en fait ,VB crée aussi une solution de même nom.

Fichiers, Chemins des sources

Si vous regardez dans ' C:\Documents and Settings\Nom Utilisateur\Mes documents\Visual Studio 2008\ Projects\MonProjet')les fichiers correspondant à un projet VB :
sous Windows 7) le programme est accessible dans 'Document/Visual Studio/Projects/Database/Database (Database étant le nom du programme). (En effet sous Windows 7 'Documents ans Settings' n'est pas accessible !! il faut passer par le répertoire 'Document' de l'utilisateur en cours.

MonProjet.sln est le fichier solution.(Pas de solution en VB express, que des projets.)

MonProjet.psess est le fichier de performance (pas toujours présent).

MonProjet.suo est le fichier de User solution.

Dessous existe un répertoire nommé aussi MonProjet qui contient:

MonProjet.vbProj le fichier de projet.

Form1.vb contient un formulaire et ses procédures.

MyClasse.vb contient par exemple des classes.

Form1.Designer.vb contient le code qui crée la fenêtre et les contrôles.

Il a encore les sous-répertoires \Bin, il y a aussi un répertoire \Obj et un répertoire \MyProjet

Si on compile le projet l'exécutable est dans un sous répertoire \Bin,

Propriétés du projet

Toutes les propriétés de l'application peuvent être modifiées dans le 'Projet Designer' (Propriétés du projet), pour l'atteindre, il faut double-cliquer sur 'My Project' dans l'explorateur de solutions :

Image non disponible

Une autre manière d'ouvrir le 'Projet Designer' est de passer par les menus 'Projet' puis 'Propriétés de…'

On retrouve dans le projet designer :

Image non disponible

Le nom de l'application, son icône, la fenêtre de démarrage, celle de fin. (Application)

Les Option Strict, Explicit compare et la nouvelle Option Infer. (Compiler).

Les références (dll liées au projet).

Les paramètres (valeurs liées à l'application).

Les ressources (texte, image, son) utilisées dans le programme.

La signature et la sécurité.

Les Extension My (nouveauté 2008).

Les paramètres relatifs à la publication (distribution et installation).

IV-A-2. Interface WPF

Plutôt que de travailler avec les Windows Forms (formulaire habituel utilisant GDI+), en VB 2008 on peut utiliser un mode graphique vectoriel extrêmement performant pour dessiner les formulaires et contrôles : pour cela on utilise les WFP (Windows Presentation Foundation).

Pour cela : menu 'Fichier', 'Nouveau', 'Projet'.

Image non disponible

On choisit 'Application WPF', on se retrouve dans un nouvel environnement :

Image non disponible

Les formulaires et contrôles sont différents de ceux des Windows Forms, ainsi que les propriétés des objets graphiques.

Il y a le 'designer' en haut qui permet de dessiner l'interface que verra l'utilisateur. Le designer génère un fichier XAML en bas qui décrit en XML l'interface.

Dans la version Express, on peut dessiner des interfaces simples, les interfaces extrêmement élaborées (dégradé de couleur, animation…) peuvent être écrites en code XAML ou en utilisant un programme extérieur payant (Expression Blend). Voir le chapitre sir les WPF.

Si on double-clique sur un bouton, par exemple, on se retrouve dans la procédure événement correspondante :

Image non disponible

On se rend compte que les événements là aussi ne sont pas les mêmes que pour les WindowsForm.

Il y a aussi d'autres modifications comme dans les propriétés du projet :

Image non disponible

Voir le chapitre sur les WPF.

IV-A-3. Vb propose des aides

Quand on tape du code, VB affiche, des aides.

Dès que je tape une lettre VB propose dans une liste des mots.

Exemple, je tape 'd', il affiche 'Dim', 'Dir'… de plus si je me mets sur un des mots, il ouvre une petite fenêtre d'explication sur le mot avec sa syntaxe.

Image non disponible

VB permet de choisir dans une liste une des propriétés d'un objet.

Exemple : je tape le nom d'un label nommé label1 puis je tape un point, cela me donne la liste des propriétés du label.

Image non disponible

Quand je pointe dans la liste un des membres (propriété ou méthode) un carré jaune affiche la définition de la fonction avec ses paramètres et une explication.

VB aide à retrouver les paramètres d'une fonction.

Si on tape le nom d'une fonction et '(', VB affiche les paramètres possibles dans un cadre.

Image non disponible

En plus il affiche les différentes manières d'utiliser les paramètres (les différentes signatures), on peut les faire défiler avec les petites flèches du cadre jaune.

VB aide à compléter des mots.

Si je tape App puis sur le bouton 'A->', Vb affiche la liste des mots commençant par App

AppActivate

AppDomain

VB fournit des exemples de code.

Les Extraits (Snippets, bride, morceau de code) permettent d'insérer du code tout fait.

Dans le code d'une procédure, le clic droit de la souris ouvre un menu.

Image non disponible

Cliquer sur 'Insérer un extrait' (Insert Snipper). Puis par menu successif vous obtiendrez le code que vous cherchez.

Vb propose des solutions pour corriger les erreurs de code.

Si je veux afficher une valeur numérique (avec option Strict=On), il y a erreur, VB me propose la correction :

Image non disponible

Il existe une abondante documentation.

Sur le Net: Msdn Framework 3.5

(http://msdn.microsoft.com/fr-fr/library/aa139616.aspx)

Dans l'IDE, VB donne accès à l'aide sur un mot-clé. Si le curseur passe sur un mot-clé, un carré affiche la définition de la fonction. Si je clique sur un mot et que je tape F1 l'aide s'ouvre et un long texte donne toutes les explications. VB donne accès à l'aide sur les contrôles. Si le curseur est sur un contrôle et que je tape F1 l'aide s'ouvre pour donner accès à la description des différents membres de cet objet. Enfin il est toujours possible de rechercher des informations par le menu '?'

Image non disponible

Erreur dans l'écriture du code.

S'il existe une erreur dans le code au cours de la conception, celle-ci est soulignée en bleu ondulé. Un carré donne la cause de l'erreur si le curseur passe sur la zone où se trouve l'erreur.

Image non disponible

Ici la propriété 'Text' a été mal orthographiée.

Si je lance le programme en mode 'Run' et qu'il y a des erreurs, Vb me le signale et répertorie les erreurs dans la liste des tâches en bas. Vb propose des solutions pour corriger les erreurs de code. (Voir plus haut.)

Mode débogage (mode BREAK)

Une fois lancée l'exécution (F5), puis stoppée (par Ctrl +Alt +Pause ou sur un point d'arrêt), on peut

- voir la valeur d'une propriété d'un objet en le pointant avec la souris :

Image non disponible

Il s'affiche un petit cadre donnant la valeur de la propriété d'un objet ;

- voir la valeur d'une variable, simplement en positionnant le curseur sur cette variable.

F8 permet l'exécution pas à pas (y compris des procédures appelées).

F10 permet le pas à pas (sans détailler les procédures appelées).

Maj+F11 exécute jusqu'à la fin de la procédure en cours.

En cliquant sur le bouton droit de la souris, on peut exécuter jusqu'au curseur (Run To Cursor), voir la définition, la déclaration de ce qui est sous le curseur (Atteindree la définition : Go To Definition)…

Image non disponible

Il y a un chapitre sur le débogage pour apprendre à trouver les erreurs de code.

On peut grâce au menu 'Affichage' avoir accès à plein de choses :

Image non disponible

IV-B. Visual Basic 2010 Express

Image non disponible

C'est l'Integrated Development Environment (IDE) : Environnement de développement intégré de Visual Basic Express 2010 de Microsoft. Il permet de dessiner l'interface (les fenêtres, les boutons, List, Image…) et d'écrire le code VB. Chez nous, on peut aussi dire EDI (Environnement de Développement Intégré).

L'IDE de Visual Basic 2010 est similaire à celle de VB 2005 et VB 2008.VB 2010 Express et est GRATUIT. Donc pas d'hésitation, chargez et utilisez VB Express 2010.


Où trouver Visual Basic 2010 Express ?
Cliquer sur le lien :
http://www.microsoft.com/express/downloads/ Dans la liste de liens, cliquer sur 'Visual Basic Express 2010'
Puis dans la liste 'Select language', choisissez "French", une fenêtre pop-up démarre.

Est-il possible d'utiliser les éditions Express à des fins commerciales ?
Oui. Il n'y a aucune restriction liée aux licences pour les applications créées à l'aide des éditions Express.
Cette réponse (pour VB express 2008) est indiquée sur le site de Microsoft : http://msdn.microsoft.com/fr-fr/express/default.aspx

Vb 2010 utilise le Framework 4 : Voir la documentation Msdn du Framework 4

Mais on peut choisir d'utiliser le Framework 2, 3, 3.5, 4 : menu 'Projet', 'Propriété de…', onglet 'Compiler', en bas liste:'Framework cible'.

Page de démarrage

Quand on lance VB.net 2010, on affiche la Page de démarrage.

Image non disponible

On a le choix entre :
- Nouveau projet… ;
- Ouvrir un projet… ;
- Projets récents.
Quand le pointeur est sur un élément de la liste Projets récents, ce dernier est mis en surbrillance et une icône de punaise s'affiche. Cliquer sur la punaise "épingle" le projet à la liste, afin qu'il reste dans sa position actuelle ultérieurement.
Si vous ouvrez plein de projets, votre projet punaisé restera visible dans la liste.

En bas de la page de démarrage, il y a 2 options pour cette page :
"Fermer la page après le chargement du projet" ;
"Afficher la page au démarrage".

Créer un nouveau projet

Pour créer un nouveau projet Visual Basic, il faut choisir 'Nouveau projet' dans le menu démarrage ou passer par le menu 'Fichier' puis 'Nouveau Projet'. La fenêtre suivante s'ouvre :

Image non disponible

Il faut choisir 'Application Windows Forms' ou 'Application WPF'.
On peut aussi choisir 'Modèle en ligne' à gauche pour avoir une liste (courte) de modèle de programme.

On a donc le choix (à partir de VB 2008) de créer l'interface utilisateur : en Windowsforms (basé sur GDI+), interface habituelle, bien connue ou en WPF interface vectorielle élaborée n'existant pas avant VB 2008.

IV-B-1. Interface 'Windows Forms'

Choisir l'icône 'Application Windows forms', puis donner un nom au projet, enfin valider sur 'OK'.

(Le chemin de l'emplacement du projet n'est pas modifiable ici, il est par défaut ' C:\Documents and Settings\Nom Utilisateur\Mes documents\Visual Studio 2010\ Projects\MonProjet')
C:/Utilisateurs/Philippe/Mes document/ Visual Studio 2010/Projet sous Windows 7
Avec l'explorateur : Documents=> Visual Studio 2010=>Projet.

On remarque qu'on aurait pu choisir 'Application WPF', on y reviendra.

IV-B-1-a. Fenêtre Projet

Image non disponible

On constate que les diverses fenêtres (pour chaque Form du projet ou chaque module de code) sont accessibles par des onglets.
À droite en haut il y a la fenêtre 'Explorateur de solution' ou se trouve les divers éléments du projet.
À droite en bas il y a la fenêtre 'Propriétés' contenant les propriétés de l'objet pointé à droite.
(Si on est sur un bouton à droite, ce sont les propriétés du bouton qui sont à gauche).

Image non disponible

Vous pouvez ancrer les fenêtres correspondant aux onglets aux extrémités de la fenêtre de l'IDE ou les déplacer n'importe où sur le Bureau (sur un second moniteur aussi).
Ci-dessus la fenêtre de Form2 est détachée de l'IDE (il suffit de cliquer déplacer l'onglet).

Quand on déplace une fenêtre de l'IDE, une 'croix' s'affiche, il suffit de déplacer le curseur dans un élément de la croix qui symbolise une position dans l'IDE (en haut en bas, à droite…) et de lâcher le bouton de la souris pour que la fenêtre se positionne en haut, en bas, à droite… dans l'IDE.

Image non disponible

IV-B-1-b. Créer ou ajouter une fenêtre 'WinForm'

Dans un nouveau projet, créer ou ajouter une fenêtre 'WinForm'.

Pour ajouter une fenêtre (un formulaire) Menu 'Project', 'Ajouter un formulaire Windows' ( 'Add a WindowsForms' en version anglaise) :

Image non disponible

Cela permet d'ajouter un formulaire, mais aussi un module standard, un module de Classe.

Cliquer sur Windows Form, une fenêtre (un formulaire) Form2 vide apparait (Form1 était le nom du premier formulaire).

Il y a des fenêtres toutes faites pour accélérer le travail (les templates) comme les 'Ecran de démarrage' les 'Formulaire Explorateur'…

IV-B-1-c. Le concepteur (Designer)

C'est la zone permettant de dessiner l'interface utilisateur : les fenêtres, controles…

La zone de travail se trouve au centre de l'écran : c'est l'onglet Form1.vb[Design] ci-dessous qui donne donc accès au dessin de la feuille (du formulaire); on peut ajouter des contrôles, modifier la taille de ces contrôles…

Image non disponible

IV-B-1-d. Les procédures

Elles contiennent le code en visual basic. On se souvient que pour chaque événement de chaque objet visuel il existe une procédure.

Dans l'explorateur de solution à droite, cliquer sur Form1.vb puis sur l'icône 'Afficher le code' (survoler les petites icônes, c'est la 4e), cela donne accès aux procédures liées à Form1.

Il est aussi possible en double-cliquant dans le formulaire ou un contrôle de se retrouver directement dans le code de la procédure correspondant à cet objet.

Image non disponible

Dans toute fenêtre de code ou de texte, vous pouvez effectuer rapidement un zoom avant ou arrière (agrandir ou réduire la taille des caractères) en appuyant sur la touche CTRL tout en déplaçant la roulette de défilement de la souris.

On peut 'taper' du code dans les procédures. Dès que vous tapez quelques caractères Vb ouvre des listes vous proposant la suite (voir aide).

La liste déroulante de gauche au-dessus de la procédure donne la liste des objets, celle de droite, les événements correspondants à cet objet.

Ici on voit la procédure Button1_Click liée au Button1 de la fenêtre de Design :

Image non disponible

Il est possible de faire de la saisie ou de l'insertion multiple.
Pour cela il faut appuyer sur ALT puis sélectionner à la souris une colonne sur plusieurs lignes:
Image non disponible Si ensuite on tape du code , il apparait sur toutes les lignes :
Image non disponible Insertion de texte : sélectionnez plusieurs lignes puis tapez dans la sélection de zone pour insérer le nouveau texte dans chaque ligne sélectionnée.
Collage : collez le contenu d'une sélection de zone dans une autre.
Zones de longueur nulle : effectuez une sélection verticale de zéro caractère de largeur pour créer un point d'insertion multiligne où insérer du texte sur toutes les lignes en même temps.

Quand on clique sur une variable, cette variable est surlignée dans l'ensemble du code :
CTL+MAJ+Flèche haut ou Flèche bas permet de passer à la variable surlignée suivante ou précédente.

Image non disponible

Renommer un nom : modification automatique

On nomme cela 'Refactoring': cliquer sur une variable, puis bouton droit, dans le menu cliquer sur 'Renommer'. Modifier le nom de la variable, valider. Dans toute la Classe la variable est renommée.

Si une ligne de code est trop longue, on peut ajouter un caractère de continuation de ligne "_" et passer à la ligne. En VB 2010, après certains mots il peut y avoir continuation de ligne implicite (plus besoin de _ après la virgule, après &, après une parenthèse ouvrante, après { ou = ou + ou Is…).

 
Sélectionnez
Public Function GetUsername(ByVal username As String,
                            ByVal delimiter As Char,
                            ByVal position As Integer) As String

    Return username.Split(delimiter)(position)
End Function

En vb 2010, si dans le code, on utilise une classe qui n'existe pas, vb souligne le nom de la classe et vous propose (en cliquant sur le bouton dessous) de créer une classe, une structure ou un Enum vide :

Image non disponible

. Cliquez sur 'générer un nouveau type".

Image non disponible

Il existe une 'Recherche rapide' très puissante accessible par le menu 'Édition'.

Image non disponible

Il y a bien sur les habituels boutons 'Couper', 'Copier', 'Coller', mais aussi le bouton qui transforme les lignes sélectionnées en commentaire (ou l'inverse).

Image non disponible

Le menu 'Édition' puis 'IntelliSense' donne accès aux aides à l'écriture

Image non disponible

IV-B-1-e. Ajouter des contrôles au formulaire

Ajouter un bouton par exemple.

Passer sur Boite à outils (Toolbox) à gauche, les contrôles apparaissent tous ou classés par ordre alphabétique.

Image non disponible

Cliquer sur 'Button' dans la boite à outils, cliquer dans la Form, déplacer le curseur sans lâcher le bouton, puis lâcher : un bouton apparait.

Modifier les propriétés d'un contrôle ou du formulaire

Quand un formulaire ou un contrôle est sélectionné dans la fenêtre Design, ses propriétés sont accessibles dans la fenêtre de 'Propriétés' (Properties) à droite en bas: ici ce sont les propriétés du contrôle 'Button1' qui sont visibles (Text, Location…) on peut modifier directement les valeurs.

Image non disponible
Image non disponible

En bas de la fenêtre propriétés, il y a une explication succincte de la propriété sélectionnée (si elle n'apparait pas, clic droit sur la propriété puis dans le menu 'Description').

Exemple

Si au niveau de la ligne 'Text' des propriétés du bouton, j'efface 'Button1' et que je tape 'OK', dans le designer, le texte écrit sur le bouton deviendra 'OK'.

En haut de cette fenêtre de propriété, il y a un bouton avec un éclair donnant accès aux événements de l'objet.

Le déplacement des contrôles

Plus de croix ni de petite flèche pour déplacer le contrôle ou ouvrir un menu. Pour déplacer le contrôle, appuyer bouton gauche dedans puis déplacer.

L'alignement automatique des contrôles

Si on modifie la taille ou l'emplacement d'un contrôle, VB signale par un trait bleu que le contrôle modifié et le contrôle voisin sont alignés :

Image non disponible

Disposition des contrôles

Le menu 'Outils', 'Personnaliser' permet d'ajouter une barre de disposition :

Image non disponible

Cela permet (comme avec le menu Format) d'aligner les contrôles sur la grille, d'aligner les côtés, la taille, les espacements, d'uniformiser les tailles, de centrer dans la fenêtre…

IV-B-1-f. Voir tous les composants d'un projet

Pour cela il faut utiliser la fenêtre Explorateur de solutions en haut à droite, elle permet de voir et d'avoir accès au contenu du projet (pour voir tous les fichiers, il faut cliquer sur le deuxième bouton en haut) :

Image non disponible

MyProjet : double-cliquer dessus, vous ouvrirez la fenêtre 'propriétés du projet'.

Références qui contient les dll chargées. Pour atteindre les références, on peut aussi passer par le menu 'Projet' puis 'Propriétés' ou double-cliquer sur 'MyProjet' puis choisir l'onglet 'Références.

Form1.vb est un formulaire (une fenêtre). Les formulaires, modules de classe ou standard sont tous des '.vb' il suffit de double-cliquer dessus pour les ouvrir.

Si on ouvre la sous-liste de Form1.vb (en cliquant sur le petit triangle), on voit :

Form1.Designer.vb (qui montre le code qui crée le formulaire, on n'a pas à y toucher) ;

Form1.resx (le fichier de ressources).

Il suffit de cliquer sur la ligne Form1 dans l'explorateur de solution pour voir apparaitre la Form1 dans la fenêtre principale.

Si on clique sur un espace de noms dans la liste Références, cela montre l'arborescence des Classes.

IV-B-1-g. Tester son logiciel

La Liste d' erreurs, en bas indique les erreurs de syntaxe (erreurs et avertissements).

Image non disponible

On peut tester le projet grâce à :Image non disponible lancer l'exécution avec le premier bouton (mode 'Run'), le second servant à arrêter totalement l'exécution: Retour au mode 'Design' (ou 'Conception').

Pour arrêter le programme temporairement en mode 'Debug' il faut un point d'arrêt ou faire Ctrl+Pause (ce qui ouvre une autre fenêtre !!).
En cliquant sur Image non disponible (visible lors de l'exécution) on peut aussi suspendre l'exécution.
Par contre on peut mettre un point d'arrêt quand le programme tourne en cliquant dans la marge grise avant le code.

Quand on est en arrêt temporaire en mode 'Debug', la ligne courante, celle qui va être effectuée, est en jaune :

Image non disponible

Si on tape la touche F8 (exécution pas à pas), la ligne est traitée et la position courante passe à la ligne en dessous.
F5 relance l'exécution.

En mode Debug, on peut modifier une ligne et poursuivre le programme qui tiendra compte de la modification (sauf pour les déclarations). On parle d''Edit and continue'.

IV-B-1-h. Sauvegarde, Projet, chemin

La sauvegarde du projet se fait comme dans tous les logiciels en cliquant sur l'icône du paquet de disquettes.

On peut compiler (on dit 'générer') le programme pour créer un exécutable par le menu 'Générer' ('Build'). Le code présent dans l'IDE est le code source, après compilation le fichier exécutable contient du code exécutable.

Projet

Dans la terminologie VB, un projet est une application en cours de développement.

Une 'solution' (Team Project) regroupe un ou plusieurs projets (c’est un groupe de projets). Il n'y en a pas dans la version express.

En VB express on parle donc uniquement de projet, en fait ,VB crée aussi une solution de même nom.

Fichiers, Chemins des sources

Sous Windows XP regardez dans ' C:\Documents and Settings\Nom Utilisateur\Mes documents\Visual Studio 2010\ Projects\MonProjet'
Sous Windows 7 le programme est accessible dans 'Document/Visual Studio 2010/Projects/MonProgramme'.

MonProjet.sln est le fichier solution. (Pas de solution en VB express, que des projets.)

MonProjet.psess est le fichier de performance (pas toujours présent).

MonProjet.suo est le fichier de User Option.

Dessous existe un répertoire nommé aussi MonProjet qui contient :

MonProjet.vbProj le fichier de projet ;

Form1.vb contient un formulaire et ses procédures ;

MyClasse.vb contient par exemple des classes ;

Form1.Designer.vb contient le code qui créer la fenêtre et les contrôles.

Il a encore les sous répertoires \Bin, il y a aussi un répertoire \Obj et un répertoire \MyProjet.

Si on compile (génère) le projet l'exécutable est dans un sous répertoire \Bin, Vb 2010 choisit automatiquement la configuration Debug (compilée avec des informations de débogage symboliques et aucune optimisation) lorsque vous cliquez sur Démarrer dans le menu Déboguer et la configuration Release (ne contient pas d'informations de débogage relatives aux symboles et est entièrement optimisée) lorsque vous utilisez le menu Générer.
Les exécutables générés (fichier .exe) sont respectivement dans /bin/Debug et /bin/Release.

IV-B-1-i. Propriétés du projet

Toutes les propriétés de l'application peuvent être modifiées dans le 'Projet Designer' (Propriétés du projet), pour l'atteindre, il faut double-cliquer sur 'My Project' dans l'explorateur de solution.

Une autre manière d'ouvrir le 'Projet Designer' est de passer par les menus 'Projet' puis 'Propriétés de…'

On retrouve dans le projet designer :

Image non disponible

Le nom de l'application, son icône, la fenêtre de démarrage, celle de fin. (Application)

Les Option Strict, Explicit compare et Option Infer.(Onglet Compiler).

Les références (dll liées au projet).

Les paramètres (valeurs liées à l'application).

Les ressources (texte, image, son) utilisées dans le programme.

La signature et la sécurité.

Les Extension My (nouveauté 2008).

Les paramètres relatifs à la publication (distribution et installation).

IV-B-1-j. Autre

On peut mettre des commentaires précédés de '.

 
Sélectionnez
' Commentaire non exécutable
'TODO ne pas oublier de modifier …

Si le premier mot du commentaire est TODO, comme ci-dessus, ce commentaire sera affiché dans la liste des tâches :
(Menu Affichage, Autres fenêtres, Liste des tâches).

Image non disponible

C'est bien pratique pour ne pas oublier des modifications à faire.

IV-B-2. Interface WPF

Plutôt que de travailler avec les Windows Forms (formulaire habituel utilisant GDI+), en VB 2008 on peut utiliser un mode graphique vectoriel extrêmement performant pour dessiner les formulaires et contrôles : pour cela on utilise les WFP (Windows Presentation Foundation).

Pour cela : menu 'Fichier', 'Nouveau', 'Projet'.

On choisit 'Application WPF', on se retrouve dans un nouvel environnement :

Image non disponible

Les formulaires et contrôles sont différents de ceux des Windows Forms, ainsi que les propriétés des objets graphiques.

Il y a le 'designer' en haut qui permet de dessiner l'interface que verra l'utilisateur. Le designer génère un fichier XAML en bas qui décrit en XML l'interface.

Dans la version Express, on peut dessiner des interfaces simples, les interfaces extrêmement élaborée (dégradé de couleur, animation…) peuvent être écrites en code XAML ou en utilisant un programme extérieur payant (Expression Blend). Voir le chapitre sur les WPF.

Si on double-clique sur un bouton, par exemple, on se retrouve dans la procédure événement correspondante.

On se rend compte que les événements là aussi ne sont pas les mêmes que pour les WindowsForm.

Il y a aussi d'autres modifications comme dans les propriétés du projet : voir le chapitre sur les WPF.

IV-B-3. Vb propose des aides

Quand on tape du code dans une procédure, VB affiche, des aides : dès que je tape une lettre VB propose dans une liste des mots.

Exemple, je tape 'di', il affiche 'Dim', 'Dir'…, de plus si je me mets sur un des mots, il ouvre une petite fenêtre d'explication sur le mot avec sa syntaxe.

Image non disponible

VB permet de choisir dans une liste une des propriétés d'un objet.

Exemple : je tape le nom d'un label nommé label1 puis je tape un point, cela me donne la liste des propriétés du label.
Quand on pointe une propriété, un rectangle donne une explication sur cette propriété.

Image non disponible

VB aide à retrouver les paramètres d'une fonction.

Si on tape le nom d'une fonction et '(', VB affiche les paramètres possibles dans un cadre.

Image non disponible

En plus il affiche les différentes manières d'utiliser les paramètres (les différentes signatures), on peut les faire défiler avec les petites flèches du cadre blanc.

VB aide à compléter des mots.

Si je tape 'App' Vb affiche la liste des mots commençant par App: Objet, variables…

Dans le code, cliquez avec le bouton droit ouvre un menu et donne accès à :

Image non disponible

VB fournit des exemples de code.

Les Extraits (Snippets, bride, morceau de code) permettent d'insérer du code tout fait.

Dans le code d'une procédure, le clic droit de la souris ouvre un menu.

Image non disponible

Cliquer sur 'Insérer un extrait' (Insert Snipper). Puis par menu successif vous obtiendrez le code que vous cherchez.

Il existe une abondante documentation:
http://msdn.microsoft.com/fr-fr/library/dd831853%28v=VS.100%29.aspx

Dans l'IDE, VB donne accès à l'aide sur un mot-clé. Si je clique sur un mot et que je tape F1 l'aide s'ouvre et un long texte donne toutes les explications.
VB donne accès à l'aide sur les contrôles. Si le curseur est sur un contrôle et que je tape F1 l'aide s'ouvre pour donner accès à la description des différents membres de cet objet.
Enfin il est toujours possible de rechercher des informations par le menu '?'.

Si le curseur passe sur un mot-clé, un carré affiche la définition de la fonction, le type de la variable, sa déclaration.

Image non disponible

Erreur dans l'écriture du code

Vb propose des solutions pour corriger les erreurs de code :

Si je fais une erreur Vb la souligne en ondulé bleu, si je mets le curseur dessus il m'explique l'erreur :

Image non disponible

S'il y a un soulignement rouge, mettre le curseur dessus affiche un bouton avec un point d'exclamation qui ouvre une fenêtre donnant la correction de l'erreur :

Image non disponible

Si je lance le programme en mode 'Run' et qu'il y a des erreurs, Vb me le signale et répertorie les erreurs dans la liste des tâches en bas.

Image non disponible

Mode débogage (mode BREAK)

Une fois lancée l'exécution (F5), puis stoppée (par Ctrl +Pause ou sur un point d'arrêt), ou en cliquant sur Image non disponible on peut :

voir la valeur d'une propriété d'un objet, d'une variable en le pointant avec la souris :

Image non disponible

Il s'affiche un petit cadre donnant la valeur de la propriété d'un objet.
Si on clique sur la punaise, l'affichage de la variable et de sa valeur devient permanent et la valeur est mise à jour.

Quand on clique sur une variable, cette variable est surlignée dans l'ensemble du code :

Image non disponible

F8 permet l'exécution pas à pas (y compris des procédures appelées).

MAJ F8 permet le pas à pas (sans détailler les procédures appelées).

CTRL+F8 exécute jusqu'au curseur.

Il y a un chapitre sur le débogage pour apprendre à trouver les erreurs de code.

IV-C. IDE SharpDevelop (logiciel libre en open spource)

C'est l'IDE (Integrated Development Environment) : Environnement de développement intégré GRATUIT, en open source, alternative à VisualStudio.

Image non disponible

Depuis sa version 2 #develop est un très bon produit.
Il manque certaines choses.
Pas de "Edit and continue" : si on suspend l'exécution et qu'on modifie le code, la modification n'est pas prise en compte si on continue l'exécution, débogueur moins performant). On en est à la version 3.2 (version 4 en bêta).

Sharpevelopp (#Develop) sera toujours gratuit.

C'est un logiciel libre en open source (GPL).

IV-C-1. Où le trouver ? Comment l'installer ?

SharpDevelop 3.2 (version stable)

Si ce n'est pas fait, télécharger et installer le FrameWork 3.5. (Impérativement en premier).

Télécharger et installer le SDK.

C'est le Kit de Développement Microsoft .NET Framework : SDK du Framework 3.5.

Télécharger et installez SharpDevelop 3.2 (le 14/4/2010).

Télécharger SharpDevelop 3.2 (gratuit)

L'installer en exécutant le fichier d'installation.

Le Framework, le SDK et #develop suffisent pour faire des programmes.
La version 3.2 permet de travailler en VB avec les winforms.

SharpDevelop 4 (version beta)

Si ce n'est pas fait, télécharger et installer le FrameWork 4. (Impérativement en premier.)

Télécharger et installer le SDK.

C'est le Kit de Développement Microsoft .NET Framework : SDK du Framework 4.

Télécharger et installez SharpDevelop 4 bêta (le 14/12/2010).

Télécharger SharpDevelop 4 (gratuit)

L'installer en exécutant le fichier d'installation.

Le Framework, le SDK et #develop suffisent pour faire des programmes.

La version 4 bêta permet aussi de travailler avec WPF. Au 27/12/2010 elle n'est pas finalisée : impossible de créer facilement une Sub événement.

Lien

Site SharpDevelop

IV-C-2. Fenêtre Projet Windows Forms

Didacticiel en anglais pour les Windows Forms : http://community.sharpdevelop.net/blogs/mattward/articles/FeatureTour.aspx.

Lancer SharpDevelop

Au lancement de l'application, on peut :

  • ouvrir une solution existante: Bouton 'Ouvrir une solution' (ou cliquer sur le nom d'un projet récent en haut) ;
  • créer un nouveau projet (une nouvelle solution).

Si l'on veut rajouter des fichiers à notre projet faire :
'Fichier'-'Ouvrir'-'Fichier' et catégorie VB

Détaillons la création d'un nouveau projet.

Bouton 'Nouvelle solution' ou

Menu 'fichier'-'Nouveau'-'Solution'

Image non disponible

Sélectionner la catégorie 'VBNET' et choisir le type d'application à créer. (Dans le cas d'une création d'un projet Visual Basic, il faudra choisir dans les 'Modèles' : Application Windows.) On remarque que #Develop permet aussi d'écrire du C#, du C++ du ILAsm un setup du Python, Ruby….
On peut utiliser les Windows Forms (version 3.2) ou WPF (version 4).

Puis il faut donner un nom au projet (il n'y a pas de nom par défaut), modifier si nécessaire le chemin de l'emplacement du projet qui est par défaut ' C:\Documents and Settings\NomUtilisateur\Mes documents\SharpDevelop Projects' (cocher si nécessaire 'Créer le répertoire source') enfin valider sur le bouton 'Créer'. Une fenêtre 'MainForm' apparait.

Si, comme dans notre exemple, on a tapé 'Prog2', #develop crée une 'solution' nommée 'SolutionProg2' (ensemble, groupe de projets) contenant un projet (Prog2) contenant un formulaire nommé 'MainForm'.

L'écran principal se présente ainsi :

Image non disponible

Au centre, sont visibles les écrans du code et des formulaires ; on peut changer d'écran grâce aux onglets du haut. Ici on voit 'MainForm'.

À gauche, les onglets du bas donnent accès au projet en cours (les solutions, projets, formulaires, autres fichiers : ressources, assembly…) ou aux outils : Table ascii, Presse papier et surtout (si on a un formulaire au centre et non du code) aux objets (bouton, texteBox, ListBox…).

À droite, en bas, les classes et surtout la fenêtre de Propriétés (Name, Text…) de l'objet sélectionné au centre.

En bas les fenêtres de 'sortie' (affichage de la console) liste des 'erreurs' des 'tâches', définitions', 'Résultat des recherches'…

IV-C-2-a. Dans un nouveau projet, créer une fenêtre

Pour ajouter une fenêtre (un formulaire) ouvrir le gestionnaire de projet et solution (Onglets en bas à gauche), il donne le nom de la solution (solutionprog2) et du projet (prog2 ici). Cliquer avec le bouton droit sur prog2 puis dans les menus sur 'Ajouter', 'Nouveau fichier'. Cela ouvre la fenêtre 'Nouveau fichier'.

Image non disponible

Dans la fenêtre qui s'ouvre, à gauche, choisir 'VB' puis 'Application Windows', à droite 'Formulaire', taper un nom de formulaire (Form1 par exemple) puis 'Créer', une fenêtre 'Form1' apparait. La première fenêtre qui s'ouvre automatiquement quand on crée un projet se nomme 'MainForm'.

La zone de travail se trouve au centre de l'écran : on voit les onglets MainForm, Form1.vb pour chaque formulaire (fenêtre)

Image non disponible

En bas les onglets 'Source' et 'Design' permettent de passer de l'affichage du code('Source') à la conception de l'interface utilisateur ('Design') : affichage de la fenêtre et de ses contrôles permettant de dessiner l'interface.

IV-C-2-b. Ajouter des contrôles au formulaire

Ajoutons un bouton par exemple :

Image non disponible

Cliquer sur l'onglet 'Outils' à gauche en bas , bouton 'Windows Forms', puis sur 'Button', cliquer dans la MainForm, déplacer le curseur sans lâcher le bouton, puis lâcher le bouton :

Image non disponible

IV-C-2-c. Modifier les propriétés d'un contrôle ou du formulaire

Quand une feuille ou un contrôle est sélectionné dans la fenêtre Design, ses propriétés sont accessibles dans la fenêtre de propriétés à droite en bas. (Si elles ne sont pas visibles, cliquer sur l'onglet 'Propriétés' en bas.)

Ici ce sont les propriétés du contrôle 'Button1' (BackColor, Image, Texte…).

Un petit texte d'aide concernant la propriété en cours apparait en bas.

(On peut modifier les propriétés directement.)

Image non disponible

IV-C-2-d. Voir les procédures

L'onglet 'Source' en bas donne accès aux procédures (au code) liées à Form1.

Image non disponible

La combo déroulante de droite donne la liste des objets. Si on en choisit un, le pointeur va sur les procédures liées à cet objet.

Malheureusement, contrairement à Visual Studio, la combo de gauche ne contient que les formulaires et pas les objets. Par exemple, on aura MainForm, mais pas Label1… Du coup la recherche se fait directement dans la combo de droite et c'est forcément beaucoup moins clair dès qu'il y a beaucoup de contrôles sur un formulaire…

Il est possible en double-cliquant dans le formulaire ou sur un contrôle de se retrouver directement dans le code de la procédure correspondant à cet objet.

Si la procédure n'existe pas (ButtonClick par exemple),double-cliquez sur le bouton pour la créer.

Pour créer les autres procédures événements, utiliser le bouton Image non disponible qui est sur la fenêtre des propriétés à droite, il fait apparaitre la liste des événements, double-cliquant sur un événement cela permet d'ouvrir la fenêtre de code et de créer les procédures.

IV-C-2-e. Voir tous les composants d'un projet, les classes

Pour cela il faut utiliser La fenêtre Projet à gauche (Si elles ne sont pas visibles, cliquer sur l'onglet 'Propriétés' en bas), elles permettent de voir et d'avoir accès au contenu du projet.

Le gestionnaire de projet et solution donne le nom de la solution (solutionprog2) et du projet (prog2 ici). Cliquer sur les '+' pour développer : vous verrez apparaitre les formulaires, les modules… et :

Références qui contient les espaces de nom ;

Assembly : info nécessaire pour générer le projet…

Le menu 'Fichier', 'Afficher les diagrammes de Classe' permet de voir les Classes du projet sous forme de diagramme :

Image non disponible

IV-C-2-f. Remarque relative aux fenêtres de l'IDE

Pour faire apparaitre une fenêtre qui a disparu (fenêtre projet par exemple) utiliser le menu 'Affichage' puis 'projet'.

Quand la fenêtre est ancrée (accrochée aux bords), le fait de la déplacer avec sa barre de titre la 'dé ancre', et elle devient autonome.

Pour la 'réancrer', il faut double-cliquer dans sa barre de titre.

IV-C-3. Interface WPF

Interface WPF est présente à partir de la version 4.

Faire 'Fichier', 'Nouveau projet' :

Image non disponible

Choisir 'VB', 'WPF' à gauche puis 'Application WPF' à droite, donner un nom en bas.

On se trouve dans l'environnement wpf :

Image non disponible

L'onglet 'Window1.xaml' permet de voir le 'Designer'.
Le menu 'Affichage', 'Outils' permet d'avoir la liste des contrôles à gauche: On peut prendre un contrôle, un bouton par exemple, et le déposer dans la fenêtre centrale.
Si on clique sur un contrôle, on voit à droite ses propriétés.

En bas du designer l'onglet 'Source' permet d'avoir accès au code Xaml décrivant l'interface. Ici on voit le code xaml correspondant au bouton :

Image non disponible

En bas à gauche, on peut cliquer sur l'onglet 'Projet'.
S'affiche les composants du projet, donnant accès à 'Windows.xaml.vb' contenant le code 'behind' visual basic.

Raccourcis clavier :

Ctrl+Entrée : Aller à la définition;
Ctrl + H: Rechercher;
Ctrl + G: Aller à.
Voir http://wiki.sharpdevelop.net/KeyboardShortcuts.ashx.

IV-C-4. Tester son logiciel

On peut compiler le projet avec le premier bouton ci-dessous. Créer le projet avec le second. Lancer l'exécution avec le bouton flèche verte (débogueur actif), le point d'exclamation lance l'exécution sans débogage, le rond à droite (qui devient rouge pendant l'exécution) sert à terminer l'exécution.

La liste déroutante permet de choisir la configuration des fenêtres de l'IDE :

Défaut : c'est les fenêtres habituelles précédemment décrites ;

Débogage : ouvre les fenêtres: variables locales, points d'arrêt, modules chargés… ;

Texte simple: uniquement les fenêtres centrales ;

Éditer : ouvre la fenêtre Edit Layout.

La sauvegarde du projet se fait comme dans tous les logiciels en cliquant sur l'icône du paquet de disquettes.

IV-C-5. Fichiers, Chemins des sources

Avant, en #develop 1 :

.prjx est le fichier de projet.

.cmbw est le fichier solution.

Avec Sharpdevelop 2 c'est comme en VB : les solutions sont maintenant des fichiers .sln

.vb sont tous les fichiers Visual Basic (Feuille module…)

Les sources sont par défaut dans ' C:\Documents and Settings\NomUtilisateur\Mes documents\SharpDevelop Projects'

Si on compile le projet l'exécutable est dans un sous-répertoire \Bin\Debug ou \Bin\Realese.

Si vous avez plusieurs versions du framework sur votre machine (version 1.0, version 1.1, voire version 2.0 bêta), il vous est possible de choisir le compilateur dans les options du projet.

Visual Studio 2003 à version 1.1 du framework.

Visual Studio 2005 à version 2.0 du framework.

IV-C-6. Propriétés du projet

Menu 'Projet', 'Option du projet' permet l'accès aux propriétés du projet en cours.

Le quatrième onglet (Compiler) est le plus intéressant :

Image non disponible

On peut :

compiler le programme en mode 'Debug' ou 'Release' ;

forcer le programmeur à travailler en Option Strict= On (empêcher les conversions automatiques) ;

Option Explicit=On (Forcer la déclaration des variables) ;

Choisir le Framework avec lequel on travaille (1 ou 2, pas le trois encore) ;

Dans l'onglet Import, on peut importer des espaces de noms.

IV-C-7. #Develop propose des aides

La fenêtre d'aide à droite donne accès à des aides :

de #develop en anglais, non à jour !! ;

du Framework ;

de zipLib.

Si vous avez installé le SDK (SDK Framework .Net et/ou SDK Direct X), vous avez accès à l'aide (partie en haut à droite de l'écran), et donc également à l'intellisense, qui affiche les propriétés, les méthodes des objets, les paramètres des fonctions, des types… des différents objets.

Image non disponible

Ici par exemple on a tapé MessageBox. , la liste des membres (Equals, Show…) est affichée.

IV-C-8. Erreur de compilation

Si on fait une faute dans le code, elle est détectée lorsque l'on lance l'exécution.

Ici on a tapé 'Texte' à la place de 'Text'.

La ligne en cause est soulignée en rouge et la fenêtre des erreurs située en bas s'ouvre, elle indique et décrit l'erreur :

Image non disponible

L'aide dynamique à droite propose des liens en rapport avec le contexte.

IV-C-9. Erreur d'exécution : Exceptions

S'il y a une erreur d'exécution (division par zéro par exemple), l'exécution s'arrête et la fenêtre d'exception s'ouvre :

Image non disponible

On peut choisir d'arrêter le programme, de continuer, d'ignorer.

IV-C-10. Débogage

Le débogueur est maintenant intégré dans la version 2.

Une fois l'exécution lancée, on peut :

suspendre l'exécution par ALT+CTRL+B , reprendre par F6

Ajouter des points d'arrêt

Grâce à des points d'arrêt (pour définir un point d'arrêt en mode de conception, cliquez en face d'une ligne dans la marge grise, cela fait apparaitre un rond et une ligne rouge. Quand le code est exécuté, il s'arrête sur cette ligne).

Image non disponible

(Recliquer sur le rond pour l'enlever).

Ajouter des marques pages

On peut ajouter des marques pages, en cliquant (quand on est sur la ligne à marquer) sur le petit carré bleu de la barre d'outils :

Image non disponible Ensuite, on peut se déplacer de marque en marque avec les 2 boutons qui suivent.

En mode 'Run', si on clique sur l'onglet 'Points d'arrêt' à droite, on voit la liste des points d'arrêt et des marques, on peut rendre inactif tous les points d'arrêt (3e bouton) ou un seul en le décochant dans la liste.

Image non disponible

Voir la valeur d'une variable, simplement en positionnant le curseur sur cette variable.

Image non disponible

En plus en mode Run, la fenêtre 'Variables locales' située en bas affiche la valeur de toutes les variables de la procédure. (Y compris 'e' et 'sender' qui sont les paramètres de la Sub.)

Enfin à droite on peut voir les modules chargés et les threads.

Exécution pas à pas

F11 permet l'exécution pas à pas (y compris des procédures appelées).

F10 permet le pas à pas (sans détailler les procédures appelées).

Maj+F11 exécute jusqu'à la fin de la procédure en cours.

On peut aussi utiliser les boutons : Image non disponible

Attention, il n'est pas possible de modifier les fichiers sources à partir du moment où vous avez démarré le débogage.

Fonctions présentes dans #develop 1, mais pour l'instant absente dans #develop 2: C++ NProf Wix NAnt, générateur de MessageBox.

Créer un installateur (en anglais).

IV-C-11. Conclusion

Programme permettant de faire du VB.net gratuitement (rapport qualité/prix infiniment élevé).

CONCLUSION D'UN UTILISATEUR

SharpDevelop est un IDE agréable à utiliser, pour le développement des programmes .NET, en mode WYSIWYG.

Il est possible d'atteindre un niveau de qualité équivalent à Visual Studio ou à Borland C# Builder en faisant une installation complète. Très ouvert, on peut lui rajouter des plugins. Certains programmes externes peuvent être utilisés également avec Visual Studio ou Borland C# Builder.

SharpDevelop est en perpétuelle évolution.

Un forum permet de déposer le descriptif des erreurs rencontrées, mais également de vos demandes de modifications, si vous pensez à une évolution qu'il serait bien que SharpDevelop possède. En plus vous pouvez récupérer le code source et pouvez donc modifier à loisir l'IDE.

Bien sûr, pour les débutants, il manque les assistants de Visual Studio (Crystal report, ADO .NET…). Le problème avec les assistants est qu'une fois qu'on pratique un peu, ils deviennent vite une gêne, et souvent, il faut repasser derrière eux, pour enlever le superflu de code qu'ils ont écrit (souvent ils n'optimisent pas le code).

Il manque également la partie UML de Visual Studio Architecte, mais là on attaque le haut du panier des développeurs.

Par contre, SharpDevelop apporte en plus :

  • aide à la génération automatique des MessageBox ;
  • aide à la conversion C# vers VB.NET et de VB.NET vers C# ;
  • aide à la génération d'expression régulière.

Il fournit les logiciels :

  • NDoc : permet de faire des fichiers d'aide compilée au format MSDN, à partir de lignes commentées dans le code ;
  • NUnits : permet de faire des tests unitaires (!) ;
  • SharpQuery : permet de se connecter aux bases de données .

IV-C-12. J'ai besoin d'aide

Comment créer facilement un installateur (SetUp) avec #develop ? Certains utilisateurs utilisent Inno Setup, d'autres Excelcior delivery.

Comment utiliser NDoc NUnits ?

Comment utiliser simplement des ressources ?

Comment utiliser des bases de données ?

Qui utilise le menu 'Outils' et ses différentes options ?

Merci à Fabrice SAGE pour son aide.

Merci à Hubert WENNEKES, CNRS Institut de Biologie de Lille pour son aide.

Remarque pour les forts

On peut s'étonner qu'il n'y ait pas Handles Button1.Click à la fin de la ligne suivante (comme dans VB 2005) :

 
Sélectionnez
Sub Button1Click(ByVal sender As Object, ByVal e As EventArgs)

End Sub

En fait si on va voir dans InitializeComponent, il y a un AddHandler après la description du bouton.

 
Sélectionnez
Private Sub InitializeComponent()

….

AddHandler Me.button1.Click, AddressOf Me.Button1Click

V. Langage Visual Basic

V-A. Introduction

Image non disponible

Nous allons étudier :

Le langage Visual Basic.Net qui est utilisé dans les procédures.

Comme nous l'avons vu, le langage Visual Basic sert à

  • agir sur l'interface (Afficher un texte, ouvrir une fenêtre, remplir une liste, un tableau, poser une question).
    Exemple afficher 'Bonjour" dans un label :

     
    Sélectionnez
    Label1.Text="Bonjour"
  • effectuer des calculs, des affectations en utilisant des variables.
    Exemple: Mettre dans la variable B la valeur de A+1

     
    Sélectionnez
    B=A+1
  • faire des tests avec des structures de décision: évaluer des conditions des comparaisons et prendre des décisions.
    Exemple: SI A=1 …

     
    Sélectionnez
    If A=1 ThenEnd If
  • travailler en boucle pour effectuer une tâche répétitive.
    Exemple faire 100 fois…
 
Sélectionnez
For I=0 To 100. Next I

Comme nous l'avons vu, le langage Visual Basic sert à

Tout le travail du programmeur est là.

Dans VB.Net nous avons à notre disposition deux sortes de choses:  

V-A-1. Les Classes du framework

Le Framework (un framework est un ensemble de classes) en est à sa version 4 en VB 2010.

Les classes du Framework permettront de créer des objets de toutes sortes: objet 'chaine de caractères', objet 'image', objet 'fichier'… On travaille sur ses objets en utilisant leurs propriétés, leurs méthodes.

Il existe des milliers de classes: les plus utilisées sont les classes 'String' (permettant de travailler sur des chaines de caractères), Math (permettant d'utiliser des fonctions mathématiques), Forms (permettant l'usage de formulaires, de fenêtres et donnant accès aux contrôles: boutons, cases à cocher, listes…).

Elles sont communes à tous les langages utilisant le FrameWork (VB, C#, C… ).

Ces classes ont de multiples méthodes (rappel de la syntaxe: Classe.Methode).

Exemple d'utilisation de la Class TextBox (contrôle contenant du texte) et de sa méthode Text :

 
Sélectionnez
TextBox1.Text="Hello"

'Affiche "Hello" dans le Textbox.

Parfois la Classe n'est pas chargée par défaut au démarrage de VB, il faut dans ce cas 'l'importer' en haut du module (au-dessus de Public Class…). Si par exemple, je veux utiliser Sin() de la classe Math, il faut écrire en haut du module :

 
Sélectionnez
Imports System.Math
Public Class Form1

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        'Je peux utiliser Sin
        Console.WriteLine(Sin(1).ToString)

End Sub
End Class

Si on n'a pas importé Math, on peut quand même utiliser Sin en tapant Math.Sin().

V-A-2. Les instructions de Microsoft.VisualBasic

Vb permet d'utiliser des instructions Visual Basic; seul VB peut les utiliser et de lui seul (pas C#).

Il s'agit d'instructions, de mots-clés qui ont une syntaxe similaire au basic, mais qui sont du VB.Net.

Exemple :

 
Sélectionnez
A = Mid(MaString, 1, 3)

'Mid retourne une partie de la chaine de caractères.

Il y a aussi les Classes de compatibilité VB6. Elles ne dépayseront pas ceux qui viennent des versions antérieures de VB, car elles reprennent la syntaxe utilisée dans VB6 et émulent les fonctions VB6 qui ont disparu de VB.Net. Ce sont des fonctions VB6 qu'on ajoute à VB.net par souci de compatibilité, mais ce n'est pas du VB.Net. Il faut les oublier !

L'outil d'import automatique de VB6 vers VB.Net en met beaucoup dans le code. Il faut à mon avis éviter de les utiliser, car ce n'est pas vraiment du VB. Ce cours 'pur' VB.Net n'en contient pas.

Pour le moment cela peut paraitre un peu compliqué, mais ne vous inquiétez pas, cela va devenir clair.

V-A-3. Saisir, Afficher

Dans l'étude du langage VB, on s'occupe du code, on ne s'occupe pas de l'interface (les fenêtres, les boutons, l'affichage du texte…), mais parfois, on a besoin, pour faire fonctionner des exemples de code, de saisir des valeurs, de les afficher :

  • Saisir une valeur, pour cela on utilise une InputBox, c'est une boite qui s'ouvre, l'utilisateur y tape un texte puis il clique sur 'OK' ; on retrouve ce qu'il a tapé dans la variable Réponse.
 
Sélectionnez
Réponse= InputBox()
Image non disponible
  • Afficher des résultats, pour le moment on affichera du texte de la manière suivante :

dans une fenêtre, dans des TextBox :

 
Sélectionnez
TextBox1.Text="TextBox1"

Image non disponible

ou un label :

 
Sélectionnez
Label1.Text="Résultat"

sur la console :

 
Sélectionnez
Console.WriteLine ("Résultat")
Image non disponible

ou

dans une Boite de message :

 
Sélectionnez
MsgBox("Bonjour")

'ou
MessageBox.Show ("Bonjour")

Image non disponible

V-B. Les 'Algorithmes'

Ici nous allons étudier les principes généraux de la programmation, ils sont valables pour tous les langages de programmation. Ici il faut simplement comprendre le principe de ce qui est expliqué.

V-B-1. Pour écrire un programme

Pour écrire un programme, aller du problème à résoudre à un programme exécutable, il faut passer par les phases suivantes :

  • Analyse du cahier des charges
    Il doit être clair, exhaustif, structuré.
  • Analyse générale du problème
    Il existe des méthodes pour professionnels (MERISE, JACKSON…), nous utiliserons plutôt l'analyse procédurale: le problème global est découpé en sous-problèmes nommés fonctions. Chaque fonction ne contient plus qu'une partie du problème. Si une fonction est encore trop complexe, on itère le processus par de nouvelles fonctions à un niveau plus bas.
    Cela s'appelle la 'Conception structurée descendante'. La 'Conception ascendante' existe aussi: en assemblant des fonctions préexistantes, on résout le problème: attention, il faut que les fonctions préexistantes soient cohérentes. (Pour le moment on ne fait pas de programmation objet).
  • Analyse détaillée
    Chaque fonction est mise en forme, la logique de la fonction est écrite dans un pseudo langage (ou pseudocode) détaillant le fonctionnement de la fonction. Ce pseudocode est universel, il comporte des mots du langage courant ainsi que des mots relatifs aux structures de contrôle retrouvées dans tous les langages de programmation.
  • Codage
    Traduction du pseudocode dans le langage que vous utilisez.
  • Test
    Car il faut que le programme soit valide.

Exemple simpliste

  • Analyse du cahier des charges.
    Création d'un programme affichant les tables de multiplication, d'addition, de soustraction.
  • Analyse générale du problème.
    Découpons le programme en diverses fonctions:
    Il faut créer une fonction 'Choix de l'opération', une fonction 'Choix de la table', une fonction 'TabledeMultiplication', une fonction 'TabledAddition', une fonction 'Affiche'…
  • Analyse détaillée.
    Détaillons la fonction 'TabledeMultiplication'
    Elle devra traiter successivement (pour la table des 7 par exemple)
    1X7
    2X7
    3X7…

    Voici l'algorithme en pseudocode.

     
    Sélectionnez
    Début
    
        Pour i allant de 1 à 10
    
            Ecrire (i*7)
    
        Fin Pour
    
    Fin

    Exemple simpliste

  • Codage.
    Traduction du pseudocode en Visual Basic, en respectant la syntaxe du VB.

     
    Sélectionnez
    Sub MultiplicationPar7
    
    Dim i As Integer
    
    For i=1 to 10
    
        Call Affiche(i*7)
    
    next i.
    
    End Sub

    Exemple simpliste

  • Test
    Ici il suffit de lancer le programme pour voir s'il marche bien…

Pour des programmes complexes, il existe d'autres méthodes.

V-B-2. Définition de l'algorithme

Un problème est traitable par informatique si :

  • on peut parfaitement définir les données (entrées) et les résultats (sorties) ;
  • on peut décomposer le passage de ces données vers ces résultats en une suite d'opérations élémentaires exécutables.

L'algorithme décrit le processus de résolution d'un problème permettant de décrire les étapes vers le résultat.

L'algorithme détaille, le fonctionnement de ce passage et en décrit la logique.

L'algorithme est une succession de tests, décisions et actions dans le but de décrire le comportement d'une entité (objet, programme, personne). Définition du Dicodunet.

On écrit bien 'algorithme' et non 'algorythme'.Le mot "algorithme" vient du nom du mathématicien arabe Al Khuwarizmi (latinisé au Moyen Âge en Algoritmi).

Pour représenter l'algorithme et ses opérations, on utilisait les organigrammes (dessins avec des cases et des flèches qui ne permettaient de visualiser que des problèmes très simples); maintenant on utilise du pseudocode (composé d'instructions généralistes).

La mise en œuvre de l'algorithme consiste en l'écriture de ces opérations dans un langage de programmation (le Visual Basic pour nous).
On utilise l'anglicisme implémentation pour désigner cette mise en œuvre.

Étudions cette logique valable pour tous les langages de programmation (ceux qui sont des langages impératifs).

Pour représenter n'importe quel algorithme, il faut disposer des trois possibilités suivantes :

  • la séquence qui indique que les opérations doivent être exécutées les unes après les autres.

    Image non disponible

    Pour représenter n'importe quel algorithme, il faut disposer des trois possibilités suivantes :

  • le choix qui indique quelles instructions doivent être exécutées en fonction de circonstances.

    Image non disponible

    Pour représenter n'importe quel algorithme, il faut disposer des trois possibilités suivantes :

  • la répétition qui indique que des instructions doivent être exécutées plusieurs fois.
Image non disponible

Pour représenter n'importe quel algorithme, il faut disposer des trois possibilités suivantes :

Exemple d'algorithme principalement composé d'une répétition:
Sélectionnez
Pour i allant de 1 à 10
        Ecrire (i*7)
Fin Pour

Voyons cela en détail.

Le langage algorithmique et son pseudocode ne sont pas vraiment standardisés, chacun écrit le pseudocode à sa manière, aussi vous verrez des notations différentes dans les divers cours d'algorithme. Cela n'a pas d'importance, car un programme en pseudocode ne sera jamais exécuté sur une machine.

L'intérêt d'étude des algorithmes est didactique: elle permet de comprendre la logique d'un programme totalement indépendamment du langage: ce qui suit est valable en C++, Delphi, Java, Visual Basic, Assembleur… Comme on est dans un cours de VisualBasic, je donnerais pour chaque notion le pseudocode, mais aussi l'équivalent en Visual Basic.

V-B-3. Structures élémentaires

Il y a les structures de données (dans quoi sont stockées les données?) dans des :
-Constantes ;
-Variables ;
-Tableaux ;
-Collections ;
-Listes, Graphe, Arbre…
Il y a les structures de contrôles (Comment fonctionne le code ?) :
-Séquence ;
-Condition ;
-Boucle.

V-B-3-a. Séquences

Au sein d'un programme, la structure est généralement séquentielle.

Image non disponible

On fait de la programmation impérative, on travaille sur le modèle de la machine de Turing, avec une mémoire centrale et des instructions qui modifient son état grâce à des assignations successives.

Le code est fait d'une succession de lignes (ou instructions) qui seront lues et traitées les unes après les autres.

Instruction 1

Instruction 2

Instruction 3

Quand le programme s'exécute, il le fait de haut en bas, Instruction 1 sera exécuté puis instruction 2 puis instruction 3…

En VB on peut mettre plusieurs instructions sur la même ligne, séparées par ":"

Instruction1 : Instruction2

V-B-3-b. Variables, 'Type' de variable

Les 'Variables' contiennent les informations les données nécessaires au déroulement du programme (c’est le même sens qu'en mathématiques, à la différence qu'en informatique une variable ne contient qu'une valeur).

Chaque variable a un Nom (identifiant) et un Type. Ce dernier indique la nature de l'information que l'on souhaite mettre dans la variable.

Un type indique :

- la nature de l'information (un chiffre ? du texte ?) ;

- les valeurs que peut prendre la variable (un entier, un réel…) ;

-les opérations possibles (addition, concaténation…).

Exemple : le Type 'Entier' (Integer en VB) peut contenir une valeur entière, positive ou négative, les opérations possibles sont l'addition, la soustraction, la multiplication…Ainsi si je crée une variable de type Entier, je sais que je ne pourrai y mettre qu'un entier et que je pourrai faire une addition avec, je ne pourrai pas y mettre de caractères.

Les types disponibles sont :

Type numérique

'Entier', 'réel'… (Integer, Single en VB) Exemple d'un entier: 123 ;

Type alphanumérique

'Caractère' (Char en VB) contient 1 caractère Exemple d'un caractère: 'a' (avec des guillemets)

'chaine de caractères',(String en VB), contient plusieurs caractères. Exemple: 'toto' (avec des guillemets) ;

Booléen (Boolean en VB) ne peut contenir que 'Vrai' ou 'Faux' ;

Objet (Object en VB) ;

Monétaire (Décimal en VB) ;

Date (Date en VB) ;

Matrice, nombre imaginaire (depuis VB 2010).

À partir des types précédents, on peut créer des types complexes (ou structurés) :

- les Tableaux (Array) qui contiennent plusieurs éléments ;

- les Collections qui contiennent plusieurs éléments aussi.

Exemple : la variable nommée 'Total' contient un réel dans un programme de comptabilité.

On remarque qu'il ne faut pas confondre 1 qui est une valeur numérique( sans guillemets) et "1" qui est le caractère '1' (avec des guillemets).

Utilisation des variables

Les variables numériques serviront à faire des calculs.

Les variables alphanumériques (String et Char du VB) serviront entre autres à manipuler et afficher du texte.

Comment afficher les résultats de calcul ?

On apprendra à transformer des variables numériques en variables alphanumériques.

Pour utiliser une variable, il faut qu'elle existe, il faut donc la créer, on dit il faut la déclarer.

Dans un algorithme : 'Variable A en Numérique' 'crée une variable nommée A et de Type Numérique.

En VB : 'Dim A As Integer' 'crée une variable nommée A et de Type Integer.

On peut aussi initialiser une variable, c'est-à-dire définir sa valeur initiale.

Pour cela on peut utiliser un littéral : c'est une donnée utilisée directement.

X <- 2 veut dire : donner à la variable X la valeur 2 (2 est une littéral).

V-B-3-c. Constantes

Comme une variable, une 'Constante' a un Nom (identifiant) et un Type. Elle contient une valeur: un nombre, une chaine de caractères…

Son contenu ne peut pas être modifié.

Exemple :'Constante A en Numérique =12'.

En VB : 'Const A As Integer =12'.

On la déclare et on l'initialise en même temps.

Ensuite on ne peut pas modifier sa valeur, on ne peut que la lire. Les constantes sont utilisées dans les programmes pour conserver des valeurs fixes qui n'ont pas à changer. Si j'ai un programme d'astronomie, je créerai une constante contenant la vitesse de la lumière pour faire mes calculs (elle a peu de chances de changer !).

V-B-3-d. Affectation (ou Assignation)

C'est une instruction consistant à donner une valeur à une variable.

En langage algorithmique on l'indique par '<-'

X <- 2 veut dire : donner à la valeur X la valeur 2 (2 est une littéral).

Z <- X veut dire : donner à la variable Z la valeur de la variable X.

Z <- X+1 veut dire : donner à la variable Z la valeur de la variable X à laquelle on ajoute 1 (Z prendra la valeur 2+1 =3).

Cela revient à évaluer l'expression de droite et à en mettre la valeur dans la variable de gauche.

En VB le signe d'affectation est '=' on écrit donc :

 
Sélectionnez
    Z=X+1

Attention le signe '=' utilisé en VB est ambiguë et n'a donc pas le même sens qu'en mathématiques.

Exemple Visual Basic: A=B

Image non disponible

Attention ce n'est pas une égalité, mais une affectation.

L'affectation ne marche que si le type de variable est le même :

Variable A en Numérique

Variable B en Numérique

B<-12

A<-B 'fonctionne, car B contient 12, on met 12 dans A

Variable A en Numérique

Variable B en Alphanumérique

B<-'toto'

A<-B 'ne fonctionne pas, car on tente de mettre le contenu de B qui est alphanumérique dans une variable numérique.

L'affectation sert à effectuer des calculs

Variable A en Numérique.

A<-3+4-2 'L'expression à droite est évaluée et son résultat est affecté à la variable A.

Ici les + - sont des opérateurs, il y en a d'autres : * (multiplier), / (diviser)….

V-B-3-e. Booléens

On a parfois besoin de savoir si une assertion est vraie ou Fausse (True ou False).

Pour stocker une information de ce type, on utilise une variable de type booléen. Une variable de ce type ne peut contenir que True ou False.

Le terme booléen vient de "l'algèbre de Boole", cette algèbre ne travaille que sur les valeurs 1 ou 0 (True ou False).

Soit B une variable booléenne.

On peut écrire B<-True (B=True en VB).

On peut aussi tester cette variable.

Si B=False alors (If B=False Then… en VB).

L'expression après 'Si' est évaluée, si elle est vraie 'alors' se produit.

Autre exemple

Si C=2 alors… (If C=2 Then …en VB).

L'expression C=2 est évaluée, si C est effectivement égal à 2, C=2 est évalué et prend la valeur True, dans ce cas le programme se poursuit après Then.

si C est différent de 2, C=2 est évalué et prend la valeur False, dans ce cas le programme ne se poursuit pas après Then.

V-B-3-f. Choix : Si…Alors

Le programme doit pouvoir choisir parmi deux ou plusieurs possibilités en fonction d'une condition :

Image non disponible
 
Sélectionnez
Si Condition Alors

      Action 1

Sinon

      Action 2

Fin Si

Si Condition est vraie Action 1 est effectuée, sinon Action 2 est effectuée.

Parfois il n'y a pas de seconde branche :

 
Sélectionnez
Si Condition Alors

      Action 1

Fin Si

ou sur une seule ligne :

 
Sélectionnez
    Si Condition Alors Action 1

Il peut y avoir plusieurs conditions imbriquées :

 
Sélectionnez
Si Condition 1 Alors
    Si Condition 2 Alors

            Action 1

    Sinon

            Action 2

    Fin Si

Sinon

      Action 3

Fin Si

Noter bien le retrait des lignes de la seconde condition afin de bien visualiser la logique du programme :

Action 2 est effectuée si la Condition 1 est remplie et la Condition 2 n'est pas remplie.

En VB cela correspond à l'instruction IF THEN

 
Sélectionnez
If Condition 1 Then

      Action 1

Else

      Action 2

End If

Remarque sur les conditions

Une condition contient deux valeurs et un opérateur :

Si C>2 Alors est correcte.

Si B=3 Alors est correcte.

Si 2<B<7 Alors est incorrecte, car il y a deux opérateurs, il faut dans ce cas utiliser plusieurs conditions et des opérateurs logiques.

Si B>2 Et B<7 Alors est correcte (If B>2 And B<7 Then en Visual Basic).

La condition est évaluée.

Exemple : soit l'expression Si C>2 Alors , elle sera évaluée, si C contient 3, C>2 est vérifié donc Vrai.

Exemple : trouver le plus grand nombre entre x et y et le mettre dans max

 
Sélectionnez
Variable x en Numerique

Variable y en Numerique

Variable max en Numerique

Si x>y Alors

    max<-x

Sinon

    Max<-y

Fin Si

En VB

 
Sélectionnez
Dim x As Integer

Dim y As Integer

DIm max As Integer

if x>y Then

    max=x

Else

    max=y

End if

V-B-3-g. Choix : Décider entre

Il est parfois nécessaire d'effectuer un choix parmi plusieurs solutions :

Image non disponible
 
Sélectionnez
Décider Entre
      Quand Condition 1 Alors

            Action 1

      FinQuand
 

      Quand Condition 2 Alors

            Action 2

      FinQuand

      …

      …

      Autrement

            Action 4

      FinAutrement

FinDécider

Si la condition 1 est remplie, Action 1 est effectuée puis le programme saute après FinDécider.

Si la condition 1 n'est pas remplie, on teste la condition 2…

Si aucune condition n'est remplie, on saute à Autrement, on effectue Action 4.

On pourrait aussi parler de sélection :

 
Sélectionnez
Sélectionner.

      Le cas : condition 1

            Action 1

      Le cas : condition 2

            Action 2

      …

      Les autres cas

FinSélectionner

En VB cela correspond à

 
Sélectionnez
Select Case Valeur

      Case condition 1

            Action 1

      Case condition 2

            Action 2Case Else

            Action 4

End Select

Si Valeur=Condition 1 Action 1 est effectuée,si Valeur=Condition 2 Action 2 est effectuée…

V-B-3-h. Répétitions : Pour…Répéter

Permet de répéter une séquence un nombre de fois déterminé :

Image non disponible

Le cas le plus classique est :

 
Sélectionnez
Pour I variant de 0 à N Répéter

      Action

FinRépéter

I prend la valeur 0, 'Action' est effectuée,

puis I prend la valeur 1, Action est effectuée,

puis I prend la valeur 2…

cela jusqu'à N.

La boucle tourne N+1 fois (car ici on commence à 0 ).

Cela se nomme une itération.

Intérêts ?

Au lieu de faire :

Afficher (1*7)

Afficher (2*7)

Afficher (3*7)

Afficher (4*7)

on remarque qu'un élément prend successivement la valeur 1, 2, 3…

Une boucle peut faire l'itération :

 
Sélectionnez
Pour i allant de 1 à 10 Répéter

    Affiche (i*7)

Fin répéter

La variable dite 'de boucle' prend bien les valeurs 1 puis 2 puis 3… ; elle est utilisée dans le corps de la boucle.

Une instruction Sortir permet de sortir prématurément de la boucle.

En VB

 
Sélectionnez
For i=0 To N

      …

Next i

L'instruction Exit For permet de sortir prématurément de la boucle.

On peut aussi boucler en parcourant tous les éléments d'une collection.

(Une collection est une liste d'objets, liste de taille variable en fonction de ce qu'on ajoute ou enlève.)

 
Sélectionnez
Pour Chaque élément de la liste

      Action

Fin Pour

En VB :

 
Sélectionnez
For Each élément In list

 

Next

V-B-3-i. Répétitions : Tant que

Permet de faire une boucle sans connaitre le nombre d'itérations à l'avance.

Image non disponible
 
Sélectionnez
Tant Que Condition

      Action

Fin Tant Que

L'action qui est dans la boucle doit modifier la condition afin qu'à un moment 'Tant que' ne soit pas vérifié et que l'on sorte de la boucle. Sinon la boucle tourne sans fin.

Pour plus cadrer avec la réalité :

 
Sélectionnez
Faire tant que condition

      Action

Boucler

En VB :

 
Sélectionnez
Do while Condition

      Action

Loop

Il existe une boucle équivalente :

 
Sélectionnez
Répéter

      Action

Jusqu'à Condition

 

En VB :

Do

      Action

Loop Until Condition

Une instruction Exit Do permet de sortir prématurément de la boucle.

V-B-3-j. Logique : Et, Ou, Non

Une condition contient deux valeurs et un opérateur :

Si C>2 Alors… est correcte.

Si B=3 Alors est correcte.

Si 2<B<7 Alors est incorrecte, car il y a deux opérateurs, il faut dans ce cas utiliser plusieurs conditions et des opérateurs logiques :

Si B>2 Et B<7 Alors est correcte (If B>2 And B<7 Then en Visual Basic)

La condition est évaluée.

Exemple : Soit l'expression Si C>2 Alors , elle sera évaluée, si C contient 3, C>2 est vérifiée donc Vrai.

ET

On a vu Si B>2 Et B<7 Alors

Il existe aussi :

OU

Si B>2 Ou B<7 Alors

et

NON

Si NON(B>2) Alors est équivalent à Si B<=2 Alors

En VB on utilise les termes AND OR NOT.

V-B-3-k. Les Sauts

Un saut dans le code correspond à 'Aller à'.

Cela permet de 'sauter' vers un label (une étiquette= un endroit du code).

Exemple :

 
Sélectionnez
Variable A en Numérique

Variable B en Numérique

Variable C en Numérique

B<-12

A<-B  

Aller à Poursuivre

C=11

Étiquette Poursuivre

A<-A+1

Le programme saute de 'Aller à Poursuivre' à 'Étiquette Poursuivre', il n'exécute pas C=11.

En VB on utilise GoTo pour faire le saut, pour créer une étiquette, on lui donne un nom et on ajoute ':'…

 
Sélectionnez
MonEtiquette:

GoTo monetiquette

On verra que les sauts ne sont pratiquement plus utilisés.

V-B-3-l. Programmation structurée

Avant on écrivait :

 
Sélectionnez
Variable A en Numérique
Variable B en Numérique
Variable C en Numérique

B<-12
A<-B  

Si A=B Aller à Poursuivre1
  C<-1
Étiquette Poursuivre1

Si A<>B Aller à Poursuivre2

C<-2

Étiquette Poursuivre2

On faisait des sauts dans tous les sens!! Code illisible, non structuré.

Maintenant, on structure et on n'utilise pas de 'Aller à'.

 
Sélectionnez
Variable A en Numérique
Variable B en Numérique
Variable C en Numérique

B<-12
A<-B  

Si A=B Alors
    C<-1
Sinon
    C<-2
Fin Si

V-B-3-m. 'Sous-programme' ou 'procédure'

On a déjà vu cette notion.

Quand on appelle une procédure, le logiciel 'saute' à la procédure, il effectue celle-ci puis revient effectuer ce qui suit l'appel.

Dans un algorithme, une procédure commence par le mot Proc et se termine par End Proc.

Image non disponible

Le programme effectuera les instructions 1, 2, 3, 10, 11, 4, 5.

Une opération complexe peut être découpée en plusieurs procédures ou sous-programmes plus petits et plus simples qui seront appelés. Chaque procédure résout un problème.

Et VB les sous-programmes (ou procédures) sont des Sub ou des Function. Pour appeler une procédure, on utilise Call NomProcedure() ou NomProcedure()

On peut fournir aux procédures des paramètres, ce sont des variables qui seront transmises à la procédure.

Exemple

Création d'une Procédure 'MaProcédure' recevant deux paramètres :

 
Sélectionnez
Sub MaProcédure(paramètre1, paramètre2)

…

End Sub

Exemple d'appel de la procédure 'Maprocédure' en envoyant deux paramètres :

Call MaProcédure(premierparamètre, secondparamètre)

Exemple : si j'écris Call MaProcédure(2,3)

dans la procédure MaProcédure paramètre1=2 et paramètre2=3.

Il est nécessaire de définir le type des paramètres :

Sub MaProcédure(paramètre1 As Integer, paramètre2 As Integer) indique que la procédure attend deux entiers.

Il y a deux manières d'envoyer des paramètres :

- Par valeur : (By Val)c'est la valeur, le contenu de la variable qui est envoyé.

- Par référence : (By Ref) c'est l'adresse (le lieu physique où se trouve la variable) qui est envoyée. Si la Sub modifie la variable, cette modification sera visible dans la procédure appelante après le retour.

Parfois on a besoin que la procédure appelée retourne une valeur, dans ce cas il faut créer une fonction :

 
Sélectionnez
Function MaFonction()  As Integer    'MaFonction qui retourne un entier

…

    Return Valeur

End Function

Pour appeler la fonction :

ValeurRetournée=MaFonction()

Donc ValeurRetournée est aussi un entier.

Exemple de fonction: créer une fonction qui retourne le plus petit nombre :

 
Sélectionnez
Fonction Minimum (x en Numerique, y en Numérique) en numérique
Si x<y Alors

    Retourner x

Sinon

    Retourner y

Fin Si

Fin Fonction

Pour l'utiliser :

 
Sélectionnez
Variable Min en Numerique

Min<-Minimum (5,7) 'Appelle la fonction en donnant les 2 paramètres 5 et 7.

Min contient maintenant 5

En Vb

 
Sélectionnez
Function Minimum(x As Integer, y As Integer) As Integer

    If x<y Then

        Return x

    Else

        Return y

    End If

End Function

Pour l'utiliser :

 
Sélectionnez
Dim Min As Integer

Min= Minimum (5,7)

La fonction résout un problème et plus précisément à partir de données, calcule et fournit un résultat.

V-B-3-n. Tableaux

Un tableau de variables permet de stocker plusieurs variables de même type sous un même nom de variable, chaque élément étant repéré par un index ou indice.

C'est une suite finie d'éléments.

Soit un tableau A de quatre éléments :

3

12

4

0

Pour accéder à un élément, il faut utiliser l'indice de cet élément.

L'élément d'index 0 se nomme A[0] et contient la valeur 3.

On remarque que le premier élément est l'élément d'index 0 (ZÉRO).

L'élément d'index 1 se nomme A[1] et contient la valeur 12.

Quand on crée un tableau, il a un nombre d'éléments bien défini : 4 dans notre exemple d'index 0 à 3.

Pour donner une valeur à un des éléments, on affecte la valeur à l'élément.

 
Sélectionnez
A[2] <- 4

Pour lire une valeur dans un tableau et l'affecter à une variable x :

 
Sélectionnez
x <- A[2]

Traduction en VB

 
Sélectionnez
Dim  A(4) As Integer 'on déclare le tableau
A(2)=4

x = A(2)

Pour parcourir tous les éléments d'un tableau, on utilise une boucle.

Exemple : afficher tous les éléments du tableau tab qui contient n éléments.

 
Sélectionnez
début
          Pour i allant de 0 à n-1 Répéter
              écrire(tab[i])
          Fin Répéter
fin

En VB :

 
Sélectionnez
       For i=0 to n-1

            Affiche ( tab(i))    'routine d'affichage

       Next i

Il existe des tableaux multidimensionnels avec plusieurs index :

Voyons les index de chaque élément :

B(0,0)

B(0,1)

B(0,2)

B(1,0)

B(1,1)

B(1,2)

B(2,0)

B(2,1)

B(2,2)

B[1,0] désigne l'élément de la seconde ligne, première colonne.

Voyons par exemple, le contenu de chaque élément :

3

12

0

18

4

5

12

2

8

Ici B[1,0] =18

En VB on utilise des parenthèses : B(1,0) =18

V-B-3-o. Collection

Une collection permet de stocker plusieurs variables ou objets, chaque élément étant repéré par un index ou indice. Mais la collection n'a pas de nombre d'éléments précis au départ, elle ne contient que les éléments qu'on y ajoute.

Soit la collection Col, au départ elle est vide.

J'ajoute des éléments (ou items) à cette collection.

Col.Ajouter ("Toto")

Voici la collection :

Toto

La collection a maintenant 1 élément.

 
Sélectionnez
Col.Ajouter("Lulu")

Col.Ajouter("Titi")

Toto

Lulu

Titi

La collection a 3 éléments maintenant.

Col.Retirer(2) enlève l'élément numéro 2.

Toto

Titi

La collection n'a plus que 2 éléments maintenant.

On voit que le nombre d'éléments n'est pas connu à l'avance, il varie en fonction des éléments ajoutés (ou retirés).

Un élément est repéré par un indice.

En VB

 
Sélectionnez
Col.Add    'Ajoute un élément

Col.Remove 'Enlève un élément

Il existe des collections avec des clés permettant de retrouver la valeur d'un élément rapidement.

V-B-3-p. Pile et Queue

Une Pile (ou stack) est une collection de type LIFO (Last In, First Out). Dernier entré, premier sorti.

Ce type de stack (pile) est très utilisé en interne par les programmes informatiques : on stocke dans une stack les adresses de retour des procédures appelées, au retour on récupère l'adresse du dessus.

Push insère un objet en haut de la pile.

Pop enlève et retourne un objet en haut de la pile.

Image non disponible

On peut utiliser une pile dans un programme pour gérer le déplacement de l'utilisateur dans un arbre, les éléments en cours sont stockés par Push, pour remonter en chemin inverse, on Pop.

Une 'Queue' est une collection de type FIFO (First In, First Out). Premier arrivé premier servi.

C'est la queue devant un cinéma, le premier arrivé, prend son billet le premier.

Les éléments stockés dans Queue sont insérés à une extrémité; les éléments extraits le sont à l'autre extrémité.

Image non disponible

Le nombre d'éléments de la queue est géré automatiquement.

Généralement on a les possibilités suivantes :

DeQueue supprime et retourne l'objet de début de liste

EnQueue ajoute un objet en fin de liste

Peek retourne l'objet de début sans le supprimer

V-B-3-q. Liste chainée

Une liste chainée est une liste d'éléments non classée. Dans chaque enregistrement il y a, outre le contenu de l'enregistrement, la localisation, l'adresse, l'index de l'enregistrement précédent et de l'enregistrement suivant.

Image non disponible

Ainsi on peut parcourir la liste en allant d'enregistrement en enregistrement. Il existe des algorithmes pour ajouter ou supprimer un enregistrement. La liste peut être ouverte ou fermée (le dernier enregistrement bouclant sur le premier).

V-B-3-r. Notion de Clé

Quand on classe une série importante de données, on peut utiliser la notion de clé/Valeur (Key/Value).

Ici on utilise comme clé le numéro du département et comme valeur, le nom du département.

Image non disponible

Si on a la clé, on peut retrouver la valeur correspondante.

Autre exemple: La clé peut être le nom, prénom.

V-B-3-s. Notion de Hachage

Une fonction de hachage est une fonction qui fait subir une succession de traitements à une donnée fournie en entrée pour en produire une empreinte servant à identifier la donnée initiale.

Donnée d'entrée=> Fonction de hachage => Empreinte.

Le résultat d'une fonction de hachage peut être appelé selon le contexte empreinte, somme de contrôle (dans le cas de la CRC), résumé, condensé, condensat ou encore empreinte cryptographique (dans le cadre de la cryptographique). On l'appelait aussi autrefois aussi signature.

Les fonctions de hachage sont utiles en cryptographie où elles sont utilisées pour chiffrer une donnée initiale.

Mot de passe: "GftUi6h77"=> Fonction de hachage => Empreinte : "4587213399545684246847"

C'est l'empreinte qui va être enregistrée. Quand l'utilisateur rentre le mot de passe, on le 'hache" et on compare l'empreinte du mot de passe tapé par l'utilisateur avec l'empreinte enregistrée pour voir si le mot tapé est bon. Ainsi à aucun moment le mot de passe est en clair.

Ces fonctions de hachage sont aussi très utilisées pour accéder rapidement à une donnée contenue dans un grand nombre de données.

Ceci grâce aux tables de hachage (ou hash tables en anglais).

Un exemple classique et simpliste de fonction de hachage est la fonction modulo n : Si on dispose d'un grand nombre de données, à mettre dans un tableau de n cases, on pourra ranger l'élément numéro i dans la case i modulo n. Ainsi, pour aller chercher notre donnée, nous n'avons plus besoin de parcourir tous les éléments jusqu'à trouver l'élément i : Il suffit de parcourir les éléments contenus dans la case i modulo n. Si les données initiales étaient réparties uniformément, le temps de recherche en moyenne est divisé par n. En pratique, on utilise des fonctions de hachage bien plus complexes.

Le hachage est un nombre qui permet la localisation des éléments dans une table.

Exemple

Nous avons une série de noms et adresses, nous voulons rapidement trouver l'adresse correspondant à un nom sans avoir à faire une boucle qui compare le nom cherché avec chaque élément du tableau pour le trouver.

Pour chaque nom la fonction de hachage, va créer un numéro (empreinte).

Image non disponible

On crée des enregistrements indexés par ledit numéro (empreinte), chaque enregistrement contenant l'adresse.

Image non disponible

Si maintenant on cherche un nom, on calcule son empreinte, ce qui nous donne l'index de l'enregistrement que l'on trouve rapidement.

Image non disponible

Si la fonction de hachage est uniforme, cela veut dire que pour des entrées différentes, il n'y a jamais la même empreinte. Ce qui est la plupart du temps impossible.

Deux noms peuvent donc donner la même empreinte parfois (on parle de collision). Dans ce cas, on range les enregistrements ayant la même empreinte les uns à la suite des autres (sous forme de liste chainée). Si le premier enregistrement n'est pas le bon, on regarde le suivant.

Image non disponible

V-B-3-t. Arbre

Structure de données. Désigne une forme de diagramme qui modélise une hiérarchie.

Image non disponible

Un arbre est constitué d'un ensemble de nœuds et de branches reliant les nœuds. On peut parler de feuilles pour les éléments, les objets qui sont en bout de branches.
Le premier nœud d'un arbre (celui sans branche entrante) se nomme la racine.
Un arbre est unidirectionnel et sans boucle.

Un exemple de données en 'arbre' : sur un disque dur, les répertoires, sous-répertoires et fichiers ont une structure en arbre.

V-B-3-u. Erreur d'exécution : Notion de 'Sécurisation' du code

Erreur d'exécution

Si le code exécute Z=X/Y avec Y=0 (pour des entiers) , comme la division par zéro est impossible, le logiciel s'arrête.

Il s'agit d'une 'Erreur d'exécution' (dépassement de capacité).

En VB on dit qu'une exception est levée.

Il appartient au programmeur, une fois l'algorithme écrit, de le sécuriser : des instructions doivent protéger certaines parties du code afin d'éviter d'effectuer des opérations incohérentes.

 
Sélectionnez
Si Y <> 0 Alors
    Z= X/Y
Fin Si

Si vous testez cela en VB, bien utiliser des Integers, avec des Single le comportement est différent.

V-B-3-v. Récursivité

Une procédure est récursive si elle peut s'appeler elle-même.

 
Sélectionnez
Sub Calcul()

'…

    Calcul()

'…

End Sub

Pourquoi utiliser la récursivité ?
Une procédure récursive découpe le problème en morceaux plus petits et s'appelle elle-même pour résoudre chacun des plus petits morceaux, elle résout une petite partie du problème elle-même.

V-B-3-w. Flag et variables d'état

Un Flag (ou drapeau) est une variable utilisée pour enregistrer un état, la valeur de cet état servant à déclencher ou non des actions. C'est une manière de retenir qu'un événement s'est produit.

Si le drapeau est abaissé, les voitures roulent…

Exemple : utiliser un Flag pour sortir d'une boucle.

On utilise flagSortir.

 
Sélectionnez
flagSortir=Faux 

Tant que  flagSortir =Faux

      Si on doit sortir de la boucle, on met la valeur de flagSortir à Vrai

Boucler

En VB :

 
Sélectionnez
flagSortir=Faux 

Do while flagSortir =Vrai

     ' Si on doit sortir de la boucle, on met la valeur de flagSortir à Vrai

Loop

Tant que flagSortir =Faux la boucle tourne.

On peut généraliser cette notion en parlant de variable d'état.

Une variable d'état sert à décrire l'état du programme.

Exemple

fileIsOpen est une variable indiquant si un fichier est ouvert ou fermé.

V-B-3-x. Compilation, interprétation

Ici on n'est pas à proprement parler dans l'algorithmie.

Le texte que vous écrivez pour construire un programme est le code source.

Tout langage doit obligatoirement être traduit en langage machine (le langage du processeur) pour que ce programme soit exécutable.

Il existe deux stratégies de traduction :

- le programme traduit les instructions au fur et à mesure qu'elles se présentent (à la volée) au cours de l'exécution. Cela s'appelle l'interprétation ;

- le programme commence par traduire l'ensemble du programme (programme source) en langage machine, constituant ainsi un deuxième programme (un deuxième fichier) distinct physiquement et logiquement du premier, c'est le fichier exécutable. Cela s'appelle la compilation. Ensuite, pour exécuter le programme, on exécute l'exécutable, ce second programme.

Les premiers langages Basic étaient interprétés. Un langage interprété était plus maniable : on exécutait directement son code au fur et à mesure qu'on le tapait, sans passer à chaque fois par l'étape supplémentaire de la compilation. Un programme compilé s'exécute beaucoup plus rapidement qu'un programme interprété : le gain est couramment d'un facteur 10, voire 20 ou plus.

Le VB.Net est un langage compilé.

Le code source est dans des fichiers '.vb' et l'exécutable est un '.exe'. On verra que dans l'environnement de développement vb présente les avantages d'un langage interprété (exécution pas à pas, modification du source en cours de débogage…) On peut aussi créer un exécutable autonome.

Les choses sont plus complexes, car en vb, entre le source et l'exécutable il y a un code 'intermédiaire'.

V-B-4. Grandes stratégies

Pour trouver des réponses à un problème, on va choisir une grande stratégie et utiliser des structures élémentaires pour l'exécuter.

Algorithme direct ou explicite
Ici l'algorithme utilise la seule voie possible, évidente mathématiquement.
Exemple : pour calculer les racines d'une équation du second degré, l'algorithme calcule le déterminant puis en fonction de sa valeur (plusieurs cas), il calcule les racines.
Il est possible de découper un problème complexe en plusieurs problèmes plus simples.

Algorithme glouton
Un algorithme glouton suit le principe de faire, étape par étape, un choix optimum local, dans l'espoir d'obtenir un résultat optimum global.
Par exemple, dans le problème du rendu de monnaie (rendre une somme avec le moins possible de pièces), l'algorithme consiste à répéter le choix de la pièce de plus grande valeur qui ne dépasse pas la somme restante; c'est un algorithme glouton.
Nous faisons beaucoup d'algorithmes gloutons !

Diviser pour régner
Diviser pour régner est une technique algorithmique consistant à diviser un problème de grande taille en plusieurs sous-problèmes analogues.
Les algorithmes Diviser pour régner appliquent deux stratégies principales. La première est la récursivité sur les données: on sépare les données en deux parties, puis on résout les sous-problèmes (par la même fonction), pour enfin combiner les résultats. La seconde stratégie, la récursivité sur le résultat, consiste elle à effectuer un prétraitement pour bien découper les données, puis à résoudre les sous-problèmes, pour que les sous-résultats se combinent d'eux-mêmes à la fin.
Exemple : les algorithmes de tri (trier un tableau par exemple).

Recherche exhaustive
Cette méthode utilisant l'énorme puissance de calcul des ordinateurs consiste à regarder tous les cas possibles.
Exemple : rechercher une clé pour pénétrer dans un site (c'est mal !!): on teste à l'aide d'une boucle toutes les clés possibles, on parle de 'force brute'.

Algorithme aléatoire, approches successives
Certains algorithmes utilisent des recherches aléatoires, ou par approches successives donnant de meilleurs résultats que des recherches directes ou explicites. Exemple : ceux dits de Monte-Carlo et de Las Vegas.

Les heuristiques
Pour certains problèmes, les algorithmes ont une complexité beaucoup trop grande pour obtenir un résultat en temps raisonnable. On recherche donc une solution la plus proche possible d'une solution optimale en procédant par essais successifs. Certains choix stratégiques doivent être faits. Ces choix, généralement très dépendants du problème traité, constituent ce qu'on appelle une heuristique. Les programmes de jeu d'échecs, de jeu de go fonctionnent ainsi.

V-B-5. Quelques algorithmes

Les algorithmes les plus étudiés sont :
- Algorithmes simples :
…Inversion de variables,
…Recherche d'une valeur dans un tableau,
…Tri,
…Problème du voyageur de commerce ;
- Algorithmes utilisant la récursivité ;
- Algorithmes mathématiques ;
- Algorithmes informatiques complexes :
…Compression,
…Cryptage,
…Graphisme,
….

V-B-5-a. Recherche dans un tableau

Soit un tableau A() de 4 éléments :

3

12

4

0

Je veux parcourir le tableau pour savoir s'il contient le chiffre '4'.

Il faut faire une itération afin de balayer le tableau : la variable dite de boucle ( I ) va prendre successivement les valeurs: 0 ,1 ,2 ,3. (Attention : dans un tableau de 4 éléments, l'index des éléments est 0,1,2,3)

 
Sélectionnez
Pour I variant de 0 à 3 Répéter

      …

FinRépéter

Dans la boucle il faut tester si la valeur de l'élément du tableau est bien la valeur cherchée.

 
Sélectionnez
Pour I variant de 0 à 3 Répéter

      Si A(I)= 4 Alors…

FinRépéter

Si on a trouvé la bonne valeur, on met un flag (drapeau) à Vrai.

 
Sélectionnez
flagTrouvé<-Faux

Pour I variant de 0 à 3 Répéter

      Si A(I)= 4 Alors flagTrouvé<-Vrai

FinRépéter

Ainsi si après la boucle flagTrouvé= Vrai, cela veut dire que le chiffre 4 est dans le tableau.

En VB :

 
Sélectionnez
flagTrouve=False

For I=0 To 4

    If A(I)=4 Then flagTrouve=True

Next I

V-B-5-b. Tri de tableau

Pour trier un tableau de chaines de caractères (des prénoms par exemple), il faut comparer 2 chaines contiguës, si la première est supérieure (c'est-à-dire après l'autre sur le plan alphabétique: "Bruno" est supérieur à "Alice"))on inverse les 2 chaines, sinon on n'inverse pas. Puis on recommence sur 2 autres chaines en balayant le tableau jusqu'à ce qu'il soit trié.

Tableau non trié :

Bruno

Alice

Agathe

On compare les lignes 1 et 2, on inverse

Alice

Bruno

Agathe

On compare les lignes 2 et 3, on inverse

Alice

Agathe

Bruno

Le tableau n'étant pas encore trié, on recommence :

On compare les lignes 1 et 2, on inverse

Alice

Agathe

Bruno

On compare les lignes 2 et 3, on n'inverse pas.

Le tableau est trié.

Tout l'art des routines de tri est de faire le moins de comparaisons possible pour trier le plus vite possible.

On a utilisé ici le Bubble Sort (ou tri à bulle), on le nomme ainsi, car l'élément plus grand remonte progressivement au fur et à mesure jusqu'au début du tableau comme une bulle. ("Agathe" est passé de la troisième à la seconde puis à la première position).

Une boucle externe allant de 1 à la fin du tableau balaye le tableau N fois (La boucle varie de 0 à N-1), une seconde boucle interne balaye aussi le tableau et compare 2 éléments contigus (les éléments d'index j et j+1)et les inverse si nécessaire. La boucle interne fait remonter 1 élément vers le début du tableau, la boucle externe le fait N fois pour remonter tous les éléments.

 
Sélectionnez
Pour i allant de 0 à N-1

    Pour j allant de 0 à N-1

        Si T(j)>T(j+1) Alors 

            Temp<-T(j) 

            T(j)<-T(j+1)

            T(j+1)<-Temp

        Fin Si

    Fin Pour

 Fin Pour

En Visual Basic :

 
Sélectionnez
Dim i, j , N  As Integer    'Variable de boucle i, j ; N= nombre d'éléments-1

Dim Temp  As String

N=4  'tableau de 5 éléments.

Dim T(N) As String  'élément de 0 à 4

For i=0 To N-1

    For j=0 To N-1

        If T(j)>T(j+1) then 

            Temp=T(j): T(j)=T(j+1):T(j+1)=Temp

        End if

    Next j

 Next i

Remarque : pour inverser le contenu de 2 variables, on doit écrire

Temp=T(j): T(j)=T(j+1): T(j+1)=Temp (L'instruction qui faisait cela en VB6 et qui se nommait Swap n'existe plus)

Cet algorithme de tri peut être optimisé, on verra cela plus loin.

Les algorithmes s'occupent aussi de décrire la manière de rechercher des données dans des tableaux, de compresser des données… Nous verrons cela au fur et à mesure.

V-B-6. Lexique anglais=>français

If = Si.

Then= Alors

Step=Pas

Do (To)= faire

While= tant que

Until= Jusqu'à ce que.

Loop= boucle

V-C. L'affectation

Image non disponible

C'est l'instruction la plus utilisée en programmation.

On peut aussi utiliser le terme 'Assignation' à la place de l'affectation.

'Variable = Expression' est une affectation, c'est le signe '=' qui indique l'affectation.

L'affectation transfère le résultat de l'expression située à droite du signe 'égal' dans la variable (ou la propriété) à gauche du signe égal.

Exemple

A=B est une affectation (ou assignation).

A=B affecte la valeur de la variable B à la variable A, la valeur de B est mise dans A.

Image non disponible

Si

A=0

B=12

A=B entraine que A=12 (B n'est pas modifié).

Si nécessaire l'expression à droite du signe = est évaluée, calculée avant d'être affectée à la variable de gauche.

Si

A=0

B=12

A=B+2 entraine que A=14

L'affectation permet donc de faire des calculs :

Si nombrdHeure=100 et tauxHoraire=8

paye= nombredHeure * tauxhoraire

paye prend la valeur 800 (notez que '*' , l'étoile veut dire : multiplication.)

Attention dans le cas de l'affectation "=" ne veut donc pas dire 'égal'.

A=A+1 est possible

Si A=1

A=A+1 entraine que A=2

On verra qu'il existe des variables numériques ('Integer' 'Single') et alphanumériques (chaine de caractères ou 'String'), l'affectation peut être utilisée sur tous les types de variables.

Le second membre de l'affectation peut contenir des constantes, des variables, des calculs dans le cas de variables numériques.

A=B+2+C+D

On ne peut pas affecter une variable d'un type à une variable d'un autre type :

si A est numérique et B est alphanumérique (chaine de caractères) A=B n'est pas accepté.

Écriture compacte :

A=A+1 peut s'écrire de manière plus compacte : A += 1

A=A*2 peut s'écrire de manière plus compacte : A *= 2

A=A&"Lulu" pour une variable chaine de caractères peut s'écrire de manière plus compacte : A &= "Lulu"

L'affection marche pour les objets, leurs propriétés…

Bouton1.BackColor= Bouton2.BackColor

Signifie que l'on donne au Bouton1 la même couleur de fond que celle du bouton2: on affecte la valeur BackColor du Bouton2 au Bouton1.

Attention le signe '=' signifie par contre 'égal' quand il s'agit d'évaluer une condition, par exemple dans une instruction If Then (Si Alors)

If A=B then 'signifie: Si A égal B alors…

Permutation de variables

C'est un petit exercice.

J'ai 2 variables A et B contenant chacune une valeur.

Je voudrais mettre dans A ce qui est dans B et dans B ce qui est dans A.

Si je fais

A=B

B=A

Les 2 variables prennent la valeur de B !!

Comment faire pour permuter?

Et bien il faut utiliser une variable intermédiaire C qui servira temporairement à conserver le contenu de la variable A :

C=A

A=B

B=C

 

A

B

C

Départ

1

2

0

C=A

1

2

1

A=B

2

2

1

B=C

2

1

1

Voilà, on a bien permuté.

V-D. Les variables : généralités

Image non disponible

C'est le même sens qu'en mathématiques.

Une variable sert à stocker un nombre, du texte (chaine de caractères), une date, un objet…

Une variable a un nom et un type qui indiquent ce que l'on peut y mettre (Elle a aussi une 'portée' : où et quand sera-t-elle visible et utilisable ?).

Si myString est une variable de type chaine de caractères (ou String): je peux y mettre une chaine de caractères ("TOTO" par exemple)

Image non disponible

myString="TOTO"

Si age est une autre variable de type numérique, je peux y stocker un nombre (45,2 par exemple).

age=45,2

V-D-1. Nom des variables

On peut utiliser dans les noms de variable des majuscules ou des minuscules, mais pour VB il n'y a pas de différence.

Exemple

On ne peut pas déclarer une variable VB et une variable vb.

Si on déclare une variable nommée 'VB' et si ultérieurement on tape 'vb', le logiciel le transforme automatiquement en 'VB'.

  • On peut mettre des chiffres et des lettres dans les noms de variable, mais pas de chiffres en premier caractère.
    2A n'est pas un nom valide
    Nom2 l'est.
  • Certains caractères de ponctuation ('…) ne peuvent pas être utilisés, d'autres "_" et "-" sont permis :
    nom_Utilisateur est valide.
    L'espace n'est pas permis.
  • Bien sur, les mots clé de VB ne peuvent pas être utilisés : On ne peut pas nommer une variable Form ou BackColor

Il est conseillé de donner des noms explicites qui rappellent ce que contient la variable :

nom_Utilisateur est explicite, pas NU.

Parfois on indique en début de nom, par une lettre, le type de variable ou sa portée (la zone de code où la variable existe).

s_Nom 'Le s indique qu'il s'agit d'une variable String (chaine de caractères)

iIndex 'Le i indique qu'il s'agit d'une variable Integer (Entier)

gNomUtilisateur 'g indique que la variable est globale

Il est possible de 'forcer' le type de la variable en ajoutant un caractère spécial à la fin du nom de la variable.

Dim c$ = "aa" ' $ force c à être une variable String.

De même % force les Integer, & les long…

Cette notation est moins utilisée et non recommandée.

Voir en annexe, en bas de page des recommandations supplémentaires.

Nommage

On conseille, quand le nom d'une variable est composé de plusieurs mots, de mettre la première lettre de chaque mot en majuscule, sauf pour le premier mot.

Exemple

nom_Utilisateur

V-D-2. Déclaration, initialisation

Avant d'utiliser une variable, il faut la déclarer, la créer, pour cela on utilise l'instruction Dim :

 
Sélectionnez
Dim a As Integer    'Déclare une variable nommée 'a' de type Entier

Avant la ligne, a n'existait pas, après le DIM, a existe et contient 0.

L'instruction Dim crée la variable et lui alloue un espace de stockage.

Il faut aussi parfois l'initialiser, c'est-à-dire lui donner une valeur de départ : a=3

On peut déclarer et initialiser en même temps :

 
Sélectionnez
Dim a As Integer =3

Rien n'empêche d'utiliser une expression, une fonction pour initialiser.

 
Sélectionnez
Dim a As Integer = CalculMaVariable(4,3)

Ici pour initialiser la variable, on appelle une fonction CalculMaVariable qui retourne une valeur pour a.

Il est toujours préférable d'initialiser rapidement une variable.

On peut déclarer plusieurs variables en même temps; il faut les séparer par des virgules :

 
Sélectionnez
Dim a, b, c As Integer        'a, b et c sont maintenant des variables de type integer.

Bien sûr, on ne peut pas déclarer plusieurs fois un même nom de variable :

 
Sélectionnez
Dim a As Integer
Dim a As String' <= non accepté

On peut affecter à une variable une valeur de même type que le type de la variable :

 
Sélectionnez
Dim a As Integer
 a=2  'OK
 a= "Philippe"  'Non, car on ne peut pas mettre une chaine de caractères dans une variable de type Integer

V-D-3. En pratique : Exemple

Les variables après avoir été déclarées, vont servir à stocker des données, à effectuer des calculs, on peut afficher ensuite leur valeur.

Exemple simpliste d'utilisation de variables :

 
Sélectionnez
    Dim varA As Integer        'Création d'une variable varA
                    
    Dim varB As Integer        'Création d'une variable varB
                    
    Dim total As Integer       'Création d'une variable total

                    
    varA=3                     'Mettre '3' dans a 

                    
    varB=2                     'Mettre '2' dans b

                    
    total=varA + varB          'Mettre dans la variable 'total' la valeur de varA et de varB  

                    
    LabelTotal.Text= total.ToString    'Afficher le total dans un label

Un label est une zone permettant d'afficher du texte, pour afficher dans un label il faut transformer la variable total qui est un entier en chaine de caractères (à l'aide de ToString) puis mettre la string dans le texte du label.

Noter bien la différence entre :

 
Sélectionnez
Dim total As Integer

total= 123 'Total est une variable numérique (Integer ou Entier) contenant le nombre 123

et

 
Sélectionnez
Dim total2 As String

total2= "123" 'Total2 est une variable string contenant la chaine de caractères "123" c'est-à-dire les caractères "1" , "2" et "3"

On peut afficher les chaines de caractères (ou String), pas les variables numériques.

On fait des calculs avec les variables numériques.

Il faudra donc parfois convertir le contenu d'une variable d'un type dans un autre type ( convertir une variable numérique en String pour l'afficher par exemple ou convertir une variable String en numérique pour faire un calcul). On apprendra cela plus loin.

L'exemple simpliste juste au-dessus le montre: il faut convertir total qui est un entier en string pour l'afficher.

Concernant les variables numériques

Les variables numériques peuvent être signées (accepter les valeurs négatives ou positives) ou non signées (Comme le Type 'Byte' qui ne contient que des valeurs positives). Les variables numériques peuvent contenir des entiers(comme les Integer) ou des réels (comme les Single). Pour les réels dans le code, le séparateur est le point:

V-D-4. Les différents types de variables

En Visual Basic :

Nom :

Contient :

Boolean

Contient une valeur booléenne (logique): True ou False.

Byte

Contient les nombres entiers de 0 à 255 (sans signe)

Short

Entier signé sur 16 bits (-32768 à 32768)

Integer

Entier signé sur 32 bits (-2147483648 à 2147483647)

Long

Entier signé sur 64 bits (-9223372036854775808 à 9223372036854775807)

BigInteger

Entier signé très grand (sans limite supérieure ou inférieure) (VB2010)

Single

Nombre réel en virgule flottante (-1,401298 *10^-45 à 1,401298 10^45)

Double

Nombre réel en virgule flottante double précision. (…puissance 324)

Decimal

Nombre réel en virgule fixe grande précision sur 16 octets.

Char

1 caractère alphanumérique

String

chaine de caractères de longueur variable (jusqu'a 2 milliards de caractères)

DateTime

Date plus heure

Object

Peut contenir tous les types de variables, mais aussi des contrôles, des fenêtres…

Structure

Ensemble de différentes variables définies par l'utilisateur.

 

Depuis la version 2005 il y a aussi les Unsigned ( non signé: pas de valeur négative):

UInteger

Entier codé sur 32 bits pouvant prendre les valeurs 0 à 4 294 967 295.

ULong

Entier codé sur 64 bits :0 à 18 446 744 073 709 551 615

UShort

Entier sur 16 bits 0 à 65 535.

et

 

SByte

Byte, mais signé. Codé sur 1 octet, valeur de -128 à 127

Complex

Nombre complexe (en VB2010)

V-D-5. Les Boolean

Contient une valeur booléenne : True ou False (Vrai ou Faux pour les sous doués en anglais!).

Exemple :

 
Sélectionnez
Dim myBoolean As Boolean

myBoolean = True

Après déclaration un Boolean a la valeur False.

V-D-6. Variable entière

Byte

Contient les nombres entiers de 0 à 255 (sans signe).

Short

Entier sur 16 bits (-32768 à 32768)

Integer

Entier sur 32 bits (-2147483648 à 2147483647)

Long

Entier sur 64 bits (-9223372036854775808 à 9223372036854775807)

BigInteger

Entier signé très grand (sans limite supérieure ou inférieure) (VB2010)

Pour une variable entière il n'y a pas de possibilité de virgule!! attention, une division de 2 entiers donne un entier.

Pour le mathématicien, les Integer correspondent aux nombres entiers naturels : Entiers positif ou négatif et 0 (…-3 -2 -1 0 1 2 3…), mais avec une limite.

Attention, les variables numériques en informatique ne peuvent pas contenir de nombre infiniment grand ( sauf les BigInteger): Il y a une limite maximum : un Integer est par exemple codé sur 32 bits ce qui fait qu'il peut varier de -2147483648 à 2147483647. Si on utilise une valeur trop grande, une erreur se produit. Les entiers peuvent être positifs ou négatifs (Sauf les Bytes et les 'Unsigned': UInteger, ULong, UShort).

Plus on augmente le type (Long au lieu de Integer) plus on peut y mettre des grands nombres. Mais cela prend aussi plus de place et le traitement des opérations est plus long.

Les processeurs travaillant sur '32 bits', utilisez plutôt les Integer (qui sont codés sur 32 bits aussi), c'est plus rapide, que les short.

On utilise largement les 'Integer' comme variable de boucle, Flag, là ou il y a besoin d'entier…(Les calculs sur les réels en virgule flottante sont beaucoup plus lent.)

Exemple:

 
Sélectionnez
Dim i As Integer

i=12

Après déclaration une variable numérique contient 0.

Le type de données Byte est utilisé pour contenir des données binaires (octet codant de 0 à 255) non signé.

V-D-7. Variable réelle

Un réel peut avoir une partie fractionnaire: 1,454 est un réel.

Pour le mathématicien, les Single, Double… correspondent aux nombres réels ou fractionnaires: mais avec des limites ( sur la précision et le fait qu'ils ne sont pas infinis).

Single, Double, Decimal.

Single Nombre réel en virgule flottante (-1,401298 *10^-45 à 1,401298 10^45)

Double Nombre réel en virgule flottante double précision. (-1,79769313486231570E+308 et -4,94065645841246544E-324 pour les valeurs négatives et entre 4,94065645841246544E-324 et 1,79769313486231570E+308 pour les valeurs positives)

Decimal Nombre réel en virgule fixe grande précision sur 16 octets: Avec une échelle 0 (aucune décimale), la plus grande valeur possible correspond à +/-79 228 162 514 264 337 593 543 950 335. Avec 28 décimales, la plus grande valeur correspond à +/-7,9228162514264337593543950335

Les variables en virgule flottante ou notation scientifique

(Single, Double)

La variable peut être positive ou négative.

Le 'Double' est, bien sûr, plus précis et peut atteindre des nombres plus grands que le 'Single'.

Le 'Single' comporte 7 chiffres significatifs maximum.

Le 'Double' comporte 18 chiffres significatifs maximum.

Le nombre est codé en interne sous forme scientifique, exemple:1,234568E+008.

Mais en pratique, on travaille et on les affiche de manière habituelle, en notation normale avec un point comme séparateur décimal :

 
Sélectionnez
Dim poids As Single
                    
poids=45.45

Format scientifique, mantisse et exposant

Voici 3 nombres :

14500000
0,145
0,0000145

Ils comportent tous les 3, deux informations :

  • le nombre entier 145
  • la localisation du premier chiffre par rapport à la virgule

8
-1
-5 dans nos exemples.

Donc un réel peut être stocké sous la forme d'un couple :

  • partie entière ;
  • localisation de la virgule.

Il est codé en interne avec une mantisse (la partie entière) et un exposant (position de la virgule), sous la forme mmmEeee, dans laquelle mmm correspond à la mantisse (chiffres significatifs: partie entière) et eee à l'exposant (puissance de 10).

En fait, en notation scientifique (en codage interne) un chiffre précède toujours la virgule: 1,234568E+008.

Attention, les variables numériques réelles ne peuvent pas contenir de nombre infiniment grand: Il y a une limite maximum comme pour les entiers. La valeur positive la plus élevée d'un type de données Single est 3,4028235E+38 et celle d'un type de données Double est 1,79769313486231570E+308. Si on dépasse cette valeur VB le signale en déclenchant une erreur.

Quand on travaille avec des nombres ayant beaucoup de chiffres significatifs, il peut y avoir des erreurs d'arrondi. Le type 'Single' comporte par exemple une mantisse de 7 chiffres significatifs seulement. Si on utilise des nombres (même petit: avec un exposant négatif par exemple)avec 8 chiffres significatifs il peut y avoir des erreurs d'arrondi.

Le type en Virgule fixe.

Le type en Virgule fixe (Decimal) prend en charge jusqu'à 29 chiffres significatifs et peut représenter des valeurs jusqu'à 7,9228 x 10^28. Ce type de données est particulièrement adapté aux calculs (par exemple financiers) qui exigent un grand nombre de chiffres, mais qui ne peuvent pas tolérer les erreurs d'arrondi.
Il est codé sur 128 bits sous forme d'un entier et une puissance de 10.

Les Calculs en Decimal sont 10 fois plus lents que les calculs en Single, mais il n'y a pas d'erreur d'arrondi avec les décimals.

Pour les calculs financiers ont utilisera les 'Decimal'.

Pour les petits calculs du genre résultats d'examen biologique, on utilisera les 'Single' ou les 'Double' qui sont les plus rapides.

Pour les variables de boucle, les index, on utilise habituellement des Integers.

V-D-8. String, Char

Le type 'String' peut contenir une 'chaine de caractères' (alphanumérique) comme du texte. La longueur de la chaine n'est pas fixe et une String peut avoir un nombre de caractères allant de 0 jusqu'à environ 2 milliards de caractères.

Les chaines de longueur fixe n'existent pas (plus).

Le Type 'Char' contient un seul caractère. On utilise souvent des tableaux de 'Char'.

Pour information Char et String contiennent en interne le code des caractères au format Unicode (dans la variable,chaque caractère est codé sur 2 octets) et pas de l'ASCII ou de l'ANSI…(ancien codage où chaque caractère était codé sur un octet).

Les premiers caractères ont le même code Unicode et Ascii.

Exemple :

Caractère

Code

"a"

65

"b"

66

" "

32

Il y a aussi des caractères non affichables :

RC

13

retour chariot

LF

10

Line Feed

 

9

Tabulation

Pour passer à la ligne, on utilise les codes 13 puis 10. Il y a une constante toute faite pour cela: ControlChars.CrLf.

V-D-9. Place occupée en mémoire

Les types de variables ont un nom en VisualBasic et un nom dans le Framework.

Exemple

Integer et System.Int32 sont équivalents pour designer le type 'entier', Integer est le type VB, System.Int32 est le type 'NET' correspondant. On peut utiliser l'un ou l'autre.

Exemple de place occupée par une variable (et le nom de sa Classe dans NET).

Type VB

Place occupée

Type NET correspondant

Boolean

2 octets

System.Boolean

Byte

1 octet

System.Byte

Short

2 octets

System.Int16

Integer

4 octets

System.Int32

Long

8 octets

System.Int64

Single

4 octets

System.Single

Double

8 octets

System.Double

Decimal

16 octets

System.Decimal

Date

8 octets

System.DateTime

Char

2 octets

System.Char

Objet

4 octets

System.Objet

String

dépend de la chaine

System.String

La méthode GetType permet de savoir de quel type, de quelle Classe est une variable.

 
Sélectionnez
Dim x As String ="a"

MessageBox.Show(x.GetType.ToString)    'Affiche: Systeme.String

Prend le type de x, le transforme en String, l'affiche dans une MessageBox (Noter qu'il faut initialiser x avec une valeur avant de faire GetType).

V-D-10. Type primitif, littéral

Mise à part Objet, Structure, Class tous les autres types sont dit 'Primitif'( Byte, Boolean, Short, Integer, Long, Single, Double, Decimal, Date, Char, String).

  • Tous les types primitifs permettent la création de valeurs par l'écriture de littéraux. Par exemple, i=123 ou i=123I (le I force 123 a être entier) est un littéral de type Integer.
  • Il est possible de déclarer des constantes des types primitifs.
  • Lorsqu'une expression est constituée de constantes de type primitif, le compilateur évalue l'expression au moment de la compilation. C'est plus rapide.

Un littéral: c'est une donnée utilisée directement; une valeur numérique ou en toutes lettres par opposition à une variable.

 
Sélectionnez
Dim i As Integer
i=4   '4 est un littéral, c'est ici un integer

On voit que le littéral est un Integer en passant la souris dessus.

 
Sélectionnez
Dim i As Integer
i=100000000  'valeur non acceptée, car trop grande pour un littéral integer
Dim j As Long
j=100000000  'accepté, car le littéral est un Long

Attention, si je tape :

 
Sélectionnez
i=1.4

1.4 est un Double, il sera converti en Integer pour être affecté à i est on aura dans i la valeur 1.
Le signe entre la partie entière et fractionnaire est le '.' dans un littéral et cela force le littéral à être un Double.

On peut forcer le type d'un littéral en ajoutant une lettre :

 
Sélectionnez
i= 42L   'le 'L' indique que 42 est un Long
i= 42I   'le 'I' indique que 42 est un Integer
i= 42D   'le 'D' indique que 42 est un Decimal
i= 42S   'le 'S' indique que 42 est un Single
C = "A"c  'le 'c' force "A" à être une Char et non une String

V-D-11. Nullable

Type Nullable

Les types Par Valeur peuvent être étendus afin d'accepter une valeur normale habituelle ou une valeur Null (Nothing en VB). On peut déclarer un type Nullable de 3 manières :

 
Sélectionnez
Dim MyInteger As Nullable (Of Integer)

Mais aussi :

 
Sélectionnez
Dim MyInteger? As Integer

Dim MyInteger As Integer?

C'est le '?' qui force la variable Nullable.

Sur la seconde déclaration, la variable est MyInteger

Autre exemple :

 
Sélectionnez
Dim MyBol As Boolean?

MyBol pourra prendre la valeur True, False et Nothing.

Cela a de l'intérêt quand on travaille avec les bases de données qui ont des champs qui contiennent un Null et avec Linq.

La propriété HasValue permet de voir si la variable a une valeur autre que Nothing (Valeur retrouvée dans Value).

 
Sélectionnez
Dim a? As Integer
        If a.HasValue = True Then
            MsgBox(a.Value.ToString)
        End If

V-D-12. Choix des noms de variables

  • La plupart des noms sont une concaténation de plusieurs mots, utilisez des minuscules et des majuscules pour en faciliter la lecture.
  • Pour distinguer les variables et les routines (procédures), utilisez la casse Pascal (CalculTotal) pour les noms de routine (la première lettre de chaque mot est une majuscule).
  • Pour les variables,la première lettre des mots est une majuscule, sauf pour le premier mot (documentFormatType).
  • Le nom des variables booléennes doit contenir Is qui implique les valeurs Yes/No ou True/False, Exemple fileIsFound.
  • Même pour une variable à courte durée de vie qui peut apparaitre uniquement dans quelques lignes de code, utilisez un nom significatif. Utilisez des noms courts d'une seule lettre, par exemple i ou j, pour les index de petite boucle uniquement.
  • N'utilisez pas des nombres ou des chaines littérales telles que For i = 1 To 7. Utilisez plutôt des constantes nommées, par exemple For i = 1 To Nombre_jour_dans_semaine, pour simplifier la maintenance et la compréhension.
  • Utilisez des paires complémentaires dans les noms de variables telles que min/max, begin/end et open/close ou des expressions min max si nécessaire en fin de nom.

V-E. Variables 'String' et 'Char'

V-E-1. Variables 'String'

Il faut déclarer une variable avant de l'utiliser, pour cela on utilise l'instruction Dim.

 
Sélectionnez
Dim MyString As String

Déclare une variable nommée MyString et qui peut contenir une chaine de caractères.

Cette variable peut être utilisée pour contenir une chaine de caractères.

Image non disponible

 
Sélectionnez
MyString= "TOTO"

'On met la chaine de caractères "TOTO" dans la variable MyString.

On peut afficher le contenu de la chaine dans un label (zone présente dans une fenêtre et où on peut afficher du texte) par exemple :

 
Sélectionnez
      Label.text = MyString

Cela affiche 'TOTO' dans le label.

Remarquons que pour définir une chaine de caractères il faut utiliser des "" : Ce qui est entre" et " est la chaine de caractères. On parle ici de chaine littérale: une représentation textuelle d'une valeur particulière.

Après avoir été créée, une String contient 'Nothing' c'est-à-dire rien (même pas une chaine vide: ""); il faudra l'initialiser pour qu'elle contienne quelque chose.

 
Sélectionnez
Dim str As String    'str contient Nothing 
'Testons si str contient Nothing
If IsNothing(str) then Console.Write ( "contient Nothing")

(pas le texte "Nothing"!! mais la valeur Nothing qui signifie qu'elle ne pointe sur rien.

 
Sélectionnez
str= ""              'str contient "" : chaine vide de longueur 0

str= "TOTO"          'str contient "TOTO"

Notez bien l'importance des guillemets :

A est la variable A

"A" est une chaine de caractères contenant le caractère "A"

Exemple :

 
Sélectionnez
Dim A As String= "Visual"

Dim B As String= "Basic"

Label.text = "A+B"  affiche bêtement la chaine  "A+B"

Label.text =  A+B    affiche "VisualBasic" 'on affiche les variables.

Notez enfin que " ", l'espace est un caractère à part entière.

Si je veux inclure un caractère " dans la chaine, il faut le doubler pour qu'il ne soit pas considéré comme caractère de fin de chaine :

 
Sélectionnez
A=" Bonjour ""Monsieur"" "    'Cela affiche :  Bonjour "Monsieur"

On peut initialiser la variable en même temps qu'on la déclare.

 
Sélectionnez
Dim Chaine as string = "Toto"

On peut déclarer plusieurs variables d'un même type sur une même ligne.

 
Sélectionnez
Dim x, y, z As String    'Déclare 3 variables 'String'

On utilise GetType pour connaitre le type d'une variable.

 
Sélectionnez
x.GetType.ToString

y.GetType.ToString

z.GetType.ToString

donne

 
Sélectionnez
System.String

System.String

System.String

Ce qui prouve que les 3 variables sont bien des Strings.

V-E-1-a. La Classe System.String

Le type System.String ou String (chaine de caractères) est une Classe du Framework, qui a des méthodes.

Pas besoin de connaitre toutes les méthodes, il suffit de déclarer la String par 'Dim réponse As String') de taper réponse puis "." et vous voyez apparaitre toutes les propriétés et méthodes :

Image non disponible

Voyons par exemple la méthode .ToUpper

Elle retourne la chaine de caractères en majuscules.

 
Sélectionnez
      str=str.ToUpper()

Si str contenait "abc" il contiendra "ABC"

.ToLower transforme par contre la chaine en minuscules.

Quel intérêt ?

Exemple

Je dois comparer 2 String pour savoir si elles sont égales, la première a été saisie par l'utilisateur et je ne sais pas si l'utilisateur a tapé en majuscules ou en minuscules.

Si je compare A = "Vb" et B= "vb" elles sont différentes.

Si je compare A.ToLower et B.ToLower elles sont égales.

.Trim

Permet de supprimer des caractères en début et fin de chaine.

 
Sélectionnez
Dim a As String = "#@Informatique@#"

Dim b As Char() = {"#", "@"}    'b est un tableau de Char contenant les caractères à supprimer.

a=a.Trim(b)  Donne a= "Informatique"

Attention : Bien utiliser Char() qui est un tableau de caractères pour définir les caractères à supprimer.

(Dim b As String= "#@" est déconseillé, car produisant des résultats curieux.)

Pour enlever les espaces avant et après la chaine (cas le plus fréquent) :

 
Sélectionnez
s=" Bonjour "

s=s.Trim(" ")    'donne s="Bonjour"

Attention avec Option Strict= On, s=s.Trim("") n'est pas accepté, car le paramètre de Trim doit être une Char, la String" "n'est pas transformée (castée) en char. Il faut écrire s=s.Trim(" "c) ou s=s.Trim(CChar("")).

Il existe aussi TrimStart et TrimEnd pour agir seulement sur le début ou la fin de la chaine.

Length

Length : Taille d'une chaine en nombre de caractères.

Afficher la taille de la chaine "VB"

 
Sélectionnez
Dim s As String= "VB"

MsgBox(s.Length.ToString) 'Affiche 2

Concat

Concaténation de plusieurs chaines : mise bout à bout :

 
Sélectionnez
s=String.Concat(a,b)

Il est plus rapide de faire : s= a & b

(s= a+b fait la même chose, mais est déconseillé, on réserve '+' pour l'addition de numériques).

Concat est très pratique quand on veut mettre bout à bout tous les éléments d'un tableau :

 
Sélectionnez
Dim s() As String = {"hello ", "my ", "friend ", "to "}
Dim c As String = String.Concat( s())

Insert

Insère une chaine dans une autre.

 
Sélectionnez
Dim s As String= "VisualBasic"

s= s.Insert(6,"  " ) 'Donne s= "Visual  Basic"

Noter : le premier caractère a la position 0.

Remove

Enlève des caractères à une certaine position dans une chaine.

 
Sélectionnez
Dim s As String = "VisualBasic"

s = s.Remove(2, 7) 'Donne s= "Viic"

Replace

Remplace dans une chaine de départ, toutes les occurrences d'une chaine par une autre.

Resultat=ChaineDépart.Replace(chaineARemplacer,chaineQuiRemplace)

 
Sélectionnez
Dim s As String= "Visual_Basic"

s= s.Replace("_"," " ) 'Donne s= "Visual  Basic"

Autre exemple

L'utilisateur a tapé une date, mais avec comme séparateur des ".", comme on le verra plus loin, il est nécessaire d'utiliser plutôt les "/", pour cela on utilise Replace

 
Sélectionnez
Dim ladate as string= "12.02.1990"

ladate= ladate.Replace(".","/" ) 'Donne ladate= "12/02/1990"

Split

Découpe en plusieurs sous chaines une chaine de départ, cela par rapport à un séparateur.

Exemple

Je récupère dans un fichier une chaine de mots ayant pour séparateur ";", je veux mettre chaque mot dans un tableau.

chaine contenant les mots séparés par ";"

 
Sélectionnez
Dim s As String= "Philippe;Jean ;Toto"  

Dim separateur As Char = ";"

Dim nom() As String

nom=s.Split(separateur)

Donne :

 
Sélectionnez
      nom(0)= "Philippe"

      nom(1)= "Jean"

      nom(2)= "Toto"

Remarque : quand on déclare le tableau nom(), on ne donne pas le nombre d'éléments, c'est Split qui crée autant d'éléments qu'il faut.

En Framework 2, on peut utiliser plusieurs séparateurs différents :

 
Sélectionnez
nom=s.Split( New Char() {" "c, ","c, "."c }) 'ici on a 3 séparateurs: l'espace, la virgule et le point.

le ci-après chaque séparateur veut dire Char, car les séparateurs sont des caractères.

On peut ajouter 2 paramètres permettant d'indiquer le nombre de lignes maximum et forcer l'élimination des lignes vides.

 
Sélectionnez
Dim sep() As Char={" "c, ","c, "."c}

Dim nom() As String = S.Split ( sep, 100, StringSplitOptions.RemoveEmptyEntries )

Allons encore plus loin: avant et après le séparateur, il peut y avoir des espaces.

Il faut dans ce cas utiliser la méthode Split de la classe Regex :

 
Sélectionnez
Imports System.Text.RegularExpressions

Dim S As String = "abc ; def ; ghi"

' On crée un Regex

Dim R As New Regex("\s*;\s*")

' décomposition de ligne en champs

Dim Nom As String() = R.Split(S)

.Join

Concatène tous les éléments d'un tableau et peut ajouter des séparateurs.

Si myLines() est un tableau de String, je veux ajouter ces lignes bout à bout en les séparant d'un retour à la ligne.

 
Sélectionnez
Dim myText As String = String.Join ( ControlChars.CrLf, myLines)

.IndexOf .LastIndexOf

Indique le numéro du caractère, la position (la première occurrence) ou une chaine à chercher est trouvée dans une autre. Recherche en commençant par la fin avec LastIndexOf.

 
Sélectionnez
Dim a As String= "LDF.EXE"

Dim r As Char()={"."}

a.IndexOf(r)  retourne 3

Se souvenir : le premier caractère est en position 0 en .Net.

.LastIndexOf retourne la dernière occurrence.

.IndexOfAny .LastIndexOfAny (Framework 2)

Indique le numéro du caractère, la position (la première occurrence) ou une chaine à chercher est trouvée dans une autre avec en plus possibilité d'indiquer la position de départ.

 
Sélectionnez
Dim a As String= "LDF.EXE"

Dim r As Char()={"."}

a.IndexOfAny(r)  recherche à partir du début de chaine.

a.IndexOfAny(r,2)  recherche à partir du deuxième caractère.

Autre exemple: On recherche ici plusieurs caractères (en fait un tableau de Char)

 
Sélectionnez
Dim str As String ="gfdjzak;,vdqsygeak"

Dim start As Integer =2

Dim at As Integer 

Dim count As Integer =5

Dim target As String = "ou" 'chaine à chercher 

Dim anyOf As Char() = target.ToCharArray() 'on transforme la chaine en tableau de char 

at = str.IndexOfAny(anyOf, start, count) 
'on cherche le tableau de Char anyOf dans str à partir de la position start et sur count caractères.

.Compare

Compare 2 chaines :

 
Sélectionnez
Dim rep As Integer

rep=String.Compare(a,b)

Retourne un entier.

 
Sélectionnez
      -1 si a<b

      0 si a=b

      1 si a>b

On peut comparer des sous-chaines et indiquer la sensibilité à la casse (Framework 2) :

 
Sélectionnez
Dim myStr1 As [String] = "My Uncle Bill"
Dim myStr2 As [String] = "My uncle bill"
Dim r As Integer = String.Compare(myStr1, 2, myStr2, 2, 10, StringComparison.CurrentCultureIgnoreCase)

Ici on compare 10 caractères en commençant par le deuxième caractère de chaque chaine en mode insensible à la casse (majuscules=minuscules).
Voir ci-dessous, le chapitre comparaison.

.Equals

Permet de comparer 2 chaines. Retourne True si elles sont égales.

 
Sélectionnez
Dim b As Booleen= String.Equals("aaa", "AAA")
'b=False

On peut ajouter un paramètre pour signifier la culture ou indiquer de ne pas tenir compte de la case comme ici :

 
Sélectionnez
Dim b As Booleen= String.Equals("aaa", "AAA", StringComparison.CurrentCultureIgnoreCase)
'b=True

.Contains

Permet de savoir si une chaine apparait dans une autre: (Framework 2)

 
Sélectionnez
Dim trouve As Boolean

trouve = a.Contains( "123")

Retourne True ou False

.Substring

Extrait une partie d'une chaine.

Le premier paramètre indique la position de départ; le second, le nombre de caractères à extraire.

 
Sélectionnez
Dim a As String= "Informatique"

MessageBox.show(a.Substring(2,3)) 'Affiche  for

Le premier paramètre indique la position du caractère où doit commencer la sous-chaine, en commençant à la position 0. (les caractères sont comptés 0, 1, 2, 3….

Le second paramètre la longueur de la sous-chaine.

Exercice 1: comment obtenir les 4 caractères de droite :

 
Sélectionnez
Dim a As String= "Informatique"

MessageBox.show(a.Substring(A.Length-4)) 'Affiche  ique

Ici on omet le second paramètre,la longueur de la sous-chaine, va jusqu'a la fin de la chaine.

Exercice 2 : comment obtenir les 3 caractères de gauche :

 
Sélectionnez
Dim a As String= "Informatique"

MessageBox.show(a.Substring(0, 3)) 'Affiche  inf

.Chars

Une chaine peut être perçue comme un tableau de caractères (instances Char) ; vous pouvez extraire un caractère particulier en faisant référence à l'index de ce caractère par l'intermédiaire de la propriété Chars. Par exemple :

 
Sélectionnez
Dim maString As String = "ABCDE"
Dim monChar As Char
monChar = maString.Chars(3) ' monChar = "D"

On peut créer des chaines avec la Classe String :

 
Sélectionnez
myString = New String(" ", 15)    'Créer une chaine de 15 espaces

.PadRight

Aligne les caractères de cette chaine à gauche et remplit à droite en ajoutant un caractère Unicode spécifié pour une longueur totale spécifiée.

 
Sélectionnez
Dim str As String
Dim pad As Char
str = "Nom"
pad = Convert.ToChar(".") 
Console.WriteLine(str.PadRight(15, pad)) ' Affiche Nom………………

PadLeft fait l'inverse.

.StartsWith() et EndsWith()

Permettent de tester si une string commence ou se termine par une string, retourne True ou False.

Tester si la String s commence par "abc" et se termine par "xyz" :

 
Sélectionnez
If s.StartWith ("abc") And s.EndWith ("xyz") Then

En VB 2005, on peut ajouter un argument gérant la culture ou la casse.

Voir aussi String.Format dans le chapitre : Afficher correctement du texte.

.IsNull , IsNullOrEmpty() Framework 2

Il est parfois nécessaire de vérifier si une chaine est égale à Nothing ou de longueur égale à 0 (vide).

 
Sélectionnez
If S Is Nothing AndOr S.length=0 Then

Ou

 
Sélectionnez
If String.IsNullOrEmpty( S) Then

À partir de vb 2010 existe aussi String.IsNullOrWhiteSpace qui est égal à True si la chaine est Null Empty ou ne contient que des espaces :

 
Sélectionnez
If String.IsNullOrWhiteSpace(value) Then'Est équivalent à (mais plus rapide): 
If String.IsNullOrEmpty(value) OrElse value.Trim().Length = 0 Then.

V-E-1-b. Les instructions 'Visual Basic'

CONSEIL: Si vous débutez, laissez de coté ces instructions Visual Basic: elles font double emploi avec la classe String, elles ne sont pas toujours cohérentes avec le reste et cela embrouille.

Utilisez donc uniquement la classe String.

Les instructions VB, elles, sont bien connues des 'anciens' et font partie intégrante de VisualBasic; elles sont parfois plus simples. Mais elles ne fonctionnent pas comme des Objets, mais comme des instructions.

Elles font partie de l'espace de noms 'Microsoft.VisualBasic', il est 'chargé' par défaut et il n'y a pas lieu de l'importer. Par contre quand certains 'mots' sont communs à plusieurs classes ou instructions, il peut y avoir ambiguïté et il faut utiliser dans ce cas la syntaxe complète (avec l'espace de nom). Cela semble le cas pour left qui est un mot-clé Vb, mais aussi une propriété des contrôles. Pour lever l'ambiguïté, il faut écrire Microsoft.VisualBasic.left(C,i) par exemple.

Ces méthodes font souvent double emploi avec les méthodes de la classe String.

Attention : le premier caractère est en position 1 dans les instructions VB.

Mid

Permet de récupérer une sous-chaine.

 
Sélectionnez
MaString = "Mid Demonstration" 
a = Mid(MaString, 1, 3) ' Retourne "Mid".

Retourne 3 caractères à partir du premier

Le premier paramètre indique la position du caractère où doit commencer la sous-chaine, en commençant à la position 1. (les caractères sont comptés 1, 2, 3…; on rappelle qu'avec SubString la sous-chaine, commence à la position 0.

 
Sélectionnez
a = Mid(MaString, 14)

Retourne "tion": du 14e à la fin (pas de 3e argument)

Mid permet aussi de remplacer une string dans une string

 
Sélectionnez
Mid(MaString, 1, 3) = "Fin"

=> MaString="Fin Demonstration"

Left, Right (Pas d'équivalent dans le Framework)

Retourne x caractères de gauche ou de droite :

 
Sélectionnez
a=Right(MaString,2)

a="on"

 
Sélectionnez
a=Microsoft.VisualBasic.Left(MaString,2)

a="Mi"

Notez bien que, pour lever toute ambiguïté avec les méthodes 'Left' d'autres classes, il faut indiquer Microsoft.VisualBasic.Left.

Len

Retourne la longueur de la chaine:

 
Sélectionnez
MyLen = Len(MaString)

Retourne 17.

LTrim, RTrim

Enlève les espaces à gauche ou à droite d'une chaine.

 
Sélectionnez
    a=LTrim("  RRRR")

a="RRR"

InStr

Retourne un entier spécifiant la position de début de la première chaine à l'intérieur d'une autre.

 
Sélectionnez
n=InStr(1,"aaaaRaa","R")        'retourne 5

Recherche à partir du premier caractère, à quelle position se trouve 'R' dans la chaine "aaaaRaa"

Si la chaine n'est pas trouvée, retourne 0.

InStrRev

Recherche aussi une chaine, mais de droite à gauche. La position de départ est le 3e argument.

InStrRev (Ch1, Ch2 , PosDépart)

StrComp Compare 2 chaines.

Space

Retourne une chaine d'espace: Space(10) retourne " "

StrDup

Retourne une chaine de caractères par duplication d'un caractère dont on a spécifié le nombre.

 
Sélectionnez
maString = StrDup(5, "P") ' Retourne "PPPPP"

Asc

Retourne le code de caractère du caractère. Il peut être compris entre 0 et 255 pour les valeurs du jeu de caractères codés sur un octet (SBCS) et entre -32 768 et 32 767 pour les valeurs du jeu de caractères codés sur deux octets (DBCS). La valeur retournée dépend de la page de codes.

AscW retourne le code Unicode du caractère entré. Il peut être compris entre 0 et 65 535.

 
Sélectionnez
    x=Asc("A")

retourne 65

 
Sélectionnez
x=Asc("ABCD")

retourne 65 : seul le premier caractère est pris en compte.

Chr et ChrW

Retourne le caractère associé au code de caractère.

 
Sélectionnez
Chr(65)

retourne "A" 'cela dépend de la page de code.

On peut donner le numéro du caractère en hexadécimal, dans ce cas on le fait précéder de &H

 
Sélectionnez
Chr(&H20)

est équivalent de Chr(32) et retourne un caractère " ".

ChrW retourne le caractère correspondant à l'Unicode.

GetChar

Retourne le caractère d'une chaine à une position donnée.

 
Sélectionnez
Dim maString As String = "AIDE"
Dim monChar As Char
monChar = GetChar(maString, 3) ' monChar = "D"

LCase Ucase

Retourne la chaine en minuscules ou majuscules :

 
Sélectionnez
Lowercase = LCase(UpperCase)

Lset Rset

Retourne une chaine alignée à gauche avec un nombre de caractères.

 
Sélectionnez
Dim maString As String = "gauche"
Dim r As String
r = LSet(maString, 2) ' Retourne "ga" 

Si la chaine de départ est plus courte que la longueur spécifiée, des espaces sont ajoutés.
r = LSet(maString, 8) ' Retourne "gauche  "

StrRevers

Retourne une chaine ou les caractères ont été inversés :

 
Sélectionnez
Dim maString As String = "STRESSED"

Dim revString As String

revString = StrReverse(maString)    ' Retourne "DESSERTS"

Marrant l'exemple !

Filter (VB2005)

Passe les Strings d'un tableau dans un autre tableau, si elles contiennent ou non une chaine.

 
Sélectionnez
TableauResultat= Filter( TableauChaine, Match, Include, Compare)

Match: chaine à chercher.

Include: Filtre sur la présence ou non de la chaine à chercher.

Compare en binaire ou en texte (majuscules = minuscules dans ce cas)

 
Sélectionnez
Dim TestStrings(2) As String
TestStrings(0) = "Ici"
TestStrings(1) = "Si"
TestStrings(2) = "si"
Dim subStrings() As String    'chaine des résultats

subStrings = Filter(TestStrings, "i", True, CompareMethod.Text)
'Retourne "Ici","Si","si"

subStrings = Filter(TestStrings, "si", True, CompareMethod.Binary)
' Retourne "si".

subStrings = Filter(TestStrings, "si", False, CompareMethod.Binary)
'Retourne "Ici","Si"

Like

Instruction hyper puissante: Like, elle compare une chaine String avec un modèle (Pattern), elle permet de voir si la chaine contient ou ne contient pas un ou des caractères, ou une plage de caractères. (c'est l'équivalent des expressions régulières du Framework)
UTILISER PLUTÔT le REGEX.

result = String Like Pattern

Si string correspond à pattern, la valeur de result est True ; s'il n'y a aucune correspondance, la valeur de result est False. Si string et pattern sont une chaine vide, le résultat est True. Sinon, si string ou pattern est une chaine vide, le résultat est False.

L'intérêt de Like est que l'on peut y mettre des caractères génériques:

? veut dire tout caractère unique.

* veut dire * ou plusieurs caractères.

# veut dire tout chiffre.

[caractères] veut dire tout caractère présent dans la liste.

[!caractères] veut dire tout caractère NON présent dans la liste.

- trait d'union permet de spécifier un début et une fin de plage.

Exemple :

 
Sélectionnez
Dim R As Boolean
R = "D" Like "D" ' Est-ce que "D" est égal à "D"? => True.


R = "F" Like "f" ' Est-ce que "F" est égal à "f"? => False.


R = "F" Like "FFF" ' Est-ce que "F" est égal à "FFF"? => False.


R = "cBBBc" Like "c*c" ' Est-ce que "cBBBc" répond au pattern (avoir un "c" au 
'début, un  "c" à la fin, et des caractères au milieu? Retourne True.


R = "J" Like "[A-Z]" ' Est-ce que "J" est contenu dans les caractères allant de
'  A à Z? Retourne True.


R = "I" Like "[!A-Z]" ' Est-ce que "I" n'est PAS dans les caractères allant de
'  A à Z? Retourne  False.


R = "a4a" Like "a#a" ' Est-ce que "a4a" commence et finit par un
' "a" et à un nombre entre les 2? Retourne True.


R = "bM6f" Like "b[L-P]#[!c-e]" ' Est-ce que "bM6f" 

'commence par  "b",

'a des caractères entre L et P

'un nombre

'se termine par un caractère non compris entre c et e

'retourne True

V-E-1-c. Un exemple

Combinaison de chaines de caractères, de variables.

Souvent, on a besoin d'afficher une combinaison de chaines littérales, le contenu de variables, des résultats de calcul, c'est possible.

Exemple

Pour afficher dans un label 'Le carré de X est X2', avec une valeur dans la variable x :

 
Sélectionnez
Dim X As Integer = 2

Label1.Text= "Le carré de " & X & "  est " & X * X

Ce qui est entre guillemets est affiché tel quel. C'est le cas de "Le carré de" et de "est"

Ce qui n'est pas entre guillemets est évalué, le résultat est affiché. C'est le cas de X et X*X

Pour ne faire qu'une chaine on ajoute les bouts de chaines avec l'opérateur '&'.

Notez l'usage d'espace en fin de chaine pour que les mots et les chiffres ne se touchent pas.

 
Sélectionnez
Dim X As Integer

X=2

Label1.Text= "Le carré de " & X & "  est " & X * X

Affiche dans le label: "Le carré de 2 est 4".

V-E-1-d. Comparaison de caractères (Option Compare)

On peut comparer 2 String avec :

 
Sélectionnez
les instructions '=', '>', '<':
 
Sélectionnez
Dim s1 As String ="ABCD"

Dim s2 As String ="XYZ"

Dans ce cas s1<s2 est vraie.

Car par défaut Option Compare Binary

Les caractères sont classés dans un ordre croissant (l'ordre de leur code Unicode).

Voyons l'ordre des certains caractères particuliers :

" " +,-./ 0123456789 :;ABCDEF abcdef èéê

On constate que l'ordre est espace puis quelques caractères spéciaux, les chiffres, les majuscules puis les minuscules, les accentués (voir le tableau d'Unicode).

Ainsi B<a

En utilisant Option Compare Binary, la plage [A-E] correspond à A, B, C, D et E.

Avec Option Compare Text

Les caractères sont classés dans un ordre qui reflète plus la réalité d'un texte :

Tous les types de a: A, a, À, à, puis tous les types de b: B, b…

Avec Option Compare Text, [A-E] correspond à A, a, À, à, B, b, C, c, D, d, E et e. La plage ne correspond pas à Ê ou ê parce que les caractères accentués viennent après les caractères non accentués dans l'ordre de tri.

Ainsi B>a

L'ordre des caractères est donc défini par Option Compare et aussi les paramètres régionaux du système sur lequel s'exécute le code.

On peut modifier Option Compare soit dans les propriétés de l'application (Menu 'Projet' puis 'Propriétés de ' puis onglet 'Compiler') ou dans un module en ajoutant en haut 'option Compare Text'.

Grandes règles de comparaison

La comparaison s'effectue de gauche à droite.

La comparaison s'effectue sur le premier caractère de chaque chaine.

Si le premier caractère est identique, la comparaison se fait sur le deuxième caractère…

"zz" > "za" est vrai

En cas de chaine du type "zz" et "zzz" , la seconde est supérieure.

"zz" < "zzz" est vrai.

Il y a quelques pièges.

Si je veux créer des chaines du genre 'un nombre puis le mot string' et qu'elles soient classées dans un ordre logique pour l'humain.

Je vais taper: "1string", "2string", "10string", "11string", "100string"

Le classement par Vb sera 'surprenant', car les chaines seront classées dans cet ordre :

"100string", "10string", "11string", "1string","2string"

Pourquoi? c'est l'application stricte des règles de comparaison: regardons le troisième caractère des 2 premières chaines (les 2 premiers caractères étant égaux), "0" est bien inférieur à "s" donc "100string" < "10string" est vrai !!

Pour résoudre le problème et obtenir un classement correct, il faut écrire des blocs numériques de même longueur et alignés à droite:

Écrire 010string et non 10string.

"001string", "002string", "010string", "011string", "100string" ' ici le tri est dans le bon ordre.

V-E-1-e. Comparaison avec Equals et String.Compare

Equals retourne un Boolean égal à True si les 2 chaines sont égales.

Cette méthode effectue une comparaison ordinale respectant la casse (majuscules et minuscules ne sont pas égales) et non spécifique à la culture.

 
Sélectionnez
Dim myStr1 As [String] = "My Uncle Bill"
Dim myStr2 As [String] = "My uncle bill"
Dim r A Boolean= myStr1.Equals(MyStr2)

'Autre syntaxe:
Dim r A Boolean= String.Equals(MyStr1, MyStr2)

'Avec la première syntaxe, on peut ajouter des options de comparaison :
Dim r A Boolean= myStr1.Equals(MyStr2, CurrentCultureIgnoreCase)

String.Compare compare 2 chaines et retourne un Integer qui prend la valeur :
0 si les 2 chaines sont égales.
inférieur à 0 si string1 est inférieur à string2.
supérieur à 0 si string1 est supérieur à string2.

 
Sélectionnez
Dim myStr1 As [String] = "My Uncle Bill"
 Dim myStr2 As [String] = "My uncle bill"
        Dim r As Integer = String.Compare(myStr1, myStr2)
        MessageBox.Show(r.ToString)

Par défaut la culture en cours est utilisée et la comparaison est comme avec Option Compare=Binary: le code Unicode est utilisé.

 
Sélectionnez
'Affiche 1, car "A"<"a"
 MessageBox.Show(String.Compare("A", "a").ToString)

On peut ajouter des options de comparaison : IgnoreCase, IgnoreSymbol, IgnoreNonSpace, IgnoreWidth, IgnoreKanaType et StringSort.

 
Sélectionnez
Dim myStr1 As [String] = "My Uncle Bill"
 Dim myStr2 As [String] = "My uncle bill"
        Dim r As Integer = String.Compare(myStr1, myStr2, ignoreCase:=True)
        MessageBox.Show(r.ToString)

'Autre syntaxe: on a 2 options
Dim r As Integer = String.Compare(myStr1, myStr2, CompareOptions.IgnoreCase And CompareOptions.IgnoreSymbol)

On peut même comparer dans une autre culture :

 
Sélectionnez
Dim myComp As CompareInfo = CultureInfo.InvariantCulture.CompareInfo
Dim r As Integer= myComp.Compare(myStr1, myStr2))

Ici on compare 10 caractères en commençant par le deuxième caractère de chaque chaine en mode insensible à la casse (majuscules=minuscules).
Les options font partie de l'énumération StringComparison et pas de CompareOptions comme plus haut.

 
Sélectionnez
Dim myStr1 As [String] = "My Uncle Bill"
Dim myStr2 As [String] = "My uncle bill"
Dim r As Integer = String.Compare(myStr1, 2, myStr2, 2, 10, StringComparison.CurrentCultureIgnoreCase)

V-E-1-f. Unicode

Les variables 'String' sont stockées sous la forme de séquences de 16 bits (2 octets) non signés dont les valeurs sont comprises entre 0 et 65 535. Chaque nombre représente un caractère Unicode. Une chaine peut contenir jusqu'à 2 milliards de caractères.

L'Unicode est donc un codage de caractères sur 16 bits qui contient tous les caractères d'usage courant dans les langues principales du monde.

Les premiers 128 codes (0-127) Unicode correspondent aux lettres et aux symboles du clavier américain standard. Ce sont les mêmes que ceux définis par le jeu de caractères ASCII (ancien codage sur un octet). Les 128 codes suivants (128-255) représentent les caractères spéciaux, tels que les lettres de l'alphabet latin, les accents, les symboles monétaires et les fractions. Les codes restants sont utilisés pour des symboles, y compris les caractères textuels mondiaux, les signes diacritiques, ainsi que les symboles mathématiques et techniques.

Voici les 255 premiers :

Image non disponible

Le petit carré indique un caractère non imprimable (non affichable), certains caractères sont des caractères de contrôle comme le numéro 9 qui correspondant à tabulation, le numéro 13 qui correspond au retour à la ligne…

V-E-2. Variables 'Char'

Les variables Char contiennent un caractère et un seul, un caractère est stocké sous la forme d'un nombre de 16 bits (2 octets) non signé dont les valeurs sont comprises entre 0 et 65 535. Chaque nombre représente un seul caractère Unicode. Pour les conversions entre le type Char et les types numériques, il y a les fonctions AscW et ChrW qui peuvent être utilisées…

L'ajout du caractère 'c' à un littéral de chaine force ce dernier à être un type Char. À utiliser surtout si Option Strict (qui force à être strict…) est activé.

Exemple:

 
Sélectionnez
Option Strict On
'…
Dim C As Char
C = "A"c

'Autre manière de faire:
C=CChar("A")
'On convertit la String "A" en Char

Après déclaration une variable Char contient '' c'est-à-dire un caractère vide.

String.ToCharArray: Permet de passer une string dans un tableau de Char :

 
Sélectionnez
Dim maString As String = "abcdefghijklmnop"
Dim maArray As Char() = maString.ToCharArray

La variable maArray contient à présent un tableau composé de Char, chacun représentant un caractère de maString.

Pour mettre le tableau de Char dans une String :

 
Sélectionnez
Dim maNewString As String (maArray)
 
String.Chars():

vous pouvez extraire un caractère particulier en faisant référence à l'index de ce caractère par l'intermédiaire de la propriété Chars. Par exemple :

 
Sélectionnez
Dim maString As String = "ABCDE"

Dim monChar As Char

monChar = maString.Chars(3) ' monChar = "D"

Un caractère est-il numérique ? un chiffre ? une lettre ? un séparateur ? un espace ?

 
Sélectionnez
    Dim chA As Char
        chA = "A"c
        Dim ch1 As Char
        ch1 = "1"c
        Dim str As String
        str = "test string"

        Console.WriteLine(chA.CompareTo("B"c))          ' Output: "-1" '  A est plus petit que B
        Console.WriteLine(chA.Equals("A"c))             ' Output: "True" ' Egal?
        Console.WriteLine(Char.GetNumericValue(ch1))    ' Output: 1     'Convertir en valeur numérique (double)
        Console.WriteLine(Char.IsControl(Chr(9)))       ' Output: "True"'  Est une caractère de contrôle?
        Console.WriteLine(Char.IsDigit(ch1))            ' Output: "True"'  Est un chiffre
        Console.WriteLine(Char.IsLetter(","c))          ' Output: "False"' Est une lettre
        Console.WriteLine(Char.IsLower("u"c))           ' Output: "True" ' Est en minuscules
        Console.WriteLine(Char.IsNumber(ch1))           ' Output: "True" ' Est un nombre
        Console.WriteLine(Char.IsPunctuation("."c))     ' Output: "True" ' Est un caractère de ponctuation
        Console.WriteLine(Char.IsSeparator(str, 4))     ' Output: "True" ' Est un séparateur
        Console.WriteLine(Char.IsSymbol("+"c))          ' Output: "True" ' Est un symbole
        Console.WriteLine(Char.IsWhiteSpace(str, 4))    ' Output: "True" ' Est un espace
        Console.WriteLine(Char.ToLower("M"c))           ' Output: "m"     ' Passe en minuscules

Existe aussi IsLetterOrDigit, IsUpper.

Bien sûr, si 'Option Strict= On', il faut ajouter .ToString à chaque ligne :

 
Sélectionnez
Console.WriteLine(Char.ToLower("M"c).ToString)

On note que l'on peut tester un caractère dans une chaine : Char.IsWhiteSpace(str, 4)

Autre manière de tester chaque caractère d'une String :

 
Sélectionnez
Dim V as string

For Each C As Char in V    'Pour chaque caractère de V…

      C…

Next

Ici la String est considérée comme une collection de Char. (C'est aussi une collection de String)

Mais on verra plus loin les collections et les boucles For Each.

Conversions Char <->Unicode

On rappelle que l'Unicode est le mode de codage interne des caractères.

 
Sélectionnez
Dim monUnicode As Short = Convert.ToInt16 ("B"c) ' le code Unicode  de B est 66.
Dim monChar As Char = Convert.ToChar (66) '   monChar="B"

Pour savoir si un caractère a un code Unicode précis il y a 2 méthodes :

if MyChar=Convert.ToChar(27) then…

ou

if AscW(MyChar)=27 then…

Si vous souhaitez utiliser Asc et Chr de VisualBasic :

 
Sélectionnez
Dim monAscii As Short = Asc("B") 'Asc donne le code ASCII ou l'Unicode (Ascw fait de même ?)
Dim monChar As Char= Chr(66) 'Char retourne le caractère qui a le code ASCII donné.

V-E-3. Et les chaines de longueur fixe

Débutant s'abstenir.

On a vu que les chaines de longueur fixe n'existent pas en VB.NET (compatibilité avec les autres langages oblige), ET ON S'EN PASSE TRÈS BIEN, mais il y a moyen de contourner le problème si nécessaire.

On peut créer une chaine d'une longueur déterminée (comme paramètres pour appeler une API par exemple) par :

 
Sélectionnez
Dim Buffer As String
Buffer = New String(CChar(" "), 25)
'appel
UserName = Left(Buffer, InStr(Buffer, Chr(0)) - 1) 'on lit jusqu'au caractère 
'chr(0) qui est en interne le dernier caractère de la chaine

On peut aussi utiliser la Classe de compatibilité VB6: à éviter++

(Il faut charger dans les références du projet Microsoft.VisualBasic.Compatibility et Compatibility Data)

 
Sélectionnez
Dim MaChaineFixe As New VB6.FixedLengthString(100)

'pour l'initialiser en même temps:
Dim MaChaineFixe As New VB6.FixedLengthString(100, "hello")

Pour afficher la chaine fixe, utilisez MaChaineFixe.ToString.

Mais pour mettre une chaine dans cette chaine de longueur fixe!! galère pour trouver!!!

MaChaineFixe.Value="ghg"

Enfin ce type de chaine fixe ne peut pas être utilisé dans les structures, mais il y a un autre moyen pour les structures. On verra cela plus loin.

Donc les chaines fixes sont à éviter.

V-E-4. Regex, expressions régulières

Débutant s'abstenir.

Les expressions régulières sont une manière de rechercher (de remplacer, d'extraire) une sous-chaine ou un modèle d'une chaine de caractères.

On a un modèle, on veut voir si une chaine contient des parties répondant à ce modèle. Simplement pour voir ou pour séparer des sous-chaines, remplacer…

Exemple: une chaine ne contient-elle que les lettres 'abc', commence-t-elle par 'hello' ou 'HELLO', est-elle une adresse mail valide, un code postal valide? Comment découper une chaine ayant comme séparateur des chiffres? Comment remplacer tous les caractères 'wxyz' par des '-'?….

V-E-4-a. Principe du regex

Les Regex servent à :
- vérifier la syntaxe d'une chaine de caractères ;
- remplacer une partie de la chaine par une autre chaine ;
- découper une chaine de caractères ;
-extraire certaines sous-chaines.

Pour expliquer le principe, on va comparer une chaine String avec un modèle, un 'Pattern', nommé 'REGEX'.

Cela permet de vérifier la syntaxe d'une chaine de caractères. La chaine de caractères à examiner respecte-t-elle un motif (le Regex) décrivant la syntaxe attendue ?

Nécessite l'import d'un espace de noms en haut du module :

 
Sélectionnez
Imports System.Text.RegularExpressions

Premier exemple très simple: Voir si une String ne contient que des chiffres.

Il faut dans un premier temps instancier un Regex contenant le motif. Comme exemple nous allons utiliser un motif permettant de voir si la String contient uniquement des chiffres :

 
Sélectionnez
Dim rg As New Regex("[0-9]")

Notez que le motif est entre guillemets. Le motif [0-9] signifie: tous les caractères entre 0 et 9.
Ensuite on va utiliser la propriété IsMatch du Regex rg pour voir si la String à vérifier ("4545896245" ici comme exemple) répond au motif. Elle retourne True si la String répond au motif.

 
Sélectionnez
rg.IsMatch("4545896245")  'retourne True, car il n'y a que des chiffres.

Pour afficher :

 
Sélectionnez
MsgBox(rg.IsMatch("45gdGRj1"))  'Affiche False dans une Box

Second exemple pas simple: Voir si une String contient une adresse mail valide.

Il faut dans un premier temps instancier un Regex contenant le motif. Comme exemple nous allons utiliser un motif permettant de voir si une adresse mail est valide :

 
Sélectionnez
Dim rg As New Regex("^([\w]+)@([\w]+)\.([\w]+)$")

Bonjour le motif !!!!
Ensuite on va utiliser la propriété IsMatch du Regex pour voir si la String à vérifier répond au motif. Elle retourne True si la String a bien la syntaxe d'une adresse mail.

 
Sélectionnez
MsgBox(rg.IsMatch("philippe@lasserrelyon.fr")) 'affiche True

C'est donc extrêmement puissant !! mais on l'a compris tout l'art est d'écrire le motif !!

V-E-4-b. Caractères pour modèle regex

Principaux caractères composant les motifs :

hello veut dire le texte 'hello'
\ Caractère d'échappement: \. veut dire un point
^ Début de ligne
$ Fin de ligne
. N'importe quel caractère
| Alternative: toto|lulu veut dire toto ou lulu
( ) Groupement
-Intervalle de caractères: a-c veut dire a b ou c
[ ] Ensemble de caractères
[^] Tout sauf un ensemble de caractères

Après le caractère ou un groupe de caractères, on peut indiquer le nombre de caractères :
+ 1 fois ou plus
? 0 ou 1 fois
* 0 fois ou plus
{x} x fois exactement
{x,} x fois au moins
{x, y} x fois minimum, y maximum

Il y a aussi des métacaractères :

\s Caractère d'espacement (espace, tabulation, saut de page, etc)
\S Tout ce qui n'est pas un espacement
\d Un chiffre
\D Tout sauf un chiffre
\w Un caractère alphanumérique
\W Tout sauf un caractère alphanumérique
\r retour chariot

Il y a plein d'autres caractères et métacaractères…

V-E-4-c. Exemples

Petits exemples

[\.] contient un point car "." ne signifie pas 'n'importe quel caractère
il y a un caractère d'échappement avant.
^z$ contient uniquement z (entre début et fin).
es$ finit par "es"
^.$ contient un seul caractère (entre début et fin)
^(i|A) commence par i ou A
^((b)|(er)) commence par b ou er
^[a-c] commence par a,b ou c
[a-zA-Z] caractères en majuscules ou minuscules
[A-Z]+ un mot en majuscules
[A-Z]{1,7} un mot en majuscules de 1 à 7 caractères
[0-9] contient un chiffre
[^0-9] tous sauf un chiffre
\d+ entier positif
[+-]?d+ entier positif ou négatif , le signe + ou - est facultatif
^[^y] ne commence pas par y
^(o)+ commence par un ou plusieurs o
^(a)* peut ou non commencer par a
a{2,4} deux, trois ou quatre fois "a"
[12\^] chaine contenant les chiffres 1 ou 2 ou le symbole ^
^[0-9]+-[0-9]+$ 2 nombres séparés par un tiret: 55-4589 4586-85
[aeiou]\d Une voyelle et un chiffre: a2 i5
\d+ des chiffres (un ou plusieurs)

Validité de différent nom:
^[pP]hilip(pe)?$ True si philip Philip philippe Philippe

Validité d'une adresse ip :
^(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3}$

V-E-4-d. Divers utilisations de Regex

Validation d'une chaine de caractères : IsMatch

 
Sélectionnez
Funtion  SiValideMail (Adresse As String) As Boolean

Dim rg As New Regex("^([\w]+)@([\w]+)\.([\w]+)$")
Return rg.IsMatch(Adresse) 

End Function

Retourne True si la chaine envoyée à la fonction est une adresse mail valide.

Remplacement dans une chaine de caractères : Replace

 
Sélectionnez
Funtion  Remplace (Chaine As String) As String

Dim rg As New Regex("hello|salut|buenas dias")
Return rg.Replace(Chaine, "bonjour") 

End Function

Retourne une chaine où hello, salut, buenas dias ont été remplacés par bonjour…

Découpage d'une chaine de caractères : Split.

Split permet de découper une chaine de caractères et de la mettre dans un tableau en utilisant l'expression régulière comme séparateur.

 
Sélectionnez
Dim ch As String ="az45er78ty"

Dim rg As New Regex("\d+")
Dim t() As String= rg.Split(ch)

ch ="az45er78ty"', retourne t(1)="az" t(2)="er" t(3)="ty"
Retourne un tableau de chaines découpées à partir de ch avec comme séparateur les chiffres (séparateur : 1 ou plusieurs chiffres).

Extraire des chaines de caractères : Matches.

Matches permet d'extraire les séquences de caractères correspondant à un motif. Retourne une MatchCollection qui a une propriété Count indiquant le nombre d'éléments retournés. Cette MatchCollection en lecture seule est composée de 'Match' qui ont les propriétés 'Value' (chaine retournée) 'Index' (position: numéro caractère) et 'Length'.

On va extraire les chaines de 2 caractères (caractères de a à z, pas les ',').

 
Sélectionnez
Dim ch As String ="az,er,ty"

Dim rg As New Regex("[a-z]{2}")
Dim mac As MatchCollection = rg.Matches(ch)

For Each m As Match In mac 
 MsgBox( m.Value &" en position " & m.Index)
Next

Extraire des mots d'une chaine: Matches.

Matches permet d'extraire les séquences de lettres donc des mots. Retourne une MatchCollection qui a une propriété Count indiquant le nombre d'éléments retournés.

Le motif pourrait être [A-Za-z]+, mais il y a des problèmes avec les accentués qui ne font pas partie de a-z!! il faut utiliser le motif: (\p{Lu}|\p{Ll})+ (Explication: \p{LU}: caractères Unicode majuscules, \p{Ll}: caractères Unicode minuscules).

 
Sélectionnez
Dim ch As String ="Ceci est un cours vb"

Dim rg As New Regex("(\p{Lu}|\p{Ll})+")
Dim mac As MatchCollection = rg.Matches(ch)

For Each m As Match In mac 
 MsgBox( m.Value &" en position " & m.Index)
Next

Le motif "\b(?!(le|un|une|et|de|la)\b)(\p{Lu}|\p{Ll})+" permet en plus d'éliminer les un, une, le, la…

Méthodes statiques

On peut utiliser une autre syntaxe (pour Replace, Match, Matches) avec une méthode statique (sans instanciation du regex):

 
Sélectionnez
Funtion  Remplace (Chaine As String) As String

Return Regex.Replace("salut", "bonjour") 

End Function

Options

Les méthodes statiques ou non peuvent avoir un ou plusieurs arguments optionnels (les séparer par 'Or') :
RegexOptions.IgnoreCase : ignore la case oui, oui…
RegexOptions.IgnorePatternWhitespace : ignore l'espace la tabulation, nouvelle ligne
RegexOptions.Compiled : accélère, car compile le regex.
RegexOptions.MultiLine : applique les caractères de début et fin à chaque ligne.

 
Sélectionnez
Funtion  Remplace (Chaine As String) As String

Return Regex.Replace("salut", "bonjour" , RegexOptions.IgnoreCase Or RegexOptions.Compiled) 

End Function

ou en instanciant le regex :

 
Sélectionnez
Dim rg As New Regex("salut", RegexOptions.IgnoreCase Or RegexOptions.Compiled)

On pourrait écrire des livres sur les expressions régulières !!! Pour trouver des motifs, voir : des centaines de chaines de motif toutes faites.

V-E-5. StringBuilder

Débutant s'abstenir.

Les opérations sur les Strings peuvent être accélérées, il faut pour cela utiliser les StringBuilder.

Exemple d'une opération coûteuse en temps :

 
Sélectionnez
Dim s As String = "bonjour"
     
s += "mon" + "ami"

Le Framework va créer 3 chaines en mémoire avec toutes les pertes en mémoire et en temps que cela implique. (il crée une chaine "bonjour" puis il crée une chaine "bonjour mon" puis…
On dit que le type String est immutable.
Pour l'exemple précédent, cela ralentit peu, mais dans une boucle qui concatène 10 000 chaines !!

Pour effectuer des opérations répétées sur les string, le framework dispose donc d'une classe spécialement conçue et optimisée pour ça : System.Text.StringBuilder.

Pour l'utiliser, rien de plus simple :

 
Sélectionnez
Dim sb As new System.Text.StringBuilder()

    sb.Append("bonjour")

    sb.Append("mon ami")

    Dim s As String

    s = sb.ToString()

Il y a création et utilisation d'une seule chaine : sb La méthode ToString de la classe StringBuilder renvoie la chaine qu'utilise en interne l'instance de StringBuilder.

Pour comparer 2 StringBuilder utiliser la méthode Equals plutôt que =.

À partir de vb 2010 il existe StringBuilder.Clear.

V-F. Variables numériques

Image non disponible 4815162342

Une variable numérique peut contenir des données numériques.

On a vu qu'une variable numérique peut être entière :

  • Integer (entier signé) ;
  • Short (entier court signé) ;
  • Long (Entier long signé) ;
  • Byte (entier non signé de valeur 0 à 255).

À partir de VB2005 il y a aussi :

  • UInteger (entier non signé) ;
  • UShort (entier court non signé) ;
  • ULong (Entier long non signé) ;
  • SByte (entier signé).

Une variable numérique peut aussi être un fractionnaire :

  • Single (virgule flottante simple précision) ;
  • Double (virgule flottante double précision) ;
  • Decimal (virgule fixe haute précision).

À partir de vb 2010 il y a en plus :

  • BigInteger ( Entier signé très grand (sans limite supérieure ou inférieure) (VB2010) ) ;
  • Complex (Nombre complexe).

On déclare une variable numérique avec Dim.

 
Sélectionnez
Dim i As Integer

Après déclaration une variable numérique contient 0.

on peut initialiser en même temps qu'on déclare :

 
Sélectionnez
Dim i As Integer= 3

Si la variable est numérique, il faut la transformer en String avant de l'afficher :

 
Sélectionnez
Dim I As Integer=12

Label.Text = I.ToString

.ToString fait partie des méthodes de la classe String. Il y en a d'autres :

.GetType retourne le type de la variable

 
Sélectionnez
Dim i As Integer
i=3 ' Il faut initialiser i avant d'utiliser GetType

Label1.Text = i.GetType.ToString  'Affiche: System.Int32

.MaxValue .MinValue donne le plus grand et le plus petit nombre possible dans le type de la variable.

On verra qu'on peut utiliser des opérateurs + - * / .

 
Sélectionnez
Dim I As Integer=2

Dim J As Integer

J=I+3 ' J est égal à 5, car on affecte à J la valeur I+3

On rappelle que le séparateur est le point :

J=1.2 veut dire J=1,2 en bon français !!

de même pour Str et Val du VisualBasic.

Par contre pour les instructions du Framework (CType, TryCaste, Cint…), le séparateur est celui de la culture (',' en culture française, '.' en culture us).

V-F-1. La Classe Math du Framework

Pour qu'elle soit disponible, il faut d'abord importer l'espace de noms 'Math' du FrameWork :

Pour cela il faut taper en haut de la fenêtre (au-dessus de public Class) :

 
Sélectionnez
Imports System.Math

Si on n'a pas importé l'espace de nom, il faut ajouter Math. avant le nom de la fonction. Exemple :

 
Sélectionnez
R=Math.Abs(N)

On verra plus loin ce que cela signifie.

 
Sélectionnez
Dim N As Single

Dim R As Single

 

R=Abs(N)    'retourne la valeur absolue

            'Si N=-1.2  R=1.2

R=Sign(N)   'retourne le signe

            'Si N=-1.2  R=-1 (négatif) ; retourne 1 si nombre positif

 

R=Round(N)  'retourne le nombre entier le plus proche

            ' N=1.7     R=2

            ' N=1.2     R=1

            ' N=1.5     R=2

Pour Round, si nombre <0.5 retourne 0 si > ou = à 0.5 retourne 1; c'est la manière d'arrondir les nombres en Euros, comme sur la feuille d'impôts.

On peut donner en second paramètre le nombre de digits : Math.Round(Valeur, 2)donne 2 décimales après la virgule.

 
Sélectionnez
R=Truncate(N)

Retourne la partie entière (enlève les chiffres après la virgule, arrondie à l'entier le plus proche en allant vers zéro).

'N=1.7 R=1

 
Sélectionnez
R=Floor(N)

Retourne le plus grand entier égal ou inférieur (arrondi à l'entier inférieur le plus proche en allant vers l'infini négatif).

N=1.7 R=1

 
Sélectionnez
R=Ceiling(N)

Retourne le plus petit entier égal ou supérieur. (arrondi à l'entier supérieur le plus proche en allant vers l'infini positif).

N=1.2 R=2

 
Sélectionnez
R=Max(2,3)

Retourne le plus grand des 2 nombres.

Retourne 3

 
Sélectionnez
R=Min(2,3)

Retourne le plus petit des 2 nombres.

Retourne 2

 
Sélectionnez
R=Pow(2,3)

Retourne 2 puissance 3.

Retourne 8

 
Sélectionnez
R=Sqrt(9)

Retourne la racine carrée.

Retourne 3

longResult = Math.BigMul(int1, int2) 'BigMul donne le résultat de la multiplication de 2 entiers sous forme d'un long.

intResult = Math.DivRem(int1, int2, Reste) DivRem donne le résultat (intResult) de la division de int1 par int2 et retourne le reste (Reste), cela pour des entiers.

Il existe aussi Log, Log10, Exp.

Bien sur il y a aussi Sin Cos Tan, Sinh Cosh Tanh (pour hyperbolique) Asin Acos Atan Atan2.

Prenons un exemple :

 
Sélectionnez
Imports System.Math
Dim MonAngle, MaSecant As Double
MonAngle = 1.3 '  angle en  radians.
MaSecant = 1 / Cos(MonAngle) ' Calcul la sécante.

On remarque que les angles sont en radians.

Rappel:2pi=360° ; Angle en radians= (2pi/360)*Angle en degrés.

V-F-2. Les instructions du langage VisualBasic

Int et Fix qui suppriment toutes deux la partie fractionnelle et retournent l'entier.

 
Sélectionnez
Dim R As Single= 1.7

Int(R)    'retourne 1

Si le nombre est négatif, Int retourne le premier entier négatif inférieur ou égal au nombre, alors que Fix retourne le premier entier négatif supérieur ou égal au nombre. Par exemple, Int convertit -8,4 en -9 et Fix convertit -8,4 en -8.

V-F-3. Dépassement de capacité, 'Non Nombre'

Testé en VB2005

On a vu que , codées sur un nombre de bits défini, les variables numériques ne peuvent pas avoir des valeurs très très grandes. MaxValue donne le plus grand nombre possible dans le type de la variable. (MinValue le plus petit nombre) Que se passe-t-il , si on dépasse la valeur maximum ?

  • Si on affecte à une variable entière une valeur supérieure à .MaxValue cela déclenche une erreur (on dit une exception de type OverFlow) et cela plante.
  • Si on affecte à une valeur à virgule flottante(un Single par exemple), une valeur supérieure à .MaxValue, la variable prend la valeur 'infinie' ( +ou - infinie: Single.NegativeInfinity ou Single.PositiveInfinity)).

Exemple

IsInfinity, IsNegativeInfinity, IsPositiveInfinity permettent de tester si le résultat d'un calcul dépasse les valeurs autorisées pour le Type virgule flottante.

 
Sélectionnez
Dim s As Single = 2147483647 ^ 33

If Single.IsInfinity(s) Then MsgBox("infinie")

s prend la valeur Single.PositiveInfinity.

Les opérations en virgule flottante retournent NaN pour signaler que le résultat de l'opération est non défini. Par exemple, le résultat de la division de 0,0 par 0,0 est NaN.

On peut tester une expression par IsNan.

Exemple :

 
Sélectionnez
If Single.IsNaN(0 / 0) Then

V-F-4. Problème de précision

Integer Single ou Decimal ? Précision ou rapidité ?

Vu le système de codage en interne, on a vu qu'avec les variables en virgule flottante, comme les Single par exemple, certaines valeurs ou calculs sont représentés avec une certaine approximation, infime, mais réelle.
Souvent le calcul est exact, mais parfois (rarement en pratique courante) on peut avoir un infime manque de précision. Voici un exemple: on a 0,0001, avec une boucle on l'additionne dix mille fois :

 
Sélectionnez
        Dim i As Integer
        Dim k As Single
        Dim j As Single = 0.0001
       
        For i = 1 To 10000
            k = k + j
        Next
        
        MsgBox(k.ToString)' Affiche 1.000054

        Dim k1 As Decimal
        Dim j1 As Decimal = 0.0001
        
        For i = 1 To 10000
            k1 = k1 + j1
        Next
        
        MsgBox(k1.ToString)' Affiche 1

Avec des Decimal on obtient bien 1, mais avec des Single on obtient 1,000054 !!
Cela peut poser des problèmes si on compare le résultat du calcul avec 1.

Avec les entiers la précision est parfaite.

Dans notre exemple le calcul est DIX fois plus long avec les Decimal qu'avec les Single.

V-F-5. BigInteger

Un BigInteger est un Entier signé très grand (sans limite supérieure ou inférieure).
Il apparait dans vb 2010.

La valeur, en théorie, n'a pas de limites supérieure ou inférieure.

Il faut charger dans les références (passer par propriétés du projet) pour charger System.Numerics puis Importer cet espace.

Instanciation :

 
Sélectionnez
Imports System.Numerics
'Instanciation directe avec new 
Dim MyBitInteger As New BigInteger(17903)
'Si variable avec virgule, la partie après la virgule sera tronquée.

'À partir d'un long
Dim MylongValue As Long = 631548935      
Dim MyBigInteger2 As BigInteger = Mylong

Dim MyBigInteger As BigInteger = CType(64312.65d, BigInteger)

On peut utiliser les opérations mathématiques de base telles que l'addition, la soustraction, la division, la multiplication (+ -* /), la négation et la négation unaire.
Vous pouvez également comparer deux valeurs .Comme les autres types intégraux, BigInteger prend en charge également les opérateurs de bit, de décalage vers la droite et de décalage vers la gauche And, Or et XOr Il existe aussi Add, Divide, Multiply, Negate et Subtract.
Sign, retourne une valeur qui indique le signe d'une valeur BigInteger.
Abs retourne la valeur absolue d'une valeur BigInteger.
DivRem retourne à la fois le quotient et reste d'une opération de division.
GreatestCommonDivisor retourne le plus grand diviseur commun de deux valeurs BigInteger.

Exemple: Creation de 2 BitInteger (2190 Puissance 2 et 42656*35); affichage du plus grand commun diviseur.

 
Sélectionnez
Dim n1 As BigInteger = BigInteger.Pow(2190, 2)
Dim n2 As BigInteger = BigInteger.Multiply(42656, 35)

Console.WriteLine("Le plus grand commun diviseur de {0} et de {1} est {2}.", _
                     n1, n2, BigInteger.GreatestCommonDivisor(n1, n2))

Les calculs avec les BigInteger sont lents (20 fois plus lent qu'avec les Single pour 10 000 additions par exemple).
Comme ce sont des entiers, il ne devrait pas y avoir d'erreur d'arrondi.

V-F-6. Nombre complexe

Les nombres complexes sont une notion mathématique (je les avais étudiés en terminal S il y a quelques années). Ils sont utilisés dans certains calculs en génie électrique.

Un nombre complexe comprend une partie réelle et une partie imaginaire.
Un nombre complexe z s'écrit sous la forme suivante : z = x + yi, où x et y sont des nombres réels, et i est l'unité imaginaire qui a la propriété i2 = -1.
La partie réelle du nombre complexe est représentée par x, et la partie imaginaire du nombre complexe est représentée par y. Un nombre complexe peut être représenté comme un point dans un système de coordonnées à deux dimensions, appelé plan complexe.La partie réelle est positionnée sur l'axe des abscisses (axe horizontal), et la partie imaginaire est positionnée sur l'axe des ordonnées (axe vertical).

Tout point peut également être exprimé, en utilisant le système de coordonnées polaires.
Un point est caractérisé par deux nombres :
- sa grandeur, qui est la distance entre le point et l'origine (autrement dit, 0,0) ; -sa phase, qui est l'angle entre le véritable axe et la ligne tirée entre l'origine et le point.

Image non disponible

En vb x et y (coordonnées cartésiennes) sont des 'Double'.
Les propriétés Real et Imaginary retournent la part réelle et imaginaire du nombre complexe.
La magnitude (d) et la phase (alpha exprimé en radians) sont des 'Double'.
(Pour convertir des degrés en radians, multiplier par Math.Pi/180). Les propriétés Magnitude et Phase retournent d et alpha.

Il faut charger dans les références (passer par propriétés du projet) pour charger System.Numerics puis Importer cet espace.

 
Sélectionnez
Imports System.Numerics

Module Example
   Public Sub Main()
      ' Creationn d'un complexe 11+ 6i .
      Dim c1 As New Complex(11, 6)
      Console.WriteLine(c1) 'Affiche  (11, 6)

      ' Assigne un  Double à un complex .
      Dim c2 As Complex = 3.1416
      Console.WriteLine(c2) 'Affiche  (3.1416, 0)


      ' Assign la valeur retournée .
      Dim c3 As Complex = Complex.One + Complex.One
      Console.WriteLine(c3) 'Affiche  (2, 0)

      ' Instancie un complex à partir des coordonnées polaires.
      Dim c4 As Complex = Complex.FromPolarCoordinates(10, .524)
      Console.WriteLine(c4) 'Affiche  (8.65824721882145, 5.00347430269914)
     
     'Affichage coordonnées cartésiennes
      Console.Write(c4.Real)
      Console.Write(c4.Imaginary)
      'Affichage coordonnées polaires
      Console.WriteLine("   Magnitude: {0}", c4.Magnitude)
      Console.WriteLine("   Phase:     {0} radians", c4.Phase)

   End Sub
End Module

Opérateurs

Les opérations sur les nombres complexes obéissent à des règles mathématiques particulières (voir un cours de maths). Vb connait ces règles.
En plus de quatre opérations arithmétiques fondamentales (+ - / * ou Add, Substrat, Divise, Multiply), vous pouvez élever un nombre complexe à une puissance spécifiée (Pow), rechercher la racine carrée d'un nombre complexe (Sqrt) et obtenir la valeur absolue d'un nombre complexe (Abs).
Vous pouvez obtenir l'inverse (Negate) le Log et les valeurs trigonométriques (Cos, Sin…). Enfin on peut comparer avec Equals et =.

 
Sélectionnez
Dim c4 As New Complex(1, 1)
        Dim c2 As New Complex(2, 2)
        Dim c1 As New Complex
        ' c1 = c4 - c2
        c1 = Complex.Subtract(c4, c2)
        ' ou c1=c4-c2
        Console.Write(c1)

Attention, les valeurs étant des doubles il peut y avoir des problèmes d'arrondis: perte de précision lors de certaines opérations ce qui peut poser des problèmes au cours de comparaisons.

Pour formater une impression de nombre complexe, on peut utiliser ToString ou le ComplexFormatter :

 
Sélectionnez
Dim c1 As Complex = New Complex(12.1, 15.4)
      Console.WriteLine("Formatting with ToString():       " + 
                        c1.ToString())
      Console.WriteLine("Formatting with ToString(format): " + 
                        c1.ToString("N2"))
      Console.WriteLine("Custom formatting with I0:        " + 
                        String.Format(New ComplexFormatter(), "{0:I0}", c1))
      Console.WriteLine("Custom formatting with J3:        " + 
                        String.Format(New ComplexFormatter(), "{0:J3}", c1))
                        ' The example displays the following output:
'    Formatting with ToString():       (12.1, 15.4)
'    Formatting with ToString(format): (12.10, 15.40)
'    Custom formatting with I0:        12 + 15i
'    Custom formatting with J3:        12.100 + 15.400j
'Merci Microsoft pour cet exemple

V-G. Conversion, séparateur décimal

Image non disponible

On a vu qu'on peut afficher les chaines de caractères (des 'String'), par ailleurs, on fait des calculs avec les variables numériques (Integer, Single…).

On a donc besoin sans arrêt de faire des calculs avec des variables numériques et de transformer le résultat en String pour l'afficher et vice versa.

Est-il possible de convertir une variable d'un type à un autre ? OUI !!

On aura donc besoin de savoir transformer des variables de tous types en d'autres types.

V-G-1. Conversion numérique vers String

Quel intérêt de convertir ?

Après avoir effectué un calcul, on veut afficher un résultat numérique.

On ne peut afficher que des Strings (chaine de caractères) dans un label ou un TextBox par exemple.

Aussi, il faut transformer cette valeur numérique en chaine avant de l'afficher, on le fait avec la méthode ".ToString":

 
Sélectionnez
     Dim i As Integer=12        'On déclare une variable I qu'on initialise à 12

     Label.text = i.ToString

La valeur de i est transformée en String puis affectée à la propriété Text du label, ce qui affiche '12'

On verra plus loin qu'on peut ajouter des paramètres.

Il existe aussi Cstr :

 
Sélectionnez
     Dim i As Integer=12        'On déclare une variable I qu'on initialise à 12

     Label.text = CStr(i)

V-G-2. Conversion String vers numérique

À l'inverse une chaine de caractères peut être transformée en numérique.

Par exemple, l'utilisateur doit saisir un nombre, il saisit un nombre dans une boite de saisie (InputBox), mais il tape des caractères au clavier et c'est cette chaine de caractères qui est retournée, il faut la transformer en numérique Integer grâce à CInt.

 
Sélectionnez
Dim s as String

Dim i as Integer

s= InputBox ("Test", "Taper un nombre") 'Saisie dans une InputBox  d'un nombre par l'utilisateur.

's contient maintenant une chaine de caractères, "45" par exemple

i= CInt(S)     'on transforme la chaine s en Integer

On peut aussi utiliser Parse :

 
Sélectionnez
Dim s as String

Dim i as Integer

s= InputBox ("Test", "Taper un nombre") 'Saisie dans une InputBox  d'un nombre par l'utilisateur.

's contient maintenant une chaine de caractères, "45" par exemple

i= Integer.Parse(s)     'on transforme la chaine s en Integer

Bizarre cette syntaxe!! en fait c'est le type Integer qui a une méthode (Parse) qui transforme une chaine en entier.

On peut aussi utiliser, et c'est plus simple, CType pour convertir n'importe quel type en n'importe quel type :

Il suffit de donner à cette fonction la variable à modifier et le type à obtenir.

 
Sélectionnez
Dim i As Integer

Dim s As String= "12"

 i=CType(s,Integer)  ' s est la variable à modifier, Integer est le type à obtenir.

i contient maintenant l'entier 12.

Voilà ces quelques instructions devraient suffire pour un usage courant !! Mais il en existe d'autres.

V-G-3. Tous les modes de conversion

CType pour tout.

CType peut aussi servir à convertir de la même manière un single en double, un Short en Integer…

Il est donc possible de convertir un type de variable en un autre.

Il suffit de donner à cette fonction la variable à modifier et le type à obtenir.

 
Sélectionnez
Dim d As Double = 2.65

 Dim i As Integer

 i=CType(d,Integer)    'conversion d'un Double en entier
 
Sélectionnez
Dim d As Double = 2.65

 Dim s As String

 s=CType(d,String)    'conversion  d'un Double  en String
 
Sélectionnez
Dim d As Integer = 2

 Dim S As Single

 S=CType(d, Single)    'conversion d'un Integer en Single

Pour les forts.

DirectCast fait de même, mais on doit utiliser une variable ByRef.

i=DirectCast(s,Integer) 'S doit être ByRef.

Par contre DirectCast nécessite que le type d'exécution d'une variable objet soit identique au type spécifié.

 
Sélectionnez
' nécessite Option Strict Off.
Dim Q As Object = 2.37   ' crée un objet contenant un double.
Dim K As Integer =CType(Q, Integer)       'Marche

Dim J As Integer = DirectCast(Q, Integer)   ' échoue

DirectCast échoue, car le type d'exécution de Q est Double. CType réussit, car Double peut être converti en Integer, mais DirectCast échoue, car le type d'exécution de Q n'est pas encore Integer.

TryCast à partir de VB 2005 (Framework 2)Image non disponible

TryCast fonctionne comme DirectCast, mais retourne Nothing si la conversion est impossible (et ne plante pas! autrement dit, il ne lève pas d'exceptions).

 
Sélectionnez
Dim chaine As String = TryCast(b, String)
 If IsNothing(chaine) Then

Fonctions spécifiques

CType fait toutes les conversions, mais on peut aussi utiliser des fonctions qui sont spécifiques au type de la variable de retour : le nom de ces fonctions contient le nom du type de la variable de retour.

 
Sélectionnez
CBool()  'Pour convertir en Booléen
CByte()  'Pour convertir en octet
CChar()  'Pour convertir en Char
CDate()  'Pour convertir en Date
CDbl()   'Pour convertir en Double
CDec()   'Pour convertir en Decimal
CInt()   'Pour convertir en Integer
CLng()   'Pour convertir en Long
CObj()   'Pour convertir en Objet
CShort() 'Pour convertir en  Short
CSng()   'Pour convertir en Single
CStr()   'Pour convertir en String
'Et en VB 2005
CSByte()  'Pour convertir en SByte
CUShort() 'Pour convertir en  UShort
CUInt()   'Pour convertir en UInteger
CULng()   'Pour convertir en ULong

Exemple CDbl retourne un 'Double'.

 
Sélectionnez
Dim I As Integer=123

Dim D As Double

D=CDbl(I)    'donnera D=123  D est un Double (réel double précision)

Ces fonctions sont plus rapides, car elles sont spécifiques.

Remarque

Les fonctions CInt et CLng arrondissent les parties décimales égales à 0,5 au nombre pair le plus proche. Par exemple, 0,5 s'arrondit à 0 et 1,5 s'arrondit à 2. Bizarre !!

Val et Str (de MicroSoft.VisualBasic) existe aussi:

Ouf pour les anciens !!

Ces fonctions permettent aussi la conversion String=>Numérique et Numérique=>String

Val donne la valeur numérique d'une expression String.

 
Sélectionnez
Dim i As Integer

i=Val("5")    ' i=5

Val s'arrête au premier caractère non numérique.

Val("12er") retourne 12

Val reconnaît le point (et pas la virgule).

 
Sélectionnez
Dim i As Double

i=Val("5.45")    ' donnera i=5,45

i=Val("5,45")    ' donnera i=5

Str transforme une valeur numérique en String :

 
Sélectionnez
Dim s As String

s=Str(1999)    ' s=" 1999"

Noter bien : Str ajoute un espace à gauche ou le signe'-' si le nombre est négatif.

Str ne reconnaît que le point comme séparateur décimal. Pour utiliser les autres séparateurs internationaux, il faut utiliser la fonction CStr().

La Classe System.Convert

La Classe System.Convert permet la conversion d'un type de base vers un autre:

.ToString en fait partie

Exemple

Pour convertir un Single en Byte (entier 8 bits non signé)

.ToByte

Pour convertir un Byte en Single:

.ToSingle

 
Sélectionnez
singleVal = System.Convert.ToSingle(byteVal)

En Decimal

.ToDecimal

On a des méthodes pour pratiquement convertir tous les types en tous les types. Cherchez !!

On verra plus loin, la fonction Format utilisée pour convertir une valeur numérique en une chaine de caractères généralement destinée à l'affichage en imposant un formatage: vous pouvez mettre un format pour l'affichage des dates, des heures, un format pour les monnaies ou les nombres (nombre de chiffres affichés, séparateur…) Ce n'est pas à proprement parler une conversion, mais plutôt une mise en forme.

 
Sélectionnez
Dim nb As Single = 12.23
MsgBox( Format (nb, "000,000.000")  'Affiche 000 012.230

V-G-4. Pour résumer et faire très simple, retenir

ToString pour les conversions en String des variables numériques(pour afficher).

CType pour convertir tout en tout.

Le fait de convertir d'un type dans un autre s'appelle 'effectuer un cast'

V-G-5. Conversion Explicite et Implicite

À noter que dans cette page, on a étudié la conversion Explicite : elle permet de forcer la conversion vers un type à l'aide de mots-clés. C'est l'option par défaut de VB (pour le voir : menu 'Projet', 'Propriétés de …', Onglet 'Compiler').

Exemple

 
Sélectionnez
Dim d As Double = 2.65

Dim i As Integer

 i=CType(d,Integer)

Il existe aussi la conversion Implicite effectuée automatiquement sans syntaxe particulière et de manière transparente.

VB peut le permettre (Si Option Explicit= Off dans la configuration ).

Exemple :

 
Sélectionnez
Option Explicit Off

Dim d As Double = 2.65

Dim i As Integer

 i=d  'Pour affecter à i, un Integer, le Double d, Vb a transformé le double d en Integer.
 ' Transformation effectuée  automatiquement  et sans qu'on le voie.

On verra que ce mode de travail Implicite n'est pas recommandé.

V-G-6. Conversion restrictive, erreur

Attention, la conversion est dite restrictive si le type final ne peut pas convertir toutes les valeurs possibles du type de départ.

Si je convertis un Single en Integer, la partie décimale peut être tronquée, c'est une conversion restrictive.

L'inverse (conversion Short en Single par exemple) est dite étendue.

V-G-7. Erreur de dépassement de capacité dans les calculs

Voyons le code suivant qui semble correct :

 
Sélectionnez
Dim i As Integer = 1000000000
Dim j As Long
        j = i * 10
        MsgBox(j)

J'ai un grand nombre dans un integer, comme je le multiplie par 10 et que cela risque de dépasser le MaxValue dans Integer, je mets le résultat dans un Long. Pourtant il y a une erreur à l'exécution !!
Explication: quand l'expression j=i*10 est exécutée, l'expression de droite (i*10) est exécutée en premier, comme i est un Integer et '10' aussi, le résultat est mis dans un Integer (c'est là qu'il y a dépassement de capacité) puis casté en Long pour être affecté à J.

Pour éviter cela, il faut travailler directement en Long ou bien écrire 'j=i*10L': le L force 10 a être un Long et le calcul est effectué en Long.

V-G-8. Séparateur décimal : le point, la virgule, Culture

On rappelle aussi que le séparateur d'un littéral est le point (un littéral sert à donner une valeur à une variable) :

 
Sélectionnez
Dim s As Single

s= 456.67

Les fonctions Val (conversion d'une String en numérique) et Str (conversion d'un numérique en String), de Visual Basic, ne reconnaissent que le point (.) comme séparateur décimal.

 
Sélectionnez
Dim s As Single

s=Val ("123.4")    'est accepté, c'est 123,4 en français.

Les fonctions CDbl, CType, CSng ou Parse ainsi que ToString utilisent le séparateur des paramètres locaux de la machine . Ils reconnaissent la culture.

Le symbole de séparateur décimal (ainsi que celui des milliers ) est donc spécifique à la culture.

  • En France, sur votre ordinateur, le séparateur décimal est la virgule.

     
    Sélectionnez
    Dim s As Single
    
    s = CType("123,4", Single)
    
    Console.Out.WriteLine(s.ToString) 'affiche sur la console s transformé en String

    Le symbole de séparateur décimal (ainsi que celui des milliers ) est donc spécifique à la culture.

    Affiche: '123,4'

    Le symbole de séparateur décimal (ainsi que celui des milliers ) est donc spécifique à la culture.

    Par contre s = CType("123.4", Single) est refusé.

    Le symbole de séparateur décimal (ainsi que celui des milliers ) est donc spécifique à la culture.

  • Au Usa le séparateur décimal est le point.
 
Sélectionnez
s = CType("123.4", Single) est accepté

Console.Out.WriteLine(s.ToString)

'Affiche '123.4'

Le symbole de séparateur décimal (ainsi que celui des milliers ) est donc spécifique à la culture.

On remarque donc que ToString utilise aussi le séparateur spécifique à la culture.

 
Sélectionnez
Console.Out.WriteLine(s.ToString)

Affiche: '123,4' en France

Lors de l'utilisation d'autres séparateurs décimaux (applications internationales, par exemple), convertissez la chaine en nombre à l'aide de la fonction CDbl ou CType CSng ou Parse.

Pour voir quel est le séparateur en cours:

Menu Démarrer->Paramètres->Panneau de configuration>Options régionales et linguistiques.

Obtient le séparateur décimal en fonction des paramètres locaux de la machine par du code.

 
Sélectionnez
SeparateurDécimal = NumberFormatInfo.CurrentInfo.NumberDecimaleparator

On peut modifier le CultureInfo

On peut, si on est en CultureInfo Français, afficher en mode Us.

 
Sélectionnez
Dim i As Single = 45.78

' Afficher dans la CultureInfo courante: Français 

Console.WriteLine(i.ToString)    'Affiche 45,78

' Créer un CultureInfo en anglais  U.S.
Dim us As New CultureInfo("en-US")


' Afficher sur la console  en CultureInfo Us.
Console.WriteLine(i.ToString("c", us))    'Affiche 45.78

Il s'agit ici d'une surcharge de ToString , "c" signifie NumberFormatInfo.

V-G-9. IsNumeric

On utilise la fonction IsNumeric pour déterminer si le contenu d'une variable peut être évalué comme un nombre.

Exemples :

 
Sélectionnez
Dim MyVar As Object
Dim R As Boolean

MyVar = "45" 
R = IsNumeric(MyVar) ' R= True.
'…
MyVar = "678.92" 
R = IsNumeric(MyVar) ' R= True.
'…
MyVar = "45 kg"
R = IsNumeric(MyVar) ' R= False.

'Attention le dernier exemple indique que "45 kg" n'est pas purement numérique, mais Val("45 kg") retourne 45 sans déclencher d'erreur, car Val transforme les caractères numériques à partir de la gauche, en s'arrêtant dès qu'il y a un caractère non numérique.

V-G-10. Lexique anglais=>français

To Cast = Mouler, couler.

Type = Type, genre.

To parse = analyser.

V-H. Les 'Tableaux'

Image non disponible

C'est un beau tableau, mais en VB, ce n'est pas ça un tableau !!

Image non disponible

Les tableaux permettent de regrouper des données de même type.

Les tableaux vous permettent de faire référence à un ensemble de variables par le même nom et d'utiliser un numéro, appelé index ou indice, pour les distinguer.

Comment déclarer un tableau :

 
Sélectionnez
Dim Tableau(3) As Integer

déclare un tableau de 4 entiers

On remarque que, dés la déclaration du tableau, le nombre d'éléments est bien défini et restera toujours le même. Après As on indique le type utilisé dans le tableau.

Dim Tableau(3) As Integer entraine la création des variables 'Integer' suivante :

Tableau (0)

Tableau (1)

Tableau (2)

Tableau (3)

Contenu du tableau:

0

0

0

0

soit 4 éléments.

Noter que comme c'est un tableau d'entier, juste après la création du tableau les éléments sont initialisés à 0.

Le tableau commence toujours par l'indice 0.

Le nombre d'éléments dans le tableau est toujours égal à l'indice de dimension + 1 (ou l'indice du dernier élément+1)

Dim Tableau(3) comporte 4 éléments (éléments d'index 0 à 3).

Si j'exécute Tableau(4)=5, cela plante et me donne le message d'erreur suivant:
L'exception System.IndexOutOfRangeException n'a pas été gérée
"L'index se trouve en dehors des limites du tableau."
En effet l'élément Tableau (4) n'existe pas (Le tableau comporte 4 éléments, éléments d'index 0 à 3); l'index 4 est trop grand.
On fait parfois cette erreur quand on utilise une variable comme index dans une boucle par exemple et qu'on a mal calculé la valeur maximum de l'index de boucle.

 
Sélectionnez
Tableau(1)= 12

permet d'affecter le nombre 12 au 2e élément du tableau.

0

12

0

0

 
Sélectionnez
Dim S As Integer
S=Tableau(1)

permet d'affecter à la variable S le 2e élément du tableau.

Un tableau peut avoir plusieurs dimensions :

 
Sélectionnez
Dim T(2,2)     ' 3 X 3 éléments

Pour un tableau à 2 dimensions, le premier argument représente les lignes, le second les colonnes.

Voyons pour chaque élément du tableau le numéro de ligne et celui de la colonne: (pas le contenu des éléments ici, mais leurs index)

élément:0,0

élément:0,1

élément:0,2

élément:1,0

élément:1,1

élément:1,2

élément:2,0

élément:2,1

élément:2,2

Exemple

La première ligne comporte les 3 éléments: T(0,0) T(0,1) et T(0,2)

Pour mettre 33 dans l'élément central :

 
Sélectionnez
Dim T(2,2) As Integer

T(1,1)=33

voyons le contenu du tableau :

0

0

0

0

33

0

0

0

0

Il est possible de créer des tableaux à 3, 4 …dimensions.

Exemple :

 
Sélectionnez
Dim T(3,1,2)

crée un tableau de 4X2X3 éléments.

Image non disponible

On peut créer des tableaux de tableaux :

 
Sélectionnez
Dim T(2),(2)

Il a autant d'éléments que le tableau T (2,2) (mais pour l'accès à un élément, ils fonctionnent plus vite).

Il est possible de créer des tableaux avec tous les types de variables (y compris les structures).

 
Sélectionnez
Dim Mois(11) As String    'tableau de String de 12 éléments

Notez que dans ce cas (après la ligne Dim )les éléments contiennent Nothing, car le tableau contient des String et quand on déclare une String, elle contient Nothing au départ.

On peut initialiser un tableau (Donner une valeur aux éléments).

En effet après déclaration d'un tableau, il contient :

- la valeur 0 si c'est un tableau de numérique ;

- Nothing si c'est un tableau de String ou d'Objet.

 
Sélectionnez
Dim mois(11) As String 

'mois (1) contient Nothing

mois(0)="Janvier"

mois(1)="Février"

mois(2)="Mars"

On peut aussi l'initialiser lors de sa déclaration :

 
Sélectionnez
Dim Mois() As String ={Janvier,Février,Mars}

' Crée un tableau de type String().
Dim winterMonths = {"December", "January", "February"}

' Crée un tableau de type Integer()
Dim numbers = {1, 2, 3, 4, 5}

'Crée un tableau de Double
Dim b = {1, 2, 3.5} 

'Attention création d'un tableau d'OBJECT
Dim d = {1, "123"} 

'Création de tableau à plusieurs dimensions et de tableau de tableau
    Dim e = {{1, 2, 3}, {4, 5, 6}} 'Integer(,)
    Dim f = {({1, 2, 3}), ({4, 5, 6})} 'Integer()() (jagged array)

On remarque ici que le nombre d'éléments n'est pas indiqué, comme on initialise 3 éléments, le tableau en aura 3.
On peut même se passer d'indiquer le type (à partir du deuxième exemple), le compilateur déduit le type à partir des littéraux. On nomme cela l'inférence de type.
À part quand on utilise Linq, je pense qu'il faut mieux indiquer explicitement le type de variable.

Autre syntaxe :

 
Sélectionnez
'Déclaration
Dim t As String()

'On instancie et on initialise
t = New String(1) {"One", "Two"} 
' on affecte au tableau un nouveau tableau de String contenant "One" et "Two"

 
Dim R(,) as Integer ={{0, 1}, {1, 2}, {0, 0}, {2, 3}}

Dans le premier exemple, on fait les choses en deux étapes, on déclare puis on dimensionne (instanciation) et on initialise un tableau 't'. Dans le second exemple, n déclare et on initialise en même temps un tableau à 2 dimensions, remarquez qu'on rentre les éléments 2 à 2.(Equivalent à R(0,0)=0 R(0,1)=1 R(1,0)=1 R(1,1)=2 …)

Redim permet de redimensionner un tableau (modifier le nombre d'éléments d'un tableau existant), si on ajoute Preserve les anciennes valeurs seront conservées (Array.Resize fait de même, voir plus bas).

Attention, on ne peut pas modifier le nombre de dimensions ni le type des données. Un tableau à 2 dimensions de 20 fois 20 string pourra être redimensionné en tableau de 30 fois 30 String, mais pas en tableau d'entiers ou à 3 dimensions.

 
Sélectionnez
Dim T(20,20) As StringRedim Preserve T(30,30)

Il est possible d'écrire Dim T( , ) As String

Dim T( , ) As String 'Sans donner les dimensions du tableau : il est déclaré, mais n'existe pas, car T(1,1)="toto" déclenche une erreur. Il faut avant de l'utiliser écrire Redim T(30,30), (sans remettre As String).

Certaines instructions, comme Split (qui découpe une String pour la mettre dans un tableau), redimensionnent elles-mêmes le tableau au nombre d'éléments nécessaires.

 
Sélectionnez
Dim Nom() as String

Nom=S.Split(Separateur)

Erase efface le tableau et récupère l'espace.

 
Sélectionnez
    Erase Tableau

Erase Tableau (équivalent à tableau= Nothing ).

Clear réinitialise le tableau (remise à 0 d'un tableau de numérique par exemple).

 
Sélectionnez
    Array.Clear(t, 2, 3)

Réinitialisation tableau t à partir de l'élément 1 et pour 3 éléments.

Comment parcourir un tableau?

Pour parcourir un à un tous les éléments d'un tableau, on utilise une boucle:

Exemple: créer un tableau de 11 éléments et mettre 0 dans le premier élément, 1 dans le second, 2 dans le troisième…

 
Sélectionnez
Dim T(10) As Integer

Dim i As Integer

 

For i = 0 To 10    'Pour i allant de 0 à 10

         T(i)=i

Next i

La variable de boucle i est utilisée pour parcourir le tableau: on utilise l'élément T( i ) donc successivement T(1) puis T(2)…et on affecte i donc 1 puis 2 puis 3…

On peut aussi utiliser For Each:( un tableau hérite de la classe System.Array)

 
Sélectionnez
Dim amis() As String = {"pierre", "jean", "jacques", "toto"}

For Each nom As String In amis

    Console.Out.WriteLine(nom)

Next

L'exemple affiche sur la console (menu Affichage->Fenêtre->Sortie) les noms qui sont dans le tableau.

VB alloue de l'espace mémoire pour chaque élément créé. Ne dimensionnez pas un immense tableau si vous avez besoin d'un tableau de 4*4, car cela utilise de la mémoire inutilement.

V-H-1. Un tableau est un objet de type Array

La Classe Array (tableau) a des propriétés et des méthodes que l'on peut utiliser.

Créons 2 tableaux et examinons les principales méthodes.

 
Sélectionnez
Dim a(3) As String

Dim b(3) As String

b=a         'Copie le tableau a dans b

b=a.copy    'Est équivalent

Attention: il copie les références (l'adresse, l'endroit ou se trouve la variable) et non pas la valeur de cette variable, ce qui fait que si vous modifiez b(3), a(3) sera aussi modifié.

Car lorsque vous assignez une variable tableau à une autre, seul le pointeur (l'adresse en mémoire) est copié. Donc en fait a et b sont le même tableau.

Pour obtenir une copie 'indépendante' dans un nouveau tableau faire :

 
Sélectionnez
b=a.clone

Dans ce cas si vous modifié a(2), b(2) ne sera pas modifié.

Par contre a(1)=b(1) n'affecte que l'élément a(1).

Soit un tableau Mois()

Clear

Array.Clear(Mois,0,2) Efface 2 éléments du tableau Mois à partir de l'élément 0.

Reverse

Array.Reverse(Mois, 1, 3) inverse les 3 éléments à partir de l'élément 1.

Copy

Array.Copy(Mois,1,Mois2,1,20) copie 20 éléments de Mois vers Mois2 à partir du 2e élément.

Array.ConstrainedCopy fait la même chose, mais annule tout si la copie n'est pas effectuée intégralement.

De même: mySourceArray.CopyTo(myTargetArray, 6) copie TOUS les éléments de la source dans la destination à partir d'un index dans la destination.

Sort

Array.sort(Mois) Trie le tableau Mois

Malheureusement cette méthode marche sur des tableaux unidimensionnels uniquement.

Au lieu d'utiliser un tableau à 2 dimensions (sur lequel la méthode 'Sort' ne marche pas, on peut ruser et créer 2 tableaux et surcharger la méthode sort pour trier les 2 tableaux (un servant de clé, le second d'items):

Array.Sort(myKeys, myValues) (Voir un exemple plus bas).

Equals compare 2 tableaux.

Binarysearch recherche un élément dans un tableau trié unidimensionnel.(algorithme de comparaison binaire performant sur tableau trié)

Exemple :

 
Sélectionnez
I=Array.BinarySearch(Mois, "Février") 'retourne I=1  se souvenir le premier élément est Mois(0)

BinarySearch effectue une recherche dichotomique : il regarde l'élément du milieu, si l'élément cherché est plus petit, il regarde l'élément du milieu du haut du tableau…

C'est rapide, mais le tableau doit être trié.

S'il trouve un élément, il retourne son index.

Si la recherche échoue, il retourne un nombre négatif, si on effectue un Not sur ce nombre retourné, on a l'index où on doit insérer l'élément.

IndexOf

Recherche un objet spécifié dans un tableau unidimensionnel (trié ou non), retourne l'index de la première occurrence.

 
Sélectionnez
Dim myIndex As Integer = Array.IndexOf(myArray, myString)

Retourne -1 si l'élément n'est pas trouvé.

LastIndexOf fait une recherche à partir de la fin.

Ici la recherche est linéaire : on compare l'élément recherché avec le premier puis le deuxième, puis le troisième élément…C'est long , mais le tableau n'a pas besoin d'être trié.

On a probablement intérêt à trier le tableau et à faire un Binarrysearch (Cela se dit, mais je ne l'ai pas vérifié).

Ubound

Retourne le plus grand indice disponible pour la dimension indiquée d'un tableau.

 
Sélectionnez
Dim Indice, MonTableau(10, 15, 20)
Indice = UBound(MonTableau, 1) ' Retourne 10. (1 indique la première dimension du tableau)

GetUpperBound même fonction.

 
Sélectionnez
Indice = MonTableau.GetUpperBound(0) '( 0 pour première dimension!!) Retourne 10.

Lbound existe (plus petit indice), mais est inutile, car toujours égal à 0.

Length retourne un entier qui représente le nombre d'éléments total dans le tableau.

Pour un tableau à une dimension Length-1 retourne l'indice du dernier élément.

Cela est souvent utilisé pour parcourir tous les éléments du tableau :

 
Sélectionnez
Dim t(10) As String

 Dim i As Integer

 For i = 0 To t.Length-1

   t(i)=Next t

On remarque que dans un tableau multidimension Length n'est pas égale à Ubound.

GetLength(x) retourne un entier qui représente le nombre d'éléments dans la dimension x.

GetValue et SetValue permettent de connaitre ou de modifier la valeur d'un élément du tableau :

Mois.GetValue(0) est équivalent à Mois(0)

Dans un tableau à 2 dimensions, comment modifier l'élément (0,3) :

 
Sélectionnez
myArray.SetValue("fox", 0, 3)

C'est équivalent à myArray(0,3)="ox"

ArraySegment permet de définir un segment, une plage dans une Array.(framework 2).

 
Sélectionnez
Dim myArrSegMid As New ArraySegment(Of String)(myArray, 2, 5) 'ici le segment débute au second élément et contient 5 éléments.

(Si on modifie un élément de myArrSegMid cela modifie myArray, car le segment définit une plage du tableau et non un nouveau tableau).

Sur des tableaux, les actions à effectuer sont principalement:

Rechercher un élément.

Trier le tableau.

Insérer un élément.

Enlever un élément.

On a déjà évoqué cela, mais pour étudier le détail de ces algorithmes voir le chapitre 'Travail sur les tableaux et collections'.

Pour les super pro (débutant passe ton chemin), on peut utiliser des méthodes génériques.

Exemple recherche dans un tableau de Short nommé monTab l'élément 2.

index= Array.indexOf (Of Short)(monTab, 2) est hyper plus rapide que

index= Array.indexOf (monTab, 2), car la première version avec généric est directement optimisée pour les Short.

Il est est de même pour Binarysearch et Sort.

Cela est valable pour les types 'valeur' (peu d'intérêts pour les strings par exemple).

V-H-2. Fonctions avancées sur les tableaux

Débutant s'abstenir

La méthode Resize permet de modifier le nombre d'éléments du tableau sans perdre le contenu :

 
Sélectionnez
Dim array As T(10)
Dim newSize As Integer=2

Array.Resize(array, newSize)

La méthode Reverse permet d'inverser les éléments d'un tableau.

 
Sélectionnez
Dim t(10) As Integer
        t(1) = 2
        Array.Reverse(t)

On peut aussi spécifier l'indice de début et le nombre d'éléments à inverser.

 
Sélectionnez
Dim t(10) As Integer
        t(1) = 2
        Array.Reverse(t, 2, 2)

À partir du Framework 2 les Arrays ont donc de nouvelles méthodes.

  • Exists
  • Le tableau contient-il des éléments qui correspondent aux conditions définies par un prédicat ?
  • TrueForAll
  • Chaque élément dans le tableau correspond-il aux conditions définies par un prédicat ?
  • Find
  • Recherche un élément qui correspond aux conditions définies par le prédicat et retourne la première occurrence.
  • FindLast
  • Idem pour la dernière occurrence.
  • FindAll
  • Récupère tous les éléments qui correspondent aux conditions définies par le prédicat.
  • ConvertAll
  • Chaque élément est passé individuellement à un Converter, et les éléments convertis sont enregistrés dans le nouveau tableau.

La syntaxe est de la forme Array.Find(Tableau, AdresseOf Predicat)

Un Predicat est une Sub qui retourne True si une condition est remplie.

Exemple fourni par Microsoft : on a un tableau contenant le nom d'animaux préhistoriques, le prédicat retourne True si le nom de l'animal se termine par 'saurus'. On veut savoir si la condition est remplie sur la liste au moins une fois (Exists), si tous les éléments remplissent la condition (TrueForAll), quel élément remplit la condition(Find), le premier, le dernier (FindLast), on veut récupérer dans un nouveau tableau tous les éléments qui remplissent la condition.

 
Sélectionnez
  Dim dinosaurs() As String = { "Compsognathus", _
            "Amargasaurus",   "Oviraptor",      "Velociraptor", _
            "Deinonychus",    "Dilophosaurus",  "Gallimimus", _
            "Triceratops" }

        Console.WriteLine()
        For Each dinosaur As String In dinosaurs
            Console.WriteLine(dinosaur)
        Next

        Console.WriteLine(vbLf & _
            "Array.Exists(dinosaurs, AddressOf EndsWithSaurus): {0}", _
            Array.Exists(dinosaurs, AddressOf EndsWithSaurus))

        Console.WriteLine(vbLf & _
            "Array.TrueForAll(dinosaurs, AddressOf EndsWithSaurus: {0}", _
            Array.TrueForAll(dinosaurs, AddressOf EndsWithSaurus))

        Console.WriteLine(vbLf & _
            "Array.Find(dinosaurs, AddressOf EndsWithSaurus): {0}", _
            Array.Find(dinosaurs, AddressOf EndsWithSaurus))

        Console.WriteLine(vbLf & _
            "Array.FindLast(dinosaurs, AddressOf EndsWithSaurus): {0}", _
            Array.FindLast(dinosaurs, AddressOf EndsWithSaurus))

        Console.WriteLine(vbLf & _
            "Array.FindAll(dinosaurs, AddressOf EndsWithSaurus):")
        Dim subArray() As String = _
            Array.FindAll(dinosaurs, AddressOf EndsWithSaurus)

        For Each dinosaur As String In subArray
            Console.WriteLine(dinosaur)
        Next
        
    End Sub

    
    Private Shared Function EndsWithSaurus(ByVal s As String) _
        As Boolean
    'Retourne True si la fin du mot se termine par "saurus"
        If (s.Length > 5) AndAlso _
            (s.Substring(s.Length - 6).ToLower() = "saurus") Then
            Return True
        Else
            Return False
        End If
    End Function

Résultat affiché :

 
Sélectionnez
'Compsognathus
'Amargasaurus
'Oviraptor
'Velociraptor
'Deinonychus
'Dilophosaurus
'Gallimimus
'Triceratops
'
'Array.Exists(dinosaurs, AddressOf EndsWithSaurus): True
'
'Array.TrueForAll(dinosaurs, AddressOf EndsWithSaurus: False
'
'Array.Find(dinosaurs, AddressOf EndsWithSaurus): Amargasaurus
'
'Array.FindLast(dinosaurs, AddressOf EndsWithSaurus): Dilophosaurus
'
'Array.FindAll(dinosaurs, AddressOf EndsWithSaurus):
'Amargasaurus
'Dilophosaurus

Pour Array.ConvertAll, elle retourne un tableau dont chaque élément qui vient d'un premier tableau a été modifié par une fonction.
Ici on va créer une fonction qui mettre en majuscules.

 
Sélectionnez
Private Sub Button1_Click() Handles Button1.Click
        Dim dinosaurs() As String = {"Compsognathus", _
            "Amargasaurus", "Oviraptor", "Velociraptor", _
            "Deinonychus", "Dilophosaurus", "Gallimimus", _
            "Triceratops"}
        Dim dinosaurs2() As String
        
       
        dinosaurs2 = Array.ConvertAll(dinosaurs, New Converter(Of String, String)(AddressOf MettreEnMajuscules))

End Sub

Private Shared Function MettreEnMajuscules(ByVal e As String) _
        As String
        Return e.ToUpper
    End Function

On peut aussi utiliser les expressions lambda multilignes :

 
Sélectionnez
Dim nums() As Integer = {1, 2, 3, 4, 5}

    nums = Array.FindAll(nums, Function(n)

                                   Console.WriteLine("testing " & n)
                                   Return n > 2

                               End Function)

ForEach
Exécute une action spécifiée sur chaque élément du tableau spécifié.
Syntaxe de la forme :
Array.ForEach(MyArray, Action)

Exemple : on a un tableau d'Integer, on veut afficher ces nombres et leurs carrés.
On va créer une sub ShowCarré qui reçoit un Integer et affiche le carré.
Il faut ensuite créer une 'Action', un delegate qui pointe sur la Sub.
Enfin, utiliser Array.ForEach.

 
Sélectionnez
Sub Demo
   Dim nums() = {2, 3, 5, 4}
  'Créer un delegate pour la méthode ShowCarré
    Dim action As New Action(Of Integer)(AddressOf ShowCarré)

    Array.ForEach(nums, action)
    
End Sub    
    

    Private Shared Sub ShowCarré(ByVal val As Integer)
        Console.WriteLine("{0:d} Carré = {1:d}", val, val * val)
    End Sub

On peut utiliser une expression lambda, voir le chapitre plus loin.

 
Sélectionnez
        'Tableau
        Dim nums() = {2, 3, 5, 4}
       
        'Expression lamda multiligne
        'Pour chaque élément du tableau afficher  'nombre: x'
        Array.ForEach(nums, Sub(n)
                                Console.Write("Nombre: ")
                                Console.WriteLine(n)
                            End Sub)
'ou
'Expression lambda simple: affiche la série de nombres
    Array.ForEach(nums, Sub(n) Console.WriteLine(n))

V-H-3. Exemple courant d'utilisation des tableaux

Exemple détaillé

Créer un tableau de 6 éléments, mettre dans chaque élément du tableau le carré de son indice, afficher le contenu du tableau.

Cela montre l'intérêt d'utiliser une boucle pour balayer tous les éléments d'un tableau. Première boucle pour remplir le tableau, seconde boucle pour afficher.(Une boucle For …Next est ici utilisée, on verra cela plus loin.)

 
Sélectionnez
      Dim arr(5) As Integer

      Dim i As Integer

      For i = 0 To arr.GetUpperBound(0)' GetUpperBound(0) retourne 5

         arr(i) = i * i

      Next i

 

     For i = 0 To arr.GetUpperBound(0)

         Console.WriteLine("arr(" & i & ") = " & arr(i))

      Next i

Faire une boucle allant de 0 au dernier élément du tableau (For i=0 to …)

Dans chaque élément du tableau, mettre le carré de son indice (arr(i)=i*i )

Nouvelle boucle pour afficher les noms des différents éléments et leur contenu. (Console.WriteLine() affiche sur la console le nom de l'élément et son contenu)

Le programme génère la sortie suivante :

 
Sélectionnez
arr(0) = 0

arr(1) = 1

arr(2) = 4

arr(3) = 9

arr(4) = 16

arr(5) = 25

Exemple de recherche dans un tableau :

Dans un tableau de String rechercher dans quel élément et à quelle position se trouve la string "MN".

 
Sélectionnez
Dim Tableau() As String = {"ABCDEFG", "HIJKLMNOP"}
Dim AChercher As String = "MN"
Dim i As Integer
Dim position As Integer
For i = 0 To Tableau.Length - 1 'on parcourt chaque élément du tableau
    position = Tableau(i).IndexOf(AChercher) 'dans l'élément  du tableau on cherche la sous-chaine
    If position >= 0 Then Exit For
Next i

Exemple de tri de 2 tableaux :

On crée un tableau de clés et un tableau des valeurs, à chaque clé est liée une valeur.

On trie à partir du tableau des clés myKeys , le tableau myValues est modifié pour 'suivre' le tri des clés. La Sub PrintKeysAndValues affiche les résultats.

 
Sélectionnez
Public Shared Sub Main()

' ****************Création des tableaux.
'Tableau des clé
Dim myKeys() As String = {"red", "GREEN", "YELLOW", "BLUE", "purple", "black", "orange"} 
'tableau des éléments
Dim myValues() As String = {"strawberries", "PEARS", "LIMES", "BERRIES", "grapes", "olives", "cantaloup"} 

 

'Affichage du tableau non trié

Console.WriteLine("Tableau non trié:")

PrintKeysAndValues(myKeys, myValues)


' Tri les éléments 1 à 3 puis affichage.

Array.Sort(myKeys, myValues, 1, 3)

Console.WriteLine("Après tri d'une partie du tableau:")

PrintKeysAndValues(myKeys, myValues)


    ' Tri la totalité du tableau.

Array.Sort(myKeys, myValues)

Console.WriteLine("Après tri de la totalité du tableau:")

PrintKeysAndValues(myKeys, myValues)

End Sub 'Fin de Main

 

    ' Routine affichant dans la console les clés et valeurs

Public Shared Sub PrintKeysAndValues(ByVal myKeys() As [String], ByVal myValues() As [String])

Dim i As Integer

For i = 0 To myKeys.Length - 1

    Console.WriteLine(" {0,-10}: {1}", myKeys(i), myValues(i))

Next i

Console.WriteLine()

End Sub 'PrintKeysAndValues

Création de tableau avec CreatInstance.

 
Sélectionnez
' Créons un tableau d'entier (Int32) comprenant 5 éléments.
Dim myArray As Array = Array.CreateInstance(GetType(Int32), 5)
Dim i As Integer
For i = myArray.GetLowerBound(0) To myArray.GetUpperBound(0)
    myArray.SetValue(i + 1, i)
Next i

Merci Microsoft pour les exemples.

V-I. Les 'Collections'

Image non disponible
Image non disponible

Une alternative aux tableaux est l'usage de Collection.

Les Collections permettent de regrouper des données. Les collections sont très utilisées dans la programmation 'Objet'.

Une collection fonctionne plutôt comme un groupe d'éléments dans laquelle il est possible d'ajouter ou d'enlever un élément à n'importe quel endroit sans avoir à se préoccuper de la taille de la collection ni où se trouve l'élément.

Le nombre d'éléments n'est pas défini au départ comme dans un tableau. Dans une collection, il n'y a aucun élément au départ, puis il n'y a que les éléments que l'on a ajoutés.

Les éléments sont repérés grâce à un index ou avec une Clé unique.

Les items affichés dans une ListBox donnent une idée concrète de ce qu'est une collection.

V-I-1. Exemple simpliste

Soit la collection Col, au départ elle est vide.

J'ajoute des éléments (ou items) à cette collection.

Col.Add ("Toto")

Voici la collection :

Toto

La collection a maintenant 1 élément (on dit un Item).

Je fais maintenant :

Col.Add("Lulu")

Col.Add("Titi")

Toto

Lulu

Titi

La collection a 3 éléments maintenant, l'élément (on dit Item) 0, 1, 2.

Je fais :

Col.Remove(1) enlève le deuxième élément. (Attention on compte les éléments à partir de l'élément 0).

Toto

Titi

La collection n'a plus que 2 éléments maintenant.

On voit que le nombre d'éléments n'est pas connu à l'avance, il varie en fonction des éléments ajoutés (ou retirés)

Un élément est repéré par son indice.

Col.Item(1) contient "Titi" (le second Item de la collection)

Remarque:

J'ai pris une collection de 'Base 0': le premier élément à l'indice 0, c'est habituel dans les classes du Framework; il existe aussi des collections (celles venant de Visual Basic) de Base 1.

V-I-2. Classification des collections

Il est intéressant de classer les collections par fonction.

Il y a les List, comme dans l'exemple simpliste. On a un Index pour repérer les éléments. (Pas de clé).

Toto

Lulu

Titi

Il y a les Dictionnaires, chaque élément à une clé, on parle de Collection Clé-Valeur. On utilise la clé pour retrouver une valeur.

Image non disponible

Certaines collections combinent List et Dictionnaire, d'autres sont triées automatiquement.

Enfin il y a des collections particulières: les Piles, Queue, HashSet, SortedSet…

Certaines collections peuvent contenir des objets, d'autres des Strings ou des Bytes…

Certaines collections utilisent, elles, les génériques : elles sont faites pour contenir des génériques c'est-à-dire ce que l'on veut. Quand on utilise la Collection, on indique le type.

Du coup la collection est fortement typée : elle ne peut contenir qu'un type de donnée.

Exemple : List(Of String) est une List ne pouvant contenir que des Strings.

Voici les principales collections :

  • Les Listes :ArrayList, List(Of…) VB 2005
  • Les Dictionnaires :HashTable, Dictionnary
  • Les Listes-Dictionnaires :SortedList,DictionnaryList
  • Les Queue et les Queue (Of…)
  • Les Piles: Les Stack et les Stack (Of…)
  • Les Listes chaînées Les LinkedList(Of….) VB 2005
  • Gestion des ensembles: Les HashSet VB 2008
  • Collections travaillant sur les Bits :BitArray, BitVector32
  • Collections triées : SortedList, SortedDictionnary SortedSet du framework 4
  • Autres : ObservableCollection

V-I-3. ArrayList

Fait partie de System.Collections. C’est une Classe .Net. Il faut donc ajouter en haut du module :

 
Sélectionnez
Imports System.Collections

C'est une 'Liste' d'objets, d'Item. La ArrayList est une collection particulière. On peut y mettre des objets : chaines, nombres… rien n'empêche que le premier élément soit un entier, le second une chaine… . Il n'y a pas de clé.

Attention le premier élément, le premier Item, est ici l'élément 0 (l'index va de 0 à count-1) ; c'est du .NET!!

Exemple :

 
Sélectionnez
Dim L As New ArrayList()     'On crée une collection ArrayList

Dim L As ArrayList = ArrayList.Repeat("A", 5) 

'On crée une ArrayList de 5 éléments contenant chacun  "A" (on répète "A")
 

L.Add("Bonjour")             'On ajoute un élément à la collection

MsgBox(L(0))                 'On affiche le premier élément

L.Add() permet d'ajouter un élément, on affiche le premier élément L(0).

On pourra aussi écrire L.Item(0) pour pointer le premier élément, en effet les éléments sont L.Item(0), L.Item(1), L.Item(2)…

 
Sélectionnez
MsgBox(L.Count.ToString)     'On affiche le nombre d'éléments.

Attention c'est le nombre d'éléments. S'il y a 3 éléments dans la ArrayList ce sont les éléments d'index 0,1,2.

 
Sélectionnez
L.Remove("Bonjour")          'On enlève l'élément de la liste qui contient "Bonjour"

L.RemoveAt(0)                'On enlève l'élément 0 de la liste

L.Sort()                     'Trie la collection

L.Clear()                    'Efface tous les éléments

L.Contains (élément)        ' Retourne True si la liste contient élément.

Insert permet d'insérer à un index spécifié :

 
Sélectionnez
L.Insert( position, Ainserrer)

InsertRange insère une ArrayList dans une autre ArrayList.

 
Sélectionnez
L.Containts (élément)  ' Retourne True si la liste contient 'élément'.

Recherche d'un élément dans une collection NON TRIÉE avec IndexOf :

 
Sélectionnez
Dim l As New ArrayList

Dim i As Integer

l.Add("toto")

l.Add("lulu")

i = l.IndexOf("lulu")

MsgBox(i.ToString)    'Affiche 1 qui est l'index de "lulu"

On rappelle qu'il existe aussi LastIndexOf qui démarre par la fin et une surcharge permettant de débuter la recherche à partir d'un indice donné. Comment rechercher "lulu" à partir du 3e élément).

 
Sélectionnez
i = l.IndexOf(3,"lulu")

Recherche d'un élément dans une collection TRIÉE avec BinarySearch :

 
Sélectionnez
Dim l As New ArrayList

Dim i As Integer

l.Add("toto")

l.Add("lulu")

l.Sort()'Il est nécessaire que le tableau soit trié 

i = l.BinarySearch("lulu")

MsgBox(i.ToString) 'affiche 1

Pour parcourir une collection, 3 méthodes :

-Avec l'index de l'item

 
Sélectionnez
For i=0 to L.Count-1

      A=L.Item(i)

Next i

N.B. Comme vu plus haut, on utilise Count pour trouver le nombre d'éléments, aussi la boucle doit balayer de 0 à count-1. Enfin bien se souvenir que A est un Objet, il faudra le convertir pour l'utiliser :

 
Sélectionnez
Dim s As String= CType(A,String)

-Avec For Each

 
Sélectionnez
Dim o As Objet

For Each o in L

      À=o

Next

Attention, A est un objet. De plus on verra que dans une boucle For Each, on ne peut pas modifier la collection.

-Avec l'objet IEnumerator (débutant passe ton chemin)

On crée un objet C de type IEnumerator pour parcourir la collection, cet objet a 3 propriétés :

MoveNext qui avance d'un élément dans la collection. S'il ne peut plus avancer (s'il est déjà après le dernier) il retourne False

Reset qui place l'élément courant au début, avant le premier élément (Comme au départ)

Current désigne l'élément courant.

Exemple montrant la seule manière de faire pour parcourir la collection :

 
Sélectionnez
Dim L As New ListArray

Dim C As IEnumerator= L.GetEnumerator()

While C.MoveNext())

     A=C.Current

End While

Attention, si Option Explicit=On

Les éléments de la ListArray étant des objets, on ne peut pas les affecter à une variable String par exemple, il faut écrire :

 
Sélectionnez
Str = CType(L(0), String)    'on convertit (on cast) l'objet en String.

Remarque :

 
Sélectionnez
L.Add(Nothing)    'est accepté: on ajoute un élément vide

V-I-4. List (Of)

À partir de 2005 on a des collections que l'on peut typer, c'est-à-dire qu'elles ne pourront contenir qu'un type de donnée, que des String, des entiers, des instances de telle classe… On parle de collections génériques. Le terme Of permet de définir le type de la collection.

Nécessite :

 
Sélectionnez
Imports System.Collections.Generic

Créons une liste ne contenant que des 'Decimal'.

 
Sélectionnez
Dim lst As New List (Of Decimal)

Exemple: créons une collection de String List(Of String): Elle est typée, car elle ne peut contenir que des 'String'.

 
Sélectionnez
Dim lst As New List(Of String)

Il s'agit d'une List avec Index.

lst(0) est le premier élément.

ou lst.item(0)

On ajoute une String :

 
Sélectionnez
lst.Add("toto")

Elle devient le dernier élément de la liste.

Comment affecter cet élément à une String ?

 
Sélectionnez
Dim S As String = lst.Item(0)

L'item est bien typé : même avec 'Option Strict=on' pas besoin de CType.

Nombre d'éléments de la list :

 
Sélectionnez
lst.Count

On peut à partir de vb 2010 'remplir' simplement une collection grâce à 'From' :

 
Sélectionnez
Dim names As New List(Of String) From {"Christa", "Brian", "Tim"}

Noter bien le New.

On peut aussi remplir avec un tableau ou ajouter une List par un AddRange :

 
Sélectionnez
Dim input() As String = { "Brachiosaurus", _
                                  "Amargasaurus", _
                                  "Mamenchisaurus" }

Dim Animals As New List(Of String)(input)

'Ajouter une list à une autre liste avec AddRange
Animals.AddRange(2, Animals)

La liste contient-elle "toto"?

 
Sélectionnez
Dim present As Boolean =lst.Contains("toto")

Present = True si la liste contient "toto".

Insérer un élément à une position donnée :

 
Sélectionnez
lst.Insert(2, "lulu")

Supprimer un élément à une position donnée :

 
Sélectionnez
lst.Remove("lulu")    'supprime le premier élément contenant "lulu"
lst.RemoveAt(3)       'supprime le 4e élément
lst.RemoveRange(3,2)  'supprime du 4e élément au 5e élément

Parcourir tous les éléments et les afficher :

 
Sélectionnez
For Each element As String In lst 

    Console.WriteLine(element) 

Next

Rechercher un élément dans la liste :

 
Sélectionnez
lst.IndexOf("lulu") 'retourne l'index de l'élément qui contient "lulu" 

lst.IndexOf("lulu", 2,7) recherche à partir de l'élément 2 et sur 7 éléments.

Il existe aussi LastIndexOf.

Sur une list triée on utilise BinaryScearch, voir ArrayList, c'est pareil.

On peut copier une List ou partie de List dans un tableau :

 
Sélectionnez
'Avec CopyTo
Dim array(14) As String 'tableau
lst.CopyTo(array)       'copier la list dans le tableau
lst.CopyTo(array, 6)    'copier 6 éléments de la list dans le tableau
lst.CopyTo(2, array, 12, 3)  'index de départ dans list, tableau, index de départ dans array, nombre

'Avec GetRange
Dim output() As String = lst.GetRange(2, 3).ToArray()

On voit que List (Of) possède toutes les méthodes des ArrayList, mais en plus il existe des méthodes propres aux collections génériques (à partir du Framework 2) :

  • Exists
  • List contient-il des éléments qui correspondent aux conditions définies par un prédicat ?
  • TrueForAll
  • Chaque élément dans List correspond-il aux conditions définies par un prédicat ?
  • Find
  • Recherche un élément qui correspond aux conditions définies par le prédicat et retourne la première occurrence.
  • FindLast
  • Idem pour la dernière occurrence.
  • FindAll
  • Récupère tous les éléments qui correspondent aux conditions définies par le prédicat.
  • ConvertAll
  • Chaque élément est passé individuellement à un Converter, et les éléments convertis sont enregistrés dans la nouvelle collection.
  • RemoveAll
  • Efface les éléments qui correspondent au Predicat

La syntaxe est de la forme ListeResultat= List.Find(Liste, AdresseOf Predicat)

Un Predicat est une Fonction qui retourne True si une condition est remplie.

Exemples

Exemple 1
Avec FindAll
J'ai une list 'Animals', je veux mettre dans 'listResult' tous les éléments de Animals qui se terminent par 'us'.

On crée une liste (listResult) qui grâce à FindAll se chargera des éléments de Animals qui répondent à une condition :

 
Sélectionnez
'List de String contenant des noms d'animaux
Dim Animals As New List(Of String) From {"Compsognathus", _
            "Amargasaurus", "Oviraptor", "Velociraptor", _
            "Deinonychus", "Dilophosaurus", "Gallimimus", _
            "Triceratops"}
            
Dim listResult As List(Of String) = Animals.FindAll(AddressOf SeTermineParUS)

En argument de FindAll on a l'adresse d'une fonction: ici la fonction 'SeTermineParUS'. Pour chaque élément de Animals si SeTermineParUS retourne True, l'élément correspondant est passé dans listResult.

Voici la fonction de test, le Predicat.

 
Sélectionnez
Private Shared Function SeTermineParUS (ByVal s As String) As Boolean 

If (s.Length > 2) AndAlso  (s.Substring(s.Length - 2).ToLower() = "lu") Then
     Return True 
Else 
    Return False 
End If 

End Function

Exemple 2
Avec ConvertAll on obtient à partir d'une première liste, une seconde liste ou chaque élément à été convertit par une fonction.
Ici on a une liste d'animaux , on va obtenir une seconde liste avec des noms courts (4 caractères).

 
Sélectionnez
'List de String contenant des noms d'animaux
Dim Animals As New List(Of String) From {"Compsognathus", _
            "Amargasaurus", "Oviraptor", "Velociraptor", _
            "Deinonychus", "Dilophosaurus", "Gallimimus", _
            "Triceratops"}
'Seconde list de String
Dim Animals2 As New List(Of String)

'Remplir Animals2 avec tous les éléments de Animals après passage par le converteur RaccourcirNom

Animals2 = Animals.ConvertAll(New Converter(Of String, String)(AddressOf RaccourcirNom))


        'Afficher la seconde list
        For Each dinosaur As String In Animals2
            Console.WriteLine(dinosaur)
        Next

   'Fonction  RaccourcirNom  
    Private Shared Function RaccourcirNom(ByVal x As String) As String
       Return x.Substring(0, 4)
    End Function

Trier une List

Soit une liste (Of String) de noms d'animaux, on veut trier par ordre alphabétique:
On utilise Sort.

 
Sélectionnez
Dim Animals As New List(Of String) From {"Compsognathus", _
            "Amargasaurus", "Oviraptor", "Velociraptor", _
            "Deinonychus", "Dilophosaurus", "Gallimimus", _
            "Triceratops"}

        

        Animals.Sort()

Mais on peut indiquer une Fonction qui va définir la manière de trier : ici je veux trier en fonction de la longueur des String.
Je vais indiquer l'adresse de ma fonction de comparaison comme argument de Sort:

 
Sélectionnez
Dim Animals As New List(Of String) From {"Compsognathus", _
            "Amargasaurus", "Oviraptor", "Velociraptor", _
            "Deinonychus", "Dilophosaurus", "Gallimimus", _
            "Triceratops"}

        

        Animals.Sort(AddressOf CompareByLength)


'Avec la fonction:
 Private Shared Function CompareByLength( _
           ByVal x As String, ByVal y As String) As Integer
                   Return x.Length.CompareTo(y.Length)
End Function

V-I-5. HashTable

C'est un 'Dictionnaire' qui comporte des couples clé-élément, des paires clé-valeur.

Ces couples sont de type Objet-Objet.

Image non disponible

La clé toujours unique permet de retrouver la valeur, La clé ne doit pas être vide non plus.

Créons une Hashtable :

 
Sélectionnez
Dim H As New Hashtable

H.Add(Clé,Valeur) Ajoute un élément.

H.Item(Clé) Retourne l'élément correspondant à une clé.

H.ContainsKey(Clé) Retourne True si la Clé est dans la table.

H.ContainsValues(Valeur) Retourne True si la valeur est dans la table.

H.Clear Efface tous les éléments.

H.Remove(Clé) Supprime l'élément ayant une clé spécifiée.

Les collections H.Values et H.Keys contiennent les valeurs et les clés.

Exemple :

 
Sélectionnez
'  Creation d'une Hashtable.
Dim myHT As New Hashtable()

' Mettre des éléments dans la HashTable
myHT.Add("un", "premier")
myHT.Add("deux", "second")
myHT.Add("trois", "troisième")
myHT.Add("quatre", "quatrième")
 

'Recherche la valeur correspondant à la clé "trois"

myReponse=myHT.Item("trois")     'Retourne "troisième"
 

'Parcourir la HashTable

'Création d'un IDictionaryEnumerator
Dim myEnumerator As IDictionaryEnumerator = myHT.GetEnumerator()

While myEnumerator.MoveNext()

'Afficher clé et valeur
    MsgBox( myEnumerator.Key+ myEnumerator.Value)
End While

Attention on n'utilise pas de numéro d'index, mais uniquement la clé.

En interne, pour chaque élément, la clé est 'hachée' pour créer un code de hashage qui sert à pointer l'élément et sa valeur (voir le chapitre sur l'algorithme), ce procédé accélère la recherche de la valeur à partir de la clé.

V-I-6. Dictionnary (Of)

À partir de VB 2005, il y a cette collection de type Dictionnaire (Clé-Valeur), mais elle utilise les génériques.

La clé doit être unique (pas de doublon de clé).

La récupération d'une valeur à partir de sa clé est très rapide.(Utilisation d'un hachage.)

Of permet de choisir le type de la clé et celui des valeurs.

Créons un Dictionnary avec des clés de type String et des valeurs de type String.

 
Sélectionnez
Dim Dic As New Dictionary(Of String, String)

' Ajout d'élément

 
Sélectionnez
    Dic.Add("txt", "notepad.exe") 

     Dic.Add("bmp", "paint.exe")

Depuis vb 2010 on peut ajouter rapidement des éléments :

 
Sélectionnez
Dim days = New Dictionary(Of Integer, String) From
    {{0, "Sunday"}, {1, "Monday"}}

' Ajout d'élément en vérifiant avant si la clé n'existe pas

 
Sélectionnez
  If Not Dic.ContainsKey("ht") Then

         Dic.Add("ht", "hypertrm.exe")

    End If

' Modifier la valeur correspondant à la clé 'doc'

 
Sélectionnez
Dic("doc") = "winword.exe"

'Parcours du Dictionary (le type de clé/Value est KeyValuePair).

 
Sélectionnez
For Each kvp As KeyValuePair(Of String, String) In Dic

     Console.WriteLine("Key = {0}, Value = {1}",  kvp.Key, kvp.Value) 

Next kvp

' Récupérer une valeur correspondant à une clé

 
Sélectionnez
Dim tt As String = Dic("rtf")

'TryGetValue permet de rechercher une valeur correspondant à une clé, retourne False si la clé n'existe pas (sans déclencher d'erreur).

 
Sélectionnez
Dim value As String = "" 

If Dic.TryGetValue("tif", value) Then

     Console.WriteLine("For key = ""tif"", value = {0}.", value)

 Else

     Console.WriteLine("Key = ""tif"" non trouvée.") 

End If

Dic…ContainsKey("ht") permet aussi de tester si une clé existe.

'Enlever un élément

 
Sélectionnez
Dic.Remove("doc")

V-I-7. SortedList SortedList (Of)et SortedSet

SortedList
Combine List et Dictionnaire avec un tri automatique.

Il permet l'accès aux valeurs par l'intermédiaire des clés associées ou des index.

C'est un hybride de HashTable et de Array.

On ajoute un élément par mySL.Add(Clé,Valeur).

La séquence d'index est basée sur la séquence de tri. Quand un élément est ajouté, il est inséré dans l'ordre de tri adéquat, et l'indexation s'ajuste en conséquence. Le tri est donc automatique.

On peut donc lire une valeur par sa Clé ou son Index

  • Quand la clé d'un élément permet d'accéder à celui-ci à l'aide de la propriété d'indexeur Item, l'élément se comporte comme Hashtable.

     
    Sélectionnez
    mySL.Item(CLE) 'retourne la valeur correspondant à la clé CLE

    On peut donc lire une valeur par sa Clé ou son Index:

  • Quand l'index d'un élément permet d'accéder à celui-ci à l'aide de GetByIndex ou de SetByIndex, l'élément se comporte comme Array (tableau avec un Index).
 
Sélectionnez
mySL.GetKey(3) 'retourne la Clé qui est dans l'élément d'index 3

mySL.GetByIndex(3) 'retourne la valeur qui est dans l'élément d'index 3

On peut donc lire une valeur par sa Clé ou son Index :

SortedList maintient en interne deux tableaux, un tableau pour les clés et un autre pour les valeurs associées.

Index de base 0 : le premier élément est 0.

Exemple :

 
Sélectionnez
Dim mySL As New SortedList()
mySL.Add("1", "Hello")
mySL.Add("2", "World")
mySL.Add("3", "!")


Console.WriteLine(" Count: {0}", mySL.Count)    'Nombre d'éléments
Console.WriteLine(" Capacity: {0}", mySL.Capacity) 
'nombre d'éléments possible,automatique, on n'a pas à s'en occuper.
 

Dim i As Integer
For i = 0 To mySl.Count - 1
    Console.WriteLine( myList.GetKey(i)& myList.GetByIndex(i)) 
     'affiche les éléments de la collection
     ' par index croissant.
Next i

Les SortedList(Of…) sont des SortedList génériques avec Clé et valeur ,triées sur la clé. Ressemble à SortedDictionary, mais occupe moins de mémoire et est moins rapide pour les insertions/suppressions.

Les SortedDictionnary(Of…) sont des collections génériques avec Clé et valeur ,trié sur la clé.

Les SortedSet (Framework 4)
Collections génériques. Un SortedSet maintient un ordre trié à mesure que les éléments sont insérés et supprimés sans que les performances en soient affectées.Les éléments dupliqués ne sont pas autorisés.

Il est possible de créer un comparer qui sera utilisé par le tri.

 
Sélectionnez
Dim mediaFiles1 As SortedSet(Of String) = New SortedSet(Of String)(New ByFileExtension)
 
 'on crée un comparer:
  Public Class ByFileExtension
        Implements IComparer(Of String)
……
End Class

V-I-8. Queue

Collection d'objets de type FIFO (First In, First Out)

Premier arrivé premier servi.

C'est la queue devant un cinéma, le premier arrivé, prend son billet le premier.

Les objets (String, Integer… ) stockés dans Queue sont insérés à une extrémité et supprimés à l'autre.

Le nombre d'éléments de la queue est géré automatiquement.

DeQueue supprime et retourne l'objet de début de liste.

EnQueue ajoute un objet en fin de liste.

Peek retourne l'objet de début sans le supprimer.

Image non disponible
 
Sélectionnez
Dim myQ As New Queue()
myQ.Enqueue("One")
myQ.Enqueue("Two")
myQ.Enqueue("Tree")


Console.WriteLine ( myQ.Count) 'Affiche le nombre d'éléments.
 

Console.WriteLine (myQ.Dequeue())

Affiche le premier sorti en le sortant. "one" dans notre exemple. S'il n'y a plus d'élément cela lève une exception (une erreur) il faut donc gérer l'exception ou contrôler le nombre d'éléments avec la propriété Count.

 
Sélectionnez
If MyQ.Count>0 then

    myQ.DequeueEnd If
 
Sélectionnez
Console.WriteLine (myQ.Peek())

Affiche le premier élément sans l'enlever de la Queue

 
Sélectionnez
myQ.Clear()

Efface tous les éléments de la queue.

Les Queue(Of…) sont des Queue mais avec un généric.

V-I-9. Stack

Collection d'objets de type pile ( ou stack) LIFO (Last In, First Out)

Dernier entré, premier sorti.

Ce type de stack (pile) est très utilisé en interne par les programmes informatiques: on stocke dans une stack les adresses de retour des procédures appelées, au retour on récupère l'adresse du dessus.

Push insère un objet en haut de la pile

Pop enlève et retourne un objet en haut de la pile

Image non disponible

On peut utiliser une pile dans un programme pour gérer le déplacement de l'utilisateur dans un arbre, les éléments en cours sont stockés par Push, pour remonter en chemin inverse, on Pop.

Attention le premier élément est ici l'élément 1 (élément d'index 1 à count)

Exemple :

 
Sélectionnez
Dim MaPile As New Stack()

Dim Str As String

'Ajouter des éléments à la pile

MaPile.Push ("A")

MaPile.Push ("B")

MaPile.Push ("C")

'Récupérer un objet de la pile:

 Srt =MaPile.Pop()

Str est maintenant égal à "C"

Attention, si Option Explicit=On, les éléments de la pile étant des objets, on ne peut pas les affecter à une variable String, il faut écrire:

 
Sélectionnez
Str = CType(MaPile.Pop(), String)    'on convertit (cast) l'objet en String

Si la pile est vide et que l'on 'Pop', une exception non gérée du type 'System.InvalidOperationException' se produit.(une erreur se produit et cela plante!!), là aussi vérifier que MaPile.Count (qui indique le nombre d'éléments dans la pile) n'est pas égale à 0 avant de 'Poper'.

 
Sélectionnez
Mapile.Clear()     'Supprime tous les objets.

Les Stack(Of…) sont des track mais avec un généric.

V-I-10. Les LinkedList (Of)

Ce sont des Listes chainées de générique, chaque élément comportant une propriété Value(qui contient la valeur de l'élément), Next et Previous. À partir d'un élément, on peut connaitre le suivant ou le précédent.

Voir le chapitre sur les algorithmes qui explique la notion de liste chainée.

Schémas d'une liste chainée :

Image non disponible
 
Sélectionnez
Imports System.Collections.Generic 

' Création d'une list. 

Dim words() As String = {"the", "fox", "jumped", "over", "the", "dog"} 

' Création d'une Linkedlist. 

Dim lk As New LinkedList(Of String)(words)

 Ajouter le mot 'today' au début.

 lk.AddFirst("today")

'Effacer le dernier élément.

 lk.RemoveLast()

'Les éléments sont des LinkedListNode, on peut en chercher un avec Find FindFirst, FindLast.

Dim current As LinkedListNode(Of String) = lk.FindLast("the")

 

'À partir de l'élément courant, on peut ajouter avant ou après.

lk.AddAfter(current, "old")  'il y a aussi AddBefore

'À partir de l'élément courant, on peut parcourir la linkedList

Dim element As LinkedListNode(Of String) = current.Previous  'il y a aussi Next

'On peut déplacer un élément

lk.AddBefore(current, element)

'On peut voir le contenu d'un LinkedListNode

current.Value

current.Previous.Value

'on peut voir la valeur du premier ou du dernier élément:

lk.First.Value

lk.Last.Value

'Il existe aussi

Containst, Count

V-I-11. HashSet (Of)

Travailler sur les ensembles.

Il s'agit d'une collection de génériques sans ordre qui contient des éléments uniques. HashSet possède comme toutes les collections Add, Remove et Contains… et fournit plusieurs opérations d'ensembles (notamment l'union, l'intersection et la différence symétrique) ce qui permet de prendre en charge la plupart des opérations mathématiques qui sont généralement réalisées sur des ensembles (sens mathématique du terme).

 
Sélectionnez
Dim hs As New HashSet(Of String)

'Ajout d'éléments:

hs.Add("toto")

hs.Add("lulu")

hs.Add("titi"

La méthode Add renvoie True ou False pour indiquer si elle a fonctionné (s'il n'y avait pas déjà dans la HashSet l'élément que l'on veut ajouter).

 
Sélectionnez
Dim caMarche As Boolean = hs.Add("toto")  'retourne False
 
Sélectionnez
hs.Count 'donne le nombre d'éléments.

On peut effacer un élément :

 
Sélectionnez
hs.Remove("lulu")

On peut effacer sous condition.

Exemple : effacer tous les éléments contenant un "t":

 
Sélectionnez
hs.RemoveWhere( Adress Of Test)

'La fonction Test reçoit chaque string de la table et retourne un booléen qui indique si la condition est remplie ce qui déclenche le Remove.

 
Sélectionnez
Private Shared Function Test(ByVal s As String) As Boolean  

    Return (Instr(s,"t")<>0) 

End Function

On peut ajouter la collection hs2 à hs grâce à UnionWith :

 
Sélectionnez
hs.UnionWith(hs2)

Les éléments doublons (qui existent déjà dans hs) ne sont pas ajoutés.

Cela correspond à un And.

On peut rechercher les éléments communs à hs2 et à hs grâce à IntersectWith :

 
Sélectionnez
hs.IntersectWith(hs2)

hs contient maintenant les éléments qui étaient présents dans hs et hs2

Cela correspond à un Or.

On supprime tous les éléments de hs qui sont aussi contenus dans la collection passée en paramètre (hs2) avec ExceptWith.

 
Sélectionnez
hs.ExceptWith(hs2)

hs contient maintenant les éléments qui n'étaient pas présents dans hs et hs2.

On peut rechercher les éléments contenus dans hs2 et dans hs, mais pas dans les 2 grâce à SymmetricExceptWith :

 
Sélectionnez
hs.SymmetricExceptWith(hs2)

hs contient maintenant les éléments qui étaient présents dans hs ou hs2, mais pas les deux.

On peut rechercher si hs2 est un sous-ensemble de hs grâce à IsSubsetOf :

 
Sélectionnez
Dim b As Boolean= hs.IsSubsetOf(hs2)

b est égal à True si hs est un sous-ensemble de hs2 (tous les éléments de hs sont dans hs2).

Il existe aussi :

IsProperSubstOf qui retourne True si hs est un sous-ensemble de hs2 et si hs différent de hs2 (sous ensemble strict).

On peut rechercher si hs2 est un surensemble de hs grâce à IsSupersetOf :

 
Sélectionnez
Dim b As Boolean= hs.IsSupersetOf(hs2)

b est égal à True si hs est un sur ensemble de hs2 (tous les éléments de hs2 sont dans hs).

Il existe aussi :

IsProperSupersetOf qui retourne True si hs est un sur ensemble de hs2 et si hs est différent de hs2 (sur ensemble strict).

V-I-12. BitArray

Crée une collection de booléens (codés sur un bit). La valeur de chaque élément est True ou False.

 
Sélectionnez
'Creation de BitArray.
Dim myBA As New BitArray(5)    'BitArray de 5 bits

Dim myBA As New BitArray(5, False) 'BitArray de 5 bits à False

Dim myBA() As Boolean = {True, True, False, False, False}
Dim myBA As New BitArray(myBytes) 'on crée un  tableau de Booleans que l'on met dans le BitArray

Le premier élément est l'élément 0.

On peut mettre tous les bits à True avec SetAll :

 
Sélectionnez
myBA.SetAll(True)

' Mettre le dernier Bit à False avec Set.

 
Sélectionnez
myBA.Set(myBA.Count - 1, False)

'Obtenir la valeur du second Bit.

 
Sélectionnez
myBA.Get(1)

myBA(1) ou myBA.Item(1) donnent aussi la valeur du second Bit.

On peut effectuer des opérations logiques entre 2 BitArray (Or, Xor, And Not).

Exemple pour Or :

 
Sélectionnez
myBA1.Or(myBA2)

Count et Length donnent le nombre d'éléments, mais Count est en lecture seule, Length permet, lui, de modifier le nombre d'éléments.

La Collection BitVector32:

Ne permet de travailler que sur 32 bits, mais est plus rapide.

Il faut avoir ajouté: Imports System.Collection.Specialized.

V-I-13. StringCollection

L'espace System.Collections.Specialized fournit ces nouveaux types de collections très spécifiques, elles ne sont faites que pour un seul type.

StringCollection ne peut contenir que des chaines (cela devrait aller plus vite)

 
Sélectionnez
' Créer une StringCollection.
Dim myCol As New StringCollection()

'Créer un tableau de String, l'ajouter( en fin) à la collection.
Dim myArr() As [String] = {"rouge", "vert", "orange", "vert",)
myCol.AddRange(myArr)

'Ajouter un élément à la fin de la collection
myCol.Add("marron")

'Insérer un élément à l'index 3
myCol.Insert(3, "bleue")

'Enlever un élément
myCol.Remove("orange")


' chercher et enlever tous les éléments "vert" 
Dim i As Integer = myCol.IndexOf("vert")
While i > - 1
myCol.RemoveAt(i)
i = myCol.IndexOf("vert")
End While

' La collection contient-elle "jaune"?
If myCol.Contains("jaune") Then' Copie la collection dans un tableau.
Dim myArr2(myCol.Count) As [String]
myCol.CopyTo(myArr2, 0)

' Efface toutes les strings de la Collection.
myCol.Clear()
 

'Afficher la liste des Strings

Dim myEnumerator As System.Collections.IEnumerator = myCol.GetEnumerator()

While myEnumerator.MoveNext()
Console.WriteLine(" {0}", myEnumerator.Current)
End While
'C'est un peu complexe!! on y reviendra.

Attention le premier élément est ici l'élément 0 (l'index va de 0 à count-1), c'est du .NET !!

V-I-14. ObservableCollections, SortedSet(Of T)

Pour mémoire on se souvient qu'il existait un Type Collection en VB6, de Base 1, à oublier.

Par contre, à partir de VB 2008 existent les collections ObservableCollections qui peuvent être 'Bindées' (attachées) à des Objets visuels (comme une List ou une Grid WPF) et qui permettent la mise à jour automatique du contrôle quand on modifie la collection.

Enfin, à partir de VB 2010 existe SortedSet(Of T). Un SortedSet(Of T) maintient un ordre trié à mesure que les éléments sont insérés et supprimés sans que les performances en soient affectées.Les éléments dupliqués ne sont pas autorisés.

V-I-15. Généralisation de la notion de collection

Certains objets ont une liste de données, d'items, Vb les organise en Collections.

Une collection peut donc faire partie des propriétés d'un objet.

Exemple

On verra plus loin qu'un contrôle nommé TextBox peut contenir du texte, ce contrôle à une collection nommée .lines qui contient les lignes de texte (s'il y en a plusieurs)

Si le texte contient 3 lignes, elles seront dans la collection 'lines'.

 
Sélectionnez
Texbox1.lines(0)    'remarquer, ici le premier élément est 0!!

Textbox1.lines(1)

Textbox1.lines(2)

L'indice des éléments va de 0 à count-1

Autres exemples

Les contrôles ListBox possèdent une collection 'Items' dans laquelle sont placés tous les éléments contenus dans la liste. Pour ajouter un élément, on utilise la méthode Add de la collection Items:

 
Sélectionnez
ListBox.Items.Add( )

Un tas d'objets possèdent des collections.

Encore plus: chaque formulaire possède une Collection 'Controls'. Il s'agit d'une collection qui contient tous les contrôles de ce formulaire.

V-I-16. Pourquoi le premier élément est-il 0 ou 1 ?

Le .NET Framework normalise les collections comme étant des collections de base zéro (ArrayList par exemple). Visual Basic fournit des collections de base 1 (Comme Collection qu'il ne faut plus utiliser).

V-I-17. Exemples sur les collections

Créer une ArrayList, une queue, ajouter la queue à la ArrayList, chercher un élément, insérer un élément.

Les collections font partie de l'espace de noms Systeme.Collections

 
Sélectionnez
Imports System.Collections


' Créer une ArrayList.
Dim myAL As New ArrayList()
myAL.Insert(0, "un")
myAL.Insert(1, "deux")

' Créer une Queue.
Dim myQueue As New Queue()
myQueue.Enqueue("trois")
myQueue.Enqueue("quatre")


' Copies la Queue dans ArrayList à l'index 1.
myAL.InsertRange(1, myQueue)


' Chercher "deux" et ajouter "moins de deux" avant .
myAL.Insert(myAL.IndexOf("deux"), "moins de deux")


' Ajouter "!!!" à la fin.
myAL.Insert(myAL.Count, "!!!")

V-I-18. Lexique anglais=>français

Array = tableau, table.

length= longueur.

Key= clé.

Remove (to)= enlever.

Stack= tas.

V-J. Les 'Structures'

En règle générale, une structure est utilisée comme conteneur pour un petit jeu de variables.
Permet de regrouper des données de types différents.

(En Vb6 il y avait les types définis par l'utilisateur, ils sont remplacés par les structures.)

Les structures sont intéressantes quand vous voulez utiliser des variables contenant plusieurs informations de différent type. Les structures sont surtout utilisées dans la programmation non 'objet'(En programmation objet, on utilisera plutôt les Collections).

Exemple

Vous voulez définir une variable contenant une adresse composée d'un numéro, de la rue, de la ville.

Il faut d'abord définir la structure (au niveau Module ou Class, pas dans une procédure).

 
Sélectionnez
Public Structure Adresse

   Dim Numero     As Integer

   Dim Rue        As String

   Dim Ville      As String

End Structure

Puis dans une procédure il faut déclarer la variable :

 
Sélectionnez
Dim MonAdresse As Adresse

La variable MonAdresse est déclarée comme une adresse, elle contient donc :

un numéro qui est dans 'MonAdresse.Numero' ;

un nom de rue qui est dans 'MonAdresse.Rue' ;

un nom de ville qui est dans 'MonAdresse.Ville'.

On pourra enfin l'utiliser :

 
Sélectionnez
MonAdresse.Numero=2

MonAdresse.Rue= "Grande rue"

MonAdresse.Ville= "Lyon"

On peut aussi utiliser le mot-clé With pour ne pas avoir à répéter le nom de la variable (et cela va plus vite).

 
Sélectionnez
With MonAdresse

    .Rue= "Grande rue"

    .Ville= "Lyon"

End With

With est utilisable sur tous les objets.

Il est possible de travailler sur un tableau de structures :

 
Sélectionnez
Dim Adresses(99) as Adresse    'Permet de travailler sur un tableau de 100 adresses

Adresses(33).Rue="Place de la mairie"

On peut utiliser une variable de type structure comme paramètre d'une fonction :

 
Sélectionnez
Sub AfficheAdresse( ByVal  Une Adresse As Adresse)

… Imprimer l'adresse

End sub

Pour imprimer l'adresse 33, on écrira AfficheAdresse ( Adresse(33)).

V-J-1. Tableau dans une structure

Attention quand dans une structure il y a un tableau, il faut l'initialiser:

on veut définir une structure dans laquelle il y a 25 données DriveNumber.

On aurait tendance à écrire :

 
Sélectionnez
Public Type DriveInfo

   DriveNumber(25) As Integer 'FAUX

   DriveType As String

End Type

Mais cela ne fonctionne pas !!

En Visual Basic .NET il y a 2 méthodes pour utiliser un tableau dans une structure :

1-Méthode par initialize

Une structure peut comporter une méthode 'Initialize' qui sera exécutée quand on déclare une variable de type structure.

Ici, on a créé une méthode Initialize qui redimensionne le tableau interne à la structure.

 
Sélectionnez
Public Structure DriveInfo

   Dim DriveNumber() As Short

   'Noter que le nombre d'éléments a disparu.

   Dim DriveType As String

   'maintenant on instance les 25 éléments.

   Public Sub Initialize()

      ReDim DriveNumber(25)

   End Sub

End Structure

Exemple de routine utilisant la structure.

 
Sélectionnez
Function AddDrive(ByRef Number As Short, ByRef DriveLabel As String) As Object

   Dim Drives As DriveInfo

   Drives.Initialize()

   Drives.DriveNumber(0) = 123

   Drives.DriveType = "Fixed"

End Function

2-Autre manière de faire

Après la déclaration de la variable, on 'Redimensionne' le tableau.

 
Sélectionnez
Public Structure DriveInfo

   Dim DriveNumber() As Short

   Dim DriveType As String

End Structure

 

Function AddDrive(ByRef Number As Short, ByRef DriveLabel As String) As Object

   Dim Drives As DriveInfo

   Redim Drives.DriveNumber(25)

   Drives.DriveNumber(3)=12

   Drives.DriveType = "Fixed"

End Function

Si on utilise 100 variables Drives, il faut 'Redim' ou 'Initialize' le tableau pour chaque variable !!

 
Sélectionnez
Dim Drives (100) As DriveInfo

 

For i as Integer =0 to 100

Drives (i).Initialize                    'Dur dur!!

Next i

En plus si Dim Drives (100) est en tête d'un module, il faut mettre la boucle dans une procédure.

V-J-2. Allons plus loin

Une structure hérite de System.ValueType

V-J-2-a. Les structures sont des types 'valeur'

Une variable d'un type structure contient directement les données de la structure, alors qu'une variable d'un type classe contient une référence aux données, ces dernières étant connues sous le nom d'objet.

Cela a de l'importance: si je crée une variable avec une structure, que je copie cette variable dans une seconde, le fait de modifier la première variable ne modifie pas la seconde.

Prenons l'exemple donné par Microsoft :

 
Sélectionnez
Structure Point
   Public x, y As Integer
   Public Sub New(x As Integer, y As Integer)
      Me.x = x
      Me.y = y
   End Sub
End Structure

On définit une structure Point et on définit une méthode 'New' permettant de saisir les valeurs :

'Public Sub New' est un constructeur.

Pour saisir les valeurs de x et y ont peut utiliser :

 
Sélectionnez
Dim a As Point
a.x=10
a.y=10

ou utiliser le constructeur :

 
Sélectionnez
Dim a As New Point(10,10)

En partant de la déclaration ci-dessus, le fragment de code suivant affiche la valeur 10 :

 
Sélectionnez
Dim a = new Point(10, 10)
Dim b = a
a.x = 100
Console.WriteLine(b.x)    'b est donc bien différent de a

L'assignation de a à b crée une copie de la valeur, et b n'est donc pas affecté par l'assignation à a.x. Si, en revanche, Point avait été déclaré comme une classe, la sortie aurait été 100 puisque a et b auraient référencé le même objet.

Enfin, les structures n'étant pas des types 'référence', il est impossible que les valeurs d'un type structure soient nulles ( elles sont égales à 0 après la création).

V-J-2-b. Les structures peuvent contenir plein de choses

On a vu qu'elles peuvent contenir :

- des variables de différent type ;

- des tableaux ;

- des méthodes : on a vu l'exemple de Initialize et de New.

Mais aussi :

- des objets ;

- d'autres structures. ;

- des procédures ;

- des propriétés.

Exemple donné dans l'aide (et modifié par moi)

Débutant : à relire peut-être ultérieurement quand vous saurez utiliser les Classes.

Cet exemple définit une structure Employee contenant une procédure CalculBonus et une propriété Eligible.

 
Sélectionnez
Public Structure Employee
Public FirstName As String
Public LastName As String
' Friend members, accessible partout dans le programme.
Friend EmployeeNumber As Integer
Friend WorkPhone As Long
' Private members, accessible seulement dans la structure.
Private HomePhone As Long
Private Level As Integer
Public Salary As Double
Public Bonus As Double
  ' Procedure .
  Friend Sub CalculateBonus(ByVal Rate As Single)
   Bonus = Salary * CDbl(Rate)
  End Sub
' Property pour retourner l'éligibilité d'un employé.
  Friend ReadOnly Property Eligible() As Boolean
    Get
      Return Level >= 25
    End Get
  End Property
End Structure

Utilisons cette structure :

 
Sélectionnez
Dim ep As Employee    'Déclaration d'une variable Employee

ep.Salary = 100       'On saisit le salaire 

ep.CalculateBonus(20) 'On calcule le bonus

TextBox1.Text = ep.Bonus.ToString    'On affiche le bonus

Cela ressemble aux Classes !! Non ?

V-J-2-c. Portée

Vous pouvez spécifier l'accessibilité de la structure à l'aide des mots-clés : Public, Protected, Friend ou Private ou garder la valeur par défaut, Public. Vous pouvez déclarer chaque membre en spécifiant une accessibilité. Si vous utilisez l'instruction Dim sans mot-clé, l'accessibilité prend la valeur par défaut, Public.

 
Sélectionnez
Private Mastructure

    Public i As IntegerEnd Structute

En conclusion les structures sont maintenant très puissantes et peuvent contenir autant de choses que les Classes , on verra cela plus loin. Mais les structures sont référencées 'par valeur' alors que les Classes le sont 'par référence'.

V-K. Type valeur ou référence

Image non disponible

Résumons la notion très importante de variable 'par valeur' ou 'par référence'.

Un type de données est un type valeur s'il contient des données dans l'espace qui lui est alloué en mémoire. Un type référence contient un pointeur vers un autre emplacement en mémoire contenant les données.(dixit Microsoft)

V-K-1. La variable 'par Valeur'

Contient réellement une valeur.

Prenons pour exemple une variable de type 'Long'.

 
Sélectionnez
Dim L As Long

L= 1456

'L' occupe 8 octets nécessaires pour coder un long, ici L a une valeur de 1456, donc dans ces 8 octets il est codé 1456.

Sont des variables par 'Valeur' :

  • les Integer, les Long les Short ;
  • les Single, Double, Decimal ;
  • les Booleans, Char, Date ;
  • les Structures ;
  • les énumérations.

V-K-2. La variable 'par Référence'

Elles ne contiennent pas la valeur de l'objet, mais son adresse en mémoire, sa référence.

 
Sélectionnez
Dim O As Object

O contient l'adresse de l'objet codée sur 4 octets.

Sont des variables par référence :

  • les objets ;
  • les strings ;
  • les tableaux ;
  • les classes.

V-K-3. Influence sur l'Affectation

Posons le problème.

Travaillons sur A et B, 2 variables ayant la même 'nature'.

A existant déjà, faisonsc :

 
Sélectionnez
Dim B=A

Puis modifions la valeur de A, cela modifie-t-il B ?

Les variables par Valeur ou par Référence ne réagissent pas de la même manière.

Si le type de variable est par valeur (valable pour les entiers, les Long… les structures…), chaque variable ayant sa valeur, B n'est pas modifié.

Si le type de variable est par référence (valable pour les tableaux, les objets, les string…), chaque variable est définie par sa référence (son lieu physique); faire A=B entraine que A et B ont même référence: ils 'pointent' sur le même endroit. Si on modifie A, B est modifié, car il pointe au même endroit.

Voyons des exemples

Même si on affecte une variable par valeur à une autre, les deux variables restent différentes : elles conservent leur propre espace de stockage :

 
Sélectionnez
Dim L As Long

Dim P As Long

L=0

L=P     'on affecte P à L

P=4     'on modifie P

=> L=0 P=4 Modifier P n'a pas modifié L.

Par contre si on affecte une variable par référence à une autre, elle pointe toutes les 2 sur le même endroit mémoire: si j'en modifie une, cela modifie l'autre.

 
Sélectionnez
'Créons une Classe contenant un entier (Exemple à relire quand vous aurez étudié les Classes)

Class Class1
   Public Value As Integer = 0
End Class

Dim C1 As New Class1()
Dim C2 As Class1 =C1    'on crée C2, on affecte C1 à C2
C2.Value = 123          'on modifie C2

=> C1.Value=123 C2.Value=123 Modifier C2 a modifié C1, car elles pointent sur le même endroit mémoire.

V-K-4. Copie d'objet By Ref: exemple des Tableaux

Exemple sur les tableaux qui sont 'Par référence':

 
Sélectionnez
Dim A(3) As String

À(1) = "a"

Dim B(3) As String

B(1) = "b"

B = A

À(1) = "c"

Label1.Text() = B(1)    'Affiche 'c'

Voyons le détail.

B = A

Un tableau est 'par référence' et le fait de faire A=B donne la même adresse mémoire aux 2 tableaux, aussi , modifier l'un modifie l'autre. C'est ce qui se passe dans notre exemple.

Copie élément par élément.

Si on a déclaré 2 tableaux distincts, B(2)= À(2) affecte un élément d'un tableau à un élément d'un autre tableau, cela ne modifie que la valeur d'un élément et n'affecte pas le tableau. Aussi si on veut faire une copie 'indépendante' d'un tableau, il faut le déclarer puis avec une boucle copier chaque élément du tableau dans le nouveau.

B= A.Clone

B= A.Clone copie le tableau A dans B en conservant 2 tableaux distincts. Ensuite, modifier un élément du tableau ne modifie pas l'autre.

V-K-5. Le cas particulier des 'String'.

Elles sont 'Par référence'.

Attention : par contre :

 
Sélectionnez
Dim A As String

À = "a"

Dim B As String

B = "b"

B = A

À = "c"

Label1.Text() = B    'Affiche 'a'

Bien que les Strings soit par référence, B=À affecte simplement la valeur de A à B, si on modifie ultérieurement A, B n'est pas modifié. (Idem pour clone et copy !!) Pour une string qui est 'par référence', il parait donc impossible de la dupliquer, elle se comporte comme une variable par valeur !!

Pourquoi les String sont 'par référence' et se comportent comme si elles étaient 'par valeur'??

L'opérateur d'affectation "=" de deux strings "A=B" a simplement été défini de manière restrictive pour les strings. Les créateurs de vb .net lui ont permis uniquement une copie de la valeur de la string et non de la référence.
Il vaut mieux ne pas permettre l'affectation de la même référence pointant sur le même objet c'est dangereux pour les débutants et cela serait totalement incompatible avec les versions précédentes… Ensuite, parce que la copie de la valeur d'une string dans une autre est une opération extrêmement courante chez les programmeurs. Ce qui n'est pas le cas de l'affectation de la même référence pointant sur le même objet.

On dit que les String sont 'Immutable' (comme System.Nullable ?).

En conclusion, rien de choquant dans le fait qu'un type string se comporte comme un type par valeur : car c'est juste la définition de l'opérateur d'affectation "=" qui a été redéfinie, et c'est tout. Tout ce qui concerne l'implémentation du type string est strictement comme tous les types par référence. (Merci Sabri pour cette explication).

V-K-6. Déclaration avec New ?

En théorie, il faut utiliser New quand on déclare une variable 'par référence'.

Il faut écrire :

 
Sélectionnez
Dim L As Long    'un long est 'par valeur'

Dim F As New Button    'un bouton est un objet 'par référence'

En fait

 
Sélectionnez
Dim L As New Long  'est accepté

Dim O As Object    'est accepté, mais on a une référence vide.

Dim S As String    'est accepté.

Pour les Classes ou les objets graphiques, il faut par contre bien taper New pour créer l'objet :

 
Sélectionnez
Dim F As New Button

Si on tape Dim F As Button on crée une référence vide, mais pas d'objet Button.

V-K-7. Valeur après déclaration

Apres création (avant initialisation) une variable numérique 'par Valeur' contient 0,

 
Sélectionnez
Dim L As Long    'L contient 0

Par contre une String (par référence) qui a été créée par Dim et non initialisée contient 'Nothing'.

 
Sélectionnez
Dim S As String    'S contient Nothing: il ne pointe sur aucun objet.

On peut tester par If IsNothing( O ) then… ou If O Is Nothing

Pour les tableaux, bien que le tableau soit 'par Référence', c'est le type de variable utilisé dans le tableau qui décide de la valeur des éléments après déclaration.

 
Sélectionnez
Dim T(3) As Long    '=>T(0)=0

V-K-8. Comparaison

1-Une variable par Valeur peut être comparée à une autre par "=",

 
Sélectionnez
Dim L As Long=12

Dim P As Long=24

If L=P Then

2-Par contre une variable par référence peut être comparée à une autre par "Is".

 
Sélectionnez
Dim O As Object

Dim Q As Object   

If O Is Q then

NB: pour les String '=' et 'Is' peuvent être utilisés.

3-Equals peut être utilisé pour comparer les 2 types de données :

 
Sélectionnez
Obj1.Equals(Obj2)  'Retourne True si Obj1 et Obj2 ont le même pointeur.

ou

 
Sélectionnez
N1.Equals(N2)    'Retourne True si la valeur de N1= la valeur de N2

Pour les types 'référence', l'égalité est définie comme une égalité d'objets, c'est-à-dire si les références renvoient ou non au même espace mémoire. Pour les types valeur, l'égalité est définie comme une égalité au niveau du bit , autrement dit si la valeur est la même.

V-K-9. IsReference

Il existe une instruction permettant de voir si une variable est de type 'Par référence'.

Cet exemple utilise la fonction IsReference pour vérifier si plusieurs variables font référence à des types référence.

 
Sélectionnez
Dim R as Boolean
Dim MyArray(3) As Boolean
Dim MyString As String
Dim MyObject As Object
Dim MyNumber As Integer

R = IsReference(MyArray) '  R= True. Tableau
R = IsReference(MyString) ' R= True. String
R = IsReference(MyObject) ' R= True. Objet
R = IsReference(MyNumber) ' R= False. Entier

V-L. Variable 'Object' et autre type

Image non disponible

Il existe un autre type de variable: le type 'Object'.

V-L-1. Le Type 'Object'

Parfois on ne sait pas ce que va contenir une variable : un Integer ? Un String ? Un Single ?

Pour résoudre ce problème, on utilise une variable de type 'Object'.

Cela remplace le type 'Variant' de VB6.

 
Sélectionnez
Dim myObjet As Object

Ensuite :

 
Sélectionnez
myObjet=12

est accepté, et myObjet sera considéré comme un type Integer.

 
Sélectionnez
myObjet=12.6

est accepté, et myObjet sera considéré comme un type Single.

 
Sélectionnez
myObjet="Visual Basic"

est accepté aussi, et myObjet sera considéré comme un type String.

Les 3 affectations myObjet= peuvent se suivre sans planter, l'objet contenant successivement un type Integer, Single et String.

On rappelle qu'une variable objet est une variable 'Par référence'.

On peut, suite au dernier exemple, récupérer l'objet et le transformer en String.

 
Sélectionnez
Dim maString As String

maString= CType(myObjet, String)

Comment savoir quel type de variable contient la variable 'Objet' ?

Si on fait myObjet.GetType.ToString cela retourne 'System.String' indiquant que myObjet contient bien une String.

myObjet.GetType.Name retourne 'String'

Pour tester si myObjet est une String, il y a une autre manière avec TypeOf Is :

 
Sélectionnez
If TypeOf myObjet Is String ThenEnd if

Attention, TypeOf Is retourne True aussi pour les Classes d'objet parent.

 
Sélectionnez
Dim monlabel As New Label

If TypeOf monlabel Is Control Then ' est vérifié, car label dérive de control

monlabel est bien un Label, mais c'est aussi un Control. (On verra que tous les objet visuel comme Label dérive de la classe Control).

V-L-1-a. Comment utiliser les propriétés d'un objet ?

Comment utiliser les membres des variables String qui sont dans un objet ?

Exemple : mettre une string dans une variable Objet, connaitre la longueur de la String.

  • - Si Option strict=Off (On force VB à ne pas être trop strict !!! On verra cela plus loin)
 
Sélectionnez
Dim myObjet As New Object

myObjet="VB"

MessageBox.Show(myObjet.length)  'affiche 2
  • - Si Option strict=On (On force VB à ne rien tolérer)

MessageBox.Show(myObjet.length) déclenche une erreur, car length n'est pas une propriété des Object.

Il faut convertir l'objet en String et là, on peut utiliser 'Length' : il faut écrire simplement :(Merci le forum de developpez.com)

 
Sélectionnez
Dim myObjet As New Object

myObjet="VB"

MessageBox.Show(DirectCast(myObjet, String).Length.ToString)

DirectCase transforme un type de variable en un autre, DirectCase peu'tolérant', car la variable qui reçoit doit être du bon type.

Une autre méthode consiste à transformer par CType le contenu de l'objet vers une variable String, puis à afficher la longueur de cette variable String.

 
Sélectionnez
Dim myObjet As New Object

myObjet="VB"

Dim  myString  As String

myString = CType(myObjet, String)

MessageBox.Show(myString.Length.ToString)

Au départ, VB ne sait pas quel type de variable sera dans l'objet, on ne connait donc pas les propriétés de la variable; la recherche de la propriété se fait à l'exécution, c'est plus long, de plus les contrôles et vérifications se font à l'exécution. , cela se nomme une liaison tardive (à éviter).

On évitera donc d'utiliser si possible des variables 'Object'.

Utilisez plutôt des variables typées (des variables String, Integer…) au départ; quand on les utilise, les contrôles et appels sont vérifiés dés le départ, on appelle cela une liaison anticipée ou précoce.

V-L-1-b. Comparaison d'objets

Is permet de savoir si 2 variables object se rapportent à la même instance.

 
Sélectionnez
Dim o1 As New Objet = monObjet

Dim o2 As Objet

o2= o1

If o1 Is o2 Then

V-L-1-c. Nothing

Après :

 
Sélectionnez
Dim myObjet As Object

myObjet contient Nothing, c'est-à-dire 'Rien': pas de référence à une instance.

Après avoir utilisé myObjet=12

On peut faire myObjet=Nothing.

Lorsque vous assignez Nothing à une variable objet, cette dernière ne fait plus référence à une instance d'objet, elle ne pointe sur rien.

Si la variable avait fait référence à une instance au préalable, l'assignation de Nothing à la variable ne met pas fin à l'instance. L'instance se termine, et les ressources mémoire et système qui lui sont associés sont libérés uniquement lorsque le garbage collector (qui fait le ménage) détecte l'absence de toute référence active restante.

On peut tester si un Objet contient Nothing avec .IsNothing

V-L-2. Les variables d'autres types

On verra que l'interface utilisateur est composée de contrôles, ces contrôles étant des objets, et bien, on peut déclarer une variable de type 'control' : bouton, ou textbox ou formulaire.

 
Sélectionnez
Dim myButton As New Button    'crée une variable myButton de type Button

Ensuite on peut utiliser les membres de la classe Button.

 
Sélectionnez
myButton.BackColor

Autre exemple : créons un TextBox :

 
Sélectionnez
Dim myTextBox As New TextBox    'crée une variable myTextBox de type TextBox

V-L-3. Utilisez donc des variables le plus typées possible

Éviter les 'Object'. Utilisez donc des variables le plus typées possible.

Si une variable doit contenir des boutons, créer une variable de type 'Button'.

Si une variable doit être utilisée pour contenir diverses choses : Button, ListBox… plutôt que la déclarer en Objet, il est préférable de la déclarer en System.Windows.Forms.Control

 
Sélectionnez
Dim fistControl As New System.Windows.Forms.Control

fistControl= New Button

Plus la variable sera typée plus le code sera rapide, solide, plus on évitera les erreurs de programmation.

V-L-4. Attention quand on met un objet dans une variable objet

Si je mets un Button dans une variable Object.

 
Sélectionnez
Dim MyObjet As Object

MyObjet = Button1

MyObjet donne accès aux propriétés des Object (Equals, GetType, ToString…); pour utiliser les propriétés de Button (comme Text par exemple, il faut d'abord transformer l'objet en Button en écrivant : CType(MyObjet, Button).

Par exemple, pour mettre le texte du button contenu dans MyObjet dans la variable MyTexte, il faut écrire :

 
Sélectionnez
Dim MyTexte As String = CType(MyObjet, Button).Text

V-M. Variable booléenne

Mr Georges Boole 1805-1864
Mr Georges Boole 1805-1864

Il existe un autre type de variable : le type 'Boolien 'ou 'Booléen'(Boolean).

V-M-1. Introduction

L'algèbre de Boole est la partie des mathématiques, de la logique de l'électronique et de l'informatique qui s'intéresse aux opérations et aux fonctions sur les variables logiques. En logique propositionnelle, une expression est soit vraie soit fausse. (le vrai (1) et le faux (0)).

Georges Boole (1815-1864), physicien anglais définit en 1847 une algèbre qui est applicable au raisonnement logique, qui traite des fonctions à variables binaires (deux valeurs). Mais il ne s'applique pas aux systèmes à plus de deux états d'équilibre.

Une variable booléenne, ou logique, ou binaire ne prend que deux valeurs (elle est généralement stockée sous la forme d'un bit).

Vers la fin des années 30, Claude Shannon démontra qu'à l'aide d'interrupteurs fermés pour "vrai" et ouverts pour "faux" il était possible d'effectuer des opérations logiques en associant le nombre 1 pour "vrai" et 0 pour "faux".

Ce codage de l'information est nommé base binaire. C'est avec ce codage que fonctionnent les ordinateurs. Il consiste à utiliser deux états (représentés par les chiffres 0 et 1) pour coder les informations.

Il permet d'étudier les circuits logiques.

V-M-2. Les booléens

On a parfois besoin de savoir si une assertion est vraie ou Fausse (True ou False).

Pour stocker une information de ce type, on utilise une variable de type booléen. Une variable de ce type ne peut contenir que True ou False.

Le terme booléen vient de "l'algèbre de Boole", cette algèbre ne travaille que sur les valeurs 1 ou 0 (True ou False)

Soit myBoolean une variable booléenne :

 
Sélectionnez
Dim myBoolean As Boolean

On peut écrire myBoolean = True

On peut aussi tester cette variable :

 
Sélectionnez
If myBoolean = False Then

L'expression après If est évaluée, si elle est vraie 'Then' se produit.

Autre exemple montrant comment le raisonnement informatique est 'logique' :

 
Sélectionnez
If maValeur=2 ThenEnd If

L'expression 'maValeur=2' est évaluée, si maValeur est effectivement égal à 2, l'expression prend la valeur True; dans ce cas le programme se poursuit après Then.

si maValeur est différent de 2, maValeur=2 est évaluée et prend la valeur False; dans ce cas le programme se poursuit après End If.

Un booléen peut donc prendre deux états (vrai/faux, oui/non, 1/0, etc.). Il s'agit donc d'une "valeur binaire". Techniquement, un booléen peut être représenté par un seul bit (binary digit = chiffre binaire).

Dans les langages n'ayant pas de variables booliennes, on se servait souvent d'un entier, avec pour convention que la valeur 0 représente "faux", tandis que toute valeur non nulle représente "vrai". En VB6 vrai était égale à -1. En VB.Net vrai = 1. Mais on s'en fiche, car :

un booléen est un booléen, en VB.Net on utilise donc True ou False comme seules valeurs pour un Booléen.

Il n'empêche que si on utilise une expression, un nombre et qu'on l'évalue comme si c'était un booléen (c'est pas bien !!), la valeur 0 représente "False", tandis que toute valeur non nulle représente "True".

V-M-3. Les conditions

On a vu que quand il faut faire un choix (comme dans 'If condition Then') il faut une condition qui est une expression booléenne. (avec While, Do Loop aussi).

Exemple :

 
Sélectionnez
If Condition Then    'Si 'condition' est vraie faire…End if

 

 

Do Until condition    'Boucler jusqu'à ce que 'condition'Loop

 

While Condition        'Tant que 'condition' bouclerEnd While

Pour écrire une condition, on utilise les opérateurs :

 
Sélectionnez
= égal

> supérieur à

 < inférieur à

>= supérieur ou égal

<= inférieur ou égal

<> Différent de

L'évaluation d'une condition donne True (Vrai) ou False (Faux), car on l'a dit c'est une expression booléenne.

Exemple :

 
Sélectionnez
      Dim valeur1 As Integer=2

      Dim valeur2 As Integer=3  

      If valeur1=valeur2 ThenEnd if

valeur1 étant différent de valeur2, la condition 'valeur1=valeur2' prend la valeur False et le programme passe à la ligne après End If).

Ici le signe = n'indique pas une affectation, mais 'égale' dans une expression à évaluer.

On peut combiner les opérateurs et mettre des parenthèses :

 
Sélectionnez
If (valeurC <> valeurD )AND (valeurD =2)

V-M-4. Les opérateurs logiques

Si on a plusieurs expressions logiques, on peut les combiner avec des opérateurs logiques.

Si A et B sont des expressions booléennes :

 
Sélectionnez
À And B     retourne True si A et B sont vrais

À Or B      retourne True si une des 2 est vrai

À Xor B     retourne True si une et une seule est vrai

Not A       retourne True si A est faux et vice versa

IsNot A     À partir de VB 2005

On entend par expression booléenne le résultat de l'évaluation d'une condition:

c=d retourne True si c égal d et False si c différent de d.

Exemple

Si A différent de B… peut s'écrire If Not(A=B) Then…

Si A compris entre 2 et 5 peut s'écrire If A>=2 And A<=5 Then…

Comment faire une bascule

Il faut écrire A= Not A

A chaque fois que l'on effectue cette instruction A bascule à True s'il était à False et vice versa.

Les opérateurs AndAlso et OrElse sont plus rapides, car ils n'évaluent pas la seconde expression si ce n'est pas nécessaire.

Parfois les expressions sont complexes et on peut les simplifier en utilisant des transformations:

Originale

Transformation

Not A And Not B

Not (À Or B)

Not A And B

Not (A Or Not B)

À And Not B

Not (Not A Or B)

À And B

Not (Not A Or Not B)

Not A Or Not B

Not (À And B)

Not A Or B

Not (A And Not B)

À Or Not B

Not (Not A And B)

À Or B

Not (Not A And Not B)

Exemple pratique

Si A compris entre 2 et 5 peut s'écrire If A>=2 And A<=5 Then…

ou If Not (A<2 Or A>5) Then…

Une remarque

Avec une expression booléenne, on peut écrire :

 
Sélectionnez
Dim a As Boolean= True

If a = True Then

ou

 
Sélectionnez
If a Then

Exemple :

 
Sélectionnez
If (x=15)=True  Then…

ou If x=15 Then

Donc, avec une expression booléenne, et uniquement avec une expression booléenne, il est possible de se passer du = True après un If, car de toute façon, l'expression est évaluée.

IsNot à partir de VB 2005
If Not (Objet1 Is Nothing ) Then…

devient

If Objet1 IsNot Nothing Then

Voir aussi le chapitre sur l'algèbre de Boole.

V-N. Soyons strict et explicite (et Compare et Infer ?)

Image non disponible

VB peut être tolérant ou pas

Image non disponible

Option Strict=On et Option Explicit=On le rend totalement intolérant, et c'est tant mieux !! Voyons cela.

V-N-1. Notion de conversion Explicite et Implicite

La conversion Explicite: est permet de forcer la conversion d'un type de données vers un autre type à l'aide de mots-clés.

Exemple :

 
Sélectionnez
Dim d As Double = 2.65

Dim i As Integer

 i=CType(d,Integer)  'conversion d'une valeur double en Integer

Il existe aussi la conversion implicite effectuée automatiquement sans syntaxe particulière et de manière transparente.

VB peut le permettre (si Option Explicit Off dans la configuration).

Exemple :

 
Sélectionnez
Dim d As Double = 2.65

Dim i As Integer

 i=d  'Pour affecter à i le Double d, Vb a transformé le double d en Integer.

V-N-2. Comment modifier une option ?

Menu Projet puis 'Propriétés de …'.

Onglet 'Compiler'

En VB 2008 :

Image non disponible

Là on peut modifier les options de compilation.

V-N-3. Option Strict

V-N-3-a. Conversions implicites

Avec Option Strict=On VB refuse les conversions implicites qui pourraient entrainer des pertes de données.

VB est naturellement très arrangeant (trop sympa !!) quand il est configuré avec Option Strict Off.

Par défaut il transforme, quand c'est possible, et si nécessaire un type de variable en un autre type.

Si je passe un nombre qui est en double précision (Double) dans une variable en simple précision (Single), VB accepte, au risque de perdre de la précision (s'il y a un très grand nombre de chiffres significatifs).

Ainsi :

 
Sélectionnez
Dim D As Double

Dim S As Single

D=0.123456789

S=D

MessageBox.Show(s) ' affiche 0,1234568   
'le 9 est perdu, car un single à 7 chiffres significatifs.

Cela peut être ennuyeux si c'est des calculs d'astronomie !! et le programmeur ne s'en rend pas forcément compte !!

Pour éviter cela il faut activer l'OPTION STRICT à ON (elle est par défaut à Off).

Menu Projet > Propriétés de Nom de projet.

Page de propriétés de Langage VB.

Propriétés communes, génération.

En face de Option Strict, mettre On

Maintenant seules les conversions effectuées explicitement seront autorisées.

S=D est souligné dans le code pour signaler une conversion interdite.

(Par contre D=S est accepté, car on passe d'une variable à une variable plus précise)

Il faudra maintenant, pour notre exemple, écrire :

 
Sélectionnez
S= CType(D,Single)

Cela entraine une conversion de la valeur Double en Single; s'il y a perte de précision, elle se produit quand même, MAIS le programmeur SAIT qu'il y a conversion, il prendra ou pas EN CONNAISSANCE DE CAUSE le risque.

Avec Option Strict le langage VB.Net devient bien moins tolérant :

Écrire un programme avec Option Strict à Off, ça passe, mettre Option Strict à On un tas d'instruction coince!! même certains exemples Microsoft !! Car sans s'en rendre compte on passe d'un type de variable à l'autre sans arrêt !!

V-N-3-b. Conversions String-numérique

Avec Option Strict=On VB refuse les conversions String-numériques implicites.

Avec Option Strict=Off

 
Sélectionnez
Dim n As Integer=12

MessageBox(n)

Affiche 12 : le contenu de l'entier 'n' a été transformé automatiquement en String pour être affiché.

Avec Option Strict=On

 
Sélectionnez
Dim n As Integer=12

MessageBox(n)

plante.

Il faut transformer explicitement n en String et écrire :

 
Sélectionnez
MessageBox(n.ToString)

C'est pour cela qu'il y a des '.ToString' partout !!

V-N-3-c. Liaisons tardives

Avec Option Strict=On VB refuse les liaisons tardives :

 
Sélectionnez
Dim V As Object
V="VB"
MessageBox.Show(V.Length) 'est refusé

MessageBox.Show(V.Length) est refusé

Il faut écrire

 
Sélectionnez
MessageBox.Show(CType(V, String).Length.ToString)

Du fait que les membres utilisés avec une variable Object ne sont pas définis à l'écriture du programme (on ne sait même pas quel type de variable sera dans l'objet, on n'en connait donc pas les membres), la recherche du membre se fait à l'exécution, c'est plus long, de plus les contrôles et vérifications se font à l'exécution.

Cela se nomme une liaison tardive, à éviter donc.

Utilisez plutôt des variables typées (des variables String , Integer…) au départ, quand on les utilise, les contrôles et appels sont vérifiés dés le départ, on appelle cela une liaison anticipée ou précoce.

'Option Strict Off' permet n'importe quoi. C'est du mauvais Basic .

'Option Strict On' oblige à une grande rigueur.

V-N-3-d. VB rapide ?

Avec Option Strict=On VB est plus rapide.

La vérification est effectuée lors de la compilation, à l'exécution il y a moins de contrôle de type.

V-N-4. Option Explicit

Pour la déclaration des variables, nous avions dit que toute variable utilisée devait être déclarée.

Par défaut c'est vrai.

Ouvrir Menu Projet > Propriétés de Nom de projet.

Page de propriétés de Langage VB.

Onglet 'Compiler' en VB 2008.

En face de Option Explicit, il y a On

On pourrait (c'est fortement déconseillé) mettre cette option à Off.

Cela ne rend plus obligatoire la déclaration des variables.

MaVariable=10 sans déclaration préalable est acceptée.

Cela présente certains inconvénients : si on fait une faute de frappe en tapant le nom d'une variable, VB accepte le nouveau nom et crée une nouvelle variable objet distinct.

 
Sélectionnez
Dim MaVariable         'MaVariable avec un b

MaVariabble=10         'Faute de frappe(bb)

Je crois avoir mis 10 dans Mavariable. En fait j'ai mis 10 dans une nouvelle variable nommée MaVariabble

Mavariable à toujours une valeur=0

Donc, c'est clair et sans appel : laisser Option Explicit à On, ce qui oblige à déclarer toutes les variables avant de les utiliser Dans ce cas si vous tapez le nom d'une variable non déclarée, elle est soulignée en bleue.

V-N-5. Option strict et Explicit dans un module

On peut aussi indiquer dans un module les options, ces instructions doivent être tapées avant toutes les autres.

Image non disponible

V-N-6. Option Compare

Option Compare Binany permet de comparer des chaines de caractères en fonction de leur code Unicode (le numéro du caractère).

Option Compare Text permet de comparer des chaines de caractères en fonction du CultureInfo qui prend en compte, pour chaque langue, la signification, la sémantique du caractère.

Exemple : Comparons 2 caractères, on affiche True s'ils sont égaux.

 
Sélectionnez
Console.WriteLine("a" = "A")

Donne True si Option Compare Text car sémantiquement parlant c'est le même caractère, du moins il a la même signification.

Donne False si Option Compare Binary, car le code Unicode de "a" et de "A" n'est pas le même.

Avec Option Compare Binary

Les caractères sont classés dans un ordre croissant (l'ordre de leur code Unicode)

Voyons l'ordre des certains caractères particuliers :

" " +,-./ 0123456789 :;ABCDEF abcdef èéê

On constate que l'ordre est espace puis quelques caractères spéciaux, les chiffres, les majuscules puis les minuscules, les accentués.(voir le tableau d'Unicode)

Ainsi "B" est inférieur à "a".

En utilisant Option Compare Binary, la plage [A-E] correspond à A, B, C, D et E.

Avec Option Compare Text:

Les caractères sont classés dans un ordre qui reflète plus la réalité d'un texte:

Tous les types de a: À, a, À, à, puis tous les types de b: B, b…

Avec Option Compare Text, [A-E] correspond à A, a, À, à, B, b, C, c, D, d, E et e. La plage ne correspond pas à Ê ou ê parce que les caractères accentués viennent après les caractères non accentués dans l'ordre de tri.

Ainsi "B" est supérieur à "a".

V-N-7. Option Infer

Option Infer apparait en VB 2008. Débutant passe ton chemin.

'Option Infer On' permet de se passer de donner le type d'une variable quand on la déclare. Lors de l'utilisation de la variable, elle prendra le type nécessaire. Ainsi, si on met une String dans la variable cela devient une variable String.

Par défaut on a Option Infer Off.

Exemple :

 
Sélectionnez
Option Infer On

Module Test
      Sub Main()
            ' Le type de x est ' Integer'
            Dim x = 10

            ' Le type de y est 'String'
            Dim y = "abc"
      End Sub
End Module

Son utilité se retrouve dans l'usage de base de données et surtout de Linq qui permet d'interroger les bases de données.

Éviter Option Infer On pour du code habituel.

V-O. Les constantes, les énumérations

Image non disponible

V-O-1. Constantes

Comme les variables, elles ont un nom et un type, mais leurs valeurs sont 'constantes'.

On les déclare par le mot Const, on peut les initialiser en même temps avec =

Exemple :

 
Sélectionnez
Const NOMDUPROGRAMME= "LDF"   'constante chaine de caractères.

Const NOMBREDECASE As Integer = 12             'constante Integer

Ensuite on peut utiliser la constante :

 
Sélectionnez
For k= 0 To NOMBREDECASE

…

Next k

Si on utilise: For k=0 To 12, à la lecture c'est moins clair.

Si on écrit : NOMBREDECASE=13 cela déclenche une erreur !!

Habituellement, les constantes sont créées en début de programme.

Il est conseillé par convention d'écrire le nom des constantes en majuscules.

V-O-1-a. Intérêts des constantes ?

  • Améliore la lisibilité et évite d'utiliser des constantes littérales.
    Il faut éviter :

     
    Sélectionnez
    For i=0 To 100    'À quoi correspond 100?Next i

    Il faut écrire :

     
    Sélectionnez
    Const NBMAXPATIENT As Integer= 100
    
    For i=0 To NBMAXPATIENT
    
    …
    
    Next i
  • Modifications du code facilitées.
    Si une constante doit être modifiée ultérieurement, il suffit en mode conception de modifier sa valeur ce qui modifie sa valeur dans l'ensemble du code de l'application.
    Const NBMAXPATIENT As Integer= 200 'Si j'introduis une modification de valeur

     
    Sélectionnez
    For i=0 To NBMAXPATIENT            'Toutes les boucles utilisant NBMAXPATIENT seront à jour
    
    Next i
  • Amélioration la vitesse.
 
Sélectionnez
Const NBMAXPATIENT As Integer= 100 

Dim nombre= NBMAXPATIENT

est plus rapide que :

 
Sélectionnez
Dim nbpatient As Integer= 100 

Dim nombre= nbpatient

Car le compilateur code directement nombre=20 dans le premier cas.

On rappelle que seuls les types primitifs peuvent avoir des constantes (Byte, Boolean, Short, Integer, Long, Single, Double, Decimal, Date, Char, String).

V-O-1-b. Constantes prédéfinies de VB

Les constantes de Visual Basic sont toujours là :

 
Sélectionnez
vbOk    'retourné par une MessageBox quand l'utilisateur a cliqué sur Ok.

vbBack

vbCancel

vbCrLf     'caractère numéro 13  puis numéro 10 = saut à la ligne.

V-O-1-c. True False

On rappelle que True et False sont des valeurs booléennes faisant partie intégrante de VB.

Pour les anciens de VB6 ne plus utiliser -1 et 0 (d'ailleurs c'est maintenant 1 et 0).

Mais, en plus, dans Visual Basic .NET, la plupart des constantes sont remplacées par des énumérations dans le .NET Framework.

(Voir plus bas.)

Utiliser largement ces constantes fournies par VB, cela améliore la lisibilité et la maintenance.

V-O-2. Énumération

Les énumérations sont utilisées lorsque l'on a un jeu de constantes liées logiquement.

Un bloc Enum permet de créer une liste (une énumération) de constantes :

 
Sélectionnez
Enum TypeFichier

    DOC

    RTF

    TEXTE

End Enum

Les constantes ainsi créées sont :

  • TypeFichier.DOC ;
  • TypeFichier.RTF ;
  • TypeFichier.TEXTE.

Le bloc Enum doit être dans l'entête du module (en haut).

C'est bien pratique, car en écrivant le code, dès que je tape 'TypeFichier.' la liste (DOC RTF TEXTE) apparait.

Ensuite, on peut utiliser dans le programme les constantes créées par exemple :

 
Sélectionnez
fichierEnCours= TypeFichier.DOC

On peut ensuite tester par exemple :

 
Sélectionnez
If fichierEnCours= TypeFichier.RTF then

Il est conseillé, par convention, d'écrire le nom des énumérations en minuscules avec la première lettre en majuscule.

Ce qui suit concernant les énumérations est un peu plus complexe.

Chaque constante littérale de l'énumération a une valeur par défaut.

Par défaut

 
Sélectionnez
TypeFichier.Doc =0  

TypeFichier.RTF =1 

TypeFichier.TEXTE=2

La première valeur est 0.

Si on ne spécifie rien, les valeurs sont des Integers.

Parfois le nom utilisé dans l'énumération (la constante littérale) est suffisant en soi et on n'utilise pas la valeur : dans un programme gérant des fichiers, une variable prendra la valeur TypeFichier.Doc pour indiquer qu'on travaille sur les fichiers .DOC. Peu importe la valeur de la constante.

Mais d'autres fois il faut que chaque constante de l'énumération possède une valeur particulière.

Je peux imposer une valeur à chaque constante de l'énumération :

 
Sélectionnez
Enum TypeFichier

    DOC=2

    RTF=4

    TEXTE=8

End Enum

Cela évite d'écrire fichierEnCours= 15 (en retenant que 15=fichier doc, 30= fichier rtf…)

Je peux même donner plusieurs valeurs avec And et Or à condition d'utiliser l'attribut Flags.

 
Sélectionnez
<Flags()> Enum TypeFichier

    DOC=2

    RTF=4

    TEXTE=8

    TOUS= DOC AND RTF AND TEXTE

End Enum

L'attribut Flags() indique que les valeurs sont codées en bits, ce qui permet les combinaisons de valeurs. (pour 2 le second bit est à 1, pour 4 le troisième bit est à 1, pour 8, le quatrième bit est à 1…) (voir chapitre sur l'algèbre de Boole).

Voici un exemple avec une Énumération 'Repas' ou chaque bit indique la présence d'un plat.
La propriété HasFlag permet de tester si un bit est égal à 1.

 
Sélectionnez
<Flags()> Public Enum Repas As Integer
    None = 0
    Entree = 1
    Poisson = 2
    Viande = 4
    Dessert = 8
    Boisson = 16
    Digestif = 32
End Enum


  Dim myRepas As Repas = Repas.Entree Or Repas.Dessert Or
                                     Repas.Boisson

        'Affiche myRepas
        Console.WriteLine(myRepas.ToString)
        'Teste si myRepas contient Dessert
        Console.WriteLine(myRepas.HasFlag(Repas.Dessert))

        'Sortie
        'Entree, Dessert, Boisson
        'True

Les énumérations sont des types qui héritent de System.Enum et qui représentent symboliquement un ensemble de valeurs. Par défaut ses valeurs sont des 'Integer', mais on peut spécifier d'autres types: Byte, Short, Integer ou Long. L'exemple suivant déclare une énumération dont le type sous-jacent est Long :

 
Sélectionnez
Enum Color As Long
 Red
 Green
 Blue
End Enum

Habituellement, on utilise les énumérations dans le code, comme des constantes.

Exemple :

 
Sélectionnez
Enum TypeFichier

    DOC=2

    RTF=4

    TEXTE=8

End Enum

' affecter à une variable:

Dim monFichier As TypeFichier = TypeFichier.RTF

On remarque qu'on crée une variable de type énumération dans laquelle on ne peut mettre qu'une énumération (en fait un Integer).

 
Sélectionnez
' affichage d'une valeur

Console.Out.WriteLine("Numéro type du fichier=" & monFichier)

'monFichier' affiche: 4

 
Sélectionnez
Console.Out.WriteLine("Type du fichier=" & monFichier.ToString)

On utilise 'monFichier.ToString' qui affiche : RTF

 
Sélectionnez
' test avec la constante de l'énumération

If (monFichier = TypeFichier.RTF) Then

    Console.Out.WriteLine("C'est du RTF")

End If

Affiche :"C'est du RTF"

Mais parfois on a besoin de récupérer la liste des éléments d'une énumération.

Comment relire la liste des énumérations ?

Il faut utiliser une méthode statique (ne nécessitant pas d'instanciation) GetValues pour obtenir toutes les constantes littérales ou valeurs d'un type énuméré que l'on passe en paramètre.

 
Sélectionnez
' liste des mentions littérales (Constantes)

For Each t As TypeFichier In [Enum].GetValues(monFichier.GetType)

    Console.Out.WriteLine(t.ToString)

Next

' liste des mentions entières (Valeurs)

For Each t As Integer In [Enum].GetValues(monFichier.GetType)

    Console.Out.WriteLine(t)

Next

Affiche :

 
Sélectionnez
DOC

RTF

TEXTE

2

4

8

GetValues, quand on lui donne le type de l'énumération retourne la liste des éléments de l'énumération; c'est pratique pour remplir une ListBox avec une énumération :

 
Sélectionnez
ListBox1.DataSource = [Enum].GetValues(GetType(TypeFichier))

Si on affecte un élément d'une énumération à une variable Integer, on récupère la valeur, si on utilise ToString on récupère la constante littérale.

 
Sélectionnez
Dim n As Integer

n = TypeFichier.RTF

Console.Out.WriteLine(n.ToString)

Dim st As String

st = TypeFichier.RTF.ToString

Console.Out.WriteLine(st)

Affiche
 
Sélectionnez
2

RTF

Comment récupérer dans une énumération une constante à partir de sa valeur ou une valeur à partir de la constante ?

Ici il faut instancier :

 
Sélectionnez
Dim s As Type = GetType(TypeFichier)

Console.Out.WriteLine(CType([Enum].GetName(s, 15), String))

Console.Out.WriteLine(CType([Enum].Parse(s, "DOC"), String))

Affiche :

 
Sélectionnez
DOC

2

V-O-3. Les énumérations VB.NET

Noter que VB.Net contient, comme on l'a vu, un tas de constantes classées à l'aide d' Enum.

V-O-3-a. ControlChars

Cette énumération contient les caractères de contrôle.

ControlChars.CrLf égale à Chr$(13)+Chr$(10) qui sert à sauter à la ligne dans une chaine de caractères.

Si on affiche "VISUAL" & ControlChars.CrLf & "BASIC"

On obtient à l'écran :

 
Sélectionnez
VISUAL

BASIC

ControlChars.Tab Chr$(9) = caractère de tabulation

ControlChars.NullChar Aucun caractère

ControlChars.Nothing chaine vide

ControlChars.Back

Taper ControlChars. Et comme d'habitude vous obtiendrez la liste des constantes.

V-O-3-b. Couleurs

On peut aussi utiliser l'énumération des couleurs définies par le Framework

 
Sélectionnez
System.Drawing.Color.Blue    'Pour le bleu

ou en simplifiant (si Imports System.Drawing a été écrit)

 
Sélectionnez
Color.Chocolate

Color.Black

V-O-3-c. Math

Si Import System.Math est présent en haut du module,

PI contient 3,14…

E contient la base log naturel

V-O-3-d. Touche du clavier dans le Framework

Il est parfois nécessaire de savoir si une touche précise a été tapée par l'utilisateur au clavier, pour cela il faut connaitre les touches, mais pas besoin de se souvenir du code des touches, il suffit de taper Keys, et la liste des touches s'affiche. Cliquer sur le nom de la touche recherchée et vous obtenez la constante correspondant à la touche :

 
Sélectionnez
Keys.Right    'Désigne le code de la touche '->'

Keys.D8       'Désigne le code de la touche '8'

Keys.Delete   'Désigne le code de la touche 'Suppr'

Keys.D   'Désigne le code de la touche 'D'

Keys.Shift   'Désigne le code de la touche 'Majuscule'

Keys.SnapShot   'Désigne le code de la touche 'Impression écran'

V-O-3-e. Autre exemple

Quand on ferme une MessageBox (une fenêtre qui affiche un message), cela retourne une valeur qui contient :

 
Sélectionnez
MsgBoxResult.Yes

MsgBoxResult.No    ou

MsgBoxResult.Cancel

En fonction du bouton qu'a utilisé l'utilisateur pour sortir de la fenêtre MessageBox (appuie sur les boutons Oui, Non, Cancel).

V-P. Les opérateurs

+-*/And OrMod&
+-*/And OrMod&

Pour travailler sur les variables, on utilise des opérateurs (addition, soustraction…).

V-P-1. Addition : +

Dans le cas de variables numériques.

 
Sélectionnez
    Dim A,B, C As Integer
                    B=2
                    C=3
                    A=B+C

si B=2 et C=3 => A=5

On peut écrire :

A=A+1

Dans ce cas, on affecte à la variable A son ancienne valeur +1, si A=2 au départ, A=3 ensuite.

A+=1 est équivalent à A=A+1

Cela incrémente la variable A.

On peut utiliser '+' pour ajouter une string à une autre, il est préférable d'utiliser '&'.

V-P-2. Soustraction : -

B=C-D

A-=1 est équivalent à A=A-1

V-P-3. Multiplication : *

C'est une étoile : *

B= C*D

V-P-4. Division : /

On remarque que ":" n'est pas l'opérateur de division. (Ce signe sert de séparateur quand plusieurs instructions sont sur la même ligne.)

Retourne le quotient complet qui conserve le reste dans la partie fractionnaire.

B=C/D

Si C=10 et D=3 B=3.33333333333333

La division de 2 Single retourne un Single.
La division de 2 Doubles retourne un Double.
La division de 2 Decimal retourne un Decimal.
Voir en bas de page, des informations complémentaires, car
La division de 2 entiers (Integer…) retourne un Double.

V-P-5. Division entière : \

Si A=10\3 => A=3 'on perd le reste

Voir en bas de page, des informations complémentaires, car "\"sur 2 Integer retourne un Integer.

V-P-6. Puissance : ^

 
Sélectionnez
À=B^3        'À=B*B*B

V-P-7. Modulo : Mod

C'est le reste de la division par un nombre :

10 Mod 3 donne 1

Exemple A est-il multiple de 3 ?

Si A Mod 3 = 0 , A est un multiple de 3

 
Sélectionnez
If A Mod 3 = 0 then

V-P-8. Concaténation : &

C'est une mise bout à bout des chaines de caractères.

Si

A= "VISUAL"

B= " "

C= "BASIC"

D=A & B & C donne D="VISUAL BASIC"

Le signe + peut aussi être utilisé, mais il est plutôt réservé aux additions de variables numériques.

&= permet aussi la concaténation A&=B est équivalent à A= À&B

V-P-9. Priorités

L'ordre des calculs se fait en fonction de la priorité des opérateurs.

S'il y a plusieurs opérateurs, '^' a la priorité la plus forte puis * et / puis + et -

Cela veut dire que VB effectue les élévations à puissance puis les multiplications et divisions puis les additions et soustractions.

Pour être complet, voyons les priorités par ordre décroissant :

 
Sélectionnez
^ élévation à la puissance

- négation unaire 

/ et * multiplication et division

\ division entière

mod  modulo

+ et -  addition et soustraction.

Exemple 2+3^3 donne 29, car VB effectue (3^3)+2 et non pas 125 (2+3)^3

S'il y a plusieurs opérateurs de même priorité, l'ordre des calculs se fait de gauche à droite.

Pour éviter toute faute d'interprétation, utiliser des parenthèses.

2+(3^3) lève toute ambiguïté.

V-P-10. Comparaison

 
Sélectionnez
= égal

 > supérieur à

 < inférieur à

>= supérieur ou égal

<= inférieur ou égal

<> Différent de

Le résultat d'une comparaison est True (Vrai) ou False (Faux)

Exemple :

 
Sélectionnez
      Dim A As Integer=2

      Dim B As Integer=3  

      If A=B thenEnd If

À étant différent de B, A=B prend la valeur False et le programme passe à la ligne en dessous de End If (pas après then).

Ici le signe = n'indique pas une affectation, mais une expression à évaluer.

Ici aussi on peut combiner les opérateurs et mettre des parenthèses :

 
Sélectionnez
R= (C<>D)AND (D=2)   'Si C différent de D  et si D égal 2

Comparaison de chaines de caractères

Les chaines de caractères sont comparées en fonction du tri alphabétique.

Par défaut, 'Option Compare Binary' est activé, ce qui fait que l'ordre des caractères est en relation avec leur code Unicode (voir chapitre sur les Options).

 
Sélectionnez
' À<B<C&#8230;&#8230;<Y<Z<a<b<c&#8230;&#8230;y<z<à<é… 

      Dim A As String="A"

      Dim B As String="Z"  

      If A<B then

À est bien inférieur à B, donc A<B prend la valeur True et le programme saute après Then.

La casse (majuscules ou minuscule) est différenciée.

Si on veut comparer sans tenir compte du fait que c'est en majuscules ou minuscules, il faut d'abord transformer les 2 chaines en minuscules par exemple.

On veut comparer A= "aaa" et B= "AAA"

Normalement A est différent de B :

A=B retourne False

Par contre A.ToLower=B.ToLower retourne True (Vraie)

En utilisant 'Option Compare Text' en début de module, on ne différencie plus la casse: "A" devient égal à "a".

V-P-11. Logique : Not And Or ElseOr Xor

V-P-11-a. Si A et B sont des expressions booléennes

A And B retourne True si A et B sont vrais

A Or B retourne True si une des 2 est vrai

A Xor B retourne True si une et une seule est vrai

Not A retourne True si A était faux et vice versa

On entend par expression booléenne le résultat de l'évaluation d'une condition:

A=B retourne True si A=B et False si A différent de B.

Exemple

Si A différent de B… peut s'écrire IF Not(A=B)…

Si A compris entre 2 et 5 peut s'écrire If A>=2 And A<=5…

Comment faire une bascule

Il faut écrire A= Not A

À chaque fois que l'on effectue cette instruction A bascule à True s'il était à False et vice versa.

V-P-11-b. Si A et B sont des nombres (Integer par exemple)

L'opération est effectuée sur chaque bit.

A = 7 'en décimal ( 0111 en binaire)

B = 12 'en décimal( 1100 en binaire)

Que donne A And B ?

On effectue l'opération bit à bit.

Pour le premier bit de chaque nombre 0 And 1 = 0.

Pour le second bit de chaque nombre 1 And 1 = 1…

Cela donne 0100.

A And B = 4 'en décimal( 0100 en binaire)

Autre exemple

A And 1 indique si le bit le moins significatif (le plus à droite) est a 1

Exemple : si A = 7 'en décimal ( 0111 en binaire) A And 1 retourne 1

V-P-11-c. Les opérateurs And, Or et Xor sont évalués en fonction du type des opérandes

V-P-11-c-i. Pour le type Boolean

Une opération And logique est effectuée sur les deux opérandes.

Une opération Or logique est effectuée sur les deux opérandes.

Une opération Or exclusif logique est effectuée sur les deux opérandes.

V-P-11-c-ii. Pour les types Byte, Short, Integer, Long et tous les types énumérés

L'opération spécifiée est réalisée sur chaque bit de la représentation binaire des deux opérandes

And : Le bit de résultat est 1 si les deux bits sont 1. Sinon, le résultat est 0.

Or : Le bit de résultat est 1 si l'un des deux bits est 1. Sinon, le résultat est 0.

Xor : Le bit de résultat est 1 si l'un des deux bits est 1, mais pas les deux. Sinon, le bit de résultat est 0 (c'est-à-dire 1 Xor 0 = 1, 1 Xor 1 = 0).

Les opérateurs AndAlso et OrElse sont uniquement définis sur le type booléen, ils sont plus rapides, car ils n'évaluent pas la seconde expression si ce n'est pas nécessaire.

Il n'est pas judicieux d'effectuer des opérations logiques sur des Single, Decimal, Double (nombre avec virgule).

V-P-12. Déplacement de bits

Les opérateurs binaires << et >> effectuent des opérations de déplacement de bits. Ces opérateurs sont définis pour les types Byte, Short, Integer et Long.

L'opérateur << décale à gauche les bits du premier opérande du nombre de positions spécifié. Les bits de poids fort situés en dehors de la plage du type de résultat sont éliminés, et les positions libérées par les bits de poids faible sont remplies par des zéros.

L'opérateur >> décale à droite les bits du premier opérande du nombre de positions spécifié. Les bits de poids faible sont éliminés et, si l'opérande de gauche est positif, les positions libérées par les bits de poids fort sont mises à zéro ; s'il est négatif, elles sont mises à un. Si l'opérande de gauche est de type Byte, les bits de poids fort disponibles sont remplis par des zéros.

À quoi cela sert ?

Exemple décaler à gauche un Byte revient à faire une multiplication par 2.

3 en décimal= 11

Je décale à gauche, j'obtiens 110 , c'est 6 en décimal.

V-P-13. Remarque 1 : Allons plus loin avec / et \

La division de 2 Single avec "/" retourne un Single.
La division de 2 Decimal avec "/" retourne un décimal.
mais
La division de 2 entiers avec "/" retourne un double.

Avec Option Strict=Off

 
Sélectionnez
Dim i As Integer = 4

Dim j As Integer = 2

Dim k As Integer = i / j 'est accepté
'car i/j donne un double transformé en Integer 'automatiquement'.

Avec Option Strict=On, il faut écrire :

 
Sélectionnez
Dim i As Integer = 4

Dim j As Integer = 2

Dim k As Integer = CType(i / j, Integer) 'on est obligé de caster le double en Integer.

Mais "\" retourne un Integer si on divise 2 entiers.
Pour diviser 2 entiers, utiliser donc "\".

 
Sélectionnez
Dim i As Integer = 4

Dim j As Integer = 2

Dim k As Integer = i \ j 'est accepté
'même si  Option Strict=On

V-P-14. Remarque 2 : Division par zéro

La division par zéro est impossible mathématiquement.

  • Si on divise un double (ou un Single ) par zéro, on obtient NaN : nombre non défini ou PositiveInfinity ou NegativeInfitiny selon le dividende.
  • Pour les entiers, Integer , Byte… une division par zéro déclenche une erreur ( on dit une exception) DivideByZeroException ou OverflowException en vb 2010.

En pratique les choses ne sont pas si évidentes, voyons des exemples :

 
Sélectionnez
Dim i As Integer = 4

Dim j As Integer = 0

TextBox1.Text = (i/j).ToString 'Affiche " +Infini"

Le résultat de l'opération (i/j) qui est un Double prend la valeur infini et est directement affiché.

Par contre :

 
Sélectionnez
Dim i As Integer = 4

Dim j As Integer = 0

Dim k As Integer = CType(i / j, Integer) 'Erreur

Retourne une exception (une erreur) Overflow.Exception, car le résultat de l'opération est l'infini donc plus grand que MaxValue des Integers.

Il faut donc, si on risque d'avoir la valeur zéro, faire un contrôle avant la division :

 
Sélectionnez
If j<>0 Then

    k=i/j

End If

V-Q. Les structures de contrôle : Choix et boucles

Image non disponible

Elles permettent de gérer le déroulement du code.

V-Q-1. If Then

Permet de créer une structure décisionnelle :

Image non disponible

If Condition Then

End if

Si la Condition est vraie alors…

Une instruction (ou un bloc d'instructions) peut être exécutée si une condition est vraie.

Exemple :

 
Sélectionnez
If A=B then 

    MsgBox("A=B")

End If

Si A = B alors on exécute le bloc de code entre Then et End If, il affiche dans une fenêtre MessageBox "A=B"

Noter que, si on le désire, on peut écrire sur la même ligne après Then (Pas besoin de End If).

 
Sélectionnez
If A=B Then MsgBox("A=B")

On peut tester une condition fausse et dans ce cas utiliser Not.

 
Sélectionnez
If Not A=B Then MsgBox("A différent de B")

Si A et B sont différents (Not A=B signifie NON égaux) afficher "A différent de B".

(On aurait pu écrire If A<>B Then…)

Il peut y avoir des opérateurs logiques dans la condition :

 
Sélectionnez
If A=B And C=D then'Si A égal B et si C égal D

Autre exemple :

 
Sélectionnez
Dim n As String ="33" ' on crée une String , on y met les caractères "33"

If Not IsNumeric(n) then

            MsgBox ("n n'est pas un nombre")

            Exit Sub

End if

Si n n'est pas numérique alors afficher dans une boite de dialogue: "n n'est pas un nombre" puis quitter la procédure (Exit Sub).

Noter bien que comme il y a plusieurs instructions après Then on crée un bloc d'instruction de plusieurs lignes entre Then et End If.

Simplification d'écriture

Au lieu de

 
Sélectionnez
If Condition = True Then

End if

On peut écrire:

 
Sélectionnez
If Condition Then   

End if

Condition étant de toute manière évaluée pour voir si elle est égale à True.

On peut aussi utiliser la structure 'Si…Alors…Sinon' :

 
Sélectionnez
If condition then'effectué si condition vraieElse'effectué si condition fausseEnd if

Exemple :

 
Sélectionnez
If A=B then 

    MsgBox("A=B")

Else

    MsgBox("A différend de B")

End If

Des structures If Then peuvent être imbriquées :

 
Sélectionnez
IfIf…

      …

      Else

            If…

     …

End if

      End if

End If

Pour bien repérer les différents niveaux, utiliser les tabulations et décaler le 'If then' et son code au même niveau.

Pour vérifier s'il n'y a pas d'erreur, compter les 'If', il doit y en avoir autant que des 'End If'. VB souligne le 'If' si il n'y a pas de 'End if'.

Dernière syntaxe avec 'ElseIf' :

 
Sélectionnez
If Condition1 ThenElseIf condition2 ThenElseIf condition3 Thenend if

Si condition1…

Sinon si condition2

Sinon si condition3

Fin Si

V-Q-2. Select Case

Créer une structure décisionnelle permettant d'exécuter un grand nombre de blocs de code différents en fonction de la valeur d'une expression :

Image non disponible
 
Sélectionnez
Select Case expression

Case valeur1

      'code effectué si expression=valeur1


Case valeur2

      'code effectué si expression=valeur2


Case valeur3

      'code effectué si expression=valeur3Case Else

      'code effectué dans tous les autres cas


End Select

Attention si expression=valeur1 le code entre Case Valeur1 et Case valeur2 (et uniquement celui-là) est effectué, puis l'exécution saute après End Select.

Exemple d'un code affichant le jour de la semaine :

J est un entier contenant le numéro d'ordre du jour

 
Sélectionnez
Select Case N

Case 1                        'Si N=1

      MsgBox "Lundi"          'Afficher 'Lundi'  

 

Case 2

      MsgBox "Mardi"

 

Case 3

      MsgBox "Mercredi"

…

…

Case Else

      MsgBox "Nombre pas entre 1 et 7"

End select

Nous venons d'utiliser une expression simple après chaque Case, mais on peut utiliser des expressions plus complexes.

Plusieurs clauses d'expression peuvent être séparées par des virgules.

 
Sélectionnez
Select Case N

Case 8,9,10

      'Effectuer le code  si N=8 ou N=9 ou N=10

Le mot-clé To permet de définir les limites d'une plage de valeurs correspondantes pour N.

 
Sélectionnez
Select Case N

Case 8 To 20
      'Effectuer le code  si N est dans la plage 8 à 20
End Select

Le mot-clé Is associé à un opérateur de comparaison (=, <>, <, <=, > ou >=) permet de spécifier une restriction sur les valeurs correspondantes de l'expression. Si le mot-clé Is n'est pas indiqué, il est automatiquement inséré.

 
Sélectionnez
Select Case N

Case Is >= 5

      'Effectuer le code  si N supérieur ou égal à 5.

End Select

Vous pouvez utiliser plusieurs expressions ou plages dans chaque clause Case (séparées par des virgules). Par exemple, la ligne suivante est valide :

 
Sélectionnez
Case 1 To 4, 7 To 9, 11, 13, Is > MaxNumber

Vous pouvez aussi indiquer des plages et des expressions multiples pour des chaines de caractères. Dans l'exemple suivant, Case correspond aux chaines qui sont absolument identiques à "aaa", aux chaines comprises entre «ccc» et «ddd» dans l'ordre alphabétique, ainsi qu'à la valeur de Var :

 
Sélectionnez
Case "aaa", "ccc" To "ddd", Var

Pour les 'Pro':

Les "Case" peuvent contenir n'importe quelle expression. Aussi il est possible de tester dans les conditions, non pas les valeurs d'une même variable, mais diverses fonctions totalement indépendantes ou comme ici des fonctions travaillant toutes sur une même variable. C'est un usage méconnu du Select Case qui clarifie l'écriture et qui évite de multiples If Then ou Goto.

Ici une routine reçoit une String contenant un nom de fichier, elle teste si le nom n'est pas vide puis si le fichier existe…

 
Sélectionnez
Sub TestFichier (File As String)

Select Case true

        Case len(File) = 0 

            msgbox "Pas de nom de fichier"    

        Case Not Exit(File)

            errorState=File.NotExist

        Case Not Open(File)

            errorState=File.NotOpen

        Case Not Overwrite(File) 

            errorState=File.NotOverwrite

        Case else

        'placer les exceptions ici

End Select

End Sub

V-Q-3. For Next

Permet de faire des boucles.

Image non disponible

Les boucles sont très utilisées pour parcourir une plage de valeur qui permet par exemple de parcourir tous les éléments d'un tableau ou pour effectuer de manière itérative un calcul.

Le nombre de boucles va être déterminé par une variable qui sert de compteur : la variable de boucle.

Le nombre d'exécutions est déterminé au départ de la boucle, car le compteur a une valeur de départ, une valeur d'arrêt.

Pour variable allant de 'début' à 'fin'

Boucler

donne en VB

 
Sélectionnez
For variable=début To fin

…

Next variable

Exemple :

 
Sélectionnez
Dim i as Integer

For i=1 to 10

MsgBox (i.toString)

Next i

En langage courant : pour i allant de 1 à 10, afficher la valeur de i dans une MessageBox.

La variable compteur va prendre successivement les valeurs 1 puis 2 puis 3…… jusqu'à 10 et effectuer à chaque fois le code qui est entre For et Next.

Si on décompose :

i=1 Affiche "1", arrivé à Next, remonte à For, i =2 , affiche "2"……

… i=10 , affiche "10" poursuit après Next.

En effet i augmente d'une unité à chaque 'tour'.

Il peut y avoir un pas (Step), le compteur s'incrémente de la valeur du pas à chaque boucle.

 
Sélectionnez
Dim i as Integer

For i=1 to 10 Step 2

MsgBox i.toString

 Next i

Affiche 1 puis 3 puis 5 puis 7 puis 9

Attention si la valeur de sortie de boucle est inférieure à celle d'entrée il faut indiquer un pas négatif.

 
Sélectionnez
Dim i as integer

For i=10 to 1 Step -2

MsgBox (i.toString)

 Next i

Affiche 10 puis 8 puis 6 puis 4 puis 2

Bien sûr on peut utiliser des expressions calculées :

 
Sélectionnez
For i=À to B*10 Step X-2

    MsgBox i.toString

Next i

La variable boucle peut être déclarée après For, dans ce cas cette variable n'existe que dans la boucle :

 
Sélectionnez
For K As Integer = 1 To 10Next K

On peut quitter prématurément la boucle avec Exit For.

 
Sélectionnez
For K As Integer = 1 To 10If A=2 Then Exit For

Next K

Dans ce cas la boucle s'arrête de tourner si A=2, on poursuit après Next.

Remarque

Le nom de la variable de boucle est facultatif après Next :

 
Sélectionnez
For K As Integer = 1 To 10Next

est correct.

Depuis la version 2005 il existe aussi Continue For qui permet de sauter au prochain Next et de poursuivre la boucle.

V-Q-4. Do Loop

Permet aussi de faire des boucles, mais sans que le nombre de boucles (d'itérations) soit déterminé au départ.

Image non disponible

La boucle suivante tourne sans fin :

 
Sélectionnez
Do
Loop

Il faut une condition d'arrêt qui détermine la sortie de la boucle.

On doit mettre Until (Jusqu'à ce que) ou While (Tant que) avant la condition d'arrêt pour sortir de la boucle.

On peut mettre la condition après Do :

 
Sélectionnez
Do Until condition    

      Code

Loop

 'Boucler jusqu'à ce que condition soit vraie.

Si condition est fausse, effectuer le code, boucler et recommencer le code jusqu'à ce que condition soit égale à True.

Attention, avant de débuter la boucle, la condition doit être fausse sinon la boucle ne sera jamais exécutée…

À chaque boucle la condition est évaluée.

Exemple pour chercher un mot dans une liste :

 
Sélectionnez
Lire Premier Mot
Do Until MotCherché=MotPointé

      Pointer Mot suivant

Loop

On peut aussi utiliser While (Tant que) :

 
Sélectionnez
Lire Premier mot
Do While MotCherché<>MotPointé

      Pointer Mot suivant

Loop

Tant que le mot cherché est différent du mot pointé, boucler.

La condition peut être mise en fin de boucle, cela permet d'effectuer au moins une fois le code. Cela évite aussi d'avoir à démarrer le processus avant la boucle, dans notre exemple cela permet d'éviter de lire le premier mot avant la boucle.

Les mots sont dans un tableau Mot(), premier élément Mot(0).

 
Sélectionnez
IndexMot=-1 

Do 

     IndexMot=IndexMot+1

Loop While MotCherché<>Mot(IndexMot)

Il faudrait en plus boucler jusqu'à la fin du tableau et pas plus.

Il y a Exit Do pour sortir de la boucle, il existe aussi Continue Do qui permet de sauter au prochain Loop et de poursuivre la boucle.

Exemple complet : Imposer la saisie d'un nombre négatif à l'utilisateur.

On utilise InPutBox qui ouvre une fenêtre et attend une réponse.

 
Sélectionnez
Dim Reponse as Single

Do

      Reponse=InPutBox("Entrer un nombre négatif.")

Loop  While Reponse>=0

Si le nombre n'est pas négatif, la boucle fonctionne et la boite InPutBox s'ouvre de nouveau. Si le nombre est négatif, on sort de la boucle.

Comment créer une boucle qui tourne sans fin ?

 
Sélectionnez
DoLoop  While True

Autre exemple

Créer une boucle affichant successivement dans une MessageBox les chiffres de 1 à 10.

 
Sélectionnez
Dim i As Integer = 0    

Do   

    i = i + 1          'incrémente i de 1    

   MsgBox(i.ToString)  'affiche la valeur de i dans une messageBox   

Loop Until i = 10      'sort de la boucle quand i=10

V-Q-5. While End While

Permet une boucle qui tourne tant qu'une condition est vraie.

Image non disponible

Principe :

 
Sélectionnez
Tant que Condition
….
Fin Tant que

En VB :

 
Sélectionnez
While Condition

…

End While

Exemple : on incrémente un compteur, on sort quand il est égal à 20.

 
Sélectionnez
Dim Counter As Integer = 0
While Counter < 20 ' Test la valeur du compteur.
   Counter += 1 ' Incrémente le compteur.
End While

Il y a Exit While pour sortir de la boucle, il existe aussi Continue While qui permet de sauter au prochain End While et de poursuivre la boucle.

V-Q-6. For Each

C'est une variante de la boucle For, mais elle permet de parcourir les objets d'une collection. Elle n'utilise pas l'indice.

Image non disponible

Prenons un contrôle ListBox il a une collection Items qui contient tous les éléments de la ListBox

ListBox.item(0) contient la première ligne

ListBox.item(1) contient la seconde ligne

ListBox.item(2)…contient la troisième.

Parcourir tous les éléments de la ListBox et les mettre dans une variable V s'écrirait :

 
Sélectionnez
Dim mystring As String

Dim item as Object

For Each item in ListBox.Items

      mystring=mystring+item

Next

La variable de boucle peut être déclarée après For :

 
Sélectionnez
Dim mystring As String

For Each item As Objet in ListBox.items

      mystring=mystring+item

Next

Au lieu de déclarer Item comme un objet, on aurait pu le déclarer comme un ListBox.Item.

Cette notion de collection est beaucoup plus large que je le pensais.

Ici pour tester chaque caractère dans une String, et voir s'il est égal à "i", on peut utiliser For Each :

 
Sélectionnez
Dim chaine As String = "aeiou"

Dim c As String

For Each car As String In chaine

    If, car= "i" ThenNext

Attention, dans une boucle For Each, on peut parcourir la collection, mais on ne peut pas modifier un élément de la collection.

V-Q-7. Switch

Switch est utilisé avec des couples d'arguments, si le premier est vrai, le second est retourné.

Réponse=Switch( Expression1, Reponse1, Expression2, Reponse2)

Si Expression2 est vrai Reponse2 est retourné.

 
Sélectionnez
Monnaie= Microsoft.VisualBasic.Switch(Pays = "USA", "Dollar", _
Pays = "FRANCE", "Euro", Pays = "Angleterre", "Livre")

Si Pays="FRANCE", cette expression est vrai, le second objet du couple est retourné.

Retourne Euro

V-Q-8. IIF

IIf est utilisé avec 3 arguments.

Si le premier argument est vrai, le second est retourné.

Si le premier argument est faux c'est le troisième qui est retourné.

 
Sélectionnez
Reponse = IIf( Nombre > 0, "Positif", "Négatif ou 0")

Comme dans Switch on peut utiliser des procédures comme argument.

V-R. Les procédures et leurs paramètres

Image non disponible

On se souvient qu'en programmation procédurale on découpe les problèmes en fonctions: les Sub et les Function.

Quand on appelle une procédure (un sous-programme, une routine), le logiciel 'saute' au sous-programme, il effectue celui-ci puis revient effectuer ce qui est sous l'appel.

Image non disponible

En VB les procédures sont des Sub ou des Function.

- Les procédures Sub

Elles débutent par le mot Sub et se terminent par End Sub. Elles ont des paramètres, mais ne 'retournent' rien.

Exemple: une sub qui retourne la somme de 2 nombres :

 
Sélectionnez
Sub Addition (a , b, result)
result= a+b
End Sub

Pour l'utiliser :

 
Sélectionnez
Dim a, b, result As Integer
a=2
b=3
Addition (a ,b ,result)

- Les procédures Function

Si on a besoin que la procédure retourne un résultat (un seul), on utilise une Fonction.

Elles débutent par Function et se terminent par End Function.

On peut fournir aux procédures des paramètres qui sont envoyés à la fonction.

Exemple :

 
Sélectionnez
Function Carré ( v as Single) As Single

    Return v*v

End Function

Cela crée une fonction qui se nomme 'Carré' , on peut lui envoyer un paramètre (elle accepte un Single dans v).

Cette fonction retourne un Single (indiqué par Function Carre() As Single) qui est le carré du paramètre fourni.

Pour l'utiliser :

 
Sélectionnez
Dim resultat As Single

resultat= Carré(2)        'resultat est alors égal à 4

On appelle la fonction carré avec le paramètre 2, elle retourne 4.

Les paramètres peuvent être des variables :

 
Sélectionnez
Dim resultat as Single

Dim valeur as Single=3

resultat= Carré(valeur)

Remarque : ici, on a un paramètre nommé 'valeur', on appelle la fonction Carré avec ce paramètre. Dans la fonction Carré on retrouve ce paramètre, il se nomme 'v' : Ce paramètre est passé à la fonction, mais il a un nom différent dans la fonction.

On conseille, quand le nom d'une procédure est composé de plusieurs mots, de mettre la première lettre de chaque mot en majuscules.

Exemple :

 
Sélectionnez
MyCalcul()

V-R-1. Les parenthèses

Rappel, même s'il n'y a pas de paramètre, mettre des () lors de l'appel de procédure.

 
Sélectionnez
MaRoutine()

V-R-2. Par Valeur, Par Référence

Il y a 2 manières d'envoyer des paramètres.

Par valeur : (By Val)c'est la valeur (le contenu de la variable) qui est envoyée.

(La variable est copiée dans une autre partie de la mémoire pour être utilisée par la routine appelée.)

Par référence : (By Ref) c'est l'adresse (le lieu physique où se trouve la variable) qui est envoyée. Si la Sub modifie la variable, cette modification sera visible dans la procédure appelante après le retour.

Exemple de procédures :

 
Sélectionnez
Sub MaProcedure (ByRef x as Long, ByVal y As Long)

End Sub

Chaque paramètre est ByRef ou ByVal suivi du nom du paramètre dans la procédure puis de son type.

Si j'appelle cette procédure à partir d'une procédure nommée Main() :

 
Sélectionnez
Sub Main()
Dim A, B As Long
         MaProcedure (A, B)

End sub

C'est l'adresse de A qui est envoyée et la valeur contenue dans la variable B. Elles se retrouvent dans les variables x et y de la procédure MaProcedure. Noter que le type de la variable fournie en paramètre dans Main et le type de la variable dans 'MaProcedure' doit être le même (ici un Long).

Si dans cette dernière je modifie x, A est modifié dans la Sub Main (puisque x et A pointe sur le même endroit). Si dans Maprocedure je modifie y, B n'est pas modifié.

Exemple permettant de bien différencier By Val et By Ref.

Exemple avec ByVal :

 
Sélectionnez
Sub MaProcedure

Dim A As Integer                                'On créer une variable A

A=1                                             'On met 1 dans A

Call MaProcedure(  A  ) 'On appelle la procédure MaProcedure  en envoyant le paramètre A 

Label1.Text= A.ToString 'On affiche la valeur de A

End Sub

 

Sub MaProcedure ( ByVal Variable As Integer )    'La procédure reçoit la valeur de A donc  1

                                                 ' et la met dans 'Variable' 

    Variable=Variable+1                           'Variable=2, mais A=1

End Sub

Après l'appel de la procédure A=1, Labe1 affiche '1', car bien que dans MaProcedure Variable =2 , cela n'a pas modifié A.

Exemple avec ByRef :

 
Sélectionnez
Sub MaProcedure

Dim A As Integer                                'On créer une variable A

A=1                                             'On met 1 dans A

Call MaProcedure(  A  ) 'On appelle la procédure MaProcedure en envoyant le paramètre A 

Label1.Text= A.ToString 'On affiche la valeur de A

End Sub

 

Sub MaProcedure ( ByRef Variable As Integer )    
'La procédure reçoit l'adresse de A ; Variable et A ont donc même adresse

                                                 'Variable et A contiennent 1 

    Variable=Variable+1                          'Variable=2, mais A=2 aussi

End Sub

Après l'appel de la procédure A=2, Labe1 affiche '2', car la procédure reçoit l'adresse de A ; Variable et A ont donc même adresse; si je modifie variable cela modifie A.

Compris !!

L'avantage de passer un argument ByRef est que la procédure peut retourner une valeur au code qui a appelé la procédure en modifiant la valeur de la variable qui a été passée en argument.

L'avantage de passer un argument ByVal est que la variable de la routine est 'protégée' dans le code qui a appelé la procédure; elle ne peut pas être modifiée par la procédure qui reçoit le paramètre.

V-R-3. Par Défaut, que se passe-t-il ?

Si on n'indique pas By Val ou By Ref…

ATTENTION : par défaut les paramètres sont transmis PAR VALEUR.

Pour la clarté du code et pour éviter toute ambiguïté, spécifier ByRef ou ByVal, c'est plus lisible, plus clair.

Taper Sub MaProcedure (ByRef x as Long, ByVal x As Long).

Plutôt que Sub MaProcedure ( x as Long, x As Long).

V-R-4. Optional

Un paramètre ou argument peut être Optional, c'est-à-dire facultatif.

Indique que cet argument n'est pas requis lorsque la procédure est appelée. Si ce mot-clé est utilisé, tous les arguments suivants doivent aussi être facultatifs et déclarés à l'aide du mot-clé Optional. Chaque déclaration d'argument facultative doit indiquer une valeur par défaut qui sera utilisée dans la routine s'il n'y a pas de paramètre.

 
Sélectionnez
Sub MaRoutine (Optional X As Integer=0)

V-R-5. Tableau de paramètres

Il est possible d'envoyer un tableau comme paramètre.

Exemple :

 
Sélectionnez
Dim Reponses(10) As Integer

'Appel de la Sub
Affiche( Reponses())

La Sub 'Affiche' débute par :

 
Sélectionnez
Sub Affiche ( ByVal R() As Integer )

End Sub

V-R-6. ParamArray

Parfois il faut envoyer des paramètres de même type, mais dont on ne connait pas le nombre, dans ce cas on utilise ParamArray (Liste de paramètres).

Exemple d'une Function nommée 'Somme' qui calcule la somme de X Integer :

 
Sélectionnez
Function Somme ( ByVal ParamArray Valeurs() as Integer) As Integer

    Dim i as Integer

    Dim Total as Integer

    For i=0 to Valeurs.Length-1

        Total += Valeurs(i)

    Next i

    Return  Total

End Sub

Pour appeler cette fonction :

 
Sélectionnez
Dim LeTotal As Integer

LeTotal= Somme (2, 5, 6, 8 ,5)

À noter que le paramètre ParamArray doit être le dernier des paramètres, c'est obligatoirement un paramètre ByVal et comme on l'a dit, tous les paramètres sont de même type.

V-R-7. Portée des procédures

Le terme Sub ou Function peut être précédé d'une indication de portée, la procédure sera-t-elle visible uniquement dans le module où elle se trouve ou partout ?

La procédure peut être Private. Dans ce cas on ne peut l'appeler qu'à partir du module qui la contient.

Les procédures événements, d'une Form sont, par exemple, Private :

 
Sélectionnez
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) _ 
 Handles MyBase.Load

End Sub

La procédure peut être Public. Dans ce cas on pourra l'appeler à partir de la totalité du programme.

La Sub 'Calcul' qui est par exemple dans un module, peut être appelée de partout.

 
Sélectionnez
Public Sub Calcul

End Sub

V-R-8. Nommage

Sub , Fonctions

Utilisez la 'case Pascal' pour les noms de routine (la première lettre de chaque mot est une majuscule).

Exemple : CalculTotal()

Évitez d'employer des noms difficiles pouvant être interprétés de manière subjective, notamment Analyse() pour une routine par exemple.

Utilisez les verbe/nom pour une routine : CalculTotal().

Pour les noms de paramètres, utilisez la 'case Camel' selon laquelle la première lettre des mots est une majuscule, sauf pour le premier mot.

Exemple : typeName.

V-S. Portée des variables

Image non disponible

Quand on déclare une variable, jusqu'où est-elle visible ?

Quand une variable est visible, on peut l'utiliser. Il est important souvent de rendre une variable visible dans une procédure, mais pas les autres, dans un seul module ou dans la totalité du programme. Comment faire cela ?

V-S-1. Dans les procédures

On déclare une variable avec Dim.

Si on déclare une variable dans une procédure (une Sub ou une Function), elle est visible uniquement dans cette procédure, c'est une variable locale :

 
Sélectionnez
Sub MaProcedure (ByRef X As Integer)

    Dim Y As IntegerEnd sub

Y est déclaré en début de procédure, on pourra travailler avec Y dans la procédure jusqu'à End Sub.

Dans une autre procédure Y ne sera pas visible (l'utilisation de Y déclencherait une erreur).

Après End Sub Y n'existe plus, son contenu est perdu.

Il en est de même pour X qui est déclaré sur la ligne Sub (X reçoit la valeur envoyée comme paramètre).

Une autre procédure pourra déclarer et utiliser une variable Y, mais, même si elle a le même nom cela ne sera pas la même : chaque variable Y est uniquement visible dans sa procédure.

Variable statique

Si à la place de Dim on utilise Static, la variable est dite 'Statique' : à la sortie de la procédure, la variable et sa valeur continue d'exister et on garde sa valeur en mémoire, lors des appels suivants de la procédure, on retrouve la valeur de la variable.

Exemple :

 
Sélectionnez
Sub compteur

    Dim A as integer

    Static B as integer

    A +=1

    B +=1

End sub

À chaque appel de cette procédure A prend la valeur, 0 puis 1 puis disparait.

B prend les valeurs 0, puis 1, puis 2… (incrémentation à chaque appel).

V-S-2. Dans un bloc d'instructions

Si vous déclarez une variable dans un bloc, elle ne sera visible que dans ce bloc :

 
Sélectionnez
Do

Dim Compteur As integer

 Compteur +=1Loop

La variable Compteur existe uniquement entre Do et Loop.

Cela est aussi valable pour les blocs If.

Exemple :

 
Sélectionnez
If A=0 Then

    Dim risk As String = "Haut"

Else

    Dim risk As String = "Bas"

End If

Console.WriteLine("Le risque est " & Risk)

Dans la dernière ligne Risk est soulignée comme contenant une erreur, car il est considéré comme non déclaré. En effet les 2 déclarations Dim risk sont dans les blocs 'If…Else' et 'Else…End If'.

Attention quand même à la position de la variable locale, il peut y avoir des pièges.

Voyons ce code :

 
Sélectionnez
Dim i, j,  As Integer

For i = 1 To 10
    For J = 1 To 3
        Dim k As Integer
        K+ =1
        'Imprimer k
    Next
Next

On souhaite que K=1 puis 2 ,3 ,1 ,2 ,3… FAUX !!

Cela donne :1 ,2 ,3 ,4 ,5 ,6 ,7… 30 !!!??? pas normal

En remplaçant par Dim k As Integer = 0 cela donne des 1 ,1 ,1 ,1 ,1 , 'normal

Et en intercalant la déclaration de k entre les 2 For, cela marche comme on le souhaite:1, 2 ,3 ,1 ,2 ,3.

 
Sélectionnez
Dim i, j,  As Integer

For i = 1 To 10 

    Dim k As Integer
    For J = 1 To 3
        K+ =1
        'Imprimer k
    Next
Next

V-S-3. Dans la section déclaration d'un Module

Dans la section déclaration d'un module (en haut du module juste après la ligne 'Module'), on utilise à la place de Dim.

Private, dans ce cas la variable est propre au module, elle est visible dans toutes les procédures du module, pas dans les autres modules.

Public, dans ce cas la variable est accessible dans la totalité du programme.

 
Sélectionnez
Module Module1

    Public A as StringSub MaRoutine

 End Sub

End Module

A est accessible partout dans la totalité du programme.

(On parle dans ce cas de variable dite 'Globale'.)

V-S-4. Dans la section déclaration d'une fenêtre, d'un formulaire

Dans la section déclaration d'un formulaire (en haut du formulaire juste après la ligne 'Inherits').

Private: indique dans ce cas que la variable est propre au formulaire, elle est visible dans toutes les procédures du formulaire, pas dans les autres modules ou formulaires.

Public : indique de même une variable UNIQUEMENT visible dans le formulaire.

Elle est visible hors du formulaire à condition de la préfixer avec le nom du formulaire (Class1.A).

 
Sélectionnez
Class Class1

   Inherits System.Windows.Forms

    Public A as StringSub MaRoutine

 End Sub

End Class

Exemple

On peut atteindre la zone de déclaration en déroulant le menu de droite.

Image non disponible

Dans l'exemple ci-dessus :

MaVariable est visible dans le formulaire et hors du formulaire à condition d'utiliser Form1.MaVariable ;

MaVariable2 est visible dans le formulaire ;

MaVariable3 n'est visible que dans la procédure Button1_Click.

V-S-5. En pratique

Pour se repérer et se souvenir quelle est la portée d'une variable, on utilise une lettre en début du nom de la variable (notation avec un préfixe dite 'hongroise') :

g_MaVariable sera public (g comme global) ;

m_Variable2 sera accessible au niveau du module.

Dans un module standard, on peut mettre 'Public' toutes les variables que l'on veut rendre accessibles à tout le programme. Ce sont les variables (et constantes) générales utilisées dans la totalité de l'application : état du programme, utilisateur en cours…Pour des raisons que nous verrons plus loin, il faut éviter ce type de variable publique dite 'globale'.

Dans chaque formulaire on met dans la section déclarations, les variables du module : état du formulaire. Variable permettant l'affichage…

Dans chaque procédure les variables locales, compteur de boucle…

Pour les variables locales, on peut donc utiliser un même nom dans différentes procédures, par exemple, on nomme souvent I les variables de boucle dans toutes les procédures, par contre

il faut éviter de donner un même nom à des variables dont la portée se recoupe.

VB l'accepte et utilise la variable la plus proche, celle du bloc ou du module…mais c'est dangereux et générateur de bugs.

De manière générale, utiliser des variables avec une portée la plus réduite possible.

V-S-6. En général

Que ce soit pour les variables, procédures ou Classes :

-les variables qui sont Dim sont accessibles dans une procédure ;

- celles qui sont Public sont accessibles dans la totalité du programme ;

- celles qui sont Private ne sont accessibles qu'à l'intérieur même du module.

il y a en plus :

- celles qui sont Protected sont similaires aux Private, mais dans le cas des classes, elles ont une particularité en cas d'héritage ;

- celles qui sont Friend ne sont accessibles qu'à l'intérieur du projet, et pas par des éléments extérieurs au projet en cours.

V-T. Les nombres aléatoires

Image non disponible

Comment obtenir un nombre aléatoire ?

V-T-1. Avec la classe 'Random' du Framework

Il existe une classe (faisant partie de System ) nommée Random.

La méthode Next() retourne un Integer positif entre 0 et 2 147 483 647

La méthode NextDouble() retourne un Double entre 0 et 1.

La méthode NextBytes() retourne un Byte (octet)

On peut surcharger ces méthodes pour définir des bornes.

Exemple

J'instancie un objet à partir de la classe.

 
Sélectionnez
Dim Al As New Random

L'objet Al est initialisé avec une valeur probablement liée au temps, à l'horloge interne, aussi l'initialisation est 'aléatoire'.

Pour obtenir un nombre (un double) entre 0 et 1 (toujours inférieur à 1), j'écris :

 
Sélectionnez
MonNombrealeatoire=Al.NextDouble

Ensuite chaque NextDouble génère le nombre aléatoire suivant (à partir d'une formule).

Noter bien que dans ce qui précède, si on fait plusieurs fois Dim Al As New Random , le nombre obtenu par NextDouble n'est jamais le même.

Par contre, si on fait :

 
Sélectionnez
Dim Al As New Random(1)

MonNombrealeatoire=Al.NextDouble

MonNombrealeatoire=Al.NextDouble

On obtient toujours :

'0.248668584157093'

'0.110743977181029'

On obtient donc la même série, car on a imposé avec Random(1) une valeur de départ qui est fonction de (1) et non du temps.

Pour obtenir un nombre aléatoire entre 0 et 10, on utilise Next :

 
Sélectionnez
Dim Al As New Random()

MonNombrealeatoire=Al.Next(10)

MonNombrealeatoire=Al.Next(10)

On obtient la série: 2, 1, 4, 7, 6, 4, 3, 9

On travaille sur des 'Integer'.

Pour obtenir un nombre aléatoire entre 5 et 10 (mais < à 10), on utilise Next :

 
Sélectionnez
Dim Al As New Random()

MonNombrealeatoire=Al.Next(5,10)

MonNombrealeatoire=Al.Next(5,10)

La série comportera les nombres integers 5, 6, 7, 8, 9 (pas 10).

Pour remplir un tableau d'octets avec des octets aléatoires, on utilise NextBytes :

 
Sélectionnez
Dim rnd As New Random()
Dim b(10) As Byte
rnd.NextBytes(b)

V-T-2. Avec les instructions Rnd() et Randomize() de Visual Basic.Net

On peut utiliser les instructions VB. Ne faut-il pas mieux utiliser le Framework ?

Rnd() fournit un nombre aléatoire entre 0 et 1 (sans jamais atteindre 1):valeur inférieure à 1, mais supérieure ou égale à zéro; ce nombre aléatoire est un Single.

En fait ,si on fait des Rnd() successifs, le nombre aléatoire précédemment généré est utilisé pour le calcul du nombre aléatoire suivant (avec une formule mathématique complexe), ce qui fait que la suite de nombres aléatoires est toujours la même et qu'elle est périodique (au bout d'un grand nombre de tirages, on recommence la même suite).

Randomize() initialise le générateur de nombres aléatoires. Si on ne donne pas d'argument, Randomize utilise la valeur de l'horloge interne pour initialiser; cette valeur est due au hasard, aussi le Rnd qui suit va être dû au hasard.

Si on n'utilisait pas Randomize() avant Rnd(), la fonction Rnd() fournirait toujours les mêmes nombres aléatoires dans le même ordre.

En résumé

Rnd , s’il n'y a pas d'argument, fournit une suite de nombre pseudo aléatoire (le suivant étant calculé à partir du précédent), la suite est toujours la même, seule le premier change et est initialisé par Randomize qui est basé soit sur l'horloge système (et qui a priori initialise à une valeur toujours différente) s'il n'y a pas d'argument soit sur un argument.

Pour obtenir plusieurs fois les mêmes séries de nombres, utilisez Randomize avec un argument numérique puis appelez Rnd() avec un argument négatif.

Simuler un jeu de lancer de dé

Comment obtenir un nombre entier entre un et six au hasard ?

 
Sélectionnez
Dim MyValue As Integer

Randomize   ' Initialise le générateur de nombre aléatoire.

MyValue = CInt(Int((6 * Rnd()) + 1)) ' Génère un nombre aléatoire entre 1 et 6.

Rnd() fournissant un nombre aléatoire entre 0 et 1, je le multiplie par 6 et j'ajoute 1 pour qu'il soit entre 1 et 7 sans atteindre 7 (il peut être entre 1 et 6,999), je prends sa valeur entière : il est maintenant entre 1 et 6, enfin je le transforme en Integer.

V-T-3. En cryptographie avec le Framework

Pour remplir un tableau d'octets avec des octets aléatoires forts d'un point de vue cryptographique (pour générer un mot de passe par exemple), on utilise plutôt la classe RNGCryptoServiceProvider()

L'exemple suivant crée une séquence aléatoire de 100 octets de long et la stocke dans ra.

 
Sélectionnez
Imports System.Security.Cryptography

Dim ra() As Byte = New Byte(100) {}
Dim rng As New RNGCryptoServiceProvider()
rng.GetBytes(ra) ' les octets dans ra sont maintenant aléatoires.

Il existe aussi GetNonZeroBytes pour ne pas avoir d'octet=0.

V-T-4. Un peu de théorie

Image non disponible

Un nombre aléatoire est obtenu par tirage au sort à égalité des chances, il est impossible de prévoir le tirage suivant.

Il existe des procédures physiques permettant de générer des nombres aléatoires : comptage de désintégration par compteur Geiger, analyse de bruit…

En informatique, on utilise les nombres pseudo aléatoires générés par des algorithmes.

L'implémentation actuelle de la classe Random est basée sur l'algorithme du générateur de nombres aléatoires soustractif de Donald E. Knuth. Pour plus d'information, consultez D. E. Knuth. "The Art of Computer Programming, volume 2 : Seminumerical Algorithms." Addision-Wesley, Reading, MA, deuxième édition, 1981.

Soit un nombre de départ x (nommé' graine'ou seed en anglais)

Le nombre est utilisé pour le calcul du nombre aléatoire suivant (avec une formule mathématique complexe), ce qui fait que la suite de nombre aléatoire est toujours la même pour une même graine et qu'elle est périodique.

La formule, dite générateur à congruence linéaire, pour trouver le nombre suivant, est de la forme :

Xn+1 = (aXn+b) mod m

xn+1 = (1 664 525 xn + 1 013 904 223) mod 232 (générateur de Knuth & Lewis)

Voir l'excellent article sur les nombres pseudo aléatoires:Article de P larbier :http://www.alrj.org/docs/algo/random.php

et l'excellent site de D. Müller: www.apprendre-en-ligne.net/random/index.html

On a vu que le générateur est périodique: au bout d'un certain nombre de tirages pseudo aléatoire, dès qu'un nombre apparait la seconde fois, on recommence la même série. En théorie, la période maximale serait m de mod m dans la formule soit 232.

Quelle est la période de la Classe Random en pratique?

Période: 81 672 063 avec Next (Integer)

Période: 562 183 903 avec NextDouble (Double)

C'est un ordre de grandeur, car en fonction de la graine (valeur de départ), la série et la période sont différentes (j'ai essayé !).

Tout l'art est de choisir la graine (le premier nombre) aléatoirement!!Cela est effectué par Randomize en VB ou l'instanciation d'un objet Random. Randomize utilise par exemple la valeur de l'horloge interne pour initialiser, cette valeur serait due au hasard

Amélioration

Comment générer des nombres plus aléatoires que les pseudo aléatoires ?

1- Solution créée par le programmeur

Le nombre aléatoire est la combinaison d'un nombre pseudo aléatoire et d'un nombre probablement aléatoire par exemple :

- Position de la souris

Temps entre 2 pressions sur des touches.

- Statistique d'activité du disque dur.

- Temps écoulé depuis… (Ce que fait randomize).

Exemple

Le nombre aléatoire est le produit d'un nombre pseudo aléatoire et du nombre de secondes écoulé depuis une date :

 
Sélectionnez
        Dim pAlea As Double    'Nombre pseudo aléatoire 

        Dim second As Double   'Nombre de secondes depuis le 30/12/96 

        Dim Alea  As Double    'Nombre aléatoire 

        Randomize 

        pAlea = Int((1000000 * Rnd) + 1) 

        second = DateDiff("s", "12/30/96", Now) 

        Alea =  second *pAlea

Il y a des biais, en particulier, si on utilise régulièrement cette routine, le nombre de secondes est régulièrement croissant. On pourrait améliorer en utilisant second Mod quelque chose.

2- Solution proposée par le Framework

Méthode utilisée dans la classe System.Security.Cryptography

Le générateur doit être capable de produire des nombres aléatoires résistant à des attaques ou à des analyses statistiques qui permettraient de prédire la suite.

Les méthodes courantes pour générer des nombres aléatoires en cryptographie consistent à utiliser diverses sources disponibles sur un ordinateur : temps entre deux accès au disque, taille de la mémoire, mouvements du pointeur de la souris… et à faire passer le résultat dans une fonction de hachage cryptographique comme MD5 ou SHA-1 puis à utiliser cette valeur comme graine puis…

V-U. La 'Récursivité'

La récursivité c'est quoi ?

Exemple trouvé sur developpeur.journaldunet.com :

Image non disponible

"C'est l'histoire d'un petit garçon qui ne voulait pas dormir et dont la mère lui raconte l'histoire de la petite grenouille qui ne voulait pas dormir et dont la mère lui raconte l'histoire de l'ourson qui ne voulait pas dormir et dont la mère lui raconte l'histoire du bébé écureuil qui s'est endormi, et l'ourson s'endormit, et la petite grenouille s'endormit, et le petit garçon s'endormit."

Cette histoire, permet de mieux voir ce qui se produit lors de la récursivité : la procédure (le petit qui ne dort pas et à qui on raconte une histoire) appelle, la même procédure (le petit qui ne dort pas et à qui on raconte une histoire) qui appelle la même procédure… on passe au "niveau" suivant puis au suivant tant qu'on n'a pas atteint la condition d'arrêt (ici, l'endormissement). Celle-ci atteinte, la récursion se termine pour les autres niveaux en sens inverse en remontant.

Une procédure est récursive si elle peut s'appeler elle-même.

VB accepte les procédures récursives :

 
Sélectionnez
Sub Calcul()

…

    Calcul()

…

End Sub

On voit ici que la procédure Calcul() s'appelle elle même: la ligne centrale appelle de nouveau la procédure Calcul() avec nouveaux paramètres, nouvelles variables locales, à la sortie de la procédure (après End Sub), retour à la 'version' précédente de la procédure Calcul() ou on retrouve les variables de la précédente version.

Une procédure non récursive appelle, elle, d'autres procédures.

Pourquoi utiliser la récursivité ?

Une procédure récursive découpe le problème en morceaux plus petits et s'appelle elle-même pour résoudre chacun des plus petits morceaux, elle résout une petite partie du problème elle-même.

 
Sélectionnez
Sub Calcul(Gros)

        If… 

           Résout petit problème

        Else

           Découpe

           Calcul(Petit)

        End If

End Sub

Ici 'Résout petit problème' s'appelle le point terminal ou le point d'arrêt, c'est la branche qu'une condition qui n'appelle pas de nouveau la fonction Calcul(). C'est indispensable.

Ou bien elle découpe le problème en plus petits morceaux et pour chaque morceau on appelle de nouveau la procédure :

 
Sélectionnez
Sub Calcul(Gros)

        If… 

           Découpe

           Calcul(Petit)

        End If

End Sub

À un moment donné, la condition n'est pas remplie, cela correspond au point terminal.

On se rend compte qu'une bouche For Next peut être transformée en procédure récursive.

Exemple 

Créons une procédure qui ajoute N éléments par ordre décroissant (ajoute l'élément N puis N-1 puis … 2 puis 1).

On l'appelle avec Calcul(10) par exemple :

avec For :

 
Sélectionnez
Function Calcul(N As Integer)

    Dim total As Integer

    For i= N to 1 Step-1 

         total=total + i 

     Next i 

    Calcul=total       

End Function

 

'Avec la récursivité:

Function Calcul(N As Integer)

    Dim total As Integer

    If N>0 Then

         total= N+ Calcul (N-1)

     End If

    Calcul= total

End Fonction

On l'appelle avec Calcul(10)

Mais la récursivité ne sert pas seulement à cela, elle sert à résoudre aussi des problèmes qui seraient extrêmement complexes en programmation non récursive.

V-U-1. Règles fondamentales d'une fonction récursive

1-La récursivité doit s'arrêter à un moment donné.

Il doit y avoir un point terminal (ou point d'arrêt).

Il doit y avoir dans la fonction récursive, une expression conditionnelle dont au moins un des cas conduit à une expression évaluable.

Il doit donc y avoir un chemin non récursif (chemin où la fonction ne s'appelle pas de nouveau).

Il doit y avoir un test qui survient obligatoirement et qui arrête le fonctionnement récursif sinon la fonction tourne sans fin (ou du moins, elle plante quand la pile est pleine).

2- À aucun moment les paramètres appelant de nouveau la fonction ne doivent être les mêmes que l'appel précédent.

Sinon cela tournera indéfiniment.

3-Le nombre d'appels récursifs ne doit pas être très grand.

Sous peine de 'StackOverflow' : la pile des appels qui stocke les adresses de retour de chaque appel récursif est pleine, elle dépasse ses capacités.

Certains ajoutent dans le code de la fonction récursive 'un compteur de sécurité' :

 
Sélectionnez
Sub Calcul(ByRef Compteur As Long)

If Compteur> LIMITE Then  Exit Sub

Compteur= Compteur+1Calcul(Compteur)

…

End Sub

Noter que le compteur est un paramètre ByRef, ce qui permet de toujours incrémenter la même variable.

Voir exemple sur les fractales.

4-La fonction récursive ne doit pas déclarer un grand nombre de variables ou d'objets.

Sous peine d'occuper une place trop importante en mémoire.

5-Limiter les fonctions récursives à une seule procédure, éviter plusieurs fonctions récursives imbriquées.

Sinon cela devient vite trop complexe.

6- Chaque fois qu'elle est appelée de manière récursive (par elle-même, donc), un ou plusieurs des arguments qui lui sont transmis doivent se rapprocher de la condition d'arrêt.

Sinon il n'y aura pas d'arrêt.

7- La complexité du problème doit être réduite à chaque nouvel appel récursif.

8- Ne peut-on pas faire plus simple avec une boucle For Next ?

Parfois une boucle simple remplace avantageusement une fonction récursive. Dans ce cas, utiliser la boucle !!

C'est le cas de la fonction factorielle !!

V-U-2. Exemple 1 : Inversion de chaines

Soit une chaine de caractères, on veut une fonction qui inverse cette chaine: dernier caractère en premier, avant-dernier en second…

Exemple: "abcd" retournera "dcba"

Principe de la fonction 'inverse' récursive:

La fonction 'inverse' met le dernier caractère au début et appelle la fonction 'inverse' avec comme paramètre la chaine moins le dernier caractère.

Exemple "abcd", on met "d" au début et rappelle la fonction inverse avec comme paramètre "abc".

Point d'arrêt : si la chaine est vide, plus d'appel récursif, on retourne une chaine vide.

 
Sélectionnez
Function inverse(ByVal st As String) As String

If st = "" Then

   inverse = ""

Else

   inverse = st.Substring(st.Length() - 1, 1) + inverse(st.Substring(0, st.Length() - 1))

End If

End Function

V-U-3. Exemple 2 : Calcul de 'Factorielle'

On rappelle que N! (factorielle N)= 1*2*3*…*(N-2)*(N-1)*N

Exemple Factorielle 3 =1*2*3 :

 
Sélectionnez
Dim R As Long

R=Factorielle(3)    'retournera 6

Cette fonction n'est pas fournie par VB, créons une fonction Factorielle SANS récursivité :

 
Sélectionnez
Function Factorielle (ByVal N as Long) As Long

    Dim i As Long

    Resultat=1

    For i= 1 to N

        Resultat=i* Resultat

    Next i

    Return Resultat

end Function

Cela crée une fonction recevant le paramètre N et retournant un long.

La boucle effectue bien 1*2*3…*N-1*N.

Factorielle avec 'Récursivité' :

Une autre manière de calculer une factorielle est d'utiliser la récursivité.

Comment faire ?

On sait que N!= N * (N-1) * (N-2)… 3 * 2 * 1

on remarque donc que Factorielle N!= N * Factorielle(N-1)

N!= N*(N-1)! : en sachant que 1!=1

Créons la fonction.

Si N=1 la fonction retourne 1 sinon elle retourne N* factorielle(N-1) :

 
Sélectionnez
Function Factorielle (ByVal N as Long) As Long

    If N=1 then

        Return 1

    Else

        Return N* Factorielle(N-1)

    End If

end Function

Dans la fonction Factorielle on appelle la fonction Factorielle, c'est bien récursif.

Pour N=4.

La fonction 'descend' et appelle chaque fois la factorielle du nombre inférieur.

La fonction Factorielle est appelée 4 fois :

Factorielle(4) appelle Factorielle(3) qui appelle Factorielle(2) qui appelle Factorielle(1)

Puis la fonction remonte en retournant le résultat de chaque factorielle.

Factorielle(1) retourne 1

Factorielle(2)retourne 2 '2*factorielle(1)

Factorielle(3)retourne 6 '3*factorielle(2)

Factorielle(4) retourne 24 '4*factorielle(3)

Vb gère cela avec une pile des appels. il met dans une pile les uns au-dessus des autres les appels, quand il remonte, il dépile de haut en bas (dernier rentré, premier sorti).

Attention : la pile a une taille maximum, si N est trop grand, on déclenche une erreur de type StackOverflow.

V-U-4. Exemple 3 : Calcul d'une expression avec parenthèses multiples

Comment calculer la valeur de la chaine "(4+2(2*8)-(5/(8+1)))"

Une partie du code nommée Calculsimple sait calculer une chaine de type "8+1" ou "4+2" sans parenthèses.

Il faut gérer les parenthèses : la sub découpe ce qui est entre parenthèses et s'appelle elle-même pour calculer ce qui est entre parenthèses.

La sub calcul fait 2 choses.

S'il y a des parenthèses : appelle Calcul() avec comme paramètre la chaine entre parenthèses puis remplace la chaine entre parenthèses par sa valeur.

S’il n'y a pas de parenthèses calcule l'expression simple (= - * /).

Voici l'algorithme :

 
Sélectionnez
Sub Calcul(Chaine As String) As String

    Si  Chaine contient  "("

        Decouper ValeurEntreParenthese

        Resultat=Calcul (ValeurEntreParenthese)        'Appel récursif

        Remplacer (ValeurEntreParenthese) par Resultat

    Sinon

        CalculSimple

    Fin Si

End Sub

V-U-5. Exemple 4 : PGCD

On rappelle que le PGCD est le 'Plus Grand Commun Diviseur'.

Soit a et b 2 nombres :

Si b divise a => PGCD=b. sinon, PGCD(a,b) = PGCD(b, a mod b)

 
Sélectionnez
Function PGCD(ByVal P As Long, ByVal Q As Long) As Long

If Q Mod P = 0 Then

Return P

Else

     Return PGCD(Q, P Mod Q)

End If

V-U-6. Exemple 5 : Tri récursif

Tri récursif

Le principe est que la fonction récursive scinde le tableau en 2 et pour chaque partie appelle de nouveau le tri récursif, la condition d'arrêt survient quand le dernier élément est < ou = au premier.

Dans un premier temps on range le tableau de telle sorte que tous les éléments inférieurs à l'élément d'indice pivot se trouvent placés à la gauche de celui-ci et donc tous les éléments supérieurs à sa droite. Ensuite on appelle à nouveau (récursivement) la procédure QuickSort pour chacun des deux sous-tableaux.

Cette méthode de tri récursif qui se nomme QuickSort est proportionnellement efficace au désordre du tableau à trier. Cette méthode mettra plus de temps (qu'une autre méthode) à trier un tableau qui est déjà en partie trié qu'un tableau rangé au hasard… Mais en cas de désordre intégral, c'est certainement la plus rapide.

 
Sélectionnez
Sub QuickSort(debut As Integer, fin As Integer)
Dim pivot, gauche, droite, temp  As Integer

  pivot  = debut
  gauche = debut
  droite = fin
  do
    if t(gauche) >= t(droite) then
    'échanger si nécessairet(droite) et t(gauche)
      temp = t(gauche)
      t(gauche) = t(droite)
      t(droite) = temp
      pivot = gauche + droite - pivot 'nouvelle position du pivot
                     'pivot est alors égal à droite ou à gauche, car pivot était avant égal
                     'à gauche ou à droite
    End If
    if pivot = gauche then droite=droite-1 else gauche=gauche+1
  loop until gauche = droite
  if debut < gauche - 1 then QuickSort(debut, gauche - 1) ' //appel récursif sur la partie gauche
  if fin > droite + 1 then QuickSort(droite + 1, fin)  'appel récursif sur la partie droite
End Sub

Comment l'utiliser

On crée un tableau Public d'integer contenant les valeurs à trier :

 
Sélectionnez
Public t() As Integer = {10, 2, 7, 4, 1, 3, 12, 6}
 
Sélectionnez
Dim i As Integer

Call QuickSort(0, 7) 'paramètre= premier et dernier élément du tableau

Affichage du tableau trié dans une texteBox1

 
Sélectionnez
For I = 0 To 7

TextBox1.Text = TextBox1.Text + ControlChars.CrLf + t(i).tostring

Next

V-U-7. Exemple 6 : Parcours de répertoires et de sous répertoires

On veut afficher dans une ListBox les noms des répertoires, sous-répertoires et fichiers.

On crée une routine AfficheTree qui affiche :

- le nom du répertoire courant ;

- le nom des fichiers du répertoire courant ;

- qui parcourt les sous-répertoires et pour chacun d'eux appelle AfficheTree :

 
Sélectionnez
Imports System.IO

 

Sub  AfficheTree ( ByVal myDir As String, ByVal Optional Niveau As Integer =0)


'Affiche le répertoire myDir

List1.Items.Add(New String (" ", niveau *2) & myDir)

 

'Affiche les fichiers

For Each fichier As String  In Directory.GetFiles( myDir)

    List1.Items.Add(New String (" ", niveau *2+2) & fichier)

Next

 

'Parcourt les sous-répertoires

For each sousRepertoire As String In Directory.GetDirectories( myDir)

    'Appel de manière récursive 'AfficheTree pour afficher le contenu des sous répertoires.

    AfficheTree (sousRepertoire, niveau+1)

Next

 

End Sub

V-U-8. Exemple 7 : Évaluation d'un nombre écrit en chiffres romains

On veut taper III et voir s'afficher 3.

Taper M et voir s'afficher 1000.

Taper XLVIII et voir s'afficher 48.

On remarque (je ne l’ai pas fait tout seul !!) que :

chaque caractère romain a une valeur (I=1, V=5, X=10, L=50, C=100, D=500, M=1000) ;

pour deux caractères, on compare leurs valeurs :

si le premier est plus petit, on le soustrait au second: IX = 10 - 1 = 9 ;

si le premier est plus grand, on l'ajoute au second: VI = 5 + 1 = 6.

Pour une suite de n caractères : en partant de la gauche, si le premier chiffre a une valeur inférieure au deuxième, alors on le soustrait de la valeur de tout le reste, sinon on l'additionne à la valeur de tout le reste…

Le programme va donc comparer la valeur des 2 caractères de gauche, il va ajouter (si la valeur du premier est plus grande) ou soustraire (si la valeur du premier est plus petite) la valeur du premier caractère à la valeur de la chaine raccourcie du premier caractère.

Exemple : pour XLVIII

 
Sélectionnez
X plus petit que L  donc  -10 +valeur de (LVIII)

L plus grand que V  donc  -10 +50 + valeur de (VIII)

V plus grand que I  donc  -10 +50 + 5 + valeur de (III)

….

Il faut créer une routine nommée valeur qui calcule la valeur d'un caractère.

Et la routine Eval qui calcule l'expression.

S'il y a un caractère dans la chaine c passée en paramètre, on retourne sa valeur, s'il y en a plusieurs, on compare les 2 premiers caractères, et on additionne ou soustrait à la valeur du premier caractère l' Eval (appel récursif) du reste de la chaine.

 
Sélectionnez
Function valeur(ByVal c As Char) As Integer

Select Case c

Case "M"c : valeur = 1000

Case "D"c : valeur = 500

Case "C"c : valeur = 100

Case "L"c : valeur = 50

Case "X"c : valeur = 10

Case "V"c : valeur = 5

Case "I"c : valeur = 1

End Select

End Function

 

 

Function eval(ByVal s As String) As Integer

 

Dim n As Integer

 

If s.Length = 1 Then

    eval = valeur(s.Chars(0))

Else

    n = valeur(s.Chars(0))

    If n < valeur(s.Chars(1)) Then n = -n

        eval = n + eval(s.Substring(1, s.Length - 1))

    End If

End Function

Si on veut tester : créer dans une form 2 texteBox : TextDecimal, TextRomain et un bouton Button1 :

 
Sélectionnez
Private Sub Button1_Click

  TextDecimal.Text = eval(TextRomain.Text).ToString

End Sub

V-U-9. Exemple 8 : Suite de Fibonacci

"Possédant initialement un couple de lapins, combien de couples obtient-on en douze mois si chaque couple engendre tous les mois un nouveau couple à compter du second mois de son existence ?"

On suppose que :

  • le premier mois, il y a juste une paire de lapins ;
  • les lapins ne sont pubères qu'à partir du deuxième mois ;
  • chaque mois, toute paire susceptible de procréer engendre effectivement une nouvelle paire de lapins ;
  • les lapins ne meurent jamais (donc la suite de Fibonacci est strictement croissante).

Sont notés en gras, les couples productifs.

En janvier : 1 couple
En février : 1 couple
En mars : 1 + 1 = 2 couples
En avril : 1 + 2 = 3 couples
En mai : 2 + 3 = 5 couples
En juin : 3 + 5 = 8 couples
En juillet : 5 + 8 = 13 couples
En août : 8 + 13 = 21 couples
En septembre : 13 + 21 = 34 couples
En octobre : 21 + 34 = 55 couples
En novembre : 34 + 55 = 89 couples
En décembre : 55 + 89 = 144 couples

Les réponses constituent les nombres de la suite de Fibonacci : 1 - 1 - 2 - 3 - 5 - 8 - 13 - 21 - …, dont chaque terme à partir du 3e est la somme des deux précédents.

 
Sélectionnez
Function Fibonacci(ByVal n As Integer)

' si n > 91, cela entraine un overflows sur les long.

Dim result As Long = 0

 

If n < = 2 Then

    result = 1

Else

    result = Fibonacci(n - 1) + Fibonacci(n - 2)

End If    

 

Return result


End Function

Programme itératif correspondant :

 
Sélectionnez
Function Fibonacci2(ByVal n As Integer)

Dim u, v, w, i As Long

 

If n <= 0 Then Return 0

If n = 0 Then Return 1

 

u = 0

v = 1

For i = 2 To n

w = u + v

u = v

v = w

Next

 

Return v

End Function

V-U-10. Exemple 9 : Fractales

Calculs de fractales

Les fonctions fractales sont des fonctions récursives théoriquement infinies…

Le Flocon de Koch, du nom du mathématicien suédois Helge Von Koch (1870-1924), est une courbe fermée, reproduisant un triangle équilatéral à des échelles de plus en plus petites. En répétant ce processus une infinité de fois, la courbe obtenue possède alors un périmètre infini, mais une aire limitée. Pour ce faire, chaque segment formant un triangle équilatéral est lui-même décomposé en un triangle équilatéral dont la base mesure un tiers du segment, centrée et confondue à ce segment.

On va donc créer une fonction récursive nommée 'flocon' qui décompose un segment en ajoutant un triangle puis qui pour chaque segment appelle la fonction 'flocon.

Comme on ne peut pas afficher des points infiniment petits, on va ajouter une condition d'arrêt qui est déclenchée par le nombre d'appels récursifs. Si la condition d'arrêt est remplie, on dessine le segment.

Image non disponible
Image non disponible
Image non disponible
Image non disponible

Voici la fonction récursive :

 
Sélectionnez
Private Sub Flocon(ByRef gh As Graphics, ByVal a As Point, ByRef b As Point, ByRef n As Integer)

'procédure récursive pour dessiner la fractale de Von Koch

Dim d, c, e As Point

Dim Couleur As Color = Color.Aqua

 

If n = 0 Then

    'Condition de sortie de la récursivité

    gh.DrawLine(New Pen(Color.Red), a.X, a.Y, b.X, b.Y)

Else

    'Appel récursif

    c = Tiers(a, b)

    d = Tiers(b, a)

    e = Sommet(c, d)

    Flocon(gh, a, c, n - 1)

    Flocon(gh, c, e, n - 1)

    Flocon(gh, e, d, n - 1)

    Flocon(gh, d, b, n - 1)

End If

 

End Sub

Pour que cela fonctionne, il faut les deux routines suivantes :

 
Sélectionnez
Private Function Sommet(ByRef a As Point, ByRef b As Point) As Point

'Calcule le sommet du triangle équilatéral

'dont la base est définie par 2 points

    Sommet.x = (b.x + a.x) / 2 + (b.y - a.y) * Racine3Sur2

    Sommet.y = (b.y + a.y) / 2 - (b.x - a.x) * Racine3Sur2

End Function

 


 

Private Function Tiers(ByRef a As Point, ByRef b As Point) As Point

'Calcul le premier tiers d'un segment

'Attention: Le résultat est orienté

    Tiers.x = (b.x - a.x) / 3 + a.x

    Tiers.y = (b.y - a.y) / 3 + a.y

End Function

Pour utiliser cet exemple, il faut dans un formulaire un PictureBox nommé PictureBox1 pour afficher la fractale, un TextBox1 permettant de saisir le nombre d'appels récursifs ( ne pas dépasser 9 en pratique), et un bouton command1 exécutant le calcul et l'affichage.

Mettre en haut du module :

 
Sélectionnez
Const Racine3Sur2 As Double = 0.866025404
 
Sélectionnez
Private Sub Command1_Click(ByVal eventSender As System.Object, ByVal eventArgs As System.EventArgs) Handles Command1.Click

Dim newBitmap As Bitmap = New Bitmap(400, 400)    'créons un BitMap

Dim g As Graphics = Graphics.FromImage(newBitmap) 'créons un Graphics et y mettre le BitMap

Dim t As Integer

 

'déclarons les 3 points du triangle initial

Dim a(2) As Point

Dim b(2) As Point

 

'donnons une valeur à 2 points, calculons le troisième 

a(0).X = 164 

a(0).Y = 10 

b(1).X = 20 

b(1).Y = 260 

b(0) = Sommet(a(0), b(1))

a(1) = b(0)

a(2) = b(1)

b(2) = a(0)

 

'Pour chaque côté

For t = 0 To 2

  'Appelons la fonction récursive  

    Flocon(g, a(t), b(t), Val(TextBox1.Text))

Next t

 

'Affichons

PictureBox1.Image = newBitmap

 

End Sub

Code issu d'un code VB6 situé sur CodeS-SourceS VBFrance.com écrit par D. Thuler et transcrit par moi en VB.Net.Merci David.

V-U-11. Autre

Recherche de chemin dans un labyrinthe.

Le principe est que la fonction récursive teste le déplacement à droite, à gauche, en haut, en bas. La condition d'arrêt se produit quand on a trouvé la sortie; les endroits où on est déjà passé sont notés.

L'article http://recursivite.developpez.com/ donne des exemples et des explications extraordinaires de programmes récursifs EN PASCAL. Si vous avez le courage de les traduire en VB , envoyez-les-moi !!

V-V. Faut-il oublier le GoTo ?

Et hop!! On saute..
Et hop !! On saute…

Le Goto c'est quoi ?

Faut-il utiliser le GoTo ?

V-V-1. Le 'Goto'

L'instruction GoTo permet de transférer le contrôle à l'emplacement d'une étiquette (on dit parfois un label) locale.
Une étiquette permet de localiser un endroit du code Les étiquettes sont toujours terminées par un deux-points ":".

Goto permet un saut non conditionnel : aller à, sauter vers une étiquette :

 
Sélectionnez
GoTo FIN

A=2

B=A+2

FIN:

FIN: est une étiquette, un mot en début de ligne qui désigne un endroit du code; pour créer une étiquette, taper en début de ligne un mot suggestif de l'endroit, puis ajouter ":".

Le programme saute de la ligne GoTo FIN à l'étiquette FIN: puis se poursuit après FIN (Les instructions entre Goto FIN et FIN : ne sont pas exécutées :

Le GoTo est souvent utilisé avec une instruction If (pour rendre le saut conditionnel):

 
Sélectionnez
If A=0 Then GoTo FIN

…

FIN:

V-V-2. Pourquoi éviter le 'GoTo'

L'utilisation du GoTo est peu élégante et à éviter:

Cela casse la structure du code qui se déroule de haut en bas, le cheminement du programme est moins évident, moins visible; s'il y a plusieurs GoTo le programme devient vite illisible.

On parle dans ce cas de "code spaghetti" Image non disponible ou de "code kangourou" (à cause des sauts).
Dans la programmation structurée, il faut bannir le 'GoTo'. On le remplacera avantageusement par des If…Then et des boucles.

Exemple

On peut remplacer avantageusement la ligne :

 
Sélectionnez
If A=0 Then GoTo FIN 

B=1

FIN:

Par :

 
Sélectionnez
If A<>0 Then 

    B=1

End if

Autre exemple

Saisir à l'aide d'une InPutBox un nombre. S'il n'est pas entre 1 et 31, ressaisir.

Avec GoTo :

 
Sélectionnez
Dim réponse As String 

Question:

réponse= InPutBox ("Donner un nombre entre 1 et 31")

If Val(Reponse)<1 Or Val(Reponse) >31 Then GoTo Question

Sans GoTo :

 
Sélectionnez
Dim réponse As String 

While Val(Reponse)<1 Or Val(Reponse) >31

    réponse= InPutBox ("Donner un nombre entre 1 et 31")

Wend

V-V-3. Quand utiliser le 'GoTo'

Il est cependant parfois utilisé pour la clarté du code, car il permet de sortir de plusieurs blocs de code qui se suivent.

Exemple : détection d'erreur avant l'écriture sur un fichier :

 
Sélectionnez
If Not Exit(File) Then

    errorState=File.NotExist

    GoTo FIN

End if

 

If Not Open(File) Then

    errorState=File.NotOpen

    GoTo FIN

End if

 

If Not Overwrite(File) Then

    errorState=File.NotOverwrite

    GoTo FIN

End if

FIN:

C'est propre.

Là aussi on aurait pu utiliser des If imbriqués :

 
Sélectionnez
  If  Exit(File) Then

      If  Open(File) Then

        If  Overwrite(File) Then

            errorState=File.Ok

        Else  

            errorState=File.NotOverwrite

        End if

  

      Else  

            errorState=File.NotOpen

      End if

 

  Else  

            errorState=File.NotExit

  End if

La solution avec les GoTo à l'avantage d'être plus lisible.

Pour info, il existe une autre solution élégante et originale utilisant un Select Case : les "Case" peuvent contenir n'importe quelle expression.

 
Sélectionnez
Select Case true

        Case len(File) = 0 

            msgbox "Pas de nom de fichier"    

        Case Not Exit(File)

            errorState=File.NotExist

        Case Not Open(File)

            errorState=File.NotOpen

        Case Not Overwrite(File) 

            errorState=File.NotOverwrite

        Case else

        'placer les exceptions ici

End Select

V-W. Les bases binaires, hexadécimales, l'algèbre de Boole

Image non disponible
Mr Georges Boole 1805-1864

On étudie dans ce chapitre les différentes bases (binaire, hexadécimale…) en approfondissant. Ce chapitre n'est pas à lire de suite pour les débutants.

Voici ce que nous allons voir.

Le Bit, poids d'un bit.

Conversion décimale binaire.

L'octet, Kilo, Méga, Téracotet

Opération: L'addition, la multiplication binaire, les nombres négatifs.

Table de vérité.

Fonction logique. Or And, Not, Xor…

Notation.

Ordre des évaluations.

Loi de composition.

Déplacement de bit.

Hexadécimale.

Intérêts en Visual Basic.

A notre disposition Boolean, Integer Byte…

Conversion binaire, décimale, hexadécimale.

Cas particulier: If A then

Les masques de bit

Cryptage par Xor

Travail sur les couleurs, graphiques…

Viewer hexadécimal.

V-W-1. Introduction

L'algèbre de Boole est la partie des mathématiques, de la logique de l'électronique et de l'informatique qui s'intéresse aux opérations et aux fonctions sur les variables logiques. En logique propositionnelle, une expression est soit vraie soit fausse. (le vrai (1) et le faux (0)).

Georges Boole (1815-1864), physicien Anglais définit en 1847 une algèbre qui est applicable au raisonnement logique, qui traite des fonctions à variables binaires (deux valeurs). Mais il ne s'applique pas aux systèmes à plus de deux états d'équilibre.

Une variable booléenne, ou logique, ou binaire ne prend que deux valeurs (elle est généralement stockée sous la forme d'un bit).

Vers la fin des années 30, Claude Shannon démontra qu'à l'aide d'interrupteurs fermés pour "vrai" et ouverts pour "faux" il était possible d'effectuer des opérations logiques en associant le nombre 1 pour "vrai" et 0 pour "faux".

Ce codage de l'information est nommé base binaire. C'est avec ce codage que fonctionnent les ordinateurs. Il consiste à utiliser deux états (représentés par les chiffres 0 et 1) pour coder les informations.

Il permet d'étudier les circuits logiques.

V-W-2. Notions théoriques

Notion de base:

On utilise diverses bases dans la vie courante.

Pour les heures, minutes, secondes on utilise sans le savoir une base 'soixante' :

60 secondes = 1 minute

60 minutes = 1 heure

Si je compte : 1 s, 2s, 3s,…59s, 1mn, 1mn+1 s… 1mn+59s, 2 minutes… 59 mn+ 59s, 1h…

En base décimale, on a à notre disposition les caractères 1 2 3 4 5 6 7 8 9.

Si on veut représenter le nombre au-dessus de 9, comme on n'a plus de caractère, on recommence avec 1 mais en le décalant vers la gauche pour signifier qu'il s'agit d'une dizaine. On obtient '10'. Le nombre suivant est '11' puis "12'… Idem pour 100, 1000…

En base binaire, on n'a que le caractère 1 (et le zéro), 1 binaire= 1 décimal.

Si on veut écrire en binaire le nombre au-dessus de 1, comme on n'a plus de caractère, on procède de même en décalant vers la gauche le 1 :

10 binaire= 2 décimal.

Le nombre suivant est 11 binaire (3 en décimal).

Puis 100 (4 en décimal), car il faut de nouveau décaler.

En base hexadécimale, on a à notre disposition les caractères 1 2 3 4 5 6 7 8 9 A B C D E F.

Aussi 10 décimal = A en hexadécimal

15 décimal = F en hexadécimal

16 décimal = 10 en hexadécimal

Si on veut représenter le nombre au-dessus de 15, comme on n'a plus de caractères, on recommence avec 1 mais en le décalant vers la gauche pour signifier qu'il s'agit d'une 'seizaine'. On obtient '10' hexadécimal qui correspond à 16 décimal. Le nombre suivant est '11' puis "12' jusqu'a 1F puis 100… 1000…

Utilisons l'analogie des allumettes et des paquets d'allumettes.

En décimal on a des paquets de 10 allumettes.

On compte 1 ,2 ,3…9, 1 paquet de 10, puis 1 paquet + 1 allumette…

On a des gros paquets de 100, des énormes paquets de 1000 allumettes…

En binaire on a des paquets de 2 allumettes et des gros paquets de 4 allumettes.

On compte 1 , 1 paquet de 2, puis 1 paquet + 1 allumette, puis 1 gros paquet de 4…

Image non disponible

Donc pour compter en binaire : Binaire Décimal

1 allumette. 1 1

1 paquet de 2 10 2

1 paquet de 2 + 1 allumette 11 3

1 gros paquet de 4 100 4

1 gros paquet de 4 +1 allumette 101 5

1 gros paquet de 4 +1 paquet de 2 110 6

….

Le nombre d'allumettes qu'il y a dans un paquet se nomme le poids.

En hexadécimal, les paquets sont de 16 allumettes.

On compte 1, 2, 3 …jusqu'a 15 allumettes puis 1 paquet de 16 puis 1 paquet plus une allumette…

Base binaire

Soyons maintenant un peu plus scientifique.

Le bit

Le terme bit (b avec une minuscule) signifie "binary digit", c'est-à-dire 0 ou 1 en numérotation binaire. Il s'agit de la plus petite unité d'information manipulable par un ordinateur.

Physiquement cette information binaire correspond à :

* un signal électrique ou magnétique (pas de signal=0, au-delà d'un certain seuil de +5V, valeur 1) ;

* des trous ou pas de trous sur un CD ;

* l'état de bistables, c'est-à-dire des composants électroniques contenus dans les circuits intégrés qui ont deux états d'équilibre (état 1, état 0).

Avec un bit il est donc possible d'avoir deux états :

soit 1 ;

soit 0.

Grâce à 2 bits, il est possible d'obtenir quatre états différents (2*2) :

On peut avec 2 bits , avoir les valeurs: 0, 1, 10, 11 soit 0,1, 2, 3 en décimal :

Image non disponible

Avec 3 bits, il est possible d'obtenir huit états différents (2*2*2) de 0 à 7 en décimal :

Image non disponible

Avec 4 bits, il est possible d'obtenir huit états différents (2*2*2*2) de 0 à 15 en décimal :

Image non disponible

Pour un groupe de n bits, il est possible de représenter 2n valeurs ( de 0 à 2n-1 ).

Avec 8 bits =256 valeurs.

Avec 16 bits=65536 valeurs.

Avec 32 bits=4294967296 valeurs.

Avec 64 bits=18446744073709551616 valeurs.

Avec 8 bits (un octet) on peut représenter un nombre qui peut avoir 256 valeurs différentes :

de 0 à 255

Image non disponible

Poids des bits:

Chaque bit a un poids, qui dépend de la position du bit en partant de la droite. Comme les dizaines, les centaines et les milliers pour un nombre décimal, le poids d'un bit croît d'une puissance de deux en allant de la droite vers la gauche :

Image non disponible

Remarque : cela est valable pour toutes les bases.

Soit un nombre 'mno' en base b

Le premier chiffre à droite a la valeur : o x b1

Le deuxième chiffre à droite a la valeur : n x b2

Le troisième chiffre à droite a la valeur : m x b3

En allant de la droite vers la gauche le poids croît d'une puissance de b.

Le nombre total est la somme de toutes les valeurs :

o x b1 + n x b2 + m x b3

Conversion

Pour convertir un nombre binaire en nombre décimal

Il faut multiplier la valeur de chaque bit par son poids, puis d'additionner les résultats.

Ainsi, le mot binaire 10101 vaut en décimal :

24x1 + 23x0 + 22x1 + 21x0 + 20x1

= 16x1 + 8x0 + 4x1 + 2x0 + 1x1

= 21

Pour convertir un nombre décimal en nombre binaire

- Méthode des poids

Soit 21 en décimal.

Il faut connaitre les poids (puissance de 2): 2, 4, 8, 16 ,32…

Trouver le premier poids (la première puissance de 2) inférieur au nombre décimal 21 : c'est 16

16 donne en binaire 10000

Faire 21-16 =5

Trouver le premier poids inférieur au nombre 5, c'est 4.

4 donne en binaire 100

Faire 5-4= 1

Quand on atteint 1 (ou 0) on s'arrête.

On additionne 10000

+ 100

+ 1

_____

10101

- Méthode des divisions par 2

21 /2 = 10 reste 1

10 /2 = 5 reste 0

5 /2 = 2 reste 1

2 /2 = 1 reste 0

1 /2 = 0 reste 1

On prend les restes en commençant par la fin : 10101

Y a-t-il une solution plus élégante ?

La calculette Windows permet les conversions.

1. Dans le menu Affichage de la calculette, cliquez sur Scientifique.

2. Tapez le nombre décimal que vous souhaitez convertir.

3. Cliquez sur le RadioButton 'Bin'.

Image non disponible

Octet, Kilo méga Téra Octet.

L'octet (en anglais Byte ou B) est une unité d'information composée de 8 bits (256 valeurs possibles). Il permettait par exemple de stocker le code d'un caractère (une lettre ou un chiffre : 65 indiquant 'A' dans le code ASCII). Il y a quelques années les ordinateurs fonctionnaient avec des octets puis ils ont utilisé 16 bits, 32 bits et maintenant 64 bits. On voit que plus l'unité d'information contient de bits, plus elle pourra contenir des grands nombres.

En informatique, si 8 bits correspondent à un octet (Byte), 16 bits est généralement appelé mot (en anglais word), 32 bits correspond à un mot double (en anglais double word, d'où l'appellation dword).

En Visual Basic.Net, les entiers (Integer) sont codés sur 32 bits, les Long sur 64 bits. Les valeurs sont signées (positive ou négative), un bit est donc utilisé pour le signe. Par contre UInteger est un entier non signé codé sur 32 bits pouvant donc prendre les valeurs 0 à 4 294 967 295.

Ko, Mo, Go, To ( kB, MB, GB, TB en anglais)

Pour indiquer la capacité d'une mémoire, on utilisait:

* Un kilooctet (Ko) = 210 octets = 1024 octets

* Un Mégaoctet (Mo) = 220 octets = 1024 ko = 1 048 576 octets

* Un Gigaoctet (Go) = 230 octets = 1024 Mo = 1 073 741 824 octets

* Un Téraoctet (To) = 240 octets = 1024 Go = 1 099 511 627 776 octets

Cela correspondait bien à des puissances de 2, de plus c'était en accord avec les circuits intégrés de mémoire qui avaient bien 1024 octets dans un Kilooctet.

Il parait que depuis 1998 l'IEC a décidé :

* Un kilooctet (Ko ou KB) = 1000 octets

* Un Mégaoctet (Mo ou MB) = 1000 Ko = 1 000 000 octets

* Un Gigaoctet (Go ou GB) = 1000 Mo = 1 000 000 000 octets

* Un Téraoctet (To) = 1000 Go = 1 000 000 000 000 octets

Hors de France, on utilise le nom de "byte" plutôt que le terme "octet". Cela donne les kilobyte, mégabyte, gigabyte et terabyte : (kB, MB, GB, TB avec un B majuscule)

Ne pas confondre Byte B (octet) et bit (bit ou binary digit).

Opérations

Addition binaire

L'addition en binaire se fait comme en décimale :

0+1 = 1

1+0 = 1

0+0 = 0

1+1 =10

Pour plusieurs digits, on additionne en commençant par les bits de droite. On a des retenues lorsque la somme de deux bits de même poids dépasse la valeur de l'unité la plus grande (dans le cas du binaire : 1), cette retenue est reportée sur le bit de poids plus à gauche…

C'est ce qui se passe avec 1+1= 10

Autre exemple

0 1 1 0 0

+ 0 1 1 1 0

- - - - - -

1 1 0 1 0

Soustraction binaire

La soustraction en binaire se fait comme cela :

100

- 010

_____

010

Mais pour les processeurs il est plus facile d'additionner le complément à 2.

Le complément à 1 c'est le fait d'inverser tous les bits du nombre sur toute sa longueur.

010 donne le complément à 1 suivant: 11111101

(si on travaille sur des octets, on inverse les huit bits)

Le complément à 2, c'est le complément à 1 +1: 11111101+1=11111110

Ajoutons 00000100 à 11111110 cela donne bien 00000010

(la dernière retenue tombe dans le vide)

La table de multiplication en binaire est très simple :

* 0x0=0

* 0x1=0

* 1x0=0

* 1x1=1

La multiplication se fait en formant un produit partiel pour chaque digit du multiplicateur (seuls les bits non nuls donneront un résultat non nul). Lorsque le bit du multiplicateur est nul, le produit partiel est nul, lorsqu'il vaut un, le produit partiel est constitué du multiplicande décalé du nombre de positions égal au poids du bit du multiplicateur.

Par exemple :

1 1 0 1 multiplicande

x 0 0 1 0 multiplicateur

- - - - - -

0 0 0 0

1 1 0 1

0 0 0 0

- - - - - -

1 1 0 1 0

On constate que pour multiplier un nombre par 2, il faut le décaler d'un bit à gauche.

10 binaire multiplié par 2 est égal à 100 (2 x 2=4 en décimal)

Nombres négatifs

On peut utiliser des nombres non signés (contenant une valeur absolue), dans un octet il peut y avoir 256 valeurs (0 à 255)

On peut utiliser des nombres signés (positif ou négatif), on 'code' les nombres négatifs en complément à 2 :

Le complément à 1 c'est le fait d'inverser tous les bits du nombre sur toute sa longueur.

010 donne le complément à 1 suivant: 11111101 sur un octet

(si on travaille sur des octets, on inverse les huit bits)

Le complément à 2, c'est le complément à 1 +1: 11111101+1=11111110

On se rend compte que le premier bit à gauche est à 1 pour les nombres négatifs. Dans ce cas on ne peut plus coder que 128 valeurs (sur 7 bits) pour un octet signé.

Table de vérité

Une table de vérité est un tableau permettant de décrire toutes les possibilités de sorties en fonction des entrées. On place donc les variables d'entrées dans les colonnes de gauche en les faisant varier. La colonne (ou les colonnes si la fonction a plusieurs sorties) de droite décrit le résultat.

Exemple de table de vérité de la multiplication.

Image non disponible

L'expression logique correspondante est S= A X B

On retrouve bien par exemple : si les 2 entrées sont 1 et 1 la sortie est 1 : en d'autres termes 1 X 1 =1

Exemple des tables de vérité des fonctions logiques :

Image non disponible
Image non disponible

Pour la fonction And par exemple, l'expression logique correspondante est S= A AND B si les 2 entrées sont 1 et 1 la sortie est 1: en d'autres termes 1 And 1 =1

Comment écrire une fonction logique à partir d'une table de vérité

Il est possible à partir de la table de vérité d'une fonction d'écrire l'expression algébrique de celle-ci.

Exemple 1:Soit la table de vérité suivante :

Image non disponible

La sortie vaut 1 lorsque A vaut 1 et B vaut 0, l'expression logique de cette fonction est donc :

S=A AND NOT B

Exemple 2 : soit la table de vérité suivante :

Image non disponible

La sortie vaut 1 lorsque A vaut 1 et B vaut 0 ou lorsque A et B sont à 0, l'expression logique de cette fonction est donc :

S=(A And Not B) Or (Not A And Not B)

En conclusion

On écrit donc les expressions pour chaque sortie à 1 (avec des And), on les combine avec des Or

Fonction logique:

La loi AND, dite conjonction

Elle est définie de la manière suivante : a And b est égal à 1 si et seulement si a est égal à 1 et b est égal à 1.

On peut construire la table.

Image non disponible

"l'un et l'autre"

La loi OR, dite disjonction ou disjonction inclusive

Elle est définie de la manière suivante : a Or b est égal à 1 si et seulement si a est égal à 1 ou b est égal à 1. (Notons que si a est égal à 1 et que b est égal à 1 aussi, alors a OU b est égal à 1.)

On peut construire la table:

Image non disponible

"l'un ou l'autre ou les deux"

Le contraire, dite négation

Le contraire de "a" égal à 1 si et seulement si a est égal à 0. Le contraire de a est noté Not a

Image non disponible

La loi XOR, dite disjonction exclusive

Elle est définie de la manière suivante : a Xor b est égal à 1 si et seulement si a est égal à 1 ou b est égal à 1 mais pas les deux. (notons que si a est égal à 1 et que b est égal à 1 aussi, alors a Xor b est égal à 0.)

On peut construire la table :

Image non disponible

"l'un ou l'autre, mais pas les deux".

a Xor b équivalent à (a Or b) And Not( a And b)

a Xor b Xor b = a : si on applique sur a 2 fois Xor b, on retrouve a. C'est une propriété très utilisée.

L'opérateur Équivalence

L'équivalence (notée =) est vraie si les deux entrées ont la même valeur et faux sinon. Elle se compose comme suit :

a=b est égal à Not( a Or b) Or ( a And b)

On peut aussi dire que :

a=b est égal à Not (a Xor b)

Image non disponible

Notons la notation utilisée dans les traités d'algèbre de Boole :

+ (addition) équivalent à Or

. (produit) équivalent à And

- au-dessus (négation) équivalent à Not

Ordre des évaluations

Les opérations seront soumises aux mêmes règles que les opérations "de tous les jours", la fonction Not est prioritaire par rapport à And qui est prioritaire par rapport à la fonction Or, enfin on trouve Xor ; on peut, pour s'aider, placer des parenthèses dans les opérations pour forcer l'ordre des opérations.

Exemple :

 
Sélectionnez
Dim a As Boolean = 0 
    Dim b As Boolean = 1 
    Dim c As Boolean  1
     
    On cherche a And b Or c

    a And b = 0 
    (0 And 1 = 0)
     
    0 Or c = 1
    (O Or 1 = 1)

Le résultat est donc :

 
Sélectionnez
a And b Or c = 1

Les parenthèses modifient l'ordre des opérations : elles sont prioritaires sur tout :

 
Sélectionnez
a And (b Or c) = 0

En VB, étant donné que les opérateurs logiques et de bits ont une priorité inférieure à celle des opérateurs arithmétiques et relationnels, toutes les opérations au niveau du bit doivent être mises entre parenthèses afin de garantir une exécution précise.

Sur un groupe de bit les opérations s'effectuent bit à bit

Exemples

15 décimal 00001111

4 décimal 00000100

15 And 4 = 00000100 --->4 décimal

4 décimal 00000100

2 décimal 00000010

4 Or 2 = 00000110 --->6 décimal

Les lois de composition:

Ce sont des règles logiques qui permettent de simplifier l'écriture des expressions algébriques.

Associativité :

* (A And B)And C est équivalent à A And (B And C) et A And B And C

* (A Or B) Or C est équivalent à A Or (B Or C) et A Or B Or C

Absoption :

* A And (A Or B) est équivalent à A

* A Or A And B est équivalent à A

Commutativité :

* A And B est équivalent à B And A L'ordre est sans importance

* A Or B est équivalent à B Or A

Distributivité :

* A Or(B And C) est équivalent à (A Or B) And (A Or C)

* A And (B Or C) est équivalent à A And B Or A And C

Mais aussi :

* A Or A est équivalent à A

* À And A est équivalent à A

Identité :

* 1 And A est équivalent à A

* 0 Or A est équivalent à A

Inversion :

* A And Not A est équivalent à 0 'A ne peut pas être vrai et faux

* A Or Not A est équivalent à 1

Nullité :

* 0 And A est équivalent à 0

* 1 Or A est équivalent à 1

Théorème de De Morgan

Not (a Or b) est équivalent à Not a And Not b

Dans les deux cas, l'expression ne sera égale à 1 que si a et b sont = 0.

Not( a And b) équivalent à Not a Or Not b

Dans les deux cas, l'expression ne sera =1 que si a ou b sont =0.

Les expressions complexes peuvent donc être simplifiées en utilisant des transformations :

Image non disponible

Il existe aussi plusieurs autres opérateurs qui n'ont pas d'équivalent en Visual Basic Net

Ils existaient en VB6 !!

Implication

L'implication (notée IMP) qui n'existe pas en VB.Net s'écrit de la manière suivante :

a IMP b peut s'écrire en VB: Not(a) Or b

Cette opération n'est pas commutative a est une condition suffisante pour b, qui, elle, est une condition nécessaire pour a.

Image non disponible

Inhibition

L'inhibition (notée INH) n'existe pas en VB.Net, elle se compose comme suit :

a INH b peut s'écrire en VB: a And Not(b)

Cette opération n'est pas commutative.

Image non disponible

Déplacement de bit

Les opérateurs binaires << et >> effectuent des opérations de déplacement de bits.

L'opérateur << décale à gauche les bits du premier opérande du nombre de positions spécifié. Les bits de poids fort situés en dehors de la plage du type de résultat sont éliminés, et les positions libérées par les bits de poids faible sont remplies par des zéros.

L'opérateur >> décale à droite les bits du premier opérande du nombre de positions spécifié. Les bits de poids faible sont éliminés et, si l'opérande de gauche est positif, les positions libérées par les bits de poids fort sont mises à zéro ; s'il est négatif, elles sont mises à un. Si l'opérande de gauche est de type Byte, les bits de poids fort disponibles sont remplis par des zéros.

À quoi cela sert ?

Exemple décaler à gauche un Byte revient à faire une multiplication par 2.

3 en décimal= 11

Je décale à gauche, j'obtiens 110 , c'est 3*2=6 en décimal.

Revenons sur la base hexadécimale

En hexadécimal

On a 16 caractères : 0, 1, 2, 3 ,4 …8, 9, A, B, C, D, E, F.

Quand on compte et qu'on arrive à F (15 décimal), on passe à 10 (16 décimal) puis 11…

Voyons la correspondance décimale, hexadécimale, binaire :

Image non disponible

Pour un nombre hexadécimal à plusieurs chiffres, le poids de chaque chiffre est :

Image non disponible

1C en base 16 c'est donc 10+C en hexadécimal = en décimal c'est 161 + 12x 160 = 16 + 12 = 28

Le nombre 28 (en base 10) vaut en base 16 : 1*161 + 12*160 = 1*161 + C*160

c'est-à-dire 1C en base 16.

Le nombre FB4 (en base 16) vaut en base 10 : F*162 + B*161 + 4*160 = 3840 + 176 + 4 = 4020

À quoi sert la base hexadécimale ?

C'est une représentation plus imagée de la représentation binaire.

Pour convertir un octet en hexadécimale, on le partage en 2 groupes de 4 bits, qui correspondent chacun à un chiffre hexadécimal.

00101010 c'est un octet en binaire; impossible à retenir en binaire (en décimal on ne voit pas du tout ce qu'il représente en bits). Cet octet, on le coupe en 2, chaque demi-octet représente 4 bits dont la valeur est comprise entre 0 (0000 en binaire) et F (1111 en binaire, 15 en décimal)

00101010 en binaire= 2A en hexadécimal.

Image non disponible

Il suffit de se souvenir des nombres de 1 à 15 en binaire pour se représenter rapidement 2A.

Autre exemple :

Image non disponible

HFF = 255 décimal

HFFFF=65535 décimal

Notons que pour signifier qu'on a affaire à un nombre hexadécimal, on ajoute H devant.

L'hexadécimal est donc une manière rapide et mnémotechnique de se représenter des nombres binaires.

Les viewers et éditeurs permettant de voir et modifier les octets contenus dans un fichier affichent les octets en hexadécimal (voir plus bas).

V-W-3. Pratique en Visual Basic

En Visual Basic.Net, on a à notre disposition :

- les Boolean qui peuvent prendre les valeurs True ou False… ;

- les entiers : Byte contient 8 bits (non signé) pouvant prendre les valeurs 0 à 255 : il existe aussi en VB 2005, SByte contenant un octet signé dont les valeurs varient de moins 128 à plus 127 ;

- les Short 16 bits, les Integer sont codés sur 32 bits, les Long sur 64 bits. Ces valeurs sont signées (positives ou négatives), un bit est donc utilisé pour le signe.

Par contre en VB 2005, UInteger est un entier non signé codé sur 32 bits pouvant donc prendre les valeurs 0 à 4 294 967 295. Ushort et ULong existent aussi. (U comme Unsigned)

Il existe aussi les nombres en virgule flottante ou fixe (Single, Double, Decimal), ceux-là, on ne les utilisera pas pour travailler sur les bits.

Littéral

Un littéral est censé être en base décimale.

Dim A As Integer = 12 (12 est en base décimale)

On peut forcer un littéral a être un hexadécimal ou un octal : un nombre hexadécimal est noté avec le préfixe &H , exemple :

A=&HFF

(&O pour octal)

Il n'est pas possible de saisir un littéral en binaire.

Bien comprendre que, en interne, les entiers sont codés en binaire : c'est normal, la mémoire de l'ordinateur et les registres des processeurs sont composés d'octets de 8 bits de Dword de 16 bits et maintenant de 32 et 64 bits contenant des bits positionnés à 0 ou 1.

Dim A As Integer = 12

c'est 12 est en base décimale, c'est notre manière de l'utiliser.

mais c'est 0000000000001100 en mémoire physique, représentation binaire.

c'est 000C en hexadécimal, mais dans une autre base plus pratique, "plus imagée".

C'est toujours le même nombre !!

And Or Xor AndAlso, OrElse

En VB, en plus de And, Or, Xor, existent AndAlso et OrElse qui testent la première valeur puis, si nécessaire, la seconde. Si la seconde valeur n'a pas à être évaluée, est ne le sera pas, c'est un gain de temps.

Pourquoi Xor n'a pas d'équivalent ?

Car pour évaluer Xor, il faut d'emblée utiliser les 2 valeurs.

Comment réagit VB avec les booléens, les entiers ?

* Si A et B sont des expressions booléennes (valeur True ou False uniquement) :

IF A>=2 And A<=5 Then…

Les expressions booléennes sont évaluées et on a comme résultat True ou False.

* Si A et B sont des nombres entiers (Integer= 32 bits, Long=64 bits, Short=16 bits, Byte=8 bits par exemple).

L'opération est effectuée sur chaque bit de l'équivalent binaire, le résultat binaire est affiché en décimal.

A = 7 'en décimal ( 0111 en binaire)

B = 12 'en décimal ( 1100 en binaire)

A And B = 4 'en décimal ( 0100 en binaire)

* Si A et B sont des nombres en virgule flottante (Single, Double par exemple), ils sont codés sous la forme de mantisse plus exposant, une opération logique devrait produire un résultat aberrant. Ils sont convertis en Long avant évaluation si Option Strict= Off :

Dim a As Single = 7

Dim b As Single = 12

Dim c As Boolean = True

MsgBox(a And b) 'affiche '4', car 7 et 12 sont transformés en Long (si Option Strict=Off)

si Option Strict=On Levée d'une exception.

Un conseil : utilisez des Booléens quand vous voulez effectuer des opérations logiques, des entiers quand vous travaillez sur les bits.

Conversion Binaire, hexadécimale, décimal

L'affichage d'un entier se fait en décimal par défaut si on utilise la méthode ToString :

 
Sélectionnez
Dim a As Integer =&HFF   Littéral en hexadécimal

MsgBox (a.ToString)      Affiche  '255' décimal

On peut surcharger la méthode et afficher en hexadécimal :

 
Sélectionnez
Dim a As Integer = 255

MsgBox(a.ToString("X"))  Affiche 'FF'

On peut afficher en hexadécimal et décider le nombre de digits affichés :

 
Sélectionnez
Dim a As Integer = 255

MsgBox(a.ToString("X4")) Affiche '00FF'

En utilisant la classe Convert, on peut même afficher en base binaire, octale, décimale, hexadécimale.

Convert.ToString(Int64, base) Convertit la valeur d'un entier signé 64 bits en sa représentation String équivalente dans une base 'base' spécifiée (base 2, 8, 10, 16).

Dim d As Long = 3

Dim r As String

r= Convert.ToString(d, 2)) 'convertit la valeur Long de "d" en base 2

d= 3 donne r="11" binaire

Si on avait eu une String "3" on l'aurait convertie en Long grâce à CLng(d)

Convert.ToInt64(s, base) 'convertit en type int64(long en base 10) la valeur de la String 's' à partir d'une base 'base'.

Dim d As String = "111"

Dim r As Long

r= Convert.ToInt64(d, 2)) 'convertit d (string représentant un binaire) en Long

cela donne r=7

Enfin dans l'espace Visual Basic l'instruction Hex donne la représentation hexadécimale d'un nombre , ( Oct existe aussi)

str=Hex(456) retourne 1C8

Conversion String en Byte

Conversion String en Bytes :

 
Sélectionnez
Dim str As String= "…"
Dim encoding As New System.Text.ASCIIEncoding()
Dim Bytes() As Byte()= encoding.GetBytes(str)

Conversion Bytes en String :

 
Sélectionnez
Dim Bytes As Byte() =.
Dim str As String
Dim enc As New System.Text.ASCIIEncoding()
str = enc.GetString(Bytes)

Enregistrement d'un tableau de Bytes

1 - En mémoire : (dans un mémoryStream)

 
Sélectionnez
Imports System.IO' Creation d'un tableau de Byte.
Dim dataArray(1000) As Byte

' On le remplit avec des nombres aléatoires.
Dim randomGenerator As New Random
randomGenerator.NextBytes(dataArray)

Écriture

 
Sélectionnez
Dim binWriter As New BinaryWriter(New MemoryStream())

' Écrire les données dans la mémoire.
   
binWriter.Write(dataArray)

Lecture

 
Sélectionnez
' Créer un reader en utilisant le stream du Writer
Dim binReader As New BinaryReader(binWriter.BaseStream)

' mettre la position au début du stream.
binReader.BaseStream.Position = 0

' Relecture dans verifyArray.
Dim verifyArray() As Byte = binReader.ReadBytes(dataArray.Length)

2 - Dans un fichier :

 
Sélectionnez
Dim fs As New FileStream(FILE_NAME, FileMode.CreateNew)

Dim w As New BinaryWriter(fs)
w.Write(datArray)

w.Close()
fs.close

Le Framework 2 permet une écriture encore plus simple pour lire écrire les octets d'un fichier:

Lire et mettre dans un tableau les octets d'un fichier ? (Framework 2)

Dim myBytes() As Byte =File.ReadAllBytes("c:\monText.txt")

Il existe aussi WriteAllByte.

Précision sur 'If a Then'

Avec des valeurs numériques si

* a=0, a est évalué comme False le programme se poursuit après Then;

* si a est différent de 0 (1, -1, 45…) a est considéré comme True et le programme se poursuit après Then.

Donc

 
Sélectionnez
Dim a As Integer =15

If a  Then

C'est une mauvaise méthode !! Il vaut mieux écrire :

 
Sélectionnez
Dim a As Integer =15

If a <>0 Then

Avec une expression booléenne par contre, on peut écrire :

 
Sélectionnez
Dim a As Boolean= True

If a = True Then'ou

If a Then

Exemple :

 
Sélectionnez
If (x=15)=True  Then'ou 
If x=15 Then

Avec une expression booléenne, et uniquement avec une expression booléenne, il est possible de se passer du = True après un If, car de toute façon, l'expression est évaluée.

Masque de bit

Or permet d'écrire un bit à 1

Soit un entier, on veut forcer un des bits à 1 , la solution est de faire un Or avec un entier ayant ce seul bit à 1.

Exemple : Mettre le deuxième bit de 00000100 (4 en décimal) à 1

Il faut faire un Or avec 00000010.

Le poids du deuxième bit est 2, c'est le 'mask bit'.

4 Or 2 = 6

00000100 Or 00000010 = 00000110

En faisant Or 2, on a bien mis le deuxième bit à 1.

Le masque est toujours une puissance de 2.

Or 8 met le quatrième bit à 1

And permet de tester un bit

A And 1 indique si le bit le moins significatif (le plus à droite) est a 1

Exemple: si A = 7 'en décimal ( 0111 en binaire) A And 1 retourne 1

À And 8 indique si le quatrième bit est a 1 (8 est le poids du quatrième bit).

Exemple: si A = 7 'en décimal ( 0111 en binaire) A And 8 retourne 0

8 c'est le 'mask bit' (00001000) du quatrième bit.

A And 8 peut ensuite être évalué comme une expression booléenne:

If A and 8 Then ' Si le quatrième bit de A est à 1 alors,

And permet aussi de forcer à 0 une partie des bits et de ne conserver que la valeur de certains bits

Soit une couleur codée sur 24 bits, les 8 bits à droite codent la composante bleue, Je veux conserver uniquement ces 8 bits de droite (l'octet de droite) :

myColor And &HFF conserve le premier octet, mais met les 2 autres à 0 :

MyColor=0010 0100 1000 0010 0010 0110

And 0000 0000 0000 0000 0000 1111

= 0000 0000 0000 0000 0000 0110

Le masque correspond aux bits à conserver.

Xor permet de forcer un bit à 0

Pour mettre le 4e bit à 0

Il faut faire un Xor avec 00001000.

Le poids du deuxième bit est 2, c'est le 'mask bit'.

12 Xor 8 = 4

00001100 Or 00001000 = 00000100

Exemple pratique

Comment stocker plusieurs valeurs dans une variable en utilisant un masque.

Souvent, plutôt que de coder une information par octet, on peut coder une information par bit et ainsi coder 8 informations par octet.

Le paramètre d'une fonction est, par exemple, composé d'un entier ou chaque bit à une signification.

Exemple fictif :

00000001 le premier bit à 1 signifie gras (1 en décimal)

00000010 le deuxième bit à 1 signifie l'italique (2 en décimal)

00000100 le troisième bit à 1 signifie le soulignage. (4 en décimal)

Si je veux envoyer les paramètres gras et souligné, j'enverrais le paramètre 1 Or 4 qui correspond a 00000101. Les bits 1 et 3 sont bien à 1.

On note bien que chaque paramètre doit être une puissance de 2.

C'est plus clair de créer une énumération :

 
Sélectionnez
<Flags()> Enum, Car

    Normal=0

    Gras= 2

    Italique= 4

    Souligne= 8

End Enum

Si je veux envoyer les paramètres gras et souligné, j'enverrai le paramètre Car.Gras Or Car.Souligne

<Flags()> indique qu'on travaille bien sur des bits.

Souvent les valeurs sont proposées par VB, par exemple quand on utilise MsgBox, le deuxième paramètre qui indique le style peut comporter plusieurs indications séparées par des Or :

 
Sélectionnez
reponse= MsgBox(msg, MsgBoxStyle.DefaultButton2 Or  MsgBoxStyle.Critical Or MsgBoxStyle.YesNo, Title)

Pour lire un bit en retour d'une fonction, on utilisera And :

 
Sélectionnez
Si reponse And Car.Italique =1

c'est que le second bit de réponse est à 1.

Bien que ce soit une opération sur les bits on écrit souvent :

 
Sélectionnez
If reponse And Car.Italique Then.

Cryptage simple par Xor

La technique la plus simple est d'appliquer un "OU exclusif" (XOR) entre le texte à chiffrer et la clé.

Pour obtenir le message crypté on effectue Message Xor Cle (si la clé fait x octets on effectue le Xor entre le premier octet du message et le premier de la clé, puis le deuxième… quand on arrive à x+1 caractère du message, on recommence au premier caractère de la clé).

Comme Message Xor Cle Xor Cle =Message, pour déchiffrer le message codé, il suffit de faire de nouveau un Xor avec la clé.

La clé est donc la même pour coder et décoder, on appelle cela une clé symétrique.

Bien sûr, si on utilise un texte comme clé et comme message, c'est le code du caractère qui est utilisé.

Travail sur les couleurs

Les valeurs RVB (couleurs) sont stockées dans trois octets de 8 bits, conduisant à une couleur à 24 bits, chaque octet correspondant respectivement au rouge, au vert et au bleu.

rrrr rrrr vvvv vvvv bbbb bbbb

Comment récupérer la composante rouge verte ou bleue ?

 
Sélectionnez
Dim myColor As Integer = 15963245
'Un Integer a 32 bits , les 24 premiers sont utilisés.

Dim R, V, B As Byte

Pour le rouge :

 
Sélectionnez
R = myColor >> 16

On décale de 16 bits vers la droite: 0000 0000 0000 0000 rrrr rrrr

Pour le vert :

 
Sélectionnez
V = (myColor And &HFF00) >> 8

On fait un And &HFF00 ce qui met le premier et le troisième octet à 0 0000 0000 vvvv vvvv 0000 0000

On décale de 8 bits vers la droite: 0000 0000 0000 0000 vvvv vvvv

Pour le bleu :

 
Sélectionnez
B = (myColor And &HFF)

On fait un And &HFF ce qui met le premier et le second octet à 0

0000 0000 0000 0000 bbbb bbbb

(En Vb on peut faire plus simple)

Travail sur les graphiques

Un mode souvent utilisé pour la réalisation d'interfaces est le mode XOR. Ce mode permet d'effacer facilement un cadre de sélection en le redessinant une seconde fois à la même position.

Si l'on a un écran noir et blanc pour lequel 1 = noir et 0 = blanc et que l'on affiche une forme en noir, chaque pixel appartenant à la forme est inversé à l'écran puisque 1 xor p = not p. Donc si l'on dessine la forme deux fois, chaque pixel est inversé deux fois et revient donc dans son état initial.

Par contre, sur un écran couleur, les résultats sont imprévisibles. Si le noir est représenté par la valeur de pixel 1111 et que l'on dessine en xor sur un pixel de valeur 1001, le résultat est un pixel de valeur 1111 xor 1001 = 0110. La couleur résultante est alors imprévisible : on obtient un effet "technicolor".

En VB on a d'autres fonctions sur les graphiques.

V-W-4. Viewer hexadécimal

Comment voir le contenu d'un fichier en hexadécimal ?

C'est très simple et VB 2005 :

on utilise un composant ByteViewer ;

charger la référence System.design.Dll ;

puis entrer le code dans Form_Load :

 
Sélectionnez
Private Sub Form1_Load() Dim viewer As New System.ComponentModel.Design.ByteViewer()

Dim viewer As New System.ComponentModel.Design.ByteViewer

Me.Controls.Add(viewer)

viewer.Dock = DockStyle.Fill

Dim ofd As New OpenFileDialog 'Choix d'un fichier

If ofd.ShowDialog() = Windows.Forms.DialogResult.OK Then viewer.SetFile(ofd.FileName)

End Sub
Image non disponible

Si vous avez déjà un tableau de bytes, utilisez sa méthode SetBytes.

Vous pouvez même choisir son mode d'affichage (Ansi, Unicode, Hexadump ou automatique) avec sa méthode SetDisplayMode.

Second exemple

Ouvrir un fichier image .jpg le charger dans un tableau de Bytes et l'afficher :

 
Sélectionnez
Dim viewer As New System.ComponentModel.Design.ByteViewer

Me.Controls.Add(viewer)

viewer.Dock = DockStyle.Fill

Dim ofd As New OpenFileDialog

ofd.ShowDialog()

Dim img As Image = Image.FromFile(ofd.FileName)

Dim mstImage As IO.MemoryStream = New IO.MemoryStream

img.Save(mstImage, System.Drawing.Imaging.ImageFormat.Jpeg)

Dim bytImage As Byte() = mstImage.GetBuffer

viewer.SetBytes(bytImage)

Fait à partir d'un article de c2i en C#.

V-W-5. Éditeur hexadécimal

On peut écrire en VB.Net un éditeur hexadécimal de fichier (lecture du fichier, visualisation en hexa et ASCII, modification d'un octet.

Voir le lien suivant :

Editeur hexadécimal ULTRA EDIT de fichier par VBsorcier

Pour que le source marche, ne pas oublier de générer puis mettre les fichiers vb dans MyProjet et les fichiers ressources dans le répertoire de ressources.

V-X. Les génériques

Super complexe ? Non !!

V-X-1. Définition

À partir de VB 2005, on peut utiliser les génériques.

Un type générique (Generic) permet de créer une Classe ou une procédure, ayant des Data Types non définis au départ.

En d'autres termes, les paramètres et variables n'ont pas de type: ce ne sont pas des Strings, des Integers… Ce sont des génériques. Quand on utilise la Classe ou la procédure, on indique le type.

Les génériques nous permettent de définir un comportement ou un algorithme commun sur les types ou un sous-ensemble de types .Net. Ils sont un moyen de mutualiser un comportement.

Par exemple, je vais écrire une routine de calcul avec des génériques, elle sera utilisable avec des Integers, des Single…

Exemple de Fonction utilisant un 'generic'.

Permettant d'en comprendre l'intérêt.

Créons une sub nommée Swap (elle sert à intervertir 2 variables) fonctionnant pour tous les types de données :

 
Sélectionnez
Private Sub Swap(Of ItemType) (ByRef v1 As ItemType, ByRef v2 As ItemType)

Dim temp As ItemType

temp = v1

v1 = v2

v2 = temp

End Sub

Notons que en plus des 2 paramètres v1 et v2 à 'swapper' ,"Of ItemType" indique le type de donnée qui doit être utilisé.

Si on a 2 entiers à swapper, il faut appeler la fonction Swap comme cela :

 
Sélectionnez
Swap(Of Integer)(v1, v2)

Si ce sont des Strings :

 
Sélectionnez
Swap(Of String)(v1, v2)

Le JIT compile la fonction Swap comme si elle avait été écrite pour des Strings.

Sans les génériques j'aurais fait plusieurs routines de code pour chaque Type. Or en utilisant les génériques cette redondance peut être évitée.

Exemple de Classe utilisant un 'generic'. À revoir quand vous connaitrez les classes.

De la même manière, on peut créer une Classe entièrement générique :

 
Sélectionnez
Public Class SomeClass(Of ItemType)

Private internalVar as ItemType    ' variable generic

Public Function SomeMethod(ByVal value As ItemType) As ItemType

'Fonction acceptant un generic comme paramètreEnd Function

End Class

Exemple de Collection utilisant un 'generic'

On peut créer une collection générique (System.Collections.Generic) et lui imposer un type.

Exemple : créons une collection de String : List(Of String).

 
Sélectionnez
Imports System.Collections.Generic.



Dim l As New List(Of String)

l.Add("toto")    'On ajoute une string

Dim S As String = l.Item(0) ' l'item est bien typé : même avec 'Option Strict=on' 
'pas besoin de CType.

Habituellement les collections contiennent des objets; ici c'est une collection de String.

Je ne peux y mettre que des String (sinon cela provoque une erreur).

Comme par définition c'est des string, il n'y a pas de conversion String=>Objet et Objet=>String (pas de boxing/unboxing)

On peut aussi créer des Stack(Of…) Queue(Of…), Dictionnary(Of…) SortedList(Of…)…

V-X-2. Intérêts des génériques ?

Pourquoi ne pas utiliser des types 'Object' à la place des génériques ?

Les génériques sont fortement typés. Si on crée une collection générique de Long, on ne peut utiliser que des Long : c'est mieux, cela évite les erreurs, les conversions de type.

Ils sont plus rapides que l'usage des objets.

S'il y a erreur, elle se produit probablement à la compilation et pas à l'exécution.

Cela permet d'utiliser l'intellisense.

Comparaison ArrayList (non générique) et List (Of) générique. Si on utilise une ArrayList qui est une liste non générique, on peut sans problèmes ajouter un Integer puis une String : cela n'est pas logique et possiblement une erreur.
De plus quand on travaille sur cette liste ou qu'on parcourt cette liste il y a des opérations de Cast et de boxing/unboxing sans arrêts: on stocke des Integer, String dans des objets.
Par contre si on utilise une List générique typée, pas de Cast ni de boxing (rapidité++) et réduction du nombre d'erreurs possibles: une List de String ne peut contenir que des String.

V-X-3. Usage des génériques

On peut utiliser des méthodes génériques pour travailler sur les tableaux.

Exemple recherche dans un tableau de short nommé monTab l'élément 2

 
Sélectionnez
index= Array.indexOf (Of Short)(monTab, 2)

est hyper plus rapide que

index= Array.indexOf (monTab, 2), car la première version avec généric est directement optimisée pour les Short.

Il est de même pour Binarysearch et Sort.

Cela est valable pour les types 'valeur' (peu d'intérêts pour les strings par exemple).

Collections génériques

On peut créer une collection générique (System.Collections.Generic) et lui imposer un type.

Exemple : créons une collection de String (List(Of String)): Elle est typée, car elle ne peut contenir que des 'String'.

 
Sélectionnez
Dim l As New List(Of String)

Il s'agit d'une List avec Index.

l.Add("toto")    'On ajoute une string

Dim S As String = l.Item(0) ' l'item est bien typé : même avec 'Option Strict=on' 
'pas besoin de CType.

Il y a aussi de nouveaux types de collections génériques :

- les Dictionnary(Of…) avec Clé et valeur ;

- les SortedDictionnary(Of…) avec Clé et valeur triés ;

- les LinkedList(Of…) Liste Chainée, chaque élément comportant une propriété Value, Next et Previous ;

- les SortedList(Of…)… ;

- les Stack(Of…) ;

- les Queue(Of…).

On peut aussi créer des collections 'composées'.

 
Sélectionnez
Dim genericColl As New Dictionary(Of String, String)
genericColl.Add("PremiereClé", item1)

V-Y. Linq

'Language-Integrated Query' (LINQ), veut dire "langage de requête intégré".

On l'utilise dans VB à partir de VB2008 (Framework 3.5).

V-Y-1. Définition, mise en place

C'est un langage de requêtes (permettant d'interroger une source de données) directement dans le code Visual Basic et à l'aide de mots-clés familiers (issues du SQL, le langage d'interrogation des bases de données).

Cette source de données peut être une Base de données (Linq To SQL et Linq To DataSet )un fichier XML (Link To XML), mais aussi une collection, un tableau, une chaine de caractères.

On parle dans ce dernier cas de 'Linq To Objects'. Si un objet prend en charge l'interface IEnumerable ou IEnumerable (Of), le fournisseur LINQ to Objects vous permet de l'interroger.

LINQ (dixit Microsoft) offre trois principaux avantages par rapport aux boucles for Each traditionnelles.

Les requêtes

- Elles sont plus concises et lisibles, surtout lors du filtrage de plusieurs conditions.

- Elles fournissent des fonctions puissantes de filtrage, de classement et de regroupement avec un minimum de code d'application.

- Elles peuvent être appliquées à d'autres sources de données avec peu ou pas de changement.

Pour que LINQ soit pris en compte, il faut :

utiliser VB 2008 et le framework 3.5.

Dans les propriétés, onglet compile, il faut que Option Infer=On

Il faut ajouter System.Data.Linq.

Si vous créez un nouveau projet dans VB 2008, toutes les conditions sont effectives par défaut, si vous modifiez un ancien projet, il faut rajouter certaines références.

Dans l'Explorateur de solutions (Projet, Propriétés…), cliquez sur Références, puis cliquez sur Ajouter une référence.

Cliquez sur .NET, sur l'assembly System.Data.Linq, puis sur OK, cela ajoute la référence.

Image non disponible

Il faut ajouter l'espace de nom.

Dans l'explorateur de solution, cocher Systel.Data.Link comme ci-dessus
ou ajouter les directives suivantes en haut du Module1 : Imports System.Data.Linq

V-Y-2. Principe d'une requête Linq

À titre d'exemple simpliste, on a des données dans MyData et chaque donnée a les champs 'Nom', "Prenom", "Ville"… Comment chercher les enregistrements ayant comme nom "toto" ?

 
Sélectionnez
Dim Resultat = From Element In MyData _

Where Element.Nom = "Toto" _

Select Element

On crée une variable de requête (ici ' Dim Resultat') qui sera chargée de contenir la requête (et pas les résultats),

puis l'expression de requête composée de :

From : dans quoi chercher ? Dans quel élément ?

In : quelle source de données ? Dans MyData ;

Where : précise les conditions à appliquer, c'est le 'filtre' ;

Select : précise les éléments à extraire qui vont apparaitre dans 'Resultat'.

Remarquons que Dim From In Where Select doivent être sur une seule unique et même ligne; pour la lisibilité, on écrit sur plusieurs lignes en ajoutant des continuateurs de lignes "_".

Remarquons aussi qu'initialement on connait MyData et on sait que chaque élément de MyData a un champ 'Nom', c'est tout !! On utilise dans la requête les nouvelles variables 'Resultat' et 'Element' sans avoir à déclarer leurs types (on aurait pu le faire). 'Element' est une variable de portée déduite comme élément de MyData.

Ce fonctionnement particulier de LINQ est possible grâce à l'inférence de type et aux types anonymes (voir plus bas).

Et pour afficher les noms dans une ListBox :

 
Sélectionnez
For Each P In Resultat

   ListBox1.Items.Add(P.NOM )

Next

Ici la requête contenue dans la variable de requête 'Resultat' est exécutée pour 'alimenter' la boucle 'For Each'.
On remarque donc que l'exécution est différée.

On peut 'forcer' l'exécution immédiate en mettant la requête entre parenthèses et en utilisant une propriété (.Count , .ToArray, .ToList ) :

 
Sélectionnez
' Execution immédiate avec ToList.
Dim ListPersonneAyantPrenomToto = (From Element In MyData _
Where Element.Nom = "Toto" _
Select Element).ToList()
' On retrouve la liste des éléments de MyData ayant le Prenom='Toto"

' Execution immédiate avec Count.
Dim NombrePersonneAyantPrenomToto = (From Element In MyData _
Where Element.Nom = "Toto").Count()
' On a compté le nombre d'éléments ayant  pour Prenom="Toto".
'NombrePersonneAyantPrenomToto contient le résultat

On peut aussi utiliser .ToList ou .ToArray en mode différé :

 
Sélectionnez
' Execution différée .
Dim Resultat = From Element In MyData _
Where Element.Nom = "Toto" _
Select Element
' . . .
Dim Tableau = Resultat.ToArray()

Order By permet de trier les résultats.

 
Sélectionnez
Dim Resultat = From Element In MyData _

 Order By Element.Price Descending, Element.Nom _

 Select Element.Nom, Element.Price

Ici on trie par prix décroissant, puis à prix égal sur le nom croissant.

Remarquons qu'on sélectionne seulement 2 'colonnes'.

Il est possible d'avoir plusieurs sources, dans ce cas chaque bloc .In est séparé par une virgule :

 
Sélectionnez
Dim queryResults = From cust In customers, ord In orders _
                   Where cust.CustomerID = ord.CustomerID _
                   Select cust, ord

La clause Where peut contenir des conditions complexes avec des AND des OR…

 
Sélectionnez
Dim custs = From cust In db.Customers _
            Where cust.Country = "France" _
                And (cust.CompanyName.StartsWith("F") _
                Or cust.CompanyName.StartsWith("V")) _
            Order By cust.CompanyName _
            Select cust.CompanyName, cust.City

DataGridView1.DataSource = custs

V-Y-3. Link et les tableaux d'Integers

Un tableau peut être interrogé par Linq.

Exemple : rechercher les nombres pairs dans un tableau d'Integer :

 
Sélectionnez
' La Data source: c'est un tableau d'Integer 

Dim numbers() As Integer = {0, 1, 2, 3, 4, 5, 6}

 

' Création de la requête.

'Pour chaque élément num dans la source

'Si l'élément num est tel que num Mod 2=0 (condition pour qu'il soit pair)

'Selectionner num et le mettre dans réponses

 Dim réponses = From num In numbers _

                 Where num Mod 2 = 0  _

                 Select num 

 

' Exécution de la requête. 

' On utilise les réponses

For Each number In réponses 

    Console.Write(number & " ")

Next

Cela affiche sur la console (menu Affichage puis Sortie) : 0 2 4 6

On peut vouloir compter uniquement les nombres pairs :

 
Sélectionnez
Dim nombredepair = (From num In numbers _ 

                    Where num Mod 2 = 0 _ 

                    Select num).Count()

Console.Write(nombrepair) 'pour afficher 4

On remarque que dans le premier exemple (Select num) l'exécution de la requête est effectuée au cours de la boucle For Each (exécution différée par rapport à la création) alors que dans le second exemple (count), l'exécution est immédiate.

V-Y-4. Link et les chaines de caractères

Soit une chaine de caractères MyString, rechercher les caractères qui sont des nombres.

 
Sélectionnez
' Un string 

Dim MyString As String = "ABCjkjhkhs666KMOOP"

' Select les caractères qui sont des nombres
Dim Query = From ch In MyString _
Where ch.IsDigit(ch) _
Select ch


' Exécution de la requête
For Each c As Char In Query
  Console.Write(c & " ")
Next

' Combien y a-t-il de nombres?
Dim count As Integer = Query.Count()
Console.WriteLine("Count = " & count)

On remarque qu'il n'est pas nécessaire de réexecuter la requête.

Autre syntaxe
Sélectionner tous les caractères avant '6'

 
Sélectionnez
Dim Query2 = MyString.TakeWhile(Function(c) c <> "6")

' Execute the second query
For Each ch In Query2
 Console.Write(ch)
Next

Ici on a utilisé TakeWhile qui sélectionne les caractères jusqu'à 6. (les sélectionne une seule fois). On a utilisé une expression lambda (voir le chapitre sur les expressions lambdas).

 
Sélectionnez
Dim Query2 = MyString.Except("6")

Ici on a utilisé Except qui sélectionne les caractères sauf 6.

V-Y-5. Link et les mots d'une chaine de caractères

Rechercher combien de fois une String contient le mot 'Basic' :

 
Sélectionnez
Dim text As String = "Ceci est un cours Visual Basic" & _
" pour les débutants et les autres"

Dim searchTerm As String = "Basic"

' Conversion de la String en Tableau de mots:.
Dim dataSource As String() = text.Split(New Char() {" ", ",", ".", ";", ":"}, _
StringSplitOptions.RemoveEmptyEntries)

' Création et exécution de la requête
' Utiliser ToLower pour  trouver "Basic " et "Basic" 
Dim Query = From word In dataSource _
Where word.ToLowerInvariant() = searchTerm.ToLowerInvariant() _
Select word

' Compter les 'Basic'.
Dim count As Integer = Query.Count()
Console.WriteLine(count )

V-Y-6. Link pour rechercher la différence entre deux listes de noms

Rechercher dans la String nom1, les noms qui ne sont pas aussi dans nom2.

 
Sélectionnez
' Soit 2 tableaux de Sting 
Dim nom1 As String() =  {"Philippe", "Paul"}
Dim nom2 As String() = {"Paul", "Jean"}




' Créer la requête.
Dim difference = nom1.Except(nom2)



' Executer
For Each name As String In difference
 Console.WriteLine(name)
Next

Affiche 'Philippe'

V-Y-7. Link et les contrôles

Comment obtenir la liste des contrôles actifs dans un formulaire ?

 
Sélectionnez
Dim ControlsEnabled = _
            From c In Me.Controls _
            Where CType(c, Control).Enabled _
            Select CType(c, Control)

On se rend bien compte que, ici, Linq est une alternative à For Each.

V-Y-8. Inférence de Type et type anonyme

Débutant, tu peux sauter !!

On a vu que Linq fonctionnait d'une manière un peu particulière. Pour mieux comprendre cela, il faut savoir qu'à partir de VB 2008 on peut utiliser l'inférence de type et les types anonymes.

Inférence de Type

Il faut pour cela que Option Infer =On (Off par défaut)

Passer par le menu 'Projet' puis 'Propriétés de…', onglet 'Compiler'

En plus des options Explicit, Compare, Strict, on peut modifier Option Infer.

L'inférence est la capacité de déduire le type d'une variable par analyse des types fournis en entrées ainsi que des opérations effectuées sur ceux-ci. C'est donc le compilateur qui déduit le type de la variable.

 
Sélectionnez
' Type explicite pour une String
Dim Myname1 As String = "Rouge"

' Exploitation de l'inférence de type
Dim Myname2 = "Vert"

Le passage du curseur de la souris sur Myname2 vous permet de découvrir que celui-ci est bien un type "String".

On avait dit qu'il fallait travailler avec Option Implicit = True et là on ne déclare même pas le type !!! En fait l'inférence existe afin de supporter par exemple les types anonymes ou encore LINQ.

Il existe des cas pour lesquels l'inférence de type ne se produit pas. Pour les instructions Dim locales, l'inférence de type survient uniquement lorsqu'il y a une assignation sur la ligne de déclaration. Par conséquent, pour les assignations effectuées hors de la déclaration de la variable, le compilateur supposera que le type est Object. Object est également toujours déduit comme type des membres de niveau classe, si bien que l'inférence de type ne s'applique pas aux fonctions, sous-routines, propriétés, champs de classe/structure, etc. Lorsque Option Explicit est Off, une variable locale peut être utilisée dans le code sans déclaration explicite. La variable est supposée être dans ce cas de type Object et tous les appels sont liés tardivement. L'inférence de type ne survient pas sur les variables définies implicitement.

Type anonyme

Habituellement, on peut déclarer Mycustomer, une instance de la classe Customer et renseigner une propriété .Name.

 
Sélectionnez
Dim MyCustomer = New Customer With {.Name = "Philippe"}

Grâce au type anonyme, on peut écrire :

 
Sélectionnez
Dim AnomyneCustomer = New With {.Name = "Philippe"}

Remarque= avant New il doit y avoir '=' et pas As.

Cela créer une nouvelle classe anonyme (sans nom) possédant une propriété .Name.

Les types anonymes sont surtout utilisés avec Linq.

Exemple :

 
Sélectionnez
Dim namePriceQuery = From prod In products _ 

                     Select prod.Name, prod.Price

Si products est une liste d'objets avec plein de propriétés, namePriceQuery est une collection de type anonyme qui possède 2 propriétés : .Name et .Price .

V-Z. Les 'Region', compilation conditionnelle, 'Attributs'

Dans le code on peut ajouter des choses qui ne sont pas du code VB, mais plutôt des directives pour l'affichage, le compilateur ou le Runtime:

V-Z-1. Les Régions

Pour une meilleure visibilité, il est possible de créer des 'régions' de code. Une région peut être déroulée ou contractée.

Une région peut être déroulée: le code entre #Region et #End Region est visible (pour modifier le code par exemple)

-

#Region "Routine de Tri"

 
Sélectionnez
Sub QuickSort(ByVal debut As Integer, ByVal fin As Integer)

Dim pivot, gauche, droite, temp As Integer

DoLoop Until gauche = droite

End Sub

#End Region

Si on clique sur le petit carré (avant #region), cela contracte la région et masque le code, on voit seulement un petit carré avec un plus et le nom de la région.

+ Routine de Tri

Cela permet de masquer une procédure en totalité.

Attention, cela ne permet pas de masquer seulement une partie du code, mais la procédure entière.

Exemple

En VB 2003, dans une Classe de formulaire, il existe une région nommée 'Code généré par le Concepteur Windows Form' qui contient le code créant les contrôles du formulaire. Ce code est habituellement caché dans une 'région' fermée.

V-Z-2. La Compilation conditionnelle

La compilation conditionnelle contrôle si les séquences de lignes sont traduites en code réel. Certaines lignes peuvent être ignorées pendant le processus de compilation.

Les instructions de compilation conditionnelle sont précédées de #

On utilise :

 
Sélectionnez
#if … then

#else

#end if

Exemple :

 
Sélectionnez
#const Demo = True    'créer une constante conditionnelle

Class MaClasse
#if Demo then
  Sub F()
#else
  Sub G()
#end if

End Class

La compilation produit le résultat suivant :

 
Sélectionnez
Class C
Sub F()
End Class

Il suffit de changer la valeur de la constante pour compiler des parties différentes de code.

Noter que #const Demo crée une constante privée accessible uniquement dans le fichier.

En VB 2005 on peut définir une constante au niveau projet avec /define

 
Sélectionnez
/define const Demo=True

V-Z-3. Les Attributs

Les attributs peuvent être utilisés pour décrire votre code au runtime (fournir des informations supplémentaires) ou modifier le comportement de l'application au moment de l'exécution. Le Framework fournit de nombreux attributs, mais vous pouvez également créer vos propres attributs personnalisés.

Les attributs sont entre < et > en VisualBasic.

Les attributs peuvent modifier le comportement des propriétés, méthodes, classes, assemblys. Ils couvrent différents aspects comme la compilation, la sécurité, les services Web…

Exemple: <Obsolete > Avec une procédure.

Déclarons une fonction Add comme obsolète, en plus, le compilateur affiche le message: 'Sera enlevé à la prochaine version'.

On utilise donc <Obsolete > ou le nom complet de l'attribut: <System.ObsoleteAttribut>

 
Sélectionnez
<Obsolete("Sera enlevé à la prochaine version ")> Function Add(a as Integer, b as Integer) as Integer
Add = a + b - c
End Function

Exemple:<Browsable> avec un composant.

Dans un composant, je crée une Propertie nommée 'Valide', je ne veux pas qu'elle apparaisse dans la fenêtre 'propriétés' du composant; je veux qu'elle soit accessible uniquement par code :

 
Sélectionnez
Imports System.ComponentModel    'Classe chargée du comportement des composants.

 

<Browsable(False)> Property Valide() As Integer

Exemple:<ToolBoxBitMap> avec un composant.

Quand on crée un composant, on désire parfois avoir une icône propre à ce composant dans la boite à outils:

 
Sélectionnez
<ToolBoxBitMap("C:MonIcone")> Public Class MaClasse

Exemple:<Serializable> avec une Classe.

Quand on crée une classe, on a parfois besoin qu'elle soit sérializable :

 
Sélectionnez
<Serializable()> Public Class TestSimpleObject

Public member1 As Integer
Public member2 As String
Public member3 As String
Public member4 As Double

'Un member qui ne doit pas être sérialisé.
<NonSerialized()> Public member5 As String

Il est possible de faire un tas de choses avec les attributs, mais cela devient vite très complexe.

V-AA. Traiter les erreurs

Image non disponible

Il y a plusieurs types d'erreurs.

- Les erreurs de syntaxe.

- Les erreurs d'exécution.

- Les erreurs de logique.

Image non disponibleVoir la vidéo : au format 'Flash'> ou au format 'Avi' en Visual Basic 2005.

V-AA-1. Les erreurs de syntaxe

On peut aussi les nommer 'les erreurs du compilateur', elles se produisent lorsque le compilateur Visual Basic rencontre un code non reconnaissable, erreur de saisie ou méconnaissance du langage. Comme les erreurs du compilateur empêchent un programme de s'exécuter, vous devez être averti de ces erreurs avant de tenter d'exécuter votre programme, autrement dit durant la saisie du code.

Elles surviennent donc en mode conception quand on tape le code.

Exemples :

 
Sélectionnez
A+1=B            'Erreur dans l'affectation

f.ShowDialogue   'Faute de frappe, il fallait taper ShowDialog

2 For… et un seul Next

Dim i As Integer: Label.Text= i  'Affectation d'un Integer à une propriété text qui attend une String.

……

Dans ces cas VB souligne en ondulé bleu le code. Il faut mettre le curseur sur le mot souligné, l'explication de l'erreur apparait.

Exemple : Propriété Text d'un label mal orthographiée :

Image non disponible

Il faut les corriger immédiatement en tapant le bon code (ici 'Text').

En bas il y a aussi une fenêtre; "liste des erreurs" :

Image non disponible

Elle affiche tous les problèmes; pour atteindre le code correspondant à une de ces erreurs, double-cliquez sur une des lignes de la liste.

En VB 2005 un bouton avec point d'exclamation permet d'ouvrir une fenêtre proposant le moyen de corriger l'erreur :

Image non disponible

Ici on met dans la propriété text d'un label un Integer, alors qu'il faut mettre une String (Option Strict est probablement égal à On); Vb montre la correction : CStr(i) convertit i en String.

Si vous exécutez le programme dans l'IDE alors qu' il y a un problème, VB demande si on veut exécuter la dernière génération réussie :

Image non disponible

Si vous tapez 'oui' VB exécute la dernière version qui a été générée correctement, mais PAS le code source actuel qui contient des erreurs !!

V-AA-2. Les erreurs d'exécution

Elles surviennent en mode Run dans l'IDE ou lors de l'utilisation de l'exécutable:
Une instruction ne peut pas être effectuée.

Quand on utilise l'exécutable: le logiciel s'arrête brutalement, c'est très gênant !!

Pour l'utilisateur c'est un 'BUG' Image non disponible

Il y a 'levée d'une exception', voila ce que cela donne dans l'IDE.

Exemple : je tente d'accéder à un élément d'un tableau qui n'existe pas (l'indice est trop grand cela entraine une exception 'OutOfRange').

En cours de test, dans l'IDE, s'il y a une exception, le logiciel s'arrête, l'instruction qui a planté apparait en jaune et VB donne une explication.

Image non disponible

L'erreur est :

  • soit une erreur de conception.
    Exemple
    Ouvrir un fichier qui n'existe pas ( on aurait dû vérifier qu'il existe avant de l'ouvrir!).
    Division par zéro.
    Utiliser un index d'élément de tableau supérieur au nombre d'éléments.
    Envoyer un mauvais paramètre à une fonction ;
  • soit une erreur de l'utilisateur.
    Exemple : on lui demande de taper un chiffre, il tape une lettre ou rien puis valide.
    Il faut toujours vérifier ce que fait l'utilisateur et prévoir toutes les possibilités.
    Exemple: si je demande à l'utilisateur de taper un nombre entre 1 et 10, il faut :
    vérifier qu'il a tapé quelque chose ;
    que c'est bien un chiffre (pas des lettres) ;
    que le chiffre est bien entre 1 et 10 ;
    sinon il faudra reposer la question.

A-Capter les erreurs avec Try Catch Finally

Plutôt que de laisser le logiciel 'planter', je vais anticiper et essayer de capter l'erreur au niveau des lignes de code qui peuvent la provoquer.

Avant l'instruction supposée provoquer une erreur indiquez : Essayer l'instruction (Try), si une erreur se produit Intercepter l'erreur (Catch) puis poursuivre (après Finally).

 
Sélectionnez
Try

    'Instruction susceptible de provoquer une erreur.

Catch

    'Traitement de l'erreur

Finally

    'Code toujours exécuté    

End Try

Il faut pour que cela fonctionne avoir tapé au préalable Imports System.IO

Il est possible d'utiliser Catch pour récupérer l'objet 'Exception' qui est généré par l'erreur.

 
Sélectionnez
Catch ex As Exception

Cet objet Exception à des propriétés.

Message qui contient le descriptif de l'erreur.

Source qui contient l'objet qui a provoqué l'erreur…

ex. Message contient donc le message de l'erreur.

Cet objet généraliste Exception (de l'espace IO) a aussi des classes dérivées :

-StackOverFlowException ;

-FileNotFoundException ;

-EndOfStreamException ;

-FileLoadException ;

-PathTooLongException.

Enfin une exception peut provenir de l'espace System : ArgumentExceptions ; ArithmeticException.

-DivideByZeroException…

Il est possible d'écrire plusieurs instructions Catch avec pour chacune le type de l'erreur à intercepter. (Faisant partie de la classe Exceptions.)

Exemple

On ouvre un fichier par StreamReader, comment intercepter les exceptions suivantes ?

Répertoire non valide

Fichier non valide

Autre.

 
Sélectionnez
Try

    sr= New StreamerReader (NomFichier)

Catch ex As DirectoryNotFoundException

    MsgBox("Répertoire invalide")

Catch ex As FileNotFoundException

    MsgBox("Fichier invalide")

Catch ex As Exception

    MsgBox(ex.Message)

End Try

Noter que le dernier Catch intercepte toutes les autres exceptions.

On peut encore affiner la gestion par le mot-clé When qui permet une condition.

 
Sélectionnez
Catch ex As FileNotFoundException

             When ex.Message.IndexOf ("Mon Fichier.txt") >0

                MsgBox ("Impossible d'ouvrir Mon Fichier.txt")

Si le texte "Mon Fichier.txt" est dans le message, affichez que c'est lui qui ne peut pas être ouvert.

Exit Try permet de sortir prématurément. Quitte immédiatement le bloc Try ou Catch dans lequel il est. L'exécution continue avec le bloc Finally s'il y en a un, ou avec l'instruction qui suit End Try.

B-Capter les erreurs avec On error :

On peut aussi utiliser la méthode Visual Basic:

On Error Goto permet en cas d'erreur de sauter à une étiquette (un emplacement dans le code) emplacement ou une portion de code traite l'erreur.

On peut lire le numéro de l'erreur qui s'est produite, ce numéro est dans Err.Number.

Err.Description contient le texte décrivant l'erreur. Err.Source donne le nom de l'objet ou de l'application qui a créé l'erreur.

Quand l'erreur est corrigée, on peut revenir de nouveau à la ligne qui a provoqué l'erreur grâce à Resume ou poursuivre à la ligne suivante grâce à Resume Next

Exemple :

 
Sélectionnez
On Error GoTo RoutinedErreur 'Si une erreur se produit se rendre à 'RoutineErreur'
Dim x As Integer = 33
Dim y As Integer = 0
Dim z As Integer
z = x / y ' Crée une division par 0 !!

RoutinedErreur: ' La Routine d'erreur est ici (remarquer  ':' indiquant une etiquette).
Select Case Err.Number ' On regarde le numéro de l'erreur.
Case 6 ' Cas : Division par zéro interdite
    y = 1 ' corrige l'erreur.
Case Else
    ' autres erreurs……
End Select
Resume ' Retour à la ligne qui a provoqué l'erreur.

Pour arrêter la gestion des erreurs, il faut utiliser :

 
Sélectionnez
On Error Goto 0

Parfois on utilise une gestion hyper simplifiée des erreurs.

Si une instruction 'plante', la sauter et passer à l'instruction suivante, pour cela on utilise:

On Error Resume Next

Exemple : On veut effacer un fichier

 
Sélectionnez
On Error Resume Next

Kill (MonFichier)

On Error goto 0

Ainsi, si le fichier n'existe pas, cela ne plante pas (on aurait pu aussi vérifier qu'il existe avant de l'effacer !!).

On Error Gosub n'existe plus.

On Error est moins performant que Try Catch et surtout il ralentit le code+++ : si nécessaire utiliser Try Catch.

En résumé: pour éviter les erreurs d'exécution, il est donc possible :

- d'écrire du code gérant le problème, contrôlant les actions de l'utilisateur…

Exemple : on demande à l'utilisateur de saisir un nombre dans TextBox1 puis de cliquer sur Button3.

Si l'utilisateur a tapé une lettre au lieu d'un chiffre, le prévenir.

 
Sélectionnez
Private Sub Button3_Click 

If String.IsNullOrEmpty(TextBox1.Text) Then 'on teste si l'utilisateur a tapé quelque chose

 MsgBox("Tapez quelque chose")

Else

 If Not IsNumeric(TextBox1.Text) Then 'on teste si l'utilisateur a tapé du numérique

    MsgBox("Tapez un chiffre")

 End If

End If

End Sub

- une autre possibilité est de capter l'erreur.

Exemple : on demande à l'utilisateur de saisir un nombre dans TextBox1 puis de cliquer sur Button3.

Convertir le texte tapé en Integer, on sait que si la conversion est impossible (pas de texte tapé ou texte non numérique) une exception invalidCastException sera levée et le programme 'plantera'. On écrit donc avant l'instruction CType un Try pour capter l'erreur.

Tester s'il y a une erreur, la capter.

 
Sélectionnez
Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click

Dim i As Integer

Try

    i = CType(TextBox1.Text, Integer)

Catch

    MsgBox("saisir un nombre")

End Try

End Sub

V-AA-3. Les erreurs de logique

Image non disponible

Le programme fonctionne, pas d'erreurs apparentes, mais les résultats sont erronés, faux.

Il faut faire des tests dans les conditions réelles avec des données courantes, mais aussi avec des données remarquables (limites supérieures, inférieures, cas particuliers…) pour voir si les résultats sont cohérents et exacts.

Une fois l'erreur trouvée, il faut en déterminer la cause et la corriger.

Ou bien elle est évidente à la lecture du code ou bien elle n'est pas évidente et c'est l'horreur.

Dans ce dernier cas, il faut analyser le fonctionnement du programme pas à pas, instruction par instruction en surveillant la valeur des variables.(voir la rubrique débogage )

Les erreurs les plus communes sont :

utilisation d'un mauvais nom de variable (la déclaration obligatoire des variables évite cela) ;
erreur dans la portée d'une variable ;
erreur dans le passage de paramètres (Attention au By Val et By Ref) ;
erreur dans la conception de l'algorithme.

Quelques règles permettent de les éviter : voir Règles de bonne programmation.

V-AA-4. Les Tests

Il faut donc toujours tester le fonctionnement du programme de multiples fois.

On fera des :

  • tests unitaires : qui testeront les procédures, les classes une à une sans tester la totalité du programme ;
  • tests de composants et d'intégration : qui testeront plusieurs procédures ou classes fonctionnant ensemble ;
  • tests de régression : c'est la répétition des tests précédents afin de voir si une modification ou un ajout n'entraine pas de nouvelles erreurs qui n'existaient pas ;
  • tests système : test sur le logiciel dans sa version finale.

Les tests détecteront les erreurs, le débogage permettra de trouver la cause et de corriger l'erreur.

Il faut avoir une armée de Bêta-testeurs.

V-AB. Travailler sur les dates, les heures, sur le temps

Image non disponible

Il est probablement nécessaire de lire le chapitre VI sur les Classes avant de lire celui-ci.

Il existe un type de variable 'DateTime' pour gérer les dates et heures, comment l'utiliser ?

Nous verrons aussi comment utiliser les Timers pour déclencher des événements à intervalle régulier. Enfin comment perdre du temps ?

Une variable DateTime contient une date plus l'heure.

Elle occupe 8 octets.(64 bits.)

Elle peut contenir une date comprise entre le 1er janvier de l'année 01 et le 31 décembre 9999 et une heure comprise entre 0:00:00 (minuit) et 23:59:59.

En fait ce qui est codé dans la variable DateTime est le nombre de graduations (une graduation= 100 nanosecondes) écoulées à compter de minuit, le 1er janvier de l'année 1 jusqu'a la date codée.

N. B. DateTime fait partie d'une Classe .Net, il existe aussi un type nommé Date qui fait partie de Visual Basic, qui est équivalent à DateTime.

Préférez DateTime qui est une Classe Net.

V-AB-1. Définir une date, une heure

A - Pour définir une valeur DateTime en utilisant un littéral: elle doit être placée entre des signes (#) et son format doit être de type m/d/yyyy, par exemple #5/31/1998#.(contrairement à ce que je pensais, même si le format date dans la configuration de la langue de l'ordinateur est de type français).

 
Sélectionnez
Dim  dateNaissance As DateTime

dateNaissance= #12/02/1951#
'attention  mois/jour/année

B - Autre manière de saisir une date, une heure :

 
Sélectionnez
Dim dateNaissance As New System.DateTime(1996, 6, 3, 22, 15, 0)    

'Année, mois, jour, heure, minute, seconde, et éventuellement millisecondes)

Ici on a utilisé le constructeur.

C -Troisième méthode

On peut saisir une date dans une string puis convertir :

 
Sélectionnez
DateNaissance = CDate("02/12/1951")

CDate convertit donc une chaine en dateTime. On peut aussi utiliser Ctype :

 
Sélectionnez
Dim dateNaissance As Date = CType("01/12/2005", Date)

IsDate (objet) permet de vérifier si objet est convertible en date.

IsDate retourne True si l'expression est de type Date ou est une chaine convertible en type Date ; sinon, elle retourne False.

Cela permet de vérifier, après une saisie d'une string par exemple, si l'utilisateur a bien tapé des chiffres valides et même si la date est valide ("31/02/1945" n'est pas valide).

Bizarrerie= "12/2005" est considéré comme une date valide et équivalente à "01/12/2005"!! Pas de vérification des 2 '/'.

 
Sélectionnez
If IsDate( MyString) Then

Exemple de Microsoft :

 
Sélectionnez
Dim MyDate, YourDate As DateTime
Dim NoDate As String
Dim D As Boolean
MyDate = CDate("12 Février, 1969")
YourDate = #2/12/1969#
NoDate = "Hello"
D = IsDate(MyDate) ' Retourne True.
D = IsDate(YourDate) ' Retourne True.
D = IsDate(NoDate) ' Retourne False.

V-AB-2. Afficher une date, une heure

Pour afficher les dates et heures simplement, il suffit d'utiliser .ToString

 
Sélectionnez
MsgBox(DateNaissance.ToString)    'Affichera  02/12/1951 11:00:00

Le format utilisé est le format d'affichage des dates de l'ordinateur (en fonction du pays, en France c'est le format fr).

ToString peut comporter des arguments qui formatent l'affichage.

Voici quelques codes de formatage :

 
Sélectionnez
d        affiche le jour                           2

dd       affiche le jour sur 2 chiffres            02

ddd      affiche le jour abrégé                    Dim.

dddd     affiche le jour complet                   Dimanche

M        affiche le mois                           12

MM       affiche le mois sur 2 chiffres            12

MMM      affiche le mois abrégé                    déc

MMMM     affiche le mois complet                   décembre

y, yy, yyyy affiche 1 à 2 chiffres, deux chiffres ou quatre chiffres     51, 51, 1951

H      affiche l'heure  sur un ou deux chiffres (format 24h)

HH     affiche l'heure sur 2 chiffres

h et hh font de même, mais avec un format 12 h.

t, tt  affiche l'heure en format 12h  plus A ou P (pour matin, après midi)

m, mm, s, ss, f, ff font de même pour les minutes, secondes et millisecondes.

: et / sont les séparateurs heure et date.

Exemple :

 
Sélectionnez
MsgBox(DateNaissance.ToString("dddd d MMMM yyyy"))    'Affichera  Dimanche 2 décembre 1951

MsgBox(DateNaissance.ToString("hh:mm")    'Affichera  11:00

MsgBox(DateNaissance.ToString("dd/MM/yy")    'Affichera  02/12/51 

MsgBox(DateNaissance.ToString("%h)    
'Affichera  11   le caractère % est utilisé quand on affiche une seule donnée.

On peut enfin utiliser les méthodes de la classe DateTime !!

 
Sélectionnez
DateNaissance.ToLongDateString        'dimanche 02 décembre 1951

DateNaissance.ToShortDateString       '02/12/1951

DateNaissance.ToLongTimeString        '11:00:00

DateNaissance.ToShortTimeString       '11:00

V-AB-3. Variable "temps"

Un TimeSpan est une unité de temps (un intervalle de temps) exprimée en jours, heures, minutes, secondes.

Un TimeSpan initialisé avec 1.0e+13 graduations représente "11.13:46:40", ce qui correspond à 11 jours, 13 heures, 46 minutes et 40 secondes.

On peut initialiser un TimeSpan avec des graduations :

 
Sélectionnez
Dim instance As New TimeSpan(ticks)

ou avec des heures, minutes, secondes, millisecondes.

 
Sélectionnez
Dim instance As New TimeSpan(h, m ,s ,ms)

On peut aussi l'initialiser avec un certain nombre de jours, d'heures, de secondes. Exemple avec 4 jours.

 
Sélectionnez
Dim value As Double= 4
Dim returnValue As TimeSpan

returnValue = TimeSpan.FromDays(value)

L'espace de noms System.DateTime. contient une multitude de membres.

V-AB-4. Add, Substrat

On peut ajouter ou soustraire un TimeSpan à un DateTime, on obtient un DateTime.

En clair on peut ajouter à une date une durée, on obtient une date.

 
Sélectionnez
' Quel sera la date  dans 36 jours?.
Dim today As System.DateTime
Dim duration As System.TimeSpan
Dim answer As System.DateTime

today = System.DateTime.Now
duration = New System.TimeSpan(36, 0, 0, 0)
answer = today.Add(duration)

On peut ajouter ou soustraire 2 dates, on obtient une TimeSpan

 
Sélectionnez
Dim diff1 As System.TimeSpan
diff1 = date2.Subtract(date1)

V-AB-5. AddDay, AddMouths, AddHours, AddSeconds, AddMiliseconds

Permet d'ajouter des jours, des mois, des heures, des secondes, ou des millisecondes à une date, on obtient une date.

 
Sélectionnez
Answer=today.AddDay(36)

V-AB-6. Year, Mouth, Day, Hour, Minute, Seconde, Millisecond

Permettent d'extraire l'année, le mois, le jour, l'heure, les minutes, les secondes, les millisecondes d'une date :

 
Sélectionnez
I=DateNaissance.Year    ' => I=1951

I=System.DateTime.Now.Day    'donne le jour d'aujourd'hui (1 à 31)

(DatePart permet aussi d'extraire plein d'informations d'une date: jour , mois, année, jour de la semaine…).

V-AB-7. DayOfWeek, DayOfYear, DayInMonth

Retourne le jour de la semaine (0 pour dimanche à 6 pour samedi) :

 
Sélectionnez
I=DateNaissance.DayOfWeek    'I=0,  car le 02/12/1951 est un dimanche.

DayOfYear existe aussi.

dateNaissance.IsDaylightSavingTim indique si on est dans l'heure d'été pour le fuseau

Date.DayInMonth donne le nombre de jours dans le mois spécifié :

 
Sélectionnez
Date.DaysInMonth(1951, 12)

V-AB-8. Now, ToDay, TimeOfDay

Now est la date et l'heure du système. (Là, maintenant.)

ToDay est la date du système avec l'heure à 0.

TimeOfDay est l'heure actuelle.

My.Computer.Clock permet de récupérer l'heure courante ainsi que le nombre de millisecondes écoulées depuis le démarrage.

 
Sélectionnez
MsgBox(My.Computer.Clock.LocalTime.ToString) 'Affiche date et heure

V-AB-9. Ticks

Donne le nombre de graduations d'un DateTime.

AddTicks peut être utilisé.

V-AB-10. Année bissextile, jours fériés

Pour cela, utiliser IsLeapYear :

 
Sélectionnez
MsgBox(DateTime.IsLeapYear(2005)) 'Affiche False

V-AB-11. Comparaison de DateTime

On utilise Compare: DateTime.Compare(t1, t2) retourne 0 si t1=t2, une valeur positive si t1>t2 négative si t1<t2.

 
Sélectionnez
Dim t1 As New DateTime(100)
Dim t2 As New DateTime(20)

If DateTime.Compare(t1, t2) > 0 Then
    Console.WriteLine("t1 > t2")
End If
If DateTime.Compare(t1, t2) = 0 Then
    Console.WriteLine("t1 = t2")
End If
If DateTime.Compare(t1, t2) < 0 Then
    Console.WriteLine("t1 < t2")
End If

On peut aussi utiliser la méthode op_Equality de l'espace de noms pour voir si 2 dates sont égales :

 
Sélectionnez
areEqual = System.DateTime.op_Equality(april19, otherDate)

Il existe aussi op_GreaterThan et beaucoup d'autres.

V-AB-12. Calcul de la différence entre deux dates

On utilise DateDiff, il faut fournir en paramètre :

  • l'intervalle de temps à utiliser comme unité de la différence entre Date1 et Date2.
    DateInterval.Day pour obtenir le nombre de jours entre les 2 dates.
    DateInterval.Year pour obtenir le nombre d'années entre les 2 dates ;
  • Date1 ;
  • Date2.

Exemple

Afficher le nombre de jours entre une date donnée et la date du jour.

 
Sélectionnez
Dim DateS, Msg As String ' Declare les  variables.
Dim DateD As DateTime
DateS = InputBox("Entrer une date") 'Saisir une date : on récupère une string
DateD = CDate(DateS)                'Conversion de la string en DateTime
Msg = "Nombre de jour:"& DateDiff(DateInterval.Day, Now, DateD) 'différence en jours
MsgBox (Msg)

V-AB-13. Comment saisir rapidement une date dans un programme ?

En ajoutant à une fenêtre un contrôle DateTimePicker.

En mode Run , il apparait une zone rectangulaire avec la date système dedans :

Image non disponible

Si l'utilisateur clique sur la flèche déroulante, il apparait une fenêtre calendrier.

Image non disponible

Il suffit pour l'utilisateur de cliquer sur la bonne date.

Le programmeur récupère la date dans DateTimePicker1.value.

Il existe, bien sûr, de multiples propriétés et plusieurs événements, le plus remarquable étant: ValueChanged.

MonthCalendar est un contrôle similaire, mais qui reste toujours ouvert.

De plus grâce à CalendarDimension on peut afficher plusieurs mois.

V-AB-14. Fuseau horaire

TimeZone représente le fuseau horaire actuel, celui défini dans le panneau de configuration.

Vous pouvez utiliser la classe TimeZone pour récupérer des informations à propos du fuseau horaire actuel et convertir l'heure locale en temps universel (UTC, Universal Time Coordinated) ou vice versa.

Le fuseau actuel est dans TimeZone.CurrentTimeZone, son nom est dans la propriété .StandartName; pour convertir en temps universel : .ToUniversalTime(currentDate).

 
Sélectionnez
Imports System.Globalization
Public Class Form1

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        
        Const dataFmt As String = "{0,-30}{1}"
        Const timeFmt As String = "{0,-30}{1:dd-MM-yyyy HH:mm}"

        Console.WriteLine("Exemple TimeZone" & vbCrLf)

        ' Prendre le time zone local , la datetime de maintenant.
        'l'année actuelle
        Dim localZone As TimeZone = TimeZone.CurrentTimeZone
        Dim currentDate As DateTime = DateTime.Now
        Dim currentYear As Integer = currentDate.Year

        ' Affiche le fuseau local
        ' Affiche le fuseau de l'heure d'été.
        Console.WriteLine(dataFmt, "Nom du fuseau local:", _
            localZone.StandardName)
        Console.WriteLine(dataFmt, "Nom du fuseau de l'heure d'été:", _
            localZone.DaylightName)

        ' Affiche date et heure courantes
        'Affiche si l'heure d'été est en cours
        Console.WriteLine(vbCrLf & timeFmt, _
            "Date et heure courante:", currentDate)
        Console.WriteLine(dataFmt, "Heure d'été?", _
            localZone.IsDaylightSavingTime(currentDate))

        ' Prendre le temps universel (UTC) et l'offset
        Dim currentUTC As DateTime = _
            localZone.ToUniversalTime(currentDate)
        Dim currentOffset As TimeSpan = _
            localZone.GetUtcOffset(currentDate)

        Console.WriteLine(timeFmt, "Date et heure universelle:", _
            currentUTC)
        Console.WriteLine(dataFmt, "Différence local-UTC:", currentOffset)

        ' Prendre l'heure d'été.
        Dim daylight As DaylightTime = _
            localZone.GetDaylightChanges(currentYear)

        ' Affiche début et fin heure d'été puis le delta.
        Console.WriteLine(vbCrLf & _
            "Année de l'heure d'été {0}:", currentYear)
        Console.WriteLine("{0:dd-MM-yyyy HH:mm} à " & _
            "{1:dd-MM-yyyy HH:mm}, delta: {2}", _
            daylight.Start, daylight.End, daylight.Delta)
    End Sub


End Class

Affiche :

 
Sélectionnez
Exemple TimeZone

Nom du fuseau local:          Paris, Madrid
Nom du fuseau de l'heure d'été:Paris, Madrid

Date et heure courante:       23-05-2009 14:51
Heure d'été?                  True
Date et heure universelle:    23-05-2009 12:51
Différence local-UTC:         02:00:00

Année de l'heure d'été 2009:
29-03-2009 02:00 à 25-10-2009 03:00, delta: 01:00:00

Vous ne pouvez pas utiliser la classe TimeZone pour représenter des fuseaux horaires autres que ceux de la zone locale ou pour gérer des conversions de date et heure d'un fuseau horaire en un autre. Pour cela, utilisez la classe TimeZoneInfo (permet de travailler sur n'importe quel fuseau horaire). Exemple : dans un TimeZoneInfo, on va mettre le TimeZoneInfo local :

 
Sélectionnez
Dim localZone As TimeZoneInfo = TimeZoneInfo.Local
Console.WriteLine("Local Time Zone ID: {0}", localZone.Id)
Console.WriteLine("   Display Name is: {0}.", localZone.DisplayName)
Console.WriteLine("   Standard name is: {0}.", localZone.StandardName)
Console.WriteLine("   Daylight saving name is: {0}.", localZone.DaylightName)

TimeZoneInfo.Utc Obtient un objet TimeZoneInfo qui représente la zone de temps universel (UTC, Universal Time Coordinated).

On peut convertir un DateTime d'un fuseau à un autre :

 
Sélectionnez
Dim dateTime As DateTime
Dim destinationTimeZone As TimeZoneInfo
Dim returnValue As DateTime

returnValue = TimeZoneInfo.ConvertTime(dateTime, _
    destinationTimeZone)

La nouvelle classe DateTimeOffset permet de mieux gérer les applications qui utilisent les zones dates et heures.
Elle associe un DateTime à un Offset (différence entre heure locale et temps universel).

V-AB-15. Les Timers

Pour déclencher un événement à intervalle régulier, il faut utiliser les minuteries ou 'Timer'.

Prendre le contrôle Timer dans la Boite à outils, l'ajouter à la fenêtre. Il apparait en bas sous la fenêtre dans la barre d'état des composants.

Il n'apparait pas à l'utilisateur dans la fenêtre en mode Run.

Il est très simple à utiliser.

La propriété Interval contient la périodicité de l'événement Ticks, événement qui se déclenche régulièrement.

Interval est en millisecondes. Pour Interval=500 l'événement Ticks se déclenche toutes les 1/2 secondes.

Start et Stop déclenche et arrête la minuterie (De même Enabled active ou non ).

Exemple

Faire clignoter un label toutes les 1/2 secondes.

Créer le label1

Ajouter un Timer1 (qui se place en bas sous la fenêtre).

 
Sélectionnez
Private Sub Form3_Load(… )

    Timer1.Interval = 500

    Timer1.Start()

End Sub
 

Private Sub Timer1_Tick(…)

    Label1.Visible = Not (Label1.Visible)

End Sub

Un événement Timer_Tick se produit toutes les 1/2 secondes et inverse la valeur de la propriété visible du label. (Si elle était égale à True, elle devient égale à False et vice versa.)

Mais attention: Timer a des restrictions de taille

  • Si votre application ou une autre demande beaucoup au système (boucles longues, calculs complexes, accès intensifs à un périphérique, un réseau ou un port, par exemple), les événements de minuterie peuvent être moins fréquents que spécifiés dans la propriété Interval. Il n'est pas garanti que l'intervalle s'écoule dans le temps exact !!
  • L'intervalle peut être compris entre 1 et 64 767 millisecondes : l'intervalle le plus long ne dépasse pas de beaucoup la minute (64,8 secondes).
  • Le système génère 18 graduations à la seconde (même si la valeur de la propriété Interval est mesurée en millisecondes, la véritable précision d'un intervalle ne dépassera pas un dix-huitième de seconde).

Donc pour faire clignoter un label : OUI

Pour compter précisément un intervalle de temps : NON

Mais il y a d'autres méthodes.

V-AB-16. Perdre du temps

Parfois on a besoin de perdre du temps.

Exemple ne rien faire pendant 3 secondes puis poursuivre…

  • Il est exclu de faire des boucles vides :

     
    Sélectionnez
    For i=0 to 100000    ' le temps écoulé est variable en fonction des machines…
    
    Next i
  • Autre méthode : on boucle tant que l'heure courante est inférieure à l'heure du départ+3s

     
    Sélectionnez
    Dim t As DateTime=DateTime.Now
    
    Do While DateTime.Now <t.AddSeconds(3)
    
    Loop

    Mais cela accapare le processeur.

  • On peut utiliser un Timer et vérifier dans la procédure Tick si le temps est écoulé (avec les restrictions que l'on connait).

  • On peut utiliser Thread.Sleep (qui met le processus en cours en sommeil).
 
Sélectionnez
System.Threading.Thread.Sleep(3000)

Le temps de sommeil du thread est en millisecondes : 3000 correspond à 3 secondes.

V-AB-17. Chronométrer

Parfois on a besoin de chronométrer un événement.

Voir la rubrique Chronométrer.

L'exemple sur l'horloge est aussi didactique.

V-AB-18. Exemple: Horloge numérique

Très Simple : comment créer une horloge numérique ?

15:21:45

Dans la fenêtre Form1.

Mettre un Timer (Timer1)

Mettre un label (Label1)

Ajouter le code :

 
Sélectionnez
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

    Timer1.Interval = 1000    'Timer1_Tick sera déclenché toutes les secondes.

    Timer1.Start()            'On démarre le Timer

End Sub

Private Sub Timer1_Tick(ByVal sender As Object, ByVal e As System.EventArgs) Handles Timer1.Tick

Label1.Text = Now.ToLongTimeString    'Affiche l'heure format long.

End Sub

Simple !! non !!

V-AC. Lire et écrire dans les fichiers (séquentiels ou aléatoires)

Image non disponible

Il est probablement nécessaire de lire le chapitre VI sur les Classes avant de lire celui-ci.

Comment lire et écrire dans des fichiers du texte, des octets, du XML du Rtf ?

V-AC-1. Généralités et rappels

Le mot 'fichier' est a prendre au sens informatique: ce n'est pas un ensemble de fiches, mais plutôt un ensemble d'octets. Un fichier peut être un programme (Extension .EXE), du texte (Extension .TXT ou .DOC… ), une image (Extension .BMP .GIF .JPG…), une base de données (.MDB…) du son, de la vidéo…

Pour travailler avec du texte, des octets, des données très simples (sans nécessité d'index, de classement…), on utilise les méthodes décrites dans ce chapitre: travail direct dans les fichiers séquentiels, aléatoires, binaires. Mais dès que les informations sont plus structurées, il faut utiliser les bases de données (il y a plusieurs chapitres plus loin traitant des bases de données).

Un fichier a un nom: 'Image.GIF', une extension: '.GIF' qui en indique généralement le type de contenu , des attributs (Longueur, Date de création, de modification, Fichier en lecture seule ou non…).

On voit cela dans l'explorer Windows :

Image non disponible

Un fichier est composé d'enregistrements qui sont des 'paquets' de données, suivant le type de fichier un enregistrement peut correspondre à une ligne, un octet, un groupe d'octets…

Un fichier peut être vu comme contenant du texte, du XML, des octets.

Comment utiliser les fichiers ? Voici le plan de cet article.

A- Il est conseillé de travailler avec les Classes du Framework.

Avec la Classe FileInfo, on obtient des renseignements sur le fichier.

Pour lire écrire dans un fichier (en dehors des bases de données), il y a plusieurs méthodes:

Avec la Classe System.Io on a a notre disposition StreamReader StreamWriter BinaryReader BinaryWriter FileStream:

Pour lire ou écrire dans un fichier, il faut l'ouvrir (Open), lire ou écrire en utilisant un flux de données (Stream) puis le refermer (Close).

Le Stream (flux, torrent, courant) est une notion générale, c'est donc un flux de données provenant ou allant vers un fichier, un port, une connexion TCP/IP…

L'accès est séquentiel: les données sont traitées du début à la fin du fichier.

B- Il existe toujours la méthode classique du FileOpen.

On ouvre le fichier en mode séquentiel, aléatoire, binaire, on lit X enregistrements, on referme le fichier.

C- Avec certains objets, on gère automatiquement les lectures écritures sur disque.

Comme avec le RichTextBox par exemple.

En résumé, pour travailler sur les fichiers, on dispose :

  • de l'espace de noms System.IO avec les Classes et objets .NET ;
  • des instructions VisualBasic traditionnelles: FileOpen WriteLine… ;
  • des instructions du FSO (FileObjetSystem) pour la compatibilité avec les langages de script.

Les 2 derniers font appel au premier, donc pourquoi ne pas utiliser directement les Classes .NET ?

V-AC-2. Classe FileInfo et File, Stream du Framework

Pour travailler sur les fichiers, il faut au préalable taper :

Imports System.IO

La classe File est utilisée pour travailler sur un ensemble de fichiers ou un fichier (sans instanciation préalable : ce sont des méthodes statiques), la Classe FileInfo donne des renseignements sur un fichier particulier (il faut instancier au préalable un objet FileInfo).

La Classe File possède les méthodes suivantes.

 
Sélectionnez
Exists            Teste si le fichier existe.

Create            Crée le fichier

Copy              Copie le fichier

Delete            Efface le fichier

GetAttributes , SetAttributes     Lire ou écrire les attributs.

GetCreationTime , GetLastAccessTime , GetLastWriteTime et les Set… correspondant.

Move              Déplacement de fichier

Replace           Framework 2

ReadAllText, WriteAllText   Framework 2 lire ou écrire un texte dans un fichier

ReadAllLines, WriteAllLines   Framework 2 lire ou écrire des lignes dans un fichier

ReadAllBytes, WriteAllBytes   Framework 2 lire ou écrire des octets dans un fichier

Toutes les méthodes Open (pour un FileStream) OpenRead, OpenWrite, OpenText.

Exemple

Un fichier existe-t-il? Afficher True s'il existe :

 
Sélectionnez
                        Label1.Text = File.Exists("vessaggi.gif").ToString

Exists est bien une 'méthode de Classe': pas besoin d'instancier quoi que ce soit.

Déplacer un fichier de c: vers d:

 
Sélectionnez
    File.Move("c:\monText.txt", "d:\monText.txt")

Copier un fichier de c: vers d:

 
Sélectionnez
    File.Copy("c:\monText.txt", "d:\monText.txt", True)

Le dernier argument facultatif (framework 2) permet de remplacer le fichier cible s'il existe.

Sauvegarde un fichier et le remplace (Framework 2)

 
Sélectionnez
    File.Copy("c:\monText.txt", "c:\newText.txt",, "c:\newText.bak " True)

Sauvegarde monText.txt dans un .bak , puis copie NewText.txt dans monText.txt; True permet de remplacer la cible si elle existe.

Efface un fichier

 
Sélectionnez
File.Delete("d:\monText.txt")

Lire la totalité d'un fichier texte? (Framework 2)

 
Sélectionnez
Dim myText As String =File.ReadAllText("c:\monText.txt")

File.WriteAllText("c:\monText.txt", myText) 'pour réécrire le texte dans un autre fichier.

La méthode AppendAllText existe aussi.

Lire un fichier texte et mettre dans un tableau les lignes d'un fichier texte ? (Framework 2)

 
Sélectionnez
Dim myLines() As String =File.ReadAllLines("c:\monText.txt")

Lire et mettre dans un tableau les octets d'un fichier (Framework 2)

 
Sélectionnez
    Dim myBytes() As Byte =File.ReadAllBytes("c:\monText.txt")

Un fichier est-il en lecture seule ?

 
Sélectionnez
    If File.GetAttributes("c:\monText.txt") And FileAttributes.ReadOnly Then

La Classe FileInfo possède les propriétés suivantes :

 
Sélectionnez
Name            Nom du fichier (sans chemin)

FullName        Nom complet avec chemin

Extension       Extension   (.txt par exemple)

Length          Longueur du  fichier.

Directory       Répertoire parent

DirectoryName   Répertoire où se trouve le fichier

Exists          Existe?

LastAccessTime  Date du dernier accès, LastWriteTime existe aussi.

Attributes      Attributs

Pour voir les attributs d'un fichier, il faut faire un AND entre Attributes et une valeur de l'énumération FileAttributes ( Archive, Compressed, Directory, Encrypted, Hidden, Normal, ReadOnly, System, Temporaly).

Pour tester ReadOnly par exemple :

 
Sélectionnez
Dim sNom As String = "c:\monfichier.txt"

Dim Fi As FileInfo      'On déclare un FileInfo

Fi=New FileInfo( sNom)  'On instancie ce FileInfo avec comme paramètre le nom du fichier

Ensuite :

 
Sélectionnez
    Fi.Attributes And FileAttributes.ReadOnly    'Retourne True si le fichier est ReadOnly

Et aussi :

Fi.Name retourne "monfichier.txt"

Fi.FullName retourne "c:\monfichier.txt"

Fi.Name.Substring(0, Fi.Name.LastIndexOf(".")) retourne "monfichier" : pas de chemin ni d'extension.

Et les méthodes suivantes :

Create, Delete, MoveTo

AppendTex, CopyTo Open, OpenRead, OpenWrite, OpenText…

On voit que toutes les informations sont accessibles.

Exemple

Pour un fichier, afficher successivement le nom, le nom avec répertoire, le répertoire, la longueur, la date de dernière écriture et si le fichier est en ReadOnly.

 
Sélectionnez
Dim sNom As String = "c:\monfichier.txt"

Dim Fi As FileInfo  'On déclare un FileInfo

Fi=New FileInfo( sNom)  'on instance ce FileInfo avec comme paramètre le nom du fichier

    MsgBox("Nom="& Fi.Name)

    MsgBox("Nom complet ="& Fi.FullName)

    MsgBox("Répertoire="& Fi.DirectoryName)

    MsgBox("Longueur="& Fi.Length.ToString)

    MsgBox("Date dernière modification="& Fi.LastWriteTime.ToShortDateString)

    MsgBox("ReadOnly="& (Fi.Attributes And FileAttributes.ReadOnly).ToString)

V-AC-3. Classe My.Computer.FileSystem

À partir de VS 2005 il y a en plus la classe My.Computer.FileSystem qui simplifie énormément les choses.

Les méthodes CopyFile, DeleteFile, FileExits permettent de copier, effacer un fichier ou de voir s'il existe. Il existe aussi RenameFile et MoveFile.

Exemple

Afficher dans une MsgBox True si 'c:\config.sys' existe.

 
Sélectionnez
MsgBox(My.Computer.FileSystem.FileExists("c:\config.sys").ToString)

Exemple

Afficher la liste des fichiers qui sont sous c:\; ici on utilise GetFiles qui retourne une collection des fichiers.Count contient le nombre de fichiers, item () les noms.

 
Sélectionnez
Dim i As Integer

For i = 0 To My.Computer.FileSystem.Getfiles("c:\").Count - 1

ListBox1.Items.Add(My.Computer.FileSystem.GetFiles("c:\").Item(i))

Next i

Un fichier existe-t-il et est-il ouvert et utilisé par une autre application ?

 
Sélectionnez
If My.Computer.FileSystem.FileExists("c:\monText.txt") Then

Try

   'on tente d'ouvrir un stream sur le fichier, s'il est déjà utilisé, cela déclenche une erreur.

   Dim fs As IO.FileStream = My.Computer.FileSystem.GetFileInfo("c:\monText.txt").Open(IO.FileMode.Open, _ 
   IO.FileAccess.Read)

   fs.Close()

Catch ex As Exception

  MsgBox("Le fichier  est déjà ouvert")

End Try

End If

V-AC-4. Utiliser les "Stream" du Framework

Le Stream (flux, torrent, courant) est une notion générale, c'est donc un flux de données provenant ou allant vers un fichier, un port, une connexion TCP/IP…

Ici on utilise un Stream pour lire ou écrire dans un fichier.

L'accès est séquentiel: les données sont traitées du début à la fin du fichier.

Pour écrire dans un fichier texte :

il faut instancier un objet de la classe StreamWriter. Puis on écrit avec Write ou WriteLine (ajoute un saut de ligne). Enfin on ferme avec Close.

On peut instancier avec le constructeur de la classe StreamWriter et avec New, ou par la Classe File.

 
Sélectionnez
Dim SW As New StreamWriter ("MonFichier.txt") ' crée le fichier ou, si existe déjà, écrase

Il existe une surcharge permettant de ne pas écraser, mais d'ajouter à la fin du fichier :

 
Sélectionnez
Dim SW As New StreamWriter ("MonFichier.txt", True) ' crée ou si existe ajoute

Avec la classe File :

 
Sélectionnez
Dim SW As  StreamWriter=File.CreateText ("MonFichier.txt") ' crée ou si existe écrase

Dim SW As StreamWriter = File.AppendText("MonFichier.txt") ' crée ou si existe ajoute

Ensuite pour écrire 2 lignes :

 
Sélectionnez
SW.WriteLine ("Bonjour")

SW.WriteLine ("Monsieur")

Enfin on ferme :

 
Sélectionnez
SW.Close()

Pour lire dans un fichier Texte :

il faut instancier un objet de la classe StreamReader. Puis on lit avec Read (un nombre d'octets) ReadLine (une ligne) ReadToEnd (de la position courante jusqu'à la fin). Enfin on ferme avec Close.

Avec le constructeur de la Classe Stream Reader :

 
Sélectionnez
Dim SR As New StreamReader ("MonFichier.txt")

Avec la Classe File :

 
Sélectionnez
Dim SR As  StreamReader=File.OpenText ("MonFichier.txt") '

Comment lire chaque ligne du fichier et s'arrêter à la fin ?

En effet on ne sait pas habituellement combien le fichier contient de ligne, si le fichier contient 2 lignes il faut en lire 2 et s'arrêter sinon on tente de lire après la fin du fichier et cela déclenche une erreur.

Trois solutions :

  1. Utiliser ReadToEnd qui lit en bloc jusqu'à la fin ;
  2. Avant ReadLine mettre un Try : quand l'erreur 'fin de fichier' survient elle est interceptée par Catch qui sort du cycle de lecture et ferme le fichier ;
  3. Utiliser Peek qui lit dans le fichier un caractère, mais sans modifier la position courante de lecture.

La particularité de Peek est de retourner -1 s'il n'y a plus de caractère à lire sans déclencher d'erreur, d'exception.

La troisième solution est la plus générale et la plus élégante :

 
Sélectionnez
Do Until SR.Peek=-1

     Ligne=SR.ReadLine()

Loop

Enfin on ferme:

SR.Close()

Notion de 'Buffer', utilisation de Flush

En fait quand on écrit des informations sur le disque, le logiciel travaille sur un buffer ou mémoire tampon qui est en mémoire vive. Si on écrit des lignes dans le fichier, elles sont 'écrites' dans le buffer en mémoire vive. Quand le buffer est plein (ou que l'on ferme le fichier) l'enregistrement du contenu du buffer est effectué effectivement sur le disque.

Ce procédé est général à l'écriture et à la lecture de fichier, mais totalement transparente, car le programmeur ne se préoccupe pas des buffers.

Parfois, par contre, même si on a enregistré peu d'informations, on veut être sûr qu'elle est sur le disque, il faut donc forcer l'enregistrement sur disque même si le buffer n'est pas plein, on utilise alors la méthode Flush.

 
Sélectionnez
  SW.Flush()

Le fait de fermer un fichier par Close, appelle automatiquement Flush() ce qui enregistre des données du buffer.

V-AC-5. Utiliser "FileOpen" du VisualBasic

Bonjour les anciens.

Visual Basic fournit trois types d'accès au fichier :

  • l'accès séquentiel pour lire et écrire des fichiers 'texte' de manière continue, chaque donnée est enregistrée successivement du début à la fin; les enregistrements n'ont pas la même longueur, ils sont séparés par un séparateur (des virgules ou des retours à la ligne).
Image non disponible

On ne peut qu'écrire le premier enregistrement puis le second, le troisième, le quatrième…

Pour lire, c'est pareil: on ouvre, on lit le premier, le second, le troisième, le quatrième…

Pour lire le troisième enregistrement, il faut lire avant les 2 premiers ;

  • l'accès aléatoire (Random), (on le nomme parfois accès direct) pour lire et écrire des fichiers texte ou binaire constitués d'enregistrements de longueur fixe; on peut avoir directement accès à un enregistrement à partir de son numéro.
Image non disponible

Les enregistrements ont une longueur fixe: il faut prévoir!! si on décide de 20 caractères pour le prénom, on ne pourra pas en mettre 21, le 21e sera tronqué, à l'inverse l'enregistrement de 15 caractères sera complété par des blancs.

Il n'y a pas de séparateur entre les enregistrements.

Les enregistrements peuvent être constitués d'un ensemble de variables: une structure, ici prénom et adresse.

Ensuite on peut lire directement n'importe quel enregistrement, le second enregistrement par exemple, ou écrire sur le 3e.(on comprend que, connaissant la longueur d'un enregistrement qui est fixe, l'ordinateur peut calculer la position d'un enregistrement quelconque ;

  • l'accès binaire, pour lire et écrire dans tous les fichiers, on lit ou écrit un nombre d'octets désiré à une position désirée… C'est comme l'accès direct, on peut lire le 36e octet…
Image non disponible

En pratique

Les fichiers séquentiels sont bien pratiques pour charger une série de lignes (toujours la même) dans une ListBox par exemple.

Faut-il utiliser les fichiers séquentiels ou random (à accès aléatoire, à accès direct) pour créer par exemple un petit carnet d'adresses?

Il y a deux manières de faire :

  • créer un fichier random et lire ou écrire dans un enregistrement pour lire ou modifier une adresse ;
  • créer un fichier séquentiel. À l'ouverture du logiciel, lire séquentiellement toutes les adresses et les mettre dans un tableau (de structure). Pour lire ou modifier une adresse: lire ou modifier un élément du tableau. En sortant du programme enregistrer tous les éléments du tableau séquentiellement.(Enregistrer dans un nouveau fichier, effacer l'ancien, renommer le nouveau avec le nom de l'ancien).

Bien sûr s'il y a de nombreux éléments dans une adresse, un grand nombre d'adresses, il faut utiliser une base de données.

Attention : si on ouvre un fichier en écriture et qu'il n'existe pas sur le disque, il est créé.

Si on ouvre un fichier en lecture et qu'il n'existe pas, une exception est déclenchée (une erreur). On utilisait cela pour voir si un fichier existait: on l'ouvrait, s'il n'y avait pas d'erreur c'est qu'il existait. Mais maintenant il y a plus simple pour voir si un fichier existe (File.Exists).

Si on ouvre un fichier et que celui-ci est déjà ouvert par un autre programme, il se déclenche généralement une erreur (sauf si on l'ouvre en Binaire, c'était le cas en VB6, c'est à vérifier en VB.NET).

Pour ouvrir un fichier, on utilise FileOpen.

FileOpen (FileNumber, FileName, Mode, Access, Share, RecordLength)

Paramètres de FileOpen

FileNumber

À tout fichier est affecté un numéro unique, c'est ce numéro que l'on utilisera pour indiquer sur quel fichier pratiquer une opération… Utilisez la fonction FreeFile pour obtenir le prochain numéro de fichier disponible.

FileName

Obligatoire. Expression de type String spécifiant un nom de fichier. Peut comprendre un nom de répertoire ou de dossier, et un nom de lecteur.

Mode

Obligatoire. Énumération OpenMode spécifiant le mode d'accès au fichier : Append, Binary, Input (séquentiel en lecture), Output (séquentiel en écriture) ou Random (accès aléatoire).

Access

Facultatif. mot-clé spécifiant les opérations autorisées sur le fichier ouvert : Read, Write ou ReadWrite. Par défaut, la valeur est OpenAccess.ReadWrite.

Share

Facultatif. Spécifiant si un autre programme peut avoir en même temps accès au même fichier : Shared (permet l'accès aux autres programmes), Lock Read (interdit l'accès en lecture), Lock Write (interdit l'accès en écriture) et Lock Read Write (interdit totalement l'accès). Le processus OpenShare.Lock Read Write est paramétré par défaut.

RecordLength

Facultatif. Nombre inférieur ou égal à 32 767 (octets). Pour les fichiers ouverts en mode Random, cette valeur représente la longueur de l'enregistrement. Pour les fichiers séquentiels, elle représente le nombre de caractères contenus dans la mémoire tampon.

Pour écrire dans un fichier, on utilise :

Print, Write, WriteLine dans les fichiers séquentiels ;

FilePut dans les fichiers aléatoires.

Pour lire dans un fichier, on utilise :

Input, LineInput dans les fichiers séquentiels ;

FileGet dans les fichiers aléatoires.

Pour fermer le fichier, on utilise FileClose().

Numéro de fichier

Pour repérer chaque fichier, on lui donne un numéro unique (de type Integer).

La fonction FreeFile retourne le premier numéro libre.

 
Sélectionnez
Dim No as Integer

No= Freefile()

Ensuite on peut utiliser No pour repérer le fichier sur lequel on travaille.

 
Sélectionnez
FileOpen( No, "MonFichier", OpenMode.Output)

Print(No,"toto")

FileClose (No)

V-AC-5-a. Fichier séquentiel en VB

Vous devez spécifier si vous voulez lire (entrer) des caractères issus du fichier (mode Input), écrire (sortir) des caractères vers le fichier (mode Output) ou ajouter des caractères au fichier (mode Append).

Ouvrir le fichier 'MonFichier' en mode séquentiel pour y écrire :

 
Sélectionnez
Dim No as integer

No= Freefile

FileOpen( No, "MonFichier", OpenMode.Output)

Pour écrire dans le fichier séquentiel : on utilise Write ou WriteLine Print ou PrintLine.

  • La fonction Print écrit dans le fichier sans aucun caractère de séparation.

     
    Sélectionnez
    Print(1,"toto")
    
    Print(1,"tata")
    
    Print(1, 1.2)

    Donne le fichier 'tototata1.2'

  • La fonction Write insère des points-virgules entre les éléments et des guillemets de part et d'autre des chaines au moment de leur écriture dans le fichier, les valeurs booléennes et les variables DateTime sont écrites sans problèmes.

     
    Sélectionnez
    Write(1,"toto")
    
    Write(1,"tata")
    
    Write(1, 1.2)

    Donne le fichier '"toto";"tata";1.2"

    Attention s'il y a des points-virgules dans les chaines, elles seront considérées comme séparateurs !! ce qui entraine des erreurs à la lecture. Il faut mettre la chaine entre "" ou bien remplacer le point-virgule par un caractère non utilisé (# par exemple) avant de l'enregistrer puis après la lecture remplacer '#' par ';'

    Il faut utiliser Input pour relire ces données (Input utilise aussi le point-virgule comme séparateur.

  • La fonction WriteLine insère un caractère de passage à la ligne, c'est-à-dire un retour chariot+ saut de ligne (Chr(13) + Chr(10)),On lira les données par LineInput.
 
Sélectionnez
WriteLine(1,"toto")

WriteLine(1,"tata")

WriteLine(1, 1.2)

Donne le fichier:

"toto"

"tata"

1.2

Il faut utiliser LineInput pour relire ces données, car il lit jusqu'au retour Chariot, saut de ligne.

Toutes les données écrites dans le fichier à l'aide de la fonction Print respectent les conventions internationales ; autrement dit, les données sont mises en forme à l'aide du séparateur décimal approprié. Si l'utilisateur souhaite produire des données en vue d'une utilisation par plusieurs paramètres régionaux, il convient d'utiliser la fonction Write

EOF (NuméroFichier) veut dire 'End Of File', (Fin de Fichier) il prend la valeur True si on est à la fin du fichier et qu'il n'y a plus rien à lire.

LOF (NuméroFichier) veut dire 'Length Of File', il retourne la longueur du fichier.

Exemple: Lire chaque ligne d'un fichier texte.

 
Sélectionnez
Dim Line As String
FileOpen(1, "MonFichier.txt", OpenMode.Input) ' Ouvre en lecture.
While Not EOF(1) ' Boucler jusqu'à la fin du fichier

Line = LineInput(1) ' Lire chaque ligne
Debug.WriteLine(Line) ' Afficher chaque ligne sur la console.
 

End While
FileClose(1) ' Fermer.

Ici on a utilisé une boucle While… End While qui tourne tant que EOF est Faux. Quand on est à la fin du fichier EOF (End of File)devient égal à True et on sort de la boucle.

V-AC-5-b. Fichier à accès aléatoire en VB

On ouvre le fichier avec FileOpen et le mode OpenMode.Random, ensuite on peut écrire un enregistrement grâce à FilePut() ou en lire un grâce à FileGet(). On peut se positionner sur un enregistrement précis (le 2e, le 15e) avec Seek.

Le premier enregistrement est l'enregistrement numéro 1.

Exemple : Fichier des adresses.

Créer une structure Adresse, on utilise <VBFixedString( )> pour fixer la longueur.

 
Sélectionnez
Public Structure Adresse

   <VBFixedString(20)>Dim Nom        As String

   <VBFixedString(20)>Dim Rue        As String

   <VBFixedString(20)>Dim Ville      As String

End Structure


 

'Ouvrir le fichier, comme il n'existe pas, cela entraine sa création
Dim FileNum As Integer, RecLength As Long,  UneAdresse As Adresse
' Calcul de la longueur de l'enregistrement 
RecLength = Len(UneAdresse)
' Récupérer le premier numéro de fichier libre.
FileNum = FreeFile
' Ouvrir le fichier.
FileOpen(FileNum, "MONFICHIER.DAT", OpenMode.Random, , , RecLength)

Pour écrire des données sur le second enregistrement par exemple :

 
Sélectionnez
UneAdresse.Nom = "Philippe"

UneAdresse.Rue = "Grande rue"

UneAdresse.Ville = "Lyon"

FilePut(FileNum, UneAdresse,2 )

Dans cette ligne de code, 'FileNum' contient le numéro utilisé par la fonction FileOpen pour ouvrir le fichier, 2 (un Long) est le numéro de l'enregistrement ou est copié la variable 'UneAdresse' et 'UneAdresse' est une variable déclarée en tant que type Adresse défini par l'utilisateur. Cela écrase l'enregistrement 2 s'il contenait quelque chose.

Pour écrire à la fin du fichier, ajouter un enregistrement, il faut connaitre le nombre d'enregistrements et écrire l'enregistrement suivant.

 
Sélectionnez
Dim last as long  'noter que le numéro d'enregistrement est un long

Pour connaitre le nombre d'enregistrements, il faut diviser la longueur du fichier par la longueur d'un enregistrement.

 
Sélectionnez
last = FileLen("MONFICHIER.DAT") / RecLength

On ajoute 1 pour créer un nouvel enregistrement.

 
Sélectionnez
FilePut(FileNum, UneAdresse,last+1 )

Pour lire un enregistrement (le premier par exemple) :

 
Sélectionnez
FileGet(FileNum, UneAdresse, 1)

Attention Option Strict doit être à false .

Si option Strict est à True, la ligne qui précède génère une erreur, car le second argument attendu ne peut pas être une variable 'structure'. Pour que le second argument de FileGet (une adresse) soit converti dans une variable Structure automatiquement Option Strict doit donc être à false. (Il doit bien y avoir un moyen de travailler avec Option Strict On et de convertir explicitement, mais je ne l'ai pas trouvé)

Remarque: si le fichier contient 4 enregistrements, on peut écrire le 10e enregistrement, VB ajoute entre le 4e et le 10e, 5 enregistrements vides. On peut lire un enregistrement qui n'existe pas, cela ne déclenche pas d'erreur.

Le numéro d'enregistrement peut être omis dans ce cas c'est l'enregistrement courant qui est utilisé.

On positionne l'enregistrement courant avec Seek.

Exemple : Lire le 8e enregistrement :

 
Sélectionnez
    Seek(FileNum,8)
    FileGet(FileNum,Une Adresse)

Suppression d'enregistrements

Vous pouvez supprimer le contenu d'un enregistrement en effaçant ses champs (enregistrer à la même position des variables vides), mais l'enregistrement existe toujours dans le fichier.

Pour supprimer totalement un enregistrement :

  • créez un nouveau fichier ;
  • copiez tous les enregistrements valides du fichier d'origine dans le nouveau fichier (pas ceux qui sont vides) ;
  • fermez le fichier d'origine et utilisez la fonction Kill pour le supprimer ;
  • utilisez la fonction Rename pour renommer le nouveau fichier en lui attribuant le nom du fichier d'origine.

V-AC-5-c. Fichier binaire en VB

Dans les fichiers binaires, on travaille sur les octets.

La syntaxe est la même que pour les fichiers Random, sauf qu'on travaille sur la position d'un octet et non sur un numéro d'enregistrement.

Pour ouvrir un fichier binaire :

FileOpen(FileNumber, FileName, OpenMode.Binary)

FileGet et FilePut permettent de lire ou d'écrire des octets .

 
Sélectionnez
FileOpen(iFr, ReadString, OpenMode.Binary)
MyString = New String(" "c, 15)        'Créer une chaine de 15 espaces
FileGet(iFr, MyString)                 ' Lire 15 caractères dans MyString
FileClose(iFr)
MsgBox(MyString)

Le fait de créer une variable de 15 caractères et de l'utiliser dans FileGet permet de lire 15 caractères.

V-AC-6. Utilisation du Contrôle RichTextBox

Un contrôle RichTextBox est un contrôle qui contient du texte enrichi qui peut être modifié. On rappelle que du texte présent dans un contrôle RichTextBox peut être enregistré ou lu très simplement avec les méthodes .SaveFile et .LoadFile.

Le texte peut être du texte brut ou du RTF.

Comment enregistrer cetexte dans un fichier sur disque ?

 
Sélectionnez
richTextBox1.SaveFile(FileName, RichTextBoxStreamType.PlainText)

Si on remplace .PlainText par .RichText c'est le texte enrichi et non le texte brut qui est enregistré

Pour lire un fichier, il faut employer .LoadFile avec la même syntaxe.

Simple, non !!!

V-AC-7. Lire ou écrire des octets ou du XML

BinaryWriter et BinaryReader permettent d'écrire ou de lire des données binaires.

XMLTextWriter et XMLTextReader écrivent et lisent du Xml.

Pour enregistrer un tableau, un objet, Vb.Net propose aussi la Sérialization (voir ce chapitre).

V-AC-8. Boite de dialogue pour choix de fichier

Tapez :

 
Sélectionnez
Dim dialogOpen As New OpenFileDialog  

 

With DialogOpen

.InitialDirectory = "C:"            'répertoire sur lequel s'ouvrira la boite

.Title = "Choisir un fichier"          'titre de la barre  

.Filter = "Fichiers LDF(*.ldf)|*.ldf"   'filtre, seuls les fichiers LDF apparaitront

.ShowDialog()                           ' on ouvre la boite de dialogue enfin

        'Retour après la fermeture de la boite de dialogue

If Err.Number = 32755 Then Exit Sub     'le bouton 'annuler' a-t-il été cliqué ?

If Len(.FileName) = 0 Then  Exit Sub     'aucun choix

Dim sFile As String = .FileName           'nom du fichier choisi ( avec extension) 

End With
Image non disponible

Vous avez le nom du fichier à ouvrir, vous devez écrire le code pour l'ouvrir avec un Open…

SaveFileDialog existe aussi.

V-AC-9. Stream et fichier aléatoire avec structure

Comment enregistrer, lire, effacer des données (qui sont dans une variable structurée) dans un fichier binaire:

Sans utiliser de FileOpen FilePut, FileGet, mais en utilisant plutôt des FileStream (un BinaryReader et un BinaryWriter). On reste dans le Framework .Net.

Par Bruno Chappe.

Débutant s'abstenir.

Cette syntaxe est entièrement écrite en VB .NET 2005, et n'utilise que des objets avec méthodes et propriétés issues de VB .NET 2005.

On crée une Structure 'personne', une Class 'myBinaryReader', une Class 'myBinaryWriter' permettant de lire et d'enregistrer des 'personne'.

'System.IO doit être importé dans l'entête de votre module.

ÉTAPE N°1 : Créer la structure et les classes binaryReader et binaryWriter personnalisées.

 
Sélectionnez
'Créer la structure avec son constructeur spécifique 

Structure personne

Public pNom As String

Public pPrenom As String 

Public pAge As Integer 

Public pMarie As Boolean 

Sub New(ByVal myNom As String, ByVal myPrenom As String, ByVal myAge As Integer, ByVal myMarie As Boolean) 

Me.pNom = myNom

Me.pPrenom = myPrenom

Me.pAge = myAge

Me.pMarie = myMarie 

End Sub 

End Structure 

  

'Créer une classe de binarywriter personnalisée à partir de la classe binarywriter 
' native de vb 

Class myBinarywriter 

Inherits System.IO.BinaryWriter 

Sub New ( ByVal st1 As System.IO.Stream ) 

MyBase.New(st1) 

End Sub 

'PadRight est utilisé pour faire des chaines de caractères de longueur  fixes 

'C'est indispensable pour pouvoir calculer la longueur des enregistrements 
' par la suite et avoir des enregistrements qui ont tous la même longueur 

Overloads Sub write( ByVal e As personne ) 

MyBase.Write(e.pNom.PadRight(15)) 

MyBase.Write(e.pPrenom.PadRight(15)) 

MyBase.Write(e.pAge) 

MyBase.Write(e.pMarie) 

End Sub 

End Class

  

'Créer une classe de binaryreader personnalisée à partir de la classe binaryreader 
' native de vb 

Class myBinaryreader 

Inherits System.IO.BinaryReader 

Sub New ( ByVal st2 As System.IO.Stream ) 

MyBase.New(st2) 

End Sub 

Function readpersonne() As personne 

Dim pNom As String = MyBase.ReadString 

Dim pPrenom As String = MyBase.ReadString 

Dim pAge As Integer = MyBase.ReadInt32 

Dim pMarie As Boolean = MyBase.ReadBoolean 

readpersonne = New personne(pNom, pPrenom, pAge, pMarie) 

End Function 

End Class

ÉTAPE N° 2 : Utilisation des classes personnalisées.

***Écrire un enregistrement

DEBUT

 
Sélectionnez
'Variable string stockant le chemin d'accès au fichier 

Dim myFile as String

'Si l'on veut écrire directement dans un enregistrement existant 
' (plutôt que d'écrire à la suite du fichier) 

'il faut au préalable récupérer le rang de l'enregistrement ou l'on veut commencer à écrire 

'et multiplier ce rang par la longueur d'un enregistrement (en octets). 
'Cette opération nous donne la position du premier octet à écrire dans le fichier. 

'Pour mémoire, la longueur d'un enregistrement en octet est égale à la taille du fichier en octet 

'divisé par le nombre d'enregistrements (voir Annexe de ce document pour les explications) 

Dim position As Integer

'Déclarer une variable de type 'personne' et assigner les valeurs voulues à ses champs 

'Il est possible de travailler avec un tableau de structure, cela revient au même, mais 

'est moins indispensable qu'avant vu que l'on peut aller écrire et lire directement dans le fichier 

Dim maPersonne As personne

With maPersonne

.pNom = 'valeur du champ

.pPrenom = 'valeur du champ

.pAge = 'valeur du champ

.pMarie = 'valeur du champ

End With

'Déclare le flux et le writer qui vont nous permettre d'écrire notre structure 

'Bien faire attention aux propriétés FileMode et FileAccess en fonction des opérations 

'que vous voulez effectuer 

'Si vous voulez écrire l'enregistrement à la suite des autres : 

Dim fs As FileStream = File.Open(myFile, FileMode.Append, FileAccess.Write, FileShare.None) 

'Si vous voulez réécrite/modifier un enregistrement : 

Dim fs As FileStream = File.Open(myFile, FileMode.Open, FileAccess.Write, FileShare.None) 

'Dans les 2 cas, remarquez ici que nous instancions un objet issu de la classe 
' que nous avons créée plus haut 
'et non pas un objet issu des classes natives de vb 

Dim bw As New myBinarywriter(fs)

'Nécessaire que si vous souhaitez écrire à un endroit précis dans le fichier 

'Où position indique la position de début d'écriture dans le flux (fs) et SeekOrigin.Begin 
' indiquant à partir de quel endroit du flux commencer la recherche de position 

fs.Seek(position, SeekOrigin.Begin) 

'Dans tous les cas, l'instruction ci-dessous écrit l'intégralité de notre structure 
' sous forme binaire dans le fichier 

bw.write(maPersonne)

'SURTOUT BIEN PENSER À FERMER LES FLUX ET WRITER 

bw().Close

fs().Close

FIN

***Lire un enregistrement

DEBUT

 
Sélectionnez
'Variable string stockant le chemin d'accès au fichier 

Dim myFile as String

'Déclarer la variable qui va recevoir les informations issues du fichier 

Dim maPersonne As personne

'Instancier un objet flux et un objet binaryReader 

'Remarquez le FileAcces.Read pour la lecture 

Dim fs As FileStream = File.Open(myFile, FileMode.Open, FileAccess.Read, FileShare.None)

'Objet instancié à partir de notre classe personnalisée myBinaryreader 

Dim br As New myBinaryreader(fs) 

'Si besoin d'aller lire un enregistrement précis 

fs.Seek(position, SeekOrigin.Begin) 'Mêmes paramètres que pour l'écriture

'Sinon, vous ferez probablement un traitement en boucle de tous les enregistrements du fichier 

Do Until fs.Position = fs.Length 'Faire jusqu'à ce que la position 
' dans le flux soit égale à la longueur totale du flux

myPersonne = br.readpersonne

'Ici traitez les informations récupérées, par exemple pour afficher dans un listBox 

Loop

'SURTOUT BIEN PENSER À FERMER LES FLUX ET READER 

br().Close

fs().Close

FIN

***Supprimer un enregistrement

Au préalable il faut marquer l'enregistrement à effacer en utilisant la procédure décrite plus haut pour modifier un enregistrement. Pour cela on peut faire soit comme dans le TP en utilisant un champ "supprimé"de notre structure que l'on marque à True soit on écrit un enregistrement vide par-dessus l'enregistrement que l'on veut effacer (en affectant "Nothing" au premier champ de l'enregistrement par exemple). En résumé, n'importe quoi qui nous permet de repérer au moment de la réécriture du fichier, que cet enregistrement ne doit pas être recopié.

Commencer par créer une copie du fichier original (ne pas oublier de faire des tests sur l'existence du fichier).

 
Sélectionnez
Dim fi As New FileInfo(myFile) 

Dim newFile As String = myFile & &#8220;.bck&#8221; 

fi.CopyTo(newFile) 'Créé newFile et copie myFile dedans 

'Ensuite on ouvre les 2 flux (1 en lecture et 1 en écriture) et les 2 binary (-reader & -writer)

Dim fsR As FileStream = File.Open(newFile, FileMode.Open, FileAccess.Read, FileShare.None) 

'Ici le paramètre FileMode.Create va faire que le fichier myFile va être recréé 
' par-dessus l'ancien fichier et l'écraser 

Dim fsW As FileStream = File.Open(myFile, FileMode.Create, FileAccess.Write, FileShare.None) 

'Après l'instruction ci-dessus on a donc un fichier myFile qui existe, mais qui est vide 
' (sans avoir besoin de le supprimer d'abord et de le recréer ensuite), 
' prêt à recevoir les données du fichier newFile. 

Dim br As New myBinaryreader(fsR) 

Dim bw As New myBinarywriter(fsW) 

'On dimensionne une variable du type de notre structure 

Dim maPersonne As personne

'Faire une boucle sur le fichier en lecture 

Do Until fsR.Position = fsR.Length

maPersonne = br.readpersonne

'Si marquage de maPersonne n'indique pas qu'il faut effacer l'enregistrement alors :

bw.write(maPersonne)

End If

Loop

'Cette boucle va donc lire chaque enregistrement dans newFile, l'affecter dans 
' une variable structurée maPersonne et si cette variable ne contient pas 
' d'indicateur de suppression, l'écrire dans myFile. 
' À la fin de la boucle myFile contient donc tous les enregistrements de newFile sauf ceux marqués à supprimer. 

'On n’oublie pas de fermer les flux 

br.Close()

bw.Close()

fsR.Close()

fsW.Close()

'Et de supprimer le fichier newFile qui ne nous sert plus à rien 

File.Delete(newFile)

ANNEXE : Comment calculer la valeur de la variable "position" utilisée dans la méthode seek de notre FileStream.

Nous avons besoin de 3 éléments : la longueur totale du fichier en octets, la taille d'un enregistrement en octets, le numéro de l'enregistrement que l'on souhaite modifier/remplacer/effacer.

Longueur totale du fichier en octets :

 
Sélectionnez
Dim fi as New FileInfo(myFile) 

Dim longueurFichier As Long

longueurFichier = fi.length 'Renvoie un entier long représentant la taille totale en octet

Taille d'un enregistrement en octets

 
Sélectionnez
Dim nbEnreg As Integer 'Au préalable il faut récupérer le nombre d'enregistrements, 
' par exemple lors d'une première lecture du fichier séquentielle, 
' en incrémentant un compteur par programmation.

Dim tailleEnreg as Integer 

tailleEnreg = longueurFichier / nbEnreg

Pointer directement dans le fichier à l'octet voulu pour l'écriture.

Autrement dit, calculer la variable "position" pour pouvoir l'utiliser dans la méthode seek.

Il suffit de multiplier le numéro de l'enregistrement à écrire (le premier enregistrement doit avoir l'indice 0) par la taille d'un enregistrement. Par exemple, si j'ai un fichier de 120 octets avec 12 enregistrements (de 0 à 11), cela me fait des enregistrements de 10 octets de long. Si je veux aller modifier le 4e enregistrement, ma variable position sera égale à 40 (4*10). Il ne me reste plus qu'à déplacer le pointeur dans mon flux avant d'écrire ma variable, en utilisant :

 
Sélectionnez
fs.Seek(position, SeekOrigin.Begin)

Remarque: Le code proposé dans l'exemple permet de créer un enregistrement de 37 octets par "ligne" pour autant que l'on n'utilise pas de caractères accentués. Il faut ajouter 1 octet pour chaque caractère accentué utilisé dans les zones de texte, et ce, malgré l'usage de la fonction PadRight(15).

L'usage de Seek tel que décrit dans le même chapitre en devient impossible.

Comment corriger cela ?

V-AD. Travailler sur les répertoires et fichiers

Image non disponible

Il est probablement nécessaire de lire le chapitre VI sur les Classes avant de lire celui-ci.

Comment créer, copier effacer des répertoires (ou dossiers) ?

Avec les classes DirectoryInfo et Directory.

Avec la classe Path.

Avec la classe Environment.

Avec My.Computer.FileSystem en VS 2005.

Avec les Classes de VisualBasic.

Comment créer une boite de dialogue 'choix de répertoire' en VB2005 ?

V-AD-1. Classe DirectoryInfo et la Classe Directory du Framework

Pour travailler sur les dossiers (ou répertoires), il faut au préalable taper :

Imports System.IO

La classe Directory est utilisée pour travailler sur un ensemble de dossiers, la Classe DirectoryInfo donne des renseignements sur un dossier particulier (après instanciation ).

La Classe Directory possède les méthodes suivantes.

Exists

Teste si le dossier existe.

CreateDirectory

Crée le dossier

Delete

Efface le dossier

Move

Déplacement de dossier

GetCurrentDirectory

Retourne le dossier de travail de l'application en cours

SetCurrentDirectory

Définit le dossier de travail de l'application.

GetDirectoryRoot

Retourne le dossier racine du chemin spécifié.

GetDirectories

Retourne le tableau des sous-dossiers du dossier spécifié.

GetFiles

Retourne les fichiers du dossier spécifié.

GetFilesSystemEntries

Retourne fichier et sous dossier avec possibilité d'un filtre.

GetLogicalDrives

Retourne les disques

GetParent

Retourne le dossier parent du dossier spécifié.

La Classe Directory est statique: on l'utilise directement.

Exemple

Afficher dans une ListBox les sous-dossiers (répertoires) du répertoire de l'application :

 
Sélectionnez
Dim SousDos() As String= Directory.GetDirectories(Directory.GetCurrentDirectory)

Dim Dossier As String

For Each Dossier In SousDos

    List1.Items.Add(Dossier)

Next

Afficher dans une ListBox les sous-dossiers et fichiers.

On utilise ici la récursivité. Pour chaque sous-répertoire, on appelle la routine elle-même.

 
Sélectionnez
Imports System.IO

 

Sub  AfficheTree ( ByVal myDir As String, ByVal Optional Niveau As Integer =0)

 

'Affiche le répertoire myDir

List1.Items.Add(New String (" ", niveau *2) & myDir)

 

'Affiche les fichiers

For Each fichier As String  In Directory.GetFiles( myDir)

    List1.Items.Add(New String (" ", niveau *2+2) & fichier)

Next

 

'Parcourt les sous-répertoires

For each sousRepertoire As String In Directory.GetDirectories( myDir)

    'Appel de manière récursive 'AfficheTree pour afficher le contenu des sous-répertoires.

    AfficheTree (sousRepertoire, niveau+1)

Next

 

End Sub

La variable niveau permet de pratiquer une indentation :New String (" ", niveau*2) produit une chaine d'espace de longueur niveau *2.

On appelle cette routine avec AfficheTree (c:\myprogramme", 0) 'Pour tester éviter"c:\", car c'est très très long!!! on le fait tous pour tester!!

Directory.GetFiles et Directory.GetDirectories acceptent un argument supplémentaire qui fait office de filtre.

Directory.GetFiles( myDir, "*.txt") 'pour ne voir que les fichiers .txt.

Afficher dans une ListBox les exécutables d'un répertoire et de ses sous-répertoires.

Ici on utilise un argument supplémentaire qui permet de rechercher dans les sous répertoires.

 
Sélectionnez
For Each file As String In Directory.GetFiles("c:\windows", "*.exe", System.IO.SearchOption.AllDirectries ))

    List1.Items.Add (file)

Next

Génial , non ? Quelle économie de code !!

En plus il y a des méthodes permettant de retourner dans une collection IEnumerable la liste des fichiers (Directory.EnumerateFiles) ou la liste des répertoires (Directory.EnumerateDirectories) d'un chemin.
Exemple pour récupérer la liste des fichiers et l'afficher dans un ListBox :

 
Sélectionnez
        ' récupérer la liste des fichiers dans un répertoire
        Dim files1 As IEnumerable = _
            Directory.EnumerateFiles("c:\Article_dvp\global", "*", SearchOption.AllDirectories)
       'Mettre la liste dans une ListBox
        For Each f As String In files1
            ListBox1.Items.Add(f)
        Next

Afficher les disques présents dans une ListBox :

 
Sélectionnez
Imports System.IO

 

For Each disque As String In Directory.GetLogicalDrives()

    List1.Items.Add (Disque)

Next

Afficher dans une ListBox les fichiers .jpg d'un répertoire :

 
Sélectionnez
Dim dirInfo As New System.IO.DirectoryInfo ("C:\Nos Images\sicile")

Dim file As System.IO.FileInfo

Dim files() As System.IO.FileInfo = dirInfo.GetFiles("*.jpg")

If (files IsNot Nothing) Then

For Each file In files

    ListBox1.Items.Add(file.FullName) 

Next

End If

Changer le répertoire courant, effacer un sous-répertoire :

 
Sélectionnez
Directory.SetCurrentDirectory ("c:\mydirectory") 'change le répertoire courant

Directory.Delete (c:\otherdirectory") 'efface ce répertoire s'il est vide

Directory.Delete (c:\otherdirectory", True) 'efface ce répertoire ses fichiers et sous-répertoires.

Ah !! nostalgique du DEL *.*

Il y a d'autres méthodes pour obtenir des infos des répertoires ou des fichiers et les modifier: GetCreationTime, GetLastAccesTime, GetLastWtriteTime et les Set… correspondants.
Exemple permettant de voir la date de création d'un fichier :

 
Sélectionnez
Dim d As String = Directory.GetCreationTime("c:\Article_dvp\global\Thumbs.db")

La Classe DirectoryInfo possède les propriétés suivantes :

 
Sélectionnez
Name            Nom du dossier (sans extension)

Full Name       Chemin et nom du dossier

Exists

Parent         Dossier parent

Root            Racine du dossier

La Classe DirectoryInfo n'est pas statique : il faut instancier un dossier avant de l'utiliser.

Il y a aussi les méthodes suivantes :

 
Sélectionnez
Create, Delete, MoveTo

CreateSubdirectory

GetDirectories    Retourne les sous-dossiers

GetFiles          Retourne des fichiers

GetFileSystemInfos

Exemple

Afficher le répertoire parent d'un dossier :

 
Sélectionnez
Dim D As DirectoryInfo

D= New DirectoryInfo( MonDossier)

MsgBox(D.Parent.ToString)

Créer un répertoire :

 
Sélectionnez
Dim D As DirectoryInfo

D= New DirectoryInfo( MonDossier)

D.CreateSubdirectory("monsousdossier")

Effacer un répertoire et ses sous-répertoires :

 
Sélectionnez
Dim D As DirectoryInfo

D= New DirectoryInfo( MonDossier)

D.Delete(True)

V-AD-2. Classe Path

La Classe statique Path a des méthodes simplifiant la manipulation des répertoires.

Exemple :

 
Sélectionnez
Si  C= "C:\Windows\MonFichier.txt"

Path.GetDirectoryName(C)  'retourne "C:\Windows"

Path.GetFileName(C) retourne "Monfichier.txt"

Path.GetExtension(C) retourne ".txt"

Path.GetFileNameWithoutExtension(C) retourne "MonFichier"

Path.PathRoot(C) retourne "c:\"

Il y a aussi les méthodes GetFullPath ChangeExtension, Combine, HasExtension…

GetFullPath: Transforme un chemin relatif en chemin absolu à l'aide du répertoire courant.

Path.GetFullPath("monAppli.exe")) retourne "C:\MonRep\monAppli.exe" si le répertoire courant est "C:\MonRep"

Combine: combine bout à bout un chemin et un nom de fichier

Path.Combine("C:\MonRep", "monAppli.exe")) retourne "C:\MonRep\monAppli.exe"

V-AD-3. Classe DriveInfo

Nouveauté en VB 2005, la Classe DriveInfo :

Pour un disque particulier, il faut instancier un DriveInfo avec la lettre du drive, ensuite, on a accès à toutes les propriétés du lecteur.

 
Sélectionnez
Dim di As New DriveInfo ("c:")

di.Name retourne le nom  du lecteur ( "c:" ici)

VolumeLabel  Nom (label) du lecteur (en lecture écriture)

DriveType ( Fixed, Removal, CDRom, Ram, Networl, Unknown)

DriveFormat (NTFS, Fat32)

TotalSize, TotalFreeSpace, AvailableFreeSpace

DriveInfo.GetDrives retourne tous les disques installés

 
Sélectionnez
For Each di As DriveInfo in DriveInfo.GetDrives()

 If di.IsReady Then 'il parait qu'il faut bien tester s'il est ready!!

    MsgBox (di.VolumeLabel)

 End if


Next

V-AD-4. Classe Environment

Donne des informations concernant l'environnement et la plateforme en cours ainsi que des moyens pour les manipuler. Par exemple: les arguments de la ligne de commande, le code de sortie, les paramètres des variables d'environnement, le contenu de la pile des appels, le temps écoulé depuis le dernier démarrage du système ou le numéro de version du Common Language Runtime, mais aussi certains répertoires.

 
Sélectionnez
Environment.CurrentDirectory  'donne le répertoire courant : ou le processus en cours démarre.

Environment.MachineName       'Obtient le nom NetBIOS de l'ordinateur local.

Environment.OsVersion 'Obtient un Identificateur et le numéro de version de la plateforme en cours.

Environment.SystemDirectory   'Obtient le chemin qualifié complet du répertoire du système

Environment.UserName          'Obtient le nom d'utilisateur de la personne qui a lancé le thread en cours.

La fonction GetFolderPath avec un argument faisant partie de l'énumération SpecialFolder retourne le répertoire d'un tas de choses.

Exemple : Quel est le répertoire Système ?

 
Sélectionnez
Environment.GetFolderPath(Environment.SpecialFolder.System)

En vb 2010 on trouve les répertoires :
Cookies ;
CDBurning ;
Desktop ;
Favories ;
History ;
Programs ;
MyMusic ;
MyPicture ;
Recent ;
SendTo ;
System ;
Templates ;
Personal (Mydocuments) ;
ProgramFiles ;
UserProfile ;
CommonDocuments, CommonMusic, CommonPictures, CommonVideos ;
MyVideos ;
Ressources ;
Windows.

Comment récupérer le nom des disques ?

 
Sélectionnez
Dim drives As String() = Environment.GetLogicalDrives()

Comment récupérer la ligne de commande ?

 
Sélectionnez
Dim arguments As String() = Environment.GetCommandLineArgs()

ou avec My :

 
Sélectionnez
'Afficher dans une liste Box les arguments de la ligne de commande
ListBox1.DataSource = My.Application.CommandLineArgs.ToArray

V-AD-5. Classe My.Computer.FileSystem en VS 2005

En VS 2005 la classe My.Computer.FileSystem simplifie énormément les choses :

les méthodes CopyDirectory, CreateDirectory, DeleteDirectory, DirectoryExits permettent de copier, créer, effacer un répertoire ou de voir s'il existe. Il existe aussi RenameDirectory et MoveDirectory.

Exemple

Afficher dans une MsgBox True si le répertoire 'c:\MyApplication\' existe.

 
Sélectionnez
MsgBox(My.Computer.FileSystem.DirectoryExists("c:\MyApllication\").ToString)

Copier un répertoire dans un autre :

 
Sélectionnez
My.Computer.FileSystem.CopyDirectory("c:\a\", "c:\b\")

Afficher la liste des répertoires qui sont sous c:\; ici on utilise GetDirectories qui retourne une collection des répertoires.(count contient le nombre des répertoires, item () les noms.

 
Sélectionnez
Dim i As Integer

For i = 0 To My.Computer.FileSystem.GetDirectories("c:\").Count - 1

ListBox1.Items.Add(My.Computer.FileSystem.GetDirectories("c:\").Item(i))

Next i

SpecialDirectories permet de connaitre certains répertoires spéciaux comme Programs, My Documents, My Music…

Exemple

 
Sélectionnez
MsgBox(My.Computer.FileSystem.SpecialDirectories.CurrentUserApplicationData)

My.Computer.FileSystem.Drives est une collection contenant les disques présents.

On peut rechercher les fichiers qui contiennent un certain texte et afficher leurs noms dans une listBox.

Grâce à My.Computer.FileSystem.FindInFiles (Répertoire, texteàchercher, respectdelacasse, tyderecherche)

 
Sélectionnez
Dim value As System.Collections.ObjectModel.ReadOnlyCollection(Of String) = My.Computer.FileSystem.FindInFiles
_("c:\", "Open", False, FileIO.SearchOption.SearchTopLevelOnly)

For Each name As String In value

ListBox1.Items.Add(name)

Next

V-AD-6. Les méthodes de l'espace Visual Basic

CurDir() retourne le chemin d'accès en cours.

 
Sélectionnez
MyPath = CurDir() 
MyPath = CurDir("C"c)

Dir()

Retourne une chaine représentant le nom d'un fichier, d'un répertoire ou d'un dossier qui correspond à un modèle ou un attribut de fichier spécifié ou à l'étiquette de volume d'un lecteur.

 
Sélectionnez
'vérifier si un fichier existe:

' Retourne "WIN.INI" s’il existe.
MyFile = Dir("C:\WINDOWS\WIN.INI")

' Retourne le fichier spécifié par l'extension .
MyFile = Dir("C:\WINDOWS\*.INI")

'Un nouveau Dir retourne le fichier suivant
MyFile = Dir()

' On peut surcharger avec un attribut qui sert de filtre .
MyFile = Dir("*.TXT", vbHidden) ' affiche les fichiers cachés

' Recherche les sous-répertoires.
MyPath = "c:\" ' Set the path.
MyName = Dir(MyPath, vbDirectory)

ChDrive change le lecteur actif. La fonction lève une exception si le lecteur n'existe pas.

 
Sélectionnez
ChDrive("D")

MkDir crée un répertoire ou un dossier. Si aucun lecteur n'est spécifié, le nouveau répertoire ou dossier est créé sur le lecteur actif.

 
Sélectionnez
MkDir("C:\MYDIR")

RmDir efface un répertoire ou un dossier existant.

 
Sélectionnez
' Vérifier que le répertoire est vide sinon effacer les fichiers avec Kill.
RmDir ("MYDIR")

ChDir change le répertoire par défaut, mais pas le lecteur par défaut.

 
Sélectionnez
ChDir("D:\TMP")

L'exécution de changements relatifs de répertoire s'effectue à l'aide de "…", comme suit :
ChDir("…") ' Remonte au répertoire parent.

FileCopy
Copier un fichier.

 
Sélectionnez
FileCopy(SourceFile, DestinationFile)

Rename
Renommer un fichier, un répertoire ou un dossier.

 
Sélectionnez
Rename (OldName, NewName)

FileLen donne la longueur du fichier, SetAttr et GetAttr pour modifier ou lire les attributs du fichier.

 
Sélectionnez
Result = GetAttr(FName)

Result est une combinaison des attributs. Pour déterminer les attributs, utilisez l'opérateur And pour effectuer une comparaison d'opérations de bits entre la valeur retournée par la fonction GetAttr et la valeur de l'attribut. Si le résultat est différent de zéro, cet attribut est défini pour le fichier désigné. Par exemple, la valeur de retour de l'expression And suivante est zéro si l'attribut Archive n'est pas défini :

 
Sélectionnez
Result = GetAttr(FName) And vbArchive

V-AD-7. Boite de dialogue 'Choix de répertoire' en VB2005

Il faut instancier un FolderBrowserDialog, indiquer le répertoire de départ (RootFolder), le texte de la barre (Description) et l'ouvrir avec ShowDialog.

Le répertoire sélectionné par l'utilisateur se trouve dans SelectedPath.

 
Sélectionnez
Dim fB As New FolderBrowserDialog

fB.RootFolder = Environment.SpecialFolder.Desktop

fB.Description = "Sélectionnez un répertoire"

fB.ShowDialog()

If fB.SelectedPath = String.Empty Then

  MsgBox("Pas de sélection")

Else

  MsgBox(fB.SelectedPath)

End If

fB.Dispose()
Image non disponible

V-AD-8. Parcours de répertoires et de sous répertoires

Parcours de répertoires et sous-répertoires

On veut afficher dans une ListBox les noms des répertoires, sous-répertoires et fichiers en utilisant la récursivité.

On crée une routine AfficheTree qui affiche :

- le nom du répertoire courant ;

- le nom des fichiers du répertoire courant ;

- qui parcourt les sous-répertoires et pour chacun d'eux appelle AfficheTree.

 
Sélectionnez
Imports System.IO

 

Sub  AfficheTree ( ByVal myDir As String, ByVal Optional Niveau As Integer =0)

 

'Affiche le répertoire myDir

List1.Items.Add(New String (" ", niveau *2) & myDir)

 

'Affiche les fichiers

For Each fichier As String  In Directory.GetFiles( myDir)

    List1.Items.Add(New String (" ", niveau *2+2) & fichier)

Next

 

'Parcourt les sous-répertoires

For each sousRepertoire As String In Directory.GetDirectories( myDir)

    'Appel de manière récursive 'AfficheTree pour afficher le contenu des sous répertoires.

    AfficheTree (sousRepertoire, niveau+1)

Next

 

End Sub

V-AD-9. Fichiers et répertoires avec Linq

Lire le nom des fichiers du répertoire courant avec Linq.(VB 2008)

 
Sélectionnez
Dim myFiles= From Files in My.Computer.fyleSystem.GetFile(CurDir)

Select Files

V-AE. Afficher correctement du texte

Image non disponible
  1. Remarque sur le rafraîchissement de l'affichage.
  2. Comment afficher du texte, du numérique suivant le format désiré ?
  3. Comment utiliser les 'CultureInfo' ?

V-AE-1. Remarque sur la mise à jour de l'affichage

La mise à jour de l'affichage d'un Label (comme les autres contrôles d'ailleurs) est effectuée en fin de Sub.

Si on écrit :

 
Sélectionnez
Dim i As Integer

For i = 0 To 100

    Label1.Text = i.ToString

Next i

La variable i prend les valeurs 1 à 100, mais à l'affichage rien ne se passe pendant la boucle, VB affiche uniquement 100 à la fin.
Cela provient du fait qu'il y a une hiérarchie dans l'exécution des tâches; on a l'impression que l'affichage à une priorité faible et qu'il est effectué en fin de Sub quand la totalité du code a été exécuté.
Si on désire voir les chiffres défiler avec affichage de 0 puis 1 puis 2… il faut rafraîchir l'affichage à chaque boucle avec la méthode Refresh() :

 
Sélectionnez
Dim i As Integer

For i = 0 To 100

    Label1.Text = i.ToString: Label1.Refresh()

Next i

Une alternative est de mettre un Application.DoEvents() qui donne à Windows le temps de traiter les messages et de rafraîchir l'affichage.

V-AE-2. Afficher du texte

On a vu que pour afficher du texte il fallait l'affecter à la propriété 'Text' d'un label ou d'un textBox (ou pour des tests l'afficher sur la fenêtre 'console').

Pas de problème pour afficher des chaines de caractères, par contre, pour les valeurs numériques, il faut d'abord les transformer en 'String' et les formater (définir les séparateurs, le nombre de décimales…).

Ce n'est pas à proprement parler une conversion, mais plutôt une mise en forme.

V-AE-2-a. ToString

On a déjà vu que pour afficher une variable numérique, il fallait la transformer en 'String' de la manière suivant :

MyDouble.ToString

Exemple : pour afficher dans un TextBox la valeur contenue dans la variable MyDouble:
MyTextBox.Text=MyDouble.ToString

ToString utilise le séparateur de la culture en cours (',' si vous être en culture française, '.' si vous êtes en culture anglaise).

Mais ToString peut être surchargé par un paramètre appelé chaine de format. Cette chaine de format peut être standard ou personnalisée.

Chaine de format standard

Cette chaine est de la forme 'Axx' ou A donne le type de format et xx le nombre de chiffres après la virgule. Le format est défini par la 'culture' en cours ( française, anglaise…)sur le thread courant.

 
Sélectionnez
Imports System
Imports System.Globalization
Imports System.Threading

Module Module1
Sub Main()

Thread.CurrentThread.CurrentCulture = New CultureInfo("en-us")'changement de culture
Dim UnDouble As Double = 123456789

Console.WriteLine("Cet exemple est  en-US culture:")
Console.WriteLine(UnDouble.ToString("C"))    'format monétaire (C) affiche $123,456,789.00
Console.WriteLine(UnDouble.ToString("E"))    'format scientifique (E) affiche     1.234568E+008
Console.WriteLine(UnDouble.ToString("P"))    'format %   (P)            affiche      12,345,678,900.00%
Console.WriteLine(UnDouble.ToString("N"))    'format nombre (N)    affiche      123,456,789.00
Console.WriteLine(UnDouble.ToString("N4"))   'format nombre (N) 4 chiffres après la virgule, affiche  123,456,789.0000
Console.WriteLine(UnDouble.ToString("F"))    'format virgule fixe (F) affiche       123456789.00

End Sub
End Module

La 'culture' en cours est utilisée; ainsi en français le format 'N' utilise le séparateur décimal ','.

Autre exemple

S=(1.2).ToString("C") retourne en CurrentCulture Français (par défaut sur mon ordinateur) :1,2€

Il existe aussi D pour décimal, G pour général X pour hexadécimal.

  • Chaine de format personnalisé

On peut créer de toute pièce un format, on utilise pour cela les caractères suivants :

0 indique un espace réservé de 0

Chaque '0' est réservé à un chiffre. Affiche un chiffre ou un zéro. Si le nombre contient moins de chiffres que de zéros, affiche des zéros non significatifs. Si le nombre contient davantage de chiffres à droite du séparateur décimal qu'il n'y a de zéros à droite du séparateur décimal dans l'expression de format, arrondit le nombre à autant de positions décimales qu'il y a de zéros. Si le nombre contient davantage de chiffres à gauche du séparateur décimal qu'il n'y a de zéros à gauche du séparateur décimal dans l'expression de format, affiche les chiffres supplémentaires sans modification.

# indique un espace réservé de chiffre.

Chaque '#' est réservé à un chiffre. Affiche un chiffre ou rien. Affiche un chiffre si l'expression a un chiffre dans la position où le caractère # apparait dans la chaine de format ; sinon, n'affiche rien dans cette position.

Ce symbole fonctionne comme l'espace réservé au 0, sauf que les zéros non significatifs et à droite ne s'affichent pas si le nombre contient moins de chiffres qu'il n'y a de caractères # de part et d'autre du séparateur décimal dans l'expression de format.

. (point) indique l'emplacement du séparateur décimal (celui affiché sera celui du pays )

Vous devriez donc utiliser le point comme espace réservé à la décimale, même si vos paramètres régionaux utilisent la virgule à cette fin. La chaine mise en forme apparaitra dans le format correct pour les paramètres régionaux.

, (virgule) indique l'emplacement du séparateur de millier.

Séparateur de milliers. Il sépare les milliers des centaines dans un nombre de quatre chiffres ou plus à gauche du séparateur décimal.

"Littéral" la chaine sera affichée telle quelle.

% affichera en pour cent.

Multiplie l'expression par 100. Le caractère du pourcentage (%) est inséré

E0 affiche en notation scientifique.

: et / sont séparateur d'heure et de date.

; est le séparateur de section : on peut donner 3 formats (un pour les positifs, un pour les négatifs, un pour zéro) séparés par ;

Exemples

Chaine de format '0000', avec le nombre 145 cela affiche '0145'

Chaine de format '####', avec le nombre 145 cela affiche '145'

Chaine de format '000.00', avec le nombre 45.2 cela affiche '045.20'

Chaine de format '#,#', avec le nombre 12345678 cela affiche '12,345,678'

Chaine de format '#,,' avec le nombre 12345678 cela affiche '12'

La chaine de formatage' #,##0.00 ' veut dire obligatoirement 2 chiffres après le séparateur décimal et un avant.

Si on affiche avec ce format :

1.1 cela donne 1,10

.5 cela donne 0,50

4563 cela donne 4 563,00

Exemple :

 
Sélectionnez
Dim N As Double = 19.95

Dim MyString As String = N.ToString("$#,##0.00;($#,##0.00);Zero")

' En page  U.S. English culture, MyString ="$19.95".
' En page  Française , MyString ="19,95€".

Exemple 2 :

 
Sélectionnez
Dim UnEntier As Integer = 42
MyString = UnEntier.ToString( "Mon nombre " + ControlChars.Lf + "= #" )

Affiche :
Mon nombre
= 42

Pour mémoire on a aussi d'autres manières de transformer un numérique en String :

 
Sélectionnez
Dim num As Integer = CType( chaine, String)

V-AE-2-b. Str() de Microsoft.VisualBasic est toujours accepté

Il permet de transformer une variable numérique et String, qui peut ensuite être affichée.

 
Sélectionnez
MyString=Str( LeNombre)
Label1.Text=MyString

Pas de formatage et le séparateur décimal est le point…

V-AE-2-c. String.Format du Framework

Permet de combiner des informations littérales à afficher sans modification et des zones formatées.

Les arguments de String.Format se décomposent en 2 parties séparées d'une virgule.

  • Chaine de formatage entre guillemets: Exemple "{0} + {1} = {2}" : les numéros indiquent l'ordre des valeurs.
  • Valeurs à afficher dans l'ordre, la première étant d'indice zéro. Exemple= A, B, A+B

Exemple :

 
Sélectionnez
Si A=3 et B=5
MsgBox(String.Format("{0} + {1} = {2}",A, B, A+B)) affiche  3+5=8

Autre exemple :

 
Sélectionnez
Dim MonNom As String = "Phil"
String.Format("Nom = {0}, heure = {hh}", MonNom, DateTime.Now)

Le texte fixe est "Nom =" et ", heure =", les éléments de format sont "{0}" et "{hh}" et la liste de valeurs est MonNom et DateTime.Now.

Cela affiche: Nom = Phil Heure= 10

Là aussi on peut utiliser les formats

  • Prédéfinis : ils utilisent là aussi les paramètres régionaux. Ils utilisent C, D, E, F,G,N,P,R,X comme ToString.

     
    Sélectionnez
       MsgBox(String.Format("{0:C}",-456.45))    Affiche -456,45MsgBox(String.Format("{0:D8}", 456))    Affiche 00000456    Décimal 8 chiffres
    
       MsgBox(String.Format("{0:P}", 0.14))    Affiche   14%    Pour cent
    
       MsgBox(String.Format("{0:X}", 65535))    Affiche  FFFF    Hexadécimal
  • Personnalisés : avec des # et des 0 :
 
Sélectionnez
    MsgBox(String.Format("{0:##,##0.00}", 6553.23))

La fonction Format de Microsoft.VisualBasic (pas la classe String.Format) fournit des fonctions similaires, mais les arguments sont dans l'ordre inverse (valeur, chaine de formatage) et il n'y a pas de numéro d'ordre et de{} !! C'est pratique pour afficher une seule valeur, mais c'est quand même à éviter.

 
Sélectionnez
MyStr = Format(5459.4, "##,##0.00") ' Returns "5,459.40".
MyStr = Format(334.9, "###0.00") ' Returns "334.90".
MyStr = Format(5, "0.00%") ' Returns "500.00%"

V-AE-3. CultureInfo

Image non disponible

On se rend compte que l'affichage est dépendant de la CurrentCulture du Thread en cours.

Exemple

Si la CurrentCulture est la 'CultureInfo Us' et que j'affiche avec le format 'C' (monétaire) cela affiche un $ avant, si je suis en 'CurrentCulture Français' cela affiche un € après.

Par défaut la CultureInfo est celle définie dans Windows, probablement 'fr-FR' sur votre ordinateur.
fr signifie français et FR signifie 'région France'; il existe fr-CH (Suisse), fr-BE (Belgique).
Dans en-US, en signifie anglais et US signifie USA.

On peut modifier la CurrentCulture par code (voir exemple plus haut).

 
Sélectionnez
Imports System.Threading

Thread.CurrentThread.CurrentCulture = New Globalization.CultureInfo("en-us")'passage en culture US culture

On peut utiliser l'objet My.

 
Sélectionnez
MsgBox(My.Application.Culture.ToString) 'affiche 'fr-FR'

(My.Application.ChangeCulture 'permettra de changer la culture )

On peut aussi modifier le cultureInfo uniquement sur une instruction ToString ou Format :

 
Sélectionnez
Dim d As Double=12.35
Dim s As String= d.ToString( New CultureInfo("en-US")

En français par défaut :

le séparateur de décimal numérique est le '.'

Exemple : 1.20

Le séparateur décimal monétaire est la ','

Exemple : 1,20€

V-AF. Méthode d'extension, Lambda expression

Ce sont des nouveautés de VB 2008, débutant passe ton chemin.

Méthodes d'extension

Permet d'ajouter des fonctionnalités à un Type (sans devoir faire une Classe dérivée).

Exemple

Soit le Type 'String', je veux y ajouter une méthode Print qui affichera la String sur la console :

 
Sélectionnez
Imports System.Runtime.CompilerServices

Module StringExtensions

    <Extension()> _
    Public Sub Print(ByVal aString As String)
        Console.WriteLine(aString)
    End Sub

End Module

C'est le "ByVal aString As String" qui indique que c'est une extension sur les 'String'.

Comment utiliser la méthode Print ?

 
Sélectionnez
Imports ConsoleApplication2.StringExtensions

Module Module1

    Sub Main()

        Dim exemple As String = "Bonjour"
        ' Appel de  l'extension method Print.
        exemple.Print()

        ' Appel de la méthode d'instance  'ToUpper'.
        exemple.ToUpper()
        exemple.ToUpper.Print()

    End Sub

End Module

Si on veut ajouter un paramètre à la méthode Print, il faut l'ajouter au premier paramètre qui lui indique le DataType.

 
Sélectionnez
<Extension()> _
Public Sub PrintPonctuation(ByVal aString As String,  ByVal punc As String)
    Console.WriteLine(aString & punc)
End Sub

Ensuite pour l'utiliser :

 
Sélectionnez
Dim exemple As String = "Exemple" 
exemple.PrintPonctuation(".")

Lambda Expression

Une expression lambda est une fonction permettant de calculer et retourner une valeur unique. Exemple: Créons une expression lambda qui incrémente un Integer. Création de la fonction :

 
Sélectionnez
Dim ajoute1 = Function(num As Integer) num + 1

Utilisation de la fonction dans la même sub :

 
Sélectionnez
Console.WriteLine(ajoute1(5))   Affiche 6.

On dit que la fonction lambda 'ajoute1( num As Integer)' conduit à num+1.

On peut déclarer et utiliser la fonction en même temps :

 
Sélectionnez
Console.WriteLine((Function(num As Integer) num + 1)(5))

Dans ce cas il n'y a pas de nom de fonction.

Attention

On n'a pas de 'End Function'(dans les expressions lambda à une ligne) ni de 'Return' ni de 'As', on ne peut pas utiliser les génériques.

Si on veut déclarer l'expression lambda dans la tête du module afin d'avoir un accès public, c'est plus complexe :

 
Sélectionnez
Class Window1

Delegate Function ajoute(ByVal num As Integer) As Integer

Public ajoute1 As ajoute = Function(num) num + 1

 

Private Sub Button_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) _
 Handles Button.Click

    MsgBox(ajoute1(3).ToString)

End Sub

 
End Class

Voyons comment on peut passer à une Sub une fonction lambda en argument. On crée une fonction 'testResult' qui a pour argument une valeur et une fonction lambda. Cette fonction affiche "Success" ou "Failure" en fonction de la valeur True ou False retournée par la fonction lambda qui a reçu la valeur. Pour utiliser cette sub on l'appelle avec comme argument la valeur à tester et la fonction Lambda.

 
Sélectionnez
Module Module1
 Sub Main() 
'On appelle une fonction en envoyant une valeur et une fonction lambda.
' La ligne affiche "Success", car 4 est pair. 
testResult(4, Function(num) num Mod 2 = 0) 
' La ligne affiche "Failure", car 5 n'est pas > 10.
testResult(5, Function(num) num > 10)
 End Sub 
 
' Sub testResult a 2 arguments, 'value' un Integer  et 'fun' la fonction lambda 
' On teste la fonction lambda 'fun(value)' 
' en fonction du résultat True ou False on affiche "Success" ou "Failure"
Sub testResult(ByVal value As Integer, ByVal fun As Func(Of Integer, Boolean)) 
If fun(value) Then
 Console.WriteLine("Success") 
Else
 Console.WriteLine("Failure") 
End If 
End Sub 
End Module

En vb 2010 on peut créer une expression lambda sur plusieurs lignes, on ajoute dans ce cas un 'End Function'.

 
Sélectionnez
Dim paireoupas = Function(x)
                     If (x Mod 2=0) Then
                      Return "paire"
                     Else
                      Return "Impair"
                    End If
                 End Function

' Affiche 2.
Console.WriteLine(paireoupas(1))

En plus, on peut créer une Sub lambda.

V-AG. L'espace de noms 'My'

Ce chapitre est placé ici, car il ne concerne pas l'interface, mais il sera plutôt lu dans un second temps.

Cet espace de noms comporte des objets qui sont des chemins d'accès simplifiés à de nombreux domaines touchant l'application, l'ordinateur, les ressources, les imprimantes…

My qui est extrêmement pratique est présent à partir de VB 2005 et uniquement dans VB (pas dans C#).

My : le SUPER RACCOURCI.

V-AG-1. My.Application

My.Application permet d'accéder rapidement aux propriétés de l'application en cours.

Vous pouvez ainsi récupérer des informations sur l'assembly, la culture (langue), de l'application.

Vous pouvez aussi avec My.Apllication.Info récupérer des informations sur le répertoire de travail le titre le copyrhigt de l'application.

 
Sélectionnez
'Culture
MsgBox(My.Application.Culture.ToString) ' culture du thread en cours affiche 'fr-FR'
My.Application.ChangeCulture (it-IT) 'permettra de changer la culture 

'Formulaire
'My.Application.OpenForms qui retourne la collection des formulaires ouverts.
'Exemple: rajouter le texte 'ouvert' à la barre  des formulaires ouverts:
For Each F As System.Windows.Forms.Form In My.Application.OpenForms
F.Text += "[ouvert]"
Next

'modifier la durée de l'affichage de l'écran Splash
My.Application.MinimumSplashScreenDisplayTime = 2000 '<= À rajouter dans Application_New
'voir chapitre sur écran Splash

'Afficher dans une liste Box les arguments de la ligne de commande
ListBox1.DataSource = My.Application.CommandLineArgs.ToArray

'Afficher les infos de l'application
MsgBox(My.Application.Info.DirectoryPath) 'affiche le nom du répertoire ou est l'exécutable.
MsgBox(My.Application.Info.Title) 'affiche le titre de l'application, de l'exécutable.
MsgBox(My.Application.Info.Version.ToString) 'affiche le nom du répertoire ou est l'exécutable.
MsgBox(My.Application.Info.ProductName) 'affiche le nom de produit de l'application.

V-AG-2. My.Computer

My.Computer
permet d'accéder aux propriétés de l'ordinateur, du hardware.
Aux ressources logicielles et/ou matérielles de l'ordinateur.

My.Computer.Audio : permet de jouer des fichiers wav, ainsi que les sons systèmes de Windows.

 
Sélectionnez
My.Computer.Audio.Play("c:\mysound.wav")
My.Computer.Audio.Play("c:\mysound.wav", AudioPlayMode.BackgroundLoop) 'joue en boucle
My.Computer.Audio.Stop  'stop la boucle

My.Computer.Clipboard : permet de récupérer des informations sur le contenu du presse-papier, de récupérer et de définir son contenu.

 
Sélectionnez
If My.Computer.Clipboard.ContainsImage Then
    PictureBox1.Image = My.Computer.Clipboard.GetImage
ElseIf My.Computer.Clipboard.ContainsText Then
    TextBox1.Text = My.Computer.Clipboard.GetText
End If

My.Computer.Clock : permet de récupérer l'heure courante ainsi que le nombre de millisecondes écoulées depuis le démarrage.

 
Sélectionnez
MsgBox(My.Computer.Clock.LocalTime.ToString) 'Affiche date et heure

My.Computer.FileSystem: permet de trouver des répertoires et d'effectuer les opérations d'entrées/sorties standards.

On peut ainsi lire le chemin des répertoires habituels :

 
Sélectionnez
    MsgBox(My.Computer.FileSystem.CurrentDirectory)  'répertoire courant
MsgBox(My.Computer.FileSystem.SpecialDirectories.MyDocuments) 'répertoire documents
MsgBox(My.Computer.FileSystem.SpecialDirectories.CurrentUserApplicationData)'rep données utilisateur en cours
MsgBox(My.Computer.FileSystem.SpecialDirectories.AllUsersApplicationData)'rep données utilisateur en cours
MsgBox(My.Computer.FileSystem.SpecialDirectories.Programs) 'répertoire des programmes

Il y a aussi Destock, MyMusic, MyPictures, ProgramsFiles.

Récupérer le nom du premier disque :

 
Sélectionnez
MsgBox(My.Computer.FileSystem.Drives.Item(0).ToString)'affiche 'A:'

La collection Drives contient des items indiquant les disques.
GetDrives et GetDriveInfo permettent de récupérer une collection de disques présents, et des informations sur les disques.

Un répertoire existe-t-il ?

 
Sélectionnez
MsgBox(My.Computer.FileSystem.DirectoryExists("c:\").ToString) 'affiche True si c:\ existe.

De même pour un fichier :

 
Sélectionnez
MsgBox(My.Computer.FileSystem.FileExists("c:\myfiel.txt").ToString) 'affiche True si c:\myfile.txt existe.

Possibilité de copier, créer, effacer, déplacer répertoires ou fichiers

Il y a :
CopyDirectory
DeleteDirectory
RenameDirectory
MoveDirectory
CreateDirectory
et
CopyFile
DeleteFile
RenameFile
MoveFile

Exemple : copie d'un répertoire :

 
Sélectionnez
My.Computer.FileSystem.CopyDirectory(sourcedirectory, destinationdirectory)

On peut ajouter 2 paramètres, pour afficher une boite de dialogue qui indique la progression de la copie et pour générer une interruption si l'utilisateur annule le processus (il faut dans ce cas que le code soit dans un Try Catch).

Voir les sous-répertoires :

 
Sélectionnez
My.Computeur.FileSystem.GetDirectories("c:\").item(0) 'permet de voir le premier sous répertoire.

Afficher dans ListBox1 tous les répertoires qui sont dans C :

 
Sélectionnez
ListBox1.DataSource = My.Computer.FileSystem.GetDirectories("c:\")

GetFiles fait de même avec les fichiers et GetDrives pour les disques.

Mettre le contenu d'un fichier texte dans une variable :

 
Sélectionnez
Dim LeTexte As String = My.Computer.FileSystem.ReadAllText("c:\devicetable.log")

(Il existe aussi WriteAllText, ReadAllBytes et WriteAllBytes)

FindInFiles permet de retrouver les fichiers contenant un texte.

 
Sélectionnez
Dim list As System.Collections.ObjectModel.ReadOnlyCollection(Of String)
liste = My.Computer.FileSystem.FindInFiles("C/", "Chaine à chercher", True, FileIO.SearchOption.SearchAllSubDirectories)

My.Computer.Info : Obtient des informations concernant l'ordinateur et le système d'exploitation (mémoire vive libre, nom de l'os, version de l'os, etc.).

 
Sélectionnez
MsgBox(My.Computer.Info.TotalPhysicalMemory.ToString) 'affiche la mémoire physique

Il y a aussi AvailablePhysicalMemory, TotalPhysicalMemory, TotalVirtualMemory OSVersion, OSFullName…

My.Computer.Keyboard : permet de tester l'état des touches CTRL, ALT, etc., et de simuler l'appui de touches grâce à la méthode Sendkeys.

 
Sélectionnez
MsgBox(My.Computer.Keyboard.AltKeyDown.ToString)' teste si la touche Alt est enfoncée.

My.Computer.Keyboard.SendKeys("a")' simule l'appui d'une touche.

My.Computer.Mouse : permet de récupérer des informations sur la souris (présence de la souris, présence de molette, boutons inversés, etc.)

 
Sélectionnez
MsgBox(My.Computer.Mouse.WheelExists.ToString) 'affiche True s'il y a une molette.

My.Computer.Name : récupère le nom de l'ordinateur.

 
Sélectionnez
MsgBox(My.Computer.Name.ToString)

My.Computer.Network : permet de télécharger et d'uploader des fichiers, de vérifier si l'ordinateur est connecté à Internet, d'effectuer des pings, et de récupérer les événements lors des connexions et déconnexions.

Charger un fichier à partir du réseau :

My.Computer.Network.DownloadFile(AdresseCompleteFichierACharger, DestinationFileNane)

 
Sélectionnez
With My.Computer.Network
    If .IsAvailable And .Ping(txtIpAdress.text) Then
        .UploadFile("c:\filetupload.ext", txtIpAdress.Text)
    End If
End With

My.Computer.Ports : permet de récupérer la liste des ports séries, et de les ouvrir.

My.Computer.Printers : permet de récupérer la liste des imprimantes installées et de définir l'imprimante par défaut. (absent dans la version bêta)

My.Computer.Registry : permet de manipuler la base de registre facilement.

My.Computer.Screen : permet de récupérer les informations concernant les écrans installés.

 
Sélectionnez
    MsgBox (My.Computer.Screen.Bounds.Height.ToString) 'voir la hauteur de l'écran

V-AG-3. My.User

My.User permet de récupérer les informations sur l'utilisateur courant.

My.User.Identity.Name

My.User.IsInRole("Administrators") 'contient l'administrateur

V-AG-4. My.Ressources

My.Ressources permet de manipuler et récupérer très facilement les ressources incorporées à l'assembly.

Mettre une ressource image dans le plan BackGround d'un formulaire :

 
Sélectionnez
Me.BackgroundImage = My.Resources.Form1Background

Mettre une ressource image dans le plan BackGround d'un bouton :

 
Sélectionnez
MyButton.BackGroundImage= MonProgramme.My.Ressources.Ressources.button_Blue

Mettre une ressource icône comme icône d'un formulaire :

 
Sélectionnez
Me.Icon = My.Resources.MyIcon

Jouer un son qui est dans les ressources :

 
Sélectionnez
My.Computer.Audio.Play(My.Resources.Form1Greeting, AudioPlayMode.Background)

V-AG-5. My.Setting

My.Setting :fichiers de configuration.

En VB2005 vous pouvez créer des paramètres de type Color, Font, Point, Size :

 
Sélectionnez
My.Settings.MyFont= New Font (Me.Font, FontStyle.Italics)

Ce paramètre sera enregistré automatiquement lors de la fermeture de l'application (voir chapitre sur la configuration).

Quand vous exécuterez ensuite le programme, vous pourrez récupérer le paramètre :

 
Sélectionnez
TextBox1.Font= My.Settings.MyFont

V-AG-6. My.Forms

My.Forms: Donne accès à tous les formulaires. Si un formulaire se nomme HelpForm, pour l'afficher :

 
Sélectionnez
My.Forms.HelpForm.Show()

On peut étendre et personnaliser l'espace de noms My, mais c'est un peu complexe.

V-AH. Son, musique, batteries

Le plus simple : faire entendre un bip :

 
Sélectionnez
Beep()

Pour faire entendre un fichier wav, on utilise un SoundPlayer.

 
Sélectionnez
'On instancie un nouveau SoundPlayer, on utilise un son système ici
Dim MySoundPlayer = New System.Media.SoundPlayer("C:\Windows\Media\chord.wav")

'On joue le son:
MySoundPlayer.Play()

La méthode Play joue le son de manière asynchrone (avec un autre Thread): le code se poursuit même pendant l'émission d'un son long. PlaySync joue le son de manière synchrone.

On peut écouter le son en boucle avec PlayLoop dans ce cas il faut l'arrêter avec Stop.

 
Sélectionnez
Public Class Form1
    Public MySoundPlayer As System.Media.SoundPlayer = New System.Media.SoundPlayer("C:\Windows\Media\chord.wav")
    
    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click


        MySoundPlayer.PlayLooping()
        
    End Sub

    Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
   
        MySoundPlayer.Stop()

    End Sub
End Class

On peut indiquer où se trouve le fichier son avec SoundLocation (chemin ou Url Internet), le charger avec Load()(synchrone avec le même thread) ou LoadAsync (Asynchrone avec un autre thread) puis le jouer avec Play().

Les sons system (Asterisk, Beep, Exclamation, Hand et Question) peuvent être joués encore plus simplement avec SystemSounds :

 
Sélectionnez
  System.Media.SystemSounds.Asterisk.Play()

Information sur les batteries d'un portable :

 
Sélectionnez
Dim BatteryLife As Integer 'contient la durée de vie restante de la batterie en %
Dim BatteryLifeRestant As Integer 'contient la durée de vie restante de la batterie en sec

BatteryLife = SystemInformation.PowerStatus.BatteryLifePercent * 100 'récupérations du pourcentage, 255 si inconnue
BatteryLifeRestant = SystemInformation.PowerStatus.BatteryLifeRemaining 'récupération de la durée en sec,-1 si inconnue

'si le secteur est branché alors 'LifeRemaining' = -1
'si batterie seule alors 'LifeRemaining' = x secondes

'mais problème parfois, car la valeur de 'PowerLineStatus' est rafraîchie plus souvent par le framework que la valeur de 'LifeRemaining'

Vous avez aimé ce tutoriel ? Alors partagez-le en cliquant sur les boutons suivants : Viadeo Twitter Facebook Share on Google+   

  

Les sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright © 2020 Philippe Lasserre . Aucune reproduction, même partielle, ne peut être faite de ce site ni de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.