Excel Makro Zeile in Tabelle kopieren

Registriert
03.08.10
Beiträge
59
Hallöchen,

ich brauche mal wieder eure Hilfe. Ich probiere schon den ganzen Tag herum und komme nicht weiter.

Ich versuche, in Excel ein Makro zu bauen, das mir eine Zeile von Tabelle A in Tabelle B kopiert, sobald in einer Spalte ein bestimmter Wert aus der dortigen Drop-Down-Liste gewählt wird.

Ich habe schon auf diversen Seiten gesucht und fand zwei Makros eigentlich ganz nett vom Aufbau.

1. Version =
Dim x, i, ergo
x = 5
For i = 1 To 65535
ergo = Range("P" & i)
If ergo="ja" Then
x = x + 1
Worksheets("Tabelle1").Rows(i).Copy _
Destination:=Worksheets("Tabelle2").Rows(x)
Worksheets("Tabelle1").Rows(i).Delete
End If
Next i


Hier ist das Problem, dass ich das Makro kein zweites Mal laufen lassen kann, weil sonst die Zeilen in Tabelle B überschrieben werden.

2. Version =
Private Sub Worksheet_Change(ByVal Target As Range)
Const cTZielTabelle = "Historie" ' Anpassen ...wohin kopieren ?
Const cTLoeschZ = "ja" ' Eintrag => Kopieren/Löschen
Const cLSpalteX = 16 ' Spaltennummer für LöschKennzeichen
Dim lRow As Long
If Target.Column <> cLSpalteX Then Exit Sub
If IsEmpty(Target) Then Exit Sub
If UCase(Target.Value) = cTLoeschZ Then
Application.EnableEvents = False
With Worksheets(cTZielTabelle)
lRow = Application.Max(.Cells(.Rows.Count, cLSpalteX).End(xlUp).Row + 1, 15)
Rows(Target.Row).Copy Destination:=.Rows(lRow)
Rows(Target.Row).Delete Shift:=xlUp
End With
Application.EnableEvents = True
End If

End Sub

Hier ist das größte Problem, dass ich das Makro nicht mal gestartet bekomme. Klicke ich auf das Play-Symbol, öffnet sich ein Fenster, wo ich ein Makro wählen bzw benennen soll, aber die Liste ist leer. Erstelle ich ein neues Makro fügt es unter den o.g. Code ein neues Sub und EndSub ein.... Ich weiß auch nicht, ob das mit der 15 in der 6letzten Zeile so richtig ist; hatte es einfach aus nem Forum kopiert...


Hoffe, hier sind ein paar VBA-Experten, die mir weiterhelfen können!

Danke!
 

ImpCaligula

deaktivierter Benutzer
Registriert
05.04.10
Beiträge
13.859
Makro #1

Erstens. Wenn ich schon sehe, dass die Leute Ihre Variablen als Variant lassen und nicht deklarieren bekomme ich die "Krätze" :D ... wenn Du nur DIM i schreibst, kannst Du das DIM auch gleich weg lassen. DIM i bedeutet, dass i Variant ist und wenn ich i nicht mit DIM deklariere ist es eh Variant.

Zweitens. Wieso lässt Du das Makro 65535 Zeilen runter rauschen und gehts nicht bis zur letzten Zeile?

Kommentare
Cells(zeile,spalte).Value für den Zugriff auf Zellen im X / Y Koordinaten System

Code:
Dim i as Integer
Dim x as integer
Dim letzteZeile as Integer

letzteZeile = ActiveSheet.Cells(Rows.Count, 1).End(xlUp).Row

for i = 1 to letzteZeile

if cells(i,16).value ="ja" then
x=x+1
rows(i).select
selection.copy
sheets("tabelle2").select
rows(x).select
activesheet.paste
sheets("tabelle1").select
end if

next i

application.cutcopymode = false

Ich habe das jetzt aus dem Kopf heraus gemacht, ist die "Idioten" Methode und müsste so auf jedenfall funktionieren. Ich würde erst am Ende so aus dem Kopf heraus die Werte in Tabelle 1 löschen... da ansonsten durch das Löschen der Zeile Deine Zeilennummerierung immer eins nach oben rutscht!

Aber das ganze Makro ist nicht optimal. Normalerweise liest man die Tabelle 1 aus nach "ja" Werten und kopiert diese in einen Array oder in eine Struktur. Danach geht man den Array durch und schreibt die Werte in Tabelle 2 hinein. Dein Makro springt nämlich die ganze Zeit zwischen Tabelle 1 und Tabelle 2 hin und her... suboptimal!

---
Das zweite Makro wurde als "automatisches" Makro gesetzt. Gehe mal auf irgendeine Tabelle im VBA Editor und klicke doppelt auf ein Tabellenblatt. Oben kannst Du dann das WORKSHEET auswählen und die Aktion, wann das Makro ausgeführt werden soll - in Deinem Fall bei Änderungen im Worksheet. Aber so ein Makro gehört nicht einfach in ein einzelnes Modul hinein - sondern IN das Modul des Tabellenblattes... sonst gehts natürlich nicht...
 
Registriert
03.08.10
Beiträge
59
Hey ImpCaligula,

vielen Dank für deine schnelle Antwort.

Ja, das erste Makro fand ich eh nicht so toll, aber das zweite funktioniert immer noch nicht bei mir... irgendwas mache ich falsch!
Bin auch leider totaler VBA-Frischling...

Also, ich habe die "nackte" Excel-Datei, gehe in den VBA-Editor, doppelklicke auf Tabelle "K", dann macht sich das Code-Fenster auf. Ich kopiere den zweiten Code vom Post oben rein, speichere (in den Dropdowns stehen Worksheet und Change), und klicke dann auf die Play-Taste. Nada. Es öffnet sich ein Fenster "Makros", wo man Ausführen, Abbrechen, Einzelschritt, Bearbeiten, Erstellen oder Löschen auswählen kann. Im Fenster selber steht nichts, unten kann man noch "Makros in" auswählen. Wenn ich dann auf "Erstellen" gehe, macht der mir nur ne neue Code-Struktur auf. Aber das will ich ja nicht! Wenn ich einfach wieder den Code von oben kopiere, wiederholt sich das Spielchen.

Was mache ich falsch?

Wenn ich einfach nur speichere und dann zurück in die Tabelle gehe und entsprechend "ja" auswähle, tut sich trotzdem nichts.

Schön wäre ein Makro, das automatisch, wenn ich in Spalte 18 (hat sich geändert) aus der Gültigkeits-Liste "ja" auswähle, die ganze Zeile in das Blatt "Historie" verschiebt. Aus dem ursprünglichen Blatt soll es automatisch gelöscht werden, müllt nämlich sonst nur die Liste voll. Die Daten fangen ab Zeile 5 an und laufen bis Ende. Das mit dieser 65535 aus dem ersten Code ist völliger Blödsinn. Wie gesagt, ich habe irgendwelche Makros aus Foren genommen und kopiert.

Ich muss das gleiche Makro auch noch auf 4 andere Blätter anwenden, daher würd ichs gern einfach nur kopieren bzw anpassen können...

Kannst du mir vielleicht weiterhelfen?

Und was macht es für einen Unterschied, ob ich im VBA-Editor einen Doppelklick auf die entsprechende Tabelle mache oder einfach nur ein Modul anfüge? Da es bei mir ja bisher nicht läuft, hab ich noch keinen Unterschied feststellen können...


Danke!

PS: Das Makro soll so funktionieren, dass die Daten im Blatt "Historie" nicht überschrieben werden und ich zu jeder Zeit wieder in Tabelle "K" ein "ja" auswählen kann und es an die Historie angefügt wird...
 

ImpCaligula

deaktivierter Benutzer
Registriert
05.04.10
Beiträge
13.859
Kannst Du bis Donnerstag warten? :)

Dann schreibe ich Dir beide Makros eben mal um...
 
Registriert
03.08.10
Beiträge
59
Mir reicht ein Makro, danke ;) So lange es funktioniert :D
Wenn es geht, wäre morgen ganz toll, weil das Ding am Donnerstag abgegeben werden soll...

Danke!!!
 
Registriert
03.08.10
Beiträge
59
Haha, ja das kommt vor ;)
Meinst du denn, du hast das Makro Donnerstag Vormittag fertig oder eher nachmittags?
 

ImpCaligula

deaktivierter Benutzer
Registriert
05.04.10
Beiträge
13.859
Wenn Du meinen Stundensatz als Programmierer bezahlst... habe ich es direkt am Vormittag fertig ;)

Ansonsten da Donnerstag mein freier Tag ist und ich aus schlafe... und Dir eben mal etwas umsonst hacke, wofür normalerweise meine Kunden Geld bezahlen müssen - Nachmittag...
 
Registriert
03.08.10
Beiträge
59
Ich glaub ich hab's jetzt...

Sub Historie_schieben()
Application.ScreenUpdating = False
Sheets("K").Select
Dim x, i, ergo
x = 5 'Starten in Zeile 5 nach der Kopfzeile
For i = 5 To 65535 'Ende als willkürliche Zahl
ergo = Range("R" & i) 'zu beachtende Spalte R
If ergo = "ja" Then 'wird Wert "ja" gefunden, dann
Sheets("K").Select
Rows(i).Select 'entsprechende Zeile in Tabelle auswählen
Selection.Cut 'ausschneiden
Sheets("Historie").Select
Rows(x).Select 'in Zeile 5 im Blatt Historie einfügen
Selection.Insert Shift:=xlDown 'restliche Daten eine Zeile runterschieben
Sheets("K").Select
Rows(i).Select
Selection.Delete 'ausgewählte Zeile in Tabelle löschen (da leer)
i = i - 1 'Zähler für i zurücksetzen
End If
Next i
Range("A5").Select
End Sub


Es ist zwar kein automatisches Makro, aber macht, was es soll. Höchstens die Sache mit der 65535 ist noch optimierbar.. stammt wohl daher, dass Excel früher nur max. 65535 Zeilen macen konnte, habe ich mir sagen lassen...

Was meinst du, ImpCaligula: sollte doch eigentlich nen wasserfestes Makro sein, oder?
 

ImpCaligula

deaktivierter Benutzer
Registriert
05.04.10
Beiträge
13.859
Ja kann man lassen... außer, dass das Makro hin und her springt und dass schon wieder keine Variablen deklariert / dimensioniert werden - und dass es schon wieder bis 65000 runter rauscht, egal ob was in den Zellen steht oder nicht - ist es ok ....

:D
 

Darkelf

Erdapfel
Registriert
29.10.14
Beiträge
1
Ich habe ein ähnliches Problem, und zwar möchte ich nicht alle Zellen der Zeile verschieben bei einsetzen der Bedingung. Aber die ganze Zeile löschen nach dem verschieben...
Momentan habe ich dies, leider geht es so nicht... Die ganze Zeile zu verschieben habe ich hinbekommen...

Private Sub Worksheet_Change(ByVal Target As Range)
Const cTZielTabelle = "Aktuelle Aktionen" ' Anpassen ...wohin kopieren ?
Const cTLoeschZ = "1" ' Eintrag => Kopieren/Löschen
Const cLSpalteX = 27 ' Spaltennummer für LöschKennzeichen
Dim lrow As Long
If Target.Column <> cLSpalteX Then Exit Sub
If IsEmpty(Target) Then Exit Sub
If UCase(Target.Value) = cTLoeschZ Then
Application.EnableEvents = False
With Worksheets(cTZielTabelle)
lrow = Selection.Row(.cells("A:p").Max(Rows.Count, 1).End(xlUp).Row + 1, 7)
Rows(Target.Row).Copy Destination:=.Rows(lrow)
Rows(Target.Row).Delete Shift:=xlUp
End With
Application.EnableEvents = True
End If
End Sub

Ich hoffe jemand kann mir helfen...

Freundliche Grüsse Marcel