Excel VBA Course
Excel VBA Course - From Beginner to Expert

200+ Video Lessons
50+ Hours of Video
200+ Excel Guides

Become a master of VBA and Macros in Excel and learn how to automate all of your tasks in Excel with this online course. (No VBA experience required.)

View Course

Edit VBA code to let it automaticlly create Folder

0

Good day all

I have the below code wich is working totally perfect.

which is take the worksheet and save it as pdf and xls format and before that the code ask me to specify the destination folder

then the code attach both file on new outlook mail

I need the code do do all the same but automaticlly create and select the distenation folder "C:\Users\qaroosya\Documents\2023\" and create a folder for each month

Sub Acreatepdf()
Dim EmailSubject As String, EmailSignature As String
Dim CurrentMonth As String, DestFolder As String, PDFFile As String
Dim Email_To As String, Email_CC As String, Email_BCC As String
Dim OpenPDFAfterCreating As Boolean, AlwaysOverwritePDF As Boolean, DisplayEmail As Boolean
Dim OverwritePDF As VbMsgBoxResult
Dim OutlookApp As Object, OutlookMail As Object
Dim NewWB As Workbook
Dim ActiveWS As Worksheet
Dim Qaroos As String
Qaroos = "WSX"
CurrentMonth = ""
Set ActiveWS = ActiveSheet
Application.CalculateFullRebuild
Application.ScreenUpdating = False
Application.DisplayAlerts = False
Application.EnableEvents = False
ActiveSheet.PageSetup.PrintArea = "Qpmr"
' *****************************************************
' *****     You Can Change These Variables    *********
    EmailSubject = [SubMG]   'Change this to change the subject of the email. The current month is added to end of subj line
    OpenPDFAfterCreating = False    'Change this if you want to open the PDF after creating it : TRUE or FALSE
    AlwaysOverwritePDF = False      'Change this if you always want to overwrite a PDF that already exists :TRUE or FALSE
    DisplayEmail = True 'Change this if you don't want to display the email before sending.  Note, you must have a TO email address specified for this to work
    Email_To = "Qtest@gmail.com"   'Change this if you want to specify To email e.g. ActiveSheet.Range("H1") to get email from cell H1

    Email_CC = [CCMG]
    Email_BCC = ""
' ******************************************************
    'Prompt for file destination
    With Application.FileDialog(msoFileDialogFolderPicker)
        If .Show = True Then
            DestFolder = .SelectedItems(1)
        Else
            MsgBox "You must specify a folder to save the PDF into." & vbCrLf & vbCrLf & "Press OK to exit this macro.", vbCritical, "Must Specify Destination Folder"
            Exit Sub
        End If
    End With
    'Current month/year stored in H6 (this is a merged cell)
    CurrentMonth = Mid(ActiveSheet.Range("H6").Value, InStr(1, ActiveSheet.Range("H6").Value, " ") + 1)
    'Create new PDF file name including path and file extension
    PDFFile = DestFolder & Application.PathSeparator & [TitMG] & ".pdf"
    'If the PDF already exists
    If Len(Dir(PDFFile)) > 0 Then
        If AlwaysOverwritePDF = False Then
            OverwritePDF = MsgBox(PDFFile & " already exists." & vbCrLf & vbCrLf & "Do you want to overwrite it?", vbYesNo + vbQuestion, "File Exists")
            On Error Resume Next
            'If you want to overwrite the file then delete the current one
            If OverwritePDF = vbYes Then
                Kill PDFFile
                Kill Replace(PDFFile, ".pdf", ".xlsx")
            Else
                MsgBox "OK then, if you don't overwrite the existing PDF, I can't continue." _
& vbCrLf & vbCrLf & "Press OK to exit this macro.", vbCritical, "Exiting Macro"
                Exit Sub
            End If
        Else
            On Error Resume Next
            Kill PDFFile
            Kill Replace(PDFFile, ".pdf", ".xlsx")
        End If
        If Err.Number <> 0 Then
            MsgBox "Unable to delete existing file.  Please make sure the file is not open or write protected." _
& vbCrLf & vbCrLf & "Press OK to exit this macro.", vbCritical, "Unable to Delete File"
            Exit Sub
        End If
    End If
    'Create the PDF
    ActiveWS.ExportAsFixedFormat Type:=xlTypePDF, Filename:=PDFFile, Quality:=xlQualityStandard, IncludeDocProperties:=True, IgnorePrintAreas _
:=False, OpenAfterPublish:=OpenPDFAfterCreating
    Set NewWB = Workbooks.Add
    ActiveWS.copy Before:=NewWB.Sheets(1)
    NewWB.SaveAs Replace(PDFFile, ".pdf", ".xlsx")
    NewWB.Close
    'Create an Outlook object and new mail message
    Set OutlookApp = CreateObject("Outlook.Application")
    Set OutlookMail = OutlookApp.CreateItem(0)
    'Display email and specify To, Subject, etc
    With OutlookMail
        .To = Email_To
        .CC = Email_CC
        .BCC = Email_BCC
        .Subject = [SubMG]
        .Attachments.Add PDFFile
        .Attachments.Add Replace(PDFFile, ".pdf", ".xlsx")
        .HTMLBody = RangetoHTML(Sheets("Index").Range("AF564:AW632"))
        .Display
Application.DisplayAlerts = True
Application.EnableEvents = True
If Err Then
      MsgBox "E-mail not created", vbExclamation
    Else
            MsgBox "E-mail successfully Created, You may display your Morning report from your Outlook for final check ... ", vbInformation
    End If
        If DisplayEmail = False Then
             If Sheets("Index").Range("AG561").Value = "Timer" Then
                Application.OnTime TimeValue("AI561").Value, Procedure:="MYcode"
                   Else
            End If
        End If
    End With
ActiveSheet.Unprotect Qaroos

If ActiveSheet.Range("Z3").Value = "S" Then

For Each Pr In ActiveSheet.Pictures
       If Not Intersect(Pr.TopLeftCell, Range("K17:V33,K66:V82,K114:V130,K161:V178,K210:V226,K257:V273,K304:V320,K350:V366")) Is Nothing Then
        Pr.Delete
       End If
    Next Pr
For Each Pr In ActiveSheet.Pictures
      If Not Intersect(Pr.BottomRightCell, Range("K17:V33,K66:V82,K114:V130,K161:V178,K210:V226,K257:V273,K304:V320,K350:V366")) Is Nothing Then
        Pr.Delete
       End If
    Next Pr
Call histor
Call seplit
Call Updateuncoplatedjob
Call Clearreport
Call indexclear

Sheets("DAILY OPS REPORT8").Select
Application.ScreenUpdating = True
ActiveSheet.Protect Qaroos, DrawingObjects:=False, Contents:=True, Scenarios:=True _
        , AllowFormattingCells:=True, AllowFormattingRows:=True, _
    AllowFormattingColumns:=False, AllowInsertingColumns:=False, _
    AllowInsertingRows:=False, AllowInsertingHyperlinks:=False, _
    AllowDeletingColumns:=False, AllowDeletingRows:=False, _
    AllowSorting:=False, AllowFiltering:=False, AllowUsingPivotTables:=False
MsgBox (" " & ActiveSheet.Range("D1").Value & " Empty Morning report ready to use.")

 Else

Call histor
Call seplit
Call Updateuncoplatedjob
Call Clearreport
Call indexclear
Sheets("DAILY OPS REPORT8").Select
Application.ScreenUpdating = True
ActiveSheet.Protect Qaroos, DrawingObjects:=True, Contents:=True, Scenarios:=True _
        , AllowFormattingCells:=True, AllowFormattingRows:=True
    Application.ScreenUpdating = True
MsgBox (" " & ActiveSheet.Range("D1").Value & " Empty Morning report ready to use")

End If

ThisWorkbook.Save

End Sub
 Function RangetoHTML(Rng As Range)
' Working in Office 2000-2016
    Dim fso As Object
    Dim ts As Object
    Dim TempFile As String
    Dim TempWB As Workbook
    TempFile = Environ$("temp") & "\" & Format(Now, "dd-mm-yy h-mm-ss") & ".htm"
    'Copy the range and create a new workbook to past the data in
    Rng.copy
    Set TempWB = Workbooks.Add(1)
    With TempWB.Sheets(1)
        .Cells(1).PasteSpecial Paste:=8
        .Cells(1).PasteSpecial xlPasteValues, , False, False
        .Cells(1).PasteSpecial xlPasteFormats, , False, False
        .Cells(1).Select
        Application.CutCopyMode = False
        On Error Resume Next
        .DrawingObjects.Visible = True
        .DrawingObjects.Delete
        On Error GoTo 0
    End With
    'Publish the sheet to a htm file
With TempWB.PublishObjects.Add( _
SourceType:=xlSourceRange, _
Filename:=TempFile, _
Sheet:=TempWB.Sheets(1).Name, _
Source:=TempWB.Sheets(1).UsedRange.Address, _
HtmlType:=xlHtmlStatic)
        .Publish (True)
    End With
    'Read all data from the htm file into RangetoHTML
    Set fso = CreateObject("Scripting.FileSystemObject")
    Set ts = fso.GetFile(TempFile).OpenAsTextStream(1, -2)
    RangetoHTML = ts.readall
    ts.Close
    RangetoHTML = Replace(RangetoHTML, "align=center x:publishsource=", _
"align=left x:publishsource=")
    'Close TempWB
    TempWB.Close SaveChanges:=False
    'Delete the htm file we used in this function
    Kill TempFile
    Set ts = Nothing
    Set fso = Nothing
    Set TempWB = Nothing
End Function
Answer
Discuss

Discussion

Hi again Qaroos

I'm reluctant to spend any time helping you on this (although it's not too hard).

Why? Well I took time to answer your previous question VBA to Copy range from Sheet to another and defined a name but you said I'd missed the fourth part, something about an defined name. When I asked you what you meant, you didn't reply. Nor did you mark my Answer as Selected.

Why should I give up more of my spare time to help you, given that previous behaviour?
John_Ru (rep: 6142) Nov 22, '23 at 1:19 pm
I sincerely apologize for that, but I don't think I meant to be rude.really I am so sorry.  
Qaroos (rep: 4) Nov 23, '23 at 12:15 am
Okay Qaroos. Hope you like my Answer.
John_Ru (rep: 6142) Nov 23, '23 at 8:53 am
Add to Discussion

Answers

0
Selected Answer

Qaroos

You didn't attach a sample file to test but I suggest that you replace the section of code below:

' ******************************************************
    'Prompt for file destination
    With Application.FileDialog(msoFileDialogFolderPicker)
        If .Show = True Then
            DestFolder = .SelectedItems(1)
        Else
            MsgBox "You must specify a folder to save the PDF into." & vbCrLf & vbCrLf & "Press OK to exit this macro.", vbCritical, "Must Specify Destination Folder"
            Exit Sub
        End If
    End With

with this code (which will check that both the year and months subfolder exist, creating them if they do not) but move the declaration of the new variable fldrEnd to the other Dim statements:

Dim fldrEnd As String

    ' specify an existing parent folder path (ending with \)
    DestFolder = "C:\Users\qaroosya\Documents\"
    ' save its length
    fldrEnd = Len(DestFolder)

    ' check if both subfolders exist for current year/month
    If Dir(DestFolder & Format(Date, "yyyy") & "\" & Format(Date, "mmmm") & "\", vbDirectory) = vbNullString Then
        ' re-write path to add current year to it, like "\2023\"
        DestFolder = DestFolder & Format(Date, "yyyy")
        ' if that subfolder doesn't exist, create year subfolder then do same (but adding month)
        If Dir(DestFolder, vbDirectory) = vbNullString Then VBA.FileSystem.MkDir (DestFolder)
        DestFolder = DestFolder & "\" & Format(Date, "mmmm")
        ' if not present, create month subfolder
        If Dir(DestFolder, vbDirectory) = vbNullString Then VBA.FileSystem.MkDir (DestFolder)
        ' tell user you did that
        MsgBox "New subfolder(s) for current (year/)month created in " _
            & vbCr & Left(DestFolder, fldrEnd) & vbCr & "with name: " _
            & vbCr & vbCr & Mid(DestFolder, fldrEnd + 1, 30)
    End If

    ' full path exists (now) so set it as the destination folder

    DestFolder = myPath & Format(Date, "yyyy") & "\" & Format(Date, "mmmm") & "\"

Note that the second bold line ends the path with "....Documents\" (without the year) since it will create new folders for the year and the month when needed, giving a message like:

New subfolder(s) for current (year/)month created in 
C:\Users\qaroosya\Documents\
with name: 

2023\November

This should prove useful when you use the code in a new year or month.

Revision 05 December 2023

In your second attached file, you take the  approach of creating a filepath from a root folder plus a year and a month. I assume that the failing code is Sub AcreatepdfQ (in Module2) where I found that the line 

NewWB.SaveAs Replace(PDFFile, ".pdf", ".xlsx")

failed (when the year and monthy folders exist) because the code was trying to save a file with full path which missed those year and month folders, attempting to save:

C:\Users\qaroosya\Documents\\Subject here W.xlsx

and you can't have \\ in a path name.

The error arise within the code extract below.

Firstly my original Answer simply created necessary folders (I didn't really look at how you used them, sorry!) so the first change in bold below is needed to fix that. The second bold change is needed since you accidentally added another \ in creating the path for PDFFile:

    ' specify an existing parent folder path (ending with \)

    DestFolder = Sheets("index").Range("D2").Value



    ' save its length

    fldrEnd = Len(DestFolder)



    ' check if both subfolders exist for current year/month

    If Dir(DestFolder & Sheets("index").Range("E2").Value & "\" & Sheets("index").Range("G2").Value & "\", vbDirectory) = vbNullString Then

        ' re-write path to add current year to it, like "\2023\"

        DestFolder = DestFolder & Sheets("index").Range("E2").Value

        ' if that subfolder doesn't exist, create year subfolder then do same (but adding month)

        If Dir(DestFolder, vbDirectory) = vbNullString Then VBA.FileSystem.MkDir (DestFolder)

        DestFolder = DestFolder & "\" & Sheets("index").Range("G2").Value

        ' if not present, create month subfolder

        If Dir(DestFolder, vbDirectory) = vbNullString Then VBA.FileSystem.MkDir (DestFolder)

        ' tell user you did that

        MsgBox "New subfolder(s) for current (year/)month created in " _

            & vbCr & Left(DestFolder, fldrEnd) & vbCr & "with name: " _

            & vbCr & vbCr & Mid(DestFolder, fldrEnd + 1, 30)

    End If
    
    ' full path exists (now) so set it as the destination folder

    DestFolder = DestFolder & Sheets("index").Range("E2").Value & "\" & Sheets("index").Range("G2").Value & "\"
    
' ******************************************************





    'Current month/year stored in H6 (this is a merged cell)

    CurrentMonth = Mid(ActiveSheet.Range("H6").Value, InStr(1, ActiveSheet.Range("H6").Value, " ") + 1)

    'Create new PDF file name including path and file extension

    ' ### replaced PDFFile = DestFolder & Application.PathSeparator & [TitMG] & ".pdf"

    PDFFile = DestFolder & [TitMG] & ".pdf"

These changes are made in the file attached to this Answer. (I also added a similar first change to the original approach, even though you are not using that).

Hope this fixes your problem. If so, please be sure to mark theis Answer as Selected.

Discuss

Discussion

Hi John Run, the code run perfect to create the subfolders if the folders doesn't exist, but it gives me an error when the folders already there.
Qaroos (rep: 4) Nov 24, '23 at 10:39 pm
I add a simple file, I wondering if it's possible to let destination folder and subfolder get from cell value. 

As I tell you the code you made is exactly do what I want for the first time of the month then I get an error as what will you see on screenshot on the attached file.    
Qaroos (rep: 4) Nov 25, '23 at 2:06 am
Qaroos

In response to your points above

1) "I add a simple file, I wondering if it's possible to let destination folder and subfolder get from cell value."
     >>>John_Ru response: You seem to be asking a separate question here (and yes it's p[ossible to do that but my code does it without VLOOKUP etc.). You could create a folder path like in worksheet "Index" in your file but there is no code in the file you attached so I don't know how you're using the path "C:\Users\qaroosya\Documents\2023\November" in cell J2. That path would need to a \ then the fill file name when saving to it. It certainly can't be used directly without altering the code xhnage I suggested.

2) "As I tell you the code you made is exactly do what I want for the first time of the month then I get an error as what will you see on screenshot on the attached file."
       >>>John_Ru response: I tried my code again. For me it does NOT give an error if the folder already exists. You show the screen grab of the error message but you don't say which line of code fails (so I can't help you).

(Also, did you see the revision and second file attached to my Answer on your previous question?)
John_Ru (rep: 6142) Nov 25, '23 at 6:35 am
Hi John I just replaced the attached file and it contains the code and the code as I tell you that work smoothly but it won't be done on the 2nd run. 

And regarding the J2 value if it's possible it will be great help when I need to save a file from previous months or previous years 
Qaroos (rep: 4) Nov 29, '23 at 12:08 am
Hi again Qaroos. I've seen your file (and had to rename it since it had two extensions). I'm busy for the next 2 days but will try to reply at the weekend. 
John_Ru (rep: 6142) Nov 29, '23 at 6:00 pm
Hi John_ru

I try to modify the code and it is work perfect while creating the folders and subfolders, but the issue that I can’t understand is why it can’t save on the same folder after it created, I can’t use the folder if its exist if not it will be created if yes I get a error 1004

Qaroos (rep: 4) Dec 3, '23 at 5:28 am
 
 
    ' specify an existing parent folder path (ending with \)
    DestFolder = Sheets("index").Range("D2").Value
    ' save its length
    fldrEnd = Len(DestFolder)
 
    ' check if both subfolders exist for current year/month
    If Dir(DestFolder & Sheets("index").Range("E2").Value & "\" & Sheets("index").Range("G2").Value & "\", vbDirectory) = vbNullString Then
        ' re-write path to add current year to it, like "\2023\"
        DestFolder = DestFolder & Sheets("index").Range("E2").Value
        ' if that subfolder doesn't exist, create year subfolder then do same (but adding month)
        If Dir(DestFolder, vbDirectory) = vbNullString Then VBA.FileSystem.MkDir (DestFolder)
        DestFolder = DestFolder & "\" & Sheets("index").Range("G2").Value
        ' if not present, create month subfolder
        If Dir(DestFolder, vbDirectory) = vbNullString Then VBA.FileSystem.MkDir (DestFolder)
        ' tell user you did that
        MsgBox "New subfolder(s) for current (year/)month created in " _
            & vbCr & Left(DestFolder, fldrEnd) & vbCr & "with name: " _
            & vbCr & vbCr & Mid(DestFolder, fldrEnd + 1, 30)
    End If
Qaroos (rep: 4) Dec 3, '23 at 5:28 am
Sorry Qaroos but I don't have time todayBUT your file currently produces an error in the filename....

Cell G2 reads:
=VLOOKUP(MONTH(TODAY()),$B$5:$C$16,2,FALSE)

but this month number/ name (December) is in row 17. G2 should read:    
=VLOOKUP(MONTH(TODAY()),$B$6:$C$17,2,FALSE)
John_Ru (rep: 6142) Dec 3, '23 at 8:47 am
yes, You are right. I wrote this equation in G2 just to illustrate and clarify my idea and to show what I mean in a simple way. 

So please once you have time try to check why it give me an error on this line when the folder exis
 NewWB.SaveAs Replace(PDFFile, ".pdf", ".xlsx")
Qaroos (rep: 4) Dec 4, '23 at 2:18 am
While I try to fix that, I found a way to not face that error by create daily subfolder insaide the monthly one 
DestFolder = DestFolder & "\" & Sheets("index").Range("G2").Value & "\" & Sheets("index").Range("I2").Value & "\"


Could you please try it and see if it is Work?
Qaroos (rep: 4) Dec 5, '23 at 3:42 am
Qaroos. Please upload your latest file ( add it as a second file to your Question) so I can try that. I'm getting lost on your changes. 
John_Ru (rep: 6142) Dec 5, '23 at 5:58 am
Hi John The file has been attached.  Let me clarify it,I need now just to make the code work without errors, because I found the error come if the folder already exist
Qaroos (rep: 4) Dec 5, '23 at 7:25 am
Qaroos. Thanks for attaching the file, it really helped.

Please see my Answer and added file, specifically the explanation under  "Revision 05 December 2023".

Hopefully this fixes things for you- if so please be sure to mark my Answer as Selected. For the future, kindly note that my task is to answer your question really, not to debug your full code.
John_Ru (rep: 6142) Dec 5, '23 at 5:41 pm
Thanks a lot my hero, the code do it smoothly and fits on the file as gloves.   I try it today so many time and it is perfect and work as expected 

thank you again and again (big hug).
Qaroos (rep: 4) Dec 6, '23 at 6:26 am
Great!  Glad that worked for you. Thanks for selecting my Answer, Qaroos.
John_Ru (rep: 6142) Dec 6, '23 at 6:42 am
Add to Discussion


Answer the Question

You must create an account to use the forum. Create an Account or Login