vb@rchiv
VB Classic
VB.NET
ADO.NET
VBA
C#
sevDataGrid - Gönnen Sie Ihrem SQL-Kommando diesen krönenden Abschluß!  
 vb@rchiv Quick-Search: Suche startenErweiterte Suche starten   Impressum  | Datenschutz  | vb@rchiv CD Vol.6  | Shop Copyright ©2000-2024
 
zurück
Rubrik: Controls · TextBox & RichTextBox   |   VB-Versionen: VB201015.04.11
Textbox mit Funktion zur Formelberechnung

TextboxCompute ist ein von Windows.Forms.Textbox abgeleitetes Control, das Formeln ausgewerten kann (CodeDom).

Autor:   Manfred BohnBewertung:     [ Jetzt bewerten ]Views:  12.956 
ohne HomepageSystem:  Win2k, WinXP, Win7, Win8, Win10, Win11 Beispielprojekt auf CD 

Die Klasse "TextboxCompute" ist von Windows.Forms.TextBox abgeleitet. Das Control ermöglicht die Eingabe numerischer Werte als Formel und wertet sie aus.
Die Betätigung der Taste "Return" veranlasst die Auswertung des eingegebenen Strings (in der Text-Eigenschaft des Control). Im Erfolgsfall wird die Text-Eigenschaft durch das Ergebnis der Auswertung überschrieben. Im Fehlerfall bleibt die Eigenschaft unverändert.

Nachdem die Klasse dem Projekt hinzugefügt und das Projekt übersetzt worden ist, steht das Control in der Toolbox zur Verfügung.

Der Eigenschaft "Errorlabel" kann ein Label zugewiesen werden. Ggf. wird die erste Fehlermeldung beim Kompilieren des eingegebenen Strings angezeigt. Sinnvoll ist das nur, wenn ausschließlich numerische Eingaben in der TextBoxCompute-Instanz zugelassen sind.
(Es werden im Errorlabel Syntaxfehler oder fehlende Deklarationen gemeldet, falls eine nicht-numerische Eingabe erfolgt ist).

Die Eigenschaft "Digits" erlaubt die Festlegung, auf wie viele Nachkommastellen das Ergebnis der ausgewerteten Formel gerundet werden soll, bevor es in die Text-Eigenschaft übertragen wird.

Der zuletzt eingegebene String (vor erfolgreicher Auswertung) kann durch die schreibgeschützte Eigenschaft "GetLastString" abgefragt werden.

Details:
Die eingegebenen Zahlen werden als Double-Werte verarbeitet. Sollte eine Auswertung scheitern oder ein IEEE-Sonderwert im Ergebnis resultieren, wird der eingegebene String nicht geändert. Das optionale Errorlabel enthält eine entsprechende Information.

Die Exponentialdarstellung von Werten ist möglich. Es werden implizite Erweiterungs-Konvertierungen der eingegebenen Ziffernfolgen in den Datentyp Double vorgenommen - dabei kann es zu Genauigkeitsverlusten kommen. Die Operatoren für Ganzzahl-Division und für Mod-Division stehen zur Verfügung.

Beim Kompilieren der Formel wird der Namespace "System.Math" importiert. Im Textfeld können deshalb mathematische Funktionen wie Abs, Log, Sqrt, Sin oder Truncate (syntaktisch korrekt) verwendet werden.

Funktionen wie INT, FIX, VAL stehen nicht zur Verfügung, weil sie im Namespace Microsoft.VisualBasic" angesiedelt sind. Die entsprechende Import-Anweisung kann bei Bedarf im Code eingefügt werden.

Die Formel wird direkt übersetzt. VB verarbeitet als Dezimalpunkt den US-Dezimalpunkt. Aus diesem Grund wird der kulturspezifische Dezimalpunkt vor dem Kompilieren entsprechend umgewandelt. Es werden BEIDE Zeichen intern als Dezimalpunkt verarbeitet. (Wegen dieser Ersetzung ist z.B. die Pow-Funktion in der Eingabe nicht verwendbar!)

Bei Zuweisung eines Auswertungs-Resultats auf die Text-Eigenschaft wird das "TextChanged"-Event der Instanz ausgelöst.

Das Control kann auch als Multiline-Textbox verwendet werden, aber eingefügte Zeilenumbrüche werden als Fehler gewertet. Das VB-Zeilenfortsetzungszeichen wird akzeptiert.

Option Strict On
Option Explicit On
Option Infer Off
 
Imports System.CodeDom.Compiler
 
Public Class TextboxCompute
  Inherits Windows.Forms.TextBox
  Const cNL As String = Microsoft.VisualBasic.vbNewLine
 
  Private _dezimalpunkt As String = _
  Globalization.CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator
  Const cStd_Dezimale As String = "."            ' VB-Standard-Dezimalpunkt
 
  Private _errorlabel As Windows.Forms.Label     ' Anzeige der ersten Fehlermeldung
  Private _digits As Integer = 4                 ' Ergebnisrundung, Nachkommastellen
  Private _LastString As String = String.Empty   ' Text-Eigenschaft vor Auswertung
 
  Protected Overrides Sub OnKeyDown(ByVal e As System.Windows.Forms.KeyEventArgs)
    _LastString = String.Empty
    If _errorlabel IsNot Nothing Then _errorlabel.Text = String.Empty
    If e.KeyCode = Keys.Return Then
      If Not String.IsNullOrWhiteSpace(Me.Text) Then
        Dim itext As String = Me.Text
 
        ' Standard-Dezimalpunkt einrichten
        itext = itext.Replace(_dezimalpunkt, cStd_Dezimale)
 
        ' Zusammenstellung des Codes der Assembly für die Berechnung
        Dim CCode As String = _
        "Option Strict On : Option Explicit On : Option Infer Off" & cNL & _
        "Imports System.Math" & cNL & _
        "NameSpace nsComputeFormula" & cNL & _
        "Public Class ComputeFormula" & cNL & _
        "Public Function Compute() as Double?" & cNL & _
        "Dim erg? as Double = " & itext & cNL & _
         "Return erg" & cNL & _
         "End Function" & cNL & "End Class" & cNL & "End NameSpace"
 
        Dim myAsm As System.Reflection.Assembly = _
        CreateAssemblyFromCode(CCode)
        If Not myAsm Is Nothing Then
          Dim myCls As Object = _
          myAsm.CreateInstance("nsComputeFormula.ComputeFormula")
 
          ' Zugriff auf die Berechnungsmethode in der Klasse 
          Dim myMethod As System.Reflection.MethodInfo = _
          myCls.GetType.GetMethod("Compute")
          Dim erg? As Double = CType(myMethod.Invoke(myCls, Nothing), Double?)
 
          If erg.HasValue Then
            Dim ierg As Double = erg.Value
            If Not Double.IsNaN(ierg) And Not Double.IsInfinity(ierg) Then
              _LastString = Me.Text ' Originalstring speichern
              Me.Text = CStr(Math.Round(ierg, _digits))
              Me.SelectionStart = Me.TextLength
            ElseIf _errorlabel IsNot Nothing Then
              _errorlabel.Text = "Ergebnis enthält IEEE-Sonderwert: " & CStr(ierg)
            End If
          End If  ' HasValue?
        End If ' ASM <> nothing?
      End If ' String.Isnullorwhitespace?
    End If  ' Keycode = Keys.Return?
 
    MyBase.OnKeyDown(e)
  End Sub
 
  Private Function CreateAssemblyFromCode(ByVal Code As String) As  _
    System.Reflection.Assembly
 
    ' Assembly aus VB.NET-Sourcecode in  Codestring erstellen
 
    Dim VB_CP As CodeDomProvider = _
    New Microsoft.VisualBasic.VBCodeProvider()
 
    Dim ComParams As New CompilerParameters() _
    With {.GenerateInMemory = True}
 
    ' Code Compilieren und das Compiler-Ergebnis ermitteln
    Dim ComResults As CompilerResults = _
    VB_CP.CompileAssemblyFromSource(ComParams, Code)
    VB_CP.Dispose()
    If ComResults.Errors.Count > 0 Then
      If _errorlabel IsNot Nothing Then
        _errorlabel.Text = ComResults.Errors(0).ErrorText
      End If
      Return Nothing
    Else
      Return ComResults.CompiledAssembly
    End If
  End Function
 
  ''' <summary>Optional: Label für die erste Compiler-Fehlermeldung</summary>
  Public Property Errorlabel() As Label
    Set(ByVal value As Label)
      _errorlabel = value
    End Set
    Get
      Return _errorlabel
    End Get
  End Property
 
  ''' <summary>Optional: Nachkommastellen für Ergebnisrundung</summary>
  Public Property Digits As Integer
    Set(ByVal value As Integer)
      If value < 0 Or value > 12 Then value = 4
      _digits = value
    End Set
    Get
      Return _digits
    End Get
  End Property
 
  ''' <summary>Inhalt der Text-Eigenschaft vor der erfolgreichen Auswertung</summary>
  Public ReadOnly Property GetLastString() As String
    Get
      Return _LastString
    End Get
  End Property
End Class

Dieser Tipp wurde bereits 12.956 mal aufgerufen.

Voriger Tipp   |   Zufälliger Tipp   |   Nächster Tipp

Über diesen Tipp im Forum diskutieren
Haben Sie Fragen oder Anregungen zu diesem Tipp, können Sie gerne mit anderen darüber in unserem Forum diskutieren.

Neue Diskussion eröffnen

nach obenzurück


Anzeige

Kauftipp Unser Dauerbrenner!Diesen und auch alle anderen Tipps & Tricks finden Sie auch auf unserer aktuellen vb@rchiv  Vol.6
(einschl. Beispielprojekt!)

Ein absolutes Muss - Geballtes Wissen aus mehr als 8 Jahren vb@rchiv!
- nahezu alle Tipps & Tricks und Workshops mit Beispielprojekten
- Symbol-Galerie mit mehr als 3.200 Icons im modernen Look
Weitere Infos - 4 Entwickler-Vollversionen (u.a. sevFTP für .NET), Online-Update-Funktion u.v.m.
 
   

Druckansicht Druckansicht Copyright ©2000-2024 vb@rchiv Dieter Otter
Alle Rechte vorbehalten.
Microsoft, Windows und Visual Basic sind entweder eingetragene Marken oder Marken der Microsoft Corporation in den USA und/oder anderen Ländern. Weitere auf dieser Homepage aufgeführten Produkt- und Firmennamen können geschützte Marken ihrer jeweiligen Inhaber sein.

Diese Seiten wurden optimiert für eine Bildschirmauflösung von mind. 1280x1024 Pixel