Поиск  Пользователи  Правила 
Закрыть
Логин:
Пароль:
Забыли свой пароль?
Регистрация
Войти
 
Страницы: Пред. 1 2
RSS
Восстановление связи с Ribbon
 
Цитата
Ткач Александр написал: данные о системе
Александр, спасибо, записал номер версии. Удалите , пожалуйста, 2-ю картинку с кодом продукта.
 
См. ниже
Изменено: ZVI - 17 Окт 2019 17:53:41
 
Цитата
Ткач Александр написал: Высылаю ссылку на файл
Спасибо, достаточно было пустого файла с проблемным кодом.
Вставил в модуль API_function вместо строки с RtlMoveMemory такой код:
Код
#If VBA7 Then
  Public Declare PtrSafe Sub RtlMoveMemory Lib "kernel32" (ByRef destination As Any, ByRef Source As Any, ByVal length As LongPtr)
#Else
  Public Declare Sub RtlMoveMemory Lib "kernel32" Alias "RtlMoveMemory" (ByRef destination As Any, ByRef Source As Any, ByVal length As Long)
#End If

Компилируется без проблем, строка после #Else помечена красным и это нормальное описанное в документации поведение VBA,  означающее, что данный фрагмент в 64-битной версии не используется.
Проверьте, пожалуйста, у Вас с этим файлом при подобной замене кода выводится сообщение об ошибке при  VBE - Debug - Compile VBAProject ?
Изменено: ZVI - 17 Окт 2019 17:54:51
 
Цитата
ZVI написал:
Удалите , пожалуйста, 2-ю картинку с кодом продукта.
Владимир, добрый день. Это не ключ. Страшного ничего нет.
 
Михаил, спасибо за уточнение  :)
 
Ткач Александр, я привел сравнение с плюсами не для того чтобы выделить какой либо язык, а наоборот, сказать о том, что для каждого языка есть своя ниша, где он хорошо справляется. Наверное теория Дарвина работает и здесь, раз жив, значит востребован. Ведь не поспоришь... Вот вы на Шарп какой функционал перевели? В какой форме: надстройка VSTO, Excel-DNA, СОМ-библиотека или обычная процедурная? А ведь еще есть возможности написать решения для Excel на (VBA - уже знаем, вам не подходит :) ), C/C++, JavaScript (коллеги дополните, если что упустил). Провокационный вопрос, какой из них лучший, и почему именно он?
Собственно заканчиваю: ИМХО, лучшего нет.
Да и конечно Владимир прав, обсуждение багов VBA - лучше в отдельную тему, не делать кашу здесь.
К сожалению, сейчас не могу протестировать решение предложенное Владимиром, но за темой слежу.
«Бритва Оккама» или «Принцип Калашникова»?
 
Добрый день коллеги!
Я поддерживаю предложение о том, что в данной теме должно быть обсуждение именно ее. Поэтому давайте закончим с багами, если кто-то хочет может открыть эту тему, я присоединюсь и буду выкладывать туда материалы. Поймите правильно, у меня крайне мало времени, я часто езжу в командировки (вчера писал из Москвы, сегодня из Тулы), вести тему форума я не смогу физически.
ZVI, спасибо, что вы внимательно отнеслись к моей проблеме, я теперь точно знаю, что у меня не бетта версия (я не проверяю, доверяя нашему сис админу)
Дело не только в том, что строка красная. Я использую процедуры перезаписи кода из кода во время исполнения с перекомпиляцией, и в этом случае перекомпиляция не выполняется. И этого вполне достаточно, чтобы не использовать такой подход. Еще учтите тот факт, что в файле может быть не 8-10 API (как в выложенном файле, который находится в начале разработки), а 30-40 штук. Теперь представьте себе массив объявлений самих API, и массив переменных типа LongPtr в различных модулях в разных частях проекта.
bedvit, мы с вами говорим на одном языке, и я поддерживаю, что
Цитата
что для каждого языка есть своя ниша, где он хорошо справляется
поэтому не вижу смысла поддюдюривать друг друга  :D . Я тщательно проверю подключение библиотек в Excel (как будет время), а потом поделюсь результатами.
Давайте все-таки вернемся к теме RibbonFluent, а то мы зашли совсем в другую сторону, заблудились можно сказать)))
 
Продолжая тему 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)


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
Я постарался подробнее закомментировать)
Изменено: Ткач Александр - 18 Окт 2019 16:21:41
 
Цитата
Ткач Александр написал: ... я бы не стал использовать именованный диапазон для записи ссылки на объект ленты IRibbonUI,
Александр, в варианте Автора темы не используется именованный диапазон, использукется имя без привязки к ячейкам, это имя легко сделать невидимым, если что. Поэтому недостатка по п.1 нет.  А замечание по п.2  - на любителя, можно было и Evaluate использовать, да и избавление от "=" код не перегружает, зато нет цикла, например (есть здесь их нелюбители , не я) :)
Изменено: ZVI - 18 Окт 2019 20:26:00
 
Цитата
Ткач Александр написал:
поэтому не вижу смысла поддюдюривать друг друга
Не имею такой привычки, интересно чисто с профессиональной позиции, что удалось перевести с VBA на С#.NET, как это взаимодействует с VBA, Excel.
Цитата
Ткач Александр написал:
Дело не только в том, что строка красная. Я использую процедуры перезаписи кода из кода во время исполнения с перекомпиляцией, и в этом случае перекомпиляция не выполняется.
Не использовал никогда такие конструкции, для чего они, какой функционал несут?
По теме, за вариант кода плюсую и согласен с Владимиром, на любителя, но возможно кто-то будет использовать именно ваш.
«Бритва Оккама» или «Принцип Калашникова»?
 
Цитата
despot69 написал: вы получите формулу "=33333333",
Код
Pointer = CLng([RibbonPointer]) =CLng("=33333333")
что приводит к ошибке.
Как-то мы увлеклись интересными высказываниями, но в цитате выше утверждение неверное.
У Автора темы все правильно: [RibbonPointer] = Evaluate("RibbonPointer") и выдает требуемое число, так как RibbonPointer это не переменная, а имя.
 
Добрый день, уважаемые коллеги!
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 Окт 2019 18:45:00
 
Выкладываю таблицу всех элементов ribbon mso excel: вкладки кнопки, всплывающие меню и т.д.
Есть имена и id. Скачал у MS в этом году. Возможно это самая полная таблица.
Страницы: Пред. 1 2
Читают тему (гостей: 1)
Наверх