Semenalidery.com

IT Новости из мира ПК
11 просмотров
Рейтинг статьи
1 звезда2 звезды3 звезды4 звезды5 звезд
Загрузка...

Getobject word application

10.3 Объект Application

Объект Word.Application, запуск нового экземпляра Word, события объекта Word.Application

Объект Application — это само приложение Microsoft Word. Все остальные объекты Word «вложены» в этот объект. Создать этот объект — значит запустить Word на вашем компьютере. Как правило, это нам и надо (если мы создаем в формате Word из другого приложения, например, из Access). Но не забудьте — если вы запускаете Word из другого приложения Office, то необходимо добавить в ваш проект ссылку на библиотеку Microsoft Word 11.0 Object Library.

Код на запуск Word очень прост:

Dim oWord As New Word.Application

Однако, выполнив этот код из другого приложения, вы, скорее всего, даже не заметите, что у вас что-то произошло. Причины просты:

  • по умолчанию Word запускается в скрытом окне;
  • если в нем не открыт ни один документ, он тут же и закрывается (после того, как завершается создавшая его процедура).

Сделать Word видимым очень просто:

Однако возникает вопрос: а нужно ли его делать видимым? Некоторые знакомые разработчики утверждают, что не нужно. Пусть Word работает в скрытом окне, создавая требуемый документ. Когда пользователю потребуется, он этот документ откроет. Решать вам, но я предпочитаю, чтобы Word все-таки был видимым: во-первых, сразу видны все проблемы при создании документа, а, во-вторых, пользователям почему-то очень нравится, когда у них на глазах открывается Word и начинает печатать строки, которые в противном случае пришлось бы печатать им самим.

Если вы работаете с Word в скрытом окне, не забудьте после выполнения необходимых действий его закрыть (иначе он так и останется в оперативной памяти, видимый только через Task Manager). Для закрытия Word нужно вызвать его метод Quit().

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

Dim oWord As New Word.Application

Если Word уже открыт, то можно получить на него ссылку, например, при помощи такого кода:

Set oWord = GetObject(,»Word.Application»)

Однако на практике, кроме очень специальных случаев (активизация объектов OLE), такой подход по сравнению с открытием нового экземпляра Word ничего нам не дает. Наоборот, появляется дополнительный риск нечаянно испортить открытый в существующем экземпляре созданный пользователем документ или закрыть существующий экземпляр Word без сохранения пользовательских документов. Поэтому лучше создавать новый экземпляр Word.

Если же ваш код VBA выполняется в Word (то есть Word уже запущен), то объект Application создавать уже не надо. В этой ситуации он будет автоматически доступен в любой момент (чтобы в этом убедиться, достаточно впечатать в окне редактора кода Application и добавить точку). Более того, если не указано, к какому объекту относится то или иное свойство или метод, компилятор VBA в Word автоматически считает, что это свойство или метод принадлежит объекту Application. Поэтому такой код функционально одинаков:

Application.Selection.TypeText «Мой текст»

Selection.TypeText «Мой текст»

Еще один важный момент, который связан с объектом Application в Word. Для этого объекта предусмотрено большое количество удобных в использовании событий (открытие документа, выход из Word, щелчок правой кнопкой мыши, изменение документа, печать документа, сохранение документа и т.п.) Однако по умолчанию все эти события не видны. Чтобы они появились, необходимо в разделе Declarations кода формы (только формы — не модуля!) объявить объект Application с ключевым словом WithEvents, например, так:

Public WithEvents App As Word.Application

В списке объектов у нас появится новый объект App (то есть Application), для которого можно выбрать события и добавлять код в событийные процедуры точно так же, как это мы делаем для формы и элементов управления.

Thread: GetObject to open Word File

Thread Tools
Display
  • Linear Mode
  • Switch to Hybrid Mode
  • Switch to Threaded Mode

GetObject to open Word File

I have been trying to use VBA to open up a Word document. I wrote some code to do this while also checking to see whether Word was already open but I the result is that the code is continuously jumping to the MsgBox line.

Any help would be greatly appreciated!!

Public Sub Giri()
Dim wrdApp As Word.Application
Dim wrdDoc As Word.Document
Dim FileName As String
Dim myObject As Object

On Error Resume Next

Set myObject = GetObject(, «Word.Application»)

If myObject Is Nothing Then

Set wrdApp = CreateObject(«Word.Application»)

For Each wrdDoc In wrdApp

If StrComp(wrdDoc.FullName, FileName, vbTextCompare) = 0 Then

MsgBox «File already Open!»

On Error Resume Next

Set wrdApp = GetObject(, «Word.Application»)

If Err.Number <> 0 Then ‘Word isn’t already running
Set wrdApp = CreateObject(«Word.Application»)
End If

On Error GoTo 0

Set wrdDoc = wrdApp.Documents.Open(FileName)

wrdApp.Visible = True
[/vba]

PLS DO NOT PM; OPEN A THREAD INSTEAD.

1) Posting Code
[CODE]PasteYourCodeHere[/CODE]
(or paste your code, select it, click # button)

2) Uploading File(s)
Go Advanced / Attachments — Manage Attachments / Add Files / Select Files / Select the file(s) (multiple files can be selected while holding Ctrl key) / Upload Files / Done
Replace company specific / sensitive / confidential data. Include so many rows and sheets etc in the uploaded workbook to enable the helpers visualize the data and table structure. Helpers do not need the entire workbook.

3) Testing the Codes
always back up your files before testing the codes.

4) Marking the Thread as Solved
from Thread Tools (on the top right corner, above the first message)

PLS DO NOT PM; OPEN A THREAD INSTEAD.

1) Posting Code
[CODE]PasteYourCodeHere[/CODE]
(or paste your code, select it, click # button)

2) Uploading File(s)
Go Advanced / Attachments — Manage Attachments / Add Files / Select Files / Select the file(s) (multiple files can be selected while holding Ctrl key) / Upload Files / Done
Replace company specific / sensitive / confidential data. Include so many rows and sheets etc in the uploaded workbook to enable the helpers visualize the data and table structure. Helpers do not need the entire workbook.

3) Testing the Codes
always back up your files before testing the codes.

4) Marking the Thread as Solved
from Thread Tools (on the top right corner, above the first message)

The problem is that you did not reset the error to nothing after setting the application object. Another problem is that you did not set the objects to nothing. As it is, a hidden instance could be left at the end.

Here is an example:
[VBA]’http://www.mrexcel.com/forum/showthread.php?t=333200
Sub FillForm()
Dim wdApp As Object, WD As Object, rn As Long
rn = ActiveCell.Row
On Error Resume Next
Set wdApp = GetObject(, «Word.Application»)
If Err.Number <> 0 Then
Set wdApp = CreateObject(«Word.Application»)
End If
On Error GoTo 0

Set WD = wdApp.Documents.Open(ThisWorkbook.Path & «Car Information Page.doc»)

wdApp.Visible = True
With WD
.FormFields(«Brand»).Result = Cells(rn, «B»)
.FormFields(«Model»).Result = Cells(rn, «C»)
.FormFields(«Chasis»).Result = Cells(rn, «D»)
.FormFields(«Engine»).Result = Cells(rn, «E»)
.FormFields(«Color»).Result = Cells(rn, «F»)
.FormFields(«YearMonth»).Result = Cells(rn, «G»).Value & «/» & Cells(rn, «H»).Value
End With

Set WD = Nothing
Set wdApp = Nothing
End Sub[/VBA]

Как из Excel обратиться к другому приложению

Иногда бывает необходимо перенести что-то из Excel в другое приложение. Я возьму для примера Word. Например скопировать ячейки и вставить. Обычно мы это так и делаем — скопировали в Excel, открыли Word — вставили. Но сделать это при помощи кода чуть сложнее, хотя если разобраться никаких сложностей нет. Ниже приведен пример кода, который открывает 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») ‘Копируем из 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, 4 449 скачиваний)

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

Метод установки ссылки на библиотеку приложения через ToolsReferences называют еще ранним связыванием. Подобный метод позволяет создать ссылку на приложение быстрее и, как описано выше, предоставляет разработчику доступ к визуальному отображению свойств и методов объекта. Но есть существенный минус: если в своем коде Вы установите ссылку на 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(ViewImmediate 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

Читать еще:  Как установить рамки в word

Вместо Range ту же ошибку делают и с Selection(потому что Selection часто присутствует в записанных макрорекордером макросах), т.к. этот объект есть и в Excel и в Word и без явного указания приложения будет относится к приложению, в котором записано.

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

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

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

VBA Excel. Управление приложением Word

Создание нового экземпляра приложения Word из кода VBA Excel или подключение к открытому для работы с документами. Функции CreateObject и GetObject.

Работа с Word из кода VBA Excel
Часть 1. Управление приложением Word
[Часть 1] [Часть 2] [Часть 3] [Часть 4] [Часть 5]

Создание объекта Word.Application

Экземпляр приложения Word необходим для того, чтобы с его помощью создавать новые документы или открывать существующие для редактирования из кода VBA Excel.

Создать новый экземпляр объекта Word.Application можно при помощи раннего или позднего связывания, используя при позднем связывании функцию CreateObject. Подключиться к открытому экземпляру приложения Word можно только при помощи позднего связывания, используя функцию GetObject.

Раннее связывание приложения Word

Создание нового экземпляра Word.Application и присвоение ссылки на него переменной myWord:

Для раннего связывания переменной с объектом Word.Application необходимо подключить в редакторе VBA Excel ссылку на библиотеку Microsoft Word Object Library, если она не подключена. Подключается ссылка в окне «References VBAproject», перейти в которое можно через главное меню редактора: Tools–>References…

Раннее связывание позволяет при написании кода использовать лист подсказок для выбора и вставки свойств и методов привязанных объектов (Auto List Members). Если проект VBA Excel создается на заказ, то, после его завершения, раннее связывание следует заменить на позднее, так как на компьютере пользователя может не оказаться нужной библиотеки, и код работать не будет.

Позднее связывание приложения Word

Создание нового экземпляра Word.Application с помощью функции CreateObject и присвоение ссылки на него переменной myWord:

Присвоение переменной myWord ссылки на открытый экземпляр приложения Word с помощью функции GetObject:

Если открытого приложения Word нет, выполнение функции GetObject приведет к ошибке. Чтобы ее избежать, следует предусмотреть создание нового экземпляра Word.Application с помощью функции CreateObject, если открытое приложение не будет найдено (смотрите пример 3).

В программы VBA Excel, работающие с Word, следует включать обработчик ошибок.

Закрытие объекта Word.Application

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

Если перед завершением процедуры VBA Excel необходимо приложение Word закрыть, используйте метод Quit:

Если переменная не содержит ссылку на приложение (myWord = Nothing), метод Quit возвратит ошибку. Чтобы этого не произошло, перед применением метода Quit необходимо проверить наличие ссылки в переменной myWord (смотрите пример 3).

Примеры открытия и закрытия Word

Пример 1
Создаем новый экземпляр объекта Word.Application с ранним связыванием и отображаем его на экране:

Запустите код примера 1 на выполнение. Вы увидите появившийся на панели задач ярлык приложения Word. Перейдите на него и закройте приложение вручную.

Пример 2
Создаем новый экземпляр объекта Word.Application с поздним связыванием, отображаем его на экране, останавливаем программу и наблюдаем закрытие приложения методом Quit:

Запустите код примера 2 на выполнение. Закройте информационное окно MsgBox и смотрите, как исчезнет с панели задач ярлык приложения Word, созданного перед остановкой кода.

Пример 3
Пытаемся создать ссылку на открытый экземпляр приложения Word с помощью функции GetObject, а если открытого экземпляра нет, создаем новый с помощью функции CreateObject:

Строка On Error Resume Next передаст управление следующему оператору, если открытого экземпляра программы Word не существует, и выполнение функции GetObject приведет к ошибке. В этом случае будет создан новый экземпляр Word.Application с помощью функции CreateObject.

В код добавлен обработчик ошибок On Error GoTo Instr , который поможет корректно завершить программу при возникновении ошибки. А также он позволит во время тестирования не наплодить большое количество ненужных экземпляров приложения Word. Проверяйте их наличие по Диспетчеру задач (Ctrl+Shift+Esc) и удаляйте лишние.

Строка Exit Sub завершит процедуру, если она прошла без ошибок. В случае возникновения ошибки, будет выполнен код после метки Instr: .

Getobject word application

(Эта тема расположена в архиве и закрыта для обсуждения.)

Версия для печати

Т.е. ситуация обычная — имеем DLL ( сделанную в VB , но это не суть), которая может быть привязана к любым MsOffice приложениям — Access,Word,Excel .

Как в функции этой DLL получить , не передавая явно из VBA приложения (т.е., видимо, через WinAPI), объект Application, соответствующий VBA приложению , из которого вызвана эта функция.

nemetss
Хе-хе. yuniki хочет существующий экземпляр получить.
цитата (MSDN):
Returns a reference to an object provided by a COM component.

Public Function GetObject( _
Optional ByVal PathName As String = Nothing, _
Optional ByVal Class As String = Nothing _
) As Object

PathName Optional; String. The full path and name of the file containing the object to retrieve. If pathname is omitted, class is required.
Class Optional; String. A string representing the class of the object.

The Class argument has the following syntax and parts:
appname.objecttype
Class Parameters
appname Required; String. The name of the application providing the object.
objecttype Required; String. The type or class of object to create.
То, что нужно.

Да нет же ,пардон, но вы не поняли

Есть, скажем, книга в Excel и документ в Word, к каждому из них привязана через References моя DLL, и макросы вызывают некую функцию из нее, пусть MyFuncDLL, при этом эти макросы не передают в MyFuncDLL ни путь к своему приложению, ни объект Application ( или что почти все-равно — Document,WorkBook) и требуется , чтобы после вызова MyFuncDLL САМА (без GetObject, для работы которой нужен собсно путь к даному документу) получила ссылки на эти объекты — как я думаю, видимо отследив путь своего вызова, или получив активное окно Windows (считая, что вызов делает именно активное окно) и там на его основе(если это конечно возможно) — объект Application , но как конкретно я не знаю это возможно

Добавление от 26.05.2004 16:57:

короче , идеи как это сделать я изложил в посте от 25.05.2004 22:26, но вот КАК их реализовать, это я и хотел бы узнать

Добавление от 26.05.2004 23:25:

Люди . Ау.
Что — задача нереальная .

Ну во первых, если нужно практически в каждую из имеющихся функций это делать и все одно и то-же , а функцийй порядка сотни, то понятно, что это мягко говоря некрасиво

А во-вторых, нужно переделать уже имеющиеся VBA макросы, которые по умолчанию работают с активной книгой, и которые УЖЕ использованы во многих VBA-проектах, и хочется эти макросы организовать в виде DLL, где я уже ,как объяснял выше , не знаю как заставить их работать с активной книгой и переделывать ихз вызовы во многих их использующих VBA-проектах тоже ,мягко говоря трудновато, точно говоря — невзможно , с учетом уже отчуждения этих проектов (нахождения их у пользователя)

Ну тогда и почему в GetObject(«Word.Application») выходит ошибка, например, если его сделать в Excel, при открытом Word документе ( Аutomation Error — синтаксическая ошика) .
— а ну допер — запятую забыл , надо — GetObject(,»Word.Application»)

Читать еще:  Как отключить автозаполнение в excel

Уже полегче , Но все-равно — что делать, если функция DLL вызвана из одновремено открытых Word,Excel,Access приложений — как она может понять , кто ее вызывает — Word,Excel или Access приложение ( ну , или , несколько одновременно , скажем , Word документов ее вызвали ) ?

Добавление от 27.05.2004 18:40:

А я никогда и не повышаю, так. слегка, как обычно расстроился, когда не удалось быть понятым

Добавление от 27.05.2004 18:45:

И да , коль об GetObject(. ) поговрили, то КАК понять вообще — какие объекты есть в некотором априори неизвестном приложении, на которые она может сослаться , т.е. как узнать , ЧТО писать у нее в скобках для незакомого приложения?

McFirst То что нужно — и близко не то что нужно.

Автор конечно странного хочет.

Но вот перевожу подробно. БУКВАЛЬНО — он хочет БЕЗ ПЕРЕДАЧИ КАКОЙ ЛИБО ДОПОЛНИТЕЛЬНОЙ ИНФОРМАЦИИ оттрассировать из своей Dll в обратную сторону стек вызовов найти и восстановить указатель на ближайший COM объект из заданного списка типов пропуская все остальные (интересно он подозревает что лист Excel это достаточно самостоятельный COM объект и вызов dll вовсе не из Excel.Application идет).
Как иллюстрация запущенности ситуации — в макросе Word создано два объекта Exel. В каждый из которых загружена абсолютно своя информация. И в обработчике одного из них и вызывается dll. В системе в этот момент есть третий экземпляр Excel открытый пользователем. Который никого не вызывает но зато имеет фокус ввода. А в dll автору хочется получить ссылку именно на вызвавший dll экземпляр Excel.Application.

Проникся? Вот теперь и предлагай (для начала как определить что вызывает именно Excel а не Word ( стартовый процесс Word). Ну а потом уже определив вид COM объекта (а без этого никак даже предлагаемый GetObject откажется) какой именно экземпляр (и тут GetObject не поможет. Он насколько знаю берет ЛЮБОЙ существующий или делает новый ). А автору ведь нужен именно вызывавший, а не любой. Короче странного автор хочет.

yuniki — Приложение — Да, активное окно приложения — может быть (не помню). НО все это не то что тебе нужно увы.

to CrazyElk
(интересно он подозревает что лист Excel это достаточно самостоятельный COM объект и вызов dll вовсе не из Excel.Application идет). >

подозреваю, Application приведен для примера, по идее надо знать, как получать ссылки из DLL на Document,WorkBook и пр.

Короче странного автор хочет>

Что в этом странного? Если это невозможно , так и скажи и обоснуй, а «Короче странного автор хочет» ничего не объясняет, а почему автор хочет — тоже уже было от затронуто в посте от 27.05.2004 07:45 — вроде понятное желание.

Может, ты хочешь сказать , что трассировка стека вызовов в этом случае невозможна ?
Тогда — объясни почему, иначе твое высказывание — неясно.
И вообще , насчет трассировки вызовов, — это только мои догадки, а если короче , то — не знаю как, но нужно получить ссылку на тот объект, из метода(или что там получается в VBA) которого была вызвана функция DLL , не передавая эту ссылку явно в вызове.
Я повторюсь, но если это невозможно, то объясните — почему ( желание действительно, м.б. некорректным, но таковы уж желания людей , в отличие от желаний машин ) .

А если похакерить маленько?

Типа, повызывать функцию из разных объектов и смотреть, что в стеке меняется и что из этого может быть адресом COM-объекта (или как это там называется)? И на основании этого понять фиксированное число байт насколько надо назад смещаться.

Добавление от 29.05.2004 21:01:

Как вариант — не модифицируй все функции, а добавь одну — типа, «SetApplication». И вызывай её при начале работы (из startup-макроса, или из начала макроса).

Типа, dll-ку подгрузил — сообщил ей, кто же её грузил (SetApplication(Me)), и потом уже работаешь с сотней функций.

Как вариант — не модифицируй все функции, а добавь одну — типа, «SetApplication». >

Я это уже обдумывал раньше и даже написал функцию, устанавливающую/возвращающую в/из Static переменной заданный ей объект, Но это оказалось ненадежным для одновременной обработки нескольких приложений — после установки одного объекта , если приложение меняется (создается скажем новое VBA приложение из той же DLL), то нужно для обработки его менять и установленный в Static объект , потом возвращать обратно, что чревато ошибками .

McFirst
Да, обратная трассировка невозможна, поскольку Вы не знаете, сколько параметров даже у функции, которая вызвала функцию из Вашей DLL. Что уж говорить про «выше по стеку». >
Объясниете только — при чем здесь параметры, — А как же работают отладчики в среде разработки , показывающие нам стек вызовов?
Впрочем, не подумайте лишнего — я этот процесс плохо понимаю.Просто полагаю, раз в среде разработки есть показ стека вызовов, то значит и через Win API это можно сделать — вот только КАК ?

Отладчики пользуются отладочной инфой, которая была записана при компиляции. Если отладочной инфы нет — как в тех же Оффис — приложениях, то хрен чего узнаешь. Да, отладочная инфа пишется каждым компилятором в своем формате, никакого стандарта нет, ergo на WinApi можете особенно не рассчитывать.

ну что за желание запихать всё что только можно придумать в ВинАпи?

Добавление от 01.06.2004 09:03:

цитата: Я это уже обдумывал раньше и даже написал функцию, устанавливающую/возвращающую в/из Static переменной заданный ей объект, Но это оказалось ненадежным для одновременной обработки нескольких приложений А что, несколько приложений могут выполняться в одном процессе? Что за изврат.

yuniki Если это невозможно , так и скажи и обоснуй— Нашел дурака за три сольдо (с) Алексей Толстого. Если нужны доказательства почитай спецификацию COM объектов (чем они отличаются от просто функций и Dll). И правила оформления и исполнения вызовов функции и методов — можно даже из серии за 21 день даже в таком виде в эту ветку такой объем не влезет. Обида на фразу «странного хочет» пройдет сама собой наряду с желанием по быстрому получить разъяснение доказательства большой теоремы Ферма на пальцах «здесь и сейчас» про Ферма как пример, но по сути очень похожее требование.

Грубо — то ограничился спецификациями (и расширить их прямой передачей ссылки не желаешь) определяющими как и в каком виде в твою dll будут ДОСТАВЛЕННЫ данные, а также ВЫЗВАННЫ ЕЕ функции (ссылок на вызывающий COM или данных для его определения ТАМ НЕТ). А желаешь исходя из этих спецификаций получить канал управления/спецификацию вызовов в обратную сторону — и это при том что о возможности существовании такого канала в этих стандартах даже не подозревается . Однонаправленные они. В таком изложении не «странно»?

Чем это тебя привлекает понятно. Но с такими желаниями впору искать методы напрямую значения private переменных менять из внешних классов. ибо дико удобно это причем в java например вполне реальный трюк

Тебе никогда не приходило в голову что все что возникает, как бы само по себе, без усилий с твоей стороны, например указатель this, кем то туда подкладывается за тебя ( this например компилятором) а не возникает магическим образом. Вот и подумай с этой позиции. КТО, КОГДА и КАК за тебя сформировал и передал ссылку на вызывающий объект (а главное с какой стати. Вызывать то мог и не объект а например ASM блок или C функция.

Ссылка на основную публикацию
ВсеИнструменты
Adblock
detector