Live-Forum - Die aktuellen Beiträge
Datum
Titel
03.05.2024 10:49:02
03.05.2024 10:43:56
03.05.2024 07:38:32
Anzeige
Archiv - Navigation
1928to1932
Aktuelles Verzeichnis
Verzeichnis Index
Übersicht Verzeichnisse
Vorheriger Thread
Rückwärts Blättern
Nächster Thread
Vorwärts blättern
Anzeige
HERBERS
Excel-Forum (Archiv)
20+ Jahre Excel-Kompetenz: Von Anwendern, für Anwender
Inhaltsverzeichnis

Import aus Word

Import aus Word
24.04.2023 12:08:24
Ron

Hallo,
wer kann mir helfen und ggf. den Code optimieren.
Ich möchte den Inhalt von großen Word-Dateien einlesen und verarbeiten.
Leider ist die Verarbeitungsgeschwindigkeit nicht sehr gut.
Kann jemand Hand anlegen?

Option Explicit

Sub Datei_auswählen()

    Dim Dateiname As Variant
    Dim wdApp As Object
    Dim wdDoc As Object
    Dim filename As Variant
    Dim newSheet As Worksheet
    Dim cell As Range
    Dim regEx As Object
    Dim lastRow As Long
    Dim i As Long
    Dim a As Integer
    Dim searchRange As Range
    Dim matchPattern As String
    Dim letzteZeile As Long
    Dim rng As Range

    Set wdApp = CreateObject("Word.Application")

...
        
        'Ordner wählen, wo die Dateien abgelegt sind
        ChDrive "C"
        ChDir "C:\dokumente\Nummer\" & Range("F1") & "\dokumente\arbeitsbogen\"
        'Nur Word-Dokumente anzeigen und auswählen
        Dateiname = Application.GetOpenFilename("Word-Dokumente (*.docx*),*.doc*", , "Wählen Sie eine oder mehrere Word Dateien aus", , True)
        'Wurde eine Datei ausgewählt?
        If Not IsEmpty(Dateiname) Then
            'Für jede ausgewählte Datei den folgenden Code ausführen
            For a = LBound(Dateiname) To UBound(Dateiname)
                'Neues Arbeitsblatt erstellen
                Set newSheet = ThisWorkbook.Sheets.Add(after:= _
                                ThisWorkbook.Sheets(ThisWorkbook.Sheets.Count))
                newSheet.Name = a + 1 'Name des Arbeitsblatts auf "1", "2", "3", usw. setzen
                'Word-Dokument öffnen
                Set wdApp = CreateObject("Word.Application")
                Set wdDoc = wdApp.Documents.Open(Dateiname(a))
                'Inhalt kopieren
                wdDoc.Content.Copy
                'In Zelle A1 des aktuellen Arbeitsblatts einfügen
                With newSheet
                    Range("A1").PasteSpecial Paste:=xlPasteValues
                End With
                'Word schließen
                wdDoc.Close SaveChanges:=False
                wdApp.Quit
                'Objekte freigeben
                Set wdDoc = Nothing
                Set wdApp = Nothing
                'Zeilen löschen, die die Suchwörter nicht enthalten
                lastRow = newSheet.Cells(newSheet.Rows.Count, "A").End(xlUp).Row
                Set searchRange = newSheet.Range("A1:A" & lastRow)
                matchPattern = "\babc\b" _
                            & "|\bdef\b" _
                            & "|\bghi\b" _
                            & "|\bjkl\b" _
                            & "|\bmno\b" _
                            & "|\bjke\b" _
                            & "|\bpqr\b" _
                            & "|\bstz\b" _
                            & "|\buvw\b" _
                            & "|\bwvi\b" _
                            & "|\bVorname\b" _
                            & "|\bwww\b" _
                            & "|\bxxx\b"
                Set regEx = CreateObject("VBScript.RegExp")
                regEx.Pattern = matchPattern
                regEx.Global = True
                For i = lastRow To 1 Step -1
                    Set cell = searchRange.Cells(i, 1)
                    If Not regEx.Test(cell.Value) Then
                        cell.EntireRow.Delete
                    End If
                Next i
                'Leerzeichen aus Splate "A" vor den Wörtern entfernen
                'finde die letzte Zeile mit Inhalt in Spalte B
                letzteZeile = Cells(Rows.Count, "B").End(xlUp).Row
                'Den Bereich auswählen und markieren
                Range("A1:A" & letzteZeile).Select
                Set rng = Selection
                For Each cell In rng 'Schleife durch alle ausgewählten Zellen
                    'Ersetzen Sie alle Leerzeichen in der Zelle durch nichts
                    cell.Value = Replace(cell.Value, " ", "")
                    'Entfernen Sie alle verbleibenden Leerzeichen am Anfang und Ende der Zelle
                    cell.Value = Trim(cell.Value)
                Next cell
                Range("A1").Select
                'finde die letzte Zeile mit Inhalt in Spalte A
                lastRow = Cells(Rows.Count, "A").End(xlUp).Row
                'gehe alle Zeilen von 1 bis zur letzten Zeile durch
                For i = 1 To lastRow
                    'wenn der Wert in Spalte A ist
                    If Range("A" & i).Value = "def" Or _
                        Range("A" & i).Value = "ghi" Or _
                        Range("A" & i).Value = "mno" Then
                        'konvertiere den Wert in Spalte B zu einem Datum
                        Range("B" & i).Value = DateValue(Range("B" & i).Value)
                        Range("B" & i).NumberFormat = "dd.mm.yyyy"
                    End If
                Next i
                'gehe alle Zeilen von 1 bis zur letzten Zeile durch
                For i = 1 To lastRow
                    'wenn der Wert in Spalte A ist
                    If Range("A" & i).Value = "jkl" Then
                        'konvertiere den Wert in Spalte B zu einem vierstelligen Text um
                        Range("B" & i).Value = Format(Range("B" & i).Value, "0000")
                        Range("B" & i).NumberFormat = "0000"
                    End If
                Next i
                'füge hinter jedem Wort "abc" "mno" ein, wenn nicht schon vorhanden
                lastRow = Range("A" & Rows.Count).End(xlUp).Row
                
                For i = lastRow To 1 Step -1
                    If Range("A" & i).Value = "abc" Then
                        If i  lastRow And Range("A" & i + 1).Value > "mno" Then
                            Rows(i + 1).Insert
                            Range("A" & i + 1).Value = "mno"
                            Range("B" & i + 1).Value = "---"
                        End If
                    End If
                Next i
                'Daten in Tabellenblatt 2 kopieren
                letzteZeile = Cells(Rows.Count, "A").End(xlUp).Row
                For i = 1 To letzteZeile
                
                    If Range("A" & i).Value = "abc" Then
                        Tabelle2.Range("A" & Rows.Count).End(xlUp).Offset(1, 0).Value = Range("B" & i).Value
                    End If
                    If Range("A" & i).Value = "def" Then
                        Tabelle2.Range("B" & Rows.Count).End(xlUp).Offset(1, 0).Value = Range("B" & i).Value
                    End If
                    If Range("A" & i).Value = "mno" Then
                        Tabelle2.Range("C" & Rows.Count).End(xlUp).Offset(1, 0).Value = Range("B" & i).Value
                    End If
                    If Range("A" & i).Value = "ghi" Then
                        Tabelle2.Range("D" & Rows.Count).End(xlUp).Offset(1, 0).Value = Range("B" & i).Value
                    End If
                    If Range("A" & i).Value = "pqr" Then
                        Tabelle2.Range("E" & Rows.Count).End(xlUp).Offset(1, 0).Value = Range("B" & i).Value
                    End If
                    If Range("A" & i).Value = "wvi" Or Range("A" & i).Value = "www" Then
                        Tabelle2.Range("F" & Rows.Count).End(xlUp).Offset(1, 0).Value = Range("B" & i).Value
                    End If
                    If Range("A" & i).Value = "stz" Then
                        Tabelle2.Range("G" & Rows.Count).End(xlUp).Offset(1, 0).Value = Range("B" & i).Value
                    End If
                    If Range("A" & i).Value = "uvw" Then
                        Tabelle2.Range("H" & Rows.Count).End(xlUp).Offset(1, 0).Value = Range("B" & i).Value
                    End If
                    If Range("A" & i).Value = "jkl" Then
                        Tabelle2.Range("I" & Rows.Count).End(xlUp).Offset(1, 0).Value = Range("B" & i).Value
                    End If
                    If Range("A" & i).Value = "xxx" Then
                        Tabelle2.Range("J" & Rows.Count).End(xlUp).Offset(1, 0).Value = Range("B" & i).Value
                    End If
                Next i
                'Arbeitsblatt ohne speichern schließen
                Application.DisplayAlerts = False
                newSheet.Delete
                Application.DisplayAlerts = True   
            Next a
        End If

...
               
End Sub

Danke

11
Beiträge zum Forumthread
Beiträge zu diesem Forumthread

Betreff
Datum
Anwender
Anzeige
AW: Import aus Word
24.04.2023 12:44:22
MCO
Hallo Ron!

Was mir so auffällt:

Du verarbeitest eine Menge Dateien und öffnest sie logischerweise. Aber WORD musst du eigentlich nur 1x öffnen und schließen.

 Set wdApp = CreateObject("Word.Application")
            For a = LBound(Dateiname) To UBound(Dateiname)
                'Neues Arbeitsblatt erstellen
                Set newSheet = ThisWorkbook.Sheets.Add(after:= _
                                ThisWorkbook.Sheets(ThisWorkbook.Sheets.Count))
                newSheet.Name = a + 1 'Name des Arbeitsblatts auf "1", "2", "3", usw. setzen
                'Word-Dokument öffnen
                'Set wdApp = CreateObject("Word.Application")
                Set wdDoc = wdApp.Documents.Open(Dateiname(a))
und natürlich die Application auch nur 1x schließen

next a
wdApp.Quit
set wdApp = nothing
Jedesmal das Programm öffnen, wenn du nur eine Reihe von Dokumenten öffenen willst ist vielleicht schon deine Bremse...

Probiers mal, Rückmeldung wäre hilfreich
Gruß MCO


Anzeige
AW: Import aus Word
24.04.2023 13:19:31
Ron
Hallo MCO,
das werde ich mal ändern, danke.
Richtig viel Zeit braucht er aber, wenn die Daten in Excel kopiert sind und aufbereitet werden.
Grüße


AW: Import aus Word
24.04.2023 13:28:49
MCO
Das mag sein, aber das werd ich nicht nachbauen.

du kannst noch versuchen, die Ereignisse und Bildschirmaktualisierung abzuschalten:

Application.enabelevents = false
Application.screenupdating = false
Achtung!
Events müssen am Ende wieder eingeschaltet werden!
Application.enabelevents = true
Gruß, MCO


Anzeige
AW: Import aus Word
24.04.2023 15:02:16
Luschi
Hallo Ron,

dieser Vba-Code schreit ja förmlich nach Verbesserung, hier mal die wichtigsten Punkte:
- x-mal der Zugriff auf Range("A" & i).Value - das ist einfach viel zu langsam
- lese den Wert 1x in 1 Speichervariable und vergleiche diese mit den Vorgabewerten
- jeder 'cell.EntireRow.Delete' Befehl löst seit Excel 2013 intern 1 Neu-Berechnen-Befehl aus
  und tritt damit auf das Bremspedal
  Ausweg: sammle die cell-Objekte in eine Range-Variable rgX und lösche dann mit
  rgX.EntireRow.Delete
- streue in diesen Schleifen die 'DoEvents'-Funktion ein (warum? siehe Vba-Online-Hilfe)
- suche mal nach der Vba-Routine 'GetMoreSpeed' im I-Net
  da stehen alle die Befehle drin., die die Excel-Bremsen bei der Abarbeitung von Makros
  lösen
- stelle mal eins/zwei Demo-Worddateien bereit
  und ich stelle mein Vba-Helfer-Syndrom auf On

Gruß von Luschi
aus klein-Paris




Anzeige
AW: Import aus Word
24.04.2023 15:49:25
Ron
Hallo Luschi,
das klingt alles sehr kopliziert für mich. Dazu reichen meine Kenntnisse bei weitem nicht aus.
Gerne würde ich eine Musterdatei hochladen, aber sie ist zu groß und ich müsste unendlich viel ändern (Datenschutz).
Trotzdem vielen Dank


AW: Import aus Word
25.04.2023 08:02:02
Luschi
Hallo Ron,

und wie soll man Dir jetzt helfen, wenn Du keine abgespeckte und datenschutzbereinigte Demo-Worddatei bereitstellen kannst.
Den Excel-Vba-Code würde ich ja ummodeln, aber eine ungefähre Vorstellung vom Inhalt der Worddatei, der in Excel eingelesen wird, möchte ich schon haben.

Gruß von Luschi
aus klein-Paris


Anzeige
AW: Import aus Word
25.04.2023 11:33:14
Ron
Hallo Luschi,
das ist mir schon bewusst. Aber der Aufwand wäre mir zu groß.
Trotzdem danke...


AW: Import aus Word
24.04.2023 17:53:39
Daniel
Hi
es wäre schon ganz nett, wenn du beschreibst, was das makro machen soll, dann muss man nicht den Code rückwärts interpretieren.
du änderst hier die Anordnung von einspaltig linear in mehrspaltig.

probiers mal mit diesem Code, nach dem du den Text aus Word in die Spalte A von NewSheet eingefügt hast:

Dim Daten
Dim Erg
Dim Spalten
Dim z As Long
Dim s As Variant
Dim zD As Long
Dim letzteZeile As Long

Spalten = Array("abc", "def", "mno", "ghi", "pqr", "wvi", "stz", "uvw", "jkl", "xxx")

'--- hier der Code um die Daten in Word zu kopieren
'--- nach dem Schließen von Word dann dieser Code
'--- NewSheet sollte aktiv sein


With NewSheet
    letzteZeile = .Cells(Rows.Count, "B").End(xlUp).Row
    .Columns(1).Replace " ", "", xlPart
    Daten = .Range("A1:A" & letzteZeile).Value
    
    
    z = WorksheetFunction.CountIf(.Columns(1), "abc")
    s = UBound(Spalten) + 1
    
    ReDim Erg(1 To z, 1 To s)
    
    For zD = 1 To UBound(Daten, 1)
        If Daten(zD, 1) = "abc" Then z = z + 1
        s = Application.Match(Daten(zD, 1), Spalten, 0)
        If Not IsError(s) Then Erg(z, s) = Daten(zD, 2)
    Next
    
    Tabelle2.Cells(Rows.Count, 1).End(xlUp).Offset(1, 0).Resize(UBound(Erg, 1), UBound(Erg, 2)).Value = Erg
End With
das Array Spalten muss alle "Spaltenüberschriften" , die du sehen willst in der richtigen Reihenfolge enthalten.

wie schon von anderen angemerkt, wenn du NewSheet jedesmal neu anlegst und dann wieder löschst, dann reicht es aus, wenn du es einmalig anlegst und dann einfach nur leerst (NewSheet.Cells.Clear).

Gruß Daniel


Anzeige
AW: Import aus Word
24.04.2023 18:46:48
Ron
Hallo Daniel, mein Code läuft ja, nur nicht effektiv.
Was soll eigenlich erreicht werden. In der Worddatei gibt es zwei Spalten. In der ersten Spalte stehen ca. 30 Daten, die sich ständig wiederholen. In der zweiten Spalte stehen die zugehörigen Daten. Ich möchte diese Daten in Excel importieren. Leider stehen nach dem Import die Daten der ersten Spalte nicht am Rand sondern in der Mitte der Zelle, sodass ich die Leerzeichen davor entfernen musste. Weiterhin werden auch nicht alle Daten benötigt, sodass der unnötige Datenmüll gelöscht wird. Die Daten zwischen aaa und aaa sollen immer gleich sein. Wenn welche fehlen, müssen sie als Dummy ergänzt werden. Die Daten der zweiten Spalte sollen formatiert werden. Wenn alles angepasst wurde, sollen die Daten in eine Tabelle übertragen werden. Das ist die Kurzfassung. Hier nochmal der Code dazu:
Sub Datei_auswählen()

    Dim Dateiname As Variant
    Dim wdApp As Object
    Dim wdDoc As Object
    Dim filename As Variant
    Dim newSheet As Worksheet
    Dim cell As Range
    Dim regEx As Object
    Dim lastRow As Long
    Dim i As Long
    Dim a As Integer
    Dim searchRange As Range
    Dim matchPattern As String
    Dim letzteZeile As Long
    Dim rng As Range
    Dim tbl As ListObject
    Dim sht As Worksheet

    Application.EnableEvents = False
    Application.ScreenUpdating = False
       
....
        
        'Ordner wählen, wo die Dateien abgelegt sind
        ChDrive "C"
        ChDir "C:\dokumente\Steuernummer\" & Range("F1") & "\dokumente\arbeitsbogen\"
    
        'Nur Word-Dokumente anzeigen und auswählen
        Dateiname = Application.GetOpenFilename("Word-Dokumente (*.docx*),*.doc*", , "Wählen Sie eine oder mehrere Word Dateien aus", , True)

        'Wurde eine Datei ausgewählt?
        If Not IsEmpty(Dateiname) Then
        
            'Für jede ausgewählte Datei den folgenden Code ausführen
            For a = LBound(Dateiname) To UBound(Dateiname)
            
                'Neues Arbeitsblatt erstellen
                Set newSheet = ThisWorkbook.Sheets.Add(after:= _
                                ThisWorkbook.Sheets(ThisWorkbook.Sheets.Count))
                newSheet.Name = a + 1 'Name des Arbeitsblatts auf "1", "2", "3", usw. setzen
            
                'Word-Dokument öffnen
                Set wdApp = CreateObject("Word.Application")
                Set wdDoc = wdApp.Documents.Open(Dateiname(a))
                
                'Inhalt kopieren
                wdDoc.Content.Copy
                
                'In Zelle A1 des aktuellen Arbeitsblatts einfügen
                With newSheet
                    Range("A1").PasteSpecial Paste:=xlPasteValues
                End With
                
                'Word-Dokument schließen
                wdDoc.Close SaveChanges:=False

                'Objekte freigeben
                Set wdDoc = Nothing

                'Zeilen löschen, die die Suchwörter nicht enthalten
                lastRow = newSheet.Cells(newSheet.Rows.Count, "A").End(xlUp).Row
                Set searchRange = newSheet.Range("A1:A" & lastRow)
                matchPattern = "\baaa\b" _
                            & "|\beee\b" _
                            & "|\bddd\b" _
                            & "|\bhhh\b" _
                            & "|\bppp\b" _
                            & "|\bccc\b" _
                            & "|\bnnn\b" _
                            & "|\bmmm\b" _
                            & "|\booo\b" _
                            & "|\bzzz\b" _
                            & "|\byyy\b" _
                            & "|\bvvv\b"
            
                Set regEx = CreateObject("VBScript.RegExp")
                regEx.Pattern = matchPattern
                regEx.Global = True
                
                For i = lastRow To 1 Step -1
                    Set cell = searchRange.Cells(i, 1)
                    If Not regEx.Test(cell.Value) Then
                        cell.EntireRow.Delete
                    End If
                Next i
        
                'Leerzeichen aus Splate "A" vor den Wörtern entfernen
                'finde die letzte Zeile mit Inhalt in Spalte B
                letzteZeile = Cells(Rows.Count, "B").End(xlUp).Row
        
                'Den Bereich auswählen und markieren
                Range("A1:A" & letzteZeile).Select
                Set rng = Selection
          
                For Each cell In rng 'Schleife durch alle ausgewählten Zellen
                    'Ersetzen Sie alle Leerzeichen in der Zelle durch nichts
                    cell.Value = Replace(cell.Value, " ", "")
                    'Entfernen Sie alle verbleibenden Leerzeichen am Anfang und Ende der Zelle
                    cell.Value = Trim(cell.Value)
                Next cell
                Range("A1").Select
        
                'finde die letzte Zeile mit Inhalt in Spalte A
                lastRow = Cells(Rows.Count, "A").End(xlUp).Row
            
                'gehe alle Zeilen von 1 bis zur letzten Zeile durch
                For i = 1 To lastRow
                    'wenn der Wert in Spalte A ist
                    If Range("A" & i).Value = "eee" Or _
                        Range("A" & i).Value = "ddd" Or _
                        Range("A" & i).Value = "ppp" Then
                        'konvertiere den Wert in Spalte B zu einem Datum
                        Range("B" & i).Value = DateValue(Range("B" & i).Value)
                        Range("B" & i).NumberFormat = "dd.mm.yyyy"
                    End If
                Next i
        
                'gehe alle Zeilen von 1 bis zur letzten Zeile durch
                For i = 1 To lastRow
                    'wenn der Wert in Spalte A ist
                    If Range("A" & i).Value = "hhh" Then
                        'konvertiere den Wert in Spalte B zu einem vierstelligen Text um
                        Range("B" & i).Value = Format(Range("B" & i).Value, "0000")
                        Range("B" & i).NumberFormat = "0000"
                    End If
                Next i
        
                'füge hinter jedem Wort "Kennzeichen" "ppp" ein, wenn nicht schon vorhanden
                lastRow = Range("A" & Rows.Count).End(xlUp).Row
                
                For i = lastRow To 1 Step -1
                    If Range("A" & i).Value = "Kennzeichen" Then
                        If i  lastRow And Range("A" & i + 1).Value > "ppp" Then
                            Rows(i + 1).Insert
                            Range("A" & i + 1).Value = "ppp"
                            Range("B" & i + 1).Value = "---"
                        End If
                    End If
                Next i
                
                'Daten in Tabellenblatt 2 kopieren
                letzteZeile = Cells(Rows.Count, "A").End(xlUp).Row
                
                For i = 1 To letzteZeile
                
                    If Range("A" & i).Value = "Kennzeichen" Then
                        Tabelle2.Range("A" & Rows.Count).End(xlUp).Offset(1, 0).Value = Range("B" & i).Value
                    End If
                    If Range("A" & i).Value = "eee" Then
                        Tabelle2.Range("B" & Rows.Count).End(xlUp).Offset(1, 0).Value = Range("B" & i).Value
                    End If
                    If Range("A" & i).Value = "ppp" Then
                        Tabelle2.Range("C" & Rows.Count).End(xlUp).Offset(1, 0).Value = Range("B" & i).Value
                    End If
                    If Range("A" & i).Value = "ddd" Then
                        Tabelle2.Range("D" & Rows.Count).End(xlUp).Offset(1, 0).Value = Range("B" & i).Value
                    End If
                    If Range("A" & i).Value = "ccc" Then
                        Tabelle2.Range("E" & Rows.Count).End(xlUp).Offset(1, 0).Value = Range("B" & i).Value
                    End If
                    If Range("A" & i).Value = "ooo" Or Range("A" & i).Value = "yyy" Then
                        Tabelle2.Range("F" & Rows.Count).End(xlUp).Offset(1, 0).Value = Range("B" & i).Value
                    End If
                    If Range("A" & i).Value = "nnn" Then
                        Tabelle2.Range("G" & Rows.Count).End(xlUp).Offset(1, 0).Value = Range("B" & i).Value
                    End If
                    If Range("A" & i).Value = "mmm" Then
                        Tabelle2.Range("H" & Rows.Count).End(xlUp).Offset(1, 0).Value = Range("B" & i).Value
                    End If
                    If Range("A" & i).Value = "hhh" Then
                        Tabelle2.Range("I" & Rows.Count).End(xlUp).Offset(1, 0).Value = Range("B" & i).Value
                    End If
                    If Range("A" & i).Value = "vvv" Then
                        Tabelle2.Range("J" & Rows.Count).End(xlUp).Offset(1, 0).Value = Range("B" & i).Value
                    End If
                
                Next i
        
                'Arbeitsblatt ohne speichern schließen
                Application.DisplayAlerts = False
                newSheet.Delete
                Application.DisplayAlerts = True
    
            Next a
                
                'Word schließen
                wdApp.Quit
                
                'Objekte freigeben
                Set wdApp = Nothing

        End If

...
        
    Application.EnableEvents = True
    Application.ScreenUpdating = True
           
End Sub
Ich weiß, der Code ist nicht schön. Aber es fehlen wir noch die Kenntnisse.
Gruß


Anzeige
AW: Import aus Word
25.04.2023 10:37:50
Daniel
Ja, das dachte ich mir
Genau das macht mein Makro.
Gruß Daniel


AW: Import aus Word
25.04.2023 11:33:52
Ron
Danke

Beliebteste Forumthreads (12 Monate)

Anzeige

Beliebteste Forumthreads (12 Monate)

Anzeige
Anzeige
Anzeige