Seite 1 von 1

[GELÖST] Ordnerinhalt mit Unterordnern auflisten

Verfasst: Mi, 06.06.2012 21:11
von Micke_p
Hallo,

Das Ergebnis: Ich möchte eine Liste mit mehreren Spalten füllen. Dabei soll in Spalte A: Der Pfad, Spalte B: Der Dateiname und Spalte C: Der DateiTyp / Endung stehen.
Das Problem: Ich komme mit dem Dir - Befehl nicht weiter, weil ich auch Unterordner einschließen will. Wenn ich Unterordner einschließe, schaffe ich die saubere Trennung zwischen Ordner / Pfad, Datei und Endung nicht mehr.

Ich weiß, dass diese Frage schon ab und zu angeschnitten wurde, aber die Themen sind leider alle steinalt. Durch die hier empfohlene Literatur und dieses Forum bin ich auch schon etwas näher an der Lösung:

Code: Alles auswählen

sub testdir

' ------------------ > Vars / Objekte :

oSheet 	= thisComponent.Sheets.getByName("Tabelle1")
oFolderPicker = createUnoService("com.sun.star.ui.dialogs.FolderPicker")

dim iZeile as integer
dim liste(10000) as string
dim origin as string

' ------------------ > Start :

oFolderPicker.execute

origin = oFolderPicker.directory

iZeile = 2

m = getdirs(liste(),0, origin)

	For i=0 to m-1
	
		TeilStrings() = Split(liste (i), ".") 
	'        oSheet.getCellbyPosition(0,iZeile).string = Trim(TeilStrings(0)) 
		oSheet.getCellbyPosition(2,iZeile).string = Trim(TeilStrings(1))

		liste(i) = Left(liste(i), (Len(liste(i))) - 4) 

		TeilStrings2() = Split(liste (i), origin & "/")
		oSheet.getCellbyPosition(0,iZeile).string = Trim(TeilStrings2(0)) 
		oSheet.getCellbyPosition(1,iZeile).string = Trim(TeilStrings2(1))
		
		iZeile = iZeile + 1
    
	next i 

End sub

' ------------------ > Funktion :

function getdirs( liste(),z, folder) as integer

sFolderUrl = ConvertToUrl( Folder )
oSimpleFileAccess = createUnoService( "com.sun.star.ucb.SimpleFileAccess" )
aFolders = oSimpleFileAccess.getFolderContents( sFolderUrl,true )

	For i = LBound( aFolders ) To UBound( aFolders )

		sFile = aFolders( i )

		If oSimpleFileAccess.isFolder( sFile ) Then
			getdirs( liste(),z, sFile)
		
		Else
		liste(z) = sfile
		z = z + 1

			end if   
	next i       

getdirs = z

end function
[edit]
Betriebssystem: Windows 7, OOvers. 3.4
Code etwas aufgeräumt.
[/edit]

Re: Ordnerinhalt mit Unterordnern auflisten

Verfasst: Do, 07.06.2012 09:30
von Micke_p
....Das eigentliche Problem an die Daten zu kommen wurde ja schon mit getFolderContents erledigt. Ich versuche nun eigentlich nur noch, das Ergebnis mit Split genauer zu trennen und in die entsprechende Zeile zu schreiben.

Gibt es auch die Möglichkeit das Split das Trennzeichen nicht von links nach rechts im String sucht, sondern von rechts nach links sucht?

So käme ich an die Dateinamen und in einem zweiten Schritt auch an den Ordner....?

Oder ich trenne die komplette Url nach "/". Dann müsste ich aber nur das letzte Segment des Arrays ausgeben können und das bei Variabler Pfadlänge (durch evtl. Unterordner). Dann hätte ich Dateiname und mit Join wieder DateiPfad einzeln...

Re: Ordnerinhalt mit Unterordnern auflisten

Verfasst: Do, 07.06.2012 18:31
von Karolus
Hallo

Hier mal als Calcfunktion in Python:

Code: Alles auswählen

# -*- coding: utf-8 -*-

import uno
import os

wrapper = uno.createUnoStruct('com.sun.star.script.ArrayWrapper')
wrapper.IsZeroIndex = False

def dwalk( path ):
    output = []
    for node in os.walk( path ):
        folders, files = node[1:]
        output.extend( os.path.splitext( ffile ) for ffile in files)
        output.extend( ( elem, None) for elem in folders  )
    wrapper.Array = tuple(output)
    return wrapper
Speichere den Code in einer Datei mit dem Namen 'sheetFunction.py' in deiner Benutzerkonfiguration unter ~/Scripts/python/

Zusätzlich benötigst du noch in der Standard-library ein Basic-modul mit dem Inhalt:

Code: Alles auswählen

Global g_MasterScriptProvider
REM Specify location of Python script, providing cell functions:
Const URL_Main = "vnd.sun.star.script:sheetFunction.py$"
Const URL_Args = "?language=Python&location=user"

Function getMasterScriptProvider()
   if NOT isObject(g_MasterScriptProvider) then
      oMasterScriptProviderFactory = createUnoService("com.sun.star.script.provider.MasterScriptProviderFactory")
      g_MasterScriptProvider = oMasterScriptProviderFactory.createScriptProvider("")
   endif
   getMasterScriptProvider = g_MasterScriptProvider
End Function 


Function dwalk( rootpath )
   sURL = URL_Main & "dwalk" & URL_Args
   oMSP = getMasterScriptProvider()
   oScript = oMSP.getScript(sURL)
   x = oScript.invoke( Array( rootpath ),Array(),Array())
   dwalk = x
end function
Aus Calc heraus rufst du die Funktion auf mit :

Code: Alles auswählen

=DWALK(A1)
als Matrix-funktion bitte mit 'strg+shift+enter' abschliessen bzw. mit der [x]Matrix-option im Formelassistenten.

In A1 steht der Basispfad in Systemschreibweise zB. 'C:\Dokumente und Einstellungen\'

Karo

Re: Ordnerinhalt mit Unterordnern auflisten

Verfasst: Do, 07.06.2012 21:08
von Micke_p
Vielen Dank für deine schnelle Antwort !

Das Makro soll allerdings auch dort laufen, wo ich (oder derjenige) keinen Zugriff auf Benutzereinstellungen oder schreibberechtigungen auf dem Systemlaufwerk habe.

Gibt es denn keine Möglichkeit, den String zu beschneiden ? Das Ergebnis habe ich ja schon...
Ich wollte im Anschluss die Dateien auch verlinken, also einen Link zum Ordner und einen direkt auf die Datei. Das ist auch kein Problem, wenn ich den String erstmal habe, aber evtl. kann ich über den Link noch was erreichen.

Also X:\Docs\Test.ods als Link zur Datei und X:\Docs\Test.ods als Link zum Verzeichnis, in dem sich die Datei befindet ?
Gibt es da vllt für linkcell.Formula = "=HYPERLINK()" irgendwelche attribute ?

Re: Ordnerinhalt mit Unterordnern auflisten

Verfasst: Fr, 08.06.2012 00:33
von Micke_p
Ich habe es geschafft.

Ich habe noch mehr nach String Routinen gesucht und InStrRev gefunden, genau das, was ich brauchte !

Verlinkungen mache ich noch...hier aber der Code, funktioniert soweit ganz gut:

Code: Alles auswählen

Sub OrdnerEinlesen

CompatibilityMode(True)

oSheet	 		= thisComponent.Sheets.getByName("Tabelle1")
oFolderPicker	= createUnoService("com.sun.star.ui.dialogs.FolderPicker")

dim liste(10000) as string
dim Folder, sPfad, sDatei as string
dim iSlash, iZeichen, iZeile as integer


oFolderPicker.execute

Folder = oFolderPicker.directory
iZeile = 2

m = getdirs(liste(),0, Folder)

	For i=0 to m-1
		iSlash		= InStrRev(liste(i), "/", -1)	'Zeichen bis erster Trenner von RECHTS
		iZeichen 	= Len(liste(i))					'Gesamtzeichen der Url
		sDatei		= Right (liste(i), iZeichen - iSlash) 	'von Rechts bis Trenner anzeigen
		sPfad	 	= Left (liste(i), iSlash)		'von Links bis Trenner anzeigen
		aTyp()		= Split(sDatei, ".")			'.pdf immer 4 Zeichen
		
		oSheet.getCellbyPosition(1, iZeile).string = ConvertFromUrl(sDatei)
		oSheet.getCellbyPosition(2, iZeile).string = Trim(UCase(aTyp(1)))
		oSheet.getCellbyPosition(3, iZeile).string = ConvertFromUrl(sPfad)

		iZeile = iZeile + 1
	next i 

End sub

'----------------> Funtion
function getdirs( liste(),z, folder) as integer

sFolderUrl = ConvertToUrl( Folder )
oSimpleFileAccess = createUnoService( "com.sun.star.ucb.SimpleFileAccess" )
aFolders = oSimpleFileAccess.getFolderContents( sFolderUrl,true )

	For i = LBound( aFolders ) To UBound( aFolders )
		sFile = aFolders( i )
		
		If oSimpleFileAccess.isFolder( sFile ) Then
		getdirs( liste(),z, sFile)
		Else
		liste(z)=sfile
		z=z+1
		end if
	next i
	
getdirs=z
end function

Re: [GELÖST] Ordnerinhalt mit Unterordnern auflisten

Verfasst: Fr, 08.06.2012 09:09
von Karolus
Hallo

Etwas kompakter und verständlicher ohne Umfüllen von einer Liste in die andere:

Code: Alles auswählen

sub testdir
    GlobalScope.BasicLibraries.LoadLibrary("Tools") 
    ' wir benötigen ein paar Funktionen aus ~Tools.Strings

    oSheet    = thisComponent.Sheets.getByName("Tabelle1")
    oFolderPicker = createUnoService("com.sun.star.ui.dialogs.FolderPicker")
    oAccess = createUnoService( "com.sun.star.ucb.SimpleFileAccess" )    
    oFolderPicker.execute
    origin = ConvertToUrl( oFolderPicker.directory )
    
    setcontents( oSheet, oAccess, origin, 2)
End sub
    
function setcontents( sheet, accessor, rooturl, pos)

    aFolders() = accessor.getFolderContents( rooturl,true )
    	
    for i = 0 to ubound(afolders())    	
    	If accessor.isFolder( afolders(i) ) Then    		
    		sheet.getCellbyPosition(0, pos).string = afolders(i)
    		pos = pos +1
    		setcontents( sheet, accessor, afolders(i), pos  )   'hier wird setcontents rekursiv aufgrufen mit Arrgumenten 		
    	else
    		filename =  FileNameoutofPath(afolders(i)) 'siehe ~Tools.Strings
    		file_n = GetFileNameWithoutExtension( filename) ' ↑ dito
    		sheet.getCellbyPosition(0, pos).string = file_n
    		sheet.getCellbyPosition(1, pos).string = GetFileNameExtension( filename )
    		pos = pos +1 
    	end if
    next i
end Function
Karo