0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Application.Runを起点にセルの値やユーザーフォームからマクロを呼び出す【ExcelVBA】

Last updated at Posted at 2021-12-09

先日、ハイパーリンクをマクロ実行ボタン化するツイートが気になってたけどなかなか着手できてなくて出遅れ感がある中、先日のこの記事の中でApplication.Runとセルの値でマクロを呼び出すということができたので他のパターンにも手札を増やしてみようという企画。

概要

ハイパーリンクに限らず、セルの値をプロシージャ名にしておけば各イベントをトリガーにマクロを実行できる、というもの

image.png
ハイパーリンクをトリガーにする場合は適当に自セル参照とかさせておけばいい。

また、ユーザーフォームのあれこれにプロシージャ名を持たせておいてもいける。

image.png

標準モジュール:全パターン共通で呼ぶやつ

Option Explicit

Sub CallProc(ProcName)
  On Error GoTo Err
  Dim wbName: wbName = ThisWorkbook.Name
  Application.Run wbName & "!" & ProcName
  Exit Sub
Err:
  Select Case Err.Number
    Case Is = 1004 '何もしない。呼び出すものが無いときのエラーNoなので。
  End Select
End Sub

Sub test1()
  MsgBox 1
End Sub

Sub test2()
  MsgBox 2
End Sub

シートモジュール

Worksheet_FollowHyperlinkから

Private Sub Worksheet_FollowHyperlink(ByVal Target As Hyperlink)
  Call CallProc(Target.Name)
End Sub

Worksheet_BeforeDoubleClickから

Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean)
  Call CallProc(Target.Value)
End Sub

Worksheet_SelectionChangeから

Private Sub Worksheet_SelectionChange(ByVal Target As Range)
  Call CallProc(Target.Value)
End Sub

ちゃんと見てないけどセルの値を引数に持つやつなら何でもいける

ユーザーフォーム

image.png

コマンドボタン:オブジェクト名を拾うパターン

ボタンでいうと上のやつ
Private Sub test1_Click()
  Call CallProc(Me.test1.Name)
End Sub

コマンドボタン:キャプションを拾うパターン

ボタンでいうと下のやつ
Private Sub CommandButton1_Click()
  Call CallProc(Me.CommandButton1.Caption)
End Sub

リストボックス

Private Sub UserForm_Initialize()
  With Me
    .ListBox1.AddItem "test1"
    .ListBox1.AddItem "test2"
  End With
End Sub

Private Sub ListBox1_DblClick(ByVal Cancel As MSForms.ReturnBoolean)
  With Me.ListBox1
    Dim myIndex: myIndex = .ListIndex
    Dim myItem: myItem = .List(myIndex)
    Call CallProc(myItem)
  End With
End Sub

リストビュー

Proc名の列幅を極小にすればProc名を隠して略称だけ表示することもできる
(ListViewの構造がイマイチ理解できていないのでそのあたりはご愛嬌)

    With .ColumnHeaders
      .Add 1, "key1", "略称", 50
      .Add 2, "key2", "Proc名", 50
    End With

Private Sub UserForm_Initialize()
  Call SetListView
End Sub

Private Sub ListView1_DblClick()
  Dim buf
  buf = Me.ListView1.SelectedItem.ListSubItems.Item(1).Text
  Call CallProc(buf)
End Sub

Private Function myProcs_()
  Dim myArr(1)
  myArr(0) = Array("てすと1", "test1")
  myArr(1) = Array("てすと2", "test2")
  myProcs_ = myArr
End Function

Private Sub SetListView()
  Dim myProcs
  myProcs = myProcs_

  With Me.ListView1
    .View = lvwReport
    .LabelEdit = lvwManual
    .HideSelection = False
    .AllowColumnReorder = True
    .FullRowSelect = True
    .Gridlines = False
    
    With .ColumnHeaders
      .Add 1, "key1", "略称", 50
      .Add 2, "key2", "Proc名", 50
    End With
    
    Dim cnt
    For cnt = 0 To UBound(myProcs)
      With .ListItems.Add
        .Text = myProcs(cnt)(0)
        .SubItems(1) = myProcs(cnt)(1)
      End With
    Next
  End With
End Sub

妄想

プロシージャリストを自動で取得することもできそう

こんなのを使えばあんなこともできるかも

他ブックのマクロも呼び出せそう

wbNameに投げ込むブック名を他ブックにしてやれば他ブックのマクロも呼び出せそう(というか他ブックのマクロを呼ぶのが本来の用途?)

  Dim wbName: wbName = ThisWorkbook.Name
  Application.Run wbName & "!" & ProcName

引数つきで渡す方法もここにあります。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?