Этот подход может быть весьма эффективным, особенно если у вас есть стандартный файл, содержащий таблицы с данными, полученными с помощью макросов из Excel. Запустив макрос, вы сможете автоматически перенести данные в таблицы документа Word.
На днях мне было поручено разработать программу для создания отчета по SLA (Service Level Agreement — уровень сервисных соглашений). Отчет имел формат документа Word и включал множество таблиц и других данных, которые требуется заполнить на основании девяти таблиц Excel.
Применив описанный метод, я смог написать VBA-код, который работал с отдельными таблицами, собирая необходимую информацию и размещая ее в таблицах или диаграммах документа Word. Если бы я занимался переносом данных вручную, это заняло бы несколько дней, но с помощью кода вся работа была выполнена всего за пять минут.
1 2 3 4 5 6 7 8 9 10 11 12 13 14
Действие этого примера можно повторить и вручную, копируя и вставляя данные, но при этом вы должны быть очень усидчивым и трудолюбивым, чтобы проделать такую работу. Это хороший пример применения языка макросов, который наделяет пользователя большими возможностями по автоматизации задач в приложениях Microsoft Office и позволяет работать вне структуры меню программ Microsoft.
Вставка документа Word в книгу Excel (с использованием технологии OLE)
На основании чего вы предположили, что эти компоненты будут у вас? Я и уточнил, что данный вариант будет функционировать не на всех компьютерах, поскольку на большинстве из них данных библиотек нет. Если вы хотите, чтобы ваше устройство работало с ними, — не составит труда найти и установить эти компоненты (или их аналоги). Однако если вам необходимо, чтобы созданное решение работало и на других компьютерах, — забудьте о отображении документа Word на форме, так как стандартных компонентов для такой задачи в Windows / Office не существует.
Гость, 25 Окт 2014 — 11:59. #2
У меня Win 7, Office 2013, в библиотеке, компоненты DSO ActiveX Document Frame Control и Microsoft Rich Textbox Control не нашёл. Какими ещё компонентами можно воспользоваться?
Игорь (администратор сайта), 25 Окт 2014 — 02:10. #3
Конечно, можно попытаться. (но не рассчитывайте на то, что ваш макрос будет функционировать на других компьютерах)
Добавьте на форму элемент управления DSO ActiveX Document Frame Control или Microsoft Rich Textbox Control
Эти компоненты поддерживают работу с документами Word (есть и другие компоненты)
Гость, 24 Окт 2014 — 22:59. #4
Приветствую! У меня вопрос, возможно ли создать OLE поле на форме в Excel, для отображения документа Word? Спасибо!
Поклонник, 6 Ноя 2011 — 17:33. #5
Не такой знаток Excel как Вы. Спасибо что открыли для меня данную функцию в стандатных средствах
Игорь (администратор сайта), 6 Ноя 2011 — 17:26. #6
1. Возможность есть. Оплатить работу готовы?
2. Чем не устраивают встроенные возможности Excel по вставке OLE объектов?
(вкладка ВСТАВКА, группа ТЕКСТ, кнопка ОБЪЕКТ)

Фанат, 6 Ноября 2011 — 16:54. #7
Как из Excel обратиться к другому приложению
Иногда бывает необходимо перенести что-то из Excel в другое приложение. Я возьму для примера Word. Например скопировать ячейки и вставить. Обычно мы это так и делаем — скопировали в Excel, открыли Word — вставили. Но сделать это при помощи кода чуть сложнее, хотя если разобраться никаких сложностей нет.
Ниже приведен пример кода, который открывает Word, открывает в нем определенный документ, копирует данные из Excel и вставляет в открытый документ Word.
В файле-примере, приложенном к данной статье, в комментариях к коду есть несколько добавлений. Например, как вставить текст из ячеек в определенные закладки Word-а и как добавить новый документ, а не открывать уже имеющийся. Так же так есть код проверки — открыто ли приложение Word в данный момент. Порой это тоже может пригодиться, чтобы работать с запущенным приложением Word, а не создавать новое:
Sub Проверка_ОткрытогоWord() Dim объектWrdApp As Object On Error Resume Next ‘попытка получить доступ к объекту Word Set объектWrdApp = GetObject(, "Word.Application") If объектWrdApp Is Nothing Then ‘если приложение не запущено — создаем новый экземпляр Set объектWrdApp = CreateObject("Word.Application") ‘делаем приложение видимым. По умолчанию оно открывается в скрытом режиме объектWrdApp.Visible = True Else ‘приложение уже работает — выводим сообщение MsgBox "Программа Word уже запущена", vbInformation, "Проверка_ОткрытогоWord" End If End Sub
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 Открыть_ДругуюПрограмму() Application.АктивацияMicrosoftApp xlMicrosoftWord End Sub
Sub Open_AnotherApp() Application.ActivateMicrosoftApp xlMicrosoftWord End Sub
но данный метод может пригодиться только в том случае, если Вам необходимо действительно лишь активировать другое приложение, но дальше обращаться к этому приложению Вы уже не сможете.
По сути, методами CreateObject и GetObject можно обратиться к любому стороннему приложению(например Internet Explorer). Куда важнее при обращении к этим объектам знать объектную модель того приложения, к которому обращаетесь. Чтобы увидеть свойства и методы объектной модели приложения, можно в редакторе VBA подключить необходимую библиотеку, объявить переменную, назначив ей тип приложения. Покажу на примере того же Word-а. Для начала открываем меню Tools — References : Подключаем библиотеку: Затем объявляем переменную и присваиваем ей тип нужного приложения:
Подпрограмма ОткрытьWord()
Измерить objWrdApp как Word.Application
Установить objWrdApp = Новый Word.Application
objWrdApp.Visible = Истина
Конец Подпрограммы
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. Часто начинающие делают это так:
На строке Range.Copy обязательно получите ошибку от VBA, указывающую, что нужен аргумент для объекта. Можно попробовать добавить этот аргумент: Range(1).Copy. Но все равно получим ошибку. Можно, конечно, указать даже ячейки: Range("A1").Copy. Но это приведет к тому, что скопирована будет ячейка А1 активного листа Excel.
Все дело в том, что мы хотим скопировать данные из Word-а, выполняя при этом код из Excel. А у Excel тоже есть объект Range с другими аргументами. И если не указать какому приложению, листу или документу принадлежит Range, то по умолчанию он будет отнесен к тому приложению, из которого выполняется код. Т.е. к Excel. Если совсем кратко об этом — всегда надо указывать какому приложению или объекту принадлежит используемый объект или свойство. Правильно код должен выглядеть так:
Ошибку, аналогичную той, что возникает с Range, также можно встретить и с Selection, так как этот объект часто встречается в макросах, записанных с помощью макрорекордера. Стоит отметить, что данный объект присутствует как в Excel, так и в Word, и без явного указания приложения будет считаться относящимся к тому приложению, в котором велась запись.
В приложенном файле код немного отличается от представленных выше — в нем можно посмотреть как вставить текст из ячеек в определенные(созданные заранее) закладки Word-а. Это удобно для создания бланков в Word и заполнения их через Excel Скачать пример:
‘получаем фамилию с инициалами sWDDocName = .Cells(lr, 1).Value
‘считываем фамилию с инициалами sWDDocName = .Cells(lr, 1).Value
В общем-то, если хоть чуть-чуть разбираетесь, то поменять можно многое. А для тех, кто не разбирается достаточно будет просто создавать метки в файле Word и обозначать ими столбца в таблице Excel. Количество столбцов и строк в таблице код определяет автоматически и при изменении размеров таблицы ничего изменять не надо. Главное, чтобы метки находились в первой строке, вторая строка — заголовок(необязательно), а с третьей строки начинаются данные, которые и используются для наполнения шаблонов. Скачать пример:
65 комментариев
Иброхим :
Мне нужно было из таблицы в excel составит письмо в word. В таблице сотни организации и каждому нужно отдельное письмо нужно написать и сохранить в wordе. Думаю мне это поможет. Благодарю автора!
Alex23 :
Добрый день, Дмитрий! Очень полезный пример заполнения, прямо то что искал. В принципе это полностью подходит для решения моих задач, однако хотелось бы оптимизировать код. В моем случае я не перебираю циклом строки для заполнения, а иду последовательно попутно проверяя значения из листа анкеты и планомерно заполняю шаблон.
Поэтому хотелось ту часть макроса которая находит/заменяет значения в шаблоне сделать в виде функции и по мере необходимости просто подставлять значение для поиска и замены. Перенес эту часть в функцию: Public Function Repl(sFindVal As String, sReplaceVal As String) Dim objWrdApp As Object, objWrdDoc As Object, wdRange As Object ‘ Dim sFindVal As String, sReplaceVal As String Set wdRange = objWrdDoc.Range ‘çàìåíÿåì ìåòêè íà òåêñò èç ÿ÷ååê wdRange.Find.ClearFormatting wdRange.Find.Replacement.ClearFormatting With wdRange.Find .Text = sFindVal .Replacement.Text = sReplaceVal .Forward = True .Wrap = 1 ‘wdFindContinue .Format = False .MatchCase = False .MatchWholeWord = False .MatchWildcards = False .MatchSoundsLike = False .MatchAllWordForms = False End With wdRange.Find.Execute Replace:=2 ‘wdReplaceAll End Function а в макросе просто задаю значения и вызываю функцию sFindVal = .Cells(2, 1).Value sReplaceVal = .Cells(2, 3).Text Call Repl(sFindVal, sReplaceVal) В итоге макрос ошибок не выдает но и ничего не делает. Подскажите пожалуйста, на что обратить внимание, куда копать и возможно ли так сделать?
Дмитрий :
Alex23, стоит обратить внимание на то, что в моем коде переменные objWrdApp и objWrdDoc получают значения, соответствующие приложению Word и документу. В вашей функции они лишь объявлены, но не инициализированы значениями, поэтому их значение будет равно Nothing. Возможно, присвоение происходит в родительской процедуре, тогда их следует передавать как аргументы, а не создавать новые переменные в самой функции. Ошибок не возникает, потому что в родительской процедуре имеется строка On Error Resume Next.
Alex23 :
Спасибо большое за помощь, функция заработа благодаря Вашим подсказкам: Public Function Repl(sFindVal As String, sReplaceVal As String, wdRange As Object) ‘çàìåíÿåì ìåòêè íà òåêñò èç ÿ÷ååê wdRange.Find.ClearFormatting wdRange.Find.Replacement.ClearFormatting With wdRange.Find .Text = sFindVal .Replacement.Text = sReplaceVal .Forward = True .Wrap = 1 ‘wdFindContinue .Format = False .MatchCase = False .MatchWholeWord = False .MatchWildcards = False .MatchSoundsLike = False .MatchAllWordForms = False End With wdRange.Find.Execute Replace:=2 ‘wdReplaceAll Думал ну все, теперь все легко, однако столкнулся со следующей проблемой. Кодом собираю с листа достаточно большой кусок для замены, однако не срабатывает Dim PorType, PorPreambula As String PorType = .Cells(18, 3).Value тут Select и далее Case Is = "ИП" PorPreambula = .Cells(17, 3).Value , действующий на основании " ", номер ОГРНИП " _ ", (паспорт гражданина РФ серия " (ДО ЭТОГО МОМЕНТА РАБОТАЕТ, А ПОСЛЕ НИЧЕГО НЕ МЕНЯЕТ) " № " ", выданный " ", " " г., код подразделения " ", СНИЛС " ", ИНН " "), именуемый в дальнейшем Поручитель" sFindVal = "" sReplaceVal = PorPreambula Call Repl(sFindVal, sReplaceVal, objWrdDoc.Range) Причем дело не в ячейке 27-3, пробовал просто добавлять текст, тоже в итоге ничего не заменяет. Вроде переменная String позволяет хранить достаточно много символов. не могу понять в чем затык
Alex23 :
Попробовал вручную присвоить переменной PorPreambula рандомный текст (абзац строк на 7) — тот же результат. Такое впечатление что если переменная длиннее какого-то количества символов то происходит ошибка и функция просто не срабатывает
Дмитрий :
Из VBA есть ограничение: значение для поиска и для замены не должно превышать 255 символов. Поэтому для корректной работы с длинными текстами надо изобретать обходные пути.




