Excel (VBA)

Excel VBAに関するフォーラムです。
  • 解決済みのトピックにはコメントできません。
このトピックは解決済みです。
質問

 
(Windows 10 Pro : Excel 2016)
CallByNameのオブジェクトを変数で指定する方法
投稿日時: 19/09/02 13:35:25
投稿者: あべ

よろしくお願いします。
 
設定シートにいれてあるセルの値を読み込み、
CallByNameで使いたいのですが、オブジェクト名の指定がいけず困っています。
 
 

Sub TEST()

    Dim obj             As Object
    Dim strProc         As String
    Dim strCallType     As String
    
    strProc = Range("B1").Value
    strCallType = Range("C1").Value
    
    Set obj = ""  'Range("A1").Value ★
    
    
    Call VBA.CallByName(obj, strProc, strCallType)

End Sub

 
上記の★のところでオブジェクトを入れる方法が見出せず止まっております。
CallByNameでは、「オブジェクト本体」を入れないと動かず、文字列で指定してもエラーとなってしまいます。
 
    If Range("A1").Value = "Application" Then Set obj = Application
    If Range("A1").Value = "Thisworkbook" Then Set obj = ThisWorkbook
    If Range("A1").Value = "Activesheet" Then Set obj = ActiveSheet

 
上記のようにIFやSELECTも考えましたが、CallByNameで指定できるオブジェクト全部を書くのは美しくないと思いました(そもそも使えないオブジェクトもあるのかもしれず全部書けないですが)。
 
 
このような状態ですが何か良い方法ございますでしょうか?
 
なお、用途は使用するオブジェクトとその機能をガリガリとハードコードせずに
シート上で管理するようにしたいと思っています。
よろしくお願い致します。

回答
投稿日時: 19/09/02 16:46:28
投稿者: mattuwan44

要はマクロ実行後に、文字列(名前)でオブジェクトを指定(特定)するようにしたい
ということですよね?
 
そんなことが出来るか、オブジェクトブラウザでそれっぽいものを検索してみる位しか
思いつきません。
 

Sub test()
    Dim obj As Object
    
    Set obj = getobj(Range("A1").Value)
    
    On Error Resume Next
    CallByName obj, Range("B1").Value, VbGet
End Sub

Function getobj(sName As String) As Object
    Dim o As Object
    For Each o In Application.UsedObjects
        If o.Name = sName Then
            Set getobj = o
        End If
    Next
End Function

 
試してないけど、こういうことですかね?
第3引数も文字列で指定するなら、Selectcase等で変換する自作関数を作るのかなぁ。。。。
 
この方法では、
Thisworkbook
Activesheet
というような指定は出来なさそうですが。。。
 

回答
投稿日時: 19/09/02 17:55:30
投稿者: kumatti
投稿者のウェブサイトに移動
回答
投稿日時: 19/09/02 18:02:05
投稿者: simple

できないと思います。
それは、文字列をコードの一部とみて、
それを"評価する"ということですが、
そういう機能は、VB6という言語には備わっていません。
(言語のなかにはそうした機能を持つものもありますが)
 
よくある話題、

"vbRed" いった定数の名前をシートから読み込んで、
それを定数vbRedとして機能させることができるか、
というのと同じで、できません、が回答です。

投稿日時: 19/09/03 13:16:22
投稿者: あべ

皆様
 
見てもらいありがとうございます。
 
simpleさんの回答から、やはり無理か・・ということに気持ちが傾きつつですが
一方でEvaluateとかでなんとかできないかと悪あがきもしています。。

MsgBox CallByName([A1].parent, "name", VbGet)

 
 
イメージとしては、mattuwan44さん、simpleさんのお考えどおりです。
願わくば
 
Set obj = Application.UsedObjects("オブジェクト名の文字列")
 
のイメージですが・・
ただ「UsedObjects」の存在が知れたことは大きいです。ありがとうございます。
(ウォッチウィンドウで見るとThisWorkbookとか色々持っているようですので
なんとかできないものか歯がゆいですが・・)
 
kumattiさんのURL見ました。
やはりobjectとして呼んでいるようなので難しいかと。。
理解できているか分かりませんが、このURLの内容は、呼び先の「引数の数」についてですかね。。
(もしそうなら、私も以前悩み、名前付き引数で対応しようとしたら怒られ、
Select Caseで逃げた記憶があります。。)
 
 
いくつかのヒントもいただけたので代替案含めて考えてみたいと思います。
一旦解決とさせていただきます。
ご回答くださった皆様ありがとうございました!