Da es immer wieder Umsteiger von VB6 oder Leute, die versuchen, ein VB6-Buch auf VB.NET anzuwenden, gibt, fasse ich hier mal die bösen, veralteten VB6-Funktionen zusammen, die es noch in VB.NET gibt, samt ihrer korrekten Alternativen.
Warum sollte man die VB6-Funktionen nicht weiterverwenden?
Sie sind veraltet. Sie verhalten sich anders. Sie sind nicht standardkonform in der .NET-Umgebung (sie sind standardkonform zu VB6) und lassen sich daher nicht einfach in C# konvertieren. Sie führen zu Code, welcher grundlegende Gesetze der objektorientierten Programmierung verletzt.
Leider basieren viele Tutorials, Snippets und Forenbeiträge immer noch auf diesen veralteten Funktionen und auch der automatische Import des Microsoft.VisualBasic-Namespaces (in welchem diese ganzen Funktionen liegen) macht es dem Anfänger schwierig zu erkennen, dass man diese Funktionen nicht verwenden sollte. Ein "Veraltet"-Hinweis ("deprecated") im IntelliSense wäre wünschenswert.
By the way: Einige VB6-Funktionen (vor allem mathematische) wurden aus VB.NET schon durch deren Pendants Math.Funktion() ersetzt.
Die "bösen" Funktionen:
Sortiert nach Kategorien (vielen Dank an ErfinderDesRades):
Spoiler anzeigen
Alphabetisch sortiert:
Spoiler anzeigen
Böse Operatoren:
EDR hat dazu einen Artikel geschrieben: vb-paradise.de/t/91397-
Wer noch etwas hinzufügen möchte oder bemerkt, dass etwas nicht stimmt, einfach eine PN an mich!
lg SeriTools
Warum sollte man die VB6-Funktionen nicht weiterverwenden?
Sie sind veraltet. Sie verhalten sich anders. Sie sind nicht standardkonform in der .NET-Umgebung (sie sind standardkonform zu VB6) und lassen sich daher nicht einfach in C# konvertieren. Sie führen zu Code, welcher grundlegende Gesetze der objektorientierten Programmierung verletzt.
Leider basieren viele Tutorials, Snippets und Forenbeiträge immer noch auf diesen veralteten Funktionen und auch der automatische Import des Microsoft.VisualBasic-Namespaces (in welchem diese ganzen Funktionen liegen) macht es dem Anfänger schwierig zu erkennen, dass man diese Funktionen nicht verwenden sollte. Ein "Veraltet"-Hinweis ("deprecated") im IntelliSense wäre wünschenswert.
By the way: Einige VB6-Funktionen (vor allem mathematische) wurden aus VB.NET schon durch deren Pendants Math.Funktion() ersetzt.
Die "bösen" Funktionen:
Sortiert nach Kategorien (vielen Dank an ErfinderDesRades):
- keine böse Funktion
(Ehe ich zB. eine Methode selber schreibe, nehme ich lieber Funktionen aus dem VisualBasic-Namespace.)
- AscW() - .NET: bei konstantem Parameter: AscW(), ansonsten: System.Convert.ToInt16()
- AppActivate() - .NET: Leider keine einfache Alternative, da AppActivate() wohl direkt auf die WINAPI zugreift.
- InputBox() - .NET: Eigenen Dialog verwenden, viel mehr Möglichkeiten
- StrReverse() - .NET: selber schreiben (wenn man denn sowas eigenartiges je braucht).
- MsgBox() - .NET: System.Windows.Forms.MessageBox.Show() IMO: egal ob MessageBox oder MsgBox: schlecht von der Experience her. Also setzt man es ein, wo es selten gebraucht wird, und der Aufwand eines ordentlichen Dialoges auf später vertagt werden kann.
- CreateObject("Com.Object.Name") - .NET: System.Activator.CreateInstance(System.Type.GetTypeFromProgID("Com.Object.Name"))
- GetObject() - .NET: z.B.: codeproject.com/KB/cs/CSGetObject.aspx
- AscW() - .NET: bei konstantem Parameter: AscW(), ansonsten: System.Convert.ToInt16()
- Auflistungen
- IsArray() - .NET: Typvergleich ausführen
- LBound() - .NET: Array.GetLowerBound()
- UBound() - .NET: Array.GetUpperBound()
- ReDim - .NET: Verwendung von AuflistungsKlassen, wie List(Of T)
- ArrayList - .NET: List(Of T)
- Collection (VB6) - .NET: List(Of T) oder Dictionary(Of TKey, TValue)
- HashTable (VB2003) - UNTYPISIERT! .NET: Dictionary(Of TKey, TValue)
- Reflection
- CallByName() - .NET: Late Binding ist schlecht! Es würde über System.Refelection gehen.
- SystemTypeName() - .NET: unnötig
- TypeName() - .NET: .GetType.Name/FullName()
- VarType(), VbTypeName() - .NET: unnötig.
- CallByName() - .NET: Late Binding ist schlecht! Es würde über System.Refelection gehen.
- File-Handling
- ChDir() bzw. ChDrive() - .NET: System.IO.Directory.SetCurrentDirectory() bzw. Eigenschaft System.Environment.CurrentDirectory() setzen
- CurDir() - .NET: System.IO.Directory.GetCurrentDirectory() bzw. Eigenschaft System.Environment.CurrentDirectory() auslesen
- Dir() - .NET: System.IO.GetDirectoryInfo() und die dazugehörigen Klassen verwenden.
- File*(), FileSystemObject, EOF(), FreeFile(), Input(), Loc(), Lock() etc., also Dateizugriff in VB6 - .NET: System.IO-Namespace benutzen
- Kill() - .NET: System.IO.File.Delete()
- MkDir() - .NET: System.IO.Directory.CreateDirectory()
- Rename() - .NET: System.IO.File/Directory.Move()
- RmDir() - .NET: System.IO.Directory.Delete()
- & und annere String-Operationen mit Dateipfaden - .NET: System.IO.Path.Combine und annere Path-Methoden nutzen
- ChDir() bzw. ChDrive() - .NET: System.IO.Directory.SetCurrentDirectory() bzw. Eigenschaft System.Environment.CurrentDirectory() setzen
- Fehlerbehandlung
- On Error GoTo ... - .NET: TryCatch - Konzept verwenden
- ErrorToString() - .NET: TryCatch - Konzept verwenden
- GetException() - .NET: TryCatch - Konzept verwenden
- On Error GoTo ... - .NET: TryCatch - Konzept verwenden
- Strings
- Asc() - .NET: bei konstantem Parameter: AscW(), ansonsten: System.Convert.ToInt16() für UTF-8, bei anderen Encodings msdn.microsoft.com/en-us/library/5881c0k9.aspx
- Chr() - .NET: bei konstantem Parameter: ChrW(), ansonsten: System.Convert.ToChar() für UTF-8, bei anderen Encodings msdn.microsoft.com/en-us/library/khac988h.aspx
- CBool(), CByte(), CChar(), CDate(), CDbl(), CDec(), CInt(), CLng(), CObj(), CSByte(), CShort(), CSng(), CStr(), CUInt(), CULng(), CUShort() - diese Schlüsselworte sind i.a. sehr performant - bei Konstanten werden sie zT. schon vom Compiler ausgewertet und nehmen zur Laufzeit keine Rechenzeit in Anspruch.
sie sind aber nicht dazu konzipiert, um von String zu konvertieren - dafür sind die Parse-Functions des ZielTypen vorgesehen (DateTime.Parse(), Boolean.Parse(), ...). - Format(), Format* - .NET: System.String.Format()
- GetChar() - .NET: deinString(index) bzw. deinString.Char(index)
- InStr() - .NET: String.Contains() bzw. String.IndexOf()
- InStrRev() - .NET: String.LastIndexOf()
- IsDBNull() - .NET: DataRow.IsNull(), DataReader.IsDbNull(), Convert.IsDbNull()
- IsNumeric(), IsDate() etc. - .NET: Integer/Double/Date/.TryParse()
- Join() - .NET: String.Join() oder string &= "...", bei vielen Verkettungen ist ein StringBuilder empfehlenswert.
- LCase() - .NET: String.ToLower()
- Left(), Right(), Mid() - .NET: String.Substring()
- Len() - .NET: String.Length()
- LTrim() - .NET: String.TrimStart(Nothing)
- LSet(), RSet(), Space() - .NET: String.PadLeft()/PadRight()
- Oct(), Hex() - .NET: Convert.ToString(value,8) (oktal), Convert.ToString(value,16) (hexadezimal), s.a. Convert.ToString(value,2) (binär)
- Replace() - .NET: String.Replace()
- Split() - .NET: String.Split()
- Str() - .NET: .ToString()
- StrComp() - .NET: String.Compare() / String.CompareTo()
- StrConv(conv) - .NET: im nicht-asiatischen Sprachraum unnötig - einzig mit VbStrConv.ProperCase als Parameter manchmal sinnvoll
- StrDup() - .NET: String.Pad-Left/-Right, oder zB: New String(" "c, 20) erzeugt einen String mit 20 Spaces.
- UCase() - .NET: String.ToUpper()
- Val() - .NET: explizite Typkonvertierung durchführen (z.B. .ToString())
- Asc() - .NET: bei konstantem Parameter: AscW(), ansonsten: System.Convert.ToInt16() für UTF-8, bei anderen Encodings msdn.microsoft.com/en-us/library/5881c0k9.aspx
- Sonstige: die Aufzählung versucht nach Wichtigkeit geordnet zu sein
- Date...(), Day(), Hour() etc. - .NET: Die Klassen System.DateTime und System.TimeSpan bieten alle Funktionalität, die man sich zur Behandlung von Zeit-Werten nur wünschen kann - Zeiten-Handling ist im Grunde ein ähnlich komplexer Bereich wie das String-Handling
- Or / And - .NET: OrElse / AndAlso
- IIf() - .NET: If(expression, TruePart, FalsePart) oder If(expression, FalsePart)
- Shell() - .NET: System.Diagnostics.Process.Start()
- Command() - .NET: System.Environment.CommandLine()
- Environ() - .NET: System.Environment.GetEnvironmentVariable()
- *Setting(), GetAllSettings() - .NET: Microsoft.Win32.Registry/RegistryKey benutzen
- Randomize(), Rnd() - .NET: System.Random benutzen.
- Choose(index, variable) - .NET: variable(index) oder (bei manchen Listen o.ä.) variable.Item(index)
- Beep() - .NET: Keine äquivaltente Methode (benutzt WINAPI), außer für Konsolenfenster: System.Console.Beep() - Achtung: Funktioniert nicht auf XP x64/Vista x64, wurde in Windows 7 gelöst.
- DDB() - .NET: Folgende Formel anstatt Parameter benutzen: Depreciation / Period = ((Cost – Salvage) * Factor) / Life
- Filter() - .NET: Keine direkte Entsprechung
- Fix(), Int() - .NET: System.Math.Truncate()
- FV() - .NET: selber berechnen.
- Hex() - .NET: Convert.ToString(value,16)
- IPmt() - .NET: selber berechnen.
- IRR() - .NET: selber berechnen.
- IsNothing() - .NET: If variable Is Nothing Then [...]
- MIRR() - .NET: selber berechnen.
- NPer() - .NET: selber berechnen.
- NPV() - .NET: selber berechnen.
- Pmt(), PPmt(), PV() - .NET: selber berechnen.
- QBColor() - .NET: unnötig.
- Rate() - .NET: selber berechnen.
- RGB() - .NET: Color-Klasse benutzen.
- SLN() - .NET: selber berechnen.
- Switch() - .NET: Switch benutzen bzw. While oder For
- SYD() - .NET: selber berechnen.
- Date...(), Day(), Hour() etc. - .NET: Die Klassen System.DateTime und System.TimeSpan bieten alle Funktionalität, die man sich zur Behandlung von Zeit-Werten nur wünschen kann - Zeiten-Handling ist im Grunde ein ähnlich komplexer Bereich wie das String-Handling
Alphabetisch sortiert:
- AppActivate() - .NET: Leider keine einfache Alternative, da AppActivate() wohl direkt auf die WINAPI zugreift.
- Asc() - .NET: Keine direkte Entsprechung, da Asc() nur ASCII-Werte verarbeiten kann und VB.NET vollkommen auf Unicode basiert. Möglicherweise mit System.Convert.ToByte()
- AscW() - .NET: bei konstantem Parameter: AscW(), ansonsten: System.Convert.ToInt16()
- Beep() - .NET: Keine äquivaltente Methode (benutzt WINAPI), außer für Konsolenfenster: System.Console.Beep() - Achtung: Funktioniert nicht auf XP x64/Vista x64, wurde in Windows 7 gelöst.
- CallByName() - .NET: Late Binding ist schlecht! Es würde über System.Refelection gehen.
- CBool(), CByte(), CChar(), CDate(), CDbl(), CDec(), CInt(), CLng(), CObj(), CSByte(), CShort(), CSng(), CStr(), CUInt(), CULng(), CUShort() - .NET: bei konstantem Parameter: CBool() etc. weiterbenutzen; bei variablem Parameter: System.Convert.ToDatentyp() / variable.ToString(), wobei Datentyp für den .NET-Datentyp steht, nicht für eine Abkürzung wie in CLng für Long.
- ChDir() bzw. ChDrive() - .NET: System.IO.Directory.SetCurrentDirectory() bzw. Eigenschaft System.Environment.CurrentDirectory() setzen
- Choose(index, variable) - .NET: variable(index) oder (bei manchen Listen o.ä.) variable.Item(index)
- Chr() - .NET: Keine direkte Entsprechung, siehe Asc()
- ChrW() - .NET: bei konstantem Parameter: ChrW(); ansonsten: System.Convert.ToChar()
- Command() - .NET: System.Environment.CommandLine()
- CreateObject("Com.Object.Name") - .NET: System.Activator.CreateInstance(System.Type.GetTypeFromProgID("Com.Object.Name"))
- CurDir() - .NET: System.IO.Directory.GetCurrentDirectory() bzw. Eigenschaft System.Environment.CurrentDirectory() auslesen
- Date...(), Day(), Hour() etc. - .NET: Die Klasse System.DateTime bietet entsprechende Funktionen an. In manchen Fällen kann man auch System.TimeSpan benutzen
- DDB() - .NET: Folgende Formel anstatt Parameter benutzen: Depreciation / Period = ((Cost – Salvage) * Factor) / Life
- *Setting(), GetAllSettings() - .NET: Microsoft.Win32.Registry/RegistryKey benutzen
- Dir() - .NET: System.IO.GetDirectoryInfo() und die dazugehörigen Klassen verwenden.
- Environ() - .NET: System.Environment.GetEnvironmentVariable()
- File*(), FileSystemObject, EOF(), FreeFile(), Input(), Loc(), Lock() etc., also Dateizugriff in VB6 - .NET: System.IO-Namespace benutzen
- ErrorToString() - .NET: Evtl. System.Exception benutzen
- Filter() - .NET: Keine direkte Entsprechung
- Fix(), Int() - .NET: System.Math.Truncate()
- Format(), Format* - .NET: System.String.Format()
- FV() - .NET: selber berechnen.
- GetChar() - .NET: deinString(index) bzw. deinString.Char(index)
- GetException() - .NET: unnötig.
- GetObject() - .NET: z.B.: codeproject.com/KB/cs/CSGetObject.aspx
- HashTable (VB2003) - UNTYPISIERT! .NET: Dictionary(Of TKey, TValue)
- Hex() - .NET: Convert.ToString(value,16)
- IIf() - .NET: If(expression, TruePart, FalsePart) oder If(expression, FalePart)
- InputBox() - .NET: Eigenen Dialog verwenden, viel mehr Möglichkeiten
- InStr() - .NET: String.Contains() bzw. String.IndexOf()
- InStrRev() - .NET: String.LastIndexOf()
- IPmt() - .NET: selber berechnen.
- IRR() - .NET: selber berechnen.
- IsArray() - .NET: Typvergleich ausführen
- IsDBNull() - .NET: DataRow.IsNull(), DataReader.IsDbNull(), Convert.IsDbNull()
- IsNothing() - .NET: If variable Is Nothing Then [...]
- IsNumeric(), IsDate() etc. - .NET: Integer/Double/Date/.TryParse()
- Join() - .NET: String.Join() oder string &= "...", bei vielen Verkettungen ist ein StringBuilder empfehlenswert.
- Kill() - .NET: System.IO.File.Delete()
- LBound() - .NET: Array.GetLowerBound()
- LCase() - .NET: String.ToLower()
- Left(), Right(), Mid() - .NET: String.Substring()
- Len() - .NET: String.Length()
- LSet(), RSet(), Space() - .NET: String.PadLeft()/PadRight()
- LTrim() - .NET: String.TrimStart(Nothing)
- MIRR() - .NET: selber berechnen.
- MkDir() - .NET: System.IO.Directory.CreateDirectory()
- MsgBox() - .NET: System.Windows.Forms.MessageBox.Show() IMO: egal ob MessageBox oder MsgBox: schlecht von der Experience her. Also setzt man es ein, wo es selten gebraucht wird, und der Aufwand eines ordentlichen Dialoges auf später vertagt werden kann.
- NPer() - .NET: selber berechnen.
- NPV() - .NET: selber berechnen.
- Oct() - .NET: Convert.ToString(value,8)
- Pmt(), PPmt(), PV() - .NET: selber berechnen.
- QBColor() - .NET: unnötig.
- Randomize(), Rnd() - .NET: System.Random benutzen.
- Rate() - .NET: selber berechnen.
- ReDim() - .NET: Entweder Array.Resize, wenn es unbedingt sein muss; VIEL besser ist eine List(Of T) anstatt eines Arrays zu benutzen
- Rename() - .NET: System.IO.File/Directory.Move()
- Replace() - .NET: String.Replace()
- RGB() - .NET: Color-Klasse benutzen.
- RmDir() - .NET: System.IO.Directory.Delete()
- Shell() - .NET: System.Diagnostics.Process.Start()
- SLN() - .NET: selber berechnen.
- Split() - .NET: String.Split()
- Str() - .NET: .ToString()
- StrComp() - .NET: kleine If-Abfrage selber schreiben.
- StrConv(), StrDup(), StrReverse() - .NET: selber schreiben.
- Switch() - .NET: Switch benutzen bzw. While oder For
- SYD() - .NET: selber berechnen.
- SystemTypeName() - .NET: unnötig
- TypeName() - .NET: .GetType.Name/FullName()
- UBound() - .NET: Array.GetUpperBound()
- UCase() - .NET: String.ToUpper()
- Val() - .NET: explizite Typkonvertierung durchführen (z.B. .ToString())
- VarType(), VbTypeName() - .NET: unnötig.
Böse Operatoren:
- logisches VB-Like Or/And: Die Operatoren überprüfen immer beide Ausdrücke, auch wenn der erste schon ein Ergebnis liefert, welches den zweiten unnötig macht. Richtig: OrElse/AndAlso: Diese machen es richtig. And und Or sind allerdings hilfreich, wenn der zweite/beide Ausdruck/Ausdrücke aus Funktionsaufrufen besteht und diese ausgeführt werden sollen, egal, wie das Ergebnis lautet.
EDR hat dazu einen Artikel geschrieben: vb-paradise.de/t/91397-
Wer noch etwas hinzufügen möchte oder bemerkt, dass etwas nicht stimmt, einfach eine PN an mich!
lg SeriTools
Dieser Beitrag wurde bereits 29 mal editiert, zuletzt von „SeriTools“ ()