質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
VBA

VBAはオブジェクト指向プログラミング言語のひとつで、マクロを作成によりExcelなどのOffice業務を自動化することができます。

Q&A

解決済

3回答

2180閲覧

VBA 関数の戻り値が値かオブジェクトか分からない場合の受け方

doju_m

総合スコア19

VBA

VBAはオブジェクト指向プログラミング言語のひとつで、マクロを作成によりExcelなどのOffice業務を自動化することができます。

1グッド

2クリップ

投稿2022/01/11 07:03

前提・実現したいこと

VBAで あるライブラリを使用しているのですが、
その中の関数が、結果によってオブジェクトと値のどちらを返してくるか
実行してみるまで分からない仕様となっており
呼び出し側で戻り値をどう受ければよいか困っております。

とりあえず値が戻ると仮定して一度呼び出して、
エラーになれば再度オブジェクトとして受けるように呼び出すという手段もあるかと思いますが
関数の背後で通信が発生しているため、あまり頻繁な呼び出しは避けたいと思っています。

なにか良い方法はありますでしょうか?

(該当のライブラリはBSDライクのライセンスなので、受け手でどうにもならない場合は
ライブラリのコードに手を入れることも考えています)

xail2222👍を押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

ベストアンサー

どうやるのが一般的か知らないですが思い付いた方法を回答します。

まず、以下のクラスを作成します。

VBA

1Public X As Variant 2Public IsObject As Boolean 3 4Public Sub SetX(v As Variant) 5 If VBA.Information.IsObject(v) Then 6 Set X = v 7 IsObject = True 8 Else 9 X = v 10 IsObject = False 11 End If 12End Sub

使い方は次の通り

VBA

1Public Sub test() 2 Dim t_Container As New Container_Class 3 Dim t_X As Variant 4 5 ' オブジェクトの場合 6 t_Container.SetX Sheet1 7 If t_Container.IsObject Then 8 Set t_X = t_Container.X 9 Else 10 t_X = t_Container.X 11 End If 12 13 ' 値の場合 14 t_Container.SetX 1 15 If t_Container.IsObject Then 16 Set t_X = t_Container.X 17 Else 18 t_X = t_Container.X 19 End If 20End Sub

関数の引数にすれば、オブジェクトでも値でも受けれるので
それを利用した感じです。
別にクラスを作らなくても出来ますが、まぁ一例ということで。

投稿2022/01/11 13:13

編集2022/01/11 13:17
xail2222

総合スコア1508

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

hatena19

2022/01/11 13:58

> 関数の引数にすれば、オブジェクトでも値でも受けれる なるほど、素晴らしいアイデアです。 いわれてみれば簡単なことですが、思いつかなかった。
xail2222

2022/01/11 14:33

sinya0320さんの回答にあるように、Variantで受け取ってそれを使って判定しているだけなのですが VBAの場合、それをするのにひと工夫必要なので回答してみました。 後は、実際の使い方に応じた実装をすればいいとは思いますが hatena19さんの回答でいいかもしれませんね。 IsObjectを二回することになってますが、IsObjectなんてほとんど処理時間なんてかからないでしょうし。
doju_m

2022/01/12 04:30

回答ありがとうございます。 これは思いつきませんでした……ありがとうございます!
guest

0

xail2222さんの「関数の引数にすれば、オブジェクトでも値でも受けれる」という素晴らしいアイデアを拝借して、

vba

1'外部ライブラリのつもり 2Public Function GetX(i As Long) 3 If i = 0 Then 4 Set GetX = Sheet1 5 Else 6 GetX = i + 1 7 End If 8End Function 9 10Public Sub SetX(ByRef X, V) 11 If IsObject(V) Then 12 Set X = V 13 Else 14 X = V 15 End If 16End Sub 17 18Public Sub test() 19 Dim X As Variant 20 21 SetX X, GetX(0) 22 Debug.Print TypeName(X) 23 If IsObject(X) Then 24 Debug.Print X.Name 25 Else 26 Debug.Print X 27 End If 28 29 SetX X, GetX(1) 30 Debug.Print TypeName(X) 31 If IsObject(X) Then 32 Debug.Print X.Name 33 Else 34 Debug.Print X 35 End If 36 37End Sub

ベストアンサーは辞退します。

投稿2022/01/11 14:01

hatena19

総合スコア34075

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

doju_m

2022/01/12 04:32

回答ありがとうございます。 こちらもシンプルでよいですね。ありがとうございます。
guest

0

値なのかオブジェクトなのかをどう判別するかは分かりませんが
取り合えず、Variant型で受け取って、それを使って諸々の判定を行えば良いのではないでしょうか

例えば、値が数値ならば、IsNumericで判定した後でCIntやCLngで変換すれば良いでしょうし

投稿2022/01/11 10:04

sinya0320

総合スコア211

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

hatena19

2022/01/11 13:05 編集

Variant型で受け取るにしても、オブジェクトだとSetがないとエラーになるし、それ以外の型だとSetがあるとエラーになります。 結局、エラートラップで再トライするしかないと思います。
doju_m

2022/01/12 04:28

回答ありがとうございます。 質問文に明記しておらず、申し訳ありませんでしたが 困っているポイントは、hatena19さんがご指摘いただいた点になります。 (実行時まで分からないことに対して、静的にコードで対応しなければならない)
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問