Moin zusammen,
ich bin (noch) VBA-Anfänger und habe bisher eigentlich nur mit "normalen" Formeln in Excel gearbeitet. Seit einiger Zeit lese ich hier schon begeistert das Forum und die Tuts, so dass ich langsam VBA lerne und ich muss sagen, dass ich es wirklich klasse, wie hier geholfen wird.
Ich habe ein aus Pro-Sicht vermutlich völlig lächerliches kleines Problem, bei dem ich aber irgendwie ein Brett vor dem Kopf habe und einfach nicht durchblicke. Ich weiß, dass meine nachfolgende Beschreibung auch einfach mit einer "normalen" Formel in Excel zu lösen ist. Ich möchte jedoch um VBA weiter/besser zu lernen und zu verstehen, das ganze über VBA umsetzen und hoffe, dass ihr mir hierbei auf die Sprünge helfen könnt.
In einer Exceltabelle habe ich in den Zeilen der Spalte A immer entweder den Buchstaben A oder T stehen. Abhängig von dem Buchstaben soll durch eine Subprozedur Spalte B befüllt werden, in meinem Lern-Fall mit der Zeilen-Nr und der Angabe aus der Zelle in Spalte A (z.B. "14 A"). Angefangen werden soll in Zeile 10. Um nun die Übergabe von Variablen zwischen Prozeduren besser zu verstehen, möchte ich abhängig von der Angabe in Spalte A entweder die eine oder andere Prozedur ausführen, so dass z.B. mit einer For each Schleife alle befüllten Zeilen nacheinander automatisch abgearbeitet werden. Dafür habe ich 3 kleine Prozeduren geschrieben:
1. "Haupt- bzw. Start-Prozedur": Soll mit einer For-Schleife für jede Zeile zwischen A und T differenzieren und die jeweilige Unterprozedur in einem anderen Modul aufrufen.
2. "AblaufA": Soll die Zeilen mit "A" bearbeiten
3. "AblaufT": Soll die Zeilen mit "T" bearbeiten
Wenn ich von den Unterprozeduren immer nur eine Zeile bearbeiten lasse und dann über die Start-Prozedur für die nächste Zeile differenziert wird, läuft das alles auch gut durch (so wie bei "AblaufA" als Code geschrieben). Damit könnte ich eigentlich aufhören.
Etwas weiter an den Modulen geschraubt wäre es doch bestimmt auch möglich, dass eine Unterprozedur nicht nur eine Zeile bearbeitet und dann zur Start-Prozedur zurückgekehrt wird, sondern die Unterprozedur so lange durchläuft, bis der "andere Fall" eintritt (wie z.B. in AblaufT). Und das läuft das Ganze dann nicht mehr sauber durch. So wie ich mich das bisher zumindest erklärt habe, schaffe ich es zwar, die jeweils zu bearbeitende Tabellenzeile von der Start-Prozedur an die Unterprozedur zu übergeben. Wenn in AblaufT jedoch nicht nur eine Zeile bearbeitet wird, sondern mehrere Zeilen und dann zu Start zurückgeschaltet wird, scheint die Start-Prozedur mit der Tabellenzeile weiter zu laufen, die zuvor auch an AblaufT übergeben wurde nicht jedoch mit der Tabellenzeile, in der AblaufT zuvor fertig geworden ist, z.B.:
Für Tabellenzeile 11 wird aufgrund der Angabe "T" in Spalte A von der Start-Prozedur entschieden, AblaufT zu starten. Angabe "Zeile 11" wird an AblaufT übergeben. AblaufT bearbeitet Zeile 11 und die nachfolgenden Zeilen, bis in Spalte A die Angabe "A" erfolgt, z.B. bis Zeile 14, so dass dann zur Start-Prozedur zurückgekehrt wird. Die Start-Prozedur läuft dann aber scheinbar wieder ab der ursprünglich übergebenen Zeile 11 weiter und nicht ab Zeile 15...
Modul mit Prozedur: Start-Prozedur:
Sub AblaufBeginn()
Dim sheet As Worksheet, rngStart As Range, rngEnd As Range, cell As Range
Dim strItem As String 'Variable zur Differenierung zwischen T und A
Dim ZZurück As Integer 'Zeilennummer, die von den Subprozeduren zurückgegeben werden soll
Set sheet = ActiveSheet
Set rngStart = sheet.Range("A10")
Set rngEnd = rngStart.End(xlDown)
counter = 0
For Each cell In sheet.Range(rngStart, rngEnd)
'Auswahl zwischen T und A
strItem = sheet.Cells(cell.Row, "A").Text
Select Case strItem
Case "A"
Call AblaufA(cell.Row)
Case "T"
Call AblaufT(cell.Row, ZZurück)
Set rngStart = sheet.Range("A" & ZZurück)
Case Else
MsgBox "AuflaufStart *** Bis inkl. Zeile " & cell.Row - 1 & " wurde(n) " & counter & " Einträge erstellt." & vbCrLf & vbCrLf & _
"Zeile " & cell.Row & " enthält keine gültige Angabe zum Item T oder A." & vbCrLf & vbCrLf & _
"Die weitere Verarbeitung wird abgebrochen!", vbExclamation
Application.StatusBar = ""
Exit Sub
End Select
counter = counter + 1
Next
MsgBox "Ablauf Ende - Es wurden " & counter & " Einträge durchlaufen"
End Sub
Modul mit Prozedur: AblaufA
Sub AblaufA(ByVal NrZeile)
On Error Resume Next
Dim sheet As Worksheet, rngStart As Range, rngEnd As Range, cell As Range
Set sheet = ActiveSheet
Set rngNrZeile = sheet.Cells(NrZeile, "B")
rngNrZeile.Value = NrZeile & " A"
End Sub
Modul mit Prozedur: AblaufT
Sub AblaufT(ByVal NrZeile, ByRef NrZeileZurück As Integer)
Dim sheet As Worksheet, rngStart As Range, rngEnd As Range, cell As Range
Set sheet = ActiveSheet
Set rngStart = sheet.Cells(NrZeile, "A")
Set rngEnd = rngStart.End(xlDown)
For Each cell In sheet.Range(rngStart, rngEnd)
strItem = sheet.Cells(cell.Row, "A").Text
If strItem = "" Then
NrZeileZurück = cell.Row
MsgBox "Ende Sub"
Exit For
End If
If strItem = "A" Then
NrZeileZurück = cell.Row
Exit For
End If
MsgBox "Info: " & cell.Row & " T wird in Zeile geschrieben"
Set rngNrZeile = sheet.Cells(cell.Row, "B")
rngNrZeile.Value = cell.Row & " T"
Next
MsgBox "Zurück"
End Sub
Zur Lösung habe ich überlegt, dass beim Zurückschalten von AblaufT zur Start-Prozedur eine Variable übergeben wird, die die Zeilen-Nr enthält, in der AblaufT fertig geworden ist und ich mit der Variablen, die Startzeile für die For-Schleife in der Startprozedur neu setze das hilft leider auch nicht. Aus Pro-Sicht ist das vermutlich eine Bagatelle, ich stehe aber bei Verstehen der Nutzung von verschiedenen Prozeduren und der Übergabe und Rückgabe von Variablen und Werten irgendwie total auf dem Schlauch
Deshalb bitte ich bereits vorab um Nachsicht und bedanke mich schon jetzt für Eure Unterstützung ganz herzlich!!
Micha
P.S.: Error-Handling habe ich noch nicht eingebaut, da ich mich damit auch noch nicht wirklich auskenne und viele Dinge dabei auch noch nicht verstanden habe.