Выбрать дату в календареВыбрать дату в календаре

Страницы: 1
Восстановление связи с Ribbon
 
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<customUI onLoad="Ribbon_OnLoad" xmlns="http://schemas.microsoft.com/office/2009/07/customui"&gt;
<ribbon startFromScratch="true">
<qat>
<sharedControls>
<control idMso="FileSave"/>
<control idMso="Undo"/>
<control idMso="Redo"/>
<button id="cmdRefreshRibbon" label="Обновить ленту" imageMso="RefreshMenu" onAction="cmdRefreshRibbon_RibClick"
screentip="Обновить ленту"
supertip="Применяется при неправильном отображении ленты.
&#10;Признаки неправильного отображения ленты: недоступны или не отображаются
некоторые закладки или кнопки, нарушен порядок элементов и т.д."
/>
</sharedControls>
</qat>

<tabs>
<!-- MS Office Tabs управление встроенными Tabs по правам доступа в VBA процедуре MsoTab_RibGetVisible -->
<tab idMso="TabHome" getVisible="MsoTab_RibGetVisible"/>
<tab idMso="TabView" getVisible="MsoTab_RibGetVisible"/>
<tab idMso="TabPrintPreview" getVisible="MsoTab_RibGetVisible"/>
<tab idMso="TabHeaderAndFooterToolsDesign" getVisible="MsoTab_RibGetVisible"/>
<tab idMso="TabPageLayoutExcel" getVisible="MsoTab_RibGetVisible"/>

<tab idMso="TabData" getVisible="MsoTab_RibGetVisible"/>
<tab idMso="TabFormulas" getVisible="MsoTab_RibGetVisible"/>
<tab idMso="TabInsert" getVisible="MsoTab_RibGetVisible"/>
<tab idMso="TabDeveloper" getVisible="MsoTab_RibGetVisible"/>
<tab idMso="TabPowerPivot" getVisible="MsoTab_RibGetVisible"/>
<tab idMso="TabReview" getVisible="MsoTab_RibGetVisible"/>

<!-- Мои вкладки -->
<tab id="tabGraph" label="ГРАФИК" insertBeforeMso="TabHome" >
<!-- группа MSO Буфер обмена (Clipboard): копировать / вставить  -->
<group idMso="GroupClipboard" getVisible="Group_RibGetVisible">
<!-- Все кнопки, которые есть в группе Mso -->
</group>

<!-- Моя группа Структура: группировка, форматирование, внесение формул -->
<!-- ============================================================­============================================================­ -->
<group id="grpStructure" label="Структура" getVisible="Group_RibGetVisible">
<!-- меню Структура -->
<menu id="mnuStructure" label="Структура" size="large" imageMso="ViewGridlinesPowerPoint" tag="grpStructure"
getEnabled="grpStructure_RibGetEnabled"
screentip="Операции для всей таблицы: форматирования, группировки, вставки формул и расчета по ним">
.................
Восстановление связи с Ribbon
 
Добрый день, уважаемые коллеги.
Эндрю, если вы глубоко не изучите тему конструирования ленты, вы будете еще долго задавать множество вопросов, и терять свое время.
При этом не факт, что ваши вопросы правильно поймут. И не факт, что в файле, который вы получите будет именно то, что вам нужно.
Это походит на разговор моей супруги с электриком, когда исчезло электричество в половине квартиры, все равно мне пришлось ему звонить и объяснять.
Как конструировать и программировать ленту - широкая тема, которой посвящены 1000 статей в сети. Какого-то лучшего рецепта нет, каждый выбирает свой путь.
Например, я программирую xml так:
- отключаю ленту по умолчанию;
- выбираю существующие tabs mso, которые меня устраивают целиком (visible = true);
- создаю свои tabs , в которые включаю как свои элементы управления, так и существующие mso;
- управляю свойством visible для существующих mso (потому что иные свойства не программируются), и свойствами enabled и visible для своих элементов;
- в зависимости от прав доступа пользователя, а также от состояния редактирования документа изменяется состояние элементов управления ленты: они могут быть невидимы или недоступны.
Попытка динамического обновления файла xml из vba не дала удовлетворительного результата по надежности. При этом нужно понимать, что обновление ленты может происходить только при переключении между документами (передача фокуса). На встроенных событиях лента изменяться не будет, потому что файл xml внутри архива doc не перепишется пока  документ в фокусе. Поэтому способ динамического обновления файла xml средствами vba - это тупиковый путь. Как правильно написал Андрей VG программирование на С: С++, С# вам в помощь, там можно сделать).
Управляйте элементами ленты. Создавайте свои и используйте существующие. И изучайте эту тему самостоятельно.
На форуме предполагается, что человек уже знает тему, и ему нужно решить какую-то конкретную локальную задачу.  
Восстановление связи с Ribbon
 
Добрый день. Эндрю, если вы хотите создать свою ленту в Word, вам придется изучить эту тему.
В качестве поиска рекомендую использовать предложение Customize the ribbon word vba
В качестве старта предлагаю вам прочитать материал по ссылке: https://wordmvp.com/FAQs/Customization/Customising%20the%20Ribbon%20-%20Advanced.htm
Принцип построения Ribbon в MS Office идентичен - xml +vba.
Также вам нужно подобрать удобный редактор xml. В сети можно найти достаточно материалов на эту тему.
Восстановление связи с Ribbon
 
Цитата
Call cmdMyButton_RibClick(Nothing)
Добрый день.
Андрей VG полностью согласен с вами.
Однако я постарался показать суть, и надеюсь у меня получилось)
Восстановление связи с Ribbon
 
Добрый день.
VW3, высылаю вам файл с обновленным кодом. Объяснения в коде VBA через #
Восстановление связи с Ribbon
 
Добрый день.
VW3, вышлите мне файл на почту, я посмотрю.

контакт удален (см. правила форума) [МОДЕРАТОР]
Восстановление связи с Ribbon
 
Добрый день! Недавно ко мне обратились с вопросом: Как вызвать в vba процедуру, которая назначена событию кнопки на ленте Ribbon?
Есть стандартная ситуация, когда в xml мы создаем кнопку. Например
Код
<button id="cmdMyButton" label="Моя кнопка" size="normal" imageMso="CreateReport" onAction="cmdMyButton_RibClick"/>
В VBA мы соответственно пишем код для события onAction
Код
Sub cmdMyButton_RibClick(control As IRibbonControl)
   Msgbox "Моя кнопка нажата"
End Sub
Теперь нужно вызвать эту процедуру из другого модуля VBA. Простой вызов
Код
Sub CallMyButton    
    'Вызываем
    Call cmdMyButton_RibClick
End Sub
выдаст ошибку, т.к. не определен control (IRibbonControl). Вопрос был в о том, как задать control  при вызове cmdMyButton_RibClick.
Для VBA события элементов управления ленты Ribbon недоступны.  Процедура Sub cmdMyButton_RibClick(control As IRibbonControl) инициируется при возникновении события элемента управления на ленте через закрытый код MS Office посредством callback или обратного вызова. Со стороны Ribbon при нажатии на кнопку поступает запрос к VBA на наличие процедуры cmdMyButton_RibClick. Если такая процедура есть, то она исполняется, а если нет, то поступает сообщение о том, что процедура не найдена. И вообщем это все, и какого-то особого значения не имеет. Со стороны VBA процедура  Sub cmdMyButton_RibClick(control As IRibbonControl) самая рядовая процедура, никак не привязанная ни к каким событиям, ни к каким элементам управления. И для VBA аргумент control As IRibbonControl любой возможный control типа IRibbonControl (если бы аргумент был control As ComboBox, то можно было передать любой ComboBox). Этим и можно воспользоваться.
Код
Sub CallMyButton()
    'Задаем виртуальный IRibbonControl
    Dim ctlVirtualControl As IRibbonControl
    
    'Вызываем
    Call cmdMyButton_RibClick(ctlVirtualControl)
End Sub
Суть проста. Создаем виртуальный VirtualControl, и передаем его в процедуру cmdMyButton_RibClick.
Аналогично можно вызвать любую другую процедуру, передав ее аргументам соответствующие значения.
Возможно моя заметка будет кому-нибудь интересна. Всем удачи)
Изменено: Ткач Александр - 04.12.2019 17:06:17
Восстановление связи с Ribbon
 
Выкладываю таблицу всех элементов ribbon mso excel: вкладки кнопки, всплывающие меню и т.д.
Есть имена и id. Скачал у MS в этом году. Возможно это самая полная таблица.
Восстановление связи с Ribbon
 
Добрый день, уважаемые коллеги!
ZVI, у автора темы п. 4, строки кода 6, 9
Код
lPointer = CLng([RibbonPointer])
И где вы видели Evaluate? Запись [...] лично у меня выдает ошибку, хотя должно работать. Но если бы и работало то мы получаем цепочку обработки данных Eval() => CLngPtr(), зачем? Мы же стремимся писать оптимально или не так?  К примеру, об операторе Mod тоже много написано.  Однако результат его применения в VBA не тот, который описан в VB. И еще раз обращу внимание, что я часто использую очистку Names, потому что диапазоны могут изменяться. Представьте 6 листов на каждом до 12-15 именованных диапазонов. Если я их буду перебирать поштучно по именам, то пользователь заснет, а код распухнет до небес. Поэтому я удаляю на каждой странице все, а затем заново переопределяю. А пользовательские свойства документа - гораздо более надежное хранилище в этом плане. И важную информацию лучше сохранять именно там, особенно касаемо инфы для единственного объекта в единственном экземпляре..
bedvit, если действительно интересно, то мы использовали следующий подход. Книга Excel - user interface, строки и колонки - поля данных, и просто разметка листа типа координатной сетки.
Наша надстройка на C# уровня файла (не приложения!). Каждый файл заточен под определенные данные. Например, в одном Организация корпоративов, в другом Анализ проектов предевелопмента и т.д. Данные хранятся в базе. При открытии файла данные подгружаются автоматом. В файле Excel работает user, там вычисления, графики и любые персональные данные и заметки. При закрытии файла  определенные данные подготавливаются и отправляются на сервер. Индивидуальная пользовательская информация сохраняется только в файле. Писано сразу на С# в VS и встроено в файл в виде надстройки средствами VS. VBA используется для макетирования, т.к позволяет выиграть время. Кроме того, если использовать один файл в процессе разработки, а затем писать надстройку, то там остается куча мусора, который без доступа к коду MSO убрать практически невозможно. VBA, VB и С# не взаимодействуют никак. От VB. Net мы отказались, слишком громоздко писать. И самая лучшая поддержка у C#. Вероятно он станет кроссплатформенным. Но и это уже вчерашний день когда мы говорим об office (не обязательно MSO, но и свободных). Сегодня и завтра облака + JS + JSON (взамен xml и/или совместно) + google sheet и/или office 360. Полагаю, что совсем скоро персональный софт потеряет смысл. Сегодня даже сложные и очень тяжелые графические программы у auto desk (fusion 360 например из autodesk 360) перешли в облака.  
Изменено: Ткач Александр - 24.10.2019 18:45:00
Восстановление связи с Ribbon
 
Продолжая тему Johny, я бы не стал использовать именованный диапазон для записи ссылки на объект ленты IRibbonUI, а воспользовался более надежным местом - DocumentProperty (ссылка на DocumentProperty: https://docs.microsoft.com/ru-ru/office/vba/api/office.documentproperties.add ). Для этого несколько оснований:
  1. одна и таже ячейка может входить в несколько именованных диапазонов. Поэтому при  групповых операциях можно ненароком удалить как сам диапазон, так и очистить значения. К коллекции DocumentPropertys обращаются реже, если вообще обращаются.
  2. меньше преобразований текстовых строк , т.к. не нужно из формулы "=123456..." удалять знак равно.
Тогда модули будут выглядеть так:
Код
Public objRib as IRibbonUI 

'Загрузочная запись ленты Ribbon
Sub Ribbon_OnLoad(ribbon As IRibbonUI)

    Set objRib = ribbon

    'Записываем IRibbonUI в пользовательское свойство RibbonPointer
    Call WriteRibbon(objRib)

End Sub


'Обновление состояния элементов управления на Ленте.
'Обработка ошибок нужна, если по какой-то причине id objRib не сохранится
Sub RefreshRibbon()
On Error GoTo Err_discr
    
    'Проверяем переменную objRib объекта IRibbonUI текущего проекта.
    If objRib Is Nothing Then
        'Если переменная пустая, пытаемся восстановить objRib
        Call RestoreRibbon(objRib)
        'Если восстановление не получилось, выводим сообщение Err_discr
        If objRib Is Nothing Then _
            GoTo Err_discr
    End If
    
    'обновляем состояние элементов Ленты
    objRib.Invalidate

Exit Sub

Err_discr:
    MsgBox "Ошибка при обращении к Ленте." & _
            vbNewLine & "Сохраните и перезагрузите файл", _
                                        vbCritical, "ошибки ленты"

End Sub

'Процедура создает id ссылку на объект objRibbon типа IRibbonUI,
'в пользовательских свойствах DocumentProperties с именем "RibbonPointer".
'Если такого свойства нет, то создает его.
Sub WriteRibbon(objRibbon As Object)
    Dim pr As DocumentProperty 'пользовательское свойство
    Dim prs As DocumentProperties 'коллекция пользовательских свойств
    Dim bExist As Boolean
    
    'Проверяем пользовательские свойства проекта.
    Set prs = ThisWorkbook.CustomDocumentProperties
    'Ищем существует ли свойство RibbonPointer.
    bExist = False
    
    For Each pr In prs
        'Если свойство существует, устанавливаем переменную bExist=True,
        'и выходим из цикла
        If pr.Name = "RibbonPointer" Then _
            bExist = True: _
            Exit For
    Next
    
    'Если свойство не существует, добавляем его в коллекцию DocumentProperties.
    'Т.к. тип данных DocumentProperty не поддерживает LongPtr (LongLong),
    'записываем id объекта objRib в строку, с последующим преобразованием CLongPtr.
    'Поэтому используем тип данных msoPropertyTypeString, а не msoPropertyTypeNumber
    If Not bExist Then
        prs.Add "RibbonPointer", False, msoPropertyTypeString, ObjPtr(objRib)
    Else
       ThisWorkbook.CustomDocumentProperties("RibbonPointer").Value = ObjPtr(objRib)
    End If


End Sub

'Восстанавливает объект IRibbonUI из RibbonPointer
Sub RestoreRibbon(objRibbon As Object)
    Dim llPointer As LongPtr
    
    'Считываем ссылку на id objRib из свойства RibbonPointer.
    'Преобразуем значение RibbonPointer из строки в число.
    llPointer = CLngPtr(ThisWorkbook.CustomDocumentProperties("RibbonPointer"))
    
    'Перемещаем ссылку llPointer в объект objRib с помощью API процедуры RtlMoveMemory
    Call RtlMoveMemory(objRibbon, llPointer, LenB(llPointer))
 
End Sub
Я постарался подробнее закомментировать)
Изменено: Ткач Александр - 02.02.2020 18:14:37 (дополнено)
Восстановление связи с Ribbon
 
Добрый день коллеги!
Я поддерживаю предложение о том, что в данной теме должно быть обсуждение именно ее. Поэтому давайте закончим с багами, если кто-то хочет может открыть эту тему, я присоединюсь и буду выкладывать туда материалы. Поймите правильно, у меня крайне мало времени, я часто езжу в командировки (вчера писал из Москвы, сегодня из Тулы), вести тему форума я не смогу физически.
ZVI, спасибо, что вы внимательно отнеслись к моей проблеме, я теперь точно знаю, что у меня не бетта версия (я не проверяю, доверяя нашему сис админу)
Дело не только в том, что строка красная. Я использую процедуры перезаписи кода из кода во время исполнения с перекомпиляцией, и в этом случае перекомпиляция не выполняется. И этого вполне достаточно, чтобы не использовать такой подход. Еще учтите тот факт, что в файле может быть не 8-10 API (как в выложенном файле, который находится в начале разработки), а 30-40 штук. Теперь представьте себе массив объявлений самих API, и массив переменных типа LongPtr в различных модулях в разных частях проекта.
bedvit, мы с вами говорим на одном языке, и я поддерживаю, что
Цитата
что для каждого языка есть своя ниша, где он хорошо справляется
поэтому не вижу смысла поддюдюривать друг друга  :D . Я тщательно проверю подключение библиотек в Excel (как будет время), а потом поделюсь результатами.
Давайте все-таки вернемся к теме RibbonFluent, а то мы зашли совсем в другую сторону, заблудились можно сказать)))
Восстановление связи с Ribbon
 
Вот еще один баг вспомнил.
Сообщение, которое изображено на картинке (Err №6) имеет два последствия:
1. переполнение кэша. Например вызванное слишком большим массивом данных, что просто лечится
2. поломка файла). А это уже совсем другое дело. Можно отключить VBA, удалить все коды, перезагрузить комп, но это не поможет. Каждый раз, когда файл будет загружаться, это сообщение будет появляться. Вы сейчас возможно скажите: при чем VBA? При том, что именно в VBA был скомпелирован и запущен код, который привел к необратимым последствиям поломки файла. Что-то сохранилось и вызывает ошибку.
Конечно, такое явление случается редко, но раз в пол года оно лично у меня случается). И причина этого не в кэше, а в неправильно написанном коде, который приводит к поломке.  Не в смысле самого языка а в способе написания, ведь можно по разному написать код для достижения одной и той же цели. А учитывая наследие прошлых версий начала 2000-х, таких способов достаточно много. MS закрытая система, и что происходит при компиляции неизвестно, и неизвестно какой мусор сохраняется. Как правильно заметил bedvit
Цитата
Интерпретатор VBA ...
потому что компиляция условная, скорее интерпритация и проверка
Изменено: Ткач Александр - 17.10.2019 14:52:05
Восстановление связи с Ribbon
 
Высылаю ссылку на файл на google disk (править на 100 kB слишком долго, а пустой не вижу смысла отправлять):
https://drive.google.com/drive/folders/1AS5trm8jDqfkZbn9gdbApu833MJOUUun?usp=sharing

Данный файл является частью проекта по разработке пользовательского интерфейса управления строительными проектами для взаимодействия с 1С:ERP, Project online, SQL server, MSO Access + Excel

Уважаемый ZVI, ваше пожелание выполнено).
Восстановление связи с Ribbon
 
данные о системе
Восстановление связи с Ribbon
 
Добрый день.
Уважаемый bedvit , я не писал о неработоспособности, это явный перебор)). По поводу плюсов я конечно соглашусь, спорить бессмысленно  :D .
По поводу  C# можно привести простой пример разработки не только в Win, но и в Linux (MonoDevelop из Ubuntu Software Center, Visual Studio Code и т.д.). Я думаю вы сами об этом знаете, поэтому сравнение VBA и C# похожа на провокацию  :)  :)  :) .

Уважаемый ZVI, применение операторов #if... else я не советовал для декларирования API функций, потому что неоднократно сталкивался с багами. В иных случаях - пожалуйста. Но я использую другой подход, который на протяжении 12 лет показал самую высокую стабильность: отдельно коды для х32 и х64. Пользователь привык к тому, что подавляющее большинство дистрибутивов различных программ выложены в 2-х вариантах на сайтах разработчиков. Поэтому, когда я кому-то отправляю 2 файла, даже домохозяйка понимает какой нужно открыть)). А дополнительное программирование по замене типов данных переменных и declare  - дело 10-20-30 минут. И такой подход я считаю правильной и надежной практикой.
В  Conditional Compilation Arguments ошибок не было и быть не могло, потому что я не создавал пользовательские аргументы. Я не участвую в 'Программе предварительной оценки Office (Insider)'. Я постараюсь сегодня выложить файл (он на сервере, к которому сейчас у меня нет доступа), чтобы вы могли его посмотреть. Файл с данными, с моей лентой, поэтому сразу напишу вход, если вы разрешите запустить макросы при открытии:
  лог: разработчик (выбрать из списка)
  пар: 123654
Сразу сообщаю высылаю данные о системе.
Есть еще один баг. При запуске кода на Protect, а затем ThisWorkbook.SaveAs AccessMode:=xlShared изменения вступают в силу, но не сохраняются. При следующем открытии снова монопольный доступ, шара не сохраняется. Эти процедуры содержаться в модуле ЭтаКнига (ThisWorkbook for en MSO).
Восстановление связи с Ribbon
 
Коллеги, разве столь важно какая сборка и версия WIN'10'7x64 и MSO'19'16'13x64? Когда в корпоративной сети сотни пользователей, да еще регионы, подобная нестабильность превращается в огромную головную боль. Поэтому для сетевых файлов мы конечно же не используем VBA. Платформо-сборочно-версионно зависимый язык не подходит для таких задач. Есть у MS C#, который поддерживается на порядок лучше. Точно также, как Access не может заменить SQL server. VBA больше подходит для моделирования интерфейса, а Access для моделирования БД. Можно конечно писать надстройки, автоматизировать исполнение определенных задач для персонального использования или небольшой группы. VBA прост в освоении, имеет достойный редактор кодов, доступен, и самодостаточен, поэтому у него есть и перспектива, и большая аудитория юзеров. Я же не принижаю язык, а стараюсь поделиться своим опытом в том, что не стоит использовать при написании кодов. О том, что будет устойчиво работать на практически любой сборке MSO в среде WIN10.
Восстановление связи с Ribbon
 
Добрый день, уважаемые коллеги!
Хочется отметить профессиональный подход bedvit  :idea:!
После того, как я написал, подумал, что нужно будет код приложить для ссылок на библиотеки, чтобы его могли скопировать или повторить. Радостно, что этого делать не пришлось.
Однако проблема с библиотеками в файле access. Я не могу однозначно сейчас утверждать будет ли этот баг в excel, нужно проверить. Но это VBA, не С#, не Java. И ссылка адресована на библиотеку Microsoft Excel object library. При смене версии mso (между 13 и 16) после исполнения кода можно открыть Tools - > References и увидеть missing.
Access конечно не в теме форума, но если вы будете не против, я загружу этот проект, скорее всего в пятницу, запарка на работе. В проекте есть несколько моментов, которые могут быть интересны:
1. Модуль класса индикатор прогресса с формой.
2. Процедура перезаписи кода из кода  "на лету", с последующей перекомпиляцией.
3. Подробная информация по пользователю на базе API.
4. Строка adodb.connection с возможностью одновременной работы в обоих файлах access + excel, подобранная после многочисленных неудачных попыток работать в excel, не выходя из access, а также в real time обновлять данные в excel. В Excel находится набор сводных таблиц, подключенных к базе access.
Восстановление связи с Ribbon
 
Скрытый текст
Уважаемый bedvit, в скриншоте как раз факты). А можно и   серьёзный баг, который выдаст ошибку на старте, и не даст дальше воспользоваться набором объектов. Напишите в макросе код для Reference через GUID для подключения библиотеки, которая по умолчанию не подключена к проекту (например библиотеку Access). Затем воспользуйтесь какими-либо обектами из этой библиотеки. Включите макрос в workbook_open. Сделайте это в MSO 2013, и попробуйте открыть файл на другом компе с  MSO 2016. Можно и наоборот из 2016 в 2013. Ошибки в обе стороны. Библиотека не подключится, как ни странно. Это о совместимости версий, и проскальзываниях в исполнении кода VBA. Таких грубых багов в VB  не было.
Уважаемый sokol92, вы совершенно правильно поняли, и абсолютно правы. Я сделаю небольшую ремарку.
Conditional Compilation Arguments предназначен, чтобы задать аргументы компиляции. Можно написать любое имя константы и присвоить значение (можно и несколько констант задать), например
Код
А=1:В="чужой":С=3.14

а затем использовать для задания условий компиляции. Это свойство сродни пользовательским свойствам проекта, которые также могут быть назначены пользователем.

Посмотрите ссылку, так будет понятнее.

http://dailydoseofexcel.com/archives/2006/02/16/conditional-compilation-arguments/

Константы типа Vba7, Win64 определяются автоматически в зависимости от операционной системы и офиса.

Восстановление связи с Ribbon
 
Приятно, ZVI, что вы вникли в суть проблемы). Но это лишь заметка на этом форуме, потому что я исключил альтернативное декларирование в VBA ещё с момента выхода первых версий mso x64. Корни этой проблемы гораздо глубже, и вызвана отношением самой MS к своему детищу VBA. Я начинал с VB5, и использовал Excel, как источник данных с драйверами  MS, а все коды были в VB. По мере развития VBA, и эволюционирование  VB6 в VB.NET, я не стал эволюционировать))), а для MSO стал использовать VBA. Вот и начались проблемы одна интереснее другой. Я конечно понимаю, что VBA - облегченная версия VB6, но ее уж слишком "облегчили". Поэтому наработанные в vb шаблоны пришлось перерабатывать заново. Я определил для себя набор объектов и конструкций, которые нестабильно работают от компа к компу, от версии к версии. Эти объекты я просто не использую.
ZVI, согласитесь, что мои баги могут всплыть у другого пользователя, и вы не станете каждый раз узнавать номер сборки и подписку. И представьте, что ко мне станут регулярно обращаться наши сотрудники из офисов в Москве, Туле, Рязани, Твери... Я вам могу сказать абсолютно точно, что ПО (win + office), установленное одним и тем же админом, с одного и того же дистрибутива, на одних машинах работает стабильно, на других даёт сбои. Поэтому, изрядно намучившись, я просто исключил коды, которые могут вызвать сбои...
Если интересно могу поделиться своими наблюдениями в области взаимодействия Ribbon Fluent и VBA). В частности, о странной последовательности событий между onLoad и workbook_open))  
Восстановление связи с Ribbon
 
Уважаемые коллеги, уважаемый sokol92. Я прекрасно знаком с Conditional Compilation Arguments, а также с Conditional Compiler Constant типа Win64, Win32,..., Vba7, Mac,... Сам код  
Код
#if Vba7 then 
'  Code is running in the new VBA7 editor 
     #if Win64 then 
     '  Code is running in 64-bit version of Microsoft Office 
     #else 
     '  Code is running in 32-bit version of Microsoft Office 
     #end if 
#else 
' Code is running in VBA version 6 or earlier 
#end if
верен, компилируется и работает! Я же написал, что конструкция #If...else работает в сообщении выше. Не в этом проблема. А проблема в том, что в этой конструкции объявление API x32 в #if OR #else вызывает ошибку! Внимательно посмотрите на скиншоты, вы не поняли о чем я пишу. И именно в Win10 Pro x64, MSO 2016 Pro x64, именно с последними обновлениями. И VBA7=True, и не глючит, и ни одна проверка не выявила причина. Это баг компилятора VBA, о чем я написал в MS. Когда отпишутся о причине, я непременно поделюсь.
И такие проблемы возникают периодически с разными объектами VBA. Именно поэтому я избегаю декларирования функций для x32 и x64, например. Либо 32, либо 64. Гораздо проще в офисе поставить на все рабочие машины ПО MS одинаковой разрядности. Я пишу прикладные программы для решения наших внутри корпоративных задач, и достаточно испытал проблем с обратной совместимостью, и различными версиями Win и MSO.  
Восстановление связи с Ribbon
 
Добрый день, господа.
Если вы имеете ввиду, что конструкция #If...else работает в принципе, я согласен. Вопрос в том для чего ее применять. Декларация API - это не тот случай, и лучше так не делать, потому что может вызвать ряд серьезных проблем в  различных версиях и разрядности приложений MS Office. Так, например, использовать эту конструкцию для декларации API {x32;x64} на Win10 x64 в Excel 2016 x64 не получится в принципе. Т.к. редактор VBA выдаст ошибку, которую я прилагаю в скриншотах.

Одна из значительных проблем VBA - проскальзывание (неисполнение) кода. Кому приходилось сталкиваться с разработкой приложений, знает о чем я пишу. Даже если код работает - не значит, что его нужно использовать! Я накопил собственный опыт по использованию удачных (читай стабильных) приемов при разработке небольших корпоративных приложений на Access, начиная где-то с 2005 г. Есть ряд вполне рабочих конструкций, НО которых стоит избегать. Ярчайший пример - динамическое подключение/отключение библиотек. То, что стабильно никогда не работает, но ведь можно :) ))). Стабильно - это от PC к PC, от версии MSO к версии MSO.

VBA - не Java, обратная совместимость в новых объектах и их методах/свойствах/событиях может отсутствовать, и это вторая очень серьезная проблема.  
Восстановление связи с Ribbon
 
Уважаемый, Johny!
В вашем коде допущена ошибка пункт 4.
Код
Names("RibbonPointer").Value = ObjPtr(ribbon)
записывает не число, а формулу. Например, записав число 33333333,
Код
Names("RibbonPointer").Value =  33333333
вы получите формулу "=33333333",
Код
 lPointer = CLng([RibbonPointer]) =CLng("=33333333")
что приводит к ошибке.
Правильно написать так, чтобы убрать знак равно:
Код
lPointer = CLngPtr(Mid(ThisWorkbook.Names("RibbonPointer").Value, 2))
VBA  (в отличие от VB) не умеет правильно обрабатывать конструкцию типа
Код
#If VBA7 Then
Public Declare PtrSafe Sub CopyMemory Lib "kernel32" _
    Alias "RtlMoveMemory" (ByRef destination As Any, ByRef Source As Any, ByVal length As LongPtr)
#Else
Public Declare Sub CopyMemory Lib "kernel32" _
    Alias "RtlMoveMemory" (ByRef destination As Any, ByRef Source As Any, ByVal length As Long)
#End If
После Else строка останется красной. Поэтому лучше сразу определить код для 64 битной системы - VBA 7
Код
Public Declare PtrSafe Sub CopyMemory Lib "kernel32"  Alias "RtlMoveMemory" (ByRef destination As Any, ByRef Source As Any, ByVal length As LongPtr)
или для 32 битной системы
Код
Public Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (ByRef destination As Any, ByRef Source As Any, ByVal length As Long)
А в остальном оригинальное, простое и отличное решение!
:idea:  :idea:  :idea:  
Изменено: despot69 - 01.10.2019 17:59:39
Страницы: 1
Наверх