Домашняя страница Undo Do New Save Карта сайта Обратная связь Поиск по форуму
МИР MS EXCEL - Гость.xls

Вход

Регистрация

Напомнить пароль

 

= Мир MS Excel/макрос не видит книг открытых в других экземплярах EXCEL - Мир MS Excel

Старая форма входа
  • Страница 1 из 1
  • 1
Модератор форума: китин, _Boroda_  
макрос не видит книг открытых в других экземплярах EXCEL
Sambo_ Дата: Среда, 31.10.2012, 01:02 | Сообщение № 1
Группа: Гости
Добрый день.
Прошу помочь решить такую проблему:
Есть макрос, который запускается из имеющейся книги, находит данные в двух других открытых книгах и копирует эти данные в соответствующие строки исходной книги.
Проблема в том, что эти две книги являются выгрузками из учетной программы и открываются в новых экземплярах эксель. Запущенный макрос попросту не видит эти две книги, и приходится перед запуском макроса сперва их сохранять, потом заново открывать. А это дополнительные операции и время(
Вопрос: можно ли сделать эти книги видимыми для макроса без их сохранения и переоткрывания?
 
Ответить
СообщениеДобрый день.
Прошу помочь решить такую проблему:
Есть макрос, который запускается из имеющейся книги, находит данные в двух других открытых книгах и копирует эти данные в соответствующие строки исходной книги.
Проблема в том, что эти две книги являются выгрузками из учетной программы и открываются в новых экземплярах эксель. Запущенный макрос попросту не видит эти две книги, и приходится перед запуском макроса сперва их сохранять, потом заново открывать. А это дополнительные операции и время(
Вопрос: можно ли сделать эти книги видимыми для макроса без их сохранения и переоткрывания?

Автор - Sambo_
Дата добавления - 31.10.2012 в 01:02
Саня Дата: Среда, 31.10.2012, 13:49 | Сообщение № 2
Группа: Друзья
Ранг: Ветеран
Сообщений: 1068
Репутация: 560 ±
Замечаний: 0% ±

XL 2016
[vba]
Code
Option Explicit
Private Declare Function GetDesktopWindow Lib "user32" () As Long
Private 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
Private Declare Function GetWindowText Lib "user32" Alias "GetWindowTextA" (ByVal hwnd As Long, ByVal lpString As String, ByVal cch As Long) As Long

Sub t_()    ' если известно расположение файлов

' запускаемый экземпляр
     Dim MyXL1 As Object
     Set MyXL1 = GetObject(, "Excel.Application")
     Debug.Print MyXL1.hwnd

     ' экземпляр какой-то книги
     Dim MyXL2 As Object
     Set MyXL2 = GetObject(ThisWorkbook.Path & "\Книга3.xlsx").Application
     Debug.Print MyXL2.hwnd
End Sub

Sub t__()   ' поиск дескрипторов всех экземпляров Excel. Возможный вектор поиска решения...
     Dim alH() As Long
     FindAllHwnd GetDesktopWindow, alH, "XLMAIN"

     Dim i As Integer
     For i = LBound(alH) To UBound(alH)
         Debug.Print alH(i)
         Debug.Print GetWindowText_(alH(i))
     Next i
End Sub

Sub FindAllHwnd(hWndParent As Long, _
                 ByRef alHwnd() As Long, _
                 Optional ByVal sClass As String = vbNullString, _
                 Optional ByVal sCaption As String = vbNullString)

     Dim hwnd As Long
     Dim n As Integer: n = 0
     Do
         hwnd = FindWindowEx(hWndParent, hwnd, sClass, sCaption)
         If hwnd <> 0 Then
             n = n + 1
             ReDim Preserve alHwnd(1 To n)
             alHwnd(n) = hwnd
         End If
     Loop Until hwnd = 0
End Sub

Private Function GetWindowText_(hwnd As Long)
     Dim MyStr As String: MyStr = String(100, Chr$(0))
     GetWindowText hwnd, MyStr, 100
     GetWindowText_ = Left$(MyStr, InStr(MyStr, Chr$(0)) - 1)
End Function
[/vba]
 
Ответить
Сообщение[vba]
Code
Option Explicit
Private Declare Function GetDesktopWindow Lib "user32" () As Long
Private 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
Private Declare Function GetWindowText Lib "user32" Alias "GetWindowTextA" (ByVal hwnd As Long, ByVal lpString As String, ByVal cch As Long) As Long

Sub t_()    ' если известно расположение файлов

' запускаемый экземпляр
     Dim MyXL1 As Object
     Set MyXL1 = GetObject(, "Excel.Application")
     Debug.Print MyXL1.hwnd

     ' экземпляр какой-то книги
     Dim MyXL2 As Object
     Set MyXL2 = GetObject(ThisWorkbook.Path & "\Книга3.xlsx").Application
     Debug.Print MyXL2.hwnd
End Sub

Sub t__()   ' поиск дескрипторов всех экземпляров Excel. Возможный вектор поиска решения...
     Dim alH() As Long
     FindAllHwnd GetDesktopWindow, alH, "XLMAIN"

     Dim i As Integer
     For i = LBound(alH) To UBound(alH)
         Debug.Print alH(i)
         Debug.Print GetWindowText_(alH(i))
     Next i
End Sub

Sub FindAllHwnd(hWndParent As Long, _
                 ByRef alHwnd() As Long, _
                 Optional ByVal sClass As String = vbNullString, _
                 Optional ByVal sCaption As String = vbNullString)

     Dim hwnd As Long
     Dim n As Integer: n = 0
     Do
         hwnd = FindWindowEx(hWndParent, hwnd, sClass, sCaption)
         If hwnd <> 0 Then
             n = n + 1
             ReDim Preserve alHwnd(1 To n)
             alHwnd(n) = hwnd
         End If
     Loop Until hwnd = 0
End Sub

Private Function GetWindowText_(hwnd As Long)
     Dim MyStr As String: MyStr = String(100, Chr$(0))
     GetWindowText hwnd, MyStr, 100
     GetWindowText_ = Left$(MyStr, InStr(MyStr, Chr$(0)) - 1)
End Function
[/vba]

Автор - Саня
Дата добавления - 31.10.2012 в 13:49
Gustav Дата: Среда, 31.10.2012, 15:15 | Сообщение № 3
Группа: Админы
Ранг: Участник клуба
Сообщений: 2797
Репутация: 1161 ±
Замечаний: ±

начинал с Excel 4.0, видел 2.1
Боюсь, что самым простым будет - написать макрос, запускаемый НЕ из Excel (!), а из другого приложения (Word, Outlook или отдельно стоящий VB-скрипт).

Макрос будет делать примерно следующее:
* последовательно закрывать все открытые экземпляры Excel - до полного отсутствия Excel в оперативной памяти компьютера, когда очередной оператор GetObject ничего не вернет;
* если очередной экземпляр будет с одним из этих двух временных файлов, то сохранять его на диске и также закрывать;
* заканчивать свою работу запуском в новом экземляре Excel существующей книги с макросом (т.е. фактически передавая ему управление), который и будет переносить информацию из файлов, полученных из учетной системы.

Исходя из этого, а также из кода, который привел Саня, может быть, дополнительные затраты времени и сил на ручное сохранение файлов уже не кажутся Вам такими уж затратными? wink


МОИ: Ник, Tip box: 41001663842605
 
Ответить
СообщениеБоюсь, что самым простым будет - написать макрос, запускаемый НЕ из Excel (!), а из другого приложения (Word, Outlook или отдельно стоящий VB-скрипт).

Макрос будет делать примерно следующее:
* последовательно закрывать все открытые экземпляры Excel - до полного отсутствия Excel в оперативной памяти компьютера, когда очередной оператор GetObject ничего не вернет;
* если очередной экземпляр будет с одним из этих двух временных файлов, то сохранять его на диске и также закрывать;
* заканчивать свою работу запуском в новом экземляре Excel существующей книги с макросом (т.е. фактически передавая ему управление), который и будет переносить информацию из файлов, полученных из учетной системы.

Исходя из этого, а также из кода, который привел Саня, может быть, дополнительные затраты времени и сил на ручное сохранение файлов уже не кажутся Вам такими уж затратными? wink

Автор - Gustav
Дата добавления - 31.10.2012 в 15:15
Hugo Дата: Среда, 31.10.2012, 23:03 | Сообщение № 4
Группа: Друзья
Ранг: Участник клуба
Сообщений: 3691
Репутация: 790 ±
Замечаний: 0% ±

365
Учётную программу нельзя заставить доработать, чтоб открывала файлы в уже существующем Экселе, если он открыт?
На vbs такое сделать не сложно, использую.
Т.е. открыли файл с макросом, подгрузили туда отчёты - и работаете.


webmoney: E265281470651 Z422237915069
USDT TRC20: TN8XeEF17o5KPBD9pNwYzNyruycuAc2mVD
 
Ответить
СообщениеУчётную программу нельзя заставить доработать, чтоб открывала файлы в уже существующем Экселе, если он открыт?
На vbs такое сделать не сложно, использую.
Т.е. открыли файл с макросом, подгрузили туда отчёты - и работаете.

Автор - Hugo
Дата добавления - 31.10.2012 в 23:03
Sambo_ Дата: Четверг, 01.11.2012, 00:23 | Сообщение № 5
Группа: Гости
Да.., не думал, что эта задача такая гемор=я. Предполагал, что раз уж из Exel можно работать, например, с тем же Wordом, который запускается, уж наверняка в другом процессе, то как-то можно работать и с книгой запущенной в другом экземпляре.
Теперь понятно почему за весь вчерашний вечер в инете не удалось найти по данному вопросу ничего толкового.
Тем не менее, спасибо всем за советы.
Hugo,заставить доработать программу, пожалуй, самый простой вариант, но увы, наша учетная программа не настраивается индивидуально под пользователя, так как ее используют несколько сот муниципальных образований. А если изменять код для всех, то кому-то это, конечно, покажется не удобным(
Gustav, вы по сути предлагаете автоматизировать ручные операции по закрытию и открытию книг. Данный вариант для меня также не выход: дело в том, что книга с макросом каждый раз после обновления данных пересохраняется в другой папке и с несколько иным именем. Поэтому прописать в коде где находится книга, подлежащая открытию, и как она называется не получится.
Саня, отдельное спасибо, но чтобы понять ваш код мне потребуется, наверное, несколько лет усиленных занятий по изучению ВБА :)
Понимаю, что здесь не курсы изучения языков программирования, но просвятите хотя бы, что за функции такие GetDesktopWindow и FindWindowEx и что означает Lib "user32"?
 
Ответить
СообщениеДа.., не думал, что эта задача такая гемор=я. Предполагал, что раз уж из Exel можно работать, например, с тем же Wordом, который запускается, уж наверняка в другом процессе, то как-то можно работать и с книгой запущенной в другом экземпляре.
Теперь понятно почему за весь вчерашний вечер в инете не удалось найти по данному вопросу ничего толкового.
Тем не менее, спасибо всем за советы.
Hugo,заставить доработать программу, пожалуй, самый простой вариант, но увы, наша учетная программа не настраивается индивидуально под пользователя, так как ее используют несколько сот муниципальных образований. А если изменять код для всех, то кому-то это, конечно, покажется не удобным(
Gustav, вы по сути предлагаете автоматизировать ручные операции по закрытию и открытию книг. Данный вариант для меня также не выход: дело в том, что книга с макросом каждый раз после обновления данных пересохраняется в другой папке и с несколько иным именем. Поэтому прописать в коде где находится книга, подлежащая открытию, и как она называется не получится.
Саня, отдельное спасибо, но чтобы понять ваш код мне потребуется, наверное, несколько лет усиленных занятий по изучению ВБА :)
Понимаю, что здесь не курсы изучения языков программирования, но просвятите хотя бы, что за функции такие GetDesktopWindow и FindWindowEx и что означает Lib "user32"?

Автор - Sambo_
Дата добавления - 01.11.2012 в 00:23
Gustav Дата: Четверг, 01.11.2012, 09:46 | Сообщение № 6
Группа: Админы
Ранг: Участник клуба
Сообщений: 2797
Репутация: 1161 ±
Замечаний: ±

начинал с Excel 4.0, видел 2.1
Quote (Sambo_)
Gustav, вы по сути предлагаете автоматизировать ручные операции по закрытию и открытию книг. Данный вариант для меня также не выход: дело в том, что книга с макросом каждый раз после обновления данных пересохраняется в другой папке и с несколько иным именем. Поэтому прописать в коде где находится книга, подлежащая открытию, и как она называется не получится.

Ого! Это у вас типа DocFlow такое, что книга переименовывается и путешествует по папкам? smile Но вручную-то когда запускаете, как-то же знаете, где она находится и как называется в момент запуска?

А если макрос из нее вынуть и включить его в самостоятельный VB-скрипт, который бы один всем рулил и никому не передавал управление?

Собственно, основной смысл моего предыдущего выступления был в том, что Getobject(,"Excel.Application") при нескольких открытых приложениях привязывается к одному из них непредсказуемо. И гарантированно побывать во всех из них по разу за один цикл можно лишь путем закрытия очередного, в который попали в текущий момент. И это объективная реальность, с которой вам придется считаться при разработке того или иного решения.

Quote (Sambo_)
Предполагал, что раз уж из Exel можно работать, например, с тем же Wordом, который запускается, уж наверняка в другом процессе, то как-то можно работать и с книгой запущенной в другом экземпляре.

Это можно. НО! Только в том случае, если другой экземпляр запущен из первого. Если же он запущен НЕЗАВИСИМО от первого, то - увы!..


МОИ: Ник, Tip box: 41001663842605

Сообщение отредактировал Gustav - Четверг, 01.11.2012, 11:29
 
Ответить
Сообщение
Quote (Sambo_)
Gustav, вы по сути предлагаете автоматизировать ручные операции по закрытию и открытию книг. Данный вариант для меня также не выход: дело в том, что книга с макросом каждый раз после обновления данных пересохраняется в другой папке и с несколько иным именем. Поэтому прописать в коде где находится книга, подлежащая открытию, и как она называется не получится.

Ого! Это у вас типа DocFlow такое, что книга переименовывается и путешествует по папкам? smile Но вручную-то когда запускаете, как-то же знаете, где она находится и как называется в момент запуска?

А если макрос из нее вынуть и включить его в самостоятельный VB-скрипт, который бы один всем рулил и никому не передавал управление?

Собственно, основной смысл моего предыдущего выступления был в том, что Getobject(,"Excel.Application") при нескольких открытых приложениях привязывается к одному из них непредсказуемо. И гарантированно побывать во всех из них по разу за один цикл можно лишь путем закрытия очередного, в который попали в текущий момент. И это объективная реальность, с которой вам придется считаться при разработке того или иного решения.

Quote (Sambo_)
Предполагал, что раз уж из Exel можно работать, например, с тем же Wordом, который запускается, уж наверняка в другом процессе, то как-то можно работать и с книгой запущенной в другом экземпляре.

Это можно. НО! Только в том случае, если другой экземпляр запущен из первого. Если же он запущен НЕЗАВИСИМО от первого, то - увы!..

Автор - Gustav
Дата добавления - 01.11.2012 в 09:46
Саня Дата: Четверг, 01.11.2012, 10:39 | Сообщение № 7
Группа: Друзья
Ранг: Ветеран
Сообщений: 1068
Репутация: 560 ±
Замечаний: 0% ±

XL 2016
Quote (Sambo_)
но чтобы понять ваш код мне потребуется, наверное, несколько лет усиленных занятий по изучению ВБА smile

в 2007 году я не знал что такое ВПР...

Quote (Sambo_)
Понимаю, что здесь не курсы изучения языков программирования, но просвятите хотя бы, что за функции такие GetDesktopWindow и FindWindowEx и что означает Lib "user32"?

все это функции Win API:
GetDesktopWindow - получение манипулятора рабочего стола (это окно высшего уровня иерархии окон)
FindWindowEx - эта функция циклически просматривает непосредственные дочерние окна - для рабочего стола это все запущенные приложения и "еще что-то", "отлов" основного окна Excel происходит по имени класса "XLMAIN". Если погружаться дальше, то можно дойти: ленты, строки состояния, адресной строки, всех окон рабочих книг (именно здесь я думал зацепиться за экземпляры приложения)

user32 - user32.dll - это имя библиотеки, где и находятся эти замечательные функции
 
Ответить
Сообщение
Quote (Sambo_)
но чтобы понять ваш код мне потребуется, наверное, несколько лет усиленных занятий по изучению ВБА smile

в 2007 году я не знал что такое ВПР...

Quote (Sambo_)
Понимаю, что здесь не курсы изучения языков программирования, но просвятите хотя бы, что за функции такие GetDesktopWindow и FindWindowEx и что означает Lib "user32"?

все это функции Win API:
GetDesktopWindow - получение манипулятора рабочего стола (это окно высшего уровня иерархии окон)
FindWindowEx - эта функция циклически просматривает непосредственные дочерние окна - для рабочего стола это все запущенные приложения и "еще что-то", "отлов" основного окна Excel происходит по имени класса "XLMAIN". Если погружаться дальше, то можно дойти: ленты, строки состояния, адресной строки, всех окон рабочих книг (именно здесь я думал зацепиться за экземпляры приложения)

user32 - user32.dll - это имя библиотеки, где и находятся эти замечательные функции

Автор - Саня
Дата добавления - 01.11.2012 в 10:39
Саня Дата: Четверг, 01.11.2012, 14:51 | Сообщение № 8
Группа: Друзья
Ранг: Ветеран
Сообщений: 1068
Репутация: 560 ±
Замечаний: 0% ±

XL 2016
То, что вчера я не нашел - возвращает объект из дескриптора окна
[vba]
Code
Option Explicit
Private Const OBJID_NATIVEOM = &HFFFFFFF0
Type GUID
     lD1 As Long
     iD2 As Integer
     iD3 As Integer
     abytD4(0 To 7) As Byte
End Type
Declare Function AccessibleObjectFromWindow Lib "oleacc" ( _
                    ByVal hWnd As Long, _
                    ByVal dwId As Long, _
                    riid As GUID, _
                    ppvObject As Object) As Long
'-------------------------------------------------------------------------------

Function AppFromHwnd(hWnd As Long) As Object
' GUID для IDispatch object {00020400-0000-0000-C000-000000000046}
     Dim id As GUID
     With id
         .lD1 = &H20400
         .iD2 = &H0: .iD3 = &H0
         .abytD4(0) = &HC0: .abytD4(1) = &H0
         .abytD4(2) = &H0: .abytD4(3) = &H0
         .abytD4(4) = &H0: .abytD4(5) = &H0
         .abytD4(6) = &H0: .abytD4(7) = &H46
     End With

     Dim obj As Object
     AccessibleObjectFromWindow hWnd, OBJID_NATIVEOM, id, obj
     Set AppFromHwnd = obj.Application
End Function
[/vba]

весь код во вложении - проц. GetAllXLApp
кто хочет посмотреть оконные "потроха" Excel'я - проц. AllWindowsOfAllXLs

копай!
biggrin biggrin biggrin
К сообщению приложен файл: 1220187.xlsm (29.1 Kb)
 
Ответить
СообщениеТо, что вчера я не нашел - возвращает объект из дескриптора окна
[vba]
Code
Option Explicit
Private Const OBJID_NATIVEOM = &HFFFFFFF0
Type GUID
     lD1 As Long
     iD2 As Integer
     iD3 As Integer
     abytD4(0 To 7) As Byte
End Type
Declare Function AccessibleObjectFromWindow Lib "oleacc" ( _
                    ByVal hWnd As Long, _
                    ByVal dwId As Long, _
                    riid As GUID, _
                    ppvObject As Object) As Long
'-------------------------------------------------------------------------------

Function AppFromHwnd(hWnd As Long) As Object
' GUID для IDispatch object {00020400-0000-0000-C000-000000000046}
     Dim id As GUID
     With id
         .lD1 = &H20400
         .iD2 = &H0: .iD3 = &H0
         .abytD4(0) = &HC0: .abytD4(1) = &H0
         .abytD4(2) = &H0: .abytD4(3) = &H0
         .abytD4(4) = &H0: .abytD4(5) = &H0
         .abytD4(6) = &H0: .abytD4(7) = &H46
     End With

     Dim obj As Object
     AccessibleObjectFromWindow hWnd, OBJID_NATIVEOM, id, obj
     Set AppFromHwnd = obj.Application
End Function
[/vba]

весь код во вложении - проц. GetAllXLApp
кто хочет посмотреть оконные "потроха" Excel'я - проц. AllWindowsOfAllXLs

копай!
biggrin biggrin biggrin

Автор - Саня
Дата добавления - 01.11.2012 в 14:51
  • Страница 1 из 1
  • 1
Поиск:

Яндекс.Метрика Яндекс цитирования
© 2010-2024 · Дизайн: MichaelCH · Хостинг от uCoz · При использовании материалов сайта, ссылка на www.excelworld.ru обязательна!