| View previous topic :: View next topic |
| Author |
Message |
Zarius OOo Enthusiast


Joined: 21 Jan 2005 Posts: 142 Location: Brisbane, Australia
|
Posted: Tue Jul 25, 2006 7:51 pm Post subject: Word AutoCorrect import macro |
|
|
Thanks to patb for the original module, I've just tried to clean it up a bit and make it more general - it should work on any version from StarOffice 7 to OpenOffice 2.x (you will need to select the autocorr dat file appropriate to your version however, I haven't automated that yet - search for "edit me").
I've tried to get rid of all the dispatcher calls (excluding copy & paste, as I don't see a way around them), but haven't worked out how to remove the top two lines of the word autocorrect backup file without leaving a hanging paragraph break.
See original thread here for more details: AutoCorrect import macro?
| Code: |
global gWriterDoc as object
global gCalcDoc as object
global autoCorrDbDatFileWithPath as string
global autoCorrFileXmlWithPath as string
sub ImportACLfromWord
' ImportACLfromWord - 23/06/2006 by Pat B
' Modifications 25/06/2006 by Zarius (refactored & generalised)
' ** Back up your //.openoffice.org2/user/autocorr/acor_xx-xx.dat before you start.
' Use MS Word to back up your Word autocorrect list using the macro at
' http://word.mvps.org/FAQs/Customization/ExportAutocorrect.htm
' Then open that document in Writer, run this macro then restart OpenOffice.
' Tested on OOo 2.0.2 on Linux (Ubuntu 6.0.6) - locale en-AU
' Tested on StarOffice 7.0 on Linux (RHEL 4) - locale en-AU
' "Should" be general enough to work on any OS that OO works on.
' Before running, uncomment the appropriate version below and
' replace the locale (OO1.x: 1033, OO2.x: en-AU) with your locale.
' New: the macro should automatically detect the locale on OO2.x
' **********************************************************************
' ******************** EDIT ME *****************************************
' SO7/OO1.x
'locale = "1033" ' SO7, OO1.x - other locales have different numbers (eg 1031)
'autoCorrDbDatFile = "acor"+locale+".dat" ' this probably wont change
' OO2.x
'locale = "en-AU" ' en-AU = Australian English (change to your own locale)
locale = detectSetupSystemLocale() ' automatic detection - only for OO2.x
autoCorrDbDatFile = "acor_"+locale+".dat" ' this probably wont change
' ******************** END: EDIT ME ************************************
' **********************************************************************
' The macro selects the unformatted entries (ie RTF='False' elements) in MS
' Word's AutoCorrect Backup Document and transposes these to a text document
' called DocumentList.xml which is then zipped into
' //.openoffice.org2/user/autocorr/acor_en-AU.dat.
' It does not transpose formatted entries. I suggest you do this manually.
' Good luck! No Warranty!
dim oWriterDocFrame, oCalcDocFrame as object
dim dispatcher as object
dim vcursor, txtype as object
dim msg, seln as string
Dim CalcDoc As Object
Dim CalcUrl As String
Dim OpenDummy()
dim GoRLUD(1) as new com.sun.star.beans.PropertyValue
dim gotoCell(1) as new com.sun.star.beans.PropertyValue
dim TypeText(0) as new com.sun.star.beans.PropertyValue
autoCorrFileXml = "DocumentList.xml" ' this probably wont change
' setup the path and filenames for the AutoCorrect database and the xml file
oPaths = CreateUnoService( "com.sun.star.util.PathSettings" )
sofficeConfigPathUrl = oPaths.UserConfig
sofficeConfigPath = ConvertFromURL(sofficeConfigPathUrl) ' strip the file:/// from the front
autoCorrDbDatFileWithPath = sofficeConfigPathUrl + "/../autocorr/" + autoCorrDbDatFile
autoCorrFileXmlWithPath = sofficeConfigPathUrl + "/../autocorr/" + autoCorrFileXml
' setup the dispatcher (note: trying to phase out the dispatcher commands,
' though probably need it for the copy & paste at the least)
dispatcher = createUnoService("com.sun.star.frame.DispatchHelper")
' ---------------- writer section
' grab the current document
gWriterDoc = ThisComponent
oWriterDocFrame = gWriterDoc.CurrentController.Frame
' If the table is large, these steps can take minutes. Pls be patient.
' TODO: work out a way of doing this (deleting top two lines) using the
' API whilst not leaving one paragraph hanging at the top of the document.
' make sure we're right at the top of doc, need all three of these
dispatcher.executeDispatch(oWriterDocFrame, ".uno:GoToStartOfDoc", "", 0, Array())
dispatcher.executeDispatch(oWriterDocFrame, ".uno:GoToStartOfDoc", "", 0, Array())
dispatcher.executeDispatch(oWriterDocFrame, ".uno:GoToStartOfDoc", "", 0, Array())
' del first two lines then go to top again
GoRLUD(0).Name = "Count"
GoRLUD(0).Value = 1
GoRLUD(1).Name = "Select"
GoRLUD(1).Value = true
dispatcher.executeDispatch(oWriterDocFrame, ".uno:GoDown", "", 0, GoRLUD())
dispatcher.executeDispatch(oWriterDocFrame, ".uno:Delete", "", 0, Array())
dispatcher.executeDispatch(oWriterDocFrame, ".uno:Delete", "", 0, Array())
dispatcher.executeDispatch(oWriterDocFrame, ".uno:GoToStartOfDoc", "", 0, Array())
dispatcher.executeDispatch(oWriterDocFrame, ".uno:GoToStartOfDoc", "", 0, Array())
dispatcher.executeDispatch(oWriterDocFrame, ".uno:GoToStartOfDoc", "", 0, Array())
' check you are now in a table and abort if not.
vCursor = ThisComponent.currentcontroller.getViewCursor()
textType = ThisComponent.Text.createEnumeration().NextElement
if ( not(textType.supportsService("com.sun.star.text.TextTable")) ) then
msg = "You don't seem to be in a table. " & _
chr(10) & "The open document should be the AutoCorrect Backup Document " & _
chr(10) & " created by MS Word" & _
chr(10) & "The macro may need tweaking." & _
chr(10) & "Aborting......"
msgbox ( msg, 0, "ERROR!")
exit sub
endif
' get the rows and columns of the table, so we can remove bits we don't need
oTables = gWriterDoc.getTextTables()
oTable = oTables.getByName("Table1")
oRows = oTable.getRows()
oColumns = oTable.getColumns()
' loop through all rows and remove those that have "True" in the third column
' (note: a for loop seems easier, but didn't work well due to a shrinking row count)
rowCount = oRows.Count
i = 0
while (i < rowCount)
cellName = "C"+trim(str(i+1))
cellLeftVal = oTable.getCellByName("A"+trim(str(i+1))).String
if(oTable.getCellByName(cellName).String = "True") then
oRows.removeByIndex(i, 1)
i = i-1
rowCount = rowCount - 1
endif
i = i+1
wend
' delete header row and third column (true/false column)
oRows.removeByIndex(0,1)
if (oColumns.Count > 2) then
oColumns.removeByIndex(2, 1)
endif
' replace special characters with their appropriate xml representations
searchArray = array(chr(38), chr(34), chr(60), chr(62), chr(39), "==>")
replaceArray = array("&", """, "<" , ">" , "'", "'==>")
searchAndReplaceArrays(gWriterDoc, searchArray(), replaceArray())
' back to the top again
dispatcher.executeDispatch(oWriterDocFrame, ".uno:GoToStartOfDoc", "", 0, Array())
dispatcher.executeDispatch(oWriterDocFrame, ".uno:GoToStartOfDoc", "", 0, Array())
dispatcher.executeDispatch(oWriterDocFrame, ".uno:GoToStartOfDoc", "", 0, Array())
'check you are still in a table and abort if not.
if ( not(textType.supportsService("com.sun.star.text.TextTable")) ) then
msg = "You don't seem to be in a table." & _
chr(10) & "The macro may need tweaking." & _
chr(10) & "Aborting macro......"
MsgBox ( msg, 0, "ERROR!")
exit sub
endif
' select the entire remaining table and copy it to clipboard
dispatcher.executeDispatch(oWriterDocFrame, ".uno:SelectTable", "", 0, Array())
dispatcher.executeDispatch(oWriterDocFrame, ".uno:Copy", "", 0, Array())
' close the writer document as we no longer need it
' (commenting this out while testing can make life easier)
gWriterDoc.close(true)
' ---------------- spreadsheet section
' open a blank spreadsheet to assemble our new xml file into
gCalcDoc = StarDesktop.loadComponentFromURL( "private:factory/scalc", "_blank", 0, Array() )
calcDocFrame = gCalcDoc.CurrentController.Frame
' Fill first 2 lines with the xml header text
currentSheet = gCalcDoc.getCurrentController().getActiveSheet()
oRange = currentSheet.getCellRangeByName("A1")
oRange.setString("<?xml version=""1.0"" encoding=""UTF-8""?>")
oRange = currentSheet.getCellRangeByName("A2")
oRange.setString("<block-list:block-list xmlns:block-list=""http://openoffice.org/2001/block-list"">")
' If the table is large, these steps can also take minutes. Pls be patient.
' Fill columns B & D by pasting the two table cols & inserting a col between them
oRange = currentSheet.getCellRangeByName("B3")
gCalcDoc.getcurrentcontroller().Select(oRange)
dispatcher.executeDispatch(calcDocFrame, ".uno:Paste", "", 0, Array())
oColumns = currentSheet.Columns
oColumns.insertByIndex(2, 1)
' Fill columns A, C & E
fillColumn("A", 3, " <block-list:block block-list:abbreviated-name=""")
fillColumn("C", 3, """ block-list:name=""")
fillColumn("E", 3, """/>")
saveCalcFile() ' We now have the Word replacement list saved as DocumentListPart1
calcDocFrame.close(true) ' Clean up by closing the spreadsheet
joinAcLists() ' Append the new list to the top of the current list
msgbox "Successfully merged the word ac list with OpenOffice. You will need to restart OpenOffice to see the changes.", 0, "Success."
end sub
sub saveCalcFile()
dim SaveFileAs(3) as new com.sun.star.beans.PropertyValue
oPaths = CreateUnoService( "com.sun.star.util.PathSettings" )
sofficeConfigPath = oPaths.UserConfig
'Save As Text
sFileUrl = sofficeConfigPath + "/../autocorr/DocumentListPart1"
oArgs = Array(_
MakePropertyValue( "FilterName", "Text - txt - csv (StarCalc)" ),_
MakePropertyValue( "FilterOptions", "0,0,76,0" ),_
)
gCalcDoc.storeToURL( sFileUrl, oArgs() )
end sub
sub joinAcLists()
'We are constructing a new DocumentList.xml with Word's replacement list at top. Then ALL of
' Writer's existing replacement list entries underneath. Otherwise we lose Writer's formatted
' autocorrect entries. So we have a lot of duplicates which Writer will automatically remove
' at the next change to its replacement table. Second duplicate is the one discarded, hence we
' put the Word list at the top.
oPaths = CreateUnoService( "com.sun.star.util.PathSettings" )
sofficeConfigPathUrl = oPaths.UserConfig
oUcb = createUnoService("com.sun.star.ucb.SimpleFileAccess")
if (not(oUcb.Exists(autoCorrDbDatFileWithPath))) then
msgbox "Error: autocomplete file ("+autoCorrDbDatFileWithPath+") is missing."
end ' stop program completely
endif
if (oUcb.getSize(autoCorrDbDatFileWithPath) = 0) then
msgbox "Error: autocomplete file is empty, this macro doesn't handle that yet."
end ' stop program completely
endif
' unzip the document.xml out of the auto correct db file
unzipAutoCorrDB()
' open both the new word AC list and our OO AC list (DocumentList.xml)
wordACListDocument = sofficeConfigPathUrl + "/../autocorr/DocumentListPart1"
oWordAcWriterDoc = StarDesktop.loadComponentFromURL( wordACListDocument, "_blank", 0, Array() )
oOoAcWriterDoc = StarDesktop.loadComponentFromURL( autoCorrFileXmlWithPath, "_blank", 0, Array() )
' search and replace a few times to cut the xml header away (since it's in the new file)
oRD = oOoAcWriterDoc.createReplaceDescriptor()
oRD.searchRegularExpression = false
oRD.SearchString = "<?xml version=""1.0"" encoding=""UTF-8""?>"
oRD.ReplaceString = ""
oOoAcWriterDoc.ReplaceAll(oRD)
oRD.SearchString = "<block-list:block-list xmlns:block-list=""http://openoffice.org/2001/block-list"">"
oOoAcWriterDoc.ReplaceAll(oRD)
' get rid of the blank paragraph remaining at the top
oRD.searchRegularExpression = true
oRD.SearchString = "^$"
oOoAcWriterDoc.ReplaceAll(oRD)
' copy the contents of the Word AC list and paste into the OO AC list
oWriterDocFrame = oWordAcWriterDoc.getCurrentController().getFrame()
dispatcher = createUnoService("com.sun.star.frame.DispatchHelper")
dispatcher.executeDispatch(oWriterDocFrame, ".uno:SelectAll", "", 0, Array())
dispatcher.executeDispatch(oWriterDocFrame, ".uno:Copy", "", 0, Array())
oWriterDocFrame = oOoAcWriterDoc.getCurrentController().getFrame()
dispatcher.executeDispatch(oWriterDocFrame, ".uno:Paste", "", 0, Array())
' save the OO AC list and close the documents
oOoAcWriterDoc.Store()
oWordAcWriterDoc.close(true)
oOoAcWriterDoc.close(true)
' remove the word ac list
kill wordACListDocument
' zip the OO AC list (document.xml) back into the auto correct db dat file
zipAutoCorrDB()
end sub
' This function will search through the document and replace anything in the
' document that matches entries in the searchArray with the relevant
' entry in the replaceArray.
function searchAndReplaceArrays(oDocument, searchArray, replaceArray)
dim oReplace as object
oReplace = ThisComponent.createReplaceDescriptor()
oReplace.SearchCaseSensitive = True
For i = LBound(searchArray()) To UBound(searchArray())
oReplace.SearchString = searchArray(i)
oReplace.ReplaceString = replaceArray(i)
ThisComponent.ReplaceAll(oReplace)
Next i
end function
' simple function to make this procedure look a little neater
function setStruct(struct, strName, value)
struct.Name = strName
struct.Value = value
end function
' Given a top cell location of a given column it will fill from the given row
' to the last used row with the value in cellString.
function fillColumn(topCol, topRow, cellString)
' assemble our cell references
topCell = topCol & trim(str(topRow))
lastRow = getLastUsedRow(gCalcDoc.getCurrentController.getActiveSheet())
bottomCell = topCol & trim(str(lastRow+1)) ' +1 is needed
rangeName = topCell + ":" + bottomCell
' grab the dataArray from the required range and fill with the val in cellString
oSheet = gCalcDoc.getCurrentController().getActiveSheet()
oRange = oSheet.getCellRangeByName(rangeName)
dataArray = oRange.getDataArray()
For i = LBound(dataArray) To UBound(dataArray)
aRow = dataArray(i)
For j = LBound(aRow) to UBound(aRow)
aRow(j) = cellString
Next j
dataArray(i) = aRow
Next i
' write the data array back to the spreadsheet
oRange.setDataArray( dataArray() )
end function
' simply return the value of the last row with data in it in the given sheet
function getLastUsedRow(oSheet as Object) as Integer
Dim oCell As Object
Dim oCursor As Object
Dim aAddress As Variant
oCell = oSheet.GetCellbyPosition( 0, 0 )
oCursor = oSheet.createCursorByRange(oCell)
oCursor.GotoEndOfUsedArea(True)
aAddress = oCursor.RangeAddress
GetLastUsedRow = aAddress.EndRow
end function
' thanks to al_andreas for the original zip and unzip autocorrdb functions
sub zipAutoCorrDB()
dim zipService as variant
dim filestreamService as variant
dim inputStream as variant
dim theZipper as variant
dim outputStream as variant
Dim args1(0)
args1(0) = autoCorrDbDatFileWithPath
filestreamService = createUnoService("com.sun.star.ucb.SimpleFileAccess")
inputStream = FilestreamService.OpenFileRead(autoCorrFileXmlWithPath)
zipService = createUnoService("com.sun.star.packages.Package")
zipService.initialize(args1())
theZipper=zipService.createInstance()
theZipper.SetInputStream(inputStream)
autoCorrFileXml = FileNameoutofPath(autoCorrFileXmlWithPath)
outputStream=zipService.getByHierarchicalName("")
outputStream.replaceByName(autoCorrFileXml, theZipper)
zipService.commitChanges()
kill autoCorrFileXmlWithPath
end sub
' thanks to al_andreas for the original zip and unzip autocorrdb functions
sub unzipAutoCorrDB()
dim zipService as variant
dim filestreamService as variant
dim inputStream as variant
dim theZipper as variant
dim outputStream as variant
dim autoCorrFileXml as string
dim args1(0)
args1(0) = autoCorrDbDatFileWithPath
zipService = createUnoService("com.sun.star.packages.Package")
zipService.initialize(args1())
autoCorrFileXml = FileNameoutofPath(autoCorrFileXmlWithPath)
theZipper = ZipService.getByHierarchicalName(autoCorrFileXml)
inputStream = TheZipper.getInputStream()
outputStream = createUnoService("com.sun.star.ucb.SimpleFileAccess")
outputStream.WriteFile(autoCorrFileXmlWithPath, inputStream)
End Sub
' Simple function to grab the string description of the currently set locale
function detectSetupSystemLocale() as string
Dim currentLocale as string
Dim oSettings, oConfigProvider
Dim oParams(0) As new com.sun.star.beans.PropertyValue
oConfigProvider = createUnoService( "com.sun.star.configuration.ConfigurationProvider" )
oParams(0).Name = "nodepath"
oParams(0).Value = "/org.openoffice.Setup/L10N"
oSettings = oConfigProvider.createInstanceWithArguments("com.sun.star.configuration.ConfigurationAccess", oParams() )
currentLocale= oSettings.getbyname("ooSetupSystemLocale")
detectSetupSystemLocale() = currentLocale
end function
|
_________________ Zarius Tularial. (WinXP - OOo 1.1.4, FedoraCore 4 - OOo 2.0, RHEL4 - StarOffice 7)
Quoots - a quicker way to open your documents and fill in template details in OOo. (written in OOBasic) |
|
| Back to top |
|
 |
raywood Newbie

Joined: 30 Jun 2007 Posts: 4
|
Posted: Sat Jun 30, 2007 4:40 pm Post subject: Needed: A More General Solution to Import AutoCorrect Lists |
|
|
I use Word. I have about 7,400 autocorrect entries. This doesn't (yet) run afoul of the 10,000-entry limit in OOo Writer. But as you can imagine, I won't be typing those entries into Writer manually.
I may eventually have time to figure out how to use the macro shown here. It looks like its author put in a lot of work, and my sense is that it will take the knowledgeable user a long way towards easing his/her transition from Word. Unfortunately, I am not a knowledgeable user.
I'm not new to scripts and such. I took my first (and only) programming course in 1979 (BASIC), and I worked a lot with scripts in the following 10-15 years. Nowadays, though, I'm sorry to report that I am a bit short on time, not to mention technically rusty. As a practical matter, I don't and won't know how to adapt the proffered macro to my situation.
For me, and probably for some others, the absence of an easy way to import the Word AutoCorrect list is a deal-breaker. I just do too much writing to try to get by without the full list.
What's the chance that someone could devise a better solution? The Word macro produces a table of entries (e.g., "teh") and their replacements (e.g., "the"). Can Writer (or a Writer macro) be adapted to import that table more straightforwardly? |
|
| Back to top |
|
 |
bobloblian Newbie

Joined: 17 Nov 2007 Posts: 1
|
Posted: Sat Nov 17, 2007 10:04 pm Post subject: |
|
|
A note for those that come across this thread that have as little experience with macros as I had two days ago, which was none. My charge was to migrate xp/msoffice to vista/openoffice. In order for all of this to work for me, I had to correct a few syntax problems first. They were almost all related to spaces where there shouldn't have been any. As I remember, the offending spaces were highlighted, deleting them carried on.
I got several errors about undefined functions. I am not sure what the correct way to fix that kind of problem is, but I worked around it by searching for the code relating to the functions and inserting them into this macro. If the line throwing the error has a StringWithCapsFollowedBy(), then search google for "function StringWithCapsFollowedBy". Most of them I found in macro organizer under openoffice.org macros=>tools=>strings. Just copied the function from there and pasted to the end of this macro.
For the big finale, the joinAC part kept giving me all sorts of grief about unsupported URL type. My final solution was to comment everything except the if-exists parts at the top, and the rezip part at the end, and renaming the documentlistpart1 file to documentlist.xml. no big deal for me since this was a fresh install and the original documentlist.xml was empty.
In the end, success was mine, and it tasted sweet.
Hope these couple of tidbits saves somebody a few of the hours it took me. And many many thanks to patb and zarius for providing this, much appreciated. Three cheers for each of you  |
|
| Back to top |
|
 |
Tommy27 OOo Advocate


Joined: 18 Nov 2006 Posts: 300
|
Posted: Sun Mar 02, 2008 1:16 am Post subject: Re: Needed: A More General Solution to Import AutoCorrect L |
|
|
| raywood wrote: | | This doesn't (yet) run afoul of the 10,000-entry limit in OOo Writer. |
is that true? you cannot have more than 10,000 autocorrect entries to OOo?
do you have references about it?
UPDATE
the 10'000 limit doesn't exist.
i have more than 60'000 autocorrect entries in my OOo.
thanks to Bikku Pesala who counted for me.
http://user.services.openoffice.org/en/forum/viewtopic.php?f=7&t=3156&p=14960#p14960 |
|
| Back to top |
|
 |
raywood Newbie

Joined: 30 Jun 2007 Posts: 4
|
|
| Back to top |
|
 |
Tommy27 OOo Advocate


Joined: 18 Nov 2006 Posts: 300
|
Posted: Mon Jun 23, 2008 9:30 pm Post subject: |
|
|
actually the autocorrect entries limit seems to be 65214
if you reach that number the autocor.dat file crashes and all the entris previously stored are deleted. (tested on OOo 2.4.0)
i had a backup copy so i didn't loose my data.
i opened an issue here:
http://www.openoffice.org/issues/show_bug.cgi?id=87672
a workaoround to prevent the 65214 crash is described there in more detail. |
|
| Back to top |
|
 |
rmdemi Newbie

Joined: 28 Jul 2004 Posts: 4 Location: turkey
|
Posted: Tue Jul 01, 2008 1:55 am Post subject: |
|
|
Hello,
Thanks to Patb and Zarius for creating and modifications this module. I modified the macro module.
I put Modified code and application document (autocorr.odt) new forum site adress is;
http://user.services.openoffice.org/en/forum/viewtopic.php?f=21&t=7368
Code modifications is;
* Calc section, cut, copy, paste sections canceled. No more file operations.
* Now detectlocale function converts two byte locale strings to five bytes correct forms. Such as fr, tr to fr-FR, tr-TR
* File picker dialog added for selection backup word file
* If user hasn't acor_xx-xx.dat in user path macro copies it from OOo share path.
* İf writer has same autocorrect entries like word These entries doesn't insert to writer. So we prevent duplicate entries in writer auto correct list.
Now code is fully automatic like word macro.
Sincerely,  |
|
| Back to top |
|
 |
Tommy27 OOo Advocate


Joined: 18 Nov 2006 Posts: 300
|
Posted: Fri Mar 18, 2011 10:54 pm Post subject: |
|
|
does anybody knows if it's possible to do the opposite...
i mean, can you export OOo autocorrect into MS Word? |
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|