MS Access VBA Delete Empty Folders - ms-access

I have a list of folder paths I need to delete on a regular basis via an Access program. I only want to delete them if all of the sub folders are empty. How do I delete an empty folder via VBA? This is my code but it doesn't do anything.
I call it via:
PrepareDirModified ("C:\Users\xxxxxxx\Desktop\New folder\TEST123\test456")
Here is the main sub:
Public Sub PrepareDirModified(dirStr As String)
On Error Resume Next
If Right(dirStr, 1) <> "\" Then dirStr = dirStr & "\"
Kill dirStr & "*.*"
RmDir dirStr
MkDir dirStr
On Error GoTo 0
End Sub

I used the FileScripting Object to delete a whole series of files then folders, something like;
Dim FSO As Object
Set FSO = CreateObject("scripting.filesystemobject")
On Error GoTo FileError
'Delete files
FSO.deletefile mypath & "\*.*", True
'Delete subfolders
FSO.deletefolder mypath & "\*.*", True
The below blatantly copied from Ron's excellent site https://www.rondebruin.nl/win/s9/win003.htm
You can check a folder exists using the same object;
Dim FSO As Object
Dim FolderPath As String
Set FSO = CreateObject("scripting.filesystemobject")
FolderPath = "C:\Users\Ron\test"
If Right(FolderPath, 1) <> "\" Then
FolderPath = FolderPath & "\"
End If
If FSO.FolderExists(FolderPath) = False Then
MsgBox "Folder doesn't exist"
Else
MsgBox "Folder exist"
End If
And you can check if a file exists in the same way;
Dim FSO As Object
Dim FilePath As String
Set FSO = CreateObject("scripting.filesystemobject")
FilePath = "C:\Users\Ron\test\book1.xlsm"
If FSO.FileExists(FilePath) = False Then
MsgBox "file doesn't exist"
Else
MsgBox "File exist"
End If
End Sub
In order to iterate through the folders I would use this script;
Public Sub DeleteEmptyFolders(ByVal strFolderPath As String)
Dim fsoSubFolders As Folders
Dim fsoFolder As Folder
Dim fsoSubFolder As Folder
Dim strPaths()
Dim lngFolder As Long
Dim lngSubFolder As Long
DoEvents
Set m_fsoObject = New FileSystemObject
If Not m_fsoObject.FolderExists(strFolderPath) Then Exit Sub
Set fsoFolder = m_fsoObject.GetFolder(strFolderPath)
On Error Resume Next
'Has sub-folders
If fsoFolder.SubFolders.Count > 0 Then
lngFolder = 1
ReDim strPaths(1 To fsoFolder.SubFolders.Count)
'Get each sub-folders path and add to an array
For Each fsoSubFolder In fsoFolder.SubFolders
strPaths(lngFolder) = fsoSubFolder.Path
lngFolder = lngFolder + 1
Next fsoSubFolder
lngSubFolder = 1
'Recursively call the function for each sub-folder
Do While lngSubFolder < lngFolder
Call DeleteEmptyFolders(strPaths(lngSubFolder))
lngSubFolder = lngSubFolder + 1
Loop
End If
'No sub-folders or files
If fsoFolder.Files.Count = 0 And fsoFolder.SubFolders.Count = 0 Then
fsoFolder.Delete
End If
End Sub
Copied from here http://www.freevbcode.com/ShowCode.asp?ID=7821

Related

Using Like operator to open Excel workbooks | VBA

Thank you for taking the time to read this.
I am trying to use the LIKE operator to open workbooks. Previously I went with this code which works really well
Report_Name = "\XYZ.xls"
Workbooks.open Filename:= ThisWorkbook.Path & Report_Name
My main goal is to essentially open a report and sometimes the names differ i.e healthdoc or healthassess
I tried utilizing the LIKE operator to pick up on the name of the workbook however I cannot find a way to code it.
Any direction or help is appreciated. Thank you!
I was trying to use this syntax
Dim Report_Name as Workbook
if Report_Name LIKE "*Health*" then
xyz
else
xyz
However I could only get LIKE operator working only with strings
Use FSO to loop through files and check their names:
Option Explicit
Sub Example()
Dim WB As Workbook
Dim FSO As New FileSystemObject
Dim oFolder As Object
Dim oFile As Object
Set FSO = CreateObject("Scripting.filesystemobject")
Set oFolder = FSO.GetFolder("C:\Users\cameron\Documents")
For Each oFile In oFolder.Files
If oFile.Name Like "*Your Partial File Name*" Then
Set WB = Workbooks.Open(oFile.Path)
'Do whatever you want with your workbook.
WB.Close '(Optional True/False for save changes)
End If
Next oFile
End Sub
Here are 2 sub that I can suggest. Since I don't understand from your question if you want to loop, open and modify the files in a folder, or you want simply to check the files names in a folder, I made 2 sub. One "LoopFilesNamesInFolder" will loop to check the file names without opening the files, and second one "LoopAndOpenFilesInFolder" allows you to open and make changes if you want to the files. You can use any of them based on your needs. Let me know if it helps you
Public Sub LoopFilesNamesInFolder()
Dim myPath As String
Dim myFile As String
Dim myExtension As String
Dim MyFileName As String
myPath = ThisWorkbook.Path & "\"
'The file name that you are looking for
MyFileName = "*Health*"
myExtension = "*.xls*"
'Current File in loop
myFile = Dir(myPath & myExtension)
Do While myFile <> vbNullString
If myFile Like MyFileName Then
'You can also use something like
'If LCase(myFile) Like LCase(MyFileName) Then
'If you want to make it not case sensitive
'Your code
Else
'Your code
End If
'Get next file name
myFile = Dir
Loop
End Sub
Public Sub LoopAndOpenFilesInFolder()
Dim wb As Workbook
Dim myPath As String
Dim myFile As String
Dim myExtension As String
Dim MyFileName As String
'if you want to Optimize code keep the following 3 instructions
Application.ScreenUpdating = False
Application.EnableEvents = False
Application.Calculation = xlCalculationManual
myPath = ThisWorkbook.Path & "\"
'The file name that you are looking for
MyFileName = "*Health*"
myExtension = "*.xls*"
'Current File in loop
myFile = Dir(myPath & myExtension)
Do While myFile <> vbNullString
Set wb = Workbooks.Open(Filename:=myPath & myFile)
'You can add a DoEvents here to give time to Excel to open the workbook before moving fwd
DoEvents
'Do Whatever you want to do
If wb.Name Like MyFileName Then
'You can also use something like
'If LCase(wb.Name) Like LCase(MyFileName) Then
'If you want to make it not case sensitive
'Your Code
Else
'Your Code
End If
'If you want to save your changes, replace the False by True to Save and Close Workbook
wb.Close SaveChanges:=False
'You can add a DoEvents here as well to give time to your Excel to close before moving to next one
DoEvents
'Get next file name
myFile = Dir
Loop
'Reset Settings
Application.ScreenUpdating = True
Application.EnableEvents = True
Application.Calculation = xlCalculationAutomatic
End Sub

how i can merge multi pdfs files by using VBA code

I have a table that contains a paths of multi pdfs file...now I need a VBA code to merge all these files to a single pdf file.
Notice:-the number of pdfs files to be merged varies from time to time.
Sub Combine_PDFs_Demo()
Dim i As Integer 'counter for records
Dim x As Integer
Dim strNPDF As String
Dim bSuccess As Boolean
Dim DB As Database
Dim RS As Recordset
Set DB = CurrentDb
Set RS = DB.OpenRecordset("SELECT[paths] from scantemp ")
strNPDF = CurrentProject.Path & "\request_pic\" & (request_no) & ".pdf"
RS.MoveLast
DB.Recordsets.Refresh
i = RS.RecordCount
RS.MoveFirst
Dim strPDFs() As String
ReDim strPDFs(0 To i)
strPDFs(0) = RS![paths]
RS.MoveNext
For i = 1 To i - 1
strPDFs(i) = RS![paths]
bSuccess = MergePDFs(strPDFs, strNPDF)
Next i
If bSuccess = False Then MsgBox "Failed to combine all PDFs", vbCritical, "Failed to Merge PDFs"
DoCmd.SetWarnings False
DoCmd.RunSQL "delete from scantemp" 'delete all paths from table scantemp after converted it to pdf
DoCmd.SetWarnings True
RS.Close
Set RS = Nothing`enter code here`
public Function MergePDFs(arrFiles() As String, strSaveAs As String) As Boolean
Dim objCAcroPDDocDestination As Acrobat.CAcroPDDoc
Dim objCAcroPDDocSource As Acrobat.CAcroPDDoc
Dim i As Integer
Dim iFailed As Integer
On Error GoTo NoAcrobat:
'Initialize the Acrobat objects
Set objCAcroPDDocDestination = CreateObject("AcroExch.PDDoc")
Set objCAcroPDDocSource = CreateObject("AcroExch.PDDoc")
'Open Destination, all other documents will be added to this and saved with
'a new filename
objCAcroPDDocDestination.Open (arrFiles(LBound(arrFiles))) 'open the first file
'Open each subsequent PDF that you want to add to the original
'Open the source document that will be added to the destination
For i = LBound(arrFiles) + 1 To UBound(arrFiles)
objCAcroPDDocSource.Open (arrFiles(i))
If objCAcroPDDocDestination.InsertPages(objCAcroPDDocDestination.GetNumPages - 1, objCAcroPDDocSource, 0, objCAcroPDDocSource.GetNumPages, 0) Then
MergePDFs = True
Else
'failed to merge one of the PDFs
iFailed = iFailed + 1
End If
objCAcroPDDocSource.Close
Next i
objCAcroPDDocDestination.save 1, strSaveAs 'Save it as a new name
objCAcroPDDocDestination.Close
Set objCAcroPDDocSource = Nothing
Set objCAcroPDDocDestination = Nothing
NoAcrobat:
If iFailed <> 0 Then
MergePDFs = False
End If
On Error GoTo 0
End Function
This uses a list of PDF or PS files to create one PDF. Sorry it's in VB.net and I don't really have time to convert. But it illustrates the concept if you can wade through it. Basically you write the options and file names to a text file then use that file as an argument to Ghostscript.
Private Shared Sub ConvertToPDF(ByVal PSPathFileList As List(Of String), _
ByVal PDFPathName As String, _
ByVal WaitForExit As Boolean, ByVal DeletePS As Boolean)
'check that all files exist
PSPathFileList.ForEach(AddressOf CheckFiles)
'check old pdf file
If IO.File.Exists(PDFPathName) Then
Throw New ApplicationException( _
"PDF cannot be created. File already exists: " & PDFPathName)
End If
'convert engine
Dim myProcInfo As New ProcessStartInfo
myProcInfo.FileName = DanBSolutionsLocation & "Misc\GhostScript\GSWIN32C.EXE"
Debug.Print(myProcInfo.FileName)
'write file names to text file as the list can be very long
Dim tempPath As String = IO.Path.GetDirectoryName(PSPathFileList.Item(0))
Dim fiName2 As String = tempPath & IO.Path.GetFileNameWithoutExtension(PDFPathName) & ".txt"
Dim ft As New StreamWriter(fiName2)
ft.WriteLine("-sDEVICE=pdfwrite -q -dSAFER -dNOPAUSE -sOUTPUTFILE=""" & PDFPathName & """ -dBATCH ")
For i As Long = 0 To PSPathFileList.Count - 1
ft.WriteLine(Chr(34) & PSPathFileList.Item(i) & Chr(34))
Next
ft.Close()
'set args to text file
myProcInfo.Arguments = """#" & fiName2 & """"
'set up for output and errors
myProcInfo.UseShellExecute = False
myProcInfo.RedirectStandardOutput = True
myProcInfo.RedirectStandardError = True
Debug.Print(myProcInfo.Arguments)
'do the conversion
Dim myProc As Process = Process.Start(myProcInfo)
Debug.Print(myProc.StandardOutput.ReadToEnd)
Debug.Print(myProc.StandardError.ReadToEnd)
If WaitForExit Then
'wait for finish; (no more than 60 seconds)
myProc.WaitForExit(60000)
'delete PS
If DeletePS Then
PSPathFileList.ForEach(AddressOf DeleteFiles)
End If
End If
End Sub
Here's VBA code for a single PS to PDF. So between the VB.net above and this below hopefully you can salvage something useful.
Private Sub printToPdfDemo()
'verify printer setup
'be sure to install the PsPrinterInstall module
Call PSPrinterSetup
Dim svPsFileName As String
Dim svPDFName As String
'define names
svPsFileName = "C:\Temp\Input 1.ps"
svPDFName = "C:\Temp\Output 1.PDF"
'save current printer
Dim PrinterInUse As String
PrinterInUse = Application.ActivePrinter
'print to PS
'If Fso.FileExists(svPsFileName) Then Call Fso.DeleteFile(svPsFileName)
Worksheets(1).PrintOut ActivePrinter:=PSPrinterName, PrintToFile:=True, _
PrToFileName:=svPsFileName
'revert to saved printer name
Application.ActivePrinter = PrinterInUse
'convert
Call ConvertToPDF(svPsFileName, svPDFName)
End Sub
Sub ConvertToPDF(ByVal svPsFileName As String, ByVal svPDFName As String)
Dim fso As New FileSystemObject
'Dim Fso: Set Fso = CreateObject("Scripting.FileSystemObject")
Dim folGS As Folder
Dim lcCmd As String
'check inputs
If svPsFileName = "" Or svPDFName = "" Then
Call MsgBox("PS file name or PDF file name is blank in ""ConvertToPDF"" macro", vbExclamation, "Error! Missing Inputs")
Exit Sub
End If
'check file
If Not fso.FileExists(svPsFileName) Then
Call MsgBox(svPsFileName & " file is not found", vbExclamation, "Error! Missing File")
Exit Sub
End If
'check variable
If DanBSolutionsLocation = "" Then DanBSolutionsLocation = GetDanBSolutionsLocation
'delete old file
If fso.FileExists(svPDFName) Then Call fso.DeleteFile(svPDFName)
'get files
Set folGS = fso.GetFolder(DanBSolutionsLocation & "Misc\GhostScript\") 'S:\DanB Solutions\Misc\GhostScript\GSWIN32C.EXE
'GS command
lcCmd = folGS.ShortPath & "\GSWIN32C.EXE " & _
"-q -dNOPAUSE -I" & folGS.ShortPath & "\lib;./fonts " & _
"-sFONTPATH=./fonts -sFONTMAP=" & folGS.ShortPath & "\lib\FONTMAP.GS " & _
"-sDEVICE=pdfwrite -sOUTPUTFILE=" & """" & svPDFName & """" _
& " -dBATCH " & """" & svPsFileName & """"
'convert
Debug.Print lcCmd
Call ShellWait(lcCmd)
'delete PS
If fso.FileExists(svPDFName) Then fso.DeleteFile (svPsFileName)
End Sub

Copy multiple files to multiple folders using FileDialog in Access vba

I am looking for a way to copy multiple files from a single folder and copy this grouping of files to multiple folders using FileDialog in Access vba. Below is what I have so far - the problem with this code is that I can only copy multiple files from a single folder to another single folder. Can anyone help with this:
Public Function CopyFilesToFolders()
On Error GoTo Err_Copy
Dim sourcefiles As String
Dim destination As String
Dim source As String
With Application.FileDialog(msoFileDialogFolderPicker)
.Title = "Select a folder that contains the desired files to copy."
If .Show = -1 Then source = .SelectedItems(1)
If Len(source) = 0 Then Exit Function
.AllowMultiSelect = True
.Title = "Select a folder location to copy the files."
If .Show = -1 Then destination = .SelectedItems(1)
If Len(destination) = 0 Then Exit Function
End With
sourcefiles = Dir$(source & "\*.*")
Do While Len(sourcefiles) > 0
FileCopy (source & "\" & sourcefiles), (destination & "\" & sourcefiles)
sourcefiles = Dir$
Loop
Exit_Copy:
Exit Function
Err_Copy:
CopyFilesToFolders = True
MsgBox Error$
Resume Exit_Copy
MsgBox "Task Complete!"
End Function
Thank you,
Al
So you want the function to automatically detect all the subfolders and copy the selected files to them? You can use FileSystemObject to detect all the subfolders, then copy the files to them. See this modified function:
Public Function CopyFilesToFolders()
On Error GoTo Exit_Copy
Dim sourcefiles As String
Dim destination As String
Dim source As String
Dim FileSystem As Object
Set FileSystem = CreateObject("Scripting.FileSystemObject")
With Application.FileDialog(msoFileDialogFolderPicker)
.Title = "Select a folder that contains the desired files to copy."
If .Show = -1 Then source = .SelectedItems(1)
If Len(source) = 0 Then Exit Function
.AllowMultiSelect = True
.Title = "Select a folder location to copy the files."
If .Show = -1 Then destination = .SelectedItems(1)
If Len(destination) = 0 Then Exit Function
End With
sourcefiles = Dir$(source & "\*.*")
Dim SubFolder
Do While Len(sourcefiles) > 0
For Each SubFolder In FileSystem.GetFolder(destination).SubFolders
FileCopy (source & "\" & sourcefiles), (SubFolder.path & "\" & sourcefiles)
Next
sourcefiles = Dir$
Loop
Exit_Copy:
Exit Function
End Function
Sorry, for changing the topic a bit, but I think int would be a lot easier to do this in Excel, rather than in Access. See the example below.
Sub sbCopyingAFile()
'Declare Variables
Dim FSO
Dim sFile As String
Dim sSFolder As String
Dim sDFolder As String
'This is Your File Name which you want to Copy
sFile = "Sample.xls"
'Change to match the source folder path
sSFolder = "C:\Temp\"
'Change to match the destination folder path
sDFolder = "D:\Job\"
'Create Object
Set FSO = CreateObject("Scripting.FileSystemObject")
'Checking If File Is Located in the Source Folder
If Not FSO.FileExists(sSFolder & sFile) Then
MsgBox "Specified File Not Found", vbInformation, "Not Found"
'Copying If the Same File is Not Located in the Destination Folder
ElseIf Not FSO.FileExists(sDFolder & sFile) Then
FSO.CopyFile (sSFolder & sFile), sDFolder, True
MsgBox "Specified File Copied Successfully", vbInformation, "Done!"
Else
MsgBox "Specified File Already Exists In The Destination Folder", vbExclamation, "File Already Exists"
End If
End Sub
Now, if you want to dynamically list the files in a folder, each file path in an individual cell, and then specify exactly which files to copy from one folder to another, that is definitely doable. First, try the sample code above, and give me feedback for future enhancements.

MS Access VBA lookup image file names from table, search for them and copy them

I'm using Access 2013. I have a list of images in a table. I then need to search through a set of folders (including sub folders), locate the images and copy them to a new directory. The table that contains the image names does not reference the file path.
What is the best way to achieve this? Is it possible to loop through the table and perform the search, or would I have break it down and manually locate each file and update a flag to say it exists, then go back and copy them?
Not sure how to do this but would appreciate any ideas.
Thanks.
For some import programs I had to manipulate files, create copies etc. and I created some functions to help process, you might find some use in them:
To create folder from VBA:
Public Function folderCreate(filePath As String) As Boolean
'define variables
Dim fsoFold As Object
'set file system object
Set fsoFold = CreateObject("Scripting.FileSystemObject")
If Not fsoFold.folderExists(filePath) Then
'check if folder exists
fsoFold.CreateFolder (filePath)
End If
folderCreate = True
Set fsoFold = Nothing
End Function
To check if folder exists:
Public Function folderExists(folderPath As String) As Boolean
'define variables
Dim fso As Object
'set file system object
Set fso = CreateObject("Scripting.FileSystemObject")
'check if file exists
If fso.folderExists(folderPath) Then
folderExists = True
Else
folderExists = False
End If
Set fso = Nothing
End Function
To check if file exists:
Public Function fileExists(filePath As String) As Boolean
'define variables
Dim fso As Object
'set file system object
Set fso = CreateObject("Scripting.FileSystemObject")
'check if file exists
If fso.fileExists(filePath) Then
fileExists = True
Else
fileExists = False
End If
Set fso = Nothing
End Function
Similar to this, use movefile to move it to new location.
fso.movefile strFullPath, strFullBackUp
EDIT: Following sub will go through given folder and list all JPG images - this code is just example how to find files, folders and how to recursively go through them.
Public Sub listImages(folderPath As String)
'define variables
Dim fso As Object
Dim objFolder As Object
Dim objFolders As Object
Dim objF As Object
Dim objFile As Object
Dim objFiles As Object
Dim strFileName As String
Dim strFilePath As String
Dim myList As String
'set file system object
Set fso = CreateObject("Scripting.FileSystemObject")
'set folder object
Set objFolder = fso.GetFolder(folderPath)
'set files
Set objFiles = objFolder.files
Set objFolders = objFolder.subfolders
'list all images in folder
For Each objFile In objFiles
If Right(objFile.Name, 4) = ".jpg" Then
strFileName = objFile.Name
strFilePath = objFile.Path
myList = myList & strFileName & " - " & strFilePath & vbNewLine
End If
Next
'go through all subflders
For Each objF In objFolders
'call same procedure for each subfolder
Call listImages(objF.Path)
Next
Debug.Print myList
Set objFolder = Nothing
set objFolders = Nothing
Set objFile = Nothing
set objF = Nothing
Set fso = Nothing
End Sub

Microsoft Access 2010 open all files in a directory

I am creating an MS Access 2010 database. I am using the API to do what the common dialog control did in previous versions of MS Access to open a directory and select a file. My client would like me to be able to open all of the files in the directory when a user clicks on a folder (so the user does not click on a file, just a folder). I cannot find an even triggering when the folder is clicked on within the common dialog control that comes up using the API.
Can anyone tell me how to open all the files in a directory (they will be .pdf files) when using the API for the common dialog control in MS ACCESS 2010?
The API calls I am using are here: http://access.mvps.org/access/api/api0001.htm
Use a FileSystemObject from Microsoft.Scripting.Runtime (must add reference to the project).
The following sub adds to a collection the string names of all pdf files in a given folder.
Get the folder path from the dialog (with folder picking option, not file picking)
Sub GetFolderPDFFiles(FolderPath As String, Col As Collection)
Dim FS As New FileSystemObject
Dim Dir As Folder
Dim Arq As File
Set Dir = FS.GetFolder(FolderPath)
For Each Arq In Dir.Files
If UCase(Right(Arq.Name, 4)) = ".PDF" Then
Call Col.Add(Arq.Path)
End If
Next
End Sub
This worked great for me... it will promt the dialog box to select the folder and open the .pdf files. it will also list all the files in Table1.
Option Compare Database
'function to select the folder where the files are:
Function ChooseFolder() As String
Dim fldr As FileDialog
Dim sItem As String
Set fldr = Application.FileDialog(msoFileDialogFolderPicker)
With fldr
.Title = "Select a Folder"
.AllowMultiSelect = False
.InitialFileName = strPath
If .Show <> -1 Then GoTo NextCode
sItem = .SelectedItems(1)
End With
NextCode:
ChooseFolder = sItem
Set fldr = Nothing
End Function
Enter the routines to open and list the pdf files in the folder (it also look for files in subfolders):
Sub Open_List_Files()
'Declare the variables
Dim objFSO As Scripting.FileSystemObject
Dim objFolder, objTopFolder As Scripting.Folder
Dim strTopFolderName As String, ProjectF As String
Dim i As Long
' call the function to select the folder
Call Módulo1.ChooseFolder
'Create an instance of the FileSystemObject
Set objFSO = CreateObject("Scripting.FileSystemObject")
'Get the top folder
Set objTopFolder = objFSO.GetFolder(ChooseFolder)
'Call the RecursiveFolder routine
Call RecursiveFolder(objTopFolder, True)
End Sub
Sub RecursiveFolder(objFolder As Scripting.Folder, IncludeSubFolders As Boolean)
'Declare the variables
Dim objFile As Object
Dim objSubFolder As Scripting.Folder
Dim DBStr, filepath As String
'Loop through each file in the folder
For Each objFile In objFolder.Files
On Error Resume Next
If InStr(objFile.Name, ".pdf") Then
DBStr = "INSERT INTO Table1 ([File Name]) " & _
" VALUES (" & _
"'" & objFile.Name & "', " & "');"
CurrentDb.Execute DBStr
'open the file
Application.FollowHyperlink objFile
End If
Next objFile
'Loop through files in the subfolders
If IncludeSubFolders Then
For Each objSubFolder In objFolder.SubFolders
Call RecursiveFolder(objSubFolder, True)
Next objSubFolder
End If
End Sub
Run the Open_List_Files() Macro and there you go! :)