Lost your password?


Хитрости »
Основные понятия (27)
Сводные таблицы и анализ данных (10)
Графики и диаграммы (5)
Работа с VB проектом (12)
Power BI и Power Query (23)
Условное форматирование (5)
Списки и диапазоны (5)
Макросы(VBA процедуры) (68)
Разное (43)
Баги и глюки Excel (5)

Как из 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 709 скачиваний)


В файле-примере, приложенном к данной статье, в комментариях к коду есть несколько добавлений. Например, как вставить текст из ячеек в определенные закладки 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

но данный метод может пригодиться только в том случае, если Вам необходимо действительно лишь активировать другое приложение, но дальше обращаться к этому приложению Вы уже не сможете.

По сути, методами CreateObject и GetObject можно обратиться к любому стороннему приложению(например Internet Explorer). Куда важнее при обращении к этим объектам знать объектную модель того приложения, к которому обращаетесь. Чтобы увидеть свойства и методы объектной модели приложения, можно в редакторе VBA подключить необходимую библиотеку, объявить переменную, назначив ей тип приложения. Покажу на примере того же Word-а.
Для начала открываем меню Tools -References:

Подключаем библиотеку:

Затем объявляем переменную и присваиваем ей тип нужного приложения:

Sub OpenWord()
    Dim objWrdApp As Word.Application
    Set objWrdApp = New Word.Application
    objWrdApp.Visible = True
End Sub

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

Так же можно нажать F2 и через поиск найти Word и просмотреть все методы и свойства данного приложения.

Метод установки ссылки на библиотеку приложения через 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) и применить позднее связывание. Посмотреть числовое значение константы можно просто записав её в коде, начать выполнение кода через F8 и навести курсор мыши на эту константу. Всплывающая подсказка покажет числовое значение. Так же можно отобразить окно Immediate(View -Immediate Window или сочетание клавиш Ctrl+G), записать вопросительный знак и вставить эту константу и нажать Enter:
?wdLine
ниже будет выведено числовое представление этой константы.
А заменять эти константы их числовыми значениями в случае с поздним связыванием необходимо, т.к. Excel не знает их значений.
Попробую пояснить поподробнее про эти константы и почему их надо заменять какими-то числами: при подключении библиотеки Wordа(Word 12 Object Libbary) мы так же подключаем и все свойства, методы и константы, которые доступны из Wordа. И их использование напрямую становится доступно из Excel и мы можем смело написать что-то вроде wbLine и Excel поймет эту константу. При позднем же связывании мы уже не подключаем библиотеки Word(во избежание ошибок совместимости) и как следствие - методы, свойства и константы Wordа для Excel становятся чем-то неизвестным и не документированным и мы получим ошибку "Variable not defined"(если включена директива Option Explicit) при попытке назначить свойство через wdLine. Если же Option Explicit не включена - то хоть ошибки не будет, но и код будет работать неверно, т.к. для неизвестной для Excel переменной wbLine будет назначено значение 0(Empty). Поэтому и надо все константы другого приложения заменять их числовыми значениями.

Главная ошибка новичка
И хочу так же упомянуть про ошибку, которую очень часто совершают при обращении к одному приложению из другого. Допустим, необходимо скопировать из 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 709 скачиваний)


А в архиве ниже - практически готовое решение заполнения всевозможных бланков Word из Excel. Как это работает. У нас есть таблица Excel с данными для заполнения бланков заявлений на пособия:
Исходная таблица
Обращаю внимание, что в первой строке расположены метки. Они нужны для того, чтобы код мог понять значения какого столбца в какое место шаблона Word должны попасть. А в самом шаблоне Word мы должны проставить эти самые метки:
Шаблон Word с метками
Фигурные скобки сделаны для того, чтобы код 100% искал и заменял только метку в шаблоне, исключая при этом замену случайного текста вне скобок(ведь слово "Должность" может встречаться и само по себе).
А здесь я схематично привел то, как будут происходить замены:
Схема замен
Сначала программа создаст новую папку, в которую и будет сохранять создаваемые файлы(имя папки состоит из даты и времени запуска кода). Далее программа циклом пройдется по каждой строке таблицы, создаст на основании шаблона Word("Шаблон.doc") новый файл для этой строки, заполнит этот шаблона данными на основании меток, и сохранит созданный файл под новым именем. Сам файл шаблона при этом не изменяется - все метки в нем сохраняются как были настроены до запуска кода. Конкретно в приложенном коде значение для имени нового файла берется из первого столбца "ФИО с инициалами". Но это можно изменить в коде при необходимости. Делается это в этой строке:

'считываем фамилию с инициалами
sWDDocName = .Cells(lr, 1).Value

Что еще важно: файл шаблона Word должен находиться в той же папке, что и файл с кодом. Название файла в приложенном к статье файле должно быть "Шаблон.doc". Но его так же можно изменить, не забыв изменив его в коде в этой строке:

'имя шаблона Word с основным текстом и метками
Const sWDTmpl As String = "Шаблон.doc"

В общем-то, если хоть чуть-чуть разбираетесь, то поменять можно многое. А для тех, кто не разбирается достаточно будет просто создавать метки в файле Word и обозначать ими столбца в таблице Excel. Количество столбцов и строк в таблице код определяет автоматически и при изменении размеров таблицы ничего изменять не надо. Главное, чтобы метки находились в первой строке, вторая строка - заголовок(необязательно), а с третьей строки начинаются данные, которые и используются для наполнения шаблонов.
Скачать пример:

  Автосоздание бланков Word из таблицы Excel.zip (37,6 KiB, 1 866 скачиваний)

Примеры работы с тем же Outlook можно посмотреть в моих статьях:
Как отправить письмо из Excel?
Сохранить вложения из Outlook в указанную папку


Статья помогла? Поделись ссылкой с друзьями!
  Плейлист   Видеоуроки

Поиск по меткам

Access apple watch Multex Power Query и Power BI VBA управление кодами Бесплатные надстройки Дата и время Записки ИП Надстройки Печать Политика Конфиденциальности Почта Программы Работа с приложениями Разработка приложений Росстат Тренинги и вебинары Финансовые Форматирование Функции Excel акции MulTEx ссылки статистика
Обсуждение: 59 комментариев
  1. Александр:

    Большое спасибо автору!!!! Очень долго бился над эти вопросом!!!

  2. Фася:

    Огромнейшее спасибище!

  3. Анастасия:

    здравствуйте, возник вопрос, как сделать так, чтобы файл не открывался, а создавался?

  4. Caleb:

    Огромное спасибо за совет полного указания приложения. Теперь excel автоматически подсказывает продолжение строки. Я смотрю на записаный макрос в word'е и передираю его в макрос excel.

  5. Юрий:

    Добрый день Дмитрий.
    Воспользовался Вашим кодом (перенос данных с excel d word). Но мне нужно скопированный диапазон скопировать в Word не в первую строку ,а ниже . У меня слева на листе ворд логотип, а справа реквизиты. Т.е. лист сверху заполнен. Какие изменения нужно сделать в коде. Спасибо.

  6. Тимофеев:

    к Автокад тоже бы в статью обращение

  7. Валерий:

    Подскажите, пожалуйста как копировать свыше 255 символов

  8. Andrey854:

    Огромнейшее спасибо автору!!!! Но у меня возникла ситуация, когда файл экселя и шаблон ворд находятся на флэшке в разных папках, и т.к. флэшка может иметь разное буквенное обозначение диска, то задать путь к шаблону ворд не получается. Подскажите есть ли какое- либо решение, как прочитать путь к родительской папке эксель, и через него задать путь к шаблону ворд. Заранее спасибо.

    • Andrey854, в принципе в коде это уже есть(если мы говорим о файлах из архива). Там есть строки:

      'путь к папке с файлом кода
          'здесь же должен лежать файл шаблона Word
          sPath = ThisWorkbook.Path

      как видите - sPath = ThisWorkbook.Path - это и есть путь к папке с файлом Excel. Если правильно понял вопрос, конечно.

      • Andrey854:

        В самом начале макроса у Вас написано:
        Sub ReplaceInWord()
        'имя шаблона Word с основным текстом и метками
        Const sWDTmpl As String = "Шаблон.doc"
        например: файл ворд находиться в папке Шаблоны и имеет путь: X:\шаблоны\шаблон.doc, а эксель файл располагется по пути X:\примеры\Иванов\Tips_Macro_FillWordTemplate.xls - где X может принимать любую букву, так как на разных компьютерах флэшка может принимать разное значение диска. И получается в макросе я не могу напрямую задать расположение шаблона, только сначала определить путь до файла эксель, выделить буквенное обозначение диска, присвоить его переменной и уже потом через переменную с добавлением имени папки указать путь к шаблону. Может конечно я некорректно выражаюсь,если скажите то могу и на форуме задать вопрос.

        • Андрей, либо я не понимаю, что Вы хотите, либо Вы не понимаете принцип. Почему нельзя помещать нужный шаблон в ту же папку, что сам файл Excel и заполнять его без всяких этих проблем?
          Я указал, что sPath - это путь к папке с файлом Excel. Если проблема в том, чтобы выдернуть имя диска - то я её точно не вижу.

          sPath = Left(sPath,2) 'получили имя диска
          sPath = sPath & "шаблоны" 'добавили путь к шаблонам

          т.е. должно в целом получиться так:

              sPath = ThisWorkbook.Path
              sPath = Left(sPath, 2)          'получили имя диска
              sPath = sPath & "шаблоны"     'добавили путь к шаблонам
              'добавляем разделитель папок, если его нет
              sPath = IIf(Right(sPath, 1) = Application.PathSeparator, "", sPath & Application.PathSeparator)
              'полный путь к файлу шаблона
              sWDTmplFullName = sPath & sWDTmpl

          чем такое решение проблемы не подходит? Получить как-то иначе путь к шаблонам, не вижу другого решения, не имея понятия о принципах формирования пути к папке с ними. Только получать имя текущего диска и дописывать статичный путь. Другой вариант только указывать имя файла Word через диалоговое окно при каждом заполнении шаблонов. Статья по вызову такого диалога есть на сайте.
          И да, лучше создать тему на форуме - здесь как-то не самое удобное место обсуждать конкретную проблему.

  9. Георгий:

    Дмитрий, добрый день! Перенос данных Excel-Word-Прекрасная работа! БРАВО!!!
    Один маленький вопрос: а как в Вашем примере сделать так, чтобы вновь созданные файлы Word сохранялись не в разных папках, а в одной (можно специально созданной для этого). Сам я делаю первые попытки в VBA, учусь вот на Ваших примерах и объяснениях. Приведите , пожалуйста, пример решения этой задачи. Заранее благодарю.

    • Георгий, в коде вроде есть комментарии - не так уж сложно разобраться :) Есть такой блок:

          'создаем папку для сохранения создаваемых файлов Word
          sToSavePath = sPath & Format(Now, "YYYY_MM_DD hh_mm")
          If Dir(sToSavePath, 16) = "" Then
              MkDir sToSavePath
          End If

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

      sToSavePath = "C:Desktop" 'свой полный путь к имеющейся на ПК папке
  10. Леонид:

    Добрый день! Подскажите пожалуйста как правильно макросом из Excel найти определенную таблицу, выделить ее и скопировать в шаблон ворда на закладку. Что бы вставилась как картинка по размеру листа ворд. Никак проблему не могу решить с форматированием (выходит за области страницы). Спасибо.

    • Леонид, с таким вопросом Вам на форум(https://www.excel-vba.ru/forum/index.php). Потому что по одному описанию ничего конкретного сказать нельзя. Особенно в части "определенной таблицы". Кем или чем она определена? Как её найти, если нет никакого описания параметров, по которым её искать? :) Размер листа в Word тоже отдельная история. Самое правильное - готовить таблицу так, чтобы можно было скопировать её как картинку и после этого она помещалась на лист заранее подготовленного шаблона Word без дополнительных манипуляций(за исключением разве что подгонки ширины-высоты). Если вставлять как именно таблицу - надо работать с конкретным шаблоном и подгонять все это кодом уже после вставки.

Поделитесь своим мнением

Комментарии, не имеющие отношения к комментируемой статье, могут быть удалены без уведомления и объяснения причин. Если есть вопрос по личной проблеме - добро пожаловать на Форум


Для оформления сообщений Вы можете использовать следующие тэги:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

Тренинги

Заказать
Юридическая информация

Использование материалов сайта

Политика Конфиденциальности

ИП Щербаков Дмитрий Валентинович
ОГРНИП: 318502700083307
ИНН: 504013350772

Наши партнеры

Перейти

Счетчики

Рейтинг@Mail.ru Яндекс.Метрика
© 2024 Excel для всех   Войти