Consulting

Results 1 to 5 of 5

Thread: Save in two places

  1. #1
    VBAX Regular
    Joined
    Jan 2016
    Posts
    18
    Location

    Question Save in two places

    Hi all,

    I am very new to VBA so I would like to get some help with a macro I have created (some parts of it were found in the Internet). The macro should save make a backup (in a specified path) of a file that is currently being saved, a procedure that is often discussed since Word lacks of it. I will talk over what I think the macro does and should do.

    1. FileSave procedure is intercepted.
    2. The macro checks if an active document is saved. If it is, no extra action is required and the macro closes.
    3. If an active document in not saved, the usual "Save As" dialog appears. If the user chooses to not save the file then the macro closes.
    4. If document is not saved, the macros saves it.
    5. The macro looks for a backup folder. If it is not found, the macro creates it and shows a message box.
    6. Then the macro checks if the source folder is the same as the backup folder. If they are the same, the macro shows a message and closes.
    7. The active (current) document is copied to the backup folder. If it fails, a message box is displayed.

    I tested this macro and it seems to work. However, there is a huge imperfection. When document is modified and the user chooses to close it, a dialog appears asking if the document should be saved. If the user chooses to do so, the document is saved, but a backup copy is not created - and I would like to create a backup in this situation.

    Could you check the macro against errors and suggest how to implement the above-mentioned feature? I am newbie so I am pretty sure that the macro is, to say the least, imperfect and it could be rewrirtten. I did my best to make it as elegant (e.g. I tried to avoid the GoTo procudure) and short as I could.

    Please find the macro below.

    Sub FileSave()
        Dim source As String
        Dim DocName As String
        Dim objF As Object
        Dim retVal As Long
    
        backup = "C:\Users\" & Environ("UserName") & "\Documents\BackupWord\"
    
        With ActiveDocument
                
                If .Saved Then Exit Sub
                    If .Path = "" Then
                        If Application.Dialogs(wdDialogFileSaveAs).Show <> -1 Then Exit Sub
                    End If
                'GoTo continue
                            
                If Not .Saved Then
                    ActiveDocument.Save
                End If
    'continue:
                If Dir(backup, vbDirectory) = "" Then
                    MkDir backup
                    MsgBox "Backup folder has been created.", vbInformation
                End If
            
                source = .Path & "\"
                DocName = .Name
                If source = backup Then
                    MsgBox "WARNING! Backup folder is the same as the source folder."
                    Exit Sub
                End If
    
                Set objF = CreateObject("Scripting.FileSystemObject")
                retVal = -1
                On Error Resume Next
                retVal = objF.CopyFile(source & DocName, _
                  backup & DocName, True)
                On Error GoTo 0
                Set objF = Nothing
                If retVal <> 0 Then
                    MsgBox "Backup has not been copied to folder " & backup
                End If
        End With
    End Sub

  2. #2
    VBAX Sage SamT's Avatar
    Joined
    Oct 2006
    Location
    Near Columbia
    Posts
    7,814
    Location
    Does this apply to
    1. All Documents
    2. Documents of a certain Template
    3. Only certain Documents


    In any case the code must be in a Class Module
    If 1 , then it must be in Normal.dot
    If 2, it must be in the Templae
    If 3, it must be in the Document itself.

    You will need two Event Procedures
    For case 1, Private Sub appWord_DocumentBeforeClose and Private Sub appWord_DocumentBeforeSave
    For cases 2 and 3, Private Sub appWord_Quit and Private Sub appWord_DocumentBeforeSave

    The following is from the Help files

    Private Sub App_Quit()


    object An object of type Application declared with events in a class module. See using events with the Application object below


    Private Sub App_DocumentBeforeClose(ByVal Doc As Document, Cancel As Boolean)


    object An object of type Application declared with events in a class module. For more information about using events with the Application object see below.

    Doc The document that's being closed.
    Cancel False when the event occurs. If the event procedure sets this argument to True, the document doesn't close when the procedure is finished.


    Private Sub App_DocumentBeforeSave(ByVal Doc As Document, ByVal SaveAsUI As Boolean, Cancel As Boolean)


    object An object of type Application declared with events in a class module. For more information about using events with the Application object see below.

    Doc The document that's being saved.

    SaveAsUI True to display the Save As dialog box.
    Cancel False when the event occurs. If the event procedure sets this argument to True, the document isn't saved when the procedure is finished.


    Using Events with the Application Object

    See Also Specifics
    To create an event handler for an event of the Application object, you need to complete the following three steps:


    1. Declare an object variable in a class module to respond to the events.
    2. Write the specific event procedures.
    3. Initialize the declared object from another module.

    Declare the Object Variable

    Before you can write procedures for the events of the Application object, you must create a new class module and declare an object of type Application with events. For example, assume that a new class module is created and called EventClassModule. The new class module contains the following code.
    Public WithEvents App As Word.Application Write the Event Procedures

    After the new object has been declared with events, it appears in the Object drop-down list box in the class module, and you can write event procedures for the new object. (When you select the new object in the Object box, the valid events for that object are listed in the Procedure drop-down list box.) Select an event from the Procedure drop-down list box; an empty procedure is added to the class module.
    Private Sub App_DocumentChange()

    End Sub Initialize the Declared Object

    Before the procedure will run, you must connect the declared object in the class module (App in this example) with the Application object. You can do this with the following code from any module.
    Dim X As New EventClassModule
    Sub Register_Event_Handler()
    Set X.App = Word.Application
    End Sub Run the Register_Event_Handler procedure. After the procedure is run, the App object in the class module points to the Microsoft Word Application object, and the event procedures in the class module will run when the events occur.
    I expect the student to do their homework and find all the errrors I leeve in.


    Please take the time to read the Forum FAQ

  3. #3
    VBAX Sage SamT's Avatar
    Joined
    Oct 2006
    Location
    Near Columbia
    Posts
    7,814
    Location
    The code in the two Event Procedure should jut call the sub that does the actual savingl
    I expect the student to do their homework and find all the errrors I leeve in.


    Please take the time to read the Forum FAQ

  4. #4
    http://www.gmayor.com/SaveInTwoPlacesAddIn.htm might save you a lot of effort.
    Graham Mayor - MS MVP (Word) 2002-2019
    Visit my web site for more programming tips and ready made processes
    http://www.gmayor.com

  5. #5
    VBAX Regular
    Joined
    Jan 2016
    Posts
    18
    Location
    gmayor

    I know your addin - it's great.Your is very user friendly with GUI, pop-ups and so on. I would like to have a macro to suit my needs - with almost no pop ups and son on.

    Quote Originally Posted by SamT View Post
    Does this apply to
    1. All Documents
    2. Documents of a certain Template
    3. Only certain Documents


    In any case the code must be in a Class Module
    If 1 , then it must be in Normal.dot
    If 2, it must be in the Templae
    If 3, it must be in the Document itself.
    It seems that it applies to all document. The code is in normal.dot in Microsoft Word Object -> ThisDocument. For a starter, I would like to deal with a dialog when I close Word which shows if I want to save or not a document or to cancel. My macro fails to show a msgbox when I choose "Cancel". Could you help me with this? Your first reply was to complicated for me - I am really newbie in VBA.

    Private Sub DocumentBeforeSave()
    
        With ActiveDocument
            If Application.Dialogs(wdDialogFileSaveAs).Show = 0 Then
                MsgBox "The Cancel button."
            End If
    
    End With
    End Sub

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •