Live-Forum - Die aktuellen Beiträge
Datum
Titel
17.04.2024 18:57:33
17.04.2024 16:56:58
Anzeige
Archiv - Navigation
1452to1456
Aktuelles Verzeichnis
Verzeichnis Index
Übersicht Verzeichnisse
Vorheriger Thread
Rückwärts Blättern
Nächster Thread
Vorwärts blättern
Anzeige
HERBERS
Excel-Forum (Archiv)
20+ Jahre Excel-Kompetenz: Von Anwendern, für Anwender
Inhaltsverzeichnis

Excel VBA - VBA-gesteuerte Manipulation von VBA-Co

Excel VBA - VBA-gesteuerte Manipulation von VBA-Co
31.10.2015 15:38:30
VBA-Co
Hallo VBA-Experten,
habe ein Problem mit der VBA-gesteuerten Manipulation von VBA-Code in einem VBA-Modul.
Hierzu habe ich das Problem auf ein möglichst einfaches Beispiel reduziert:
Per VBA-Code verändere ich eine Funktion (erste Änderung).
Der erste Aufruf dieser Funktion liefert dann das erwartete Ergebnis.
Dann verändere ich die Funktion (zweite Änderung).
Der zweite Funktionsaufruf liefert das erste Ergebnis, die zweite Änderung in wird ignoriert.
Was muss ich tun, damit die zweite Änderung berücksichtigt wird?
Muss nach der Änderung eventuell irgendein Update/Refresh erfolgen?
Weitere Hinweise: Das Problem tritt auch bei Excel 2010 auf.
Habe auch mal testweise den Virusscanner deaktiviert - ohne Erfolg.
Grüße und vielen Dank im Voraus!
Harry

Function myTest() As Variant ' wichtig: dies ist die erste Zeile im VBA-Modul!
' diese Zeile wird durch den VBA-Code ersetzt ...
End Function

Sub Start() ' Start-Prozedur
Dim Result As Double: Result = 0
Application.VBE.ActiveCodePane.CodeModule.replaceline 2, "myTest = 2"
MsgBox myTest ' ergibt 2, wie erwartet
' sind an dieser Stelle eventuell weitere Schritte erforderlich? (Update/Recompile)
Application.VBE.ActiveCodePane.CodeModule.replaceline 2, "myTest = 3"
MsgBox myTest ' ergibt 2 anstelle von 3
End Sub

12
Beiträge zum Forumthread
Beiträge zu diesem Forumthread

Betreff
Datum
Anwender
Anzeige
AW: Excel VBA - VBA-gesteuerte Manipulation von VBA-Co
31.10.2015 16:09:49
VBA-Co
Hallo,
ich denke nach dem ersten Aufruf der Funktion ist diese zur Laufzeit gesperrt und
wird erst nach Abschluss aktualisiert.
Wo liegt eigentlich der Sinn in solch einer Aktion?
Gruß Tino

AW: Excel VBA - VBA-gesteuerte Manipulation von VBA-Co
31.10.2015 19:16:30
VBA-Co
Hallo Tino, hallo Luschi,
vielen Dank für die Antwort(en).
Zweck der Funktion myTest: Auswertung eines beliebigen String-Ausdrucks (Parser).
myTest() soll Strings auswerten und das Ergebnis zurückgeben,
z. B. Zahlen
"(2*3)-8*3"
oder z. B. Bool'sche Auswertung (True/False)
"a=1 and b=2"
Es geht mir also nicht darum, die Zahlen durch numerische Vorgaben zu beeinflussen (so wie im Lösungsvorschlag), sondern nur durch den String (der z. B. aus einer Datei stammt).
Würde die Funktion sich also zur Laufzeit aktualisieren lassen, könnte ich darauf verzichten, einen externen Parser einzubinden oder selbst einen zu schreiben.
Gibt es irgendeine Möglichkeit, die Sperre zur Laufzeit aufzuheben bzw. eine programmgesteuerte Aktualisierung zu machen?
Gruß
Harry

Anzeige
wenn nicht zur Laufzeit, dann danach
31.10.2015 19:42:27
Tino
Hallo,
bin mir sicher man könnte das was du machen möchtest bestimmt auch ander lösen.
Dazu kenne ich aber dein vorhaben zu wenig.
Option Explicit
 
Function myTest() As Variant ' wichtig: dies ist die 3. Zeile im VBA-Modul! 
myTest = 3
End Function

Sub Start()
Start_ 0
End Sub

Sub Start_(intIndex%)
Dim Result As Double: Result = 0
   
With Application.VBE.ActiveCodePane.CodeModule
    If intIndex = 0 Then
        .replaceline 4, "myTest = 2"
    ElseIf intIndex = 1 Then
        .replaceline 4, "myTest = 3"
    End If
End With

MsgBox myTest ' ergibt 2, wie erwartet 
If intIndex < 1 Then _
    Application.OnTime Now + TimeSerial(0, 0, 1), "'Start_ 1'"
End Sub
Gruß Tino

Anzeige
AW: Excel VBA - VBA-gesteuerte Manipulation von VBA-Co
31.10.2015 16:12:11
VBA-Co
Hallo Harry,
Du mußt Vba zwingen das Ergebnis der Funktion neu zu berechnen:

Option Explicit
Function myTest(i As Integer) As Variant ' wichtig: dies ist die erste Zeile im VBA-Modul!
'Ersetzungszeile
End Function
Sub Start() ' Start-Prozedur
Dim Result As Double: Result = 0
Application.VBE.ActiveCodePane.CodeModule.ReplaceLine 4, "myTest = 2 + i"
MsgBox myTest(0) ' ergibt 2, wie erwartet
' sind an dieser Stelle eventuell weitere Schritte erforderlich? (Update/Recompile)
Application.VBE.ActiveCodePane.CodeModule.ReplaceLine 4, "myTest = 2 + i"
MsgBox myTest(1) ' ergibt 2 anstelle von 3
End Sub
Gruß von Luschi
aus klein-Paris
PS: aber ob die Idee überhaupt gut ist, kiann ich mir nicht vorstellen!!!

Anzeige
mach für mich überhaupt keinen Sinn?! ;-) oT.
31.10.2015 16:21:04
Tino

AW: mach für mich überhaupt keinen Sinn?! ;-) oT.
31.10.2015 16:27:32
Luschi
Hallo Tino,
für mich natürlich auch nicht, aber des Menschen Vba-Wille ist sein ?-Himmelreich.
Gruß von Luschi
aus klein-Paris

die zweite Wiederholung
31.10.2015 16:32:31
Tino
Hallo,
ich meine die zweite Zeile
Application.VBE.ActiveCodePane.CodeModule.ReplaceLine 4, "myTest = 2 + i"
ändert die Funktion nicht.
Dim Result As Double: Result = 0
Application.VBE.ActiveCodePane.CodeModule.ReplaceLine 4, "myTest = 2 + i"
MsgBox myTest(0)
MsgBox myTest(1)
Gruß Tino
Gruß Tino

Das kann nicht so fktionieren, ...
31.10.2015 20:52:17
Luc:-?
…Harry,
wie du's dir vorstellst, da hat Tino recht, denn dazu muss neu kompiliert wdn, was aber erst nach Abschluss des 1.Durchlaufs geschieht. Ich hatte Derartiges noch/schon unter Xl9 ausprobiert und dabei festgestellt, dass man die Initialisierung/Änderung einer Prozedur und ihren Aufruf nicht in derselben Prozedur unterbringen kann. Hier reduziert sich das allerdings auf weitere Aufrufe, der 1.akzeptiert die initialisierende Änderung noch. Das so etwas kontraproduktiv ist, merkt man schon daran, dass sich die SubProz nach der 1.Änderung nicht mehr anhalten lässt.
Du benötigst also für jede Änderung einen eigenen Aufruf, zB so:
Option Explicit
Function myTest()   'Fkt m.WechselZeile
Rem WechselZeile
End Function
Sub RufMTS2()   '1.Start-RufProzedur
Call MyTestStart("myTest", " = 2", 1)
End Sub
Sub RufMTS3()   '2.Start-RufProzedur
Call MyTestStart("myTest", " = 3", 1)
End Sub
Rem parametrierte Start-Prozedur
Sub MyTestStart(ByVal naRelFkt$, ByVal ErgZuweis$, Optional ByVal prozTyp As Long)
Const relZlVsatz As Long = 1, txProzArt$ = "Sub Function Property", _
txWxZl$ = vbTab & "Rem WechselZeile"
Dim Result As Double, relZl As Long, prozArt As String
prozArt = Split(txProzArt)(prozTyp)
With Application.VBE.ActiveCodePane.CodeModule
relZl = .ProcStartLine(naRelFkt, vbext_pk_Proc)
While InStr(.Lines(relZl, 1), prozArt) = 0: relZl = relZl + 1: Wend
.ReplaceLine relZl + relZlVsatz, vbTab & naRelFkt & ErgZuweis
Result = Evaluate(naRelFkt & "()"): MsgBox CStr(Result)
.ReplaceLine relZl + relZlVsatz, txWxZl
End With
End Sub
Da ich nicht davon ausgehe, dass das eigentliche Problem so simpel ist, scheint mir Luschis Lösung hier auszuscheiden und eine generelle Feststellung dazu angebrachter.
Allerdings vermute ich, dass der Hintergrund dieser Frage anders aussieht als es den Anschein hat und das eigentliche Problem eines sein könnte, das besser anders gelöst wdn sollte.
Gruß, Luc :-?
Besser informiert mit …

Anzeige
AW: Excel VBA - VBA-gesteuerte Manipulation von VBA-Co
01.11.2015 13:52:41
VBA-Co
Hallo Tino, hallo Luschi,
vielen Dank für die Antwort(en).
Zweck der Funktion myTest: Auswertung eines beliebigen String-Ausdrucks (Parser).
myTest() soll Strings auswerten und das Ergebnis zurückgeben,
z. B. Zahlen
"(2*3)-8*3"
oder z. B. Bool'sche Auswertung (True/False)
"a=1 and b=2"
Es geht mir also nicht darum, die Zahlen durch numerische Vorgaben zu beeinflussen (so wie im Lösungsvorschlag), sondern nur durch den String (der z. B. aus einer Datei stammt).
Würde die Funktion sich also zur Laufzeit aktualisieren lassen, könnte ich darauf verzichten, einen externen Parser einzubinden oder selbst einen zu schreiben.
Da es anscheinend keine Möglichkeit gibt, die Sperre zur Laufzeit aufzuheben bzw. eine programmgesteuerte Aktualisierung zu machen, muss ich einen anderen Weg gehen.
Gruß und vielen Dank!
Harry

Anzeige
Das hatte ich mir schon beinahe gedacht, ...
01.11.2015 14:18:56
Luc:-?
…Harry;
da du es vorziehst, meine umfangreiche AW zu ignorieren, hiermal nur ein Tipp → vbFkt Evaluate (oder benannte Fml mit XLM-Fkt AUSWERTEN).
Auf dieser Basis kann man auch eine kleine UDF schreiben, die im Ggsatz zur XLM-Fkt auch in ZellFmln eingesetzt wdn könnte, allerdings mit FmlText in US-Original-Notation (was hier aber wohl der lokalen deutschen gleich wäre).
Luc :-?

AW: Das hatte ich mir schon beinahe gedacht, ...
01.11.2015 21:20:07
Harry
Hallo Luc :-?,
sorry, habe Deinen umfangreichen Beitrag natürlich auch gesehen u. möchte mich auch bei Dir herzlich dafür bedanken! Die Möglichkeit über Evaluate oder über Excel-Funktionen hatte ich auch schon geprüft aber verworfen, weil ich ursprünglich eine möglichst direkte Kopplung mit dem VBA-Code wollte.
Z. B. sollte beim String mit dem Bool'schen Ausdruck "Fritz = 1 AND Franz = 2" auf die Public-VBA-Variablen "Fritz" und "Franz" zugegriffen werden. Das wäre möglich, falls sich der VBA-Code dynamisch aktualisieren ließe. Die damit verbundenen Möglichkeiten wären absolut großartig.
Sehr wertvoll für mich ist die Information von Euch, dass ein ReCompile der gleichen Funktion zur Laufzeit nicht mehrfach möglich ist. D. h. ich kann die VBA-Code-Manipulation als Lösungsoption ausschließen u. meine Energie auf andere Möglichkeiten fokussieren.
Nochmals herzlichen Dank!
Harry

Anzeige
Wenn du 'Evaluate' nicht willst, ...
02.11.2015 02:31:42
Luc:-?
…Harry,
musst du das alles selber pgmieren. Ich habe das vor ca 12 Jahren mal gemacht und die daraus resultierende FktsProzedur (UDF) ist bis heute meine mit Abstand längste, musste wg LängenÜberschreitung auch noch geteilt wdn.
Die 1.Versuche in dieser Richtung, nur auf Basis von Xl-Standard­Operatoren, waren allerdings deutlich kürzer. Dazu muss der zu berechnende Text durchgegangen, Zahlen, Namen und Operatoren isoliert und richtig zueinander in Beziehung gesetzt wdn. Evaluate bietet dagegen den Vorteil, eine Notation wie in einer engl Fml benutzen zu können, wobei man dann natürlich keine VBA-Schreibweise mit bspw And als Operator benutzen kann. Pgmierst du das selbst, kannst du natürlich machen, was du willst, nur nicht so wie von dir angedacht.
Mit einem eigenen Programm könnte das evtl so wie mit der o.g. UDF aussehen:
 ABCDE
1VariablenNamenFmlTextErgebnisZellFml
2alphabetaa<25&b>10ƒ(a=25, b=11)=Falsch⇒T2Form(C2;;alpha;beta)
32511a<25|b>10ƒ(a=25, b=11)=Wahr⇒T2Form(C3;;alpha;beta)

Ich vermute aber, dass das auch nicht deinen Intentionen entspricht. Anders geht's nur so wie in der von dir letztlich ebenfalls verworfenen Variante, die auch nicht mittels Ereignissen in Verbindung mit globalen Zählern zu anderem Arbeiten zu bewegen ist. Man bewegt sich hier wohl in einer „Grauzone“ außerhalb des normalen Verlaufs, deren Variablen nach Abschluss der Operation zurückgesetzt wdn. Die einzige Möglichkeit besteht hier darin, Xl wenigstens in Form einer benannten Konstanten in Anspruch zu nehmen. Deren lfd Erhöhung bleibt nämlich erhalten und kann so zur Grundlage eines ereignis­gesteuerten Mehrfach­Aufrufs der Modifi­kation­sprozedur gemacht wdn.
Ansonsten ist auch mit CallByName eher nichts zu machen, denn hierbei geht's, ähnlich wie bei Run,um vbObjekt- und -Eigenschaften­Namen in Textform, nicht um ganze VBA-Kommando­Zeilen-Texte. Dafür gibt's wohl nichts außer der behandelten Möglichkeit.
Luc :-?
Anzeige

Beliebteste Forumthreads (12 Monate)

Anzeige

Beliebteste Forumthreads (12 Monate)

Anzeige
Anzeige
Anzeige