online 1
gast (50)

/ Forum / Tabellenkalkulation

TabellenkalkulationTabellenkalkulation

Fragevon Petra65 vom 03.10.2021, 11:21 Options

Lösung

Tabellen eines Ordners auslesen und in eine Tabelle zusammenführen

Hallo,

ich stehe mal wieder vor einem VBA-Problem und kann es nicht lösen (trotz ähnlicher Fragen hier) ;-(

Ich habe einen Ordner mit zur zeit 123 Tabellen (es werden täglich mehr), der Aufbau dieser Tabellen ist komplett gleich.
Nun möchte ich bestimmte Werte automatisch in eine andere Tabelle (einfach untereinander) übernehmen, und zwar so:

Tabellen im Ordner (1.xls, 2.xls, 3.xls, usw....)
Hier soll das 1. Tabellenblatt angesprochen werden (Tabelle1)
Alle Werte, die in B10 bis H..... (Ende immer unterschiedlich) sollen in den Bereich E5 bis K ... übernommen werden. Zusätzlich sollen in jeder Zeile
der Wert aus C3 in die Spalte A
der Wert aus C4 in die Spalte B
der Wert aus C5 in die Spalte C
der Wert aus C6 in die Spalte D

Tabelle Auswertung
Ab A5 soll diese Tabelle gefüllt werden

Genial wäre es, wenn man das zusätzlich noch nach Jahren trennen könnte (das Datum steht in der Spalte B der einzelnen Tabellen. Wenn also eine Abfrge wäre ... Wenn B = 2009, dann kopiere die Daten ... ??

Oh jeee ... ich hoffe echt auf Anregungen ....

Viele Grüße - Petra


Antwort schreiben

Antwort 1 von malSchauen vom 03.10.2021, 14:10 Options

Hi,

Schau doch mal, ob Du etwas aus dieser Datei für Dich verwenden kannst.

btw: Datum
Was heisst das genau?
Heisst das im Bereich
Zitat:
B10 bis H..... (Ende immer unterschiedlich)
können in den Zellen B10 bis B.... immer unterschiedliche Jahreszahlen stehen? Oder ist das pro Quelldatei immer nur ein und dieselbe Jahreszahl?

Bye
malSchauen

Antwort 2 von Petra65 vom 03.10.2021, 16:06 Options

Hi,

.... da brauche ich ja Stunden zum durchwühlen ;-))))

Aber grundsätzlich funktioniert es schonmal - außer der Tatsache, dass die Werte aus C3, C4, C5 und C6 nur einmal pro Tabelle übertragen werden.

In der Spalte B kommen übrigens die Jahre 2008 und 2009 vor, die Trennung der Jahre muss nicht zwingend sein (ich habe mir nur gedacht, dass das Makro schneller ausgeführt wird wenn weniger Daten zu suchen sind ??)

Ich habe mal 2 Tabellen (1.xls und Behandlungen.xls) online gestellt, daraus wird dann - so hoffe ich - ersichtlich was ich meine....

Tabelle 1.xls
http://www.file-upload.net/download-1923734/1.xls.html


Tabelle Behandlungen.xls
http://www.file-upload.net/download-1923730/MB_Behandlungen.xls.html


Vielen Dank schonmal ....

Gruss - Petra

Antwort 3 von coros vom 03.10.2021, 18:59 Options

Hallo Petra,

nachfogendes Makro kopiert Dir die Daten aller Dateien in einem Pfad in Deine Übersichtsdatei.

Kopiere das Makro in Deine Datei "MB_Behandlungen.xls" in ein StandardModul und starte es z.B. über eine Befehlsschaltfläche.
Teste das Makro aber bitte in einer Testdatei und nicht gleich in Deiner Originaldatei.

Option Explicit

Const strPath = "C:\Eigene Dateien"

Sub Dateien_auslesen()
Dim Datei$
Dim lngFirstRow As Long
Dim lngLastRow As Long
Dim lngCopyRow As Long

Datei = Dir(strPath & "\*.xls")
Do While Datei <> ""
    If Right(Datei, 4) = ".xls" Then
        GetObject (strPath & "\" & Datei)
        lngFirstRow = ActiveSheet.Cells(Rows.Count, 2).End(xlUp).Offset(1, 0).Row
        lngLastRow = Workbooks(Datei).Sheets(1).Cells(Rows.Count, 2).End(xlUp).Row
        lngCopyRow = lngFirstRow + (lngLastRow - 10)
        
        With Workbooks(Datei).Sheets(1)
            'Behandlungsdaten
            .Range("B10:H" & lngLastRow).Copy ActiveSheet.Cells(lngFirstRow, 5)
            'Kundenummer
            ActiveSheet.Range("A" & lngFirstRow & ":A" & lngCopyRow) = .Range("C3")
            'Nachname
            ActiveSheet.Range("B" & lngFirstRow & ":B" & lngCopyRow) = .Range("C4")
            'Vorname
            ActiveSheet.Range("C" & lngFirstRow & ":C" & lngCopyRow) = .Range("C5")
            'Abrechnung
            ActiveSheet.Range("D" & lngFirstRow & ":D" & lngCopyRow) = .Range("C6")
        End With
        
        Workbooks(Datei).Close
    End If
    Datei = Dir()
Loop
End Sub
In dem Makro musst Du in der Zeile

Const strPath = "C:\Eigene Dateien"
noch den Pfad, in dem sich die auszulesenden Dateien, anpassen.

Solltest Du nicht wissen, wie Du den Code in Deine Datei bekommst, dann schau mal auf meiner HP in der Rubrik Anleitungen und dort dann in der Anleitungsnummer 3 nach. Dort stelle ich dazu eine bebilderte Anleitung zur Verfügung, die Dir sicherlich helfen wird.

Bei Fragen melde Dich.

MfG,
Oliver
Da hier der einzige Lohn für die Helfer eine Rückmeldung ist, wäre es nett, wenn Du
ein Feedback abgeben könntest, ob der Lösungsvorschlag Dein Problem gelöst hat.

Antwort 4 von Petra65 vom 03.10.2021, 21:03 Options

Hi,

sieht schon super gut aus, ansich funktioniert es einwandfrei, allerdings sind nun 2 neue Probleme aufgetaucht:

1. Excel wackelt ;-)) fürchterlich ... man sieht also, dass etwas passiert, ich habe Application.DisplayAlerts = False eingefügt ... doch garantiert wieder an der falschen Stelle ...

2. Es werden auch leere Datensätze übernommen (das hatte ich vorher gar nicht bedacht). Es existieren Tabellen, in denen keine Daten vorhanden sind, diese brauchen dann ja auch gar nicht übertragen werden.
Also brauche ich eine If-Abfrage ... mein Ansatz wäre
If ActiveSheet.Range("B10") = "" Then
doch dann?? es soll ja kein Abbruch erfolgen??


Hier der geänderte Code:

Option Explicit

Const strPath = "C:\Users\Petra\Desktop\Behandlungen"

Sub Dateien_auslesen()
Dim Datei$
Dim lngFirstRow As Long
Dim lngLastRow As Long
Dim lngCopyRow As Long

[A5:k65000] = "" 'Alte Eintragungen löschen

Datei = Dir(strPath & "\*.xls")
Application.AskToUpdateLinks = False 'deaktiviert Aktualisierung

Do While Datei <> ""
Application.DisplayAlerts = False 'HIER oder WO ???

If Right(Datei, 4) = ".xls" Then
GetObject (strPath & "\" & Datei)
lngFirstRow = ActiveSheet.Cells(Rows.Count, 2).End(xlUp).Offset(1, 0).Row
lngLastRow = Workbooks(Datei).Sheets(1).Cells(Rows.Count, 2).End(xlUp).Row
lngCopyRow = lngFirstRow + (lngLastRow - 10)

With Workbooks(Datei).Sheets(1)
If ActiveSheet.Range("B10") = "" Then
'???????
.Range("B10:H" & lngLastRow).Copy ActiveSheet.Cells(lngFirstRow, 5) 'Behandlungsdaten
ActiveSheet.Range("A" & lngFirstRow & ":A" & lngCopyRow) = .Range("C3") 'Kundennummer
ActiveSheet.Range("B" & lngFirstRow & ":B" & lngCopyRow) = .Range("C4") 'Nachname
ActiveSheet.Range("C" & lngFirstRow & ":C" & lngCopyRow) = .Range("C5") 'Vorname
ActiveSheet.Range("D" & lngFirstRow & ":D" & lngCopyRow) = .Range("C6") 'Abrechnung
End With

Workbooks(Datei).Close
End If
Datei = Dir()
Loop
Application.DisplayAlerts = True
End Sub

Antwort 5 von Petra65 vom 03.10.2021, 21:14 Options

... ähm wie blöd ....

habe zum Abschalten des Bildschirms den falschen Code angewendet, mit Application.ScreenUpdating = False funktioniert es einwandfrei ..

bleibt also noch 1 Problem ;-)


Gruss - Petra

Antwort 6 von coros vom 04.10.2021, 06:24 OptionsLösung

Lösung
Hallo Petra,

nachfolgendes Makro sollte das machen, was Du meintest.

Option Explicit

Const strPath = "C:\Eigene Dateien"

Sub Dateien_auslesen()
Dim Datei$
Dim lngFirstRow As Long
Dim lngLastRow As Long
Dim lngCopyRow As Long

Application.ScreenUpdating = False

Datei = Dir(strPath & "\*.xls")
Do While Datei <> ""
    If Right(Datei, 4) = ".xls" Then
        GetObject (strPath & "\" & Datei)
        If Workbooks(Datei).Sheets(1).Range("B10") <> 0 Then
            lngFirstRow = ActiveSheet.Cells(Rows.Count, 2).End(xlUp).Offset(1, 0).Row
            lngLastRow = Workbooks(Datei).Sheets(1).Cells(Rows.Count, 2).End(xlUp).Row
            lngCopyRow = lngFirstRow + (lngLastRow - 10)
            
            With Workbooks(Datei).Sheets(1)
                'Behandlungsdaten
                .Range("B10:H" & lngLastRow).Copy ActiveSheet.Cells(lngFirstRow, 5)
                'Kundenummer
                ActiveSheet.Range("A" & lngFirstRow & ":A" & lngCopyRow) = .Range("C3")
                'Nachname
                ActiveSheet.Range("B" & lngFirstRow & ":B" & lngCopyRow) = .Range("C4")
                'Vorname
                ActiveSheet.Range("C" & lngFirstRow & ":C" & lngCopyRow) = .Range("C5")
                'Abrechnung
                ActiveSheet.Range("D" & lngFirstRow & ":D" & lngCopyRow) = .Range("C6")
            End With
        End If
        Workbooks(Datei).Close
    End If
    Datei = Dir()
Loop
End Sub
MfG,
Oliver
Da hier der einzige Lohn für die Helfer eine Rückmeldung ist, wäre es nett, wenn Du
ein Feedback abgeben könntest, ob der Lösungsvorschlag Dein Problem gelöst hat.

Antwort 7 von Petra65 vom 04.10.2021, 07:17 Options

Hallol,

perfekt, nun funkzt es einwandfrei .....

Aber mal noch eine Frage zum Verständnis:

In der Zeile If Right(Datei, 4) = ".xls" Then WOFÜR ist
die 4 ??

Vielen, vielen Dank ;-))


Gruss - Petra

Antwort 8 von coros vom 04.10.2021, 07:23 Options

Hallo Petra,

gerne geschehen. Die Zahl 4 steht für 4 Buchstaben. Also wenn der Dateiname von rechts gelesen mit 4 Buchstaben den Text ".xls" ergibt dann....

Danke auch für die Rückmeldung.

So, ich schau dann mal weiter Formel1.

MfG,
Oliver
Da hier der einzige Lohn für die Helfer eine Rückmeldung ist, wäre es nett, wenn Du
ein Feedback abgeben könntest, ob der Lösungsvorschlag Dein Problem gelöst hat.

Antwort 9 von malSchauen vom 04.10.2021, 14:32 Options

Hi,

@Petra65
Zitat:
.... da brauche ich ja Stunden zum durchwühlen ;-))))


Stimmt auffallend. Das was bei mir da im VBA-Editor landet, ist zwar meist funktionsfähig, aber wie ich zugeben muss, sehr schlecht zu lesen und zu pflegen. Da habe ich noch sehr viel zu üben und zu lernen. Da ist der Code von Coros doch deutlich besser strukturiert/aufgebaut.

Wie es auch sei, Dir wurde von Coros geholfen, und dadurch dass ich für mich das Problem durchdacht habe, kann auch ich anhand des Codes von Coros weiter lernen, wie man entsprrechenden Code aufbauen und strukturieren kann.

Also nichts für ungut...
malSchauen

Antwort 10 von Petra65 vom 04.10.2021, 17:22 Options

Hi malSchauen,

Zitat:
Stimmt auffallend. Das was bei mir da im VBA-Editor landet, ist zwar meist funktionsfähig ... ...


Das, was bei mir im VBA-Editor landet (abgesehen von Code-Aufzeichnungen) funktioniert meist leider nicht !!! Ich drehe mich stets im Kreis und finde den Lösungsansatz nicht ;-(

Sei froh, dass Deine Codes, wenn auch etwas unübersichtlich, funktionieren ;-)

Viele Grüße - Petra

Antwort 11 von Petra65 vom 11.10.2021, 09:45 Options

Hallo, guten Morgen,

ich muss leider die Frage nochmals nach oben holen, da der Code aus Antwort 6 folgendes nicht berücksichtigt:

Es kann sein, dass in A10 eine 1 steht, aber in A11 eine 2.

Ich möchte nun, dass die Daten folgendermassen übertragen werden, z. B. wenn
B10 <> 0 UND A10 = 1 -> übertragen
B11 <> 0 UND A11 = 2 -> nicht übertragen
usw.

Das Problem ist (so glaube ich), dass der Code nur B10 auf ungleich Null abfängt (ist also B10 ungleich Null, so werden ALLE Daten übertragen).
Ich weiss nun nicht wie kompliziert es ist den Code zu ändern.

Ich hoffe auf Denkanstösse ;-)

Gruss - Petra

Antwort 12 von nighty vom 11.10.2021, 11:23 Options

hi malSchauen und der rest der welt ^^

hier ein highlight fuer dich und alle anderen motivierten vb freaks *hihi*

gruss nighty

VBAHTML 2.0.0.0 alpha 2 von Lukas Mosimann

ein addinn zum einruecken des codes *mein liebling hrhrrr*

hier der link

http://vbahtml.origo.ethz.ch/download

Antwort 13 von coros vom 11.10.2021, 14:44 Options

Hallo Petra,

Du gibst Dir die Antwort doch bereits selber in Deiner Datei mit Deiner Aussage

Zitat:
Ich möchte nun, dass die Daten folgendermassen übertragen werden, z. B. wenn
B10 <> 0 UND A10 = 1 -> übertragen

Dann änbdere doch auch die Zeile

If Workbooks(Datei).Sheets(1).Range("B10") <> 0 Then
in

If Workbooks(Datei).Sheets(1).Range("B10") <> 0 And Workbooks(Datei).Sheets(1).Range("A10") = 1 Then


MfG,
Oliver
Da hier der einzige Lohn für die Helfer eine Rückmeldung ist, wäre es nett, wenn Du
ein Feedback abgeben könntest, ob der Lösungsvorschlag Dein Problem gelöst hat.

Antwort 14 von malSchauen vom 11.10.2021, 15:13 Options

Hi,

Ich glaube ja eher, Petra meint das Zeile für Zeile. Also aus der .Range("B10:H" & lngLastRow) nur die Zeilen zu kopieren, die in SpalteA eine 1 stehen haben. Wenn das so ist, könnte das funktionieren wie folgt (Code aus AW6 abgeändert):

Sub Dateien_auslesen()
Dim Datei$
Dim lngFirstRow As Long
Dim lngLastRow As Long
Dim lngCopyRow As Long
Dim lngCount As Long
Application.ScreenUpdating = False

Datei = Dir(strPath & "\*.xls")
Do While Datei <> ""
    If Right(Datei, 4) = ".xls" Then
        GetObject (strPath & "\" & Datei)
        If Workbooks(Datei).Sheets(1).Range("B10") <> 0 Then
            lngFirstRow = ActiveSheet.Cells(Rows.Count, 2).End(xlUp).Offset(1, 0).Row
            lngLastRow = Workbooks(Datei).Sheets(1).Cells(Rows.Count, 2).End(xlUp).Row
            lngCopyRow = 0
            
            With Workbooks(Datei).Sheets(1)
                For lngCount = 10 To lngLastRow
                  If .Range("A" & lngCount).Value = 1 Then
                    'Behandlungsdaten
                    .Range("B" & lngCount & ":H" & lngCount).Copy _
                    ActiveSheet.Cells(lngFirstRow + lngCopyRow, 5)
                    lngCopyRow = lngCopyRow + 1
                  End If
                Next
                lngCopyRow = lngCopyRow + lngFirstRow - 1
                'Kundenummer
                ActiveSheet.Range("A" & lngFirstRow & ":A" & lngCopyRow) = .Range("C3")
                'Nachname
                ActiveSheet.Range("B" & lngFirstRow & ":B" & lngCopyRow) = .Range("C4")
                'Vorname
                ActiveSheet.Range("C" & lngFirstRow & ":C" & lngCopyRow) = .Range("C5")
                'Abrechnung
                ActiveSheet.Range("D" & lngFirstRow & ":D" & lngCopyRow) = .Range("C6")
            End With
        End If
        Workbooks(Datei).Close
    End If
    Datei = Dir()
Loop
Application.ScreenUpdating = True
End Sub


bye
malSchauen

Antwort 15 von malSchauen vom 11.10.2021, 16:00 Options

Hi,

Noch eine Änderung für den Fall, dass alle Behandlungen in der Quelle der Kategorie2 zugehören. (B10 ist nicht leer, aber es wird auch nichts kopiert.) Dann dürfen nat. keine Kundendaten übertragen werden.

.
.
.
                Next
                If lngCopyRow > 0 Then         ' wenn mindestens eine Zeile kopiert
                  lngCopyRow = lngCopyRow + lngFirstRow - 1
                  'Kundenummer
                  ActiveSheet.Range("A" & lngFirstRow & ":A" & lngCopyRow) = .Range("C3")
                  'Nachname
                  ActiveSheet.Range("B" & lngFirstRow & ":B" & lngCopyRow) = .Range("C4")
                  'Vorname
                  ActiveSheet.Range("C" & lngFirstRow & ":C" & lngCopyRow) = .Range("C5")
                  'Abrechnung
                  ActiveSheet.Range("D" & lngFirstRow & ":D" & lngCopyRow) = .Range("C6")
                End If
            End With
.
.
.


bye
malSchauen

Antwort 16 von Petra65 vom 11.10.2021, 17:59 Options

Hi,

Ich habe oben stehenden Code in einer Testdatei getestet, seither erhalte ich selbst bei Makros - die bisher fehlerfrei funktionierten - folgende Fehlermeldung:

Laufzeitfehler 1004
Die Methode 'Rows' für das Objekt '_Global" ist fehlgeschlagen

Diese Makros enthalten ALLE folgende Codezeile, die als fehlerhaft angezeigt wird:
lngFirstRow = ActiveSheet.Cells(Rows.Count, 2).End(xlUp).Offset(1, 0).Row

Und alle Dateien liegen im selben Ordner, Sicherungsdateien (andere Ordner) der letzten Tage funktionieren fehlerlos.

Ich stelle nun erstmal den letzen funktionierenden Zustand her ... melde mich aber auf jeden Fall nochmal - kann etwas dauern ;-)

Bisher erstmal vielen Dank für Eure Hilfe


Gruss - Petra

Antwort 17 von malSchauen vom 11.10.2021, 19:09 Options

Hi,

Sollte der von mir abgeänderte Code aus AW14&15 dafür verantwortlich sein, dann bitte ich um Entschuldigung. Ich kann es mir aber nicht erklären, wie das zustande kommen kann. Evtl. kann mich jemand der hier noch mitliest und dieses Problem identifizieren kann über die Ursache/den Fehler in meinem Code aufklären.
Führt denn evtl. eine CodeZeile die mit "_" auf die folgende Zeile verlängert wird, beim Kopieren hier aus dem Forum zu einem solchen Problem? Ich habe es versucht das Problem hier nachzustellen, aber nach dem Einfügen läuft es klaglos, sodass ich den Fehler nicht nachvollziehen kann.

Petra: So Du Dich noch traust Code aus meinen Postings zu verwenden, so folgt hier, für den Fall dass es tatsächlich daran liegen sollte, nocheinmal das Makro ohne "Zeilenerweiterung" bei 'Behandlungsdaten:
Option Explicit

Const strPath = "C:\Eigene Dateien"

Sub Dateien_auslesen()
Dim Datei$
Dim lngFirstRow As Long
Dim lngLastRow As Long
Dim lngCopyRow As Long
Dim lngCount As Long

Application.ScreenUpdating = False

Datei = Dir(strPath & "\*.xls")
Do While Datei <> ""
  If Right(Datei, 4) = ".xls" Then
    GetObject (strPath & "\" & Datei)
    If Workbooks(Datei).Sheets(1).Range("B10") <> 0 Then
      lngFirstRow = ActiveSheet.Cells(Rows.Count, 2).End(xlUp).Offset(1, 0).Row
      lngLastRow = Workbooks(Datei).Sheets(1).Cells(Rows.Count, 2).End(xlUp).Row
      lngCopyRow = 0
      
      With Workbooks(Datei).Sheets(1)
        For lngCount = 10 To lngLastRow
          If .Range("A" & lngCount).Value = 1 Then
            'Behandlungsdaten
            .Range("B" & lngCount & ":H" & lngCount).Copy ActiveSheet.Cells(lngFirstRow + lngCopyRow, 5)
            lngCopyRow = lngCopyRow + 1
          End If
        Next
        If lngCopyRow > 0 Then         ' wenn mindestens eine Zeile kopiert
          lngCopyRow = lngCopyRow + lngFirstRow - 1
          'Kundenummer
          ActiveSheet.Range("A" & lngFirstRow & ":A" & lngCopyRow) = .Range("C3")
          'Nachname
          ActiveSheet.Range("B" & lngFirstRow & ":B" & lngCopyRow) = .Range("C4")
          'Vorname
          ActiveSheet.Range("C" & lngFirstRow & ":C" & lngCopyRow) = .Range("C5")
          'Abrechnung
          ActiveSheet.Range("D" & lngFirstRow & ":D" & lngCopyRow) = .Range("C6")
        End If
      End With
    End If
    Workbooks(Datei).Close
  End If
  Datei = Dir()
Loop
Application.ScreenUpdating = True

End Sub


bye
malSchauen

Antwort 18 von Petra65 vom 11.10.2021, 19:56 Options

Hi malSchauen,

Zitat:
Petra: So Du Dich noch traust Code aus meinen Postings zu verwenden ...


Na klar ... immer her damit ;-)))

Mach Dir mal keinen "Kopf" ob es an dem Code lag .... das Risiko liegt ja wohl bei mir !! !!
Ich bin ja unheimnlich froh wenn ich hier Hilfe bekomme - alleine könnte ich das niemals lösen.

Aber was anderes: Dein Code funktioniert super gut ;-) ...
Vielen vielen Dank dafür

Gruss - Petra

Ähnliche Themen

Tabelle auslesen in EXCEL 2007
leflo  02.06.2008 - 13 Hits - 10 Antworten

Makro für Auswahl aus Tabelle und Kopieren in leere Tabelle
JNS  27.10.2008 - 180 Hits - 4 Antworten

Excel Tabellen/Matrix auslesen
Unlogisch  14.11.2008 - 57 Hits - 6 Antworten

Wert aus 2 Spalten Tabelle auslesen
Bananakurti  23.10.2009 - 223 Hits - 9 Antworten

Hinweis

Diese Frage ist schon etwas älter, Sie können daher nicht mehr auf sie antworten. Sollte Ihre Frage noch nicht gelöst sein, stellen Sie einfach eine neue Frage im Forum..

Neue Einträge

Version: supportware 1.9.150 / 10.06.2022, Startzeit:Thu Jan 8 21:07:44 2026