Excel это не сложно

Основные форумы => Вопросы по Excel и VBA => Тема начата: solmir от 19.11.2013, 08:00:52



Название: Как увидеть книгу при нескольких запущенных экзеплярах Excel
Отправлено: solmir от 19.11.2013, 08:00:52
Доброго времени суток, форумчане. Помогите решить проблему. Имеется книга с кодом
Код: (vb)
Sub test1()
    Dim Wb As Workbook
    For Each Wb In Workbooks
        Debug.Print Wb.Name
    Next Wb
End Sub

Код видит все книги открытые в одном приложении Excel.Application
Обрабатываемый файл создаётся внешним приложением ИМХО аналогично методу CreateObject (, "Excel.Application") (New), при этом в диспетчере задач создаётся еще один или несколько объектов EXCEL.EXE в зависимости от кол-ва экспортируемых документов. Подскажите код, чтобы перебирать все экземляры excel и искать все книги.
P.S. Уверен код несложный, пробовал следующее:
Код: (vb)
Sub test2()
    Dim Ap As Excel.Application, Wb As Workbook
    For Each Ap In ' вот здесь загвоздка не могу понять среди чего перебирать...
        For Each Wb In Workbooks
            Debug.Print Wb.Name
        Next Wb
    next ...
End Sub


Название: Re:Как увидеть книгу при нескольких запущенных экзеплярах Excel
Отправлено: kuklp от 19.11.2013, 09:21:51
P.S. Уверен код несложный...
Та да! Только через АПИ функции и то под вопросом. Как убить процессы знаю, а как перехватить управление, это вопрос... :( И даже если это возможно через АПИ, не факт, что будет работать под ВБА.


Название: Re:Как увидеть книгу при нескольких запущенных экзеплярах Excel
Отправлено: doober от 19.11.2013, 11:54:05
Цитировать
P.S. Уверен код несложный...
Как вы считаете?

Цитировать
И даже если это возможно через АПИ, не факт, что будет работать под ВБА

Серега,ты не прав,работает.
Учтены версии англ и рус

Код: (vb)
Private Declare Function AccessibleObjectFromWindow& Lib "oleacc.dll" _
               (ByVal Hwnd&, _
                ByVal dwId&, _
                riid As GUID, _
                xlwb As Object)
 Public Declare Function FindWindowEx Lib "user32" Alias "FindWindowExA" _
                                     (ByVal hWnd1 As Long, _
                                      ByVal hWnd2 As Long, _
                                      ByVal lpsz1 As String, _
                                      ByVal lpsz2 As String) _
                                      As Long
 
    Declare Function SendMessage Lib "user32" Alias "SendMessageA" _
(ByVal Hwnd As Long, ByVal wMsg As Integer, _
ByVal wParam As Integer, ByVal lParam As Integer) As Integer
    Declare Function ShowWindow Lib "user32" _
(ByVal Hwnd As Long, ByVal y As Integer) As Boolean

Type GUID
    Data1 As Long
    Data2 As Integer
    Data3 As Integer
    Data4(0 To 7) As Byte

End Type
Private Sub SetGUID(ByRef ID As GUID, Optional VerRus As Boolean = True)
If VerRus Then


With ID
        .Data1 = &H20400
        .Data2 = &H0
        .Data3 = &H0
        .Data4(0) = &HC0
        .Data4(1) = &H0
        .Data4(2) = &H0
        .Data4(3) = &H0
        .Data4(4) = &H0
        .Data4(5) = &H0
        .Data4(6) = &H0
        .Data4(7) = &H46

    End With

Else


With ID
        .Data1 = &H90140000
        .Data2 = &H16
        .Data3 = &H409
        .Data4(0) = &H0
        .Data4(1) = &H0
        .Data4(2) = &H0
        .Data4(3) = &H0
        .Data4(4) = &H0
        .Data4(5) = &HF
        .Data4(6) = &HF1
        .Data4(7) = &HCE

    End With
  End If
End Sub
    Sub XLref()
    
     Dim xl As Excel.Application
        Dim ob As Object
        Dim XLMAIN, XLDESK, EXCEL7 As Long
        Dim G As GUID
        SetGUID G
        XLMAIN = FindWindowEx(0, 0, "XLMAIN", vbNullString)
        While XLMAIN <> 0
            XLDESK = FindWindowEx(XLMAIN, 0, "XLDESK", vbNullString)
            EXCEL7 = FindWindowEx(XLDESK, 0, "EXCEL7", vbNullString)
            If EXCEL7 <> 0 Then
                ShowWindow XLMAIN, 8
                 ShowWindow XLDESK, 8 'SW_SHOWNA=8
                AccessibleObjectFromWindow EXCEL7, &HFFFFFFF0, G, ob
              Set xl = ob.Application
        For Each Wb In xl.Workbooks
            Debug.Print Wb.Name
        Next Wb
                          
            End If
            XLMAIN = FindWindowEx(0, XLMAIN, "XLMAIN", vbNullString)
        Wend
            
    End Sub



Название: Re:Как увидеть книгу при нескольких запущенных экзеплярах Excel
Отправлено: kuklp от 19.11.2013, 11:59:46
Серег, а в чем не прав? Насчет буде ли работать под ВБА - было только предположением. А насчет сложности и АПИ - утверждением ;)
В любом случае - спасибо. Утяну в норку :)


Название: Re:Как увидеть книгу при нескольких запущенных экзеплярах Excel
Отправлено: doober от 19.11.2013, 12:09:56
Цитировать
Насчет буде ли работать под ВБА
Это так,к слову.Типа,Борис,ты не прав ;D


Название: Re:Как увидеть книгу при нескольких запущенных экзеплярах Excel
Отправлено: kuklp от 19.11.2013, 12:12:46
А то я не понял :) Но как не побурчать...


Название: Re:Как увидеть книгу при нескольких запущенных экзеплярах Excel
Отправлено: solmir от 19.11.2013, 14:35:40
to kuklp: я мог предполагать что понадобиться использование API, но предполагал что будет такой код!
to doober: СНИМАЮ ШЛЯПУ!!! Сам бы никогда не написал такой код... Попытаюсь разобраться, однако, если не сложно, можете описать ключевые детали данного кода. Код работает как и требовалось!


Название: Re:Как увидеть книгу при нескольких запущенных экзеплярах Excel
Отправлено: doober от 19.11.2013, 22:01:37
Ключевые моменты.
Чтобы  достучаться до Excel,надо знать его  Guid   {"{00020400-0000-0000-C000-000000000046}"}
преобразуем его
Код: (vb)
      .Data1 = &H20400  
        .Data2 = &H0 
        .Data3 = &H0 
        .Data4(0) = &HC0 
        .Data4(1) = &H0 
        .Data4(2) = &H0 
        .Data4(3) = &H0 
        .Data4(4) = &H0 
        .Data4(5) = &H0 
        .Data4(6) = &H0 
        .Data4(7) = &H46 


Надо пройти от родителя до XLMAIN до самого  младшенького  потомка.

XLMAIN  XLDESK EXCEL7.
определение этой цепочки и вызывает трудности,если не знать,как подсмотреть эти имена классов
Краткое видео (http://yadi.sk/d/pqoQuPb_CyEcx),программа для просмотра (http://yadi.sk/d/p9cqI_zC7lwHk)
остальное уже дело техники,по функйиям АПИ ничего сложного нет.
Хендл мамы есть,находим дитя ее. ;D