Всем Привет! Как можно запустить/открыть файл в текущей сессии Excel (при условии, что открыто несколько сессий, и текущая - не основная (не первая)) через
- (запускается по умолчанию в первой, соответственно файл недоступен в текущей) Пока не пойму, есть ли вообще такая возможность, т.к. скрипт должен знать из какой сессии я запускаю его и если этот файл открывается Excel (может быть и другие типы файлов), открыть в текущей сессии (где скрипт запускается). Зайти как-то через ProcessID, но нужно знать, о том какой прогой по умолчанию откроется нужный файл (если Excel - в текущий процесс, другой - по умолчанию как есть). Есть идеи?
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
Доброе время суток. У Сергея в цикле While XLMAIN <> 0 перебираются все окна с таким заголовком. Далее кодом
Код
AccessibleObjectFromWindow EXCEL7, &HFFFFFFF0, G, ob
Set xl = ob.Application
получается ссылка на очередной объект Excel.Application, который вы можете по xl.Hwnd сопоставить в текущим нужным процессом и через xl.Workbook.Open выполнить открытие файла. Сергей, спасибо. Уже видел подобный код на просторах, но до ума довести не хватило способностей.
открывается именно в первой сессии (из второй, третий и т.д.). Как к скрипту прикрутить запуск нужного документа в нужной сессиии вот в чем вопрос. Процесс по-моему можно вычислить еще и так (в топике это свойство отметил, но пока не пользовался):
Код
'Объект WshShell:ProcessID
'Возвращаемое значение: идентификатор запущенного процесса (PID).
'Замечание: только чтение.
'Пример:
Set WshShell = CreateObject("WScript.Shell")
Set WshExec = WshShell.Exec("notepad")
WScript.Sleep 2000
WshShell.AppActivate WshExec.ProcessID
WshShell.SendKeys "0123456789"
Виталий, пропустил, что вы выполняете из vbscript. Хотелось бы более подробного изложения задачи. Пока подозреваю, что вам, скорее всего, потребуется написать собственный COM-объект, реализующий код Сергея, которым можно будет воспользоваться для получения нужного экземпляра Excel. Скрипту же передавать Application.Hwnd того процесса Excel, который вы определяете как текущий.
Задача выглядит несложной на первый взгляд: из VBA запускать/открывать разные файлы приложением назначенным "по умолчанию" для этого типа файла, соответственно файлы Excel открывать в той же сессии, из которой этот код выполняется. Всё )
Тогда, на мой взгляд, анализировать расширение файла. Если это xls, xlsx и т. д., то открывать через Workbooks.Open, иначе, как у вас, через wscript.shell
Пока решение сделал следующее: Сделал возможность выбирать опционально каким из способов открываем файл - 1. Workbooks.Open/Application.RegisterXLL - открывает в текущей сессии в Excel 2. wscript.shell - открывает в первой сессии приложением "по-умолчанию". Появилась возможность открывать, к примеру txt - excel-ем или текстовым редактором (к примеру блокнотом)