The macros below will automatically save a document after assembly. The macros will work "as-is" (as-are?). Simply save the appropriate macro to the macro directory (WordPerfect) or to a global add-in template (Word). The WordPerfect macro is also available for download.
Quick Overview: These macros are all based on the same concept. The user is prompted for the document's filename by HotDocs during assembly. This is just a HotDocs text variable, called TextVar in the explanations below. This text variable is placed somewhere in the template surrounded by a bookmark. When assembly is complete, the macro looks for the bookmark, extracts the value of TextVar from within it, and saves the document using this value as the filename.
Directory: You should be able to add directory-selecting functionality fairly easily. One option is to create a HotDocs multiple choice variable for the directory and include that variable within the bookmark with TextVar:
[Bookmark]«Directory»«TextVar»[Bookmark]
The second Word macro below demonstrates how to have your macro determine the directory, and additionally how to add an entry for the document in a Lawbase database.
Invoking the Macro: The macros are all invoked in the same manner, regardless of whether you use Word or WordPerfect. To invoke the macro you must use a PLAY instruction at the end of the document. In other words, make sure that the PLAY is the very last thing in the document. Otherwise, the saved document will be incomplete. To create a PLAY instruction, follow the directions found in Computation #0108: Running a Macro During Assembly.
• • • • • • •
WordPerfect:
DISPLAY( Off! )
ONERROR( Oops )
ONCANCEL( CheckStatus )
// Find and select the requested filename
BookmarkBlock( "AutoSave" )
// Extract the filename
vFile := ?SelectedText
SelectDelete
BookmarkDelete( "AutoSave" )
// Uncomment the next line of code to end the macro
// if the user did not give a filename (no-nag mode)
// IF (vFile = "") GO( CheckStatus ) ENDIF
// The following do not apply to directories or non-named files
IF (( vFile <> "" ) AND ( StrRight( vFile;1 ) <> "\" ))
// Add a file extension if there is not one
IF (StrPos( StrRight( vFile;4 ); "." ) < 1)
vFile = vFile + ".wpd"
ENDIF
// See if the file already exists
IF (StrPos( vFile; "\" ) > 0)
vDir := ""
ELSE
vDir := ?PathDocument
ENDIF
FileExists( vExists; vDir + vFile )
IF (vExists = True)
MessageBox(;"Save Document"; """" + vFile + """ already exists.")
vPos := StrPos( StrReverse( vFile ); "\" )
IF (vPos > 0)
vFile := StrLeft( vFile; StrLen( vFile ) - vPos + 1)
ELSE
vFile := ""
ENDIF
ENDIF
ENDIF
// Perform the Save operation
FileSave( Filename:vFile; Overwrite:Yes! )
GO( CheckStatus )
// Check whether the file was saved
LABEL( CheckStatus )
IF (?Name <> "")
MessageBox(;"Save Document"; "Saved as """ + ?Name + """")
ELSE
MessageBox(;"Save Document"; "Document was NOT saved.")
ENDIF
GO( Away )
LABEL( Oops )
MessageBox(;"Save Document"; "An unknown error has ocurred.")
GO( CheckStatus )
LABEL( Away )
// Instead of using QUIT, we GO( Away ).
// QUIT can kill HotDocs, so don't use it.
This macro looks for a filename located in a bookmark called AutoSave. To create this in your template, insert the HotDocs text variable which will contain the filename (TextVar). Next select the entire variable - chevrons and all. Now create the bookmark (generally: Tools or Insert > Bookmark > Create). Type AutoSave as the name of the bookmark, and make sure that Selected Bookmark is checked. Finally, create your PLAY instruction as directed above.
When your user assembles the document, your TextVar will ask them what the filename should be. If they give a unique filename with full path, the document will automatically be saved with that name. BUT: 1) If they give only a filename, but no directory, they will be presented with the "Save As" dialog with the filename filled in, where they can then choose the appropriate directory and "Save" the document. 2) If they do not include a file extension (such as ".wpd") one will be added automatically. 3) If they give only a directory (it must end in "\"), they will be presented with the "Save As" dialog with that directory preselected. 4) If the chosen filename already exists, they will be presented with the "Save As" dialog so that they can choose a different name. 5) And if they leave TextVar unanswered, they will be presented with the "Save As" dialog. This final behavior can be changed to "no-nag" mode (macro will simply end if the filename value is blank) by uncommenting the line noted in the macro.
Note that whenever the user gets the "Save As" dialog they can dismiss it without saving the document.
Contributor: LegalCS
• • • • • • •
Word:
Option Explicit
Public Sub HDSaveasmsb()
Dim Temp As String 'contents will be the filename
Dim Temp1 As String 'selected text
Dim Temp2 As String 'the final file name (with .doc) for comparison in error loop
Dim Path As String 'path of caselog that will be saved
Dim newname As String 'contents will be user input file name if temp is already a valid filename
Dim message As String 'message for input box in error routine
Path = "c:\" '!! place the directory here; be sure it ends with "\"
' Find the marker ***zzz and delete it.
' Curser will now be at the beginning of the
' filename that was inserted by HD.
Selection.Find.ClearFormatting
Selection.Find.Replacement.ClearFormatting
With Selection.Find
.Text = "***zzz"
.Replacement.Text = ""
.Forward = True
.Wrap = wdFindContinue
.Format = False
.MatchCase = False
.MatchWholeWord = False
.MatchWildcards = False
.MatchSoundsLike = False
.MatchAllWordForms = False
.Execute
End With
With Selection
If .Find.Forward = True Then
.Collapse Direction:=wdCollapseStart
Else
.Collapse Direction:=wdCollapseEnd
End If
.Find.Execute Replace:=wdReplaceOne
If .Find.Forward = True Then
.Collapse Direction:=wdCollapseEnd
Else
.Collapse Direction:=wdCollapseStart
End If
.Find.Execute
End With
' Select the rest of the line, i.e., the file name
' Then move left 1 character so the paragraph mark is not included in the selection
Selection.EndKey Unit:=wdLine, Extend:=wdExtend
Selection.MoveLeft Unit:=wdCharacter, Count:=1, Extend:=wdExtend
Temp = Path & Selection.Text ' "save to" path + file name taken from the bookmark
Temp1 = Selection.Text
Temp2 = Temp & ".doc"
' If filename is in use, keep prompting until a free name is given
While Dir(Temp2) <> ""
message = "There is already a Caselog file called " & Temp1 & ". Please choose another name for this file."
newname = InputBox(message, "Choose a New File Name")
Temp = Path & newname
Temp1 = newname
Temp2 = Temp & ".doc"
Do Loop
' Save the file
ActiveWindow.View.Type = wdNormalView ' Optional
ActiveDocument.SaveAs FileName:=Temp
ActiveDocument.Close ' Optional
End Sub
Rather than a bookmark, the template needs the label "***zzz" just before the HD text variable that holds the filename (TextVar). For example:
***zzz«TextVar»¶
The macro will take all text between this label and the paragraph mark as the filename.
Also, do not include a '.doc' extension! The macro adds it automatically.
The macro needs you to specify what the document path will be at the Path = "" line. Without this, the macro will fail.
The macro will make sure that the requested filename does not exist already. If there does happen to already be a file with that name, the macro will prompt the user for a different name.
Contributor: Mike Bernstein
• • • • • • •
Word:
Sub SaveDoc()
Dim DocNameStr As String
Dim DocPathStr As String
Dim DocNameChoppedStr As String
Dim DocDriveLtr
Dim nextSerial
' Find the bookmark called DocumentName to get the document's save name
Selection.GoTo What:=wdGoToBookmark, Name:="DocumentName"
' Select all of the text in the DocumentName line
Selection.EndKey Unit:=wdLine, Extend:=wdExtend
' Dump the searched text into a string for use in saving the file
DocNameStr = Selection.Text
DocNameChoppedStr = Selection.Text
' Use the last name of the person to whom the document is created to
' pick the directory where it will be stored
DocDriveLtr = Left(DocNameChoppedStr, 1)
' Set the string of the drive and path to where the document will be saved
' !! MODIFY THIS TO MATCH YOUR DRIVE CONFIGURATION !!
DocPathStr = "//SERVERNAME/SomePath/" & DocDriveLtr & "/"
' Delete the bookmark from the document
Selection.Delete
' Save the file using the directory that was specified above and the name
' that is designated by DocNameStr
With Dialogs(wdDialogFileSaveAs)
.Name = DocPathStr & DocNameStr & "_"
.Show
End With
' Begin section to set office link and throw the link to the document
' in there as well
Selection.GoTo What:=wdGoToBookmark, Name:="DocuSerial"
' Get the saved documents name and path
DocNameStr = ""
DocPathStr = ""
DocNameStr = ActiveDocument.Name
DocPathStr = ActiveDocument.Path
Dim SerialNum
Dim DBLawbase
Dim dsSerialNum
Dim dsAddOfficeLink
SerialNum = Trim(Selection)
' Create connection object to connect to the database
Set DBLawbase = CreateObject("ADODB.Connection")
DBLawbase.connectionstring = "DSN=Lawbase;uid=sa;pwd=sa;"
DBLawbase.Open
' Get last serial number so we can add one to it
Set dsSerialNum = CreateObject("adodb.Recordset")
nextSerial = "select max(serial) + 1 as newserial from office_link"
dsSerialNum.Open nextSerial, DBLawbase, 3, 3
' Insert all values into the officelink table for the serial in question
Set dsAddOfficeLink = CreateObject("ADODB.RecordSet")
SQL = "insert into office_link values (" & dsSerialNum.Fields("newserial") & ", " & SerialNum & ", 0, 0, '" & DocPathStr & "/" & DocNameStr & "', '" & DocNameStr & "', getdate(), 'AUTO', 'Word')"
dsAddOfficeLink.Open SQL, DBLawbase, 3, 3
' Kill serial number off of document
Selection.Delete
' Resave after cleaning
ActiveDocument.Save
' Cleanup
dsSerialNum.Close
Set dsSerialNum = Nothing
'dsAddOfficeLink.Close
Set dsAddOfficeLink = Nothing
DBLawbase.Close
Set DBLawbase = Nothing
End
End Sub
Our frim uses Lawbase as a frontend w/ a SQL Server backend. Since there is very little custom coding for Lawbase, I wrote this to simplify the ever-enthralling task of choosing the correct directory to save the document in and linking the document to the matter in our database. We use a directory with subdirectories of the alphabet. For example, documents involving John Doe would go in:
//SERVER/SomePath/D/...
I think it is eaisier to use DOS names instead of long file names.
First thing anyone wanting to use this code needs to do is insert two bookmarks into their document. The first is called DocumentName, and the second DocuSerial. Here is the format I use (you will want to use your own naming conventions):
DocumentName - [Bookmark]«lb_link_header_client_lname», «lb_link_header_client_fname», «lb_template», «TODAY:3 June 1990»[Bookmark]
DocuSerial - [Bookmark] «lb_header_serial» [Bookmark]
NOTE: «lb_header_serial» in DocuSerial must be padded with spaces on either side if it is not long enough to be a Bookmark.
I just make the text white so that it will not be visible in the document and will not confuse anyone.
Contributor: Joel Musheno