Makro um Dateititel in Zelle auszulesen.

TribunM

Erfahrenes Mitglied
Hallo Freunde,

ich habe das Problem zwar schon einmal woanders (ja schande über mich :rolleyes: ) gepostet, dort aber keine wirkliche Hilfe bekommen. Aber bisher wurde ich hier noch nie enttäuscht, von daher probiere ich es mal...

Zu meinem "Problem":

Ich suche nach einer Möglichkeit in eine Zelle in Excel durch Auswahl von Dateien mittels z.B. eines Durchsuchen Feldes die Dateititel automatisch in diese Zelle mit einem definierten Trenner <> eintragen zu lassen.

Also z.b. datei1.jpg<>datei2.jpg

Kurz zum Hintergrund. Ich suche diese Lösung für einen csv Importer, den ich dann per PHp auslese und die Spaten dann verarbeite.

Zur Veranschaulichung sieht das dann vereinfacht so aus:

Spaltenbezeichnungen:
id;titel;genre;Medium;Cover; usw.

Beispiel Datensatz
1;Terminator;Action;DVD;Terminator-cv.jpg<>Terminator-ch.jpg; usw.

Das ganze sollte mit VBA als Makro gehen, aber ich habe NULL Ahnung davon. Ich habe ein Script gefunden, welches Dateinamen untereinander packt, aber ich weiß leider nicht, wie ich die Datei richtig abändere um obiges Ergebnis zu erhalten :(

HTML:
Option Explicit

Private Declare Function SHBrowseForFolder Lib "shell32" (lpbi As BrowseInfo) As Long
Private Declare Function CoTaskMemFree Lib "ole32" (ByVal hMem As Long) As Long
Private Declare Function lstrcat Lib "kernel32" Alias "lstrcatA" (ByVal lpStr1 As String, ByVal lpStr2 As String) As Long
Private Declare Function SHGetPathFromIDList Lib "shell32" (ByVal pList As Long, ByVal lpBuffer As String) As Long
Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassname As String, ByVal lpWindowName As String) As Long

Private Type BrowseInfo
    hwnd As Long
    Root As Long
    DisplayName As Long
    Title As Long
    Flags As Long
    FName As Long
    lParam As Long
    Image As Long
End Type

Public Sub Sabine()
    Dim strFolder As String, strName As String, lngRow As Long
    strFolder = GetAOrdner("Bitte wählen sie ein Verzeichnis")
    If Trim$(strFolder) <> "" Then
        Application.ScreenUpdating = False
        Columns(1).ClearContents
        strName = Dir(strFolder & "\", 16)
        Do
            If strName <> "." And strName <> ".." Then
                lngRow = lngRow + 1
                Cells(lngRow, 1) = strName
            End If
            strName = Dir
        Loop Until strName = ""
        Application.ScreenUpdating = True
    End If
End Sub

Private Function GetAOrdner(Optional varTitel As Variant) As String
    Dim BRI As BrowseInfo, lngIDList As Long, lngReturn As Long, strFolderName As String
    With BRI
        .hwnd = FindWindow("xlMain", vbNullString)
        If Not IsMissing(varTitel) Then
            .Title = lstrcat(varTitel, "")
        Else
            .Title = lstrcat("Please select a directory", "")
        End If
        .Flags = &H1
    End With
    lngIDList = SHBrowseForFolder(BRI)
    If lngIDList <> 0 Then
        strFolderName = Space(256)
        lngReturn = SHGetPathFromIDList(lngIDList, strFolderName)
        CoTaskMemFree (lngIDList)
        strFolderName = Trim$(strFolderName)
        strFolderName = Left$(strFolderName, Len(strFolderName) - 1)
    End If
    GetAOrdner = strFolderName
End Function

Über jede Hilfe würde ich mich sehr freuen.

Tribbi
 
Noch mal kurz damit auch ich es verstehe.

Du willst mehrere Dateinamen in eine Zelle z.B. Zelle "A5", "A6", "A7" schreiben und die einzelnen Angaben z.B. durch "<>" trennen.

Um die Dateien zu ermitteln hast du ein Eingabefeld und dort suchst du nun im obigen Beispiel nach "terminator".

Was ich mich unabhängig von Problem an sich aber frage. Wenn du das später mit PHP auslesen willst, warum machst du das dann nicht gleich mit PHP?
 
Hi tombe,

Genau in einer Zelle Dateinamen hintereinander durch einen Trenner bsp. <> getrennt.
Terminator war nur ein Beispiel für einen Datensatz. Die Spalte/Zelle mit <> getrennt wären dann die Coverfotos. für diesen Datensatz.

Warum ich das nicht direkt in php mache? Weil die csv auch anderen Nutzern zur Verfügung stehen soll und ich erst einmal schauen wollte, ob das so wie ich es geplant hatte, möglich ist. Ansonsten kann man es natürlich noch mit einer extra Datei machen und diese dann separat hochladen. Find ich aber unschön.
 
Hi Tribbi,

schau mal ob du für den Anfang mit diesem Code etwas anfangen kannst:

Visual Basic:
With Application.FileSearch
    .NewSearch
'in Zelle A1 steht der Pfad
    .LookIn = Tabelle1.Range("A1")
    .SearchSubFolders = False
'in Zelle A2 steht der Suchbegriff, es wird hier nach PDF Dateien gesucht eventuell in
' "*.jpg" oder aber in "*.*" ändern
    .Filename = Tabelle1.Range("A2") & "*.pdf"
    .MatchTextExactly = False
    .FileType = msoFileTypeAllFiles
    
    If .Execute() > 0 Then
        Tabelle1.Range("B1") = ""
        For a% = 1 To .FoundFiles.Count
'Dateinamen werden in Zelle B1 eingetragen
            Tabelle1.Range("B1") = Tabelle1.Range("B1") & "<>" & Dir(.FoundFiles(a%))
        Next a%
    End If
End With
 
Hey tube,

erst einmal danke für deine Mühe. Aber wenn ich das versuche auszuführen bekomme ich einen Laufzeitfehler 445. Wenn ich deinen Ansatz richtig vestanden funktioniert das ganz anders, oder?
Bestenfalls sollte es so sein, dass ich in einer Zelle klicke und das Makro ausführe, welches mir dann ein Auswahlfenster anzeigt, in dem ich Dateien auswähle und bei klick auf O.k. werden die per Trenner in die Zeile eingefügt. Ok das ist der Idealfall, aber vielleicht ist das doch möglich?
 
Ah, so langsam blicke durch ich wie es aussehen soll.

Visual Basic:
Private Sub Worksheet_SelectionChange(ByVal Target As Range)

Dim dat As Variant

Tabelle1.Range("A1") = ""

dat = Application.GetOpenFilename("Exceldateien (*.xls), *.xls", , , , True)
For a% = 1 To UBound(dat)
    Tabelle1.Range("A1") = Tabelle1.Range("A1") & Dir(dat(a%))
    If a% < UBound(dat) Then Tabelle1.Range("A1") = Tabelle1.Range("A1") & "<>"
Next a%

End Sub

Mit diesem Code öffnet sich das Dateidialog Fenster und man kann eine oder mehrere Dateien auswählen. Diese werden dann in Zelle A1 eingetragen.

Später Nachtrag:
Der Code muss natürlich noch so angepasst werden das er nur in einer bestimmten Spalte ausgeführt wird. Sonst läuft er bei jedem Klick in irgendeine Zelle.
 
Zuletzt bearbeitet:
Alter du bist der Beste. Verstehe Null aber genau so etwas habe ich mir vorgestellt. :)

Ich denke mal das kann ich nicht mit einer csv verknüpfen, oder? Das müsste ich das dann als Makro exportieren und einmal extra installieren, richtig? Zumindest wenn man es nicht mit der csv verknüpfen kann.
Wenn das Script noch die aktuelle Zelle mitnehmen und am besten noch direkt aufgerufen würde, wäre natürlich super. Im Moment schreibt er ja alles noch in A1 und man muss das Makro immer extra ausführen.

Ich bedanke mich auf jeden Fall schon einmal für deine kompetente Hilfe.
 
Zuletzt bearbeitet:
Hi,

also ich habe das jetzt nochmal geändert und an deine erste Beschreibung angepasst.
Es gibt jetzt die Spalten ID, Titel, Genre, Medium und Cover. Da Cover dann die fünfte Spalte ist, ist der Code auf diese Spalte ausgelegt (kann aber ganz einfach geändert werden).

In die Spalten 1 - 4 trägst du dann deine Daten einfach von Hand ein. Um die Dateien auszuwählen klickst du die Spalte 5 in der Zeile an in der die Dateien eingetragen werden sollen. Dieser Rechtsklick löst das dann Makro aus.

Visual Basic:
Private Sub Worksheet_BeforeRightClick(ByVal Target As Range, Cancel As Boolean)
Dim dat As Variant
Dim zeile As Long
Dim spalte As Integer

'Hiermit wird die Spalte 5 als die Spalte für das Cover festgelegt.
'Um die Spalte zu ändern, einfach hier die Zahl entsprechend anpassen
spalte = 5

'Code wird nur ausgeführt wenn die oben definierte Spalte aktiviert ist.
If ActiveCell.Column <> spalte Then Exit Sub

'Die aktuelle Zeile ermitteln und den darin bereits enthaltenen Text löschen.
zeile = ActiveCell.Row
Tabelle1.Cells(zeile, spalte) = ""
 
'Dateifilter festlegen, letztes Argument gibt an ob Mehrfachauswahl erlaubt ist (True)
'oder nicht (dann aus False ändern).
dat = Application.GetOpenFilename("Exceldateien (*.xls), *.xls", , , , True)

'Prüfen ob zumindest eine Datei markiert wurde, wenn nicht hier Abbrechen
If Not IsArray(dat) Then
    Cancel = True
    Exit Sub
End If

'Übergebene Dateinamen in die definierte Zelle eintragen.
For a% = 1 To UBound(dat)
    Tabelle1.Cells(zeile, spalte) = Tabelle1.Cells(zeile, spalte) & Dir(dat(a%))
    If a% < UBound(dat) Then Tabelle1.Cells(zeile, spalte) = Tabelle1.Cells(zeile, spalte) & "<>"
Next a%

'Dadurch wird das übliche Rechtsklick-Ereignis verhindert, wenn es
'ausgeführt werden soll True auf False ändern oder zeile komplett löschen.
Cancel = True
End Sub

Da in einer CSV Datei immer nur der reine Text gespeichert wird, würd ich an deiner Stelle einfach hergehen und die Daten in die Excel Datei eintragen und diese zunächst im XLS format speichern. So hast du alle Daten und das Makro bleibt auch erhalten.
Anschließend speicherst du das Ganze nochmal, nur hier dann halt als CSV Datei.
 
Irgendwie komme ich mit den Makros nicht zurecht. Wenn ich ein Makro hinzufüge dann bastelt der mir immer ein

Sub Makrotitel()

End Sub


Kopiere ich deine Zeilen dort rein kriege ich immer einen Fehler lasse ich das private Sub weg, kann ich es zumindest manuell ausführen. Wenn ich die Variablen in die () einfüge, dann will er das ganze Projekt zurücksetzen? Die Hilfe verdient den Namen nicht.
Also manuell funktionierts super aber wenn ich auf die Zelle gehe, passiert nichts.

Man man ich hätte nicht gedacht, dass das so kompliziert ist ;)



Wenn ich
 
Zuletzt bearbeitet:
Machen wir das mal anders.

Wenn du in Excel bist, drückst du die Tastenkombi "ALT + F11" oder gehst im Menü auf "Extras -> Makro -> Visual Basic Editor" (wobei ich hier diesen Weg empfehlen würde).

Dort erscheint dann auf der rechten Seite dein "Projektfenster". Dort klickst du Tabelle 1 doppelt an, worauf sich im Editor ein weiteres Fenster öffnet.

In diesem Fenster klickst du auf das linke Listenfeld und wählst "Worksheet" aus. Dann klickst du auf die rechte Liste und wählst dort "BeforeDoubleClick" aus.

In diese Prozedur kopierst du dann den Code (natürlich ohne die erste und letzte Zeile "Sub..." und "End Sub").

Dann sollte es klappen.

Nachtrag:
Ich hänge mal eine Datei hier dran wo alles drin steht. Dann hast du es leichter.
 

Anhänge

  • Mappe1.zip
    7,6 KB · Aufrufe: 17
Zuletzt bearbeitet:

Neue Beiträge

Zurück