Страницы: 1
RSS
При открытии файла не происходит передача нажатия клавиш для перехода на нужную вкладку Ribbon menu, После открытия из любого места работает, а в момент открытия, только если перед передачей вызвать MsgBox.
 
В файле есть 3 типа листов. Для оперативной работы с ними созданы вкладки в меню с набором управления. При открытии файла нужно переходить на вкладку, которая приспособлена для работы с типом листа, на котором была завершена(последний раз сохранена) работа.
Казус в том, что после того, как файл открылся - все переходы по листам отрабатывают переходы на нужные вкладки, а при открытии - не переходит.
Отдельный фокус в том, что, если при открытии файла перед процедурой передачи сочетания клавиш поставить вызов MsgBox с любым содержанием - всё отлично отрабатывает.
То есть MsgBox вылез, его закрыли и вкладка меню для активного листа выбирается корректно.
Если вызов MsgBox отменяешь - переход не происходит.
Debug.Print выводит все сообщения по пути следования процедур. До SendKeys и после него.
Когда файл открылся - Sub для перехода на нужную вкладку меню отрабатывает с любой позиции - хоть из меню, хоть с кнопки на листе, а в момент открытия - не переводит фокус, хоть ты тресни...
Пробовал Application.Wait - результат тот же. MsgBox рулит выбором вкладки, а без него - никак.
Кто-нибудь - подскажите где собаку копать???
Изменено: muziker - 12.11.2017 17:52:25
 
Из файла быстро отрезал лишнее.
Прикрепляю для посмотреть
 
Ладно. Если нет желающих помочь победить, хоть подскажите куда, на какой ресурс обратиться с подобным вопросом...
 
Код активации вкладки на ленте, зная имя вкладки:

пример вызова:
Код
SwitchTab "Add-Ins"


Код
#If VBA7 Then
    Declare PtrSafe Function AccessibleChildren Lib "oleacc.dll" (ByVal paccContainer As Object, ByVal iChildStart As Long, ByVal cChildren As Long, rgvarChildren As Variant, pcObtained As LongPtr) As LongPtr
#Else
    Declare Function AccessibleChildren Lib "oleacc.dll" (ByVal paccContainer As Object, ByVal iChildStart As Long, ByVal cChildren As Long, rgvarChildren As Variant, pcObtained As Long) As Long
#End If

Function SwitchTab(TabName As String) As Boolean
    ' © Tony Jollans, August 2008.    http://www.wordarticles.com/Shorts/RibbonVBA/RibbonVBADemo.php
    On Error Resume Next: Dim RibbonTab As Object
    Set RibbonTab = GetAccessible(CommandBars("Ribbon"), &H25&, TabName)
    If RibbonTab Is Nothing Then Exit Function
    If (RibbonTab.accState(&H0&) And 32769) = 0 Then RibbonTab.accDoDefaultAction &H0&: SwitchTab = True
End Function
Public Function GetAccessible(Element As Object, RoleWanted&, NameWanted$, Optional GetClient As Boolean) As Object
    Dim ChildrenArray(), Child As Object, ndxChild&, ReturnElement As Object, NameComparand$, accName$, accValue$
    On Error Resume Next: accValue = Element.accValue(&H0&)
    accName = Element.accName(&H0&)
    Select Case accValue
        Case "Ribbon", "Quick Access Toolbar", "Ribbon Tabs List", "Lower Ribbon", "Status Bar": NameComparand = accValue
        Case "", "Ribbon Tab", "Group": NameComparand = accName
        Case Else: NameComparand = accName
    End Select
    If Element.accRole(&H0&) = RoleWanted And NameComparand = NameWanted Then
        Set ReturnElement = Element
    Else        ' not found yet
        ChildrenArray = GetChildren(Element)
        If (Not ChildrenArray) <> True Then
            For ndxChild = LBound(ChildrenArray) To UBound(ChildrenArray)
                If TypeOf ChildrenArray(ndxChild) Is Object  Then
                    Set Child = ChildrenArray(ndxChild)
                    Set ReturnElement = GetAccessible(Child, RoleWanted, NameWanted)
                    If Not ReturnElement Is Nothing Then Exit For
                End If        ' Child is Object
            Next ndxChild
        End If        ' there are children
    End If        ' still looking
    If GetClient Then Set ReturnElement = ReturnElement.accNavigate(&H7&, &H0&)
    Set GetAccessible = ReturnElement
End Function
Private Function GetChildren(Element As Object) As Variant()
    Const FirstChild As Long = 0&: Dim NumChildren&, ChildrenArray()
    #If Win64 Then
        Dim NumReturned As LongPtr
    #Else
        Dim NumReturned As Long
    #End If
    NumChildren = Element.accChildCount
    If NumChildren > 0 Then ReDim ChildrenArray(NumChildren - 1): AccessibleChildren Element, FirstChild, NumChildren, ChildrenArray(0), NumReturned
    GetChildren = ChildrenArray
End Function
 
Попробуйте через Application.OnTime сделать переход. Что-то вроде:
Код
Application.OnTime Now, "MySub"

Этот метод срабатывает только после загрузки книги, что поможет избежать срабатывания ДО того, как книга открыта полностью.
Даже самый простой вопрос можно превратить в огромную проблему. Достаточно не уметь формулировать вопросы...
 
Спасибо.
Советы буду воплощать.
Результаты, к сожалению, только завтра к вечеру.
 
Игорь - спасибо за пример.
Я, правда, не так глубоко внедрился в код, но сам процесс обращения к вкладкам меню уже был решён.

The_Prist - читал много Ваших советов в темах.
Как всегда - корректно и по существу.
Огромное спасибо!!!
Всё с вашей подсказкой заработало с первой попытки.
Проблема решена.
Предлагаю тему закрыть.

Ещё раз спасибо всем, кто откликнулся и даже просто просмотрел моё сообщение.
Почувствовать себя не одиноким на пути к решению задачи - бесценно!
Страницы: 1
Наверх