Excel VBA - makro in makro aufrufen

Hallo,

ich bin was vba anghet noch ein neuling und habe folgende frage, zu der ich bisher leider noch keine antwort gefunden hab (die ich verstanden hätte :wink::

ich rufe in meinem MakroA mit CALL ein zweites Makro auf (MakroB). Nachdem MakroB durchgeführt wurde, wird MakroA wieder von Begin gestartet. Ich möchte allerdings, dass MakroA dort weitergeführt wird, wo es zuvor durch den Call aufruf unterbrochen wurde.

Mein Code sieht in etwa so aus:

„MakroA“
Private Sub ComboBox1_Change()
im counter As Integer
Call formatrows(counter)
[…]

„MakroB“
Sub formatrows(counter As Integer)
msgbox(MakroB)
[…]
end sub

Hallo,

dafür dass Du ein Neuling in Excel bist, hast Du aber schon scharfe Fragen. Ich kann sie leider nicht ohne weiteres beantworten, ist wohl eher etwas für die VBA-Fraktion.

Viel Glück bei der Antwortfindung!

Sub Startmakro()

Dim Counter As Integer
Counter = 1
'Rufe Funktion auf
Funktion (Counter)

MsgBox „hier geht s mit dem Ausgangsmakro weiter“

End Sub

Function Funktion(ByVal Counter As Integer)

For Counter = 1 To 10
MsgBox Counter
Next Counter

End Function

Rufe Makro B aus dem Makro A heraus auf
Setze den Makro-Namen des Makros B ohne Sub und Ohne ()
also:

sub MakroA()
nnnnn
nnnn
nnnn
MakroB
mmmm
mmmm
end sub

Feedback wäre nett
Der Graubart

Erstmal vielen Dank für Deine schnelle Antwort. Leider funktioniert es auch mit „function“ nicht (aber immerhin habe ich jetzt diese Funktion auch mal kennengelernt :wink:.

Mein Code sieht jetzt wie folgt aus. Die Stellen an denen auf andere Makros verwiesen wird habe ich mit ***** gekennzeichnet. Das Problem ist, dass nach dem Ausführen von Makro 3 nicht zu Makro 2 zurückgekehrt wird, sondern Makro 1 von vorne startet. Ist das ein Problem oder stell ich mich einfach nur blöd an?

Private Sub ComboBox1_Change()
Dim dept As String
dept = ComboBox1.Text
Call addrow(dept) *****
End Sub

Sub addrow(dept As String)
Dim counter As Integer
Sheets(Array „1“, „2“).Select
If dept = „x“ Then
counter = 1
Do While counter

Hallo Graubart

danke für deinen Vorschlag, leider hat auch das bisher bei mir nicht geklappt. Ich weiß auch nicht woran es liegt versuche mein Glück aber weiter. Ich habe einen etwas vollständigeren Code hochgeladen. Trotzdem danke für Deine Hilfe bisher!!

Ich weiß nicht genau, was Du bezweckst. Daher ist die Antwort schwierig.

Ziemlich sicher (mehrfach) falsch ist aber der Ansatz

Sheets(Array „1“, „2“).Select

mit folgend

If Cells(counter, 2) = „Rezeption“ Then

Willst Du damit etwa prüfen, ob sich in den beiden Tabellenblättern mit den Namen „1“ und „2“ gleichermaßen jeweils in der Zeile (counter), Spalte 2 der Wert „Rezeption“ befindet? Falls ja, müßte das in etwa so lauten:

'Prüfe auf Wert „Rezeption“ im 1. Tabellenblatt:
If ThisWorkbook.Sheets(„1“).Cells(counter, 2) = „Rezeption“ Then
'Falls ja, prüfe auf Wert „Rezeption“ im 2. Tabellenblatt:
If ThisWorkbook.Sheets(„2“).Cells(counter, 2) = „Rezeption“ Then
'Füge eine Zeile unterhalb ein
ThisWorkbook.Sheets(Array(„1“,„2“)).Rows(counter).Insert Shift:=xlDown
formatrows (counter)
counter = counter + 2
End If
Else

Meiner Meinung nach ist es nicht möglich, eine Schleife über einen Verbund mehrerer Range-Objekte durchführen. Denn Du bildest damit ein Range-Objekt aus den beiden Zellen. Was soll denn „der“ Wert in einem Verbund mehrerer Zellen sein? Sind das beide Werte hintereinander? In welcher Reihenfolge?

Du musst daher die beiden Zellen einzeln für sich auslesen wie oben dargestellt. Natürlich könntest Du auch notieren:

If …sheets(„1“).cells(counter, 2) = „Rezeption“ AND …sheets(„2“).cells(counter, 2) = „Rezeption“ Then …

Das ist persönlicher Programmierstil. Ich würde aber die zuerst g. Version bei sehr langen, komplexen Scripten vorziehen, weil das Script dabei schneller ist.

Weitere Hinweise:

Das „Selektieren“ (select hier, select da) bringt nicht nur nichts, sondern ist unprofessionell. Bezüge zu Objekten wie Zellen, etc. werden *nicht* dadurch hergestellt, dass diese vorher selected werden, sondern dadurch dass die Objekte direkt angesprochen werden. Es heißt also nicht:

Cells(1,1).select
Selection = 1

sondern gleich:

Cells(1,1) = 1

Und besser heißt es auch außerdem:

ThisWorkbook.Sheets(1).cells(1,1) = 1, weil nur dadurch ein sicherer Bezug zur Zelle A1 im ersten TB hergestellt wird. Cells(1,1) klappt nur „zufälligerweise“, wenn bzw. weil der Fokus auf TB 1 liegt.

Um nicht 100 Mal ThisWorkbook.Sheets(1)… schreiben zu müssen, wenn man sich mehrmals auf dasselbe Objekte bezieht, schreibt man eleganterweise auch besser:

With Thisworkbook.Sheets(1)

If .cells(1,1) = 1 Then
If .cells(1,2) = 2 then

.cells(1,3)=4

end if
end if

End With

Der Punkt . steht in diesem Fall als Platzhalter für den Ausdruck nach „With“
Rows(counter).Select
Selection.Insert Shift:=xlDown

Was mir noch so aufgefallen ist:

In deinem Codeschnipsel am Ende fehlt die Übergabe der Variable Counter in der Function formatrows

Außerdem ist die Funktion in der notierten Weise ziemlich sinnlos. Was und wie soll dadurch formatiert werden? Dadurch wird lediglich kurzzeitig der Cursor auf 2 Zellen ausgewählt. Richtigerweise müßte es auch zudem heißen: Array(„1“, „2“) statt („1“, „2“). Aber wozu soll das gut sein?

Gruß

p.

P.S.:
Wie bist Du gerade auf mich als „Experten“ gekommen?

P.P.S.:
Die Arbeitsblätter *heißen* auch wirklich „1“ und „2“ oder? Es gibt nämlich auch Sheets(1) statt Sheets(„1“). Das wäre dann das erste Arbeitsplatz im Array der Arbeitsblätter im Gegensatz zum Sheet mit dem Label „1“.

Hallo,

mit folgendem Code funktioniert es, kannst du dein Problem konkretisieren?

Grüße
Sunny

Sub Makro1()
MsgBox „Makro 1 Teil 1“
Call Makro2
MsgBox „Makro 1 Teil 2“
End Sub

Sub Makro2()
MsgBox „Makro 2“
End Sub

Versuchen die MSGBox in Makro 1 einzubauen!
mit Zuweisung des weiteren Ablaufs über select case

Select Case MsgBox(„Bitte Zeitstempel setzen.“, vbInformation + vbOKOnly + vbOKCancel, „Ein Fehler will sich einschleichen …“)
Case vbCancel: Exit Sub
Case vbOK: goto 111
End Select
End If

Feedback wäre nett
der graubart

[Bei dieser Antwort wurde das Vollzitat nachträglich automatisiert entfernt]

Hallo zurück,

das liegt mit hoher Sicherheit daran, dass Dein Makro „B“ etwas in der Combobox1 verändert (was passiert eigentlich in […] ?) - und das ruft natürlich auch wieder „Combobox1_Change()“ auf.

Früher war sowas die sicherste Methode, seinen Rechner aufzuhängen :wink: - wenn Du bei so etwas „on error resume next“ eingibst, dann dürftest Du excel auch nicht wieder zurückholen können.

mit greundlichem Fuße

Hi,

entschuldige, dass ich erst so spät antworte, war lange weg.

ich rufe in meinem MakroA mit CALL ein zweites Makro auf
(MakroB). Nachdem MakroB durchgeführt wurde, wird MakroA
wieder von Begin gestartet. Ich möchte allerdings, dass MakroA
dort weitergeführt wird, wo es zuvor durch den Call aufruf
unterbrochen wurde.

Mein Code sieht in etwa so aus:

„MakroA“
Private Sub ComboBox1_Change()
im counter As Integer
Call formatrows(counter)
[…]

„MakroB“
Sub formatrows(counter As Integer)
msgbox(MakroB)
[…]
end sub

‚formatrows‘ ist bei Dir ansich nicht als Makro gedacht, sondern als Prozedur. Makros sind Objekte, die vom Excel-User direkt oder per Knopfklick ausgeführt werden sollen. Funktionen (mit Rückgabewert) und Prozeduren (ohne Rückgabewert) rufst Du aus Deinem Code direkt auf, also so:

Private Sub ComboBox1_Change()
im counter As Integer
formatrows counter
[…]

Ich hoffe, das hilft (noch) weiter. :smile:

Grüße,
Michel

Hallo,
es tut mir leid, das ich erst so spät antworte!
Leider kann ich deine Frage nicht beantworten, da ich mich nicht mehr allzu gut mit der Materie auskenne.
Vll hilft dir das Stichwort rekursiver Algorithmus weiter, da ich glaube, das du etwas in der art meinst.
Viel erfolg :wink: