krm5000
Goto Top

Hilfe bei Excel-Makro mit Fehler - Arbeitsblätter autom. erstellen und ausfüllen

Hallo,

ich bin Anfänger was VBA angeht und habe auch sonst wenig Programmierkenntnisse, deswegen habe ich ein Makro, das eigentlich funktionieren müsste, es aber nicht tut..

Ich habe eine Excel Arbeitsmappe in der in Spalte J Namen stehen zwischen den Namen sind leere Zellen.
Das Makro soll:
1. für jede Zelle in Spalte J in der etwas steht ein neues Arbeitsblatt machen.
2. Jedes Arbeitsblatt bekommt als Namen das was in der jeweiligen Zelle in Spalte J steht.
3. Die erste Zeile der Arbeitsmappe soll ins neue Arbeitsblatt kopiert werden.
4. Außerdem sollen bestimmte Zellen in Spalte A bis G ins neue Arbeitsblatt kopiert werden. Das sind die Zellen ab der jeweiligen Zelle in Spalte J bis zu der Zeile in der wieder etwas steht.

Beispiel: in Zelle J2 steht "Haus", Zellen J3 bis J5 sind leer, in J6 steht "Ball"
erzeugt wird ein Arbeitsblatt mit Namen "Haus"
Die erste Zeile wird kopiert
Der Bereich A2 bis G5 wird kopiert (<-- hier ist der Fehler)

Dafür habe ich bereits ein anderes Makro umgeschrieben:

Option Explicit

Sub BlaetterAusLagerliste()
Dim rngMuster As Range, rngDaten As Range, zz As Long, ss As Long, aa As Long, bb As Long

Set rngMuster = Sheets("Lagerliste_1002_1340_201211").Rows(1) '1. Zeile speichern
aa = 1
bb = 1

With Sheets("Lagerliste_1002_1340_201211")
For zz = 2 To .Cells(.Rows.Count, 1).End(xlUp).Row + 1
For ss = 1 To Sheets.Count
If Sheets(ss).Name = CStr(.Cells(zz, 1)) Then
'Kontrolle ob Arbeitsblatt mit dem Namen bereits existiert
MsgBox "Blatt '" & .Cells(zz, 10) & "' bereits vorhanden.", vbInformation 'X
Exit For
End If
Next ss
aa = aa + 1
'aa: aktuelle Zelle
If bb < aa Then
bb = aa
End If
Hier:
If Worksheets("Lagerliste_1002_1340_201211").Cells(bb + 1, 10) = Empty Then
'bb: immer letzte leere Zelle
bb = bb + 1
GoTo Hier
End If
Set rngDaten = Worksheets("Lagerliste_1002_1340_201211").Range(Cells(aa, 1), Cells(bb, 7)) 'XXXXXXXX
'zugehörige Zellen speichern
If ss > Sheets.Count And Not Worksheets("Lagerliste_1002_1340_201211").Cells(aa, 10) = Empty Then 'kein neues Blatt falls leer
Worksheets.Add after:=Sheets(Sheets.Count) 'Erstellt neues Arbeitsblatt
rngMuster.Copy Cells(1, 1) 'Kopiert 1. Zeile ins n. Arbeitsblatt
rngDaten.Copy Cells(2, 1) 'Kopiert zugehörige Zellen ins n. Arbeitsblatt
Cells(2, 10) = .Cells(zz, 10) 'Kopiert J2 ins neue Jzz
ActiveSheet.Name = CStr(Cells(2, 10)) 'Umbenennen nach J2
End If
Next zz
End With
End Sub


Der Fehler kommt da wo XXXXXXXX steht. Das ist die Funktion, die die zu kopierende Zellen speichern soll (unter 4. erklärt).
Fehler: Laufzeitfehler '1004'
Anwendungs oder objektdefinierter Fehler.

Ich hoffe es ist alles verständlich. Benutzt wird Office 2003.

Content-Key: 195185

Url: https://administrator.de/contentid/195185

Printed on: April 19, 2024 at 07:04 o'clock

Mitglied: 76109
76109 Dec 01, 2012 updated at 10:31:26 (UTC)
Goto Top
Hallo krm5000!

Du hast zu Begin das hier stehen
With Sheets("Lagerliste_1002_1340_201211")  

Insofern genügt:
Set rngDaten = .Range(.Cells(aa, 1), .Cells(bb, 7))
wobei sich eigentlich nur die Cells-Angaben auf das Sheet beziehen müssen. Je nach Excel-Version will aber auch das Range ein Pünktchen haben wollen.

Ist die Anzahl der Leerzeilen in Spalte J bzw. die Anzahl der Kopierzeilen Spalte A:G immer gleich?

Um den Code lesbarer zu machen, solltest Du dir mal die Formatierungshilfe ansehen und Deinen Code in Code-Tags setzenface-wink

Gruß Dieter
Member: Friemler
Friemler Dec 01, 2012 updated at 16:03:06 (UTC)
Goto Top
Hallo krm5000,

das hier sollte funktionieren:
Option Explicit


Sub BlaetterAusLagerliste()
  Dim intLine As Long, intMaxLine As Long, intStartLine As Long, intEndLine As Long, intSheetNo As Long
  Dim rngMuster As Range, rngDaten As Range
  Dim strWorkSheet As String
  
  strWorkSheet = "Lagerliste_1002_1340_201211"  
  
  With Sheets(strWorkSheet)
    Set rngMuster = .Rows(1)
    intMaxLine = .Cells(.Rows.Count, 1).End(xlUp).Row
    
    For intLine = 2 To intMaxLine
      'Kontrolle ob Arbeitsblatt mit dem aktuellen Namen bereits existiert  
      For intSheetNo = 1 To Sheets.Count
        If Sheets(intSheetNo).Name = CStr(.Cells(intLine, 10)) Then
          MsgBox "Blatt '" & .Cells(intLine, 10) & "' bereits vorhanden.", vbInformation  
          Exit For
        End If
      Next intSheetNo
      
      intStartLine = intLine
      intEndLine = intLine
      
      'letzte Zeile suchen, die zum aktuellen Namen gehört  
      While Worksheets(strWorkSheet).Cells(intEndLine + 1, 10) = Empty And intEndLine < intMaxLine
        intEndLine = intEndLine + 1
      Wend
      
      Set rngDaten = Worksheets(strWorkSheet).Range(Cells(intStartLine, 1), Cells(intEndLine, 7))
      
      'Wenn noch kein Arbeitsblatt mit dem aktuellen Namen existiert die zugehörigen Zellen speichern  
      If intSheetNo > Sheets.Count Then
        Worksheets.Add after:=Sheets(Sheets.Count)          'Erstellt neues Arbeitsblatt  
        ActiveSheet.Name = CStr(.Cells(intStartLine, 10))   'Umbenennen auf den aktuellen Namen  
        ActiveSheet.Cells(2, 10) = .Cells(intStartLine, 10) 'Kopiert den aktuellen Namen  
        rngMuster.Copy ActiveSheet.Cells(1, 1)              'Kopiert 1. Zeile ins neue Arbeitsblatt  
        rngDaten.Copy ActiveSheet.Cells(2, 1)               'Kopiert zugehörige Zellen ins neue Arbeitsblatt  
      End If
      
      intLine = intEndLine
    Next intLine
  End With
End Sub

Dein Quellcode enthält verschiedene kleine Fehler. Der entscheidende war aber wohl, dass ein Äquivalent zu And intEndLine < intMaxLine bei der Abbruchbedingung der Suchschleife in den Zeilen 20 bis 22 gefehlt hat.

Gruß
Friemler
Mitglied: 76109
76109 Dec 01, 2012 updated at 09:42:54 (UTC)
Goto Top
Hallo Friemler!

Na, dann biete ich doch auch Gleich eine Lösung mit anface-wink

Option Explicit

Private Const RowsStart = 2

Sub BlaetterAusLagerliste()
    Dim Wks As Worksheet, Cell As Range, RowsEnd As Long, RowsCopyEnd As Long

    With Sheets("Lagerliste_1002_1340_201211")  
        RowsEnd = .Cells(.Rows.Count, "A").End(xlUp).Row    'Letzte Zeile in Spalte A  
        
        For Each Cell In .Range(.Cells(RowsStart, "J"), .Cells(RowsEnd, "J"))   'Alle Zellen in Spalte J  
            If Cell.Text <> "" Then     'Test Zelle nicht Leer  
                Set Wks = Nothing       'Sheet Is Nothing  
                
                'Fehlerbehandlung Aus, Set Sheet, Fehlerbehandlung wieder Ein  
                On Error Resume Next:  Set Wks = Sheets(Cell.Text):  On Error GoTo 0
                
                If Wks Is Nothing Then  'Test Sheet noch nicht vorhanden  
                    Worksheets.Add After:=Sheets(Sheets.Count) 'Erstellt neues Arbeitsblatt  
                    ActiveSheet.Name = Cell.Text    'Sheetnamen vergeben  
                    RowsCopyEnd = Cell.End(xlDown).Row - 1  'Nächste Zeile mit Inhalt - 1  
                    If RowsCopyEnd > RowsEnd Then RowsCopyEnd = RowsEnd 'Test Ende erreicht  
                   .Rows(1).Copy Rows(1)    'Kopie Zeile 1 und Zellen Spalte A:G  
                   .Range(.Cells(Cell.Row, "A"), .Cells(RowsCopyEnd, "G")).Copy Cells(RowsStart, "A")  
                Else
                    MsgBox "Blatt '" & Cell.Text & "' bereits vorhanden.", vbInformation, "Hinweis..."  
                End If
            End If
        Next
    End With
End Sub

Gruß Dieter
Member: krm5000
krm5000 Dec 01, 2012 at 14:29:51 (UTC)
Goto Top
Vielen Dank für die Antworten, werde die Lösungen gleich am Montag als erstes testen. Melde mich dann wieder.
Member: krm5000
krm5000 Dec 03, 2012 updated at 09:23:04 (UTC)
Goto Top
Es funktioniert ;) Soweit ich das beurteilen kann funktionieren alle 3 Lösungen (Anpassungen sind möglicherweise nötig). Benutze jetzt erst mal die erste Lösung von Dieter wo ich nur die eine Zeile ändern musste. Ich muss am Makro noch arbeiten weil da wohl noch was anderes mitkopiert werden soll. Vielen Dank für die Tipps und Lösungen.

Ich hätte noch eine kleine Frage zu Excel (Glaube ein Neues Thema zu erstellen ist nicht nötig):
Wenn ich zb mit der Funktion: =WENN(ZÄHLENWENN($A$2:$A$9456;Mappe2!E4)=0;"nicht vorhanden";"vorhanden")
auf eine andere Exceldatei verweisen möchte, muss diese Datei dann unbedingt gespeichert worden sein (und nicht einfach nur offen)?

Das sind nämlich Dateien mit denen verschiedene Werte/Konfigurationen von einem CAD-Programm gesteuert werden. Sie werden vom Programm generiert und nicht als Exceldatei abgespeichert.

//EDIT: Ich ziehe meine Frage zurück.. Es klappt doch ohne zu speichern. Keine Ahnung wieso er vorhin nicht wollte.