Форум программистов, компьютерный форум, киберфорум
VBA
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.51/79: Рейтинг темы: голосов - 79, средняя оценка - 4.51
0 / 0 / 0
Регистрация: 16.03.2012
Сообщений: 5
1

Пакетная обработка *.doc с рисунками внутри. Уменьшить качество рисунков.

16.03.2012, 16:11. Показов 14574. Ответов 37
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Поискал на форуме, поискал в Интернете,
Нашёл только пакетную обработку *.Doc и изменение масштабов рисунка.

А задача такая:
Есть примерно 2000 целевых файлов в папке. Там в *.doc файлах есть рисунки, которые необходимо сжать без сильной потери качества. Вручную это делается легко, но рисунков слишком много.

Word 2007. Или 2010.

Поможете?
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
16.03.2012, 16:11
Ответы с готовыми решениями:

Плохое качество рисунков в TImageList
Собственно я недоволен компонентом TImageList . Точнее его ограничениями на размеры хранимых в нем...

Есть книга которую я отсканировал, но после сканирования качество рисунков пропадает
Есть книга который я сканировал, но после сканирование качество рисунки пропадает то есть немножко...

Пакетная обработка
Привет всем ! У меня созрел вопрос следующего характера: во время пакетной обработки в Fhotoshop,...

Пакетная обработка
Ребят задумка такая....открываю файл docx, запускаю макрос. Он копирует в буфер картинки с листа,...

37
15145 / 6418 / 1731
Регистрация: 24.09.2011
Сообщений: 9,999
20.03.2012, 12:59 21
Author24 — интернет-сервис помощи студентам
Цикл по подпапкам можно организовать так:
Visual Basic
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
Sub start()
DoFldr CreateObject("scripting.filesystemobject").getfolder("b:\temp") 'корневая папка
End Sub
 
Sub DoFldr(f)
Dim x
For Each x In f.Files
    If LCase(Mid(x.Name, InStrRev(x.Name, ".") + 1)) Like "doc*" Then DoFile x.Path
Next
For Each x In f.subfolders 'рекурсия
    DoFldr x
Next
End Sub
 
Sub DoFile(s)
With Documents.Open(s)
    Application.CommandBars.ExecuteMso "PicturesCompress"
    .Close wdSaveChanges
End With
Debug.Print s 'лог в окно Immediate - необязательно
End Sub
Только вот команда Application.CommandBars.ExecuteMso "PicturesCompress" вызывает появление окна, в котором приходится нажимать кнопку.
В моем 2007 сжатие рисунков не записывается в макрос Неужели в 2010 тоже только такая команда? Хотелось бы найти этот метод, что-то типа ActiveDocument.Compress...
1
1031 / 702 / 66
Регистрация: 30.01.2012
Сообщений: 714
20.03.2012, 13:05 22
Цитата Сообщение от Казанский Посмотреть сообщение
команда Application.CommandBars.ExecuteMso "PicturesCompress" вызывает появление окна, в котором приходится нажимать кнопку
SendKeys "оп~"отправляют нажатия клавиш "о", "п", Enter и выставляют необходимые параметры("ко всем рисункам документа", "для печати")...

Цитата Сообщение от Казанский Посмотреть сообщение
В моем 2007 сжатие рисунков не записывается в макрос Неужели в 2010 тоже только такая команда?
похоже, что так...
0
15145 / 6418 / 1731
Регистрация: 24.09.2011
Сообщений: 9,999
20.03.2012, 13:07 23
Да, я погуглил и нашел
Visual Basic
1
2
Application.CommandBars.FindControl(Id:=6382).Execute
SendKeys "%A%W{ENTER}", False
Но это для англоязычной версии, для русской другие кнопки.
1
1031 / 702 / 66
Регистрация: 30.01.2012
Сообщений: 714
20.03.2012, 18:00 24
в принципе, всё работает:



связка WinXP SP3 on VBox + MS Word 2010

в папке и подпапке по 3 файла, полученных из исходного путём последовательного увеличения степени компрессии...

после сжатия выводится отчёт, из которого видно, что размеры файлов уменьшились...

я использовал вариант с dir, но более аутентичный вариант с рекурсией, думаю, будет работать не менее эффективно...
0
1300 / 402 / 22
Регистрация: 21.10.2011
Сообщений: 1,285
26.03.2012, 10:27 25
Buckminster,
комментарии к коду в #20.
  1. В Word используется только один символ для создания нового абзаца: vbCr. В Worde нет символа vbLf.

  2. Чтобы запятые не ставить:
    Visual Basic
    1
    
    Set dirlist = Documents.Open(dirfile, , , , , , , , , , msoEncodingOEMCyrillicII)
    можно использовать названия аргументов:
    Visual Basic
    1
    
    Set dirlist = Documents.Open(FileName:=dirfile, Encoding:=msoEncodingOEMCyrillicII)
1
1031 / 702 / 66
Регистрация: 30.01.2012
Сообщений: 714
26.03.2012, 11:28 26
Цитата Сообщение от Busine2012 Посмотреть сообщение
В Word используется только один символ для создания нового абзаца: vbCr. В Worde нет символа vbLf.
Word 2010 Developer Reference > Visual Basic for Applications Language Reference > Visual Basic Language Reference > Constants:
Miscellaneous Constants
The following constants are defined in the Visual Basic for Applications type library and can be used anywhere in your code in place of the actual values:

Constant Equivalent Description
vbCrLf Chr(13) + Chr(10) Carriage return–linefeed combination
vbCr Chr(13) Carriage return character
vbLf Chr(10) Linefeed character
проверка:
Пакетная обработка *.doc с рисунками внутри. Уменьшить качество рисунков.


файл создавался средствами dir, отсюда и перевод строки...

Цитата Сообщение от Busine2012 Посмотреть сообщение
Чтобы запятые не ставить, можно использовать названия аргументов
да, так действительно гораздо удобнее... спасибо...
1
1300 / 402 / 22
Регистрация: 21.10.2011
Сообщений: 1,285
26.03.2012, 11:38 27
Казанский
а вы тестировали код?
Visual Basic
1
2
Application.CommandBars.FindControl(Id:=6382).Execute 
SendKeys "%A%W{ENTER}", False
0
1031 / 702 / 66
Регистрация: 30.01.2012
Сообщений: 714
26.03.2012, 12:14 28
приведённый Казанский код действительно вызывает панель "Сжатие рисунков" (и в Word 2003, и в Word 2010):
Код
Application.CommandBars.FindControl(Id:=6382).Execute
но вот SendKeys (как это ни парадоксально) действительно указывается до вызова панели:
Код
SendKeys "оп~"
Application.CommandBars.FindControl(ID:=6382).Execute
иначе символы посылаются в окно с активным фокусом...
1
1300 / 402 / 22
Регистрация: 21.10.2011
Сообщений: 1,285
26.03.2012, 13:10 29
Buckminster,
да, действительно, если создать txt-файл, а затем его открыть с помощью программы Word, то в конце каждого абзаца будет 2 символа: vbCr и vbLf. Только символа vbLf вообще не видно и он не относится к непечатаемым символам программы Word, которые видно.


Buckminster,
да, вот этот код работает:
Visual Basic
1
2
SendKeys "оп~"
Application.CommandBars.FindControl(ID:=6382).Execute
только работа этого кода нелогична, потому что когда мы посылаем нажатие клавиш, то нажатие клавиш должно происходить в отношении активного окна. Соответственно команда SendKeys "оп~" должна печатать буквы "оп" и ставить знак абзаца в самом документе, а не в диалоговом окне, которое ещё и не появилось.

Я считаю, что SendKeys работает в отношение немодальных окон.
Немодальное окно - это когда можно переходить из диалогового окна в документ и обратно, не закрывая диалогового окна (пример, немодального окна Найти и заменить).


Работающий вариант кода для Word 2010 с использованием рекурсивной процедуры. Часть данных взята от других участников этой темы.
Перед запуском кода просмотрите комментарии кода (они зелёным цветом).
Если при запуске кода появится диалоговое окно с двумя кнопками Применить и Отмена, то поставьте флажок Больше не показывать это предупреждение, чтобы это диалоговое окно больше не появлялось.
Visual Basic
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
Option Explicit
 
'Здесь создаём объект FileSystemObject, который
'будет доступен для всех процедур этого модуля.
Dim oFSO As New Scripting.FileSystemObject
    
'Для просмотра всех файлов в определённой папке, включая подпапки,
'буду использовать рекурсивную процедуру - это процедура,
'которая вызывает сама себя. функции Win32 API для этих целей нет -
'надо также использовать рекурсию. Это:
'cmd = " /c dir *.doc /s /b > dir.txt"
'Shell Environ$("comspec") & cmd, vbHide
'использовать не буду, т.к. не нашёл документации в интернете
'по использованию этих команд.
Sub Main()
    'Для удобства написания кода (чтобы когда ставили точку,
    'появлялись всплывающие подсказки) подключаем библиотеку классов:
    'Tools - References... - Microsoft Scripting Runtime.
    'Но подключение произойдёт только для одного компьютера,
    'на остальных компьютерах код не будет работать, поэтому надо
    'будет внести изменения в код - если это надо будет, тогда спросите.
    
    'Здесь указываем, какую папку надо будет просмотреть.
    'В этой папке будут просмотрены все подпапки.
    Const sMainFolder As String = "C:\Documents and Settings\Пользователь\Рабочий стол\Рисунки"
    'Запускаем рекурсивную процедуру Procedure1, которая будет находить
    'все doc-файлы и вносить в них изменения.
    Call Procedure1(sMainFolder)
    'Просто сообщение, что всё сделано.
    MsgBox "Работа завершена!", vbInformation
End Sub
 
Sub Procedure1(sFolderPath As String)
    'Процедура, которая находит все doc-файлы и вносит в них изменения.
    Dim oFolder As Scripting.Folder
    Dim oSubFolder As Scripting.Folder
    Dim oFile As Scripting.File
    Dim oDocument As Word.Document
    Set oFolder = oFSO.GetFolder(FolderPath:=sFolderPath)
    For Each oFile In oFolder.Files
        'lCase - на случай, если по каким-то причинам название файла
        'будет получено прописными буквами (большими).
        'Скрытые файлы с расширением ".doc" тоже считаются doc-файлами.
        'Например, когда открываем документ Word,
        'то в той же папке, где находится документ, создаётся скрытый файл.
        'Если такой файл открывать, то возникнет ошибка, поэтому
        'такие файлы, хоть они и имеют расширение ".doc", открывать не надо.
        'Скрытые файлы имеют вначале имени вот такие символы "~$".
        If LCase(oFile.Name) Like "*.doc" And LCase(Left(oFile.Name, 2)) <> "~$" Then
            'Собственно обработка файла.
            Set oDocument = Documents.Open(FileName:=oFile.Path)
            SendKeys String:="оп{ENTER}", Wait:=False
            Application.CommandBars.FindControl(ID:=6382).Execute
            oDocument.Close SaveChanges:=wdSaveChanges
        End If
    Next oFile
    'Здесь просматриваем вложенные папки (рекурсия здесь).
    For Each oSubFolder In oFolder.SubFolders
        'Запуск процедурой самой же себя.
        Call Procedure1(oSubFolder.Path)
    Next oSubFolder
End Sub
1
0 / 0 / 0
Регистрация: 16.03.2012
Сообщений: 5
27.03.2012, 14:52  [ТС] 30
Buckminster,

У меня почему-то не работает на первой же строке кода (((

Ругается, что не описан пользовательский (?!) класс Scripting.FileSystemObject

Поискал в инете, попробовал сделать

regsvr32 C:\WINDOWS\system32\scrrun.dll
Всё успешно. Перезагрузил комп.
В реестре посмотрел, тоже вроде присутствует и класс и библиотека.

У меня стоит Win7 Pro + Kasp Endpoint 8. Пробовал отключать каспа никакой реакции

Вот
0
1300 / 402 / 22
Регистрация: 21.10.2011
Сообщений: 1,285
27.03.2012, 14:56 31
corvus_ukhta,
а это делали в VBA:
Tools - References... - Microsoft Scripting Runtime.

Я просто комментарии (они зелёным цветом) в коде не туда написал, надо было в самый верх.
По поводу библиотеки классов Microsoft Scripting Runtime - первый абзац комментариев сразу после имени процедуры Main.
1
1031 / 702 / 66
Регистрация: 30.01.2012
Сообщений: 714
27.03.2012, 15:14 32
Цитата Сообщение от corvus_ukhta Посмотреть сообщение
Buckminster,
У меня почему-то не работает на первой же строке кода (((
код с dir тоже не работает? хотя, я ведь не выложил финальный вариант:

Visual Basic
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
Sub BatchCompress()
  
  dpath = "H:\Tmp\Circle\" 'путь к папке
  drive = Left(dpath, 1)
  ChDrive drive
  ChDir dpath
  Shell Environ$("comspec") & " /c dir *.doc /s > fulldir.txt", vbHide
  Shell Environ$("comspec") & " /c dir *.doc /s /b > dir.txt", vbHide 
  MsgBox "File List Created!"
 
  With Documents.Open(FileName:="dir.txt", Encoding:=msoEncodingOEMCyrillicII)  
  For i = 1 To .Paragraphs.Count
    With .Paragraphs(i).Range
      fn = Replace(Replace(.Text, vbCr, ""), vbLf, "")
      With Documents.Open(fn)
        SendKeys "оп~" 'устанавка опций
        Application.CommandBars.ExecuteMso "PicturesCompress"
        .Close wdSaveChanges
      End With
    End With
  Next 
  .Close
  End With
  
  ChDrive drive
  ChDir dpath
  Shell Environ$("comspec") & " /c dir *.doc /s >> fulldir.txt", vbHide  
  MsgBox "Compressing Finished!"  
  Documents.Open FileName:="fulldir.txt", Encoding:=msoEncodingOEMCyrillicII 'файл отчёта
  
End Sub
1
0 / 0 / 0
Регистрация: 16.03.2012
Сообщений: 5
27.03.2012, 21:19  [ТС] 33
Цитата Сообщение от Buckminster Посмотреть сообщение
BatchCompress
Огромное спасибо. Последний скрипт отработал на "Ура"

Итого обработано 864 файла *.doc размер папки с остальными файлами уменьшился с 6 до 2,5 Гб.

Раза три процесс "подвисал" на параметрах сжатия, но стоило щёлкнуть на клавишу "Ок" и всё продолжалось.

Вива Buckminster'у!
0
Buckminster
28.03.2012, 08:06
  #34

Не по теме:

код не идеален, но вполне рабочий...
я ведь специально вывесил видео в HD, чтобы можно было во всём убедиться и разглядеть детали...
рад был помочь...

0
5562 / 1368 / 150
Регистрация: 08.02.2009
Сообщений: 4,109
Записей в блоге: 30
30.12.2016, 16:26 35
Цитата Сообщение от Busine2012 Посмотреть сообщение
Казанский
а вы тестировали код?
Visual Basic
1
2
Application.CommandBars.FindControl(Id:=6382).Execute 
SendKeys "%A%W{ENTER}", False
Напомните (а кто-то забыл, да?), пожалуйста, Казанский, какое это клавосочетание.

А ещё интересно: если в нём заменить {ENTER} на тильду (~) — сработает?
0
0 / 0 / 0
Регистрация: 16.11.2017
Сообщений: 1
16.11.2017, 01:33 36
А можно сделать такой же макрос только для файлов docx?
0
0 / 0 / 0
Регистрация: 21.12.2017
Сообщений: 2
21.12.2017, 23:07 37
Добрый день. Помогите, как сделать для последнего кода для выбора папки открытие диалогового окна? Сам не смогу...

Добавлено через 8 минут
Уточню: в последнем коде для выбора папки как сделать открытие диалогового окна для указания пути?
И еще было бы здорового всплывающее окно (типа настройки) с выбором типов файлов - doc, docx (или чтобы оба формата обрабатывались) и например согласие на формирование отчетного файла.
Файлов много как в doc, так и в docx форматах. Так еще и много папок с файлами.
0
32 / 29 / 1
Регистрация: 06.01.2017
Сообщений: 297
23.12.2017, 23:33 38
Парни, аплодирую всем!
0
23.12.2017, 23:33
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
23.12.2017, 23:33
Помогаю со студенческими работами здесь

Пакетная обработка треков
Всем привет. Нужно ПО, которое будет накладывать нужный мне звуковой файл на MP3 файлы. ...

Пакетная обработка файлов
Нужно переводить большие группы файлов *.txt *.hmtl *.php и т.д. из кодировки ANSI в UTF-8 с...

Кроп и пакетная обработка
Привет форумчане, с прошедшим праздником :) Учусь делать HDR панорамы. Нужно выравнять и...

Пакетная конвертация PDF в DOC и печать любых документов на PDF-принтере
В первую очередь извините, если создал тему в неположенном разделе, но к сожалению найти близкий по...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
38
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru