Связь между экземплярами Microsoft Office в VBA - PullRequest
0 голосов
/ 19 февраля 2019

Я пытаюсь создать сценарий VBA в экземпляре A для копирования базовых элементов в экземпляр B Word, созданный программой уровня с временным и непредсказуемым именем, поэтому я не могу использовать GetObject (Path,) чтобы получить этот экземпляр с путем, потому что у меня его нет.

Мое временное решение - PowerShell, выполняющий эту команду из экземпляра A, чтобы получить имя всех Windows с «Word» в заголовке.... и сохранить его в переменной VBA, чтобы определить, является ли имя другим экземпляром, отличным от экземпляра A:

Get-Process |Where-Object {$_.mainWindowTitle -like "*Word*"} |format-table mainwindowtitle 

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

Я пытался безобразно, как это, в VBA, чтобы безуспешно пересекать различные экземпляры:

Sub GetAllInstance()
Dim WordApp As Word.Application, wordInstance As Object
Set WordApp = GetObject(, "Word.Application")

For Each wordInstance In WordApp
    MsgBox (wordInstance)
Next wordInstance

End Sub

И Немедленная команда показывает мне, чтоGetObject имеет информацию только о моем экземпляре A, в результате чего только 1 документ открывается, даже если открыто 3 экземпляра:

?WordApp.Documents.Count
1

EDIT20/02:

С хорошими советами Синди я изменил свой подход, пытаясь работать с процессом, я успешно обнаружил различные PID моих запущенных экземпляров с кодом ниже:

Sub IsProcessRunning()
    Dim process As String
    Dim objList As Object
    Dim xprocess As Variant
    Dim wdApp As Word.Application

    process = "Word.exe"

    Set objList = GetObject("winmgmts:") _
        .ExecQuery("select ProcessID from win32_process where name='" & process & "'")


For Each xprocess In objList
    Debug.Print xprocess.ProcessID
    AppActivate (xprocess.ProcessID)
    Set wdApp = GetObject(, "Word.Application")
    Debug.Print wdApp.Workbooks(1).Name
Next xprocess

End Sub

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

1 Ответ

0 голосов
/ 21 февраля 2019

Наконец-то нашли решение!С помощью приведенного ниже кода, поскольку я знаю, где мое третье программное обеспечение генерирует временный файл с новым экземпляром, я ищу имя файла с помощью HWND и GetWindowText из библиотеки user32.Это позволяет мне назначать GetObject, используя полный путь, и осуществлять взаимодействие между моими двумя документами из двух отдельных экземпляров.Спасибо Синди и Матье за ​​помощь:

' API declaration
Const GW_HWNDNEXT = 2
Private Declare PtrSafe Function GetWindow Lib "user32" (ByVal hWnd As Long, ByVal wCmd As Long) As Long
Private Declare PtrSafe Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Private Declare PtrSafe Function GetClassName Lib "user32" Alias "GetClassNameA" (ByVal hWnd As Long, ByVal lpClassName As String, ByVal nMaxCount As Long) As Long
Private Declare PtrSafe Function GetWindowText Lib "user32" Alias "GetWindowTextA" (ByVal hWnd As Long, ByVal lpString As String, ByVal cch As Long) As Long

Private Sub CommandButton1_Click()

    Dim openDoc As Document, sourceDoc As Document, targetDoc As Object
    Dim hWndThis As Long
    Dim sTitle As String
    Dim xTable As Table

    ''' INITIALIZATION '''

    'Assign the source Document
    Set sourceDoc = ActiveDocument

    'Detect each instance by Window Name, then assign it to different object
    hWndThis = FindWindow(vbNullString, vbNullString)
        While hWndThis
            sTitle = Space$(255)
            sTitle = Left$(sTitle, GetWindowText(hWndThis, sTitle, Len(sTitle)))

                If sTitle Like "*tmp*.DOC*" Then
                    FileToOpen = Left(sTitle, Len(sTitle) - 8)
                    Set targetDoc = GetObject("C:\Users\xxxxx\AppData\Local\Temp" & "\" & FileToOpen)
                    GoTo EndLoop:
                End If
            hWndThis = GetWindow(hWndThis, GW_HWNDNEXT)
        Wend
    EndLoop:
End Sub
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...