Консультация № 177919
18.04.2010, 13:14
35.77 руб.
0 62 2
'Уважаемые эксперты подскажите имеются рекомендации по поводу создания контестного меню
'выполняю его ничего не происходит за исключением того, что появляется какой то квадратик и вроде подвисает машина, почему???

Application.CommandBars.Add "Имя контекстного меню", msoBarPopup
Application.CommandBars("Имя контекстного меню").ShowPopup

With CommandBars("Имя контекстного меню")
'Установка указателя на объект добавляющий пункт меню
Set mButton = .Controls.Add(Type:=msoControlButton, ID:=850)
With mButton
'задание свойств пункта меню
.Caption = "Мой пункт"
.OnAction = "МойПунктик"
End With
End With

Чем отличаются друг от друга ?????? строки:
.Caption = "Мой пункт"
.OnAction = "МойПунктик"


'А также подскажите:
If 83 <> 81 Or 81 <= 80 Then
Beep 'почему заходит в эту строку ????????????????????????????????7
End If

If 83 <> 81 Or 81 >= 80 Then
Beep
End If

Обсуждение

Неизвестный
23.04.2010, 21:08
общий
Ципихович Эндрю:
1. msoBarTypePopup - всплывающее меню = 2
msoBarTypeNormal - панель инструментов = 0
msoBarTypeMenuBar - строка меню = 1

2. Количество = Application.CommandBars.Count
Неизвестный
24.04.2010, 01:07
общий
Измалков Эдуард Леонидович:
Получается что надо написать так:
Dim CB As CommandBar
Dim i As Integer
i = 0
Количество = Application.CommandBars.Count
For CB = 1 To Количество 'здесь выделяет CB и сообщение Type mismatch, почему, что не так???????????????????????????????????
А = CB.Type
If CB.Type = msoBarTypePopup Then
i = i + 1

' Это код, чтобы вывести CB.Name & " " & CB.NameLocal. Просто я не знаю как в Word выводить текст, т.к. работаю в основном в Excel, поэтому вывожу как нашел.
ThisDocument.Paragraphs.Add
ThisDocument.Paragraphs(i).Range.Text = CB.Name & " " & CB.NameLocal
End If
Next CB
Неизвестный
24.04.2010, 10:06
общий
Ципихович Эндрю:
потому что CB имеет тип CommandBar, а как "i", так и "Количество" - целочисленные переменные. Если Вы хотите переписать этот цикл таким образом, то нужно его кардинально менять:
Dim CB As Integer, A As Integer
Dim i As Integer
Количество = Application.CommandBars.Count
For CB = 1 To Количество ' теперь в цикле используется переменная целого типа - счетчик
А = Application.CommandBars(CB).Type ' В переменную А сохраняется тип текущей панели иструментов
If A = msoBarTypePopup Then
i = i + 1

' Это код, чтобы вывести CB.Name & " " & CB.NameLocal. Просто я не знаю как в Word выводить текст, т.к. работаю в основном в Excel, поэтому вывожу как нашел.
ThisDocument.Paragraphs.Add
ThisDocument.Paragraphs(i).Range.Text = CB.Name & " " & CB.NameLocal
End If
Next CB
Неизвестный
24.04.2010, 11:39
общий
Измалков Эдуард Леонидович:
В строке: ThisDocument.Paragraphs(i).Range.Text = CB.Name & " " & CB.NameLocal
Выделает СВ и сообщение Инвалид qualifier?? Что не так???
Неизвестный
24.04.2010, 12:13
общий
Измалков Эдуард Леонидович:
Как так получается, что в коде сегодня, 10:06 ::
пока не дождавшись ответа я заремарчиваю строку ThisDocument.Paragraphs(i).Range.Text = CB.Name & " " & CB.NameLocal

Получаю в чистом, новом документе Количество=150, прогоняю его, получаю i=0
То есть всех всплывающих меню = 150, а всплывающих меню =0??????
Также скажите, если Вы указали Dim i As Integer, тогда перед циклом не надо указазывать i=0
Как нгазывается всплывающее меню появляющееся когда курсов в таблице??????
Неизвестный
24.04.2010, 12:35
общий
Измалков Эдуард Леонидович:
Как же так получается, что я пишу:
Private Sub Document_Open()
With Application.CommandBars("Text")
With .Controls.Add(msoControlButton)
.OnAction = "МояПроцедура"
.Caption = "Первый пункт"
End With
End With
End Sub
Но пункт меню "Первый пункт" наблюдаю в чистом документе???, я так понимал, что он должен был появится только при условии если курсор будет на тексте??????
Неизвестный
24.04.2010, 13:49
общий
Ципихович Эндрю:
По порядку:
1. Недоглядел, CB в этом коде уже совсем другая переменная, поэтому ее нужно заменить в этой строке на Application.CommandBars(CB)
2. Занулять желательно, потому что VBA вроде должен их занулять, но чтобы быть полностью уверенным лучше сделать это самому. Применимо к таблице существует 8 различных меню. Тот, который вызывается в случае нахождения курсора в таблице, называется "Table Text". (чтобы получить полный их список, выполните код, который выведет список всех меню)
3. Так и должно быть. Практически вся область документа по умолчанию предназначена для ввода текста, поэтому и вызывается меню "Текст". Вот если Вы вставите какой-либо объект, тогда и будет вызываться меню, соответствующее этому объекту.

С учетом изменений код для вывода всех вспылывающих меню будет выглядеть следующим образом:
Sub СписокМеню()
Dim CB As Integer, A As Integer
Dim i As Integer, Количество As Integer
i = 0
Количество = Application.CommandBars.Count
For CB = 1 To Количество
A = Application.CommandBars(CB).Type
If A = msoBarTypePopup Then
i = i + 1
ThisDocument.Paragraphs.Add
ThisDocument.Paragraphs(i).Range.Text = Application.CommandBars(CB).Name & " " & Application.CommandBars(CB).NameLocal
End If
Next CB
End Sub
Неизвестный
24.04.2010, 14:19
общий
Измалков Эдуард Леонидович:
Немного поправил Ваш код, он работает, кому интересно, всего 63 всплывающих меню:
'создать список всплывающих меню, посчитать их количество
Dim CB As Integer, A As Integer
Dim i As Integer
i = 0
Количество = Application.CommandBars.Count
For CB = 1 To Количество
F = Application.CommandBars(CB).Name
G = Application.CommandBars(CB).Type
W = Application.CommandBars(CB).NameLocal

'msoBarTypePopup - всплывающее меню = 2
'msoBarTypeNormal - панель инструментов = 0
'msoBarTypeMenuBar - строка меню = 1

If G = msoBarTypePopup Then
Selection.TypeText Text:=F & "-" & W & ChrW(13)
i = i + 1
End If
Next CB

MsgBox$ i, vbOKOnly, "Список всплывающих меню"

________________________________________________________
Вот их список
________________________________________________________

Drop Caps-Буквицы
Endnotes-Концевые сноски
Fields-Поля
Display Fields-Отобразить поля
Field Display List Numbers-Поле LISTNUM
Form Fields-Поля формы
Footnotes-Сноски
Frames-Рамки
Headings-Заголовки
Linked Headings-Связанные заголовки
Script Anchor Popup-Меню привязки
Lists-Списки
Inline Picture-Встроенный рисунок
Inline Canvas-Встроенное полотно
Horizontal Line Popup-Меню горизонтальных линий
Tables-Таблицы
Table Cells-Ячейки таблицы
Table Headings-Заголовки таблицы
Table Lists-Списки таблиц
Table Pictures-Шаблоны таблиц
Table Text-Табличный текст
Whole Table-Вся таблица
Linked Table-Связанная таблица
Text-Текст
Linked Text-Связанный текст
Font Popup-Меню шрифта
Font Paragraph-Шрифт для абзаца
Format Inspector Popup in Normal Mode-Format Inspector Popup in Normal Mode
Format Inspector Popup in Compare Mode-Format Inspector Popup in Compare Mode
Spelling-Орфография
Grammar-Грамматика
Grammar (2)-Грамматика (2)
Format consistency-Согласованность формата
Background Proofing Status Bar-Строка состояния фоновой проверки
Track Changes-Исправления
Frame Properties-Свойства рамки
Hyperlink Context Menu-Контекстное меню гиперссылки
AutoSignature Popup-Меню автоподписи
Field AutoText-Поле автотекста
Document Map-Схема документа
Shapes-Фигуры
Curve-Кривая
Curve Node-Узел кривой
Curve Segment-Сегмент кривой
Floating Picture-Перемещаемый рисунок
Canvas Popup-Canvas Popup
OLE Object-Объект OLE
ActiveX Control-Элемент ActiveX
WordArt Context Menu-Контекстное меню WordArt
Rotate Mode-Режим поворота
Comment-Примечание
Organization Chart Popup-Organization Chart Popup
Diagram-Схема
Connector-Соединительная линия
Track Changes Indicator-Индикатор исправлений
Chinese Translation-Перевод на китайский язык
Address Block Popup-Address Block Popup
Greeting Line Popup-Greeting Line Popup
Inline ActiveX Control-Встроенный элемент ActiveX
XML Structure Node Popup-Меню узла структуры XML
XML Error Options-Ошибка XML: варианты
Ink Comment-Рукописное замечание
System-Система
Неизвестный
24.04.2010, 15:22
общий
Измалков Эдуард Леонидович:
Всё прекрасно, за исключением одного, открыл документ, просто глянул закрывая его, спрашивает нужно ли сохранить изменения
Пользователь знает, что ничего не делал, а тут ему такой вопрос, неудобства, как избежать???
А второе нудобство из ряда вон выходящее, открыл документ, просто глянул закрывая его, спрашивает нужно ли сохранить изменения нажал отмену, а потом снова пытаешся закрыть документ получаю ошибку: Недопустимый вызов процедуры, неудобства!!!!!!!!!, как избежать???
Неизвестный
24.04.2010, 15:43
общий
Ципихович Эндрю:
Насчет первого не могу сказать, у меня все гладко, ничего не спрашивает. Второе - все правильно, код процедуры "Private Sub Document_Close()" выполняется перед закрытием. И вопрос он задает уже после выполнения этого кода. Вы нажали отмена, а пункт меню он уже удалил. Соответственно, когда Вы закрываете документ во второй раз, этого пункта уже нет, а VBA пытается его еще раз удалить. Можно добавить туда строку "On Error Resume Next" перед удалением пункта меню, либо поставить проверку на его наличие перед удалением, либо удалить все невстроенные пункты (у которых признак "BuiltIn" = False)
Неизвестный
24.04.2010, 16:57
общий
Измалков Эдуард Леонидович:
Из перечисленных мне по нутру
поставить проверку на его наличие перед удалением
удалить все невстроенные пункты (у которых признак "BuiltIn" = False)
Подскажите как сделать?????
И вроде последнее, Вы говорите:
Нужно создать обычный модуль с текстом процедуры "МояПроцедура"
Sub МояПроцедура()
MsgBox "Вроде все работает", vbOkOnly
End Sub
Подскажите как её запускать по нажатию клавиши, то есть как сказать условие, если нажато 9, тогда ....
Спасибо заранее!!!!!!!!

Неизвестный
24.04.2010, 17:19
общий
Dim УдаляемыйПункт As CommandBarConrol

For Each УдаляемыйПункт In Application.CommandBars("Text")
If УдаляемыйПункт.Caption = "Первый пункт" Then УдаляемыйПункт.Delete ' либо же If УдаляемыйПункт.BuiltIn = False Then УдаляемыйПункт.Delete
Next УдаляемыйПункт

На второй вопрос пока ответа не знаю - в Excel это делается функцией OnKey. В Word ее нет, нужно искать, как можно реализовать.
Неизвестный
24.04.2010, 18:21
общий
Измалков Эдуард Леонидович:
Выделяет УдаляемыйПункт As CommandBarConrol
И сообщение Юзер Дефинед Типе Нот Дефинед

А также предпочтительный вариант где If УдаляемыйПункт.BuiltIn = False Then УдаляемыйПункт.Delete, чтобы не указывать его имя
Я так понимаю переменной УдаляемыйПункт надо присваивать значение???
И можно сразу чтобы был один цикл, а то получается, что для "Text" один цикл, а следом нужно делать например цикл по "Table Text"
Неизвестный
24.04.2010, 18:36
общий
Ципихович Эндрю:
пропустил букву. Чтобы одним циклом - не получится, только если вложенный добавить:
Dim УдаляемыйПункт As CommandBarControl
Dim Меню as CommandBar
For Each Меню In Application.CommandBars ' для каждого меню
For Each УдаляемыйПункт In Меню.Controls ' каждый элемент меню
If УдаляемыйПункт.BuiltIn = False Then УдаляемыйПункт.Delete
Next УдаляемыйПункт
Next Меню
Неизвестный
24.04.2010, 20:51
общий
Измалков Эдуард Леонидович:
По тому последнему нерешённому вопросу
Как при помощи ВБА поставить условие в документе Ворд для запуска мною созданного контекстного меню по нажатию клавиши, то есть как сказать условие, если нажато 9, тогда .... люди подсказывают
1. проверяй условие в обработчике события приложения WindowBeforeRightClick
2.На 9 не сделаешь.Lasciate ogni speranza, voi ch'entrate.
Это мне ничего не говорит, может Вам поможет????
Неизвестный
24.04.2010, 21:52
общий
Ципихович Эндрю:
Обработчик не поможет, т.к. он вызывается при нажатии ПКМ. А Вам надо при нажатии на определенную кнопку на клавиатуре. Вторая фраза мне ни о чем не говорит, я так понимаю там какой-то французко-итальянский язык, я таких не знаю. Попробуйте задать отдельный вопрос на эту тему, может кто знающий откликнется.
Неизвестный
24.04.2010, 22:06
общий
Ципихович Эндрю:
Хотя может я не совсем понимаю, чего Вы хотите. Если задача состоит в том, чтобы сначала вызвать стандартное контестное меню с нашим пунктом, а потом наш пункт вызвать с помощью быстрой клавиши (как допустим "Вырезать" вызывается при нажатии буквы "В"), то это достаточно легко реализуется.
В примере пункт меню называется "Первый пункт". Его можно повесить только на букву, которая есть в названии. Допустим Вы хотите, чтобы он вызывался при нажатии на "П", тогда надо всего лишь в Document_Open() поменять строку
.Caption = "Первый пункт" на
.Caption = "&Первый пункт".
т.е. знак "&" перед любой буквой в свойстве Caption пункта меню (собственно в самом меню тоже) назначает эту букву для быстрого вызова данного пункта.
Неизвестный
24.04.2010, 23:43
общий
Измалков Эдуард Леонидович:
Спасибо это то что я спрашивал, даже нужную букву подчёркивает
Теперь уже наверное последнее например добавил строку меню: Добавить 123456789
Смысл заключается в том чтобы добавить в таблице одну, две или ... строки согласно нажатой цифры, возможно ли это реализовать????
И как то странно в Ворде насколько я увидел меню Text-Текст не отличается когда например курсор находится на тексте, на выделенном тексте, возможно ли это разграничить програмно????
То есть если длина выделенного более 0 тогда одно меню
Если выделенное равно 0 тогда второе меню
Спасибо
Неизвестный
25.04.2010, 12:12
общий
Ципихович Эндрю:
В этом случае придется опять действовать с помощью класса. Кстати, вчера еще нашел такую вещь: если макрос назвать AUTOOPEN, то он будет выполняться при открытии документа, т.е. заменяет собой Document_Open. То же самое и с AUTOCLOSE. Кстати, хотел бы Вас предупредить насчет удаления всех невстроенных меню. Я так понимаю Вы все это делаете не для себя одного, а для предприятия. Вполне может случится такое: пользователь создал свое меню и закрепил на нем наиболее часто используемые им кнопки. Тут приходите Вы со своим макросом, и после этого у пользователя пропадает его годами используемое меню. Поэтому я в качестве примера в начале и использовал имена пунктов. Конечно если Ваши пункты будут только во всплывающих меню (туда пользователь явно ничего не добавит), то можно выкрутиться следующим образом - поставить еще условие, если меню всплывающее, то его удалить, иначе не трогать. В связи с этими открытиямипривожу код

Модуль класса с именем "ОбработкаПКМ":
Код:
Public WithEvents App As Application

Private Sub App_WindowBeforeRightClick(ByVal Sel As Selection, Cancel As Boolean)
УдалениеМеню ' Удаляем старые пункт меню, если они существуют
If Sel.Document.Name = ThisDocument.Name Then ' обработчик будет срабатывать в любом документе, а нужен только текущий, поэтому проверка имени документа
If Sel.Style.Type = wdStyleTypeParagraph Then ' Проверка местонахождения курсора - в данном случае текст
If Len(Sel.Text) > 0 Then ' Проверка выделен какой-либо текст или нет
МенюВыделение ' Выполняется при выделении текста
Else
МенюСимвол ' Выполняется в случае когда ничего не выделено
End If
End If
End If
End Sub

' при выходе из документа (переключении на другой документ) меню также удаляется
Private Sub App_WindowDeactivate(ByVal Doc As Word.Document, ByVal Wn As Word.Window)
If Doc.Name = ThisDocument.Name Then УдалениеМеню
End Sub


И код обычного модуля:
Код:
Public wordApp As New ОбработкаПКМ

Sub AUTOOPEN()
Set wordApp.App = Application
End Sub

Sub AUTOCLOSE()
УдалениеМеню
End Sub

Sub УдалениеМеню()
Dim Меню As CommandBar, ПунктМеню As CommandBarControl
For Each Меню In Application.CommandBars
If Меню.Type = msoBarTypePopup Then
For Each ПунктМеню In Меню.Controls
If ПунктМеню.BuiltIn = False Then ПунктМеню.Delete
Next ПунктМеню
End If
Next Меню
End Sub

Sub МенюСимвол()
With Application.CommandBars("Text").Controls.Add(msoControlButton)
.Caption = "&Один символ"
.OnAction = "Символ"
End With
End Sub

Sub МенюВыделение()
With Application.CommandBars("Text").Controls.Add(Type:=msoControlButton)
.Caption = "В&ыделение"
.OnAction = "Строка"
End With
End Sub

Sub Символ()
MsgBox "Нет выделения"
End Sub

Sub Строка()
MsgBox "Выделение есть"
End Sub

Неизвестный
25.04.2010, 12:14
общий
Измалков Эдуард Леонидович:
Вот я заработался, всё сделал, протестировал, а именно после открытия любого Вордовского документа например поместив курсор в таблице
добавил строку в контестном меню: Добавить стрелка вниз 123456789 строк в таблице
Но тут ещё мысли пришли, хотел поправить но увы не смог найти куда я запрятал строки добавляющие эту строку меню
Перерыл всё, не нашёл может Вы подскажите как она появилась, куда подевались строки её добавляющие, я искал сам, искал поиском &123456789, нет ничего, мистика какая то
Если бы сам это не сделал не поверил бы!!!!!!!!!
Сам Нормал дот https://rfpro.ru/upload/2204
ТО есть временно Вам Нормал дот свой надо переименовать и поставить скачанный, мой Нормал дот. Пожалуйста, теряюсь без подсказки
Неизвестный
26.04.2010, 20:06
общий
Измалков Эдуард Леонидович:
Получил из личного ящика ответ от Вас:
Этой функции там действительно нет. Скорее всего саму функцию Вы создали в каком-либо файле, а не в шаблоне.
Тогда может я не понимаю смотрите в папке Шаблоны у меня находится Нормал дот, тот который я выгрузил на портал
Открываю любой чистый, новый документ Ворд, нажимаю правую клавишу миши видите там два последних пункта меню УК И УПК
Затем делаю следующее переименовыаю свой нормал дот в нормал дот1
Открываю любой чистый, новый документ Ворд, естественно вместе с открытием документа там пояляется в папке новый, свежий, ничем и никем не тронутый нормал дот нажимаю правую клавишу миши и конечно же там не будет два последних пункта меню УК И УПК, значит я мыслю что они запрятаны в Нормал дот, разве не так???
Но в то же время я верю и Вам и себе что нет там функций по созданию контекстного меню, мистика какая то??!!! Что это может быть????

Неизвестный
26.04.2010, 21:16
общий
Ципихович Эндрю:
Немного не так - в нормал дот нету функции, вызываемой Вашим пунктом меню. Т.е. пункт меню он создает, а самой функции, которая должна вызываться при выборе этого пункта в нем нет.
Неизвестный
27.04.2010, 05:26
общий
Измалков Эдуард Леонидович:
Я так понял пункт меню он, Нормал дот создает, и конечно же и удаляет????
Но где это я найти не могу???? Подскажите!!!
Неизвестный
27.04.2010, 05:39
общий
Измалков Эдуард Леонидович:
И забыл сразу спросить Вы говорите:самой функции, которая должна вызываться при выборе этого пункта в нем нет.
Но тогда как же получается функции, которая должна вызываться при выборе пункта меню в Нормал дот нет а я открываю чистый документ и в нём меню работае по быстроой клавише??? Почему так?? Ведь документ чистый в нём еще ничего нет!!
Неизвестный
27.04.2010, 13:28
общий
Ципихович Эндрю:
я так понял, что настройки менюшек хранятся в шаблоне. Значит Вы выполнили макрос, который создал эти пункты, потом их не удалили, и они теперь сидят в шаблоне. Т.е. любой документ, созданный из этого шаблона считает, что эти пункты так и должны быть, хотя самого макроса, их создающего, уже нет.
Неизвестный
27.04.2010, 19:57
общий
Измалков Эдуард Леонидович:
Вы говорите:я так понял, что настройки менюшек хранятся в шаблоне
Подскажите где????
Неизвестный
01.05.2010, 12:14
общий
Измалков Эдуард Леонидович:
В контекстном меню всё понял
Всё сделал, устривает, на седьмом небе, но поправить то что сделал не могу, не могу найти код где поправить
Если делать так что могу найти код где править получается то одно то другое, а именно:
Или после открытия документа спрашивает сохранить ли его, не нравится мне это ещё спрашивает два раза Баден Баден какой то, так как я открываю с шаблона
Спрашивает сохранить ли документ, сохранить ли шаблон
Или ещё бывают случаи всё хорошо ничего не спрашивает но самостоятельно изменяется Нормал дот это мне тоже не приемлимо
Есть ли выход?????
Неизвестный
01.05.2010, 12:44
общий
Ципихович Эндрю:
Можно Ваш файлик и более-менее подробное описание всех ошибок. Так не могу ответить, т.к. сам с таким не сталкиваюсь.
Неизвестный
01.05.2010, 13:03
общий
Измалков Эдуард Леонидович:
Пришлю завтра, нет Вин рара
Неизвестный
01.05.2010, 13:17
общий
Ципихович Эндрю:
не знаю, посчитают ли это рекламой или еще чем, но поищите в интернете 7z, он бесплатен и умеет создавать zip архивы
Форма ответа