Excel VBA Userform Listbox Динамическое контекстное меню с использованием метода .OnAction

Я создал динамическое контекстное меню для Userform Listbox .

Внутри этого Listbox есть файлы серии. Моя цель состоит в том, что при щелчке правой кнопкой мыши по файлу контекстное меню появляется со списком мест расположения папок. Щелчок левой кнопкой мыши по одному из этих мест папок копирует файл в это место.

Для этого я буду использовать метод .CopyFile(Location, Destination, [Overwrite]) .

У меня возникают трудности с динамическим назначением событий .OnAction для каждого добавленного Item .

Userform модуля Userform

 Option Explicit Private Const mCONTEXT_MENU_NAME = "myRightClickListbox" Private m_clsContextMenu As CContextMenu 'Function mySendTo(fName As String) 'MsgBox fName 'End Function Sub mySendTo(fName As String) MsgBox fName End Sub Private Sub ListBox1_MouseDown(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single) Dim myString As String: myString = "C:\myFolder\" Dim FolderName As String: FolderName = Dir("C:\myFolder\", vbDirectory) If Button = 2 Then '*\\Listbox right click context menu On Error Resume Next Application.CommandBars(mCONTEXT_MENU_NAME).Delete 'remove any previous instance On Error GoTo 0 Set m_clsContextMenu = New CContextMenu With CommandBars.Add(mCONTEXT_MENU_NAME, Position:=msoBarPopup) With .Controls.Add(Type:=msoControlPopup, before:=1, temporary:=True) .Caption = "Send to" i = 0 Do While FolderName <> "" If FolderName <> "." And FolderName <> ".." Then If (GetAttr(myString & FolderName) And vbDirectory) = vbDirectory Then i = i + 1 With .Controls.Add(Type:=msoControlButton, before:=i, temporary:=True) .FaceId = 23 .Caption = FolderName .Tag = "t" & FolderName .OnAction = "'mySendTo " & FolderName & "'" '.OnAction = "=mySendTo(" & FolderName & ")" '.Parameter = FolderName End With End If End If FolderName = Dir() Loop End With Set m_clsContextMenu.LBox = Me.ListBox1 End With '*// End If End Sub 

Код модуля модуля CContextMenu

 Public LBox As MSForms.ListBox 

В приведенном выше коде успешно создается контекстное меню с щелчком правой кнопкой мыши для Userform Listbox который состоит из подменю Type:=msoControlPopup содержащего Items для каждой папки в указанном каталоге FolderName .

Я пытаюсь динамически назначать события .OnAction для каждого Item созданного для вызова mySendTo или Function mySendTo . Мне сказали, что вы можете вызывать только Functions по имени таким образом и что вызов Sub с его собственными параметрами завершится ошибкой. Тем не менее я пробовал и то, и другое, похоже, работает. Хотя оба запускают Error: 400 что означает, что Excel пытается вызвать событие.

Оба события просто запускают MsgBox отображающий параметр String (я сделал это для простоты, пока не узнаю, что код работает правильно).

Важно то, что при нажатии каждого Item в подменю он запускает код, который ссылается на конкретный текст Item.Caption – в этом случае – имя FolderName каталоге FolderName (его местоположение).

Я намерен скопировать файлы из Listbox в новую папку назначения, указанную в пункте контекстного подменю.

Я знаю, что я близок к синтаксису .OnAction но не потому ли, что я неправильно использую свою Sub / Function с событиями вызова параметров или потому, что я также пытаюсь динамически назначать событие .OnAction для уже динамически созданного контекстное подменю Item , я просто не могу для жизни понять это.

Если вы вставляете вышеуказанный код в пустой модуль Userform и добавляете Listbox именем «ListBox1», у вас должно быть рабочее контекстное меню с щелчком правой кнопкой мыши с подменю.

Если вы попытаетесь щелкнуть один из этих Items вы также получите сообщение об Error: 400 .

Любая помощь в том, как я могу передать динамический Sub или Function для каждого Item с параметром, являющимся его собственным. .Caption будет высоко оценена, и еще раз спасибо за ваше время.

Г-н Дж

Установите все свои OnAction в общедоступный Sub без параметров. Затем внутри этого Sub используйте Application.CommandBars.ActionControl, чтобы получить конкретный элемент командной строки, который вызвал событие. Затем вы можете получить свойство элемента командной строки, которое идентифицирует, с каким предметом вы имеете дело. Свойство .Parameter – лучший выбор.

В вашем случае вы можете просто использовать свойство Caption, которое я предполагаю … но это опасно, потому что позже вы можете его отформатировать или усечь, или что-то еще. Таким образом, убедитесь, что поле параметра параметра команды является соответствующей папкой (которая у вас уже есть в коде, но закомментирована).

Итак, в вашем исходном коде:

 With .Controls.Add(Type:=msoControlButton, before:=i, temporary:=True) .Caption = FolderName 'etc etc .OnAction = "'MyWorkbookName.xlsx'!mySendTo" .Parameter = FolderName End With 

Кстати, всегда указывайте полное имя макроса в .OnAction. Я узнал об этом через тяжелый опыт. Обязательно всегда указывайте название книги в одинарных кавычках, как указано выше. (Кавычки не всегда нужны, но часто это … и это не повредит всегда иметь его.)

Затем в вашем обработчике событий:

 Public Sub mySend() Dim sourceFolder as String On Error resume Next sourceFolder = Application.CommandBars.ActionControl.Parameter On Error goto 0 if sourceFolder <> "" Then GoOnAndDoWhatever(sourceFolder) End Sub 
  • Ошибка в Userform.Hide внутри Workbook_Deactivate event
  • VBA - копировать текст из Combobox в User и вставлять в цикл на листе excel
  • VBA не правильно вытягивает формат
  • Ссылка на самый недавно добавленный рабочий лист
  • Вставьте данные листа в combobox userform без дублирования - Excel Vba
  • Медленная запись ввода в пользовательскую форму
  • Excel только показывать пользовательскую форму, никогда не показывать книгу
  • Пользовательская форма Excel, местоположение ячейки и дата вставки
  • Использование операторов IF & AND с флажками в пользовательской форме
  • Элемент UserSelection для MultiSelection
  • Заполнение вопросов ComboBox - дублирование значений при каждом выборе поля, а именованный диапазон не заполняется
  • Interesting Posts

    Потрясающее поведение фильтра даты между США и Великобританией Настройки: VBA

    Почему в загрузке защищенного файла XLS запускается дважды.

    Использование цикла в Excel / VBS для заполнения формы

    Excel VBA для изменения размера, цвета и прозрачности маркера на радаре

    Найти и заменить текст

    Автоматическая электронная почта с изменениями в теле – VBA

    Код VBA для цикла Nested for, чтобы посмотреть определенное значение и скопировать всю колонку на другом листе

    SQL запрашивает различные идентификаторы одновременно

    Вложенные математические функции Excel

    Excel VBA: как создать VLOOKUP с уникальным диапазоном и несколькими рабочими листами?

    Сделайте гистограмму с помощью группировки Excel 2010 нестандартным способом

    Почему мой макрос останавливается в строке 14, когда он должен перейти к строке 40?

    .csv-файл, похоже, имеет скрытый делиметр, который распознается Excel, но не Блокнот (и другие программы)

    Обновить промежуточные итоги в файлах excel

    Использование предложения (Where IN) SQL

    Давайте будем гением компьютера.