VBA2DotNet
1 Excel, VBA, VB.Net
Excel, produit de la suite Microsoft Office, est le plus célèbre des tableurs. Au cours de son histoire, il s'est vu doté de possibilités de plus en plus étendues, notamment par le support du langage VBA (Visual Basic for Applications). Ce langage interprété permet de développer rapidement de véritables logiciels, écrivants des fichiers, accédants aux bases de données... embarqués dans un simple classeur.
La puissance de cette possibilité a plusieurs revers :
- Les applications Excel-VBA peuvent contenir des virus. Excel affiche donc un message d'alerte à chaque ouverture de classeur contenant du code VBA (sauf si le classeur est signé).
- La facilité du développement, accessible même aux non-informaticiens, peut conduire à la mise en place de solutions informatiques stratégiques pour l'entreprise, en dehors des process de développement maitrisés et sécurisés.
Face à ces problèmes, Microsoft a annoncé qu'il renonçait au langage VBA, bien que les versions actuelles d'Excel permettent toujours d'éxécuter et d'assurer la maintenance des applications Excel-VBA.
En parallèle, l'architecture .Net proposée par Microsoft permet de continuer à développer des applications utilisant les fonctionnalités d'Excel (ou d'autres produits de la suite Office), via la bibliothèque d'interopérabilité (Interop).
.Net supporte plusieurs langages : VB, C#, J#... mais il est relaté que les possibilités d'utilisation d'Interop sont les plus complètes vers Excel depuis le langage VB.Net. De plus, la syntaxe de VB.Net est la plus proche de celle du VBA. Il est donc naturel de privilégier la migration de VBA vers VB.Net.
2 Migration de VBA vers VB.Net
Pour lancer une application Excel-VBA, on ouvre un classeur Excel, dans lequel du code VBA est embarqué. Typiquement, le code est exécuté lors d'une action de l'utilisateur (ex: cliquer sur un bouton) ou à l'ouverture du classeur. La plupart des applications évoluées ont un point d'entrée qui ouvre une fenêtre de saisie (userform).
Voici un principe de fonctionnement possible de l'application migrée en VB.Net Interop-Excel : Le point d'entrée de l'application sera un exécutable (.exe), dont le lancement ouvrira la fenêtre de saisie principale, démarrera une instance d'Excel et y chargera le classeur d'origine privé de son code VBA.
Il est indispensable de réfléchir vous-même à la façon dont votre application migrée en VB.Net utilisera Excel. VBA2DotNet vous aidera à traduire le code et importer les formulaires utilisateurs dans votre nouvel outil de développement (Visual Studio / Visual Studio Express).
3 Utilisation de VBA2DotNet
VBA2DotNet travaille à partir des modules, modules de classe et userform exportés de votre classeur Excel-VBA.
Il se charge d'automatiser de nombreuses modifications du code, quelles soient liées à l'évolution de la syntaxe du langage, aux l'accès à la bibliothèque Interop, aux différences de gestion des userforms entre Excel et .Net...
De plus, VBA2DotNet créée le code "Designer.vb" générant les userforms (principales caractéristiques des principaux contrôles) ce qui permet de ne pas avoir à recréer manuellement les userforms.
Le code traité par VBA2DotNet doit ensuite être importé dans un outil de développement Microsoft (Visual Studio ou VB Express) corrigé et adapté manuellement.
Voici les différentes étapes nécessaires à la migration de votre application à l'aide de VBA2DotNet :
1 Créez 1 répertoire d'entrée qui contiendra les objets exportés de votre application et 1 répertoire de sortie qui contiendra les objets générés par VBA2DotNet.
2 Exportez tous les modules, modules de classe et userforms de votre projet VBA dans le répertoire d'entrée. Pour ce faire :
- Chargez votre application dans Excel.
- Depuis l'éditeur VBA d'Excel, faite un clic-droit sur chaque objet contenant du code VBA,
- Puis sélectionner "Exporter un fichier..." (voir ci-contre).
- Vous pouvez ensuite refermer votre application.
3 Depuis Excel, ouvrez le classeur VBA2DotNet, effectuez le paramétrage nécessaire (voir le chapitre 3.1) et lancez le traitement qui peut durer quelques minutes, selon la taille des fichiers à traiter.
4 Si le classeur Excel de votre application d'origine contenait une ou des feuilles de travail qui seront toujours nécessaires à l'application migrée, créez un nouveau classeur contenant seulement ces feuilles.
5 Dans votre plateforme de développement .Net (par exemple Visual Basic Express), créez une nouvelle application, importez les objets générés contenus dans le répertoire de sortie de VBA2DotNet.
6 Corrigez les éventuelles erreurs de compilation, complétez et adaptez le code (notamment, ajouter les instruction d'ouverture du nouveau classeur sans VBA).
En cas de problème (la compilation échoue, l'éxécution plante, le fonctionnement n'est pas conforme à l'application d'origine, la migration ne respecte pas les règles décrites), la première action à réaliser est de vérifier que les recommandations de VBA2DotNet (voir chapitre 3.5) sont respectées. Après ces vérifications, vous pouvez contacter ToolOscope pour demande de support ou d'évolution.
4 L'application VBA2DotNet
4.1 La feuille Projet
Cette feuille constitue l'interface de commande de VBA2DotNet. Les cellules à renseigner par l'utilisateur sont sur fond jaune (numérotées de 2 à 10 en rouge). Chacune de ces cellules possède un commentaire qui décrit le contenu attendu. Ces commentaires sont repris dans l'encadré ci-contre.
Lorsque toutes les données en entrée sont saisies, l'utilisateur clique sur le bouton "Lancer VBA2DotNet" pour éxécuter le traitement, qui se déroule en 2 passes.
A chaque passe, VBA2DotNet lit successivement tous les modules en entrée (8) qui doivent être présents dans le dossier en entrée (6). Lors de la seconde passe, les modules migrés sont écrits dans le dossier de sortie (7). L'utilisateur peut suivre l'avancement du traitement par les nombres de lignes lues et écrites qui s'affichent sur la feuille.
Le nom des modules .bas et des classes .cls est conservé après la migration, mais l'extension devient .vb (.Designer.vb pour le code des userform).
Vous pouvez dupliquer cette feuille dans le classeur VBA2DotNet, par exemple pour conserver 1 feuille de commande pour chacun de vos projet.
Commentaires des cellules
1 Cette feuille peut être dupliquée dans ce même classeur autant de fois que vous avez de projets VBA différents à traiter.
2 Renseigner le nom de la feuille qui contient les mots réservés.
Facultatif. Si renseigné, la feuille doit exister dans le même classeur.
3 nom de la feuille qui contient les règles de migration à appliquer.
Obligatoire.
4 Renseigner le nom de la feuille où sera écrit le code et les types détectés des variables (65530 lignes maximum).
Facultatif. Si à blanc, le code ne sera pas sorti.
Si renseigné, la feuille doit exister dans le même classeur.
5 Renseigner le nom de la feuille où sera écrite la table des identificateurs rencontrés.
Facultatif. Si à blanc, la table ne sera pas sortie.
Si renseigné, la feuille doit exister dans le même classeur.
6 Renseigner le chemin du dossier qui contient les fichiers VBA à traiter, préalablement exportés d'Excel.
Obligatoire.
7 Renseigner le chemin du dossier qui contiendra les fichiers VBA migrés. Ces fichiers devront être importés manuellement dans une nouvelle solution VB.Net pour recomposer votre application.
Obligatoire.
8 Renseigner dans cette colonne les noms des fichiers VBA exportés de votre application Excel, sans extension. Ces fichiers doivent se trouver dans le dossier "Entrée".
64 fichiers maximum + limitation mémoire des projets Excel-VBA.
9 Renseigner l'extension du nom de chaque fichier VBA situé dans la cellule à gauche :
- cls pour les ModuleClass,
- bas pour les Modules,
- frm pour les UserForms.
10 Renseigner O pour afficher en commentaire sur chaque ligne migrée le nom des règles appliquées.
Renseigner N dans le cas contraire.
4.2 Les mots réservés
Cette feuille contient les mot-clés réservés du langage VBA. Elle peut être enrichie en cas de lacune.
VBA2DotNet analyse chaque mot rencontré dans le code à traiter afin de déterminer les règles de migrations à appliquer.
Certaines règles (Voir au chapitre 4) ne s'appliquent qu'aux mots réservés déclarés dans cette feuille.
4.3 La table des identificateurs
Lors du traitement, VBA2DotNet extrait tous les identificateurs déclarés dans votre projet. Si son nom est défini sur la feuille Projet, cette feuille restitue, en fonction de leur portée (projet, module ou locale), les identificateurs, leur type et éventuellement leur conteneur pour les membres d'une classe ou d'un type déclaré par l'utilisateur.
4.4 La feuille du code lu
VBA2DotNet écrit sur cette feuille (si son nom est défini sur la feuille Projet) le code lu et analysé : séparation en identificateurs et autres caractères. Sous chaque identificateur, il indique sur 2 lignes la nature qu'il a détecté : libellé, mot-clé réservé, variable, fonction... et le type du conteneur.
Ces informations peuvent être utiles pour comprendre quelles règles sont appliquées.
4.5 La feuille d'aide
Cette feuille contient la liste des règles (voir chapitre 4.2), les recommandations concernant le code à traiter... :
- Toutes les variables doivent être déclarées (option explicit recommandée) et typées (pas de variant par défaut).
- Les évènements sur contrôles doivent être déclarés Private.
- Les contructeurs et destructeurs de classe doivent être déclarés Private.
- Le constructeur doit être écrit "Class_Initialize" (attention aux majuscules !).
- Le destructeur doit être écrit "Class_Terminate" (attention aux majuscules !).
- Les identificateurs doivent être écrits précisément de la même manière (majuscules, accents...).
- Eviter de faire porter le même nom à une fonction (ou sub) et à un type.
- Eviter d'utiliser des caractères accentués ou spéciaux dans les identificateurs.
- Les Get, Set ou Let d'une même property doivent être groupés dans le code.
- Initialisez les valeurs des tableaux !
...Et les recommandations après le traitement du code :
- Vérifier l'application des règles notées "A contrôler" ou "A compléter" ci-dessous.
- Si à l'ouverture dans Visual Studio un formulaire ne s'affiche pas (c'est son code Designer.vb qui s'affiche à la place), vérifier dans le code .vb la déclaration des évènements.
- Une fois les corrections effectuées, sauver et fermer le projet, puis rouvrez-le.
4.6 Les paramètres des règles de migration
L'ensemble des règles de migration est décrit au chapitre 4. Parmi celles-ci, les règles ci-dessous ont besoin de paramètres : Ils sont définis sur la feuille "Rules".
- DefAttrb : Si l'objet de type Input1 n'a pas d'attribut, l'attribut par défaut Output1 est ajouté.
- ReplAttrb : Pour les objet de type Input1, l'attribut Input2 est remplacé par Output1.
- Preffx : Si l'identificateur Input1 ne qualifie aucun objet, il est préfixé par Output1.
- Call : Si l'identificateur Input1 n'est pas précédé de l'instruction Call, celle-ci est ajoutée.
- ReplEvent : L'évènement Input2 d'un contrôle (Input1 toujours égal à "Control") est remplacé par Output1.
- ReplReserv : Le mot réservé Input1 est remplacé par Output1.
- ReplIdent : Si l'indentificateur Input1 ne qualifie aucun objet, il est remplacé par Output1.
- ReplLibel : Le libellé Input1 est remplacé par Output1.
Les valeurs de ces paramètres sont définis sur la feuille "Rules" :
Aux premières lignes des colonnes J et K, la feuille "Rules" rappelle pour mémoire la correspondance des noms des contrôles entre VBA et VB.Net utilisée lors de la génération du code des userforms.
5 Règles de migration
5.1 Déclarations complémentaires
Dans le 1er module .bas déclaré dans la feuille Projet, VBA2DotNet ajoute les déclarations des variables publiques suivantes :
- MYEXCELAPP : Application Excel qui va contenir le classeur migré.
- MYTOOLTIP : Objet ToolTip qui va gérer les bulles d'aides sur les différents contrôles des formulaires.
- _OPTIONALDEFAULT_ : Constante de type String qui sera utilisée en valeur par défaut dans les déclaration de paramètres optionnels.
D'autre part, dans sa communication avec Excel, l'application migrée est confrontée à la problématique suivante : Dans VBA, on peut tester la valeur d'une cellule, même si cette cellule n'existe pas ou si sa valeur n'existe pas (au sens objet). En .Net, ce n'est pas autorisé.
Pour réaliser ces tests sans impacter lourdement le code migré, VBA2DotNet propose de passer par des fonctions qui renverront une chaine vide ou zéro dans les cas ci-dessus. Ces fonctions publiques sont déclarées dans le 1er module .bas :
- CellToString : Retourne le contenu de la cellule s'il existe, sinon "".
- CellToDouble : Retourne le contenu de la cellule s'il existe, sinon le flottant 0.
- CellToInt Retourne le contenu de la cellule s'il existe, sinon l'entier 0.
Si votre application ne comprend aucun module .bas, vous devrez en ajouter un vide pour bénéficier de ces déclarations.
5.2 Tableau des règles de migration
VBA2DotNet applique les règles suivantes. Le nom des règles appliquées est visible en commentaire de chaque ligne migrée si l'option 10 de la feuille de projet est "O" :
Règle | Explications | Remarque |
#ReplReserv | Remplacement d'un mot réservé de la feuille "reserv" | |
#ByRef | Si ByRef ou ByVal absent, ajout de ByRef devant les paramètres d'appels de Sub ou Function | |
#To | Gestion des déclarations de tableaux dimensionnés "m To n" | |
#Set | Gestion du mot-clé Set dans les déclarations de Property ou affectation de pointeurs | |
#Get | Gestion de la déclaration de Property Get | |
#Let | Gestion de la déclaration de Property Let | |
#Option | Suppression des options obsolètes (Explicit et Base) | |
#ByVal | Suppression du ByVal dans les appels de Sub ou Function | |
#Open | Ouverture de fichier | |
#Close | Fermeture de fichier | |
#Line | Lecture de fichier | |
#Print | Ecriture dans un fichier | |
#DeclString | Déclaration de variables de type String : affectation par défaut à "", sauf pour les tableaux et pour les variables de classe/module | |
#Array | Déclaration de tableau en ligne avec Array() : remplacement par {} | |
#Nothing | Test de pointeur Is Nothing remplacé par IsNothing(...) | |
#Optional | Déclaration de paramètres optionnels (hypothèse : ce sont des strings -ou variants migrés en strings) : initialisés à _OPTIONALDEFAULT_ | A contrôler |
#IsMissing | Test de présence des paramètres optionnels : remplacement de IsMissing(...) par la comparaison avec la valeur par défaut | A contrôler |
#Rem | Remplacement de Rem par REM (nom de la règle non affiché en commentaire) | |
#Property | Déclaration d'une Property ou fin d'une Property | |
#StructItem | Déclaration de membre d'une structure : ajout de Dim devant | |
#DeclStruct | Déclaration de variables de type utilisateur, "As" remplacé par "= New" | |
#Call | Appel de Sub sans Call et sans parenthèses interdit en .net + Sub déclarés sur la feuille Rules | |
#Enum | Item d'une enumération : ajout du nom de l'enum devant si absent | |
#ReplEvent | Déclaration d'un évènement : Codes évènements à remplacer (voir feuille Rules) | |
#Handles | Déclaration d'un évènement : Nouvelle syntaxe | |
#CellValue | Gestion de Cell(*,*).Value : appels des fonctions CellToString ou CellToDouble (à remplacer manuellement par CellToInt si besoin) | A contrôler |
#WarnValue | Un cas non géré d'utilisation de Cell(*,*).Value a été identifié. | A contrôler |
#ReplAttrb | Remplacement du nom d'un attribut (voir feuille Rules) | |
#DefAttrb | Attribut par défaut si aucun présent (voir feuille Rules) | |
#ReplIdent | Remplacement d'un identificateur (voir feuille Rules) | |
#Preffx | Ajout d'un préfixe, sauf pour les membres (voir feuille Rules) | |
#ClassInit | Remplacement de Class_Initialize par New | |
#ClassTerm | Remplacement de Class_Terminate par Finalize | |
#Unload | Déchargement d'un userform : Unload -> Close() | |
#Show | Chargement d'un userform : Show -> Show ou ShowDialog | A contrôler |
#EOF | Test de fin de fichier EOF | |
#FreeFile | Allocation de numéro de fichier | A compléter |
#Control | Dans les userforms, controlParent.controlEnfant remplacé par controlEnfant | |
#UserForm | Remplacer le nom du userform par Me dans son module | |
#TipText | Gestion des ControlTipText (les tests ne sont pas gérés) | A contrôler |
6 Exemple : application testMigratDotNet
La petite application testMigratDotNet ne fait rien de sérieux et est écrite pour tester et montrer le fonctionnement de VBA2DotNet. Elle comporte 1 module de code, 1 module de classe et 1 userform, dont les versions originales et migrées sont présentées ci-dessous.
Les noms des règles appliquées apparaissent en commentaires de chaque ligne migrée, sous la forme ' #règle1#règle2...
Les modules originaux et migrés sont présentés ci-dessous. Les noms des règles appliquées apparaissent en commentaires de chaque ligne migrée, sous la forme ' #règle1#règle2...
6.1 Module de classe "MyClass.cls"
Code source
VERSION 1.0 CLASS
BEGIN
MultiUse = -1 'True
END
Attribute VB_Name = "MyTestClass"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = False
Attribute VB_PredeclaredId = False
Attribute VB_Exposed = False
Option Explicit
Public Enum myEnum
enum0
enum1
enum2
End Enum
Const MYCONST1 = "toto"
Const MYCONST2 = 3
Private mvar1 As String
Private mvar2 As Long
Public mvar3 As Boolean 'pour test de Me
Rem constructeur : son nom ne doit pas être obfuscaté
Private Sub Class_Initialize()
mvar1 = MYCONST1
mvar2 = MYCONST2
Me.mvar3 = False
DoEvents 'pourquoi ne pas le mettre ici ?
End Sub
Rem property : changement de la syntaxe
Rem le Get et Let/Set doivent être groupés dans le code
Rem le code migré doit être :
' Property var1( ) As String
' Get
' var1 = mvar1
' End Get
' Set(parm1 As String)
' mvar1 = Value
' End Set
' End Property
Friend Property Get var1() As String
var1 = mvar1
End Property
Friend Property Let var1(parm1 As String)
mvar1 = parm1
End Property
Friend Property Let var2(parm1 As Long)
mvar2 = parm1
End Property
Friend Property Get var2() As Long
var2 = mvar2
End Property
Rem destructeur : son nom ne doit pas être obfuscaté
Private Sub Class_Terminate()
Dim lEnum As myEnum
lEnum = myEnum.enum0 ' avec le nom de l'enum
MsgBox "Object of class MyTestClass destroyed !" & vbCr & "(error = " & Error & ")"
lEnum = enum1 ' sans le nom de l'enum
End Sub
Rem property Get sans Set
Friend Property Get var3() As Boolean
var3 = mvar3
End Property
Code migré
Public Class MyTestClass
' Option Explicit ' #Option
Public Enum myEnum
enum0
enum1
enum2
End Enum
Const MYCONST1 = "toto"
Const MYCONST2 = 3
Private mvar1 As String
Private mvar2 As Integer ' #ReplReserv
Public mvar3 As Boolean 'pour test de Me
Rem constructeur : son nom ne doit pas être obfuscaté
Sub New() ' #ClassInit
mvar1 = MYCONST1
mvar2 = MYCONST2
Me.mvar3 = False
Application.DoEvents ' #Preffx 'pourquoi ne pas le mettre ici ?
End Sub
Rem property : changement de la syntaxe
Rem le Get et Let/Set doivent être groupés dans le code
Rem le code migré doit être :
' Property var1( ) As String
' Get
' var1 = mvar1
' End Get
' Set(parm1 As String)
' mvar1 = Value
' End Set
' End Property
Friend Property var1() As String ' #Property
Get ' #Get
var1 = mvar1
End Get ' #Get
Set (parm1 As String) ' #Let
mvar1 = parm1
End Set ' #Let
End Property
Friend Property var2() As Long ' #Property
Set (parm1 As Integer) ' #Let#ReplReserv
mvar2 = parm1
End Set ' #Let
Get ' #Get
var2 = mvar2
End Get ' #Get
End Property
Rem destructeur : son nom ne doit pas être obfuscaté
Protected Overrides Sub Finalize() ' #ClassTerm
Dim lEnum As myEnum
lEnum = myEnum.enum0 ' avec le nom de l'enum
Call MsgBox("Object of class MyTestClass destroyed !" & vbCr & "(error = " & Error & ")") ' #Call
lEnum = myEnum.enum1 ' #Enum ' sans le nom de l'enum
End Sub
Rem property Get sans Set
Friend Property var3() As Boolean ' #Property
Get ' #Get
var3 = mvar3
End Get ' #Get
End Property
End Class
6.2 Module de code "MyModule.bas"
Code source
Attribute VB_Name = "MyModule"
Option Explicit
Public Type myType
mvar1 As String
mvar2 As Long
mvar3 As Boolean
End Type
Const MYCONST1 = "MyModule"
Const MYCONST2 = 4
Public Type my2ndType
mvar2(1 To 5) As myType
mvar1 As Boolean
End Type
Rem sub de test
Private Sub monsubPrive(ByRef pparm1 As String, _
ByVal pparm2 As Boolean, pparm3 As myType, Optional pParamOption As Variant)
Dim mvar1 As String, lvarA As Boolean, mvar2 As my2ndType, lNum As Integer
pparm3.mvar1 = pparm1
With pparm3
.mvar2 = -3
End With
lNum = 1
With mvar2
While lNum <= 5 _
And .mvar2(lNum).mvar3 = True
If .mvar2(lNum).mvar2 > 0 Then MsgBox Str(lNum) & " : " & .mvar2(lNum).mvar1 ' call implicite après un THEN
lNum = lNum + 1
Wend ' Wend a remplacer en .Net _
suite du commentaire
End With
Rem 3 identificateurs mvar2 qui désignent tous des variables différentes
If Not (mvar2.mvar2(1)) Then ' 5 + pparm3.mvar2 Is Nothing
mvar2.mvar2(5 + pparm3.mvar2).mvar2 = -1234567
End If
lvarA = True
mvar1 = MYCONST1
MsgBox "monsubPrive : " & pparm3.mvar1 & " " & mvar1
If IsMissing(pParamOption) Then MsgBox "parametre optionel non renseigné"
End Sub
Public Sub lance()
Dim laClasse As MyTestClass, var2 As String, mvar1 As myType, lEnumItem As Integer
If laClasse Is Nothing Then
Set laClasse = New MyTestClass
End If
With ActiveSheet
.Cells(2, 2) = "Test démarré"
End With
Rem ne pas confondre les 2 "var2"
laClasse.var2 = 12345 - 1234
var2 = " toto "
monsubPrive "test", True, mvar1
Rem constantes Office ou Excel ou... à préfixer en vb.net
lEnumItem = xlNext
lEnumItem = xlPart
lEnumItem = xlDown
lEnumItem = xlValues
lEnumItem = xlWhole
lEnumItem = msoLineSingle
lEnumItem = msoTrue
lEnumItem = msoLineSolid
lEnumItem = vbRed
lEnumItem = vbFromUnicode
lEnumItem = xlLastCell
MyUserForm.Show 'affichage modal
MyUserForm.Show (vbModeless) 'affichage non modal
Application.Worksheets("Feuil1").Cells(2, 2).Value = ""
Application.Worksheets("Feuil1").Cells(3, 2).Value = ""
If Cells(1, 1).Value = "" Then _
MsgBox ("cellule vide")
If Worksheets("Feuil1").Cells(1, 1).Value <> "" Then _
var2 = Worksheets("Feuil1").Cells(1, 1).Value
If Application.Worksheets("Feuil1").Cells(1, 1).Value > -1 Then
lEnumItem = Application.Worksheets("Feuil1").Cells(1, 1).Value
End If
If Worksheets("Feuil1").Cells(1, 1).Value = "Toto" Then _
MsgBox ("cellule contient Toto")
End Sub
Rem pour test migration fonctions IO de fichiers
Private Sub recopieFichier(pNomFicEnt As String, pNomFicSor As String)
Dim lLigne As String, lNoligne As Long, lNoFicEnt As Integer, _
lNoFicSor As Integer, lContinueSiErreur As Boolean, lStop As Boolean
Rem ouverture du fichier de script
On Error GoTo gestionErreurFichier
lNoFicEnt = FreeFile
lNoFicSor = FreeFile
Open pNomFicEnt For Input As lNoFicEnt
Open pNomFicSor For Output As lNoFicSor
Rem boucle de lecture du fichier
lNoligne = 0
lStop = False
While Not (EOF(lNoFicEnt) Or lStop)
Line Input #lNoFicEnt, lLigne ' lit la ligne en entrée
Rem recopie la ligne en sortie
Print #lNoFicSor, lLigne
lNoligne = lNoligne + 1
If lNoligne > 100 Then _
lStop = True
Wend
Rem fermeture des fichiers
Close #lNoFicEnt
Close #lNoFicSor
On Error GoTo 0
Exit Sub
gestionErreurFichier:
MsgBox "Impossible d'ouvrir le fichier"
Err.Number = 0
Exit Sub
End Sub
Code migré
Public Module MyModule
Public MYEXCELAPP As Microsoft.Office.Interop.Excel.Application
Public MYTOOLTIP As System.Windows.Forms.ToolTip
Public Const _OPTIONALDEFAULT_ As String = "$$DEFAULT$$"
Public Function CellToString(ByRef pCell As Microsoft.Office.Interop.Excel.Range) As String
If pCell Is Nothing Then
CellToString = New String("")
elseIf pCell.Value Is Nothing Then
CellToString = New String("")
Else
CellToString = pCell.Value
End If
End Function
Public Function CellToDouble(ByRef pCell As Microsoft.Office.Interop.Excel.Range) As Double
If pCell Is Nothing Then
CellToDouble = 0.0#
ElseIf pCell.Value Is Nothing Then
CellToDouble = 0.0#
Else
CellToDouble = Val(pCell.Value)
End If
End Function
Public Function CellToInt(ByRef pCell As Microsoft.Office.Interop.Excel.Range) As Integer
If pCell Is Nothing Then
CellToInt = 0
ElseIf pCell.Value Is Nothing Then
CellToInt = 0
Else
CellToInt = Int(Val(pCell.Value))
End If
End Function
' Option Explicit ' #Option
Public Structure myType ' #ReplReserv
Dim mvar1 As String ' #StructItem
Dim mvar2 As Integer ' #StructItem#ReplReserv
Dim mvar3 As Boolean ' #StructItem
End Structure ' #ReplReserv
Const MYCONST1 = "MyModule"
Const MYCONST2 = 4
Public Structure my2ndType ' #ReplReserv
Dim mvar2() As myType ' #StructItem#To
Dim mvar1 As Boolean ' #StructItem
End Structure ' #ReplReserv
Rem sub de test
Private Sub monsubPrive(ByRef pparm1 As String, ByVal pparm2 As Boolean, ByRef pparm3 As myType, Optional ByRef pParamOption As String = _OPTIONALDEFAULT_) ' #ByRef#Optional#ByRef#ReplReserv
Dim mvar1 As String = "", lvarA As Boolean, mvar2 = New my2ndType, lNum As Short ' #DeclString#DeclStruct#ReplReserv
pparm3.mvar1 = pparm1
With pparm3
.mvar2 = -3
End With
lNum = 1
With mvar2
While lNum <= 5 And .mvar2(lNum).mvar3 = True
If .mvar2(lNum).mvar2 > 0 Then MsgBox(Str(lNum) & " : " & .mvar2(lNum).mvar1) ' #Call ' call implicite après un THEN
lNum = lNum + 1
End While ' #ReplReserv ' Wend a remplacer en .Net suite du commentaire
End With
Rem 3 identificateurs mvar2 qui désignent tous des variables différentes
If Not (mvar2.mvar2(1)) Then ' 5 + pparm3.mvar2 Is Nothing
mvar2.mvar2(5 + pparm3.mvar2).mvar2 = -1234567
End If
lvarA = True
mvar1 = MYCONST1
Call MsgBox("monsubPrive : " & pparm3.mvar1 & " " & mvar1) ' #Call
If pParamOption = _OPTIONALDEFAULT_ Then MsgBox("parametre optionel non renseigné") ' #IsMissing#Call
End Sub
Public Sub lance()
Dim laClasse As MyTestClass, var2 As String = "", mvar1 = New myType, lEnumItem As Short ' #DeclString#DeclStruct#ReplReserv
If IsNothing(laClasse ) Then ' #Nothing
laClasse = New MyTestClass ' #Set
End If
With MYEXCELAPP.ActiveSheet ' #Preffx
.Cells(2, 2) = "Test démarré"
End With
Rem ne pas confondre les 2 "var2"
laClasse.var2 = 12345 - 1234
var2 = " toto "
Call monsubPrive("test", True, mvar1) ' #Call
Rem constantes Office ou Excel ou... à préfixer en vb.net
lEnumItem = Microsoft.Office.Interop.Excel.XlSearchDirection.xlNext ' #Preffx
lEnumItem = Microsoft.Office.Interop.Excel.XlLookAt.xlPart ' #Preffx
lEnumItem = Microsoft.Office.Interop.Excel.XlDirection.xlDown ' #Preffx
lEnumItem = Microsoft.Office.Interop.Excel.XlFindLookIn.xlValues ' #Preffx
lEnumItem = Microsoft.Office.Interop.Excel.XlLookAt.xlWhole ' #Preffx
lEnumItem = Microsoft.Office.Core.MsoLineStyle.msoLineSingle ' #Preffx
lEnumItem = Microsoft.Office.Core.MsoTriState.msoTrue ' #Preffx
lEnumItem = Microsoft.Office.Core.MsoLineDashStyle.msoLineSolid ' #Preffx
lEnumItem = System.Drawing.ColorTranslator.ToOle(Color.Red) ' #ReplIdent
lEnumItem = vbFromUnicode
lEnumItem = Microsoft.Office.Interop.Excel.Constants.xlLastCell ' #Preffx
MyUserForm.ShowDialog(???nom_du_owner???) ' #Show 'affichage modal
MyUserForm.Show() ' #Show 'affichage non modal
MYEXCELAPP.Application.Worksheets("Feuil1").Cells(2, 2).Value = "" ' #Preffx
MYEXCELAPP.Application.Worksheets("Feuil1").Cells(3, 2).Value = "" ' #Preffx
If CellToString(MYEXCELAPP.Cells(1, 1)) = "" Then MsgBox(("cellule vide")) ' #Preffx#CellValue#Call
If CellToString(MYEXCELAPP.Worksheets("Feuil1").Cells(1, 1)) <> "" Then var2 = CellToString(MYEXCELAPP.Worksheets("Feuil1").Cells(1, 1)) ' #Preffx#CellValue#Preffx#CellValue
If CellToDouble(MYEXCELAPP.Application.Worksheets("Feuil1").Cells(1, 1)) > -1 Then ' #Preffx#CellValue
lEnumItem = CellToDouble(MYEXCELAPP.Application.Worksheets("Feuil1").Cells(1, 1)) ' #Preffx#CellValue
End If
If CellToString(MYEXCELAPP.Worksheets("Feuil1").Cells(1, 1)) = "Toto" Then MsgBox(("cellule contient Toto")) ' #Preffx#CellValue#Call
End Sub
Rem pour test migration fonctions IO de fichiers
Private Sub recopieFichier(ByRef pNomFicEnt As String, ByRef pNomFicSor As String) ' #ByRef#ByRef
Dim lLigne As String = "", lNoligne As Integer, lNoFicEnt As Short, lNoFicSor As Short, lContinueSiErreur As Boolean, lStop As Boolean ' #DeclString#ReplReserv#ReplReserv#ReplReserv
Rem ouverture du fichier de script
On Error GoTo gestionErreurFichier
lNoFicEnt_file = New System.IO.FileStream(??filepath??, System.IO.FileMode.Open, System.IO.FileAccess.????) ' #FreeFile
lNoFicSor_file = New System.IO.FileStream(??filepath??, System.IO.FileMode.Open, System.IO.FileAccess.????) ' #FreeFile
lNoFicEnt = New System.IO.StreamReader(lNoFicEnt_file) ' #Open
lNoFicSor = New System.IO.StreamReader(lNoFicSor_file) ' #Open
Rem boucle de lecture du fichier
lNoligne = 0
lStop = False
While Not (lNoFicEnt.Peek() > -1 Or lStop) ' #EOF
lLigne = lNoFicEnt.ReadLine() ' #Line ' lit la ligne en entrée
Rem recopie la ligne en sortie
lNoFicSor.WriteLine(lLigne) ' #Print
lNoligne = lNoligne + 1
If lNoligne > 100 Then lStop = True
End While ' #ReplReserv
Rem fermeture des fichiers
lNoFicEnt.Close() ' #Close
lNoFicSor.Close() ' #Close
On Error GoTo 0
Exit Sub
gestionErreurFichier:
Call MsgBox("Impossible d'ouvrir le fichier") ' #Call
Err.Number = 0
Exit Sub
End Sub
End Module
6.3 UserForm "MyUserForm.frm"
Code source
VERSION 5.00
Begin {C62A69F0-16DC-11CE-9E98-00AA00574A4F} MyUserForm
Caption = "Test VBA2DotNet"
ClientHeight = 7455
ClientLeft = 45
ClientTop = 345
ClientWidth = 4950
OleObjectBlob = "MyUserForm.frx":0000
StartUpPosition = 1 'CenterOwner
End
Attribute VB_Name = "MyUserForm"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = False
Attribute VB_PredeclaredId = True
Attribute VB_Exposed = False
Option Explicit
Private var1 As MyTestClass
Private var2 As myType
Private Sub Fermer_Click()
Worksheets("Feuil1").Cells(3, 2) = "C'est fini"
MyUserForm.Hide
Unload MyUserForm
End Sub
Private Sub TextBox1_DblClick(ByVal pCancel As msforms.ReturnBoolean)
TextBox1 = "User has double-clicked" ' il manque l'attribut ici
End Sub
Rem Initialize remplacé par l'évènement Load
Private Sub UserForm_Initialize()
Dim lTableauShapes() As String
Label1.Caption = "valeur initialisée par UserForm_Initialize"
Set var1 = New MyTestClass
With ListBox1
.Clear
.AddItem ("first")
.AddItem ("second")
.AddItem ("third")
End With
TextBox3.ControlTipText = "Some Help Text"
ReDim lTableauShapes(2)
lTableauShapes(0) = "Toto"
lTableauShapes(1) = "Tata"
lTableauShapes(2) = "Titi"
Rem remplacement de Array() par {}
On Error GoTo RangeNotFound
ActiveSheet.Shapes.Range(Array(lTableauShapes(0), lTableauShapes(1), _
lTableauShapes(2))).Select
RangeNotFound:
Err.Clear
End Sub
Private Sub CommandButton1_Click()
MsgBox "TextBox2.Value=" & var1.var1 'ne pas confondre l'instance de MyTestClass _
avec son membre de même nom
Rem les controles peuvent être qualifiés complètement ou pas du tout
MyUserForm.MultiPage1.Page2.TextBox2.Value = "-->" & var1.var1
With MyUserForm.MultiPage1
.Page2.TextBox2.Locked = True
End With
End Sub
Private Sub TextBox2_Change()
Dim mvar1 As String, var_2 As Integer, _
var_3 As Boolean 'gestion d'une ligne avec caractère de continuation
Rem les controles peuvent être qualifiés complètement ou pas du tout
var1.var1 = TextBox2.Value
Rem gestion du with : ne pas confondre la variable locale mvar1 avec le membre .mvar1
With var2
.mvar1 = "string"
.mvar2 = 123456789
.mvar3 = True
End With
End Sub
Code migré
Public Class MyUserForm
' Option Explicit ' #Option
Private var1 As MyTestClass
Private var2 = New myType ' #DeclStruct
Private Sub Fermer_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Fermer.Click ' #Handles
MYEXCELAPP.Worksheets("Feuil1").Cells(3, 2) = "C'est fini" ' #Preffx
Me.Hide ' #UserForm
Me.Close() ' #Unload#UserForm
End Sub
Private Sub TextBox1_DoubleClick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TextBox1.DoubleClick ' #ReplEvent#Handles
TextBox1.Text = "User has double-clicked" ' #DefAttrb ' il manque l'attribut ici
End Sub
Rem Initialize remplacé par l'évènement Load
Private Sub UserForm_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Me.Load ' #ReplEvent#Handles
Dim lTableauShapes() As String
Label1.Text = "valeur initialisée par UserForm_Initialize" ' #ReplAttrb
var1 = New MyTestClass ' #Set
With ListBox1
.Items.Clear() ' #ReplAttrb
.Items.Add ("first") ' #ReplAttrb
.Items.Add ("second") ' #ReplAttrb
.Items.Add ("third") ' #ReplAttrb
End With
MYTOOLTIP.SetToolTip(TextBox3, "Some Help Text") ' #TipText
ReDim lTableauShapes(2)
lTableauShapes(0) = "Toto"
lTableauShapes(1) = "Tata"
lTableauShapes(2) = "Titi"
Rem remplacement de Array() par {}
On Error GoTo RangeNotFound
MYEXCELAPP.ActiveSheet.Shapes.Range({lTableauShapes(0), lTableauShapes(1), lTableauShapes(2)}).Select ' #Preffx#Array
RangeNotFound:
Err.Clear
End Sub
Private Sub CommandButton1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles CommandButton1.Click ' #Handles
Call MsgBox("TextBox2.Value=" & var1.var1) ' #Call 'ne pas confondre l'instance de MyTestClass avec son membre de même nom
Rem les controles peuvent être qualifiés complètement ou pas du tout
TextBox2.Text = "-->" & var1.var1 ' #UserForm#Control#Control#Control#ReplAttrb
With MultiPage1 ' #UserForm#Control
TextBox2.ReadOnly = True ' #Control#Control#ReplAttrb
End With
End Sub
Private Sub TextBox2_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TextBox2.TextChanged ' #ReplEvent#Handles
Dim mvar1 As String = "", var_2 As Short, var_3 As Boolean ' #DeclString#ReplReserv 'gestion d'une ligne avec caractère de continuation
Rem les controles peuvent être qualifiés complètement ou pas du tout
var1.var1 = TextBox2.Text ' #ReplAttrb
Rem gestion du with : ne pas confondre la variable locale mvar1 avec le membre .mvar1
With var2
.mvar1 = "string"
.mvar2 = 123456789
.mvar3 = True
End With
End Sub
End Class
Code du Designer
_
Partial Class MyUserForm
Inherits System.Windows.Forms.Form
'Form remplace la méthode Dispose pour nettoyer la liste des composants.
_
Protected Overrides Sub Dispose(ByVal disposing As Boolean)
Try
If disposing AndAlso components IsNot Nothing Then
components.Dispose()
End If
Finally
MyBase.Dispose(disposing)
End Try
End Sub
'Requise par le Concepteur Windows Form
Private components As System.ComponentModel.IContainer
'REMARQUE : la procédure suivante est requise par le Concepteur Windows Form
'Elle peut être modifiée à l'aide du Concepteur Windows Form.
'Ne la modifiez pas à l'aide de l'éditeur de code.
_
Private Sub InitializeComponent()
Me.Frame1 = New System.Windows.Forms.GroupBox()
Me.TextBox1 = New System.Windows.Forms.TextBox()
Me.CommandButton1 = New System.Windows.Forms.Button()
Me.MultiPage1 = New System.Windows.Forms.TabControl()
Me.Page1 = New System.Windows.Forms.TabPage()
Me.Page2 = New System.Windows.Forms.TabPage()
Me.Label1 = New System.Windows.Forms.Label()
Me.TextBox2 = New System.Windows.Forms.TextBox()
Me.Fermer = New System.Windows.Forms.Button()
Me.OptionButton1 = New System.Windows.Forms.RadioButton()
Me.OptionButton2 = New System.Windows.Forms.RadioButton()
Me.CheckBox1 = New System.Windows.Forms.CheckBox()
Me.CheckBox2 = New System.Windows.Forms.CheckBox()
Me.CheckBox3 = New System.Windows.Forms.CheckBox()
Me.ListBox1 = New System.Windows.Forms.ListBox()
Me.ComboBox1 = New System.Windows.Forms.ComboBox()
Me.MultiPage2 = New System.Windows.Forms.TabControl()
Me.Page3 = New System.Windows.Forms.TabPage()
Me.Page4 = New System.Windows.Forms.TabPage()
Me.SpinButton1 = New System.Windows.Forms.NumericUpDown()
Me.TextBox3 = New System.Windows.Forms.TextBox()
Me.Label2 = New System.Windows.Forms.Label()
Me.Image1 = New System.Windows.Forms.PictureBox()
Me.Label3 = New System.Windows.Forms.Label()
Me.Frame1.SuspendLayout()
Me.MultiPage1.SuspendLayout()
Me.Page1.SuspendLayout()
Me.Page2.SuspendLayout()
Me.MultiPage2.SuspendLayout()
Me.Page3.SuspendLayout()
Me.Page4.SuspendLayout()
CType(Me.SpinButton1, System.ComponentModel.ISupportInitialize).BeginInit()
CType(Me.Image1, System.ComponentModel.ISupportInitialize).BeginInit()
Me.SuspendLayout()
'
'Frame1
'
Me.Frame1.Controls.Add (Me.TextBox1)
Me.Frame1.Controls.Add (Me.CommandButton1)
Me.Frame1.Location = New System.Drawing.Point(4, 12)
Me.Frame1.Name = "Frame1"
Me.Frame1.Size = New System.Drawing.Size(316, 96)
Me.Frame1.TabIndex = 0
Me.Frame1.TabStop = False
Me.Frame1.Text = "Frame number 1"
'
'TextBox1
'
Me.TextBox1.Font = New System.Drawing.Font("Tahoma", 8.25!, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, CType(0, Byte))
Me.TextBox1.MultiLine = True
Me.TextBox1.Location = New System.Drawing.Point(4, 8)
Me.TextBox1.Name = "TextBox1"
Me.TextBox1.Size = New System.Drawing.Size(188, 72)
Me.TextBox1.TabIndex = 0
Me.TextBox1.Text = "Ceci est un Userform destiné à tester le fonctionnement de Obfu-VBA."
'
'CommandButton1
'
Me.CommandButton1.Font = New System.Drawing.Font("Tahoma", 9.75!, CType((System.Drawing.FontStyle.Bold Or System.Drawing.FontStyle.Italic), System.Drawing.FontStyle), System.Drawing.GraphicsUnit.Point, CType(0, Byte))
Me.CommandButton1.Location = New System.Drawing.Point(204, 12)
Me.CommandButton1.Name = "CommandButton1"
Me.CommandButton1.Size = New System.Drawing.Size(92, 32)
Me.CommandButton1.TabIndex = 1
Me.CommandButton1.Text = "Alert !"
Me.CommandButton1.UseVisualStyleBackColor = True
'
'MultiPage1
'
Me.MultiPage1.Controls.Add (Me.Page1)
Me.MultiPage1.Controls.Add (Me.Page2)
Me.MultiPage1.Font = New System.Drawing.Font("Tahoma", 8.25!, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, CType(0, Byte))
Me.MultiPage1.Location = New System.Drawing.Point(8, 112)
Me.MultiPage1.Name = "MultiPage1"
Me.MultiPage1.Size = New System.Drawing.Size(316, 156)
Me.MultiPage1.TabIndex = 1
Me.MultiPage1.Text = "1"
'
'Page1
'
Me.Page1.BackColor = System.Drawing.SystemColors.ButtonFace
Me.Page1.Controls.Add (Me.Label1)
Me.Page1.Controls.Add (Me.CheckBox1)
Me.Page1.Controls.Add (Me.CheckBox2)
Me.Page1.Controls.Add (Me.CheckBox3)
Me.Page1.Controls.Add (Me.ListBox1)
Me.Page1.Location = New System.Drawing.Point(3, 21)
Me.Page1.Name = "Page1"
Me.Page1.Padding = New System.Windows.Forms.Padding(3)
Me.Page1.Size = New System.Drawing.Size(312, 133)
Me.Page1.TabIndex = 0
Me.Page1.Text = ""
Me.Page1.UseVisualStyleBackColor = True
'
'Page2
'
Me.Page2.BackColor = System.Drawing.SystemColors.ButtonFace
Me.Page2.Controls.Add (Me.TextBox2)
Me.Page2.Controls.Add (Me.OptionButton1)
Me.Page2.Controls.Add (Me.OptionButton2)
Me.Page2.Controls.Add (Me.MultiPage2)
Me.Page2.Location = New System.Drawing.Point(3, 21)
Me.Page2.Name = "Page2"
Me.Page2.Padding = New System.Windows.Forms.Padding(3)
Me.Page2.Size = New System.Drawing.Size(312, 133)
Me.Page2.TabIndex = 1
Me.Page2.Text = ""
Me.Page2.UseVisualStyleBackColor = True
'
'Label1
'
Me.Label1.AutoSize = False
Me.Label1.Font = New System.Drawing.Font("Tahoma", 9!, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, CType(0, Byte))
Me.Label1.AutoSize = True
Me.Label1.Location = New System.Drawing.Point(8, 8)
Me.Label1.Name = "Label1"
Me.Label1.Size = New System.Drawing.Size(280, 32)
Me.Label1.TabIndex = 0
Me.Label1.Text = "Page 1 du multipage"
'
'TextBox2
'
Me.TextBox2.Font = New System.Drawing.Font("Tahoma", 12!, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, CType(0, Byte))
Me.TextBox2.MultiLine = False
Me.TextBox2.Location = New System.Drawing.Point(8, 4)
Me.TextBox2.Name = "TextBox2"
Me.TextBox2.Size = New System.Drawing.Size(272, 28)
Me.TextBox2.TabIndex = 0
Me.TextBox2.Text = "Page 2 du multi-page"
'
'Fermer
'
Me.Fermer.Font = New System.Drawing.Font("Tahoma", 8.25!, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, CType(0, Byte))
Me.Fermer.Location = New System.Drawing.Point(228, 320)
Me.Fermer.Name = "Fermer"
Me.Fermer.Size = New System.Drawing.Size(88, 48)
Me.Fermer.TabIndex = 2
Me.Fermer.Text = "Fermer/Close"
Me.Fermer.UseVisualStyleBackColor = True
'
'OptionButton1
'
Me.OptionButton1.Font = New System.Drawing.Font("Tahoma", 8.25!, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, CType(0, Byte))
Me.OptionButton1.Location = New System.Drawing.Point(12, 40)
Me.OptionButton1.Name = "OptionButton1"
Me.OptionButton1.Size = New System.Drawing.Size(117, 20)
Me.OptionButton1.TabIndex = 1
Me.OptionButton1.TabStop = False
Me.OptionButton1.Text = "OptionButton1"
Me.OptionButton1.UseVisualStyleBackColor = True
'
'OptionButton2
'
Me.OptionButton2.Font = New System.Drawing.Font("Tahoma", 8.25!, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, CType(0, Byte))
Me.OptionButton2.Location = New System.Drawing.Point(12, 68)
Me.OptionButton2.Name = "OptionButton2"
Me.OptionButton2.Size = New System.Drawing.Size(116, 24)
Me.OptionButton2.TabIndex = 2
Me.OptionButton2.TabStop = False
Me.OptionButton2.Text = "OptionButton2"
Me.OptionButton2.UseVisualStyleBackColor = True
'
'CheckBox1
'
Me.CheckBox1.AutoSize = False
Me.CheckBox1.Font = New System.Drawing.Font("Tahoma", 8.25!, System.Drawing.FontStyle.Italic, System.Drawing.GraphicsUnit.Point, CType(0, Byte))
Me.CheckBox1.AutoSize = True
Me.CheckBox1.Location = New System.Drawing.Point(8, 44)
Me.CheckBox1.Name = "CheckBox1"
Me.CheckBox1.Size = New System.Drawing.Size(107, 20)
Me.CheckBox1.TabIndex = 1
Me.CheckBox1.Text = "CheckBox1"
Me.CheckBox1.UseVisualStyleBackColor = True
'
'CheckBox2
'
Me.CheckBox2.AutoSize = False
Me.CheckBox2.Font = New System.Drawing.Font("Tahoma", 8.25!, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, CType(0, Byte))
Me.CheckBox2.AutoSize = True
Me.CheckBox2.Location = New System.Drawing.Point(8, 64)
Me.CheckBox2.Name = "CheckBox2"
Me.CheckBox2.Size = New System.Drawing.Size(101, 24)
Me.CheckBox2.TabIndex = 2
Me.CheckBox2.Text = "CheckBox2"
Me.CheckBox2.UseVisualStyleBackColor = True
'
'CheckBox3
'
Me.CheckBox3.AutoSize = False
Me.CheckBox3.Font = New System.Drawing.Font("Tahoma", 8.25!, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, CType(0, Byte))
Me.CheckBox3.AutoSize = True
Me.CheckBox3.Location = New System.Drawing.Point(8, 88)
Me.CheckBox3.Name = "CheckBox3"
Me.CheckBox3.Size = New System.Drawing.Size(104, 20)
Me.CheckBox3.TabIndex = 3
Me.CheckBox3.Text = "CheckBox3"
Me.CheckBox3.UseVisualStyleBackColor = True
'
'ListBox1
'
Me.ListBox1.Font = New System.Drawing.Font("Tahoma", 8.25!, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, CType(0, Byte))
Me.ListBox1.FormattingEnabled = True
Me.ListBox1.Location = New System.Drawing.Point(132, 44)
Me.ListBox1.Name = "ListBox1"
Me.ListBox1.Size = New System.Drawing.Size(144, 64)
Me.ListBox1.TabIndex = 4
Me.ListBox1.Text = ""
'
'ComboBox1
'
Me.ComboBox1.Font = New System.Drawing.Font("Tahoma", 8.25!, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, CType(0, Byte))
Me.ComboBox1.FormattingEnabled = True
Me.ComboBox1.Location = New System.Drawing.Point(220, 280)
Me.ComboBox1.Name = "ComboBox1"
Me.ComboBox1.Size = New System.Drawing.Size(96, 24)
Me.ComboBox1.TabIndex = 3
Me.ComboBox1.Text = "entree1"
'
'MultiPage2
'
Me.MultiPage2.Controls.Add (Me.Page3)
Me.MultiPage2.Controls.Add (Me.Page4)
Me.MultiPage2.Font = New System.Drawing.Font("Tahoma", 8.25!, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, CType(0, Byte))
Me.MultiPage2.Location = New System.Drawing.Point(140, 40)
Me.MultiPage2.Name = "MultiPage2"
Me.MultiPage2.Size = New System.Drawing.Size(164, 84)
Me.MultiPage2.TabIndex = 3
Me.MultiPage2.Text = "0"
'
'Page3
'
Me.Page3.BackColor = System.Drawing.SystemColors.ButtonFace
Me.Page3.Controls.Add (Me.SpinButton1)
Me.Page3.Controls.Add (Me.TextBox3)
Me.Page3.Location = New System.Drawing.Point(3, 21)
Me.Page3.Name = "Page3"
Me.Page3.Padding = New System.Windows.Forms.Padding(3)
Me.Page3.Size = New System.Drawing.Size(160, 61)
Me.Page3.TabIndex = 0
Me.Page3.Text = ""
Me.Page3.UseVisualStyleBackColor = True
'
'Page4
'
Me.Page4.BackColor = System.Drawing.SystemColors.ButtonFace
Me.Page4.Controls.Add (Me.Label2)
Me.Page4.Location = New System.Drawing.Point(3, 21)
Me.Page4.Name = "Page4"
Me.Page4.Padding = New System.Windows.Forms.Padding(3)
Me.Page4.Size = New System.Drawing.Size(160, 61)
Me.Page4.TabIndex = 1
Me.Page4.Text = ""
Me.Page4.UseVisualStyleBackColor = True
'
'SpinButton1
'
Me.SpinButton1.Location = New System.Drawing.Point(128, 4)
Me.SpinButton1.Name = "SpinButton1"
Me.SpinButton1.Size = New System.Drawing.Size(28, 40)
Me.SpinButton1.TabIndex = 0
Me.SpinButton1.Text = "0"
'
'TextBox3
'
Me.TextBox3.Font = New System.Drawing.Font("Tahoma", 8.25!, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, CType(0, Byte))
Me.TextBox3.MultiLine = False
Me.TextBox3.Location = New System.Drawing.Point(4, 4)
Me.TextBox3.Name = "TextBox3"
Me.TextBox3.Size = New System.Drawing.Size(112, 36)
Me.TextBox3.TabIndex = 1
Me.TextBox3.Text = ""
'
'Label2
'
Me.Label2.AutoSize = False
Me.Label2.Font = New System.Drawing.Font("Tahoma", 8.25!, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, CType(0, Byte))
Me.Label2.AutoSize = True
Me.Label2.Location = New System.Drawing.Point(4, 8)
Me.Label2.Name = "Label2"
Me.Label2.Size = New System.Drawing.Size(96, 24)
Me.Label2.TabIndex = 0
Me.Label2.Text = "Label2"
'
'Image1
'
Me.Image1.Location = New System.Drawing.Point(12, 272)
Me.Image1.Name = "Image1"
Me.Image1.Size = New System.Drawing.Size(200, 208)
Me.Image1.Size = New System.Drawing.Size(200, 208)
'
'Label3
'
Me.Label3.AutoSize = False
Me.Label3.Font = New System.Drawing.Font("Tahoma", 8.25!, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, CType(0, Byte))
Me.Label3.AutoSize = True
Me.Label3.Location = New System.Drawing.Point(216, 376)
Me.Label3.Name = "Label3"
Me.Label3.Size = New System.Drawing.Size(108, 56)
Me.Label3.TabIndex = 4
Me.Label3.Text = "Ceci est un label long qui doit tenir sur plusieurs lignes"
'
'MyUserForm
'
Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!)
Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
Me.ClientSize = New System.Drawing.Size(336, 525)
Me.Controls.Add (Me.Frame1)
Me.Controls.Add (Me.MultiPage1)
Me.Controls.Add (Me.Fermer)
Me.Controls.Add (Me.ComboBox1)
Me.Controls.Add (Me.Image1)
Me.Controls.Add (Me.Label3)
Me.Name = "MyUserForm"
Me.Text = "Test VBA2DotNet"
Me.Frame1.ResumeLayout(False)
Me.Frame1.PerformLayout()
Me.MultiPage1.ResumeLayout(False)
Me.MultiPage1.PerformLayout()
Me.Page1.ResumeLayout(False)
Me.Page1.PerformLayout()
Me.Page2.ResumeLayout(False)
Me.Page2.PerformLayout()
Me.MultiPage2.ResumeLayout(False)
Me.MultiPage2.PerformLayout()
Me.Page3.ResumeLayout(False)
Me.Page3.PerformLayout()
Me.Page4.ResumeLayout(False)
Me.Page4.PerformLayout()
CType(Me.SpinButton1, System.ComponentModel.ISupportInitialize).EndInit()
CType(Me.Image1, System.ComponentModel.ISupportInitialize).EndInit()
Me.ResumeLayout(False)
Me.PerformLayout()
End Sub
Friend WithEvents Frame1 As System.Windows.Forms.GroupBox
Friend WithEvents TextBox1 As System.Windows.Forms.TextBox
Friend WithEvents CommandButton1 As System.Windows.Forms.Button
Friend WithEvents MultiPage1 As System.Windows.Forms.TabControl
Friend WithEvents Page1 As System.Windows.Forms.TabPage
Friend WithEvents Page2 As System.Windows.Forms.TabPage
Friend WithEvents Label1 As System.Windows.Forms.Label
Friend WithEvents TextBox2 As System.Windows.Forms.TextBox
Friend WithEvents Fermer As System.Windows.Forms.Button
Friend WithEvents OptionButton1 As System.Windows.Forms.RadioButton
Friend WithEvents OptionButton2 As System.Windows.Forms.RadioButton
Friend WithEvents CheckBox1 As System.Windows.Forms.CheckBox
Friend WithEvents CheckBox2 As System.Windows.Forms.CheckBox
Friend WithEvents CheckBox3 As System.Windows.Forms.CheckBox
Friend WithEvents ListBox1 As System.Windows.Forms.ListBox
Friend WithEvents ComboBox1 As System.Windows.Forms.ComboBox
Friend WithEvents MultiPage2 As System.Windows.Forms.TabControl
Friend WithEvents Page3 As System.Windows.Forms.TabPage
Friend WithEvents Page4 As System.Windows.Forms.TabPage
Friend WithEvents SpinButton1 As System.Windows.Forms.NumericUpDown
Friend WithEvents TextBox3 As System.Windows.Forms.TextBox
Friend WithEvents Label2 As System.Windows.Forms.Label
Friend WithEvents Image1 As System.Windows.Forms.PictureBox
Friend WithEvents Label3 As System.Windows.Forms.Label
End Class
7 Comment obtenir VBA2DotNet ?
ToolOscope vous propose une licence Shareware :
- Vous souhaitez essayer VBA2DotNet : Enregistrez-vous et téléchargez gratuitement le logiciel en version complète. Vous bénéficiez d'une licence d'évaluation.
- "A quoi bon ?" : Détruisez vos copies du logiciel et les sous-produits générés par lui.
- "Ce logiciel n'est pas mal, mais..." : Demandez une évolution ou une correction en décrivant précisément votre besoin.
- "Ca marche et je vais continuer à m'en servir ou à me servir des sous-produits" : Envoyez un e-mail de remerciements à son créateur.
Pour tout cela, rendez-vous à l'Espace Utilisateurs.
Ne modifiez pas ce logiciel, ne le diffusez pas : ToolOscope s'en charge.