Rubrik: Verschiedenes | VB-Versionen: VB5, VB6 | 15.08.03 |
MS ScriptControl - Code zur Laufzeit kompilieren Code zur Laufzeit kompilieren? Stichwort: EbExecuteLine. Das Dumme an der Funktion "EbExecuteLine" ist jedoch, dass sie nur in der VB-IDE funktioniert. Nun wäre es aber trotzdem ganz nützlich, wenn man Code aus Dateien auslesen und diesen zur Laufzeit kompilieren könnte. Kann man auch! | ||
Autor: Patrick Dinklage | Bewertung: | Views: 33.115 |
Code zur Laufzeit kompilieren? Stichwort: EbExecuteLine. Das Dumme an der Funktion "EbExecuteLine" ist jedoch, dass sie nur in der VB-IDE funktioniert. Nun wäre es aber trotzdem ganz nützlich, wenn man Code aus Dateien auslesen und diesen zur Laufzeit kompilieren könnte. Kann man auch!
Mit dem Microsoft Script Control ist es nämlich möglich, beliebigen VBScript-Code auszuführen. Da VBScript kaum große Unterschiede zu Visual Basic zeigt, ist das doch wunderbar.
Nachfolgend werde ich zeigen, wie man mit VBScript Zugriff auf Formulare bekommt und ganze Dateien kompiliert.
Zunächst müssen Sie Ihrem Projekt unter "Komponenten" das "Microsoft ScriptControl 1.0" hinzufügen. Ziehen Sie es auf ein beliebiges Formular. In diesem Beispiel heißt das Formular "TestForm" und das ScriptControl "SC". Stellen Sie sicher, dass die Eigenschaft "Language" des ScriptControls den Wert "VBScript" hat. Auf demselben Formular erstellenSie nun einen Button namens "Command1". Für diesen wird nun das Click-Ereignis erstellt:
Private Sub Command1_Click() SC.AddCode "MsgBox ""Hallo Welt!"",vbInformation,""Hallo Welt!""" End Sub
Bemerkung: "" ersetzt Chr(34).
Starten Sie das Programm und klicken Sie auf den Button. Die Meldung "Hallo Welt!" wird erscheinen.
Mit der AddCode-Funktion wird ein Code-String direkt kompiliert und ausgeführt. Wie Sie sehen, werden auch Konstanten wie "vbInformation" kompiliert. Übrigens wird im CodeString nicht auf Groß- oder Kleinschreibung geachtet.
Fügen Sie dem Formular "TestForm" eine Textbox "Text1" hinzu. Erneuern Sie das Command1-Click-Ereignis folgendermaßen:
Private Sub Command1_Click() SC.AddCode Text1.Text End Sub
Starten Sie das Programm und geben Sie einen (beliebigen) VB-Code in das Textfeld ein. Nun ja, ganz beliebig nicht (siehe Einschränkungen am Ende des Workshops).
Wenn die Syntax stimmt, wird der Code kompiliert und ausgeführt.
Jetzt wollen wir uns Zugriff auf das aktuelle Formular verschaffen. Sie können das Textfeld nun wieder entfernen, es wird nicht mehr gebraucht. Mit der AddObject-Methode registrieren wir das Formular "TestForm" im ScriptControl.
Sie ist folgendermaßen aufgebaut:
[ScriptControl].AddObject [Name],[Objekt],[Mitglieder hinzufügen]
[ScriptControl]: In unserem Falle das SC-Objekt
[Name]: Name des zu registrierenden Objektes im ScriptControl
[Objekt]: Direkter Verweis auf das Objekt.
[Mitglieder hinzufügen]: Boolesch, soll nur das Objekt selbst oder auch seine Mitglieder hinzugefügt werden.
Für sieht das dann folgendermaßen aus:
Private Sub Form_Load() SC.AddObject "Form", TestForm, True End Sub
Erneuern Sie nun das Command1-Click-Ereignis:
Private Sub Command1_Click() SC.AddCode "Form.Caption=""Hallo Welt!""" End Sub
Starten Sie das Programm und klicken Sie auf den Button. Der Titel des Formulars "TestForm" ist nun "Hallo Welt!". Das Form-Objekt muss in der AddCode-Eigenschaft so heißen, wie es registriert wurde, das heißt: Nicht "TestForm" sondern "Form". Sie können sich auch Zugriff auf die Controls des Forms verschaffen:
Private Sub Command1_Click() SC.AddCode "Form.Command1.Caption=""Hallo Welt!""" End Sub
Man kann somit auch Befehle "in die unendliche Weite ausführen":
Private Sub Command1_Click() SC.AddCode "Form.SC.AddCode ""MsgBox """"Hallo Welt!""""""" End Sub
VB-Code aus einer Textdatei auslesen und ausführen
Wollen wir uns aber nicht weiter mit zu komplizierten Sachen beschäftigen...
Nun wird es Zeit, eine komplette Datei zur Laufzeit zu kompilieren und auszuführen.
Zunächst erstellen Sie eine Datei, sagen wir "C:\Code.txt".
Diese hat folgenden Inhalt:
' Kreiszahl PI: Public Const PI=3.141592654 ' Funktion zur Berechnung einer Kreisfläche Public Function Kreisflaeche(Radius) Kreisflaeche=(Radius^Radius)*PI End Function ' Main-Sub Public Sub Main() Dim TempRadius TempRadius=InputBox("Bitte Kreisradius eingeben:","") If IsNumeric(TempRadius)=False Then MsgBox "Bitte eine Zahl eingeben!",vbCritical,"": Exit Sub End If MsgBox "Der Flächeninhalt eines Kreises mit dem Radius " & _ TempRadius & " beträgt " & Kreisflaeche(TempRadius) & "!",_ vbInformation,"" End Sub
Nun geht's los.
Zuerst lesen wir mit der ReadAll-Methode die gesamte Datei "C:\Code.txt" ein.
Diese wird dann kompiliert und anschließend wird die Prozedur "Main" ausgeführt.
Modifizieren Sie das Form-Load-Ereignis folgendermaßen:
Private Sub Form_Load() Dim CodeToCompile As String Dim FSO As Object Dim File As Object ' Gesamte Datei in einen String speichern Set FSO = CreateObject("Scripting.FileSystemObject") Set File = FSO.OpenTextFile("C:\Code.txt") CodeToCompile = File.ReadAll File.Close ' Zugriff auf TestForm zulassen SC.AddObject "Form", TestForm, True ' Code kompilieren SC.AddCode CodeToCompile End Sub
Nun ändern Sie das Command1-Click-Ereignis so um:
Private Sub Command1_Click() ' Sub Main ausführen SC.AddCode "Main" End Sub
Wenn Sie sich bis jetzt alles durchgelesen haben, dürfte sich alles von selbst erklären.
Fast alle VisualBasic-Befehle und Ausdrücke sind in VBScript erlaubt, außer folgende:
NICHT ERLAUBT IN VBSCRIPT:
- ByVal und ByRef sowie das Schlüsselwort "As" und Datentypen
' Beispiel: Dim x As Integer Function RechneAus(ByVal X As Integer) As Integer
- End, Goto, GoSub, On Error...
- Arrays mit vorgegebenem LBound
' Beispiel: Dim a(1 To 10)
- Variable nach Next
' Beispiel: For i=0 to 9...Next i
- Variablendeklaration mit Private oder Public, nur mit Dim
- Benutzerdefinierte Typen und Enumerationen
Schlussbemerkung:
Ich habe leider keine Ahnung, wie man per VBScript auf VB-Klassen zugreifen kann.
Mir ist auch noch nicht bekannt, wie auf man selbst erstellte Module und Klassenmodule zugreifen kann.
Wer hierzu eine Lösung parat hat, darf diese gerne in den vb@rchiv Foren posten
Viel Spaß mit diesem Workshop!