tagCANDY CGI VBレスキュー(花ちゃん)の Visual Basic 6.0用 掲示板 [ツリー表示へ]   [Home]
一括表示(VB6.0)
タイトルActivexで呼び先のコレクションへデータをセットする方法
記事No14563
投稿日: 2010/03/17(Wed) 17:08
投稿者ぶー
Prog1からActiveXでProg2をCALLする処理があります。
Prog1でデータ取得してコレクションcolに格納したデータを
ActiveXのProg2に送りたいのですが・・

Prog1側
Set Obj = CreateObject("Prog2.class1")
Prog2側のclass1に
public Sendatas as collectionと設定し
Prog1でCreateした後に
set obj.Sendatas = new collection
set obj.Sendatas = col
とやってみたのですが、この時にはセットあれていますが、
Prog2が呼ばれた後に見てみると空っぽになってしまいます。
他にこれと一緒に変数を送っているのですが、それは送られているのですが、
collectionだけ空っぽになってしまいます。
クラスにはセット出来ないのでしょうか?やり方を教えてください。

[ツリー表示へ]
タイトルRe: Activexで呼び先のコレクションへデータをセットする方法
記事No14564
投稿日: 2010/03/17(Wed) 18:29
投稿者魔界の仮面弁士
> set obj.Sendatas = new collection
> set obj.Sendatas = col
代入処理を 2 回行っているのはなぜでしょうか?

> Prog2が呼ばれた後に見てみると空っぽになってしまいます。
Sendatas プロパティの実装は、どのようになっていますか?

> collectionだけ空っぽになってしまいます。
Collection インスタンスの中身を入れ替えたいのでしょうか? それとも
Collection インスタンスそのものを差し替えたいのでしょうか?

[ツリー表示へ]
タイトルRe: Activexで呼び先のコレクションへデータをセットする方法
記事No14565
投稿日: 2010/03/17(Wed) 19:33
投稿者ぶー
Prog1側
  colには別のクラスの構造体にセットしたデータがコレクションの形で格納されています。 
  Set Obj = CreateObject("Prog2.class1")
  with Obj 
    .Sendatas = new collection
    set .Sendatas = col
  .Read
  end with
    
prog2側

class1のプロパティは
Instancing=MultiUse
Persistable =NotPersistable

class1.cls
 public Sendatas as collection

Public Sub Read
  if Sendatas.count > 0 then ・・・・0になっています。    
end public

> 代入処理を 2 回行っているのはなぜでしょうか?
 こうすればセットするのかなと思いまして・・(いろいろ試行錯誤してまして)

Prog2でProg1で格納したコレクションデータを使いたいだけなので
(Prog1でコレクションに格納したデータは取得するのが結構大変で時間がかかるので
また、Prog2で同じことをしなくてもいいように流用できないかなあと)

Prog2でProg1と同じデータを読めれば入れ替えでも差し替えでもいいのですが。

[ツリー表示へ]
タイトルRe^2: Activexで呼び先のコレクションへデータをセットする方法
記事No14566
投稿日: 2010/03/17(Wed) 19:55
投稿者魔界の仮面弁士
>   Set Obj = CreateObject("Prog2.class1")
>   with Obj 
>     .Sendatas = new collection
>     set .Sendatas = col

No.14563 では、Set 操作を 2 回行っていたのに対し、今回の
No.14565 では、Let 操作の後に Set 操作を行っていますね。どちらが本当ですか?

また、ここで代入している「変数 col」とは何者でしょうか?

(1) 変数 col は、As New Collection として宣言された変数である。
(2) 変数 col は、As Collection として宣言された変数である。
(3) 変数 col は、上記以外の宣言で作られた変数である。
(4) col は変数ではなく、Prog1 側のプロシージャである。

さらに、その Prog1 側の col インスタンスの内容はどうなっていますか?

(a) col には Set col = New Collection 操作を行っておらず、Nothing 状態である。
(b) col には Collecion インスタンスがセットされているが、登録データは 0 件である。
(c) col には Collecion インスタンスがセットされており、データが登録されている。
(d) その他


> class1.cls
>  public Sendatas as collection
提示されたコードだと、そもそもエラーになってしまうハズですが…。

Prog2.class1 側でモジュールレベル変数として実装されているだけなら、
Prog1 側で Let 操作を行おうとすると、エラーになってしまうはずです。

逆に、本当に今回のように Let と Set 動作を行っているのだとすれば、
Prog2.class1 側には少なくとも
 Public Property Let Sendatas(…
 Public Property Set Sendatas(…
 Public Property Get Sendatas(…
のうち、Let と Set の実装が必要になるはずです。


>> 代入処理を 2 回行っているのはなぜでしょうか?
> こうすればセットするのかなと思いまして・・(いろいろ試行錯誤してまして)
無意味だと思いますよ。2回目の Set 操作だけで十分なはずです。
(2 回目の Set 操作が行われる際に、1 回目に Set したインスタンスが破棄されるので)

[ツリー表示へ]
タイトルRe^2: Activexで呼び先のコレクションへデータをセットする方法
記事No14567
投稿日: 2010/03/17(Wed) 20:48
投稿者ぶー
>   Set Obj = CreateObject("Prog2.class1")
>   with Obj 
>     .Sendatas = new collection
>     set .Sendatas = col

No.14563 では、Set 操作を 2 回行っていたのに対し、今回の
No.14565 では、Let 操作の後に Set 操作を行っていますね。どちらが本当ですか?

答え)No.14565が正しいです。すいません

また、ここで代入している「変数 col」とは何者でしょうか?
さらに、その Prog1 側の col インスタンスの内容はどうなっていますか?

(1) 変数 col は、As New Collection として宣言された変数である。
(2) 変数 col は、As Collection として宣言された変数である。
(3) 変数 col は、上記以外の宣言で作られた変数である。
(4) col は変数ではなく、Prog1 側のプロシージャである。

答え)
private Sub DataSet 

Dim col  as collection
Dim cls2 as classA
     set col = new collection
     set cls2 = new classA
     with cls2
         .aa = "001"
         .bb = "*****"
         (こんな感じでcls2にセットされて、cls2の構造は割愛します)
     end with
     For i=1 to データ最大取得数
       col.add cls2    
     next    
    
  colの中には登録データがデータ最大取得数分入っていました。
  (debug.Print col.countで確認

     Set Obj = CreateObject("Prog2.class1")
     with Obj 
        .Sendatas = new collection
        set .Sendatas = col
     end with
    
end sub

Prog2のclass1.clsの中身

 public Sendatas as collection
提示されたコードだと、そもそもエラーになってしまうハズですが…。

答え)エラーにはなりませんでした。

debug.Print Sendatas.count で確認すると0になってしまいます。
ちなみにProg2のReadへ来るまでに
Sendatasの中身を消すような処理はありません。

Prog2.class1 側でモジュールレベル変数として実装されているだけなら、
Prog1 側で Let 操作を行おうとすると、エラーになってしまうはずです。

逆に、本当に今回のように Let と Set 動作を行っているのだとすれば、
Prog2.class1 側には少なくとも
 Public Property Let Sendatas(…
 Public Property Set Sendatas(…
 Public Property Get Sendatas(…
のうち、Let と Set の実装が必要になるはずです。

答え)Let/Setは使っていません。
どう使えばよろしいでしょうか?

>> 代入処理を 2 回行っているのはなぜでしょうか?
> こうすればセットするのかなと思いまして・・(いろいろ試行錯誤してまして)
無意味だと思いますよ。2回目の Set 操作だけで十分なはずです。
(2 回目の Set 操作が行われる際に、1 回目に Set したインスタンスが破棄されるので)

答え)ありがとうございます。勉強になります。

説明が下手ですいません。これで伝わりましたでしょうか?

[ツリー表示へ]
タイトルRe^3: Activexで呼び先のコレクションへデータをセットする方法
記事No14568
投稿日: 2010/03/17(Wed) 21:51
投稿者魔界の仮面弁士
>  public Sendatas as collection
"data" はそれ自体が複数形であり、"datas" という単語は無かったりします。
(data の単数形は datum です)

> 提示されたコードだと、そもそもエラーになってしまうハズですが…。
> 答え)エラーにはなりませんでした。
On Error で握りつぶしているという事はないですよね?

確認のため、該当コードを抜き出して実装してみたのですが、当方では
『.Sendatas = New Collection』の行で、以下のエラーが発生していました。
何か他に追加のコードがあったのでしょうか?
http://www.vb-user.net/junk/replySamples/2010.03.17.21.43/Error01.png
http://www.vb-user.net/junk/replySamples/2010.03.17.21.43/Error02.png

なお、『Set .Sendatas = col』の行はエラーにはなりませんでした。


> 答え)Let/Setは使っていません。
> どう使えばよろしいでしょうか?
Prog2 側を修正するのではなく、
Prog1 側で Let 操作を行わないようにしましょう。

[ツリー表示へ]
タイトルRe^4: Activexで呼び先のコレクションへデータをセットする方法
記事No14570
投稿日: 2010/03/18(Thu) 12:15
投稿者ぶー
Set Obj = CreateObject("Prog2.class1")
with Obj 
    .Sendatas = new collection
    set .Sendatas = col
    Stop    ・・この段階でVBのウォッチでObjの中身を見ると、
            Sendatasの中身が見れますので、
            Prog2のコレクションSendatasへセットは出来ているのかと。
  .Read
end with 

OnErrorはかけていません。実行してエラーは出ませんが、prog2側に移ってすぐ、
SendatasのCountを調べてみるとちゃんと取得データ数が表示される(※1)のですが、
VBのウォッチでSendatasの中身を見ようとすると
”プロパティまたはメソッドの呼び出しの場合には、引数または戻り値として
プライベートオブジェクトへの参照を含めることが出来ません。”とエラーが出てしまいます。
これが大きなカギになるのかと・・でもどうやればいいのか分かりません。

prog2側

class1.cls
 public Sendatas as collection

Public Sub Read
 ここでSendatas.count を見ると取得データ数が表示されます。※1
  でもウォッチでエラーが出ます。

[ツリー表示へ]
タイトルRe^5: Activexで呼び先のコレクションへデータをセットする方法
記事No14571
投稿日: 2010/03/18(Thu) 12:43
投稿者魔界の仮面弁士
> 実行してエラーは出ませんが
現象を再現可能な最低限のコードを提示できませんか?

As が as になっていたり、New が new になっていたりするので、
現在提示されているコードのうち、どこまでを信じれば良いのか曖昧です。

> Set Obj = CreateObject("Prog2.class1")
> with Obj 
>     .Sendatas = new collection
この Let 作業は本当に必要なのでしょうか?


> Stop    ・・この段階でVBのウォッチでObjの中身を見ると、
Prog2 は、インプロセス(ActiveX DLL等)でしょうか。
それとも、アウトプロセス(ActiveX EXE等)のコンポーネントでしょうか。

AcitveX DLLだとしたら、Prog2 をデバッグする際に、
Prog1 と同じプロジェクトグループに含めていますか?
(VB6 を 2 つ起動していたりはしませんか?)


> ”プロパティまたはメソッドの呼び出しの場合には、引数または戻り値として
> プライベートオブジェクトへの参照を含めることが出来ません。”とエラーが出てしまいます。
コレクションに登録されているオブジェクト――すなわち、
No14567 で示された new classA ――は、どのような物ですか?

もし classA の Instancing プロパティが 1 - Private になっているのであれば、
それを外部プロセスに渡すことはできません。

[ツリー表示へ]
タイトルRe^6: Activexで呼び先のコレクションへデータをセットする方法
記事No14572
投稿日: 2010/03/18(Thu) 13:45
投稿者ぶー
>もし classA の Instancing プロパティが 1 - Private になっているのであれば、
>それを外部プロセスに渡すことはできません。

これを見てハッ!と気がつきました。
以前似たようにProg2をActiveX形式にして先に実行し、次にProg1を実行して、
Prog1のcollectionをProg2のcollectionに送り
Prog2へセットしたことがあったのですが、なぜか今回動かない。
ただ今回のは前回のとは違ってclassAにセットしてからコレクションに入れていく
パターンでしたので、気がつきませんでした。
classA の Instancing プロパティが 1 - Private だから、コレクションカウントを
取ってみると数字は取れるのに、中身が見れないということが起きていたわけです。
本当に丁寧に何度も教えて頂きまして、ありがとうございました。

[ツリー表示へ]