Саня, спасибо, очень здорово! А можно чуть поподробнее? Что делает? Куда лучше положить? В xlstart или в addons? Как можно подстроить "под себя"? Только корректируя код? А по-человечески, через интерфейс этих мелко-мягких извращенцев никак? Я, к стыду своему , вообще не смог в коде найти как ты создаёшь вкладку "Основная", а на ней - "***ОСНОВНЫЕ ИНСТРУМЕНТЫ***" и "Макросы". Ну нет таких стрингов в проекте! А можно в группу "Макросы" как-то добавить кнопочки для своих любимых макросов? Уж чтобы картинки на кнопочках свои сделать я и не спрашиваю - это, похоже нам умные дяди запретили
Саня, спасибо, очень здорово! А можно чуть поподробнее? Что делает? Куда лучше положить? В xlstart или в addons? Как можно подстроить "под себя"? Только корректируя код? А по-человечески, через интерфейс этих мелко-мягких извращенцев никак? Я, к стыду своему , вообще не смог в коде найти как ты создаёшь вкладку "Основная", а на ней - "***ОСНОВНЫЕ ИНСТРУМЕНТЫ***" и "Макросы". Ну нет таких стрингов в проекте! А можно в группу "Макросы" как-то добавить кнопочки для своих любимых макросов? Уж чтобы картинки на кнопочках свои сделать я и не спрашиваю - это, похоже нам умные дяди запретили Alex_ST
01.06.2012 вышло обновление Ribbon XML Editor Добавлен поиск с заменой (Ctrl+H) , исправлены баги группировки на вкладке customUI14, и ещё что-то. Обновитесь, кто использует программу - стало ещё удобнее.
01.06.2012 вышло обновление Ribbon XML Editor Добавлен поиск с заменой (Ctrl+H) , исправлены баги группировки на вкладке customUI14, и ещё что-то. Обновитесь, кто использует программу - стало ещё удобнее.Alex_ST
Осваиваю XML-настройку Ribbon'а "под себя" Нужны картинки для своих кнопок. Чтобы вставлять существующие в Офисе картинки кнопок в XML-текст сделал файл, который при его открытии создаёт дополнительную вкладку, а в ней - галереи картинок. При нажатии на интересующую картинку на экран выводится форма с 3-мя видами картинки (16х16, 24х24, 32х32) и двумя кнопками: "Закрыть" и "Копировать". Кнопка "Копировать" помещает имя картинки в готовом для вставки к код виде(типа imageMso="HappyFace" )в буфер обмена. Версии сделал отдельные для 2007-го (там картинок чуть больше 1800 штук) и для 2010-го (картинок больше 7000). Это сделал специально чтобы, работая на 2010-ом, нельзя было случайно вставить ссылку на картинку, отсутствующую в 2007-ом.
____________________________________________________________________________ На всякий случай, для тех, кто будет строить свои интерфейсы, поделюсь немного опытом о паре найденных "граблей": 1. В галерее, оказывается, не может содержаться более 1000 объектов (иначе XML-схема становится не валидной и не отрабатывается). Ну, и фиг с ним. Слишком большие галереи смотреть всё равно не удобно. Сделал галереи по примерно 600 картинок. 2. В группе тоже, оказывается, может быть не более порядка 4000 элементов. Поэтому 7000 картинок 2010-го пришлось разбить на 3 группы (именно 3, а не 2 - для красоты выравнивания кнопок галерей).
Осваиваю XML-настройку Ribbon'а "под себя" Нужны картинки для своих кнопок. Чтобы вставлять существующие в Офисе картинки кнопок в XML-текст сделал файл, который при его открытии создаёт дополнительную вкладку, а в ней - галереи картинок. При нажатии на интересующую картинку на экран выводится форма с 3-мя видами картинки (16х16, 24х24, 32х32) и двумя кнопками: "Закрыть" и "Копировать". Кнопка "Копировать" помещает имя картинки в готовом для вставки к код виде(типа imageMso="HappyFace" )в буфер обмена. Версии сделал отдельные для 2007-го (там картинок чуть больше 1800 штук) и для 2010-го (картинок больше 7000). Это сделал специально чтобы, работая на 2010-ом, нельзя было случайно вставить ссылку на картинку, отсутствующую в 2007-ом.
____________________________________________________________________________ На всякий случай, для тех, кто будет строить свои интерфейсы, поделюсь немного опытом о паре найденных "граблей": 1. В галерее, оказывается, не может содержаться более 1000 объектов (иначе XML-схема становится не валидной и не отрабатывается). Ну, и фиг с ним. Слишком большие галереи смотреть всё равно не удобно. Сделал галереи по примерно 600 картинок. 2. В группе тоже, оказывается, может быть не более порядка 4000 элементов. Поэтому 7000 картинок 2010-го пришлось разбить на 3 группы (именно 3, а не 2 - для красоты выравнивания кнопок галерей).Alex_ST
Здравствуйте, первый раз на этом форуме. решил разместить свой пример надстройки google_translate + gismeteo. В надстройке приведены примеры чтения данных с ленты и вывода результатов на ленту. приведены подробные комментарии xml и vba. в группе google_translate - показана работа с editbox. на ленте два editboxa. в первый вводится текст для перевода, текст переводится функцией http://excelvba.ru/code/GoogleTranslate, полученный результат отображается во втором editbox. в gismeteo - работа с labelcontrol. Скачивается xml информера, данные выводятся на лейблы.
Здравствуйте, первый раз на этом форуме. решил разместить свой пример надстройки google_translate + gismeteo. В надстройке приведены примеры чтения данных с ленты и вывода результатов на ленту. приведены подробные комментарии xml и vba. в группе google_translate - показана работа с editbox. на ленте два editboxa. в первый вводится текст для перевода, текст переводится функцией http://excelvba.ru/code/GoogleTranslate, полученный результат отображается во втором editbox. в gismeteo - работа с labelcontrol. Скачивается xml информера, данные выводятся на лейблы.egonomist
хочу добавить один нюанс (не помню, обсуждалось это или нет) если произойдет какая-либо ошибка, напр., я вбиваю несуществующий город (я про твою надстройку, egonomist), происходит останов и ресет проекта. соответ-но, все глобальные переменные (и MyRibbon тоже) "падают", получение ссылки на интерфейс IRibbonUI происходит при загрузке ленты, т.е. выход - это перезагрузка ленты...
но есть еще способ - использование API-шной функции CopyMemory (ее почему-то даже нет у Д.Эпплмана "Win32 API и Visual Basic"): [vba]
Code
Option Explicit Dim mrbnRibbon As IRibbonUI 'пользовательский интерфейс
#If VBA7 Then Public Declare PtrSafe Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" ( _ pDst As Any, _ pSrc As Any, _ ByVal ByteLen As Long) #Else Public Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" ( _ pDst As Any, _ pSrc As Any, _ ByVal ByteLen As Long) #End If
'---------------------- ЗАГРУЗКА ЛЕНТЫ --- Sub RibbonLoading(ribbon As IRibbonUI) Set mrbnRibbon = ribbon ' интерфейс в переменную SetRegVal ObjPtr(ribbon), gsRIBBON_POINTER, gsPARAM_TYPE1 ' указатель на IRibbonUI _ у меня он записывается в реестр, _ можно куда угодно, откуда его легко получит при падении, в ячейку, напр. End Sub
#If VBA7 Then Function GetRibbon(ByVal lRibbonPointer As LongPtr) As Object #Else Function GetRibbon(ByVal lRibbonPointer As Long) As Object #End If CopyMemory GetRibbon, lRibbonPointer, LenB(lRibbonPointer) End Function
Sub RefreshRibbon() ' эта процедура поднимает риббон, если это возможно. If mrbnRibbon Is Nothing Then Dim sPnt As String: sPnt = vGetRegVal(gsRIBBON_POINTER) ' СЧИТЫВАЕТСЯ ИЗ РЕЕСТРА. If Len(sPnt) = 0 Then MsgBox "Указатель на ленту не найден." & vbCr & _ "Нужно перезагрузить надстройку.", vbCritical End '<<<=====[XXX] - УКАЗАТЕЛЬ НА ЛЕНТУ ОТСУТСТВУЕТ!!!
Else Dim objTemp As Object: Set objTemp = GetRibbon(sPnt) If TypeName(objTemp) <> "IRibbonUI" Then MsgBox "Некорректный указатель на ленту." & vbCr & _ "Нужно перезагрузить надстройку.", vbCritical DelRegVal gsRIBBON_POINTER End '<<<=====[XXX] - УКАЗАТЕЛЬ НЕ НА ЛЕНТУ!!! End If End If
Set mrbnRibbon = objTemp Debug.Print Now & " - cсылка на ленту восстановлена!"
End If
mrbnRibbon.Invalidate
End Sub '=========================================================================
[/vba]
без этого очень напрягало перезагружать надстройку.
хочу добавить один нюанс (не помню, обсуждалось это или нет) если произойдет какая-либо ошибка, напр., я вбиваю несуществующий город (я про твою надстройку, egonomist), происходит останов и ресет проекта. соответ-но, все глобальные переменные (и MyRibbon тоже) "падают", получение ссылки на интерфейс IRibbonUI происходит при загрузке ленты, т.е. выход - это перезагрузка ленты...
но есть еще способ - использование API-шной функции CopyMemory (ее почему-то даже нет у Д.Эпплмана "Win32 API и Visual Basic"): [vba]
Code
Option Explicit Dim mrbnRibbon As IRibbonUI 'пользовательский интерфейс
#If VBA7 Then Public Declare PtrSafe Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" ( _ pDst As Any, _ pSrc As Any, _ ByVal ByteLen As Long) #Else Public Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" ( _ pDst As Any, _ pSrc As Any, _ ByVal ByteLen As Long) #End If
'---------------------- ЗАГРУЗКА ЛЕНТЫ --- Sub RibbonLoading(ribbon As IRibbonUI) Set mrbnRibbon = ribbon ' интерфейс в переменную SetRegVal ObjPtr(ribbon), gsRIBBON_POINTER, gsPARAM_TYPE1 ' указатель на IRibbonUI _ у меня он записывается в реестр, _ можно куда угодно, откуда его легко получит при падении, в ячейку, напр. End Sub
#If VBA7 Then Function GetRibbon(ByVal lRibbonPointer As LongPtr) As Object #Else Function GetRibbon(ByVal lRibbonPointer As Long) As Object #End If CopyMemory GetRibbon, lRibbonPointer, LenB(lRibbonPointer) End Function
Sub RefreshRibbon() ' эта процедура поднимает риббон, если это возможно. If mrbnRibbon Is Nothing Then Dim sPnt As String: sPnt = vGetRegVal(gsRIBBON_POINTER) ' СЧИТЫВАЕТСЯ ИЗ РЕЕСТРА. If Len(sPnt) = 0 Then MsgBox "Указатель на ленту не найден." & vbCr & _ "Нужно перезагрузить надстройку.", vbCritical End '<<<=====[XXX] - УКАЗАТЕЛЬ НА ЛЕНТУ ОТСУТСТВУЕТ!!!
Else Dim objTemp As Object: Set objTemp = GetRibbon(sPnt) If TypeName(objTemp) <> "IRibbonUI" Then MsgBox "Некорректный указатель на ленту." & vbCr & _ "Нужно перезагрузить надстройку.", vbCritical DelRegVal gsRIBBON_POINTER End '<<<=====[XXX] - УКАЗАТЕЛЬ НЕ НА ЛЕНТУ!!! End If End If
Set mrbnRibbon = objTemp Debug.Print Now & " - cсылка на ленту восстановлена!"
End If
mrbnRibbon.Invalidate
End Sub '=========================================================================
[/vba]
без этого очень напрягало перезагружать надстройку.Саня
OFF: на работе завал, а разобраться как поднимать упавший риббон хочется... Попробую на днях выкроить время поразбираться. Хотя в API я ни в зуб ногой, к сожалению.
OFF: на работе завал, а разобраться как поднимать упавший риббон хочется... Попробую на днях выкроить время поразбираться. Хотя в API я ни в зуб ногой, к сожалению. Alex_ST
код сыроват - нет обработчиков ошибок. всю надстройку можно дорабатывать,оптимизировать - open source project, я просто хотел выложить пример работы, мне пришлось много разных сайтов посетить чтоб узнать как это все делается, про такие грабли что Саня написал - я и не знал. Думаю там проверку введеного имени города по уже имеющемуся списку сделать надо, или не комбобокс там ставить. to nerv, посмотрел класс http: нет обработчика ошибки если страница не загрузилась. и вопрос офтоп - в чем преимущества заведения класса перед простым объявлением объекта (именно для загрузки xml)? p.s: буду рад помочь любому другому сценарию развития - может быть кому - то надо курсы валют али еще чего.
код сыроват - нет обработчиков ошибок. всю надстройку можно дорабатывать,оптимизировать - open source project, я просто хотел выложить пример работы, мне пришлось много разных сайтов посетить чтоб узнать как это все делается, про такие грабли что Саня написал - я и не знал. Думаю там проверку введеного имени города по уже имеющемуся списку сделать надо, или не комбобокс там ставить. to nerv, посмотрел класс http: нет обработчика ошибки если страница не загрузилась. и вопрос офтоп - в чем преимущества заведения класса перед простым объявлением объекта (именно для загрузки xml)? p.s: буду рад помочь любому другому сценарию развития - может быть кому - то надо курсы валют али еще чего.egonomist
Мы все поломаем нашей силой ума
Сообщение отредактировал egonomist - Вторник, 28.08.2012, 07:28
я же писал - я записываю указатель в реестр, т.к. убежден, что надстройка (или любая другая утилита) не должна саму себя менять (код отдельно, данные отдельно). модуль MRegistry: [vba]
Code
Option Explicit Public Sub SetRegVal(vVal, Optional sParamPath As String = gsREG_PATH0, _ Optional sParamType As String = gsPARAM_TYPE0) ' [sParamPath] - записываем параметр (По умолчанию) ' ключа "HKEY_CURRENT_USER\Software\Sanya\Add-ins\Ribbon\" On Error GoTo errHandler If sParamType = gsPARAM_TYPE1 Then If Not IsNumeric(vVal) Then Err.Raise 666, , _ "Для типа параметра " & gsPARAM_TYPE1 & " необходимо число, " & _ "а не это: " & Chr(34) & vVal & Chr(34) & vbCr End If End If '=================================================================== Dim WshShell As Object: Set WshShell = CreateObject("WScript.Shell") WshShell.RegWrite sGetFullPath(sParamPath), vVal, sParamType '<<<<<<<<<<<<<<<<<<<<<< Exit Sub errHandler: MarkError "записи", Err.Description End Sub
Public Function vGetRegVal(Optional sParamPath As String = gsREG_PATH0) As Variant ' [sParamPath] - получаем параметр (По умолчанию) ' ключа "HKEY_CURRENT_USER\Software\Sanya\Add-ins\Ribbon\" On Error GoTo errHandler Dim WshShell As Object: Set WshShell = CreateObject("WScript.Shell") vGetRegVal = WshShell.RegRead(sGetFullPath(sParamPath)) '<<<<<<<<<<<<<<<<<<<<<< Exit Function errHandler: MarkError "чтения", Err.Description End Function
Public Sub DelRegVal(Optional sParamPath As String = gsREG_PATH0) ' [sParamPath] - удаляем ключ "HKEY_CURRENT_USER\Software\Sanya\Add-ins\Ribbon\" On Error GoTo errHandler Dim WshShell As Object: Set WshShell = CreateObject("WScript.Shell") WshShell.RegDelete sGetFullPath(sParamPath) '<<<<<<<<<<<<<<<<<<<<<< Exit Sub errHandler: MarkError "удаления", Err.Description End Sub
'-------------------------------------------------------------------------- Private Function sGetFullPath(ByVal sIn As String) As String Dim sPref As String: sPref = "" If Left$(sIn, 4) <> "HKEY" Then sPref = gsREG_PATH0 sGetFullPath = sPref & sIn End Function
Private Sub MarkError(sType As String, sErrDescr As String) Debug.Print Now & " - ошибка " & sType & ":" & vbCr & sErrDescr & vbCr End Sub
[/vba]
и модуль MGlobals: [vba]
Code
Option Explicit Public Const gsPARAM_TYPE0 As String = "REG_SZ" Public Const gsPARAM_TYPE1 As String = "REG_DWORD"
Public Const gsRIBBON_POINTER As String = "RibbonPointer" Public Const gsCOUNTER As String = "Counter"
Public Const gsREG_PATH0 As String = "HKEY_CURRENT_USER\Software\Sanya\Add-ins\Ribbon\"
[/vba]
надстройка большая, можа что лишнее прицепил, можа что не хватает.
Quote (nerv)
можно поподробней?
речь о необработанной исключительной ситуации - Debug Or End - "обнуление" всех глобальных переменных.
я же писал - я записываю указатель в реестр, т.к. убежден, что надстройка (или любая другая утилита) не должна саму себя менять (код отдельно, данные отдельно). модуль MRegistry: [vba]
Code
Option Explicit Public Sub SetRegVal(vVal, Optional sParamPath As String = gsREG_PATH0, _ Optional sParamType As String = gsPARAM_TYPE0) ' [sParamPath] - записываем параметр (По умолчанию) ' ключа "HKEY_CURRENT_USER\Software\Sanya\Add-ins\Ribbon\" On Error GoTo errHandler If sParamType = gsPARAM_TYPE1 Then If Not IsNumeric(vVal) Then Err.Raise 666, , _ "Для типа параметра " & gsPARAM_TYPE1 & " необходимо число, " & _ "а не это: " & Chr(34) & vVal & Chr(34) & vbCr End If End If '=================================================================== Dim WshShell As Object: Set WshShell = CreateObject("WScript.Shell") WshShell.RegWrite sGetFullPath(sParamPath), vVal, sParamType '<<<<<<<<<<<<<<<<<<<<<< Exit Sub errHandler: MarkError "записи", Err.Description End Sub
Public Function vGetRegVal(Optional sParamPath As String = gsREG_PATH0) As Variant ' [sParamPath] - получаем параметр (По умолчанию) ' ключа "HKEY_CURRENT_USER\Software\Sanya\Add-ins\Ribbon\" On Error GoTo errHandler Dim WshShell As Object: Set WshShell = CreateObject("WScript.Shell") vGetRegVal = WshShell.RegRead(sGetFullPath(sParamPath)) '<<<<<<<<<<<<<<<<<<<<<< Exit Function errHandler: MarkError "чтения", Err.Description End Function
Public Sub DelRegVal(Optional sParamPath As String = gsREG_PATH0) ' [sParamPath] - удаляем ключ "HKEY_CURRENT_USER\Software\Sanya\Add-ins\Ribbon\" On Error GoTo errHandler Dim WshShell As Object: Set WshShell = CreateObject("WScript.Shell") WshShell.RegDelete sGetFullPath(sParamPath) '<<<<<<<<<<<<<<<<<<<<<< Exit Sub errHandler: MarkError "удаления", Err.Description End Sub
'-------------------------------------------------------------------------- Private Function sGetFullPath(ByVal sIn As String) As String Dim sPref As String: sPref = "" If Left$(sIn, 4) <> "HKEY" Then sPref = gsREG_PATH0 sGetFullPath = sPref & sIn End Function
Private Sub MarkError(sType As String, sErrDescr As String) Debug.Print Now & " - ошибка " & sType & ":" & vbCr & sErrDescr & vbCr End Sub
[/vba]
и модуль MGlobals: [vba]
Code
Option Explicit Public Const gsPARAM_TYPE0 As String = "REG_SZ" Public Const gsPARAM_TYPE1 As String = "REG_DWORD"
Public Const gsRIBBON_POINTER As String = "RibbonPointer" Public Const gsCOUNTER As String = "Counter"
Public Const gsREG_PATH0 As String = "HKEY_CURRENT_USER\Software\Sanya\Add-ins\Ribbon\"
[/vba]
надстройка большая, можа что лишнее прицепил, можа что не хватает.
Quote (nerv)
можно поподробней?
речь о необработанной исключительной ситуации - Debug Or End - "обнуление" всех глобальных переменных.Саня
Саня, спасибо за советы, все прикрутил, выложил тут - http://www.sql.ru/forum/actualthread.aspx?tid=965161 здесь не могу залогиниться, а как гость загрузить файл не могу.
Саня, спасибо за советы, все прикрутил, выложил тут - http://www.sql.ru/forum/actualthread.aspx?tid=965161 здесь не могу залогиниться, а как гость загрузить файл не могу.egonomist
я же писал - я записываю указатель в реестр, т.к. убежден, что надстройка
Не вдавался, но как-то очень длинно и грустно. Я предпочитаю вариант покороче: [vba]
Code
Option Explicit
Private Declare Sub CopyMemory Lib "kernel32.dll" Alias "RtlMoveMemory" (ByRef Destination As Any, ByRef Source As Any, ByVal Length As Long) Private IRibbon As IRibbonUI
Property Let Current_Ribbon(ribbon As IRibbonUI) Set IRibbon = ribbon Me.Names.Add Name:="Current_Ribbon", RefersTo:=ObjPtr(ribbon) End Property Property Get Current_Ribbon() As IRibbonUI Dim IPoint As Long If IRibbon Is Nothing Then IPoint = Evaluate("Current_Ribbon") CopyMemory IRibbon, IPoint, LenB(IPoint) End If Set Current_Ribbon = IRibbon End Property
[/vba]
Соответственно, код в модуле книги. Впрочем, можно и под стандартный запилить. Таким образом, текущий Ribbon доступен в любой момент За 1,5 года эксплуатации такого подхода - никаких нареканий.
Quote (Саня)
я же писал - я записываю указатель в реестр, т.к. убежден, что надстройка
Не вдавался, но как-то очень длинно и грустно. Я предпочитаю вариант покороче: [vba]
Code
Option Explicit
Private Declare Sub CopyMemory Lib "kernel32.dll" Alias "RtlMoveMemory" (ByRef Destination As Any, ByRef Source As Any, ByVal Length As Long) Private IRibbon As IRibbonUI
Property Let Current_Ribbon(ribbon As IRibbonUI) Set IRibbon = ribbon Me.Names.Add Name:="Current_Ribbon", RefersTo:=ObjPtr(ribbon) End Property Property Get Current_Ribbon() As IRibbonUI Dim IPoint As Long If IRibbon Is Nothing Then IPoint = Evaluate("Current_Ribbon") CopyMemory IRibbon, IPoint, LenB(IPoint) End If Set Current_Ribbon = IRibbon End Property
[/vba]
Соответственно, код в модуле книги. Впрочем, можно и под стандартный запилить. Таким образом, текущий Ribbon доступен в любой момент За 1,5 года эксплуатации такого подхода - никаких нареканий.ElenHim
Для восстановления объекта Ribbon. Собственно, подход тот же что и в предыдущем примере, но адрес объекта Ribbon сохраняется не в реестре, а в имени "Current_Ribbon", в текущей книге. Обращение/присваивание объекта Ribbon реализовано через свойсто (property) Current Ribbon в модуле книги (но можно и в обычном; заметьте, при этом собственно переменная IRibbon является Private), и если IRibbon навернётся, процедура Property Get Current_Ribbon() As IRibbonUI восстановит его по адресу, сохранённому в имени "Current_Ribbon".
Таким образом, после объявлений из моего предыдущего поста, с лентой работаем так:
[vba]
Код
Option Explicit
Sub IRibbon_onLoad(ribbon As IRibbonUI) 'При первой загрузке, сохраняем объект Ribbon и его адрес Current_Ribbon = ribbon
'Далее, работаем с объектом Ribbon, возращаемым свойством Current_Ribbon 'При этом мы гарантированно получаем Ribbon - либо "родной", либо восстановленный после возможных сбоев With Current_Ribbon .ActivateTab ("Home") .Invalidate End With End Sub
[/vba] На мой взгляд такой подход проще, чем работа с реестром, к которому доступа, между прочим, может и не быть.
Константин,
Поясняю,
Для восстановления объекта Ribbon. Собственно, подход тот же что и в предыдущем примере, но адрес объекта Ribbon сохраняется не в реестре, а в имени "Current_Ribbon", в текущей книге. Обращение/присваивание объекта Ribbon реализовано через свойсто (property) Current Ribbon в модуле книги (но можно и в обычном; заметьте, при этом собственно переменная IRibbon является Private), и если IRibbon навернётся, процедура Property Get Current_Ribbon() As IRibbonUI восстановит его по адресу, сохранённому в имени "Current_Ribbon".
Таким образом, после объявлений из моего предыдущего поста, с лентой работаем так:
[vba]
Код
Option Explicit
Sub IRibbon_onLoad(ribbon As IRibbonUI) 'При первой загрузке, сохраняем объект Ribbon и его адрес Current_Ribbon = ribbon
'Далее, работаем с объектом Ribbon, возращаемым свойством Current_Ribbon 'При этом мы гарантированно получаем Ribbon - либо "родной", либо восстановленный после возможных сбоев With Current_Ribbon .ActivateTab ("Home") .Invalidate End With End Sub
[/vba] На мой взгляд такой подход проще, чем работа с реестром, к которому доступа, между прочим, может и не быть.ElenHim
Pluribus Impar
Сообщение отредактировал ElenHim - Пятница, 05.07.2013, 11:29
ElenHim, воспользовался выложенным кодом для работы с Ribbon, лента действительно стала работать стабильнее. Но, обнаружил одно НО: всё слетает после сохранения файла под другим именем.
Как быть в данном случае? Спасибо.
ElenHim, воспользовался выложенным кодом для работы с Ribbon, лента действительно стала работать стабильнее. Но, обнаружил одно НО: всё слетает после сохранения файла под другим именем.