Как из Excel обратиться к другому приложению
Иногда бывает необходимо перенести что-то из Excel в другое приложение. Я возьму для примера Word. Например скопировать ячейки и вставить. Обычно мы это так и делаем - скопировали в Excel, открыли Word - вставили. Но сделать это при помощи кода чуть сложнее, хотя если разобраться никаких сложностей нет. Ниже приведен пример кода, который открывает Word, открывает в нем определенный документ, копирует данные из Excel и вставляет в открытый документ Word.
Sub OpenWord() Dim objWrdApp As Object, objWrdDoc As Object 'создаем новое приложение Word Set objWrdApp = CreateObject("Word.Application") 'Можно так же сделать приложение Word видимым. По умолчанию открывается в скрытом режиме 'objWrdApp.Visible = True 'открываем документ Word - документ "Doc1.doc" должен существовать Set objWrdDoc = objWrdApp.Documents.Open("C:\Doc1.doc") 'Копируем из Excel диапазон "A1:A10" Range("A1:A10").Copy 'вставляем скопированные ячейки в Word - в начала документа objWrdDoc.Range(0).Paste 'закрываем документ Word с сохранением objWrdDoc.Close True ' False - без сохранения 'закрываем приложение Word - обязательно! objWrdApp.Quit 'очищаем переменные Word - обязательно! Set objWrdDoc = Nothing: Set objWrdApp = Nothing End Sub |
Tips_Macro_OpenWord.xls (49,5 KiB, 6 463 скачиваний)
В файле-примере, приложенном к данной статье, в комментариях к коду есть несколько добавлений. Например, как вставить текст из ячеек в определенные закладки Word-а и как добавить новый документ, а не открывать уже имеющийся. Так же так есть код проверки - открыто ли приложение Word в данный момент. Порой это тоже может пригодиться, чтобы работать с запущенным приложением Word, а не создавать новое:
Sub Check_OpenWord() Dim objWrdApp As Object On Error Resume Next 'пытаемся подключится к объекту Word Set objWrdApp = GetObject(, "Word.Application") If objWrdApp Is Nothing Then 'если приложение закрыто - создаем новый экземпляр Set objWrdApp = CreateObject("Word.Application") 'делаем приложение видимым. По умолчанию открывается в скрытом режиме objWrdApp.Visible = True Else 'приложение открыто - выдаем сообщение MsgBox "Приложение Word уже открыто", vbInformation, "Check_OpenWord" End If End Sub |
В принципе, активировать или вызвать(если закрыто) другое приложение Офиса можно одной строкой:
Sub Open_AnotherApp() Application.ActivateMicrosoftApp xlMicrosoftWord End Sub |
но данный метод может пригодиться только в том случае, если Вам необходимо действительно лишь активировать другое приложение, но дальше обращаться к этому приложению Вы уже не сможете.
По сути, методами
Для начала открываем меню
Подключаем библиотеку:
Затем объявляем переменную и присваиваем ей тип нужного приложения:
Sub OpenWord() Dim objWrdApp As Word.Application Set objWrdApp = New Word.Application objWrdApp.Visible = True End Sub |
Если теперь в редакторе, внутри этой процедуры в любом месте ниже объявления переменной набрать objWrdApp и точку, то сразу после ввода точки выпадет меню, в котором будут перечислены все доступные методы и свойства этого приложения.
Так же можно нажать
Метод установки ссылки на библиотеку приложения через Tools-References называют еще ранним связыванием. Подобный метод позволяет создать ссылку на приложение быстрее и, как описано выше, предоставляет разработчику доступ к визуальному отображению свойств и методов объекта. Но есть существенный минус: если в своем коде Вы установите ссылку на Word 12 Object Libbary(Word 2007), то на ПК с установленным Word 2003 получите ошибку MISSING, т.к. Word 2003 относится к библиотеке Word 11 Object Libbary. Подробнее можно прочитать в статье Ошибка — Cant find project or library.
Метод же CreateObject еще называется методом позднего связывания. Применяя его не возникнет проблем с MISSING, очень часто возникающих при раннем связывании. Поэтому я рекомендовал бы при разработке использовать раннее связывание для удобства использования свойств и методов(если Вы их не знаете), а перед распространением приложения в коде заменить все именованные константы(типа wdLine) на числовые константы(для wdLine это 5) и применить позднее связывание. Посмотреть числовое значение константы можно просто записав её в коде, начать выполнение кода через
ниже будет выведено числовое представление этой константы.
А заменять эти константы их числовыми значениями в случае с поздним связыванием необходимо, т.к. Excel не знает их значений.
Попробую пояснить поподробнее про эти константы и почему их надо заменять какими-то числами: при подключении библиотеки Wordа(Word 12 Object Libbary) мы так же подключаем и все свойства, методы и константы, которые доступны из Wordа. И их использование напрямую становится доступно из Excel и мы можем смело написать что-то вроде
И хочу так же упомянуть про ошибку, которую очень часто совершают при обращении к одному приложению из другого. Допустим, необходимо скопировать из Word все данные в Excel. Часто начинающие делают это так:
Sub OpenWord() Dim objWrdApp As Object, objWrdDoc As Object 'создаем новое приложение Word Set objWrdApp = CreateObject("Word.Application") 'Можно так же сделать приложение Word видимым. По умолчанию открывается в скрытом режиме 'objWrdApp.Visible = True 'открываем документ Word - документ "Doc1.doc" должен существовать Set objWrdDoc = objWrdApp.Documents.Open("C:\Doc1.doc") 'Копируем из Word все данные, обращаясь к объекту Range документа Range.Copy 'вставляем скопированное в ячейку А1 активного листа Excel ActiveSheet.Paste 'закрываем документ Word без сохранения objWrdDoc.Close False 'закрываем приложение Word objWrdApp.Quit 'очищаем переменные Word - обязательно! Set objWrdDoc = Nothing: Set objWrdApp = Nothing End Sub |
На строке Range.Copy обязательно получите ошибку от VBA, указывающую, что нужен аргумент для объекта. Можно попробовать добавить этот аргумент: Range(1).Copy. Но все равно получим ошибку. Можно, конечно, указать даже ячейки: Range("A1").Copy. Но это приведет к тому, что скопирована будет ячейка А1 активного листа Excel.
Все дело в том, что мы хотим скопировать данные из Word-а, выполняя при этом код из Excel. А у Excel тоже есть объект Range с другими аргументами. И если не указать какому приложению, листу или документу принадлежит Range, то по умолчанию он будет отнесен к тому приложению, из которого выполняется код. Т.е. к Excel. Если совсем кратко об этом - всегда надо указывать какому приложению или объекту принадлежит используемый объект или свойство. Правильно код должен выглядеть так:
Sub OpenWord() Dim objWrdApp As Object, objWrdDoc As Object 'создаем новое приложение Word Set objWrdApp = CreateObject("Word.Application") 'Можно так же сделать приложение Word видимым. По умолчанию открывается в скрытом режиме 'objWrdApp.Visible = True 'открываем документ Word - документ "Doc1.doc" должен существовать Set objWrdDoc = objWrdApp.Documents.Open("C:\Doc1.doc") 'Копируем из Word все данные, обращаясь к объекту Range документа 'при этом перед Range явно указываем откуда его брать - из документа Word -objWrdDoc("C:\Doc1.doc") objWrdDoc.Range.Copy 'вставляем скопированное из Word в активную ячейку активного листа Excel ActiveSheet.Paste 'закрываем документ Word без сохранения objWrdDoc.Close False 'закрываем приложение Word objWrdApp.Quit 'очищаем переменные Word - обязательно! Set objWrdDoc = Nothing: Set objWrdApp = Nothing End Sub |
Вместо Range ту же ошибку делают и с Selection(потому что Selection часто присутствует в записанных макрорекордером макросах), т.к. этот объект есть и в Excel и в Word и без явного указания приложения будет относится к приложению, в котором записано.
В приложенном файле код немного отличается от представленных выше - в нем можно посмотреть как вставить текст из ячеек в определенные(созданные заранее) закладки Word-а. Это удобно для создания бланков в Word и заполнения их через Excel
Tips_Macro_OpenWord.xls (49,5 KiB, 6 463 скачиваний)
А в архиве ниже - практически готовое решение заполнения всевозможных бланков Word из Excel. Как это работает. У нас есть таблица Excel с данными для заполнения бланков заявлений на пособия:
Обращаю внимание, что в первой строке расположены метки. Они нужны для того, чтобы код мог понять значения какого столбца в какое место шаблона Word должны попасть. А в самом шаблоне Word мы должны проставить эти самые метки:
Фигурные скобки сделаны для того, чтобы код 100% искал и заменял только метку в шаблоне, исключая при этом замену случайного текста вне скобок(ведь слово "Должность" может встречаться и само по себе).
А здесь я схематично привел то, как будут происходить замены:
Сначала программа создаст новую папку, в которую и будет сохранять создаваемые файлы(имя папки состоит из даты и времени запуска кода). Далее программа циклом пройдется по каждой строке таблицы, создаст на основании шаблона Word(
'считываем фамилию с инициалами
sWDDocName = .Cells(lr, 1).Value |
'имя шаблона Word с основным текстом и метками Const sWDTmpl As String = "Шаблон.doc" |
В общем-то, если хоть чуть-чуть разбираетесь, то поменять можно многое. А для тех, кто не разбирается достаточно будет просто создавать метки в файле Word и обозначать ими столбца в таблице Excel. Количество столбцов и строк в таблице код определяет автоматически и при изменении размеров таблицы ничего изменять не надо. Главное, чтобы метки находились в первой строке, вторая строка - заголовок(необязательно), а с третьей строки начинаются данные, которые и используются для наполнения шаблонов.
Автосоздание бланков Word из таблицы Excel.zip (37,6 KiB, 1 660 скачиваний)
Примеры работы с тем же Outlook можно посмотреть в моих статьях:
Как отправить письмо из Excel?
Сохранить вложения из Outlook в указанную папку
Статья помогла? Поделись ссылкой с друзьями!

Поиск по меткам
Access apple watch Multex Power Query и Power BI VBA управление кодами Бесплатные надстройки Дата и время Записки ИП Надстройки Печать Политика Конфиденциальности Почта Программы Работа с приложениями Разработка приложений Росстат Тренинги и вебинары Финансовые Форматирование Функции Excel акции MulTEx ссылки статистикаКомментарии, не имеющие отношения к комментируемой статье, могут быть удалены без уведомления и объяснения причин. Если есть вопрос по личной проблеме - добро пожаловать на Форум
objWrdDoc.bookmarks("DataPodgotovki").Range.Text = sTxt
Здравствуйте, Дмитрий. Благодарю за замечательную статью.
Есть такой вопрос. Не удалось обнаружить разницу между поведением CreateObject("тра-ла-ла") и GetObject("тра-ла-ла"); и то, и то не ведёт к использованию уже открытого приложения. Это заметно по использованию коллекций после вызовов.
Проверялось на office 2010, Win XP и Win 7
Не известен ли Вам способ действительно подключиться к работающему процессу приложения?
Александр, при верном использовании и результат верный. GetObject вызывается с запятой перед ProgID приложения:
GetObject(, "Word.Application")
. Это ОЧЕНЬ важный момент. Правда, мне неясно про какие такие колллекции Вы говорите. Если коллекции как объект VBA - то да, они же к VBA относятся, а не к Excel или Word.применила по Вашей рекомендации позднее связывание с Wordom - все работает!
большое спасибо! избавились от большое головной боли
а вот еще вопрос по MISSING библиотеки - я на все компьютеры с Office 2003 записала библиотеку Word 2007 ( в соответствующую директорию) ( ранее, еще до применения позднего связывания) - на моем компьютере это решило проблему, а на компьютере пользователя - не решило
в чем может быть причина? не может ли быть это из-за прав на библиотеку - я на своем компьютере Administrator, а пользователи - нет
очень хотелось бы разобраться
Доброго времени суток, Дмитрий!
У меня вопрос по макросам Ворда. Я понимаю, что Эксель и всё такое (по крайней мере на "планете Эксель" Юрий М. постоянно мне напоминает, что это форум Экселя, а не Ворда. Но у меня вопрос по Ворду. И не обращаюсь на форум, т.к. четко написано: "Если есть вопрос по проблеме в Excel- добро пожаловаться на Форум". А у меня Ворд.
Суть такова. Открываю файл Ворда, макросом редактирую его, сохраняю как, удаляю исходный файл, а потом открываю сохраненный файл. Так вот, когда я открываю сохраненный файл, у меня получается открыто два окна Ворда: одно с моим сохраненным файлом, а другое окно - пустое!!! И не знаю, как сделать макросом его закрытие или удаление.
Краткий код:
Заранее благодарю...
Если работаете из Word-а - последние 4 строки лишние в корне. Они создают новый экземпляр Word. Т.е. Вы сами второе окно создаете. Достаточно одной строки
Documents.Open ИмяФайлаНовое
Здравствуйте! Ваша статья - огонь, благодаря ей наконец понял как это работает. И тут же возник вопрос - а можно ли сразу документ word отправить на печать? Сейчас при включении макроса excel передает данные в шаблон word'а, и сохраняет его. А как его сразу на печать кинуть??? Что бы в excel кнопку макроса нажал - и готовый док уже из принтера ползет))?
Что мешает записать макрос печати документа в Word и потом перенести в Excel?
Здравствуйте! Отличный макрос - практически то что мне нужно, спасибо вам огромное!
Вот только никак не могу сделать так, чтобы на место закладки копировался весь выделенный диапазон(в виде таблицы), а не только текст из первой ячейки.