Показать полную графическую версию : [решено] Выяснить открыта ли книга Excel и если открыта, подключится к ней
Вот такая возникла заморока и никак не найду способ реализации.
С выяснением того, что книга открыта я придумал такой вариант:
(Get-Process excel | Select-Object -Property MainWindowTitle) -match "Заказы_2014.xls"
Но вот как подключится к открытой книге не пойму. Вариант с закрытием и последующим открытием через скрипт не подходит.
Если кто-то с книгой работает, прерывать работу нельзя.
$xl = [Runtime.Interopservices.Marshal]::GetActiveObject('Excel.Application')
$xl.Workbooks
Такой код списка открытых книг не выдает, хотя автор привел этот пример именно для этой цели.
Намучался с поиском ответа, прошу помощи.
А если не открыта — тогда что делать?
Не знаю, как у Вас, а у нас — выдаёт:
$xl = [Runtime.Interopservices.Marshal]::GetActiveObject('Excel.Application')
$xl.Workbooks | ForEach-Object -Process {$_.FullName}
E:\Песочница\0410\Книга1.xls
Ещё вариант: Converting VBScript's GetObject Function (http://technet.microsoft.com/en-us/library/ee176862.aspx).
function Release-Ref ($ref) {
([System.Runtime.InteropServices.Marshal]::ReleaseComObject([System.__ComObject]$ref) -gt 0)
[System.GC]::Collect()
[System.GC]::WaitForPendingFinalizers()
}
[reflection.assembly]::LoadWithPartialName("'Microsoft.VisualBasic") | Out-Null
$oWorkBook = [Microsoft.VisualBasic.Interaction]::GetObject("E:\Песочница\0410\Книга1.xls")
$oExcel = $oWorkBook.Application
$oExcel.Visible = $true
$oExcel.Windows.Item(1).Visible = $true
$oWorkBook.Path, $oWorkBook.Name
$oWorkBook.Worksheets.Item(1).Cells.Item(1, 1).Value()
$oWorkBook.Close($false)
$oExcel.Quit()
Release-Ref($oWorkBook)
Release-Ref($oExcel)
Если книга закрыта, то открыть через comObject, тогда вообще никаких проблем.
У меня вышеприведенный код выдает ошибку:
Исключение при вызове "GetActiveObject" с "1" аргументами: "Операция недоступна (Исключение из HRESULT: 0x800401E3 (MK_E_UNAVAILABLE))"
строка:1 знак:1
+ $xl = [Runtime.Interopservices.Marshal]::GetActiveObject('Excel.Application')
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : COMException
Это в случае, если файл открыт как обычно. Если файл запускается скриптом, то код:
$xl = [Runtime.Interopservices.Marshal]::GetActiveObject('Excel.Application')
$xl.Workbooks | ForEach-Object {$_.FullName}
выдает:
C:\Users\User\Test\Заказы.xls
Может это уже проблемы Windows? Win 8.1, Office 2010
Проверил на Win 7 и Office 2007. Та же картина.
У меня вышеприведенный код выдает ошибку:
Исключение при вызове "GetActiveObject" с "1" аргументами: "Операция недоступна (Исключение из HRESULT: 0x800401E3 (MK_E_UNAVAILABLE))"
строка:1 знак:1
+ $xl = [Runtime.Interopservices.Marshal]::GetActiveObject('Excel.Application')
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : COMException
Это в случае, если файл открыт как обычно. »
Почитайте:
Форумы caduser.ru (http://www.caduser.ru/forum/index.php?PAGE_NAME=read&FID=7&TID=49097)
When CoCreateInstance returns 0x80080005 (CO_E_SERVER_EXEC_FAILURE) - Antimail - Site Home - MSDN Blogs (http://blogs.msdn.com/b/adioltean/archive/2005/06/24/432519.aspx)
и попробуйте проверить аналогичную методику с try и повторным запросом. У меня, кстати, в отличие от Вас, тоже XP (как у автора по первой ссылке), и проблема тоже не воспроизводится.
Может это уже проблемы Windows? Win 8.1, Office 2010 »
Теоретически всё может быть. Я лично сталкивался с различным поведением одной и той же версии PowerShell на разных ОС в казалось бы весьма простой ситуации.
P.S. Поройтесь ещё здесь: powershell GetActiveObject Exception from HRESULT 0x800401E3 MK_E_UNAVAILABLE - Поиск в Google (https://www.google.ru/search?q=powershell+GetActiveObject+Exception+from+HRESULT+0x800401E3+MK_E_UNAVAILABLE), может чего найдёте.
Супер!! тема с try catch прокатила. Спасибо за наводку. Работает, конечно, с задержкой, но мне в данном случае это безразлично.
Привожу свой вариант, может кому пригодится.
[reflection.assembly]::LoadWithPartialName("'Microsoft.VisualBasic") | Out-Null
$oWorkBook = [Microsoft.VisualBasic.Interaction]::GetObject("C:\Users\User\Test\Заказы.xls")
try
{
$oExcel = [Runtime.Interopservices.Marshal]::GetActiveObject('Excel.Application')
$oExcel.Workbooks | ForEach-Object {$_.FullName}
}
catch [Microsoft.Office.Interop.Excel.Application]
{
$oExcel = [Runtime.Interopservices.Marshal]::GetActiveObject('Excel.Application')
$oExcel.Workbooks | ForEach-Object {$_.FullName}
}
$oWorkBook.Path, $oWorkBook.Name
$oWorkSheet = $oWorkBook.WorkSheets.Item(1)
$oWorkSheet.Cells.Item(1, 1).Value()
corbis, если где-нибудь, когда-нибудь, в будущем наткнётесь на объяснение причин возникновения данной проблемы под новыми ОС и методами их решения — не сочтите за труд, отпишитесь здесь.
© OSzone.net 2001-2012
vBulletin v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.