Récupérer un projet VB6 pour un non-VB6

On m'a confié la tâche de modifier un projet VB6. Rien d'incroyablement sérieux, en ajoutant quelques forms et en corrigeant quelques bugs pour la plupart. Le projet utilise SQL Server (si cela est pertinent).

Mon expérience dans la programmation a été VB / C # .NET, PHP, C ++ et surtout MySQL bien que j'ai utilisé SQL Server à une échelle beaucoup plus petite. Quel genre de conseil peut-on me donner ou des ressources pour la programmation VB6. Cela fait quelques années que j'ai fait n'importe quel travail VB .NET et pendant que je peux lire le code VB6 et comprendre ce qui se passe, je ne suis pas sûr de savoir si je vais pouvoir commencer à écrire et / ou modifier sans risque de casser quoi que ce soit.

Quel genre de conseil les autres peuvent-ils offrir? Toutes les ressources et / ou histoires seraient géniales. N'hésitez pas à consortingbuer à des choses que vous vous sentez peut-être pertinentes, mais j'ai oublié de mentionner.

Merci!

Il est probablement déjà là, mais assurez-vous que Option Explicit est en haut de tous les files. Cela force la déclaration des variables et réduit le risque qu'une faute de frappe crée une variable par inadvertance à la volée.

VB6 a un système de type cassé – en fait, il a deux systèmes de type qui ne sont pas totalement compatibles. Architecturalement, VB4-6 est un wrapper assez mince sur COM, et utilise le système de type COM. Les versions précédentes de VB avaient leur propre système de type, qui était en quelque sorte un croisement entre le BASIC traditionnel et le C. Les deux ne peuvent pas être librement mélangés et appariés.

Il n'y a pas d'inheritance et pas de gestion des exceptions réelles, alors attendez-vous à écrire beaucoup de code standard pour la gestion des erreurs et les fonctions de base de forme répétées encore et encore. C'est ici que VB obtient sa réputation pour l'ingénierie logicielle couper-coller.

Certains des types que vous pouvez déclarer dans VB ne sont pas 'compatibles avec l'automation', ce qui signifie qu'ils ne peuvent pas être sérialisés sur une limite COM ou stockés dans un Variant (plus sur ces derniers). Ces types remontent aux jours précédant VB4-6 lorsque VB ne prenait pas en charge COM. Un de ces types est un type d'logging (comme ac struct) dont le nom m'échappe, donc une collection extensible ou un tableau associatif de structs (ce qui est une chose naturelle que l'on pourrait vouloir faire) n'est pas possible. Définir une class (voir ci-dessous) est possible mais quelque peu maladroit.

VB ne prend pas en charge le multi-threading, et les solutions de contournement pour cela ont beaucoup de pièges. Le premier risque de vous mordre si vous faites du développement à trois niveaux en utilisant MTS ou COM +. Créer un module VB crée en fait un object COM singleton dans les coulisses. Cela vivra dans son propre appartement à un seul thread. Les appartements sont essentiellement légers et exécutent des servers COM avec un mécanisme de serialization / déserialization (appelé une pompe de message) où les appels sont sérialisés et mis en queue pour un seul thread. Si vous faites quelque chose de sensé (à la surface) et que vous essayez de modulariser votre code, vous créerez des points chauds dans votre niveau intermédiaire. La solution: plus de couper et coller.

Le deuxième point important est que la garbage collection de COM est plutôt basique – un simple mécanisme de comptage des references. Cela signifie que les composants COM qui se bloquent ou pour une raison quelconque ne rangeront pas eux-mêmes après la memory de fuite. Rappelez-vous comment VB6 est juste une couche mince sur COM? Ce couplage étroit signifie que vous devez être assez prudent lorsque vous utilisez le code de gestion de l'interface user qui contient des references aux controls, l'automation OLE sur des applications externes (par exemple Excel) ou toute autre chose qui configure des references. VB est assez bon pour faire des choses cachées derrière votre dos et ne pas savoir quand nettoyer après lui-même. C'est aussi une source de references circulaires générées en coulisses. Faites-en une erreur et il y aura des fuites de ressources – vous devez faire attention à ce sujet.

L'autre gotcha majeur est Variants. La meilleure description que j'ai vue pour un type Variant est une 'Spreadsheet Cell'. Ceux-ci peuvent causer beaucoup de méfaits, en particulier Variant Arrays. De nombreuses API ne fonctionnent qu'avec des variantes ou ont des parties randoms qui utilisent des variantes (Excel le fait beaucoup), donc vous ne pourrez pas toujours les éviter. Si vous êtes en train de sérialiser des choses sur les limites COM (par exemple plusieurs jeux d'loggings déconnectés), vous apprendrez bientôt à détester les arrays de variantes.

Vous findez probablement que le système de type de VB est tellement cassé que le moyen le plus simple de maintenir une structure de données non sortingvialement complexe est de faire une bibliothèque qui l'encode dans une string et la sérialise et la désérialise essentiellement. Les data structures complexes dans une application VB6 sont presque un non-démarreur.

Enfin, après avoir utilisé la boîte à outils GUI pour VB6, vous apprendrez à quel point WinForms a appris des erreurs de l'équipe VB6.

Bien qu'il ait été promu comme étant simple et facile à utiliser, la construction d'une application non sortingviale dans VB sans faire de gâchis était beaucoup plus difficile qu'il n'y paraissait à cause de tous les défauts architecturaux et de petits pièges. C'est un bon exemple de la loi de Spolsky sur les abstractions baveuses. .

Le développement de composants COM / ActiveX par Appleman dans Visual Basic 6 traite assez bien les tenants et les aboutissants de l'interaction de COM avec VB6. Il a également fait un bon travail sur la programmation Win32 et VB. .

PS (merci de me callbacker Daok), si vous trouvez que quelqu'un a utilisé On Error Resume Next , vous avez ma permission de les bash .

Depuis que je me suis cassé les dents sur Visual Basic (le CV dit VB3-6 10+ ans), je vais essayer de répondre à votre question avec autre chose que "On Error Resume Next" (ce qui est le cas, mais vous le findez partout, ou vous ne serez pas, ce qui est pire). Voici quelques choses que vous pouvez faire:

  1. Lorsque vous prenez en charge un projet VB, le plus difficile est généralement de le comstackr sur votre machine. Cela est souvent dû à des references brisées à des choses qui ont été installées sur la machine du développeur d'origine mais pas sur les vôtres (aka "DLL Hell"). Vous pouvez seulement espérer que les programmes d'installation existent encore quelque part, ou sinon vous pouvez toujours avoir recours à l'abandon des DLL et des OCX dans le directory système (n'oubliez pas de les save). Parfois, la DLL Hell provient de references internes brisées. Les développeurs VB aimaient généralement split les applications en autant de projets de composants différents que possible. Souvent, la plupart ou la totalité de vos problèmes de compatibilité disparaissent lorsque vous combinez tout dans le projet sacrément il aurait dû être en premier lieu.
  2. Une fois que tout se comstack, vous êtes à 99% là-bas. La plupart des problèmes communs mentionnés dans les messages ici sont le genre de problèmes qui se manifestent dans une application immédiatement. Si l'application dont vous avez hérité est une application simple et fiable qui a fredonné tranquillement toutes ces années (c'est arrivé en VB), vous allez probablement vous sentir bien.
  3. Une fois que vous avez compilé l'application et que vous travaillez à partir de l'EDI (je pense que c'est ce qu'on appelait à l'époque), vous pouvez commencer à expérimenter de petits changements ici et là.
  4. Postez vos problèmes ici . C'est amusant de se souvenir du passé.

En ce qui concerne Visual Basic en général, je dirais ne pas croire l'anti-hype. C'était un langage qui permettait un bon code ou un mauvais code, un peu comme les autres. Et callbackez-vous que tous les horribles programmeurs VB sont maintenant des programmeurs C # terribles.

N'utilisez pas " En cas d'erreur ".

Si votre application utilise des projets DLL ActiveX, alors vous vous assurez que c'est la situation pour minimiser l'enfer DLL

  • Définissez votre DLL sur BinaryCompatibility.
  • Assurez-vous que vous avez un directory compatible.
  • Mettez la DLL de la dernière version ici.
  • Pointez la compatibilité binary vers cette DLL.
  • Assurez-vous que votre EXE et DLL comstack dans son directory de projet.
  • Exécutez le file EXE à partir de son directory de projet lorsque vous testez. De cette façon, il utilisera la DLL que vous avez compilée.
  • Vous devez écrire un utilitaire pour pouvoir comstackr chaque projet séparément dans le bon ordre. Le compilateur VB6 peut être exécuté à partir de la command line.
  • Testez votre configuration en utilisant Virtual PC ou un autre ordinateur.

Malgré le manque d'inheritance, vous findez que VB6 est capable de mettre en œuvre de nombreux templates de design orientés object courants. Si vous regardez dans les templates de design, des éléments de logiciel orienté object réutilisable, vous verrez que la plupart des templates impliquent l'implémentation de l'interface plutôt que l'inheritance du comportement. Ils parlent de ce problème à partir de la page 16.

Les collections fortement typées ne sont pas simples à implémenter, vous écrivez la collection avec tout, y compris une propriété Item readonly. Lorsque vous avez terminé, vous devez appuyer sur {F2} et afficher le browser d'objects. Trouvez la class de collection que vous avez créée et faites un clic droit sur Item.

Tu devras

  • Sélectionnez properties
  • Cliquez sur le button Avancé
  • Modifier l'ID de procédure par défaut

Alors Item deviendra la propriété par défaut et la collection de type Strongly agira comme prévu.

Pour activer l'utilisation de la class For Each sur la collection, vous devez append cette

 Public Property Get NewEnum() As IUnknown Set NewEnum = mCol.[_NewEnum] End Property 

Avec mCol étant le nom de la variable Collection privée

Encore une fois, utilisez le browser d'objects et faites un clic droit sur NewEnum.

Tu devras

  • Sélectionnez properties
  • Cliquez sur le button Avancé
  • Remplacez l'ID de procédure par -4

Rappelez-vous que Integer est 16 bits et Long est 32 bits. Je recommand de déclarer la plupart des variables entières comme Long. De return dans la journée, il était important pour la vitesse et l'empreinte de la memory, mais avec les ordinateurs d'aujourd'hui, il vaut mieux utiliser Long et ne pas s'inquiéter de dépasser les limites.

Comme suggéré ailleurs, utilisez Option Explicit.

Visual Basic 6 est très bon pour la conversion de type implicite. Vous avez la série de fonctions de conversion Cxxx si vous voulez être sûr.

Variante est meilleure que l'object .NET à traiter avec une gamme variée de types d'objects, y compris les classs. Vous pouvez find utile si vous devez créer un formulaire personnalisé traitant de la database et l'user peut choisir quelle table utiliser pour ce formulaire. L'utilisation de Variant facilite la gestion du fait que les champs sont de types différents pour différentes tables.

Visual Basic 6 peut être utilisé pour créer des applications à plusieurs niveaux. Les formulaires peuvent implémenter des interfaces comme les classs peuvent.

N'oubliez pas que les controls ActiveX s'exécutent lorsque vous comstackz et modifiez un formulaire. Cela peut causer toutes sortes d'étrangeté si vous n'êtes pas au courant. Ceci est particulièrement problématique si vous avez vos propres controls ActiveX.

Plutôt utiliser on error resume next de l' on error goto X , mais TOUJOURS attraper des erreurs tout de suite, puis réinitialiser la gestion des erreurs.

Exemple:

 ... On Error Resume Next oDbConn.Open sDbConnSsortingng Select Case Err.Number Case &H80004005 MsgBox "Cannot connect to SQL-server, check your settings." frmSettings.Show Exit Sub Case Else ShowErrorAndQuit Err End Select On Error Goto 0 ... 

La sagesse générale lors de la déclaration d'objects était d'éviter d'utiliser "Dim myObj As New MyClass". Au lieu de cela, utilisez "Dim myObj As MyClass" et instanciez explicitement l'object en cas de besoin avec "Set myObj = New MyClass". La première méthode n'instancie pas l'object lorsque "Dim" est rencontré, mais le fait automatiquement la première fois que l'une des propriétés ou methods de l'object est référencée. Cela nécessite une surcharge supplémentaire de la part de l'exécution car elle doit vérifier si l'object existe avant chaque reference de propriété / méthode. En outre, il y avait quelques autres effets secondaires bizarres de cette méthode de déclaration d'object. Par exemple, si myObj est défini sur Nothing et que le programme rencontre une autre reference, une nouvelle instance est créée automatiquement. Les chances sont que si cette situation se produit, quelque chose ne va pas avec votre programme, mais il n'y aura pas d'erreur générée vous disant que votre object n'existe pas, ce qui peut conduire à certains difficiles à traquer les bogues. Généralement, il est préférable de créer et de détruire explicitement l'instance d'object en utilisant la syntaxe "Set = New". Les partisans de la syntaxe «Dim As New» citent généralement une meilleure lisibilité, mais ses pièges potentiels peuvent parfois vous surprendre.

Les personnes qui ont posté ici et ont dit que "Sur l'erreur Resume Next" est la plus mauvaise caractéristique de langue jamais sont fausses.

La pire caractéristique de la langue était " On Error Resume ". Fais moi confiance pour ce coup là.

Pour le VB-impaired, On Error Resume Next signifie "quelque chose s'est mal passé, sur la ligne suivante". Sur Error Resume signifie "quelque chose s'est mal passé, mieux vaut l'essayer encore et encore et encore et encore et …".

Personnellement, j'aime l' On Error goto ErrorHandler , avec un gestionnaire d'erreur au bas de chaque fonction.

N'oubliez pas de ne jamais inclure de parenthèses lors de l'appel d'une méthode, à less que vous ne regardiez sa valeur de return. Il est facile de s'en tirer avec des methods à un argument, mais parfois cela vous mord, car passer (variable) n'est pas la même chose que passer une variable.

Les gens écrivant VB n'étaient pas tout à fait sûrs s'ils préféraient des arrays indexés 0 ou des arrays 1 indexés. Vous pouvez utiliser UBound / LBound pour vérifier où un tableau commence et se termine.

N'utilisez pas "textcomparison" pour convertir un cas. Comparer les strings comme du text fait plus qu'ignorer simplement le cas. Convertissez simplement une ou les deux strings en majuscules.

Projets-> properties-> Supprimer les informations sur les controls ActiveX inutilisés doivent être désactivés si vous les appelez lors de l'exécution.

devises-> Éditeur-> Vérification automatique de la syntaxe. Si vous n'êtes pas habitué, peut-être l'éteindre.

devises-> Éditeur-> Exiger une déclaration de variable. Sur.

devises-> Environnement-> Lorsqu'un programme démarre-> Enregistrer les modifications. Si cette option est désactivée, votre programme ne sera pas sauvegardé même si vous l'exécutez.

Utilisez Exécuter-> Démarrer avec la compilation complète, pas Exécuter-> Démarrer, pour exécuter votre code.

N'utilisez pas On Error Resume Next sauf si nécessaire (il existe des cas uniques, comme le nettoyage final après le error handling ou la vérification de l'existence des éléments VB Collection, mais généralement vous n'en avez pas besoin dans le corps de la fonction).

Implémentez la gestion des erreurs appropriée, n'utilisez pas plus d'un sharepoint sortie, n'utilisez pas If-Then one-liners, utilisez le bloc Case Else, n'utilisez pas Subs – quelque chose comme la fonction skeletion suivante:

 Private Function MyFunc() As Boolean On Error Goto ErrHandler ''some code here If SomeBadExitConditionIsSet Then GoTo FuncExit End If ''some more code here MyFunc = True FuncExit: ''kill error handling to avoid error cycling On Error Resume Next ''cleanup code here - you need to check Err.Number after critical operations! ''single exit point Exit Function ErrHandler: ''you can insert local specific error processing here, do not forget save Err.Number etc ''there is possibility to raise errors to caller function, ''but in this function we do not do that Select Case MyGlobalErrHandler(Err.Number, Err.Description) Case eRetry Resume ''this is useful while debugging - good place to "Set Next Statement" Case eIgnore Resume Next Case eCancel Resume FuncExit Case Else Resume FuncExit Select End End Function