Что нового

Объединение файлов doc - сочетаниями клавиш

RipVanWinkel

Новичок
Сообщения
81
Репутация
0
доброго времени суток.
Вопрос - к специалистам.

Имеется код autoit, простыми комбинациями клавиш (эмуляцией) - собирающий содержимое текстовых файлов - в общий файл Итог.txt по Cписку.txt.
А вот созданный по образу и подобию такой же скрипт, но уже для файлов doc - уже не работает.
Выдает ошибку: "Ошибка запуска".

Рабочий скрипт (для txt) такой:
Код:
#include <WinAPIProc.au3>
#include <WinAPISys.au3>
#include <WinAPIvkeysConstants.au3>
_LoadKeyboardLayoutEngSelf()

HotKeySet("{ESC}", "_Exit")

Global $sPathList = "Список.txt", $sOutTxt = "Итог.txt", $aList, $aWnds, $iOutPID, $hOutWnd, $iPID, $hWnd

$aList = FileReadToArray($sPathList)
If @error Then Exit MsgBox(16, "", "Ошибка списка.")

If Not FileExists($sOutTxt) Then Exit MsgBox(16, "", "Итог не существует.")
$iOutPID = ShellExecute($sOutTxt)
Sleep(600)

If Not $iOutPID Then
    MsgBox(48, "", "Нажмите ОК когда появится нужное окно.")
    $hOutWnd = WinGetHandle("[ACTIVE]")
Else
    Do
        Sleep(250)
        If Not ProcessExists($iOutPID) Then Exit MsgBox(16, "", "Ошибка запуска.")
        $aWnds = _WinAPI_EnumProcessWindows($iOutPID)
    Until Not @error
    $hOutWnd = $aWnds[1][0]
EndIf

For $i = 0 To UBound($aList) - 1
    If Not FileExists($aList[$i]) Then ContinueLoop
    $iPID = ShellExecute($aList[$i])
	Sleep(600)

    If Not $iOutPID Then
        MsgBox(48, "", "Нажмите ОК когда появится нужное окно.")
        $hWnd = WinGetHandle("[ACTIVE]")
    Else
        Do
            Sleep(250)
            If Not ProcessExists($iPID) Then Exit MsgBox(16, "", "Ошибка запуска.")
            $aWnds = _WinAPI_EnumProcessWindows($iPID)
        Until Not @error
        $hWnd = $aWnds[1][0]
    EndIf
    WinActivate($hWnd)

    Sleep(250)
 Send("^a")
    Sleep(250)

 Send("^c")
    Sleep(250)
    WinActivate($hOutWnd)

    Sleep(250)
 Send("^{END}")
    Sleep(250)

 Send("^v")
   Sleep(250)

    WinClose($hWnd)
    WinWaitClose($hWnd)
Next


Sleep(250)
Send("^s")
Sleep(250)
WinClose($hOutWnd)

Func _Exit()
    Exit
EndFunc   ;==>_Exit

Func _LoadKeyboardLayoutEngSelf()
    Local Const $__KLF_ACTIVATE = 0x00000001, $__KLF_SETFORPROCESS = 0x00000100
    Local $a_Res = DllCall('user32.dll', 'long', 'LoadKeyboardLayoutW', 'wstr', '00000409', 'uint', BitOR($__KLF_ACTIVATE, $__KLF_SETFORPROCESS))
    If (@error) Or (Not $a_Res[0]) Then Return 0
    Return 1
EndFunc   ;==>_LoadKeyboardLayoutEngSelf

А нерабочий скрипт (для doc) выглядит так:
Код:
#include <WinAPIProc.au3>
#include <WinAPISys.au3>
#include <WinAPIvkeysConstants.au3>
_LoadKeyboardLayoutEngSelf()

HotKeySet("{ESC}", "_Exit")

Global $sPathList = "Список.txt", $sOutTxt = "Итог.doc", $aList, $aWnds, $iOutPID, $hOutWnd, $iPID, $hWnd

$aList = FileReadToArray($sPathList)
If @error Then Exit MsgBox(16, "", "Ошибка списка.")

If Not FileExists($sOutTxt) Then Exit MsgBox(16, "", "Итог не существует.")
$iOutPID = ShellExecute($sOutTxt)
Sleep(600)


If Not $iOutPID Then
    MsgBox(48, "", "Нажмите ОК когда появится нужное окно.")
    $hOutWnd = WinGetHandle("[ACTIVE]")
Else
    Do
        Sleep(250)
        If Not ProcessExists($iOutPID) Then Exit MsgBox(16, "", "Ошибка запуска.")
        $aWnds = _WinAPI_EnumProcessWindows($iOutPID)
    Until Not @error
    $hOutWnd = $aWnds[1][0]
EndIf

Sleep(200)
For $i = 0 To UBound($aList) - 1
    If Not FileExists($aList[$i]) Then ContinueLoop
    $iPID = ShellExecute($aList[$i])
	Sleep(600)


    If Not $iOutPID Then
        MsgBox(48, "", "Нажмите ОК когда появится нужное окно.")
        $hWnd = WinGetHandle("[ACTIVE]")

    Else
        Do
            Sleep(250)
            If Not ProcessExists($iPID) Then Exit MsgBox(16, "", "Ошибка запуска.")
            $aWnds = _WinAPI_EnumProcessWindows($iPID)
        Until Not @error
        $hWnd = $aWnds[1][0]
    EndIf
    WinActivate($hWnd)

    Sleep(250)
 Send("^a")
    Sleep(250)

 Send("^c")
    Sleep(250)
    WinActivate($hOutWnd)

    Sleep(250)
 Send("^{END}")
    Sleep(250)

 Send("^v")
   Sleep(250)

    WinClose($hWnd)
    WinWaitClose($hWnd)
Next


Sleep(250)
Send("^s")
Sleep(250)
WinClose($hOutWnd)

Func _Exit()
    Exit
EndFunc   ;==>_Exit


Func _LoadKeyboardLayoutEngSelf()
    Local Const $__KLF_ACTIVATE = 0x00000001, $__KLF_SETFORPROCESS = 0x00000100
    Local $a_Res = DllCall('user32.dll', 'long', 'LoadKeyboardLayoutW', 'wstr', '00000409', 'uint', BitOR($__KLF_ACTIVATE, $__KLF_SETFORPROCESS))
    If (@error) Or (Not $a_Res[0]) Then Return 0
    Return 1
EndFunc   ;==>_LoadKeyboardLayoutEngSelf
Как сделать скрипт для doc файлов - тоже работоспособным ?
 

Вложения

  • Скрипт для doc.rar
    9.2 КБ · Просмотры: 1
  • Скрипт для txt.rar
    1.2 КБ · Просмотры: 2

pvnn

Осваивающий
Сообщения
305
Репутация
32
С вордом просто как с txt не получится.
Здесь нужно настроить общий файл: отступы, интервалы, размер шрифта итд...
А потом уже объединять

Вот пример для объединения 2-х файлов: 2.doc и 3.doc. Можете добавить свои файлы.
Ну и горячие клавиши привязать.

Код:
#include <Word.au3>

 $oWord = _Word_Create()		; Создать Новый экземпляр Word
 $oDoc=_Word_DocAdd($oWord)		; Создать Итоговый новый пустой Word документ
 WordSetUp()	; Установка параметров в документе Word
 ReadWord(@ScriptDir&'\'&'2.doc')
 ReadWord(@ScriptDir&'\'&'3.doc')
 PDFConvert() 	; Конвертирование в PDF
 Exit

; Установка параметров в документе Word
Func WordSetUp()
	Const $WrdConst=28.35
	;MsgBox(0,'Левый отступ в см.', ($oWord.ActiveDocument.PageSetup.LeftMargin)/28.35 ) ; Узнать левый отступ
	$oWord.ActiveDocument.PageSetup.TopMargin=1.3*$WrdConst		; Отступ сверху в см
	$oWord.ActiveDocument.PageSetup.BottomMargin=1.3*$WrdConst	; Отступ снизу в см
	$oWord.ActiveDocument.PageSetup.LeftMargin=1*$WrdConst		; Отступ слева в см
	$oWord.ActiveDocument.PageSetup.RightMargin=1*$WrdConst		; Отступ справа в см

	; Установить Тип и размер шрифта
	$oWord.Selection.Font.Name = "Courier New"
	$oWord.Selection.Font.Size = 10.5

	; Отступ слева и справа
	$oWord.Selection.ParagraphFormat.LeftIndent = 0*$WrdConst 		; 0
	$oWord.Selection.ParagraphFormat.RightIndent = 0*$WrdConst		; 0
	; Интервал перед и после
	$oWord.Selection.ParagraphFormat.SpaceBefore = 0				; 0
	$oWord.Selection.ParagraphFormat.SpaceAfter=0					; 0
	; Междустрочный интервал
	$wdLineSpaceSingle=0	; Одинарный интервал
	$wdLineSpace1pt5=1		; Полуторный интервал
	$oWord.Selection.ParagraphFormat.LineSpacingRule = $wdLineSpaceSingle ; Одинарный интервал
EndFunc

Func ReadWord($Path)
	$oDocTemp=_Word_DocOpen($oWord,$Path,Default,$wdOpenFormatText)	; Открыть Word документ
	$Data=$oDocTemp.Range().Text
	$oRange = _Word_DocRangeSet($oDoc, -2)	; Устанавливает курсор в Конец итогового файла
 	$oRange.InsertAfter($Data)				; Вставить данные
 	$oRange = _Word_DocRangeSet($oDoc, -2)	; Устанавливает курсор в Конец итогового файла
;~ 	$oRange.Select	; Выделить
	$oRange.InsertBreak($wdLineBreak) ; Enter
	$oRange.InsertBreak($wdPageBreak) ; Разрыв страницы
	_Word_DocClose($oDocTemp)
EndFunc

; Конвертирование в PDF
Func PDFConvert()
	$sDocumentPdf = @ScriptDir&"\test2.pdf"
	_Word_DocExport($oDoc,$sDocumentPdf)
	If @error Then Exit MsgBox(0,$sDocumentPdf,'Ошибка конвертации в PDF')
EndFunc
 
Автор
R

RipVanWinkel

Новичок
Сообщения
81
Репутация
0
pvnn, не работает.

В файле 2.doc - текст и таблица.
В файле 3.doc - текст, таблица и рисунок.
Запускаю скрипт. На экране начинают мелькать окна Ворда.

В итоговом документе - появляются вот такие крякозябры: "мҐБ"
(Что это значит - я не понимаю. Всего три символа - "мҐБ" )
И затем появляется сообщение - "Ошибка конвертации в PDF"

Я-то спрашивал про простую вещь типа, активировать одно окно, Ctrl+A, Ctrl+C, активировать другое окно - Ctrl+End, Ctrl+V.
То есть простое перемещение между окнами, с перетаскиванием содержимого - через буфер обмена.
 

pvnn

Осваивающий
Сообщения
305
Репутация
32
RipVanWinke, это был пример для работы только с текстом.

Вот объединение файлов через буфер обмена.

Код:
#include <Word.au3>

 $oWord = _Word_Create()        ; Создать Новый экземпляр Word
 $oDoc=_Word_DocAdd($oWord)     ; Создать Итоговый новый пустой Word документ
 WordSetUp()    ; Установка параметров в документе Word
 ReadWord(@ScriptDir&'\'&'1.docx')
 ReadWord(@ScriptDir&'\'&'2.docx')
 Exit

; Установка параметров в документе Word
Func WordSetUp()
    Const $WrdConst=28.35
    ;MsgBox(0,'Левый отступ в см.', ($oWord.ActiveDocument.PageSetup.LeftMargin)/28.35 ) ; Узнать левый отступ
    $oWord.ActiveDocument.PageSetup.TopMargin=1.3*$WrdConst     ; Отступ сверху в см
    $oWord.ActiveDocument.PageSetup.BottomMargin=1.3*$WrdConst  ; Отступ снизу в см
    $oWord.ActiveDocument.PageSetup.LeftMargin=1*$WrdConst      ; Отступ слева в см
    $oWord.ActiveDocument.PageSetup.RightMargin=1*$WrdConst     ; Отступ справа в см
EndFunc

Func ReadWord($Path)
    $oDocTemp=_Word_DocOpen($oWord,$Path) 	; Открыть Word документ
	$oDocTemp.Range().CopyAsPicture() 		; Выделение и Копирование текста в ворде как изображения.
    $oRange = _Word_DocRangeSet($oDoc, -2)  ; Устанавливает курсор в Конец итогового файла
	$oRange.Paste() ; Вставка содержимого буфера обмена.
    $oRange = _Word_DocRangeSet($oDoc, -2)  ; Устанавливает курсор в Конец итогового файла
;~ 	$oRange.Select  ; Выделить
    $oRange.InsertBreak($wdLineBreak) ; Enter
    $oRange.InsertBreak($wdPageBreak) ; Разрыв страницы
    _Word_DocClose($oDocTemp)
EndFunc
 
Автор
R

RipVanWinkel

Новичок
Сообщения
81
Репутация
0
pvnn, не работает

Выдает вот такое сообщение в консоли:

"C:\1\1.au3" (22) : ==> Variable must be of type "Object".:
$oDocTemp.Range().CopyAsPicture()
$oDocTemp^ ERROR
>Exit code: 1 Time: 0.7978
 

pvnn

Осваивающий
Сообщения
305
Репутация
32
А вы эти строчки учли (.docx)?
Код:
ReadWord(@ScriptDir&'\'&'1.docx')
 ReadWord(@ScriptDir&'\'&'2.docx')


Добавьте проверку на открытие файлов
Код:
If @error Then Exit MsgBox(16, "Ошибка открытия", $Path)

После
Код:
$oDocTemp=_Word_DocOpen($oWord,$Path)


У меня все работает. Специально проверил даже для *.docx. Office 2013
 
Автор
R

RipVanWinkel

Новичок
Сообщения
81
Репутация
0
pvnn, все равно не работает.

Копирует только содержимое первого документа.
Содержимое второго документа - игнорирует.
 
Автор
R

RipVanWinkel

Новичок
Сообщения
81
Репутация
0
Alofa, Microsoft Word 2003
(Файлы с расширением doc)


Добавлено:
Сообщение автоматически объединено:

Я имел ввиду не какие-то сложнейшие манипуляции с программой ворд.

А намного более простую вещь - открытие сразу всех файлов doc из списка, а потом перемещение между ними в определенном порядки с операцией копипаста.
Типа - активировать одно окно, Ctrl+A, Ctrl+C, активировать другое окно - Ctrl+End, Ctrl+V.

То есть простое перемещение между окнами, с перетаскиванием содержимого - через буфер обмена.
 

pvnn

Осваивающий
Сообщения
305
Репутация
32
RipVanWinkel, я пробовал и с *.doc в office 2013 - все работало
Завтра попробую с office 2003...


Добавлено:
Сообщение автоматически объединено:

RipVanWinkel
А намного более простую вещь - открытие сразу всех файлов doc из списка, а потом перемещение между ними в определенном порядки с операцией копипаста.
Типа - активировать одно окно, Ctrl+A, Ctrl+C, активировать другое окно - Ctrl+End, Ctrl+V.
Я и так предлагаю вам простое решение:
Код:
$oDocTemp.Range().CopyAsPicture()
- копирует текст в буфер обмена, чем вам не Ctrl+A, Ctrl+C
Код:
$oRange.Paste()
- вставляет содержимое из буфера
Код:
$oRange = _Word_DocRangeSet($oDoc, -2)
- Устанавливает курсор в Конец итогового файла Ctrl+End

Я проверил скрип. С Office 2003 работает.

Вот немного переделанный вариант, точно должен работать проверил с Office 2003 и Office 2013.
Создается итоговый файл itog.doc:
Код:
#include <Word.au3>

 $oWord = _Word_Create()        ; Создать Новый экземпляр Word

 ; Создать и открыть итоговый файл
 $oDoc=_Word_DocAdd($oWord)
 _Word_DocSaveAs($oDoc,@ScriptDir&'\itog')
 _Word_DocClose($oDoc)
 $oDoc=_Word_DocOpen($oWord,@ScriptDir&'\itog.doc')   ; Открыть Word документ
 If @error Then Exit MsgBox(16, "Ошибка открытия", @ScriptDir&'\itog.doc')

 ReadWord(@ScriptDir&'\'&'1.doc')
 ReadWord(@ScriptDir&'\'&'2.doc')
 Exit


Func ReadWord($Path)
    $oDocTemp=_Word_DocOpen($oWord,$Path)   ; Открыть Word документ
	If @error Then Exit MsgBox(16, "Ошибка открытия", $Path)
    $oDocTemp.Range().CopyAsPicture()       ; Выделение и Копирование текста в ворде как изображения.
    $oRange = _Word_DocRangeSet($oDoc, -2)  ; Устанавливает курсор в Конец итогового файла
    $oRange.Paste() ; Вставка содержимого буфера обмена.
    $oRange = _Word_DocRangeSet($oDoc, -2)  ; Устанавливает курсор в Конец итогового файла
;~  $oRange.Select  ; Выделить
    $oRange.InsertBreak($wdLineBreak) ; Enter
    $oRange.InsertBreak($wdPageBreak) ; Разрыв страницы
    _Word_DocClose($oDocTemp)
EndFunc

RipVanWinkel, а точно файлы не добавляются? Там стоит разрыв страницы, вы прокручивали ниже документ?
Я поставил вашу версию Autoit, Office 2003 - все работает. И старый вариант скрипта и новый.
Если есть возможность предоставьте 2 файла, которые вы хотите объеденить
 
Автор
R

RipVanWinkel

Новичок
Сообщения
81
Репутация
0
pvnn , не работает.
Создает пустой файл itog.doc, затем тут же выдает ошибку : "Ошибка открытия".

И еще - я не совсем понимаю - где в вашем коде ссылка на файл Список.txt ?
Ведь именно там находится список файлов на объединение, где указан порядок объединения.
 

pvnn

Осваивающий
Сообщения
305
Репутация
32
Нет тут никакого Список.txt Список ваш можно "прикрутить" потом. Сначала проверьте работоспособность.

Ругается потому что у вас нет файлов!!!!
Укажите путь к файлам здесь:
Код:
ReadWord(@ScriptDir&'\'&'1.doc')
 ReadWord(@ScriptDir&'\'&'2.doc')


Создайте 2 файла: 1.doc и 2.doc и положите их в каталог со скриптом и запустите
 
Автор
R

RipVanWinkel

Новичок
Сообщения
81
Репутация
0
pvnn , создает файл itog.doc, в который вписывает только содержимое первого файла.

Содержимое второго файла - игнорирует (не добавляет содержимое второго файла в itog.doc ).
 

pvnn

Осваивающий
Сообщения
305
Репутация
32
Alofa, конечно!
Пришлось установить Office 2003 на другом компе.
Протестил на следующих конфигурациях
Win 7 x86, x64, office 2003, 2013.
Autoit 3.3.12.0, Autoit 3.3.14.0

Пример со списком. Пути к файлам необходимо прописать в files.txt

Код:
#include <Word.au3>
#include <Array.au3>
#include <File.au3>


 $oWord = _Word_Create()        ; Создать Новый экземпляр Word

 ; Создать и открыть итоговый файл
 $oDoc=_Word_DocAdd($oWord)
 _Word_DocSaveAs($oDoc,@ScriptDir&'\itog')
 _Word_DocClose($oDoc)
 $oDoc=_Word_DocOpen($oWord,@ScriptDir&'\itog.doc')   ; Открыть Word документ
 If @error Then Exit MsgBox(16, "Ошибка открытия", @ScriptDir&'\itog.doc')

Local $afiles
_FileReadToArray(@ScriptDir&'\'&'files.txt', $afiles)
;_ArrayDisplay($afiles)
For $i=1 To $afiles[0]
	$Path=StringStripWS($afiles[$i],3)
	If $Path<>'' Then ReadWord($Path)
Next



Func ReadWord($Path)
    $oDocTemp=_Word_DocOpen($oWord,$Path)   ; Открыть Word документ
	If @error Then Exit MsgBox(16, "Ошибка открытия", $Path)
    $oDocTemp.Range().CopyAsPicture()       ; Выделение и Копирование текста в ворде как изображения.
    $oRange = _Word_DocRangeSet($oDoc, -2)  ; Устанавливает курсор в Конец итогового файла
    $oRange.Paste() ; Вставка содержимого буфера обмена.
    $oRange = _Word_DocRangeSet($oDoc, -2)  ; Устанавливает курсор в Конец итогового файла
;~  $oRange.Select  ; Выделить
    $oRange.InsertBreak($wdLineBreak) ; Enter
    $oRange.InsertBreak($wdPageBreak) ; Разрыв страницы
    _Word_DocClose($oDocTemp)
EndFunc

RipVanWinkel предоставьте файлы для тестов
 
Автор
R

RipVanWinkel

Новичок
Сообщения
81
Репутация
0
pvnn , а вот теперь - все вроде бы кажется заработало.
Спасибо большое.
 
A

Alofa

Гость
pvnn сказал(а):
... Протестил на следующих конфигурациях
Win 7 x86, x64, office 2003, 2013.
Autoit 3.3.12.0, Autoit 3.3.14.0 ...
Беру свои слова обратно.
Разработчики Word.au3 весьма аккуратно написали UDF.
 
Верх