C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[3]: Variant の使い方


(過去ログ 177 を表示中)

[トピック内 5 記事 (1 - 5 表示)]  << 0 >>

■101457 / inTopicNo.1)  Variant の使い方
  
□投稿者/ 白音 (1回)-(2023/02/27(Mon) 14:25:53)

分類:[その他の OS] 

2023/02/27(Mon) 14:55:05 編集(投稿者)

エクセルのマクロなのですが

以下のように
関数から、処理をして該当すれば
POINTAPIで返し、該当しなければ
nothing で返したいのですが
どうすればよいのでしょうか?

Private Type POINTAPI
x As Long
y As Long
End Type


function get as variant

 if 〜
get.x = 1
get.y = 1
exit function
:
 end if

 set get = nothing

end function


いったん別に代入してから
 Dim pnt As POINTAPI
 pnt.x = 1
 pnt.y = 1

 get = pnt
としてもできません。

 set get = pnt
としてもできません。


引用返信 編集キー/
■101458 / inTopicNo.2)  Re[1]: Variant の使い方
□投稿者/ 魔界の仮面弁士 (3572回)-(2023/02/27(Mon) 15:48:48)
No101457 (白音 さん) に返信
> function get as variant
get は予約語なので、get という名前の Function は定義できません。

また、ユーザー定義型を Variant で返すことは(基本的には)できません。

クラスであれば Variant や Object で返すことができますし、Nothing も渡せます。
ユーザー定義型をクラスモジュールに変更することを検討してみてください。


もしくは、戻り値を配列で返すようにするとか……「As Variant()」ないしは「As Variant」のように。
要素数 0 な Variant 配列(あるいは Empty とか)であれば、該当なしの意味とし、
要素数 2 な Variant 配列であれば、それぞれが x As Long, y As Long の意味として扱うなど。


「As Long()」にできれば手っ取り早いのですが、VBA の場合、
要素数 0 の配列を作れないんですよね…。

一応、Byte()、String()、Object(), Variant() なら空の配列を作れるのですが、
それ以外の型の場合、要素数ゼロの配列は API を併用しないと作れません。
https://qiita.com/nukie_53/items/9a7a1eb07eff50ae1e8b


あるいは、64bit 版 VBA であれば、LongLong 型として返すようにして、
上位32bit と下位32bit を x As Long, y As Long の意味として使う…という手もありますが、
正直分かりにくいと思います。


もしくは、ユーザー定義型の宣言をちょっと拡張して
 Public Type POINTINFO
  HasValue As Boolean 'Trueならx,yを使える、Falseなら無効値扱い
  x As Long
  y As Long
 End Type
などのように、管理フィールドを追加するとか。


> 関数から、処理をして該当すれば
> POINTAPIで返し、該当しなければ
> nothing で返したいのですが
> どうすればよいのでしょうか?

そもそもユーザー定義型に Nothing は渡せませんよ。

また、ユーザー定義型を Variant に渡すには、VB6 が必要です。VB5 以下や VBA では無理ですね。
ユーザー定義型を返す Variant を扱うには、タイプライブラリを用いて、
該当構造体をレジストリに登録しておく必要があるため、VBA 単体では扱えません。
引用返信 編集キー/
■101459 / inTopicNo.3)  Re[2]: Variant の使い方
□投稿者/ 大谷刑部 (225回)-(2023/02/27(Mon) 16:05:17)
No101458 (魔界の仮面弁士 さん) に返信
> ■No101457 (白音 さん) に返信
>>function get as variant
> get は予約語なので、get という名前の Function は定義できません。
>
> また、ユーザー定義型を Variant で返すことは(基本的には)できません。
>
> クラスであれば Variant や Object で返すことができますし、Nothing も渡せます。
> ユーザー定義型をクラスモジュールに変更することを検討してみてください。

戻り値をnothingにしたいならそうなりますね。
ただそれだと、.Netでよく使われる手法なのでVBAっぽくはないコーディングにはなりますけどね。

>>関数から、処理をして該当すれば
>>POINTAPIで返し、該当しなければ
>>nothing で返したいのですが
>>どうすればよいのでしょうか?
>
> そもそもユーザー定義型に Nothing は渡せませんよ。
>
> また、ユーザー定義型を Variant に渡すには、VB6 が必要です。VB5 以下や VBA では無理ですね。
> ユーザー定義型を返す Variant を扱うには、タイプライブラリを用いて、
> 該当構造体をレジストリに登録しておく必要があるため、VBA 単体では扱えません。

これも弁さんのおっしゃる通りで、ユーザー定義型は.Netでいうと構造体なので根本的にクラスとは違います。
「Nothing」はあくまでオブジェクト系の型でオブジェクトが「ない」つまりNothingであることを表すものなので、ユーザー定義型(構造体)で使うものではありません。
.Netで長くVBで汎用型として使用されてきたVariant型がなくなって、完全にVBもオブジェクト指向型言語に代わり、いわば何でもアリの型はなくなりました。
Variant型に近い役割を果たすための型としてObjectをオブジェクト系の汎用型として使用する傾向になったため、混同が起こっているのだと思います。

質問者さんはそもそも「なし」を表す戻り値をNothingにすべきかどうかを検討しなおした方が良いかと思います。
C#でVBのNothigがnullであることでこれまた混同が起きてるかもしれませんが、Nothing=Nullではありません。

引用返信 編集キー/
■101460 / inTopicNo.4)  Re[2]: Variant の使い方
□投稿者/ 魔界の仮面弁士 (3573回)-(2023/02/27(Mon) 17:43:08)
No101458 (魔界の仮面弁士) に追記
>> 関数から、処理をして該当すれば
>> POINTAPIで返し、該当しなければ
>> nothing で返したいのですが
>> どうすればよいのでしょうか?
> もしくは、戻り値を配列で返すようにするとか……「As Variant()」ないしは「As Variant」のように。
> 要素数 0 な Variant 配列(あるいは Empty とか)であれば、該当なしの意味とし、
> 要素数 2 な Variant 配列であれば、それぞれが x As Long, y As Long の意味として扱うなど。


Public Function HitTest案1() As Variant
 Dim p As POINTAPI
 '中略
 If 該当あり Then
  HitTest案1 = Array(p.X, p.Y)
 Else
  HitTest案1 = Empty
 End If
End Function


Public Function HitTest案2() As Variant()
 Dim p As POINTAPI
 '中略
 If 該当あり Then
  HitTest案2 = Array(p.X, p.Y)
 Else
  HitTest案2 = Array()
 End If
End Function
引用返信 編集キー/
■101471 / inTopicNo.5)  Re[3]: Variant の使い方
□投稿者/ 白音 (2回)-(2023/02/28(Tue) 16:35:46)
No101460 (魔界の仮面弁士 さん) に返信

ありがとうございます。
難しいのはやはりやめておいて
わかりやすく、以下の方法を使わせていただきます。


 Public Type POINTINFO
  HasValue As Boolean 'Trueならx,yを使える、Falseなら無効値扱い
  x As Long
  y As Long
 End Type
解決済み
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -