Wechsel zwischen Dateien mit Variablem Namen

  • Excel

Es gibt 9 Antworten in diesem Thema. Der letzte Beitrag () ist von jannis-01.

    Wechsel zwischen Dateien mit Variablem Namen

    Hallo Leute,

    Ich muss in meinem Programm immer wieder zwischen zwei Dateien hin und her wechseln um Daten aus bestimmten Zellen eines Sheets der "Datei1" zu summieren und an einer bestimmten Stelle der "Datei2" im Sheet zu speichern. Dafür nutze dafür momentan

    Visual Basic-Quellcode

    1. Windows("Datei1").Activate.... Windows("Datei2").Activate


    Jetzt ändern sich allerdings immer die Endungen der Dateien, in Abhängigkeit vom Monat.
    Gibt es eine Möglichkeit wie ich das umsetzen kann ohne im VBA Code immer den neuen Namen eingeben zu müssen? Könnt ihr mir helfen? :)

    Viele Grüße,
    Jannis

    PS: Auch nach einigem Googlen konnte ich keine richtig funktionierende Lösung für das Problem finden. :/


    Edit by Manschula: Für VBA-Themen haben wir ein eigenes Unterforum. Dieses bitte auch benutzen! --> Thema verschoben, Titel und Präfix bereinigt/angepasst

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

    FloFuchs schrieb:

    Warum lässt du das summieren und einfügen nicht direkt Vom MAkro machen? Dann brauchste auch nich zwischen den Dateien hin und her zu springen?
    Hi FloFuchs,

    danke für den Tipp, aber das mache ich schon. ;) Der restliche Programmcode funktioniert auch so weit, das Problem ist nur, dass sich Wöchentlich die Namen der Dateien mit denen ich arbeite ändern und ich nicht jedes mal im VBA Code die neuen Namen der Dateien einfügen möchte um den Code ausführen zu können..

    petaod schrieb:

    Visual Basic-Quellcode

    1. Set ws1 = Thisworkbook.Sheets(1)
    2. Set wb2 = Workbooks.Open("c:\OtherWorkbook.xlsx")
    3. Set ws1 = wb2.Sheets(1)
    4. ws2.Range("A1").Value = WorkSheetFunction.Sum(ws1.Range("A1:B5")
    oder so... ;)
    Das ist schonmal hilfreich, allerdings fehlt jetzt noch der schritt zu dem Öffnen der Datei. Aktuell verwende ich:

    Visual Basic-Quellcode

    1. Windows("Datei1.xlsm").Activate


    Suche aber so etwas wie
    Windows(VARIABLE).Activate - Nur leider funktioniert das bei mir nicht.

    Gibt es sonst vielleivht auch eine andere Möglichkeit mit den verschiedenen Dateien zu arbeiten außer "Windows("Datei1.xlsm").Activate"?

    Viele Grüße und schonmal DANKE :)

    jannis-01 schrieb:

    Set wb2 = Workbooks.Open("c:\OtherWorkbook.xlsx")

    Steht doch da ;)
    statt den Dateinamen kannste da auch ne Variable einsetzen, also:

    Visual Basic-Quellcode

    1. Set wb2 = workbooksopen(DeinString)

    Un den fragste halt am Anfang vom Benutzer ab!
    Diesen .Activate Unsinn brauchste nicht ;)
    Spoiler anzeigen

    Visual Basic-Quellcode

    1. Option Explicit
    2. Dim wbUrsprung, wbZiel As Workbook
    3. Sub main()
    4. Call MappenZuweisen(OwnFileDialog("Bitte Ursprungdatei auswählen"), OwnFileDialog("Bitte Zieldatei auswählen"))
    5. End Sub
    6. Sub MappenZuweisen(ByVal wbVon As String, ByVal wbZu As String)
    7. Set wbUrsprung = Workbooks.Open(wbVon)
    8. Set wbZiel = Workbooks.Open(wbZu)
    9. End Sub
    10. Function OwnFileDialog(DialogTitle As String) As String
    11. With Application.FileDialog(msoFileDialogFilePicker)
    12. .AllowMultiSelect = False
    13. .Title = DialogTitle
    14. .Filters.Add "*.xlsx", "*.xlsx"
    15. .Filters.Add "*.xls", "*.xls"
    16. .InitialFileName = "*.xlsx"
    17. .Show
    18. OwnFileDialog = .SelectedItems(1)
    19. End With
    20. End Function

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

    Hallo zusammen,

    entweder verstehe ich die Idee hinter der Lösung nicht oder ich hab mein Problem nicht klar genug formuliert, sodass die Lösung nicht passt. Ich versuchs nochmal..

    Ich habe jetzt 3 geöffnete Excel Dateien.
    • Datei1.xlsm - Beinhaltet die Macros und ändert nie den Dateinamen
    • Datei2 xx.xx.xx.xlsx - Datei1 arbeitet mit den Daten von "Datei2 xx.xx.xx.xlsx"
    • Datei3 xx.xx.xx.xlsx - Datei1 arbeitet mit den Daten von "Datei3 xx.xx.xx.xlsx"

    Ablauf:
    1. Aus der Datei1 werden Daten eingelesen, die für die Filterung von Daten in Datei2 dienen.
    2. Aus Datei2 werden Werte auf ein Sheet von Datei 1 kopiert.

    3. Aus der Datei1 werden Daten eingelesen, die für die Filterung von Daten in Datei3 dienen.
    4. Aus Datei3 werden Werte auf ein Sheet von Datei 1 kopiert.

    Problem:
    Da sich die Namen von Datei 2 und 3 immer ändern kann ich keinen festen Dateinamen in den VBA Code einbinden, sondern muss die jeweiligen neuen Namen in einer Variablen speichern (Der Anfang der Dateien sieht immer gleich aus, nur das Datum ändert sich).

    Den Wechsel zwischen den Dateien hatte ich mit "Windows("Datei2.xlsm").Activate" gelöst.


    Frage:
    Wie kann ich den Wechsel zwischen den Dateien unabhängig vom neuen Dateinamen halten bzw. wie kann ich immer den neusten Dateinamen in eine Variable speichern und so unabhängig machen?
    Und wie kann ich den .Activate Unsinn weglassen?



    Hilft da sowas weiter?
    Spoiler anzeigen

    Visual Basic-Quellcode

    1. Sub DateienOeffnen()
    2. ' Dim strDatei As Worksheet
    3. Set strDatei = ActiveWorkbook.ActiveSheet
    4. Pfad1 = Application.ActiveWorkbook.Path
    5. MsgBox "Öffnen der Datei2"
    6. Pfad2 = Application.GetOpenFilename
    7. MsgBox "Öffnen der Datei3"
    8. Pfad3 = Application.GetOpenFilename
    9. If Pfad2 <> False Then
    10. Workbooks.Open Pfad2
    11. strDatei.Activate
    12. Range("K1").Value = Pfad1
    13. Range("K2").Value = Pfad2
    14. Workbooks.Open Pfad3
    15. strDatei.Activate
    16. Range("K3").Value = Pfad3
    17. Else
    18. MsgBox "Abbruch durch Benutzer"
    19. Exit Sub
    20. End If
    21. End Sub



    Hier ist mal der ganze Code, vielleicht beseitigt das die letzten Unklarheiten. (Ich habe bei dem Code den Teil, in dem ich mit der 3. Datei Arbeite ausgelassen. Die .Activate Teile konnte ich iregndwie nicht fett machen, vielleciht hilft die Suchfunktion die stellen zu finden)




    PS: Auf dem Sheet der "Datei1.xlsm" befinden sich in den Zelen K2 und K3 die Pfade der Dateien "Datei2 xx.xx.xx.xlsx" und "Datei 3 xx.xx.xx.xlsx"
    Spoiler anzeigen


    Visual Basic-Quellcode

    1. Sub AnnuityAndNewV2()
    2. '
    3. ' AnnuityAndNew Macro
    4. '
    5. Application.WindowState = xlMaximized
    6. [b] Windows("Datei 1.xlsm").Activate[/b]
    7. Sheets("Suche").Select
    8. Dim Name As String
    9. Dim FcstIndicator1 As String
    10. Dim FcstIndicator2 As String
    11. Dim FcstIndicator3 As String
    12. Dim FcstIndicator4 As String
    13. Dim ShipQuarter As String
    14. Dim ShipMonth As String
    15. Dim NameSheet As String
    16. Dim zaehler As Integer
    17. Dim ZeilenZaehler As Integer
    18. Dim AnzahlDerSummenEintraege As Integer
    19. Dim PersonenAnzahl As Integer
    20. Dim Summe As Long
    21. zaehler = 0 ' Der Zähler zählt die Schleifendurchläufe und dient als Abbruchkriterium. ("Loop While Zaehler < PersonenAnzahl")
    22. ZeilenZaehler = 2 ' Der ZeilenZähler dient dazu, den aktuellen Inhalt aus den Zellen 1-X, des Sheets "Suche", in den entsprechenden Variablen zu speichern
    23. PersonenAnzahl = Application.CountA(Columns(1)) - 1
    24. Do
    25. [b] Windows("Datei 1.xlsm").Activate [/b]
    26. Name = Range("B" & ZeilenZaehler)
    27. FcstIndicator1 = Range("C2")
    28. FcstIndicator2 = Range("C3")
    29. FcstIndicator3 = Range("C4")
    30. FcstIndicator4 = Range("C5")
    31. NameSheet = Range("A" & ZeilenZaehler)
    32. ShipMonth = Range("E" & ZeilenZaehler)
    33. ShipQuarter = Range("D" & ZeilenZaehler)
    34. MsgBox "Name: " & Name
    35. [b] Windows("Datei2 xx.xx.xx.xlsx").Activate[/b]
    36. ActiveSheet.Range("$A$1:$V$328").AutoFilter Field:=1, Criteria1:=Name
    37. ' If ActiveSheet.Range("A2") = "" Then
    38. ' MsgBox Name & " konnte nicht im Datei2 Sheet gefunden werden"
    39. ' End If
    40. ActiveSheet.Range("$A$1:$V$328").AutoFilter Field:=6, Criteria1:=Array(FcstIndicator1), Operator:=xlFilterValues
    41. If ShipQuarter = "" And ShipMonth = "" Then 'Falls beide Felder leer sind wird ein Fehler ausgegeben.
    42. MsgBox "Bitte geben sie entweder einen Monat oder ein Quartal ein. Beides ist nicht möglich."
    43. Exit Do
    44. ElseIf ShipMonth = "" Then 'Dient der Filterung des Datei2 Sheets nach dem Quartal
    45. ActiveSheet.Range("$A$1:$V$328").AutoFilter Field:=15, Criteria1:=ShipQuarter
    46. ElseIf ShipQuarter = "" Then 'Dient der Filterung des Datei2 Sheets nach dem Monat
    47. ActiveSheet.Range("$A$1:$V$328").AutoFilter Field:=16, Criteria1:=ShipMonth
    48. End If
    49. 'Speicherung der ganzen Werte aus der Datei2 Datei für die entsprechende Person und Kopieren in das "Suche" Sheet der Datei1
    50. Range("S2:S1000").Select
    51. Application.CommandBars("Selection and Visibility").Visible = False
    52. Selection.SpecialCells(xlCellTypeVisible).Select
    53. Selection.Copy
    54. [b]Windows("Datei1.xlsm").Activate[/b]
    55. Range("F2").Select
    56. ActiveSheet.Paste
    57. AnzahlDerSummenEintraege = Application.CountA(Columns(6))
    58. 'Dient der Filterung des Datei2 Sheets nach dem Quartal
    59. If ShipMonth = "" And ShipQuarter = "" Then
    60. MsgBox "Bitte geben Sie bei " & Name & " einen Monat oder ein Quartal ein, nach dem sortiert werden soll."
    61. ElseIf ShipMonth = "" Then
    62. Dim Quartal As String
    63. Quartal = Right(ShipQuarter, 1)
    64. Select Case Quartal
    65. Case 1
    66. ' Sheets(NameSheet).Range("D3").Value = Application.Sum(Sheets("Suche").Range("F2:F" & AnzahlDerSummenEintraege))
    67. Summe = Application.Sum(Sheets("Suche").Range("F2:F" & AnzahlDerSummenEintraege)) / 1000
    68. Sheets(NameSheet).Range("D3").Value = Summe
    69. Sheets(NameSheet).Range("D3").Interior.Color = 65535
    70. Sheets("Suche").Range("F2:F" & AnzahlDerSummenEintraege + 1).Select ' Notwendig, damit keine alten Werte kopiert werden, falls keine neuen Werte für die neue Suchanfrage gefunden werden.
    71. Selection.ClearContents
    72. End Select
    73. Select Case Quartal
    74. Case 2
    75. Summe = Application.Sum(Sheets("Suche").Range("F2:F" & AnzahlDerSummenEintraege)) / 1000
    76. Sheets(NameSheet).Range("E3").Value = Summe
    77. Sheets(NameSheet).Range("E3").Interior.Color = 65535
    78. Sheets("Suche").Range("F2:F" & AnzahlDerSummenEintraege + 1).Select ' Notwendig, damit keine alten Werte kopiert werden, falls keine neuen Werte für die neue Suchanfrage gefunden werden.
    79. Selection.ClearContents
    80. End Select
    81. Select Case Quartal
    82. Case 3
    83. Summe = Application.Sum(Sheets("Suche").Range("F2:F" & AnzahlDerSummenEintraege)) / 1000
    84. Sheets(NameSheet).Range("F3").Value = Summe
    85. Sheets(NameSheet).Range("F3").Interior.Color = 65535
    86. Sheets("Suche").Range("F2:F" & AnzahlDerSummenEintraege + 1).Select
    87. Selection.ClearContents
    88. End Select
    89. Select Case Quartal
    90. Case 4
    91. Summe = Application.Sum(Sheets("Suche").Range("F2:F" & AnzahlDerSummenEintraege)) / 1000
    92. Sheets(NameSheet).Range("G3").Value = Summe
    93. Sheets(NameSheet).Range("G3").Interior.Color = 65535
    94. Sheets("Suche").Range("F2:F" & AnzahlDerSummenEintraege + 1).Select
    95. Selection.ClearContents
    96. End Select
    97. ElseIf ShipQuarter = "" Then
    98. Dim Monat As String
    99. Monat = Right(ShipMonth, 2)
    100. Select Case Monat ' Quartal 1
    101. Case 11, 12, 1
    102. Summe = Application.Sum(Sheets("Suche").Range("F2:F" & AnzahlDerSummenEintraege)) / 1000
    103. Sheets(NameSheet).Range("D3").Value = Summe
    104. Sheets(NameSheet).Range("D3").Interior.Color = 65535
    105. Sheets("Suche").Range("F2:F" & AnzahlDerSummenEintraege + 1).Select
    106. Selection.ClearContents
    107. End Select
    108. Select Case Monat ' Quartal 2
    109. Case 2, 3, 4
    110. Summe = Application.Sum(Sheets("Suche").Range("F2:F" & AnzahlDerSummenEintraege)) / 1000
    111. Sheets(NameSheet).Range("E3").Value = Summe
    112. Sheets(NameSheet).Range("E3").Interior.Color = 65535
    113. Sheets("Suche").Range("F2:F" & AnzahlDerSummenEintraege + 1).Select
    114. Selection.ClearContents
    115. End Select
    116. Select Case Monat ' Quartal 3
    117. Case 5, 6, 7
    118. Summe = Application.Sum(Sheets("Suche").Range("F2:F" & AnzahlDerSummenEintraege)) / 1000
    119. Sheets(NameSheet).Range("F3").Value = Summe
    120. Sheets(NameSheet).Range("F3").Interior.Color = 65535
    121. Sheets("Suche").Range("F2:F" & AnzahlDerSummenEintraege + 1).Select
    122. Selection.ClearContents
    123. End Select
    124. Select Case Monat ' Quartal 4
    125. Case 8, 9, 10
    126. Summe = Application.Sum(Sheets("Suche").Range("F2:F" & AnzahlDerSummenEintraege)) / 1000
    127. Sheets(NameSheet).Range("G3").Value = Summe
    128. Sheets(NameSheet).Range("G3").Interior.Color = 65535
    129. Sheets("Suche").Range("F2:F" & AnzahlDerSummenEintraege + 1).Select
    130. Selection.ClearContents
    131. End Select
    132. End If
    133. If zaehler = 15 Then
    134. Dim a As String
    135. a = MsgBox("Möchtest du das Programm beenden?", vbYesNo)
    136. If a = vbNo Then
    137. MsgBox "Weiter geht"
    138. Else
    139. MsgBox "Tschüss!"
    140. Exit Do
    141. End If
    142. End If
    143. zaehler = zaehler + 1
    144. ZeilenZaehler = ZeilenZaehler + 1
    145. Loop While zaehler < PersonenAnzahl
    146. End Sub

    Dieser Beitrag wurde bereits 6 mal editiert, zuletzt von „jannis-01“ ()

    Wie oben schon geschrieben wurde:
    Nicht mit Activate und Select umschalten!
    Activate und Select sind "böse" Funktionen des Macrorecorders und haben (bis auf wenige Ausnahmen) im Code nichts verloren.
    Statt dessen: Objekte zuweisen und diese bei der Adressierung verwenden!

    Ansatz:

    Visual Basic-Quellcode

    1. Set wb1 = ThisWorkbook
    2. Set wb2 = Workbooks.Open(Pfad2)
    3. Set wb3 = Workbooks.Open(Pfad3)
    4. Set ws1 = wb1.Sheets("Tabelle1")
    5. Set ws2 = wb2.Sheets("Tabelle1")
    6. Set ws3 = wb3.Sheets("Tabelle1")
    7. ws1.Range("A2").Value = ws2.Range("B3").Value
    8. ...
    Versuche diesen Ansatz zu verstehen und auf dein Projekt umzusetzen.
    --
    If Not Program.isWorking Then Code.Debug Else Code.DoNotTouch
    --