Appword as word application ошибка библиотеки

Обновлено: 05.07.2024

krosav4ig, здравствуйте.

А почему бы не обратиться к полю по имени? Почему бы посреди кода не сделать так:

krosav4ig, здравствуйте.

А почему бы не обратиться к полю по имени? Почему бы посреди кода не сделать так:

А почему бы не обратиться к полю по имени? Почему бы посреди кода не сделать так:

[/vba] Автор - Rioran
Дата добавления - 23.06.2014 в 17:51 Rioran, здравствуйте, спасибо, что отозвались, но к сожалению предложенный вами код не решит мою проблему. дело в том, что в примере поля с таким кодом ,т.е. состоят из нескольких полей, вложенных друг в друга. Эти поля будут использоваться для формирования документов по шаблону. Необходимо во всех полях заменить имя атрибута на его значение. В рабочем шаблоне таких полей может быть очень много, атрибутов еще больше, и уровней вложенности может быть больше. Есть даже поле, в котором есть 2 надписи, одна из которых должна выводиться при совпадении определеного условия (в каждой из этих надписей находится таблица в которой так же есть вычисляемые поля).
как я ни пытался, произвести замену во всех полях без потери работоспособности формул в полях у меня не получается. В примере нужно заменить "Первый" на "Третий". Текст заменяется, но скобки полей, которые внутри поля заменяются на ^0019 и ^0021 и поле перестает правильно вычисяться. Rioran, здравствуйте, спасибо, что отозвались, но к сожалению предложенный вами код не решит мою проблему. дело в том, что в примере поля с таким кодом ,т.е. состоят из нескольких полей, вложенных друг в друга. Эти поля будут использоваться для формирования документов по шаблону. Необходимо во всех полях заменить имя атрибута на его значение. В рабочем шаблоне таких полей может быть очень много, атрибутов еще больше, и уровней вложенности может быть больше. Есть даже поле, в котором есть 2 надписи, одна из которых должна выводиться при совпадении определеного условия (в каждой из этих надписей находится таблица в которой так же есть вычисляемые поля).
как я ни пытался, произвести замену во всех полях без потери работоспособности формул в полях у меня не получается. В примере нужно заменить "Первый" на "Третий". Текст заменяется, но скобки полей, которые внутри поля заменяются на ^0019 и ^0021 и поле перестает правильно вычисяться. krosav4ig ,т.е. состоят из нескольких полей, вложенных друг в друга. Эти поля будут использоваться для формирования документов по шаблону. Необходимо во всех полях заменить имя атрибута на его значение. В рабочем шаблоне таких полей может быть очень много, атрибутов еще больше, и уровней вложенности может быть больше. Есть даже поле, в котором есть 2 надписи, одна из которых должна выводиться при совпадении определеного условия (в каждой из этих надписей находится таблица в которой так же есть вычисляемые поля).
как я ни пытался, произвести замену во всех полях без потери работоспособности формул в полях у меня не получается. В примере нужно заменить "Первый" на "Третий". Текст заменяется, но скобки полей, которые внутри поля заменяются на ^0019 и ^0021 и поле перестает правильно вычисяться. Автор - krosav4ig
Дата добавления - 24.06.2014 в 04:40 Есть даже поле, в котором есть 2 надписи, одна из которых должна выводиться при совпадении определеного условия

Неужели речь о вычислениях внутри Word? What a shame. В таком случае простой вариант, наверно, не подойдёт:

[/vba]
Если вывести все изменяемые тексты за пределы коллекции .shapes (а НЕ изменяемые наоборот - загнать туда), то можно жахнуть ядерной бомбой:

With Selection.Find
.Text = "1500 нет"
.Replacement.Text = "1200 да"
.Wrap = wdFindContinue
.Execute Replace:=wdReplaceAll
End With

[/vba]
Если бы всё было загнано в таблицы, можно было бы пользоваться логическими проверками. Подсказку, как это реализовать, можно найти здесь. С поиском значений по строкам и столбцам всех таблиц документа Word с помощью обращений к документу типа:

[/vba]
Что-то из перечисленного наводит Вас на праведную мысль? Есть даже поле, в котором есть 2 надписи, одна из которых должна выводиться при совпадении определеного условия

Неужели речь о вычислениях внутри Word? What a shame. В таком случае простой вариант, наверно, не подойдёт:

[/vba]
Если вывести все изменяемые тексты за пределы коллекции .shapes (а НЕ изменяемые наоборот - загнать туда), то можно жахнуть ядерной бомбой:

With Selection.Find
.Text = "1500 нет"
.Replacement.Text = "1200 да"
.Wrap = wdFindContinue
.Execute Replace:=wdReplaceAll
End With

[/vba]
Если бы всё было загнано в таблицы, можно было бы пользоваться логическими проверками. Подсказку, как это реализовать, можно найти здесь. С поиском значений по строкам и столбцам всех таблиц документа Word с помощью обращений к документу типа:

[/vba]
Что-то из перечисленного наводит Вас на праведную мысль? Rioran Есть даже поле, в котором есть 2 надписи, одна из которых должна выводиться при совпадении определеного условия

Неужели речь о вычислениях внутри Word? What a shame. В таком случае простой вариант, наверно, не подойдёт:

[/vba]
Если вывести все изменяемые тексты за пределы коллекции .shapes (а НЕ изменяемые наоборот - загнать туда), то можно жахнуть ядерной бомбой:

With Selection.Find
.Text = "1500 нет"
.Replacement.Text = "1200 да"
.Wrap = wdFindContinue
.Execute Replace:=wdReplaceAll
End With

[/vba]
Если бы всё было загнано в таблицы, можно было бы пользоваться логическими проверками. Подсказку, как это реализовать, можно найти здесь. С поиском значений по строкам и столбцам всех таблиц документа Word с помощью обращений к документу типа:

[/vba]
Что-то из перечисленного наводит Вас на праведную мысль? Автор - Rioran
Дата добавления - 24.06.2014 в 09:36 Rioran, спасибо, пока все это навело меня на такую мысль
[vba]

Dim i&, s$, s1$, s2$, zz&

s1 = "Первый"
s2 = "Третий"

.Find.Execute
If .Find.Found Then
.Find.Execute Replace:=2
End If
End With

остался 1 вопрос
хотелось бы избавиться от строки [vba]

[/vba] в цикле, но если ее убрать, то поля в надписях не обновляются. Как с этим бороться? Rioran, спасибо, пока все это навело меня на такую мысль
[vba]

Dim i&, s$, s1$, s2$, zz&

s1 = "Первый"
s2 = "Третий"

.Find.Execute
If .Find.Found Then
.Find.Execute Replace:=2
End If
End With

остался 1 вопрос
хотелось бы избавиться от строки [vba]

[/vba] в цикле, но если ее убрать, то поля в надписях не обновляются. Как с этим бороться? krosav4ig

Вы сами написали макрос и кому-то выслали. Макрос хороший и рабочий. Вы сами проверили и перепроверили. Но тут Вам сообщают - "Макрос не работает". Выдает ошибку - Can't find project or library. Вы запускаете файл - нет ошибки. Еще раз - нет. Как ни пытаетесь, какие данные не подсовываете, а ошибки такой нет. Вы уверены, что файл рабочий полностью(и верно - ведь у Вас работает), а Вам пытаются доказать обратное. Вы начинаете долго объяснять как пользоваться, что делать и т.д. и т.п. Ошибка не исчезает. Что делать-то? В чем проблема? Даже офис переустановили - у Вас работает, у них нет. А проблема проста: как и любой программе, VBA нужно иметь свой набор библиотек и компонентов, посредством которых он взаимодействует с Excel(и не только). И в разных версиях Excel эти библиотеки и компоненты могут различаться. И когда Вы делаете у себя программу, то VBA ставит ссылку(или же Вы сами) на какой-либо компонент либо библиотеку, которая может отсутствовать на другом компьютере. Вот тогда и появляется эта ошибка. Что же делать? Все очень просто:

  1. Открываете редактор VBA
  2. Идете в Tools-References
  3. Находите там все пункты, напротив которых красуется MISSING. Снимаете с них галочки.
  4. Жмете Ок.
  5. Сохраняете файл.

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

  • Visual Basic for application(эту ссылку Вы попросту не сможете отключить);
  • Microsoft Excel XX.0 Object Library(вместо X версия приложения - 12, 11 и т.д.)-эту ссылку Вы не сможете отключить;
  • Microsoft Forms X.0 Object Library(эту ссылку Вы не сможете отключить);
  • OLE Automation(хотя она тоже не нужна - но и вреда никакого).

Может я перечислил не все - но эти точно имеют полную совместимость между разными версиями Excel.

Еще, для автоматического поиска и отключения ошибочных ссылок на такие библиотеки можно делать и макросом:

Sub Remove_MISSING() Dim oReferences As Object, oRef As Object Set oReferences = ThisWorkbook.VBProject.References For Each oRef In oReferences If (oRef.IsBroken) Then oReferences.Remove Reference:=oRef Next End Sub

Но для работы этого макроса необходимо:

  1. проставить доверие к проекту VBA:
    Excel 2010-2019 - Файл-Параметры-Центр управления безопасностью-Параметры макросов-поставить галочку "Доверять доступ к объектной модели проектов VBA"
    Excel 2007 - Кнопка Офис-Параметры Excel-Центр управления безопасностью-Параметры макросов-поставить галочку "Доверять доступ к объектной модели проектов VBA"
    Excel 2003 - Сервис - Параметры-вкладка Безопасность-Параметры макросов-Доверять доступ к Visual Basic Project
  2. проект VBA не должен быть защищен.

Так же Can't find project or library возникает если у Вас просто не подключена какая-либо библиотека, которая используется в коде. Тогда не будет MISSING. Надо просто определить, в какую библиотеку входит константа, объект или свойство, которое выделяет редактор при выдаче ошибки, и подключить эту библиотеку.
Например, есть такой кусок кода:

Иногда бывает необходимо перенести что-то из 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, 5 668 скачиваний)


В файле-примере, приложенном к данной статье, в комментариях к коду есть несколько добавлений. Например, как вставить текст из ячеек в определенные закладки Word-а и как добавить новый документ, а не открывать уже имеющийся. Так же так есть код проверки - открыто ли приложение Word в данный момент. Порой это тоже может пригодиться, чтобы работать с запущенным приложением Word, а не создавать новое:

В принципе, активировать или вызвать(если закрыто) другое приложение Офиса можно одной строкой:

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 и без явного указания приложения будет относится к приложению, в котором записано.

Tips_Macro_OpenWord.xls (49,5 KiB, 5 668 скачиваний)

А в архиве ниже - практически готовое решение заполнения всевозможных бланков Word из Excel. Как это работает. У нас есть таблица Excel с данными для заполнения бланков заявлений на пособия:

Обращаю внимание, что в первой строке расположены метки. Они нужны для того, чтобы код мог понять значения какого столбца в какое место шаблона Word должны попасть. А в самом шаблоне Word мы должны проставить эти самые метки:

Фигурные скобки сделаны для того, чтобы код 100% искал и заменял только метку в шаблоне, исключая при этом замену случайного текста вне скобок(ведь слово "Должность" может встречаться и само по себе).
А здесь я схематично привел то, как будут происходить замены:

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

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

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

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

Нужно открыть документ Ворда из Ехеля…перерыл 400страниц этого сайта…вот ,что нашел…но ничего не работает …не открывает…в чем фокус.


Уважение: +0/-0
Offline

полному пути?
Posted by Chas under Visual Basic, Пост-обзор
а если там шаблон будет не найден, то открывать его в одной папке где сам файл excel?
EducatedFool

Set oWord = CreateObject("Word.Application")

If Dir("C:\моя папка\" & Filename$) <> "" Then Set oDoc = oWord.Documents.Add("C:\моя папка\" & Filename$)

If Dir(ThisWorkbook.Path & Filename$) <> "" Then Set oDoc = oWord.Documents.Add(ThisWorkbook.Pa th & "\" & Filename$)

If oDoc Is Nothing Then MsgBox "Файл " & Filename$ & " не найден!", vbCritical, "Нет шаблона": Exit Sub

Ваши желания
End Sub


Sub FillingWordFile()
Dim WD
Dim XL As Excel.Application
Set WD = CreateObject("Word.Application")
WD.Visible = True
WD.Documents.Open Filename:=Application.ThisWorkbook. Path & "\название файла.doc"

Range("адрес ячейки").Copy
WD.ActiveDocument.Bookmarks.Item("н азвание закладки").Range.Paste

End Sub
-----------------------------------------------------------------
Из всего этого выбираю такой код….открытия документа Ворд из Ехеля…но ничего не открывается …в чем может быть причина?
Sub МакросОткрытияДокуиента()
'
' МакросОткрытияДокуиента
'Dim AppWord As Word.Application

Set AppWord = CreateObject("Word.Application")
AppWord.Visible = True
AutoOpen = " C:\Documents and Settings\т\Мои документы\ Макрос переноса 1 строки.docx"
AppWord.Documents.Add
End Sub
--------------------------------------------------------------------
и этот вариант пробую … но ничего не открывается…
Sub Макрос ОТКРЫТИЯшаблона()

Set oWord = CreateObject("Word.Application")

If Dir("C:\ Documents and Settings\т\Рабочий стол\КОНДУИТ \" & Filename$) <> "" Then Set oDoc = oWord.Documents.Add("C:\ Documents and Settings\т\Рабочий стол\КОНДУИТ \" & Filename$)

If Dir(ThisWorkbook.Path & Filename$) <> "" Then Set oDoc = oWord.Documents.Add(ThisWorkbook.Pa th & "\" & Filename$)

If oDoc Is Nothing Then MsgBox "Файл " & Filename$ & " не найден!", vbCritical, "Нет шаблона": Exit Sub

Читайте также: