For example, if the current document is MyTest.odt, each time you run the macro a copy will be saved in the folder C:\BackupDocs (change the default folder name in the code, around line 57) with the name MyTest_2009-10-10_172536.odt.
In order to use this code, copy it under MyMacros / Standard library, and it is easier to create a new button in the toolbar and associate it with the macro AutomaticBackup (you unfortunately have to do this button allocation in each editor: Calc, Draw, Impress and Writer). After that, simply press this button from time to time (I recommend every 30 minutes) and you will never lose much of your work anymore!
(For advanced users, this macro can make several copies of the document, in different formats. For example, you can save a Writer document in the format .odt, .doc, .swx, etc. Look into the code how add multiple versions.)
In case of improvement or bug fixing, I will always update the code in this first post. Thanks in advance for your comments!
Code: Select all
Option Explicit
Sub AutomaticBackup
'------------------------------------------------------------------------
' This macro saves the document plus a copy, in a backup folder.
' It adds to the document a TimeStamp, so the filename will be:
' "mydocument_YYYYMMDD_HHMMSS.xxx"
' where YYYY represents the current year, MM the month, DD the day,
' HHMMSS the time in hours, minutes and seconds
'
'------------------------------------------------------------------------
' History
'------------------------------------------------------------------------
' v 1.3 2009-10-10 Now works with Windows XP and Linux (Ubuntu)
' file path format containing "/" or "\"
'
' v 1.2 2007-04-16 Add several new filters and make the selection
' of which filters to use for backup
' relatively easy for the User. Allow save of
' the document in case it is not yet saved.
'
' v 1.1.1 2007-04-12 Improve the handling of the path, with possibility
' of relative path (from current file path) or
' even empty path (same folder as current file).
'
' v 1.1.0 2007-04-10 Work with the four main document types of OOo
' (Writer, Calc, Impress and Draw).
'------------------------------------------------------------------------
Dim oDoc as Object
Dim oDocNew as Object
Dim sDocURL as String
Dim sDocNameWithFullPath as String
Dim sNewURL as String
Dim sPathBackupFolder as String
Dim sSaveToURL as String
Dim sTimeStamp as String
Dim sDocName as String
Dim i as Long
Dim j as Long
Dim k as Long
Dim sDocType as String
Dim oDispatcher as Object
Dim sBackup(200) as String
Dim sSlash as String
Dim sOtherSlash as String
Dim s as String
' Change the line below to adapt the path of the
' backup folder. It can be:
' * A full path (ex. "C:\My Documents\BackupFolder")
' * A relative path starting with a \ (ex. "\Backup")
' * Empty
sPathBackupFolder = "C:\BackupDocs"
' This is the array that defines which extensions to use for
' backup purposes, based on the type of document
' Simply add the word "BACKUP" (without quotes) between the first
' two vertical bars and the program will behave accordingly
' Each string contains five parameters which are:
' - Module in OOo
' - The word BACKUP or an empty string
' - A free text describing the format
' - The extension of the file
' - The name of the filter that will write the file in the proper format
i = 0
' I strongly recommend that you keep these four lines as they are
' which means that the backup copy will retain all the formatting
' created in OOo as they are done using native OOo file types
i = i + 1 : sBackup(i) = "Calc|BACKUP|Open Document Spreadsheet|ods|Calc8"
i = i + 1 : sBackup(i) = "Draw|BACKUP|Open Document Drawing|odd|Draw8"
i = i + 1 : sBackup(i) = "Impress|BACKUP|Open Document Presentation|odp|Impress8"
i = i + 1 : sBackup(i) = "Writer|BACKUP|Open Document Text|odt|Writer8"
' If you would like supplemental backups, feel free to add
' the word BACKUP between the first two vertical bars. Note that if
' you select several file types with the same extension, only the
' backup file with the last filter will be actually saved
' Only change the lines below if you often need to save your documents
' in non-native OOo formats
i = i + 1 : sBackup(i) = "Calc||OpenOffice.org 1.0 Spreadsheet Template|stc|calc_StarOffice_XML_Calc_Template"
i = i + 1 : sBackup(i) = "Calc||OpenOffice.org 1.0 Spreadsheet|sxc|StarOffice XML (Calc)"
i = i + 1 : sBackup(i) = "Calc||Data Interchange Format|dif|DIF"
i = i + 1 : sBackup(i) = "Calc||Microsoft Excel 97/2000/XP Template|xlt|MS Excel 97 Vorlage/Template"
i = i + 1 : sBackup(i) = "Calc||HTML Document (OpenOffice.org Calc)|html|HTML (StarCalc)"
i = i + 1 : sBackup(i) = "Calc||Microsoft Excel 5.0|xls|MS Excel 5.0/95"
i = i + 1 : sBackup(i) = "Calc||Microsoft Excel 95|xls|MS Excel 95"
i = i + 1 : sBackup(i) = "Calc||StarCalc 4.0|sdc|StarCalc 4.0"
i = i + 1 : sBackup(i) = "Calc||Microsoft Excel 97/2000/XP|xls|MS Excel 97"
i = i + 1 : sBackup(i) = "Calc||OpenDocument Spreadsheet Template|ots|calc8_template"
i = i + 1 : sBackup(i) = "Calc||Text CSV|csv|Text - txt - csv (StarCalc)"
i = i + 1 : sBackup(i) = "Calc||StarCalc 3.0 Template|vor|StarCalc 3.0 Vorlage/Template"
i = i + 1 : sBackup(i) = "Calc||StarCalc 4.0 Template|vor|StarCalc 4.0 Vorlage/Template"
i = i + 1 : sBackup(i) = "Calc||StarCalc 5.0 Template|vor|StarCalc 5.0 Vorlage/Template"
i = i + 1 : sBackup(i) = "Calc||Pocket Excel|pxl|Pocket Excel"
i = i + 1 : sBackup(i) = "Calc||Microsoft Excel 95 Template|xlt|MS Excel 95 Vorlage/Template"
i = i + 1 : sBackup(i) = "Calc||dBase|dbf|dBase"
i = i + 1 : sBackup(i) = "Calc||Microsoft Excel 2003 XML|xml|MS Excel 2003 XML"
i = i + 1 : sBackup(i) = "Calc||XHTML|xml|XHTML Calc File"
i = i + 1 : sBackup(i) = "Calc||Microsoft Excel 5.0 Template|xlt|MS Excel 5.0/95 Vorlage/Template"
i = i + 1 : sBackup(i) = "Calc||StarCalc 3.0|sdc|StarCalc 3.0"
i = i + 1 : sBackup(i) = "Calc||StarCalc 5.0|sdc|StarCalc 5.0"
i = i + 1 : sBackup(i) = "Calc||PDF - Portable Document Format|pdf|calc_pdf_Export"
i = i + 1 : sBackup(i) = "Calc||SYLK|slk|SYLK"
i = i + 1 : sBackup(i) = "Draw||PNG - Portable Network Graphic|png|draw_png_Export"
i = i + 1 : sBackup(i) = "Draw||JPEG - Joint Photographic Experts Group|jpg|draw_jpg_Export"
i = i + 1 : sBackup(i) = "Draw||PPM - Portable Pixelmap|ppm|draw_ppm_Export"
i = i + 1 : sBackup(i) = "Draw||WMF - Windows Metafile|wmf|draw_wmf_Export"
i = i + 1 : sBackup(i) = "Draw||PGM - Portable Graymap|pgm|draw_pgm_Export"
i = i + 1 : sBackup(i) = "Draw||TIFF - Tagged Image File Format|tiff|draw_tif_Export"
i = i + 1 : sBackup(i) = "Draw||PBM - Portable Bitmap|pbm|draw_pbm_Export"
i = i + 1 : sBackup(i) = "Draw||EMF - Enhanced Metafile|emf|draw_emf_Export"
i = i + 1 : sBackup(i) = "Draw||XPM - X PixMap|xpm|draw_xpm_Export"
i = i + 1 : sBackup(i) = "Draw||OpenDocument Drawing Template|otg|draw8_template"
i = i + 1 : sBackup(i) = "Draw||BMP - Windows Bitmap|bmp|draw_bmp_Export"
i = i + 1 : sBackup(i) = "Draw||Macromedia Flash (SWF)|swf|draw_flash_Export"
i = i + 1 : sBackup(i) = "Draw||OpenOffice.org 1.0 Drawing|sxd|StarOffice XML (Draw)"
i = i + 1 : sBackup(i) = "Draw||PDF - Portable Document Format|pdf|draw_pdf_Export"
i = i + 1 : sBackup(i) = "Draw||GIF - Graphics Interchange Format|gif|draw_gif_Export"
i = i + 1 : sBackup(i) = "Draw||RAS - Sun Raster Image|ras|draw_ras_Export"
i = i + 1 : sBackup(i) = "Draw||StarDraw 3.0 Template|vor|StarDraw 3.0 Vorlage"
i = i + 1 : sBackup(i) = "Draw||StarDraw 5.0 Template|vor|StarDraw 5.0 Vorlage"
i = i + 1 : sBackup(i) = "Draw||HTML Document (OpenOffice.org Draw)|html|draw_html_Export"
i = i + 1 : sBackup(i) = "Draw||StarDraw 3.0|sxd|StarDraw 3.0"
i = i + 1 : sBackup(i) = "Draw||MET - OS/2 Metafile|met|draw_met_Export"
i = i + 1 : sBackup(i) = "Draw||StarDraw 5.0|sxd|StarDraw 5.0"
i = i + 1 : sBackup(i) = "Draw||XHTML|xml|XHTML Draw File"
i = i + 1 : sBackup(i) = "Draw||EPS - Encapsulated PostScript|eps|draw_eps_Export"
i = i + 1 : sBackup(i) = "Draw||SVG - Scalable Vector Graphics|svg|draw_svg_Export"
i = i + 1 : sBackup(i) = "Draw||OpenOffice.org 1.0 Drawing Template|std|draw_StarOffice_XML_Draw_Template"
i = i + 1 : sBackup(i) = "Draw||SVM - StarView Metafile|svm|draw_svm_Export"
i = i + 1 : sBackup(i) = "Impress||StarDraw 3.0 Template (OpenOffice.org Impress)|vor|StarDraw 3.0 Vorlage (StarImpress)"
i = i + 1 : sBackup(i) = "Impress||StarDraw 5.0 Template (OpenOffice.org Impress)|vor|StarDraw 5.0 Vorlage (StarImpress)"
i = i + 1 : sBackup(i) = "Impress||Microsoft PowerPoint 97/2000/XP Template|pot|MS PowerPoint 97 Vorlage"
i = i + 1 : sBackup(i) = "Impress||OpenOffice.org 1.0 Presentation Template|sti|impress_StarOffice_XML_Impress_Template"
i = i + 1 : sBackup(i) = "Impress||StarImpress 5.0|sdd|StarImpress 5.0"
i = i + 1 : sBackup(i) = "Impress||StarDraw 5.0 (OpenOffice.org Impress)|sda|StarDraw 5.0 (StarImpress)"
i = i + 1 : sBackup(i) = "Impress||BMP - Windows Bitmap|bmp|impress_bmp_Export"
i = i + 1 : sBackup(i) = "Impress||EMF - Enhanced Metafile|emf|impress_emf_Export"
i = i + 1 : sBackup(i) = "Impress||EPS - Encapsulated PostScript|eps|impress_eps_Export"
i = i + 1 : sBackup(i) = "Impress||GIF - Graphics Interchange Format|gif|impress_gif_Export"
i = i + 1 : sBackup(i) = "Impress||JPEG - Joint Photographic Experts Group|jpg|impress_jpg_Export"
i = i + 1 : sBackup(i) = "Impress||MET - OS/2 Metafile|met|impress_met_Export"
i = i + 1 : sBackup(i) = "Impress||PBM - Portable Bitmap|pbm|impress_pbm_Export"
i = i + 1 : sBackup(i) = "Impress||PCT - Mac Pict|pct|impress_pct_Export"
i = i + 1 : sBackup(i) = "Impress||PDF - Portable Document Format|pdf|impress_pdf_Export"
i = i + 1 : sBackup(i) = "Impress||PGM - Portable Graymap|pgm|impress_pgm_Export"
i = i + 1 : sBackup(i) = "Impress||PNG - Portable Network Graphic|png|impress_png_Export"
i = i + 1 : sBackup(i) = "Impress||PPM - Portable Pixelmap|ppm|impress_ppm_Export"
i = i + 1 : sBackup(i) = "Impress||RAS - Sun Raster Image|ras|impress_ras_Export"
i = i + 1 : sBackup(i) = "Impress||SVG - Scalable Vector Graphics|svg|impress_svg_Export"
i = i + 1 : sBackup(i) = "Impress||SVM - StarView Metafile|svm|impress_svm_Export"
i = i + 1 : sBackup(i) = "Impress||TIFF - Tagged Image File Format|tiff|impress_tif_Export"
i = i + 1 : sBackup(i) = "Impress||WMF - Windows Metafile|wmf|impress_wmf_Export"
i = i + 1 : sBackup(i) = "Impress||XPM - X PixMap|xpm|impress_xpm_Export"
i = i + 1 : sBackup(i) = "Impress||PWP - PlaceWare|pwp|placeware_Export"
i = i + 1 : sBackup(i) = "Impress||OpenOffice.org 1.0 Drawing (OpenOffice.org Impress)|odg|OpenOffice.org 1.0 Drawing (OpenOffice.org Impress)"
i = i + 1 : sBackup(i) = "Impress||XHTML|xml|XHTML Impress File"
i = i + 1 : sBackup(i) = "Impress||Macromedia Flash (SWF)|swf|impress_flash_Export"
i = i + 1 : sBackup(i) = "Impress||Microsoft PowerPoint 97/2000/XP|ppt|MS PowerPoint 97"
i = i + 1 : sBackup(i) = "Impress||StarImpress 4.0|sdd|StarImpress 4.0"
i = i + 1 : sBackup(i) = "Impress||OpenDocument Presentation Template|stp|impress8_template"
i = i + 1 : sBackup(i) = "Impress||StarImpress 4.0 Template|vor|StarImpress 4.0 Vorlage"
i = i + 1 : sBackup(i) = "Impress||StarImpress 5.0 Template|vor|StarImpress 5.0 Vorlage"
i = i + 1 : sBackup(i) = "Impress||OpenOffice.org 1.0 Presentation|sxi|StarOffice XML (Impress)"
i = i + 1 : sBackup(i) = "Impress||StarDraw 3.0 (OpenOffice.org Impress)|sdd|StarDraw 3.0 (StarImpress)"
i = i + 1 : sBackup(i) = "Impress||HTML Document (OpenOffice.org Impress)|html|impress_html_Export"
i = i + 1 : sBackup(i) = "Writer||OpenOffice.org 1.0 Text Document|sxw|StarOffice XML (Writer)"
i = i + 1 : sBackup(i) = "Writer||StarWriter 4.0|sdw|StarWriter 4.0"
i = i + 1 : sBackup(i) = "Writer||HTML Document (OpenOffice.org Writer)|html|HTML (StarWriter)"
i = i + 1 : sBackup(i) = "Writer||StarWriter 3.0 Template|vor|StarWriter 3.0 Vorlage/Template"
i = i + 1 : sBackup(i) = "Writer||StarWriter 4.0 Template|vor|StarWriter 4.0 Vorlage/Template"
i = i + 1 : sBackup(i) = "Writer||StarWriter 5.0 Template|vor|StarWriter 5.0 Vorlage/Template"
i = i + 1 : sBackup(i) = "Writer||OpenOffice.org 1.0 Text Document Template|stw|writer_StarOffice_XML_Writer_Template"
i = i + 1 : sBackup(i) = "Writer||Microsoft Word 2003 XML|xml|MS Word 2003 XML"
i = i + 1 : sBackup(i) = "Writer||Pocket Word|psw|PocketWord File"
i = i + 1 : sBackup(i) = "Writer||Rich Text Format|rtf|Rich Text Format"
i = i + 1 : sBackup(i) = "Writer||PDF - Portable Document Format|pdf|writer_pdf_Export"
i = i + 1 : sBackup(i) = "Writer||StarWriter 3.0|sdw|StarWriter 3.0"
i = i + 1 : sBackup(i) = "Writer||OpenDocument Text Template|ott|writer8_template"
i = i + 1 : sBackup(i) = "Writer||AportisDoc (Palm)|pdb|AportisDoc Palm DB"
i = i + 1 : sBackup(i) = "Writer||BibTeX|bib|BibTeX_Writer"
i = i + 1 : sBackup(i) = "Writer||StarWriter 5.0|sdw|StarWriter 5.0"
i = i + 1 : sBackup(i) = "Writer||Microsoft Word 6.0|doc|MS WinWord 6.0"
i = i + 1 : sBackup(i) = "Writer||Text Encoded|txt|Text (encoded)"
i = i + 1 : sBackup(i) = "Writer||Microsoft Word 95|doc|MS Word 95"
i = i + 1 : sBackup(i) = "Writer||Microsoft Word 97/2000/XP|doc|MS Word 97"
i = i + 1 : sBackup(i) = "Writer||LaTeX 2e|ltx|LaTeX_Writer"
i = i + 1 : sBackup(i) = "Writer||XHTML|html|XHTML Writer File"
i = i + 1 : sBackup(i) = "Writer||Text|txt|Text"
i = i + 1 : sBackup(i) = "Writer||DocBook|xml|DocBook File"
' If this is a new document, we must save it first
' in order to later get its path and filter type
oDoc = ThisComponent
If Not(oDoc.hasLocation) Then
oDocNew = ThisComponent.CurrentController.Frame
oDispatcher = createUnoService("com.sun.star.frame.DispatchHelper")
oDispatcher.executeDispatch(oDocNew, ".uno:SaveAs", "", 0, array())
End If
' If the document still has no location, then we
' display an understandable error message
If Not(oDoc.hasLocation) Then
Msgbox "Your document has NOT been saved, and NO backup copy will be created. " & _
"May be you tried to save your document on a folder where you cannot write, " & _
"or you tried to override a file already in use. Please check and run again."
Exit Sub
End If
' Initialization of variables
' Retrieve the document name and path from the URL
' We also calculate the timestamp, so it will be
' identical for all the backup copies
sDocURL = oDoc.getLocation()
sDocNameWithFullPath = ConvertFromURL(sDocURL)
sTimeStamp = "_" & Format(Year(Now), "0000") & _
Format(Month(Now), "00") & _
Format(Day(Now), "00") & "_" & _
Format(Hour(Now), "00") & _
Format(Minute(Now), "00") & _
Format(Second(Now), "00")
' Determine whether the path should be written with
' "/" or "\" to indicate the hierarchy of folders
' (Modification of v1.3 to work with Windows and Ubuntu)
If Instr(1, sDocNameWithFullPath, "/") > 0 Then
sSlash = "/"
sOtherSlash = "\"
Else
sSlash = "\"
sOtherSlash= "/"
End If
sDocName = GetFileName(sDocNameWithFullPath, sSlash)
' If the Backup path contains the wrong delimiter,
' we replace it
s = ""
For i = 1 to Len(sPathBackupFolder)
If Mid(sPathBackupFolder, i, 1) = sOtherSlash Then
s = s & sSlash
Else
s = s & Mid(sPathBackupFolder, i, 1)
End If
Next i
sPathBackupFolder = s
' If the backupfolder variable is empty, or starts with a \ or /
' indicating a sub-folder, then we will use the
' current folder of the document and append the sub-folder
If sPathBackupFolder = "" or Left(sPathBackupFolder, 1) = sSlash Then
i = Len(sDocNameWithFullPath)
While Mid(sDocNameWithFullPath, i, 1) <> sSlash
i = i - 1
Wend
sPathBackupFolder = Left(sDocNameWithFullPath, i - 1) & sPathBackupFolder
End If
' Check if the backup folder exists, if not we create it
On Error Resume Next
MkDir sPathBackupFolder
On Error Goto 0
' Add a slash at the end of the path,
' if not already present
If Right(sPathBackupFolder, 1) <> sSlash Then
sPathBackupFolder = sPathBackupFolder & sSlash
End If
' Save the current document only if it has changed,
' is not new (has been saved before) and is not read only
If oDoc.isModified and oDoc.hasLocation and Not(oDoc.isReadOnly) Then
oDoc.store()
End If
' For each file filter, let's see whether we should
' create a backup copy or not
i = 1
While sBackup(i) <> ""
If GetString(sBackup(i), "|", 2) = "BACKUP" Then
sDocType = GetString(sBackup(i), "|", 1)
If (oDoc.supportsService("com.sun.star.text.TextDocument") And sDocType = "Writer") Or _
(oDoc.supportsService("com.sun.star.sheet.SpreadsheetDocument") And sDocType = "Calc") Or _
(oDoc.supportsService("com.sun.star.presentation.PresentationDocument") And sDocType = "Impress") Or _
(oDoc.supportsService("com.sun.star.drawing.DrawingDocument") And sDocType = "Draw") Then
sSaveToURL = ConvertToURL(sPathBackupFolder & sDocName & sTimeStamp & "." & GetString(sBackup(i), "|", 4))
oDoc.storeToUrl(sSaveToURL, Array(MakePropertyValue("FilterName", GetString(sBackup(i), "|", 5))))
End If
End If
i = i + 1
Wend
End Sub
Function MakePropertyValue(Optional sName As String, Optional sValue) As com.sun.star.beans.PropertyValue
'-------------------------------------------------------------------
' Create and return a new com.sun.star.beans.PropertyValue
'-------------------------------------------------------------------
Dim oPropertyValue As New com.sun.star.beans.PropertyValue
If Not IsMissing(sName) Then
oPropertyValue.Name = sName
EndIf
If Not IsMissing(sValue) Then
oPropertyValue.Value = sValue
EndIf
MakePropertyValue() = oPropertyValue
End Function
Function GetFileName(byVal sNameWithFullPath as String, byval sSlash as String) as String
'-------------------------------------------------------------------
' Return the name of the file without path nor extension from a string
' that contains the full name (including path) of a file
'-------------------------------------------------------------------
Dim i as Long
Dim j as Long
GetFileName = ""
' Let's search from the end of the full name
' a "." that will indicate the end of the
' file name and the beginning of the extension
For i = Len(sNameWithFullPath) To 1 Step -1
If Mid(sNameWithFullPath, i, 1) = "." Then
' We have found a ".", so now we continue
' backwards and search for the path delimiter "\" or "/"
For j = i - 1 to 1 Step -1
If Mid(sNameWithFullPath, j, 1) = sSlash Then
' We have found it, the file name is the
' piece of string between the two
GetFileName = Mid(sNameWithFullPath, j + 1, i - j - 1)
j = 0
i = 0
End If
Next j
End If
Next i
End Function
Function GetString(byVal sInput as String, byVal sDelimiter as String, ByVal iPosition as Long) as String
'-------------------------------------------------------------------
' This function returns a substring from sInput, located after
' the iPositionth of sDelimiter and the next occurence
' of sDelimiter or the end of the string, whatever occurs first
'-------------------------------------------------------------------
Dim i as Long
Dim j as Long
Dim k as Long
' Let's add a delimiter at the beginning and end of the string
' it makes the processing easier for the first and last portion
' of the string
sInput = sDelimiter & sInput & sDelimiter
' Find the nth delimiter
j = 0
For i = 1 to iPosition
j = InStr(j + 1, sInput, sDelimiter)
If j = 0 Then
GetString = ""
Exit Function
End If
Next i
' Find the delimiter n+1
If j = Len(sInput) Then
GetString = ""
Exit Function
End If
k = InStr(j + 1, sInput, sDelimiter)
' Return the portion of string between the two delimiters
If k = j + 1 Then
GetString = ""
Else
GetString = Trim(Mid(sInput, j + 1, k - j - 1))
End If
End Function
Function GetFilterType(byVal sFileName as String) as String
'-------------------------------------------------------------------
' This function returns the filter type of a file
' Credit: http://www.oooforum.org/forum/viewtopic.phtml?t=52047
'-------------------------------------------------------------------
Dim sURL as String
Dim oSFA as Object
Dim oInpStream as Object
Dim oTD as Object
Dim aProps(0) as new com.sun.star.beans.PropertyValue
sUrl = ConvertToUrl(sFileName)
oSFA = createUNOService ("com.sun.star.ucb.SimpleFileAccess")
oInpStream = oSFA.openFileRead(sUrl)
aProps(0).Name = "InputStream"
aProps(0).Value = oInpStream
oTD = createUnoService("com.sun.star.document.TypeDetection")
GetFilterType = oTD.queryTypeByDescriptor(aProps(), true)
oInpStream.closeInput()
End Function