OOoBasic crash course: Multi-format document backup

164

Author: Dmitri Popov

In previous OOoBasic crash course articles we’ve created a few simple macros. If you’re ready for more advanced stuff, let’s create a macro that allows you to save the currently opened document in several formats. This macro can come in handy for archiving purposes and for exchanging files with other users.

For example, if you are not sure whether your peers are able to read .odt files, you can export and send them a document in plain text, Rich Text Format, or Word formats. Archiving documents in different formats also allows you to ensure that you can open and read them later on even if you don’t have OpenOffice.org installed on your machine.

The multi-format macro starts by obtaining the directory and file name of the currently opened document, then creates backup copies of the document in specified formats (text, RTF, and Word 97) and saves them in a directory with the current date as its name. For example, if the current document is stored in the /home/user/docs directory, then the backup files will be saved in /home/user/docs/20061117.

As always, start with declaring variables:

  Sub CreateBackupArchive()
  Dim ThisDoc As Object
  Dim DocURL As String, DocDir As String, DocName As String, TarString As String
  Dim Args(0) As New com.sun.star.beans.PropertyValue

You need the last variable, Args(0), to specify the properties necessary to save the current file in other formats using the OpenOffice.org API.

The first thing the macro has to do is to obtain the path and file name of the currently opened document. The standard macro library in OpenOffice.org already contains a routine that can do this, so there is no reason to reinvent the wheel. To begin, call the Tools library:

  If (Not GlobalScope.BasicLibraries.isLibraryLoaded("Tools")) Then
  GlobalScope.BasicLibraries.LoadLibrary("Tools")
  End If

Next, make sure that the current document is saved, or, more precisely, that it has a location. Otherwise the macro won’t be able to obtain its path. The following code checks whether the current document has a location, and if it doesn’t, the macro exits.

  If ThisDoc.hasLocation=False Then
  MsgBox "You must save the document first!" :End
  End If

Now the macro can obtain the document’s path and file name.

  DocURL = ThisDoc.getURL()
  DocDir=DirectoryNameoutofPath(DocURL, GetPathSeparator())
  FileName=Left(Dir(DocURL, 0), Len(Dir(DocURL, 0))-4)

The ThisDoc.getURL() function returns the full path to the document as a URL. For example, if the Loremipsum.odt document is stored in /home/dmpop, the URL will look like this:

  file:///home/dmpop/Loremipsum.odt

To extract the path out of the URL, the macro uses the DirectoryNameoutofPath function, which is part of the Tools library. The GetPathSeparator() function returns a platform-specific path separator, which is “/” on Linux.

Extracting the file name is a bit more tricky, since you need a file name without the file extension. One way to obtain the file name is to use the Dir function. By default, this function returns the list of files in the specified directory. In this case, the path points not to the specific file, hence the Dir function returns the name of this particular file only: Loremipsum.odt. Now you need to remove the file extension, including the preceding dot. To do this, you can use the Left and Len string functions. The Len function returns the length of the specified string, while Left returns the specified number of the leftmost characters from the string. All you have to do now is to subtract the last four characters from the result returned by the Left function: Loremipsum.odt - 4 = Loremipsum.

Now the macro is ready to create a backup copy of the current document, but it must know what format to save the file in. You can specify the format using the Name and Value properties of the Args variable:

  Args(0).Name="FilterName"
  Args(0).Value="Text"

In this case, the macro uses the specified Text filter to save the document in the plain text format. If you want to save the document in the Rich Text Format, set Args(0).Value="Rich Text Format"; if you prefer to store backup copies in Word format, set Args(0).Value="MS Word 97".

The next important step is to specify the path and file name for the backup document:


BackupFilePath = ConvertToURL(DocDir & GetPathSeparator() & CDateToISO(Date()) & GetPathSeparator() & FileName & ".txt")

The CDateToISO() function returns the current date in the ISO format YYYYMMDD: 20061117. “Why not simply use the Date() function?”, you might ask. The problem is that it returns the current date using your system’s date and time settings. For example, my laptop uses the Danish date format, so Date() returns 17/11/2006, and if I use it in the macro, it will create three separate folders 17, 11, and 2006 instead of just one. CDateToISO helps to avoid this and other potential issues. You should also remember to assign an appropriate extension to the backup file. If you use the Text filter then the extension should be txt.

Finally, you can save the backup file using the following command:

  ThisDoc.StoreToURL(BackupFilePath, Args())

If you want to save backup in several formats in one go, simple copy-paste the relevant block of code and adjust the required parameters:


Args(0).Name="FilterName"
Args(0).Value="Rich Text Format"
BackupFilePath = ConvertToURL(DocDir & GetPathSeparator() & CDateToISO(Date()) & GetPathSeparator() & FileName & ".rtf")
ThisDoc.StoreToURL(BackupFilePath, Args())

Args(0).Name="FilterName"
Args(0).Value="MS Word 97"
BackupFilePath = ConvertToURL(DocDir & GetPathSeparator() & CDateToISO(Date()) & GetPathSeparator() & FileName & ".doc")
ThisDoc.StoreToURL(BackupFilePath, Args())

To add a final touch to the macro, you might want to archive and compress the backup directory. You can do this by sending the appropriate Shell command to the archiving utility of your choice. In the code below, the Shell calls the tar utility with the command specified in the TarString.


TarString=" -cjvf " & ConvertFromURL(DocDir) & GetPathSeparator() & CDateToISO(Date()) & ".tar.bz2 " & ConvertFromURL(DocDir) & GetPathSeparator() & CDateToISO(Date()
Shell("tar", 1, TarString)

In the example used throughout the article, the resulting string will be:

  -cjvf /home/dmpop/20061117.tar.bz2 /home/dmpop/20061117

You can, of course, use any other archiving utility, as long as it can run from the command line. On Windows, for example, you might want to opt for 7-Zip.

And here is the final macro in all its glory:


Sub CreateBackupArchive()
Dim ThisDoc As Object
Dim DocURL As String, DocDir As String, DocName As String, TarString As String
Dim Args(0) As New com.sun.star.beans.PropertyValue
ThisDoc=ThisComponent

If (Not GlobalScope.BasicLibraries.isLibraryLoaded("Tools")) Then
GlobalScope.BasicLibraries.LoadLibrary("Tools")
End If

If ThisDoc.hasLocation=False Then
MsgBox "You must save the document first!" :End
End If

DocURL = ThisDoc.getURL()
DocDir=DirectoryNameoutofPath(DocURL, GetPathSeparator())
FileName=Left(Dir(DocURL, 0), Len(Dir(DocURL, 0))-4)

Args(0).Name="FilterName"
Args(0).Value="Text"
BackupFilePath = ConvertToURL(DocDir & GetPathSeparator() & CDateToISO(Date()) & GetPathSeparator() & FileName & ".txt")

ThisDoc.StoreToURL(BackupFilePath, Args())
Args(0).Name="FilterName"
Args(0).Value="Rich Text Format"
BackupFilePath = ConvertToURL(DocDir & GetPathSeparator() & CDateToISO(Date()) & GetPathSeparator() & FileName & ".rtf")

ThisDoc.StoreToURL(BackupFilePath, Args())
Args(0).Name="FilterName"
Args(0).Value="MS Word 97"
BackupFilePath = ConvertToURL(DocDir & GetPathSeparator() & CDateToISO(Date()) & GetPathSeparator() & FileName & ".doc")
ThisDoc.StoreToURL(BackupFilePath, Args())

TarString=" -cjvf " & ConvertFromURL(DocDir) & GetPathSeparator() & CDateToISO(Date()) & ".tar.bz2 " & ConvertFromURL(DocDir) & GetPathSeparator() & CDateToISO(Date()
Shell("tar", 1, TarString)
End Sub

Dmitri Popov is a freelance writer whose articles have appeared in Russian, British, German, and Danish computer magazines.