Schleife möglich ?

  • Excel

Es gibt 6 Antworten in diesem Thema. Der letzte Beitrag () ist von the_racer.

    Schleife möglich ?

    Hallo zusammen.
    Ich habe folgendes Problem und hoffe, mir kann hier geholfen werden, oder zumindest eine Antwort ob´s machbar ist oder nicht gegeben werden.

    Folgendes.
    Ich möchte in Excel externe Daten einlesen, die aus HTML-Dokumenten stammen. Dies habe ich soweit auch über die Webabfrage hinbekommen. Ich habe ein Makro geschrieben (oder besser, über den Rekorder aufgenommen), was mir dies ermöglicht.

    Jetzt das Problem. Diese HTML-Dateien sind durchnummeriert. Sie heißen z.B. Datensatz_001.html, Datensatz_002.html, Datensatz_003.html usw. Bis hin zu knapp 900 Datensätzen, die sich alle drei Tage ändern, ich sie also wieder neu einlesen muß.

    So der Text zum einlesen:

    With ActiveSheet.QueryTables.Add(Connection:= _
    "URL;file:///D:/Daten/Datensatz_001.html" _
    , Destination:=Range("A1"))
    .Name = "Datensatz_001"
    .FieldNames = True
    .RowNumbers = False
    .FillAdjacentFormulas = False
    .PreserveFormatting = True
    .RefreshOnFileOpen = False
    .BackgroundQuery = True
    .RefreshStyle = xlInsertDeleteCells
    .SavePassword = False
    .SaveData = True
    .AdjustColumnWidth = True
    .RefreshPeriod = 0
    .WebSelectionType = xlEntirePage
    .WebFormatting = xlWebFormattingNone

    .WebPreFormattedTextToColumns = True
    .WebConsecutiveDelimitersAsOne = True
    .WebSingleBlockTextImport = False
    .WebDisableDateRecognition = False
    .WebDisableRedirections = False
    .Refresh BackgroundQuery:=False
    End With
    ...


    Jetzt will ich natürlich nicht 999 Sub´s schreiben, die für jeden einzelnen Datensatz funktionieren.

    Kann man da vielleicht eine Schleife einbauen, die die Datensätze alle einbezieht ?
    Ich hoffe, Ihr versteht was ich meine und könnt mir helfen !

    Schon jetzt vielen Dank dafür !

    Gruß
    Thomas
    So müsste es prinzipiell funktionieren:

    Visual Basic-Quellcode

    1. For i = 1 To 900
    2. With ActiveSheet.QueryTables.Add(Connection:= _
    3. "URL;file:///D:/Daten/Datensatz_" & Format(i, "000") & ".html" _
    4. , Destination:=Range("A1"))
    5. .Name = "Datensatz_" & Format(i, "000")
    6. .FieldNames = True
    7. .RowNumbers = False
    8. .FillAdjacentFormulas = False
    9. .PreserveFormatting = True
    10. .RefreshOnFileOpen = False
    11. .BackgroundQuery = True
    12. .RefreshStyle = xlInsertDeleteCells
    13. .SavePassword = False
    14. .SaveData = True
    15. .AdjustColumnWidth = True
    16. .RefreshPeriod = 0
    17. .WebSelectionType = xlEntirePage
    18. .WebFormatting = xlWebFormattingNone
    19. .WebPreFormattedTextToColumns = True
    20. .WebConsecutiveDelimitersAsOne = True
    21. .WebSingleBlockTextImport = False
    22. .WebDisableDateRecognition = False
    23. .WebDisableRedirections = False
    24. .Refresh BackgroundQuery:=False
    25. End With
    26. Next


    Bei "Destination:=" hab ich mal noch nichts verändert, da ich nicht weiß, was da dann pro HTML-Datei alles reinkommt.
    Okay, ob´s funktioniert, kann ich noch nicht sagen, weil jetzt folgendes Problem aufgetreten ist...
    Nach dem einlesen der Daten sollen alle Leerzeilen gelöscht werden. Das habe ich bisher so gelöst:

    Visual Basic-Quellcode

    1. Selection.ClearContents
    2. Dim i As Long, laR As Long
    3. Application.ScreenUpdating = False
    4. laR = Cells(Rows.Count, 1).End(xlUp).Row
    5. For i = laR To 1 Step -1
    6. If Cells(i, 1).Value = "" Then
    7. Cells(i, 1).EntireRow.Delete
    8. End If
    9. Next i
    10. Application.ScreenUpdating = True


    Bei jedem Datensatz als eigenständiges Sub hat es funktioniert, jetzt bekomme ich folgende Fehlermeldung noch vor dem ausführen:
    Fehler beim Kompilieren:Mehrfachdeklaration im aktuellen Gültigkeitsbereich
    :(

    Hier jetzt mal der ganze Quelltext, ich denke, das macht die Sache hoffentlich klarer. Dein Vorschlag ist schon eingearbeitet:

    Visual Basic-Quellcode

    1. Sub Einlesen_Datensaetze()
    2. '
    3. ' Einlesen_Datensaetze Makro
    4. 'Datenblätter vorbereiten (einmalig)
    5. Sheets("Tabelle1").Select
    6. Sheets("Tabelle1").Name = "RohMat"
    7. Sheets("Tabelle2").Select
    8. Sheets("Tabelle2").Name = "Ausgewertet"
    9. Sheets("RohMat").Select
    10. Sheets("Ausgewertet").Select
    11. Range("A1").Select
    12. ActiveCell.FormulaR1C1 = "Name"
    13. Range("B1").Select
    14. ActiveCell.FormulaR1C1 = "Einnahme"
    15. Range("C1").Select
    16. ActiveCell.FormulaR1C1 = "Differenz Vormonat"
    17. Range("D1").Select
    18. ActiveCell.FormulaR1C1 = "Abschlüsse"
    19. Range("E1").Select
    20. ActiveCell.FormulaR1C1 = "Vormonat"
    21. Range("F1").Select
    22. ActiveCell.FormulaR1C1 = "Gesamtbilanz I"
    23. Range("G1").Select
    24. ActiveCell.FormulaR1C1 = "Gesamtbilanz II"
    25. Range("A2").Select
    26. Sheets("RohMat").Select
    27. 'Datenabfrage
    28. For i = 1 To 900
    29. Range("B12").Select
    30. With ActiveSheet.QueryTables.Add(Connection:= _
    31. "URL;file:///D:/Daten/Datensatz_" & Format(i, "000") & ".html" _
    32. , Destination:=Range("A1"))
    33. .Name = "Datensatz_" & Format(i, "000")
    34. .FieldNames = True
    35. .RowNumbers = False
    36. .FillAdjacentFormulas = False
    37. .PreserveFormatting = True
    38. .RefreshOnFileOpen = False
    39. .BackgroundQuery = True
    40. .RefreshStyle = xlInsertDeleteCells
    41. .SavePassword = False
    42. .SaveData = True
    43. .AdjustColumnWidth = True
    44. .RefreshPeriod = 0
    45. .WebSelectionType = xlEntirePage
    46. .WebFormatting = xlWebFormattingNone
    47. .WebPreFormattedTextToColumns = True
    48. .WebConsecutiveDelimitersAsOne = True
    49. .WebSingleBlockTextImport = False
    50. .WebDisableDateRecognition = False
    51. .WebDisableRedirections = False
    52. .Refresh BackgroundQuery:=False
    53. End With
    54. Selection.ClearContents
    55. Dim i As Long, laR As Long
    56. Application.ScreenUpdating = False
    57. laR = Cells(Rows.Count, 1).End(xlUp).Row
    58. For i = laR To 1 Step -1
    59. If Cells(i, 1).Value = "" Then
    60. Cells(i, 1).EntireRow.Delete
    61. End If
    62. Next i
    63. Application.ScreenUpdating = True
    64. 'Werte in Tabelle bringen
    65. Sheets("RohMat").Select
    66. Range("A2").Select
    67. Selection.Copy
    68. Sheets("Ausgewertet").Select
    69. Range("A2").Select
    70. ActiveSheet.Paste
    71. Sheets("RohMat").Select
    72. Range("B8").Select
    73. Application.CutCopyMode = False
    74. Selection.Copy
    75. Sheets("Ausgewertet").Select
    76. Range("B2").Select
    77. ActiveSheet.Paste
    78. Sheets("RohMat").Select
    79. Range("A4").Select
    80. Application.CutCopyMode = False
    81. Selection.Copy
    82. Sheets("Ausgewertet").Select
    83. Range("C2").Select
    84. ActiveSheet.Paste
    85. Sheets("RohMat").Select
    86. Range("B14").Select
    87. Application.CutCopyMode = False
    88. Selection.Copy
    89. Sheets("Ausgewertet").Select
    90. Range("D2").Select
    91. ActiveSheet.Paste
    92. Sheets("RohMat").Select
    93. Range("D14").Select
    94. Application.CutCopyMode = False
    95. Selection.Copy
    96. Sheets("Ausgewertet").Select
    97. Range("E2").Select
    98. ActiveSheet.Paste
    99. Sheets("RohMat").Select
    100. Range("A4").Select
    101. Application.CutCopyMode = False
    102. Selection.Copy
    103. Sheets("Ausgewertet").Select
    104. Range("F2").Select
    105. ActiveSheet.Paste
    106. Sheets("RohMat").Select
    107. Range("B11").Select
    108. Application.CutCopyMode = False
    109. Selection.Copy
    110. Sheets("Ausgewertet").Select
    111. Range("G2").Select
    112. ActiveSheet.Paste
    113. Range("A3").Select
    114. Rows("2:2").Select
    115. Selection.Insert Shift:=xlDown
    116. Sheets("RohMat").Select
    117. Range("B12").Select
    118. 'Rohblatt löschen
    119. Sheets("RohMat").Select
    120. Range("B12").Select
    121. Cells.Select
    122. Application.CutCopyMode = False
    123. Selection.ClearContents
    124. Selection.QueryTable.Delete
    125. Range("B12").Select
    126. Next
    127. End Sub


    So, vielleicht bringt Euch das weiter... ;(
    Aaaaaaaaaah..... :)
    Die besten Fehler sind die, die man selber lösen kann. :)

    Der Fehler lag wohl in der doppelten Vergabe der Variable "i". :)
    Dim i As Long, laR As Long
    Mensch, Mensch. Jetzt geht´s mit einer anderen Variable tatsächlich !

    Nochmal vielen, vielen Dank für Deine Hilfe !!! *verneig*
    Freut mich, dass ich dir helfen konnte, aber du brauchst dich doch nicht verneigen. Ist ja nur ne For-Schleife. ^^ Obwohl: Es gab auch Zeiten, wo ich aufgezeichneten Code sooft kopiert hab, wie er ausgeführt werden soll. Da wusste ich von den For-Schleifen noch nichts. Das ging dann teilweise soweit, dass der Code so lang geworden ist, dass vor dem Ausführen eine Fehlermeldung kam, dass der Code zu lang sei. Wie lang der da war, weiß ich nicht mehr. Ist auch schon einige Zeit her.

    Jetzt jedoch genug davon und zur Sache:

    Ich hab mir deinen Code mal angesehen und habe ein paar Verbesserungsvorschläge:

    1. Du musst nicht unbedingt eine Zelle auswählen, um etwas reinzuschreiben.

    Statt dem hier

    Visual Basic-Quellcode

    1. Range("A1").Select
    2. ActiveCell.FormulaR1C1 = "Name"


    kannst du auch das schreiben:

    Visual Basic-Quellcode

    1. Range("A1").FormulaR1C1 = "Name"


    und wenn es keine Formel ist, sogar das:

    Visual Basic-Quellcode

    1. Range("A1") = "Name"



    2. Du kannst Werte auch direkt von Zelle nach Zelle übertragen:

    Statt diesem hier

    Visual Basic-Quellcode

    1. Sheets("RohMat").Select
    2. Range("A2").Select
    3. Selection.Copy
    4. Sheets("Ausgewertet").Select
    5. Range("A2").Select
    6. ActiveSheet.Paste


    kannst du auch das schreiben:

    Visual Basic-Quellcode

    1. Sheets("Ausgewertet").Range("A2") = Sheets("RohMat").Range("A2")


    Jedoch werden dann nur die Werte übertragen; Formatierungen (auch Zahlenformate) werden nicht übergeben.

    Willst du es doch kopieren, kann man obigen Code hierzu verkürzen:

    Visual Basic-Quellcode

    1. Sheets("RohMat").Range("A2").Copy
    2. Sheets("Ausgewertet").Select
    3. Range("A2").Select
    4. ActiveSheet.Paste



    3. Wenn du magst, kannst du auch die Tabellenblätter mit Variablen ansprechen.

    Statt diesem hier

    Visual Basic-Quellcode

    1. Sheets("Tabelle1").Select
    2. Sheets("Tabelle1").Name = "RohMat"
    3. Sheets("Tabelle2").Select
    4. Sheets("Tabelle2").Name = "Ausgewertet"
    5. Sheets("RohMat").Select


    kannst du z. B. das machen:

    Visual Basic-Quellcode

    1. Dim RohMat As Worksheet, Ausgew As Worksheet
    2. Set RohMat = Sheets("Tabelle1")
    3. Set Ausgew = Sheets("Tabelle2")
    4. RohMat.Name = "RohMat"
    5. Ausgew.Name = "Ausgewertet"
    6. RohMat.Select



    Das bei 3. ist halt mein Programmierstil. Ich habe mir angewöhnt, dass ich die Tabellen Variablen zuweise. Auf diese Weise brauche ich nur die Variable hinschreiben, auch wenn ich z. B. in eine andere Mappe gewechselt bin. Ich brauche dann beispielsweise nicht "Workbooks("Mappe1.xls").Sheets("Tabelle1")" schreiben, sondern nur "Tab", wenn ich die Variable "Tab" genannt habe. Außerdem kann ich so sicher gehen, dass ich auf die richtige Tabelle zugreife.

    In deinem Fall funktioniert es mit "Sheets("...")" genausogut, denke ich. Ich wollte nur eine Alternative aufzeigen.


    EDIT:

    Noch eine Anmerkung zu meinen Vorschlägen:

    Dem Code sehe ich an, dass du größtenteils den Code so gelassen hast, wie er aufgezeichnet wurde. Was auch okay ist, solange es funktioniert. Ich wollte nur zeigen, dass, wenn du weitere ähnliche Abläufe programmierst, der Code dann nicht unbedingt genauso sein muss wie durch die Aufzeichnung.

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „roddy“ ()

    Wow, irre. :)
    Das der Code, der beim direkten Aufzeichen generiert wird, nicht der optimalste ist, ist ja eigentlich ausser Frage. Bill Gates´ Style eben. *g*
    Und Deine Tipps habe ich bereits beherzigt und umgesetzt, vielen Dank dafür !
    Ich werde mich jetzt wohl näher mit dem direkten programmieren befassen, das schwebt mit schon lange vor. Ich werde Dich mal als "F1-Hilfe-Taste" speichern ! :)