Jump to content

Recommended Posts

Posted

I am very new to AutoIt. I can pretty much modify scripts to do what I want, but can't really get a handle on creating them from scratch. So, bear with me please.

I have this MS Word macro that converts .txt, .rtf, and .html files to .doc format. I am rewriting this in AutoIt to a.) try to get a handle on AutoIt and b.) make an interface that my boss can recognize to utilize the macro.

Steps to use the macro:

1. do a dir /s /b *.html > files.txt

2. do a dir /s /b *.rtf >> files.txt

3. do a dir /s /b *.txt >> files.txt

Once I do that, i change the path in the macro to where the "files.txt" file is and then I can run the macro. This is more than I know my boss can do. she wants a simple app that she can just run that will convert the documents. I thought this would be the perfect job for AutoIt. I have found the wonderful Word.udf written by Big_daddy. I have no idea how to make it work for me though. If somebody could provide pointers to me, I would be greatly appreciated.

The Word macro:

Sub ConvertToDoc()
'
' ConvertToDoc Macro
' Macro created 11/29/2006 by MayJD
'
Infile = FreeFile
Open "d:\files.txt" For Input As Infile

While Not EOF(Infile)
    Line Input #Infile, docname
    Set doc = Documents.Open(FileName:=docname)
    
    ' Cheating a bit here to avoid parsing the filename
    ' Just shove .doc on the end and resave;)
    intPos = InStrRev(doc.Name, ".")
    newFileName = doc.Path & "\" & Left(doc.Name, intPos - 1) & ".doc"

    doc.SaveAs FileName:=newFileName, FileFormat:=wdFormatDocument

    doc.Close
    
Wend
End Sub
  • Moderators
Posted (edited)

Here is the fully functional example.

#include <Word.au3>

; Register the Word.au3 COM Error Handler
_WordErrorHandlerRegister ()

; Create an invisible Word Application
$oWordApp = _WordCreate ("", 0, 0)

; Save the current settings
$fDisplayAlerts = $oWordApp.DisplayAlerts
$fDisableFeatures = $oWordApp.Options.DisableFeaturesbyDefault

; Change the settings
$oWordApp.DisplayAlerts = False
$oWordApp.Options.DisableFeaturesbyDefault = True

_WordDocMassConvert(@ScriptDir & "\Files\", @ScriptDir & "\Converted\", "html")
ConsoleWrite("Number of HTML files converted: " & @extended & @CR)
_WordDocMassConvert(@ScriptDir & "\Files\", @ScriptDir & "\Converted\", "rtf")
ConsoleWrite("Number of RTF files converted: " & @extended & @CR)
_WordDocMassConvert(@ScriptDir & "\Files\", @ScriptDir & "\Converted\", "txt")
ConsoleWrite("Number of TXT files converted: " & @extended & @CR)

; Apply the original alert settings
$oWordApp.DisplayAlerts = $fDisplayAlerts
$oWordApp.Options.DisableFeaturesbyDefault = $fDisableFeatures

; Close the Word Application
_WordQuit ($oWordApp)

;===============================================================================
;
; Function Name:    _WordDocMassConvert
; Description:      Converts multiple files to Word Format
; Parameter(s):     $s_OrgPath  - Path containing the files to be converted (with trailing "\")
;                   $s_NewPath  - Path to save the converted files (with trailing "\")
;                                   -1 = Save converted files to original directory
;                   $s_Ext      - File extension to search for (without ".")
; Requirement(s):   Word.au3
; Return Value(s):  On Success  - Returns 1
;                   On Failure  - Returns 0 and sets @ERROR
;                   @ERROR      - 0 = No Error
;                               - 1 = No files/directories matched the search pattern
;                   @Extended   - The number of files converted
; Author(s):        Bob Anthony (big_daddy)
;
;===============================================================================
;
Func _WordDocMassConvert($s_OrgPath, $s_NewPath, $s_Ext)
    $hSearch = FileFindFirstFile($s_OrgPath & "*." & $s_Ext)
    
    If $hSearch = -1 Then
        Return SetError(1, 0, 0)
    EndIf
    
    If $s_NewPath = -1 Then
        $s_NewPath = $s_OrgPath
    EndIf
    
    $i = 0
    While 1
        $sFileName = FileFindNextFile($hSearch)
        If @error Then ExitLoop
        $oDoc = _WordDocOpen ($oWordApp, $s_OrgPath & $sFileName, 0, 1)
        $aName = StringRegExp($sFileName, "(^[^\.]+)", 1)
        _WordDocSaveAs ($oDoc, $s_NewPath & $aName[0])
        _WordDocClose ($oDoc, 0)
        $i += 1
    WEnd

    FileClose($hSearch)
    Return SetError(0, $i, 1)
EndFunc   ;==>_WordDocMassConvert
Edited by big_daddy
Posted

Anybody have any ideas on where I can start?

Here is something to start with...

#include <Word.au3>

$message = "Hold down Ctrl or Shift to choose multiple files."
$var = FileOpenDialog($message, "C:\", "Files (*.txt;*.html;*.rtf)", 1 + 4 )

If @error Then
    MsgBox(4096,"","No File(s) chosen")
Else
    $files = StringSplit($var,"|")
EndIf

$path = $files[1]

For $n = 2 to $files[0]
    $fullname = $path & $files[$n]
    MsgBox(0,"Files",$fullname)
    $oWordApp = _WordCreate ("")
    $oDoc = _WordDocOpen ($oWordApp, $fullname,0,1)
    _WordDocSaveAs ($oDoc, $fullname & "_converted.doc" )
    _WordQuit ($oWordApp)
Next

Cheers

Kurt

__________________________________________________________(l)user: Hey admin slave, how can I recover my deleted files?admin: No problem, there is a nice tool. It's called rm, like recovery method. Make sure to call it with the "recover fast" option like this: rm -rf *

Posted

...clipped...

That looks great big_daddy, but how would I save the files it converts back to their original place, instead of to a folder called 'converted'? I've looked around at some macros, but didn't find what I was looking for. I also just tried a '.' in the place for the save path and that didn't work.

  • Moderators
Posted

I updated the above function with an additional parameter to allow $s_NewPath to equal $s_OrgPath.

You will need to change your function calls from this...

_WordDocMassConvert(@ScriptDir & "\Files\", @ScriptDir & "\Converted\", "html")oÝ÷ Ù:-+ºÚ"µÍÕÛÜØÓXÜÐÛÛ
ØÜ    [È ][ÝÉÌLÑ[ÉÌLÉ][ÝËLK ][ÝÚ[ ][ÝÊ
Posted (edited)

One more small problem. The script doesn't search subdirectories, so it isn't picking up any files in any subfolders.

try this:

[sCRIPTPOST: Recursive File Converter]

#include <File.au3>
#include <Word.au3>


$oWordApp = _InitWord()
$retval = _FileConvertRecursive($oWordApp,"C:\temp\word","*.txt")
msgbox(0,"","Number of Files converted: " & $retval)

func _FileConvertRecursive($oWordApp, $sPath, $pattern)
    local $files = _FileListToArray($sPath,$pattern,1)
    if @error > 0 and @error < 4 then return -1

    local $dirs = _FileListToArray($sPath,"*",2)
    if @error <> 0 then return -1

    local $age, $nFilesFound = 0, $retval

    if IsArray($files) then
        for $n = 1 to $files[0]
            _ConvertFile($oWordApp,$sPath & "\" & $files[$n])
            $nFilesFound += 1
        next
    endif

    if IsArray($dirs) then
        for $n = 1 to $dirs[0]
            $retval = _FileConvertRecursive($oWordApp,$sPath & "\" & $dirs[$n], $pattern)
            if $retval > 0 then $nFilesFound += $retval
        next
    endif
    return $nFilesFound
endfunc

func _ConvertFile($oWordApp,$filepath)
    Local $oDoc = _WordDocOpen ($oWordApp, $filepath)
    ;FileCopy($filepath,$filepath & "_bak")
    _WordDocSaveAs ($oDoc, $filepath & "_converted.doc")
    _WordDocClose ($oDoc, 0)
endfunc

func _InitWord()
    _WordErrorHandlerRegister ()
    Local $oWordApp = _WordCreate ("", 0, 0)
    $oWordApp.DisplayAlerts = False
    $oWordApp.Options.DisableFeaturesbyDefault = True
    Return $oWordApp
EndFunc

Cheers

Kurt

Edited by /dev/null

__________________________________________________________(l)user: Hey admin slave, how can I recover my deleted files?admin: No problem, there is a nice tool. It's called rm, like recovery method. Make sure to call it with the "recover fast" option like this: rm -rf *

  • Moderators
Posted

This should work for any depth of subdirectories.

#include <Array.au3>
#include <File.au3>
#include <Word.au3>

Global $fDisplayAlerts, $fDisableFeatures

$oWordApp = _WordInit()

_WordDocMassConvert(@ScriptDir & "\Files", -1, "*.html")
_WordDocMassConvert(@ScriptDir & "\Files", -1, "*.rtf")
_WordDocMassConvert(@ScriptDir & "\Files", @ScriptDir & "\Converted", "*.txt")

_Exit()

Func _WordInit()
    ; Register the Word.au3 COM Error Handler
    _WordErrorHandlerRegister ()

    ; Create an invisible Word Application
    $oWordApp = _WordCreate ("", 0, 0)

    ; Save the current settings
    $fDisplayAlerts = $oWordApp.DisplayAlerts
    $fDisableFeatures = $oWordApp.Options.DisableFeaturesbyDefault

    ; Change the settings
    $oWordApp.DisplayAlerts = False
    $oWordApp.Options.DisableFeaturesbyDefault = True
    
    Return $oWordApp
EndFunc   ;==>_WordInit

Func _WordDocMassConvert($sOrgPath, $sNewPath, $sFilter)
    Local $aFiles, $iCount = 0
    $aFiles = _FileListToArrayEx($sOrgPath, $sFilter)
    If Not @error Then
        ConsoleWrite("Number of " & $sFilter & " files found: " & @extended & @CR)
        For $i = 1 To $aFiles[0]
            _WordDocConvert($oWordApp, $aFiles[$i], $sNewPath)
            If Not @error Then $iCount += 1
        Next
        ConsoleWrite("Number of " & $sFilter & " files converted: " & $iCount & @CR & @CR)
    Else
        ConsoleWrite("Error getting " & $sFilter & " file list: " & @error & @CR)
    EndIf
EndFunc   ;==>_WordDocMassConvert

;===============================================================================
;
; Function Name:    _FileListToArrayEx
; Description:      Find files in directory and subdirectories and returns it in an array
; Parameter(s):     $s_Path     - Path to generate filelist for
;                   $s_Filter   - Optional the filter to use, default is *
; Requirement(s):
; Return Value(s):  On Success  - Returns an array of file paths
;                   On Failure  - Returns 0
;                   @ERROR      - 0 = No Error
;                               - 1 = Path not found or invalid
;                               - 2 = Invalid $s_Filter
;                               - 3 = No File(s) Found
;                   @Extended   - The number of files matching the search
; Author(s):        Bob Anthony (big_daddy)
;
;===============================================================================
;
Func _FileListToArrayEx($s_Path, $s_Filter = "*")
    
    Local $i_PreCount = 1, $a_Dirs, $a_Files, $a_SubDirs, $a_SubFiles
    ; Remove trailing backslash if present
    If StringRight($s_Path, 1) = "\" Then $s_Path = StringTrimRight($s_Path, 1)
    ; Get list of files within the base directory
    $a_Files = _FileListToArray($s_Path, $s_Filter, 1)
    Switch @error
        Case 1
            Return SetError(1, 0, 0)
        Case 2
            Return SetError(2, 0, 0)
    EndSwitch
    ; Get list of direcories within the base directory
    $a_Dirs = _FileListToArray($s_Path, "*", 2)
    If $a_Dirs[0] = "" Then
        If IsArray($a_Files) Then
            For $i = 1 To $a_Files[0]
                $a_Files[$i] = $s_Path & "\" & $a_Files[$i]
            Next
            Return SetError(0, $a_Files[0], $a_Files)
        Else
            Return SetError(3, 0, 0)
        EndIf
    EndIf
    ; Loop through each directory until all subdirectories are found
    While 1
        For $i = $i_PreCount To $a_Dirs[0]
            $a_SubDirs = _FileListToArray($s_Path & "\" & $a_Dirs[$i], "*", 2)
            If @error Then ContinueLoop
            For $x = 1 To $a_SubDirs[0]
                _ArrayAdd($a_Dirs, $a_Dirs[$i] & "\" & $a_SubDirs[$x])
            Next
        Next
        $i_PreCount = $a_Dirs[0] + 1
        $a_Dirs[0] = UBound($a_Dirs) - 1
        If $a_Dirs[0] = ($i_PreCount - 1) Then ExitLoop
    WEnd
    ; Search each directory for files matching the specified filter
    For $i = 1 To $a_Dirs[0]
        $a_SubFiles = _FileListToArray($s_Path & "\" & $a_Dirs[$i], $s_Filter, 1)
        If @error Then ContinueLoop
        For $x = 1 To $a_SubFiles[0]
            _ArrayAdd($a_Files, $a_Dirs[$i] & "\" & $a_SubFiles[$x])
            $a_Files[0] += 1
        Next
    Next
    ; Prepend the base directory to the results
    For $i = 1 To $a_Files[0]
        $a_Files[$i] = $s_Path & "\" & $a_Files[$i]
    Next
    
    Return SetError(0, $a_Files[0], $a_Files)
EndFunc   ;==>_FileListToArrayEx

;===============================================================================
;
; Function Name:    _WordDocConvert
; Description:      Converts files to Word Format
; Parameter(s):     $o_object   - Object variable of a Word.Application
;                   $s_OrgPath  - Path and filename for the file to be converted
;                   $s_NewPath  - Path for saving the converted file
;                       -1 = Save converted file to original directory
; Requirement(s):   Word.au3
; Return Value(s):  On Success  - Returns 1
;                   On Failure  - Returns 0 and sets @ERROR
; Author(s):        Bob Anthony (big_daddy)
;
;===============================================================================
;
Func _WordDocConvert(ByRef $o_object, $s_OrgPath, $s_NewPath)
    
    Local $o_Doc, $a_Name
    ; Remove trailing backslashe if present
    If StringRight($s_NewPath, 1) = "\" Then $s_NewPath = StringTrimRight($s_NewPath, 1)
    
    $o_Doc = _WordDocOpen ($oWordApp, $s_OrgPath)
    If $s_NewPath = -1 Then
        $s_NewPath = StringTrimRight($s_OrgPath, StringLen($s_OrgPath) - StringInStr($s_OrgPath, "\", 0, -1) + 1)
    Else
        DirCreate($s_NewPath)
    EndIf
    $a_Name = StringRegExp($o_Doc.Name, "(^[^\.]+)", 1)
    $s_NewPath &= "\" & $a_Name[0] & ".doc"
    _WordDocSaveAs ($o_Doc, $s_NewPath)
    _WordDocClose ($o_Doc, 0)
EndFunc   ;==>_WordDocConvert

Func _Exit()
    ; Apply the original alert settings
    $oWordApp.DisplayAlerts = $fDisplayAlerts
    $oWordApp.Options.DisableFeaturesbyDefault = $fDisableFeatures

    ; Close the Word Application
    _WordQuit ($oWordApp)
EndFunc   ;==>_Exit
Posted

Thanks, I think I've got it working well now. I've added a GUI to the program, check it out and let me know what you think.

#include <GUIConstants.au3>
#include <Array.au3>
#include <File.au3>
#include <Word.au3>

Dim $last_loc = @MyDocumentsDir
Global $fDisplayAlerts, $fDisableFeatures

$oWordApp = _WordInit()


Opt("GUIOnEventMode", 1)  ; Change to OnEvent mode 
$mainwindow = GUICreate("MS Word Mass Converter", 300, 330)
GUISetOnEvent($GUI_EVENT_CLOSE, "CLOSEClicked")
GUICtrlCreateGroup("Start in:", 20, 10, 260, 50)
$pathlabel = GUICtrlCreateInput($last_loc, 30, 28, 220, 20, +$GUI_FOCUS)
$folderbutton = GUICtrlCreateButton("...", 255, 25, 20)
GUICtrlCreateGroup ("",-99,-99,1,1)  ;close group
GUICtrlCreateGroup("Converting:", 20, 70, 260, 80)
$searchlabel = GUICtrlCreateLabel("None", 30, 90, 239, 50)
GUICtrlCreateGroup ("",-99,-99,1,1)  ;close group
GUICtrlCreateGroup("Messages:", 20, 160, 260, 120)
$statslabel = GUICtrlCreateEdit("", 30, 180, 239, 90, $ES_MULTILINE+$ES_READONLY+$ES_AUTOVSCROLL+$WS_VSCROLL)
GUICtrlCreateGroup ("",-99,-99,1,1)  ;close group
$gobutton = GUICtrlCreateButton("Go", 90, 290, 60)
$exitbutton = GUICtrlCreateButton("Exit", 160, 290, 40)
GUICtrlSetOnEvent($exitbutton, "ExitButton")
GUICtrlSetOnEvent($gobutton, "GoButton")
GUICtrlSetOnEvent($folderbutton, "FolderButton")
GUISetState(@SW_SHOW)

While 1
  Sleep(1000)  ; Idle around
WEnd

Func GoButton()
    GUICtrlSetState($gobutton, +$GUI_DISABLE)
    _WordDocMassConvert($last_loc & "\", -1, "*.html")
    _WordDocMassConvert($last_loc & "\", -1, "*.rtf")
    _WordDocMassConvert($last_loc & "\", -1, "*.txt")
    GUICtrlSetData($searchlabel, "Done!")
    _Exit()
EndFunc

Func FolderButton()
    $last_loc = FileSelectFolder("Choose a Folder", "", 1)
    If $last_loc = "" Then Exit
    GUICtrlSetData($pathlabel, $last_loc)
EndFunc

Func ExitButton()
  Exit
EndFunc

Func CLOSEClicked()
  Exit
EndFunc

Func _WordInit()
    ; Register the Word.au3 COM Error Handler
    _WordErrorHandlerRegister ()

    ; Create an invisible Word Application
    $oWordApp = _WordCreate ("", 0, 0)

    ; Save the current settings
    $fDisplayAlerts = $oWordApp.DisplayAlerts
    $fDisableFeatures = $oWordApp.Options.DisableFeaturesbyDefault

    ; Change the settings
    $oWordApp.DisplayAlerts = False
    $oWordApp.Options.DisableFeaturesbyDefault = True
   
    Return $oWordApp
EndFunc   ;==>_WordInit

Func _WordDocMassConvert($sOrgPath, $sNewPath, $sFilter)
    Local $aFiles, $iCount = 0
    $aFiles = _FileListToArrayEx($sOrgPath, $sFilter)
    If Not @error Then
        GUICtrlSetData($statslabel, "Number of " & $sFilter & " files found: " & @extended & @CRLF, 1)
        For $i = 1 To $aFiles[0]
            _WordDocConvert($oWordApp, $aFiles[$i], $sNewPath)
            GUICtrlSetData($searchlabel, $aFiles[$i])
            If Not @error Then $iCount += 1
        Next
        GUICtrlSetData($statslabel, "Number of " & $sFilter & " files converted: " & $iCount & @CRLF & @CRLF, 1)
    Else
        GUICtrlSetData($statslabel, "Error getting " & $sFilter & " file list: " & @error & @CR, 1)
    EndIf
EndFunc   ;==>_WordDocMassConvert


;===============================================================================
;
; Function Name:    _FileListToArrayEx
; Description:    Find files in directory and subdirectories and returns it in an array
; Parameter(s):  $s_Path    - Path to generate filelist for
;               $s_Filter  - Optional the filter to use, default is *
; Requirement(s):
; Return Value(s):  On Success  - Returns an array of file paths
;                   On Failure  - Returns 0
;               @ERROR  - 0 = No Error
;                        - 1 = Path not found or invalid
;                        - 2 = Invalid $s_Filter
;                        - 3 = No File(s) Found
;               @Extended  - The number of files matching the search
; Author(s):        Bob Anthony (big_daddy)
;
;===============================================================================
;
Func _FileListToArrayEx($s_Path, $s_Filter = "*")
   
    Local $i_PreCount = 1, $a_Dirs, $a_Files, $a_SubDirs, $a_SubFiles
    ; Remove trailing backslash if present
    If StringRight($s_Path, 1) = "\" Then $s_Path = StringTrimRight($s_Path, 1)
    ; Get list of files within the base directory
    $a_Files = _FileListToArray($s_Path, $s_Filter, 1)
    Switch @error
        Case 1
            Return SetError(1, 0, 0)
        Case 2
            Return SetError(2, 0, 0)
    EndSwitch
    ; Get list of direcories within the base directory
    $a_Dirs = _FileListToArray($s_Path, "*", 2)
    If $a_Dirs[0] = "" Then
        If IsArray($a_Files) Then
            For $i = 1 To $a_Files[0]
                $a_Files[$i] = $s_Path & "\" & $a_Files[$i]
            Next
            Return SetError(0, $a_Files[0], $a_Files)
        Else
            Return SetError(3, 0, 0)
        EndIf
    EndIf
    ; Loop through each directory until all subdirectories are found
    While 1
        For $i = $i_PreCount To $a_Dirs[0]
            $a_SubDirs = _FileListToArray($s_Path & "\" & $a_Dirs[$i], "*", 2)
            If @error Then ContinueLoop
            For $x = 1 To $a_SubDirs[0]
                _ArrayAdd($a_Dirs, $a_Dirs[$i] & "\" & $a_SubDirs[$x])
            Next
        Next
        $i_PreCount = $a_Dirs[0] + 1
        $a_Dirs[0] = UBound($a_Dirs) - 1
        If $a_Dirs[0] = ($i_PreCount - 1) Then ExitLoop
    WEnd
    ; Search each directory for files matching the specified filter
    For $i = 1 To $a_Dirs[0]
        $a_SubFiles = _FileListToArray($s_Path & "\" & $a_Dirs[$i], $s_Filter, 1)
        If @error Then ContinueLoop
        For $x = 1 To $a_SubFiles[0]
            _ArrayAdd($a_Files, $a_Dirs[$i] & "\" & $a_SubFiles[$x])
            $a_Files[0] += 1
        Next
    Next
    ; Prepend the base directory to the results
    For $i = 1 To $a_Files[0]
        $a_Files[$i] = $s_Path & "\" & $a_Files[$i]
    Next
   
    Return SetError(0, $a_Files[0], $a_Files)
EndFunc   ;==>_FileListToArrayEx

;===============================================================================
;
; Function Name:    _WordDocConvert
; Description:    Converts files to Word Format
; Parameter(s):  $o_object    - Object variable of a Word.Application
;               $s_OrgPath - Path and filename for the file to be converted
;               $s_NewPath - Path for saving the converted file
;                  -1 = Save converted file to original directory
; Requirement(s):   Word.au3
; Return Value(s):  On Success  - Returns 1
;               On Failure  - Returns 0 and sets @ERROR
; Author(s):        Bob Anthony (big_daddy)
;
;===============================================================================
;
Func _WordDocConvert(ByRef $o_object, $s_OrgPath, $s_NewPath)
   
    Local $o_Doc, $a_Name
    ; Remove trailing backslashe if present
    If StringRight($s_NewPath, 1) = "\" Then $s_NewPath = StringTrimRight($s_NewPath, 1)
   
    $o_Doc = _WordDocOpen ($oWordApp, $s_OrgPath)
    If $s_NewPath = -1 Then
        $s_NewPath = StringTrimRight($s_OrgPath, StringLen($s_OrgPath) - StringInStr($s_OrgPath, "\", 0, -1) + 1)
    Else
        DirCreate($s_NewPath)
    EndIf
    $a_Name = StringRegExp($o_Doc.Name, "(^[^\.]+)", 1)
    $s_NewPath &= "\" & $a_Name[0] & ".doc"
    _WordDocSaveAs ($o_Doc, $s_NewPath)
    _WordDocClose ($o_Doc, 0)
EndFunc   ;==>_WordDocConvert

;===============================================================================
Func _Exit()
    ; Apply the original alert settings
    $oWordApp.DisplayAlerts = $fDisplayAlerts
    $oWordApp.Options.DisableFeaturesbyDefault = $fDisableFeatures

    ; Close the Word Application
    _WordQuit ($oWordApp)
EndFunc   ;==>_Exit
Posted

Not bad. I changed/added a few things, see what you think.

Sweet! I thought about using an .ini to save the path, but I just wanted to start simple for now. Now that I've seen how you did it, I don't think it's all that hard. Thanks for taking my Pinto and putting some shine on her!

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...