This code:
strDirName = Dir(strParentFolder, vbDirectory)
Do Until strDirName = ""
returns files as well folders. It should only return folders.
Is it possible to use Dir to return a list of subfolders? Or is it recommended to use FileSystemObject(s)?
From the documentation page "files with no attributes" will also be returned so you may wish to check those.
Dir Function
Applies To: Access 2016
https://support.office.com/en-gb/article/Dir-Function-1a1a4275-f92f-4ae4-8b87-41e4513bba2e
vbDirectory 16 Specifies directories or folders in addition to files with no attributes.
I can't make any recommendations on how to do what you're asking using Dir() but below is a generic example of how you'd accomplish that using FileSystemObject.
This will print a single string of the first level of sub-directories in relation to the root directory.
Sub GetFolderList()
Set fso = CreateObject("Scripting.FileSystemObject")
Set rootFolder = fso.GetFolder("*Root Directory URI*")
Set subFolders = rootFolder.subFolders
Folders = ""
For Each fld In subFolders
Folders = Folders & fld.Name
Folders = Folders & " "
Next
Debug.Print Folders
End Sub
Related
I have created a macro that I can use to print PDF files. The PDF files will be saved in a folder to print. The path will be given that folder path where I save all PDF files. My questions are:
1) Once the files are saved in folder, is it possible to sort it automatically like first come first print. Now the issue is - prints did not come out in order of how the files are – we have to reconcile all files, so looking for each one in a random list order would take lots of time.
2) Is it possible to have the files automatically deleted from the folder after the printing is completed?
Public Sub Print_All_PDF_Files_in_Folder()
Dim folder As String
Dim PDFfilename As String
folder = "\\maple.fg.rbc.com\data\toronto\user_3\315606053\myWorkspace\Desktop\test" 'CHANGE AS REQUIRED
If Right(folder, 1) <> "\" Then folder = folder & "\"
PDFfilename = Dir(folder & "*.pdf", vbNormal)
While Len(PDFfilename) <> 0
If Not PDFfilename Like "*ecg*" Then
Print_PDF folder & PDFfilename
End If
PDFfilename = Dir() ' Get next matching file
Wend
End Sub
Sub Print_PDF(sPDFfile As String)
Shell "C:\Program Files (x86)\Adobe\Reader 11.0\Reader\AcroRd32.exe /p /h " & Chr(34) & sPDFfile & Chr(34), vbNormalFocus
' This is path of Adobe in the desktop
End Sub
There is no build in way to sort files. However, it is rather easy to read the filenames and -dates into arrays and sort them manually, but you have to use the FilesystemObject rather than using dir to get the file dates.
You can find an example to do so for example here: https://social.msdn.microsoft.com/Forums/office/en-US/5f27936e-1d98-44df-8f69-0f81624c4b92/read-files-in-a-folder-in-descending-order-with-file-name-or-date-created?forum=accessdev
The command to delete a file with VBA is kill, or you can use the .DeleteFile method of FilesystemObject. However, this will work only if the printing is already done, so you have to wait for your shell-command to finish. For this, you have to use the wscript.shell, see for example here https://stackoverflow.com/a/8906912/7599798
I'm using Dir function to get directory's content right now.
FileSpec = DirPath & "/GenerateID_*_*.zip"
FileName = Dir(FileSpec)
But Dir function is locking the folder and can't delete that folder until I close my VBA application. I have tried ChDir("C:\") to make this point to another directory after calling Dir function but it's not working.
Is it possible to filter using FileSystemObject like Dir function? Or get all files with FileSystemObject, loop each fileName and checking each one would be the only option?
You can certainly loop through the files with the FileSystemObject. From the MSDN documentation for the Files Property of the FileSystemObject:
Function ShowFileList(folderspec)
Dim fso, f, f1, fc, s
Set fso = CreateObject("Scripting.FileSystemObject")
Set f = fso.GetFolder(folderspec)
Set fc = f.Files
For Each f1 in fc
s = s & f1.name
s = s & "<BR>"
Next
ShowFileList = s
End Function
This will return a string that is delimited by '<BR>'. You can replace this with something else, like vbCrLf or whatever you like then parse the string as required.
I have the file name with the entire path of the file except the file extension.
Example: "C:\temp\FileNameWithoutExtension". Now I want to check if this file exists? I don't care about the file extension.
When I have the entire file name including file extension I was using following code to see if the file exists.
Set oFSO = CreateObject("Scripting.FileSystemObject")
FileExists = oFSO.FileExists(FileName)
Thanks for help.
It would be nice if FileExists handled wildcards but it does not. Would something like this help?
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFolder = objFSO.GetFolder("C:\temp")
Set objFiles = objFolder.Files
For Each objSingleFile in objFiles
If objSingleFile.Name Like "FileNameWithoutExtension*" Then
' The file name starts with FileNameWithoutExtension
MsgBox "Are you looking for me?: " & objSingleFile.Name
End If
Next
This is making assumption about the location you are searching and it is not recusrive but the basics are here for you to look at. This is not the only approach.
Try this
Sub FileExist()
Dim file As String, fileName As String
fileName = "C:\temp\abc" & "*"
file = Dir(fileName)
If file = "" Then
MsgBox "File doesn't exist"
Else
MsgBox "file found"
End If
End Sub
I created a temporary folder that gets deleted later on in the program using this code:
'Creates a new temporary directory path for a folder copy
If dir("C:\\InventorTempFolder\\\", vbDirectory) = "" Then
MkDir "C:\\InventorTempFolder\\\"
SetAttr "C:\InventorTempFolder", vbNormal
Else: MsgBox "This folder already exists."
End If
(I don't know if the SetAttr is right...that's part of my question!)
I then pulled this code offline that should delete all the files and directories in this folder, using this code:
Sub DeleteDirectory()
Dim dir_name As String
Dim file_name As String
Dim files As Collection
Dim i As Integer
dir_name = "C:\\InventorTempFolder"
' Get a list of files it contains.
Set files = New Collection
file_name = dir$(dir_name & "\*.*", vbReadOnly + _
vbHidden + vbSystem + vbDirectory)
Do While Len(file_name) > 0
If (file_name <> "..") And (file_name <> ".") Then
files.Add dir_name & "\" & file_name
End If
file_name = dir$()
Loop
' Delete the files.
For i = 1 To files.Count
file_name = files(i)
' See if it is a directory.
If GetAttr(file_name) = vbDirectory Then
Kill file_name
Else: Kill file_name
End If
Next i
' The directory is now empty. Delete it.
RmDir dir_name
' Remove the read-only flag if set.
' (Thanks to Ralf Wolter.)
End Sub
However, the directory won't delete. My theory is that it is because the directory is a read-only folder. That is why I tried to change the attribute to vbNormal, but it won't change. So questions I'm wondering is:
Why won't it delete? Is my theory right that it is because it is read-only?
If so, how can I fix that?
If not, what else is wrong...?
Thanks ahead of time!
The end of your script is:
RmDir dir_name
' Remove the read-only flag if set.
' (Thanks to Ralf Wolter.)
RmDir dir_name
So you're attempting to remove the same directory twice. And dir_name at this point is set to the "SillyVBA" directory -- this did get deleted when I tested it. I'm assuming the second RmDir is meant to delete "C:\InventorTempFolder"; that also worked for me when I tested it.
Updated in response to comment
The problem is likely due to your attempt to use Kill when the file type is a directory. To do a full recursive delete, you would need to start at the bottom of the tree, deleting all files and empty directories as you work your way up. However a much easier way is to use FileSystemObject:
Dim fso
Set fso = CreateObject("Scripting.FileSystemObject")
fso.deletefolder dir_name
This will delete the directory and everything in it, in one shot.
I can't find how to search for a folder (directory) that contains a string and copy all the folders (directory) that contain that string to another directory. So you search for the name of the directory, not the files in the directory.
For example: 'KTNPRK' in E:\ gives:
E:\KTNPRK1, E:\AZNKTNPR76, etc...
Here is an example of how to move the directories:
Dim sSourcePath As String
Dim sDestPath As String
Dim sTextToFind As String
sSourcePath = "D:\Temp"
sDestPath = "D:\Temp1"
sTextToFind = "test"
For Each sDir In Directory.GetDirectories(sSourcePath, "*" & sTextToFind & "*")
Directory.Move(sDir, Path.Combine(sDestPath, Path.GetFileName(sDir)))
Next
In order to copy all of the files in the folders, the loop can be changed to:
Dim sFullDestDir As String
sFullDestDir = Path.Combine(sDestPath, IO.Path.GetFileName(sFullSourceDir))
' Create the directory if it doesn't exist
If Not Directory.Exists(sFullDestDir) Then
Directory.CreateDirectory(sFullDestDir)
End If
' Copy the files in the directory
' If subfolders are to be copied, this logic can be turned into a recursive method.
For Each sFileName As String In Directory.GetFiles(sFullSourceDir)
File.Copy(sFileName, Path.Combine(sFullDestDir, IO.Path.GetFileName(sFileName)))
Next