DOBON.NET DOBON.NETプログラミング掲示板過去ログ

クラス間での変数(配列)の受け渡し方法

環境/言語:[winXP vb.net(2010) excel2000]
分類:[.NET]

先日、excelの解放とcombobox処理を教えて頂きかなり思い描いてた動作に近づいてきました。
そこで、作成したexcel呼び出し→配列取得→combobox反映の流れを4つのフォームで同様処理させる事となるのだから、同じ事を各フォームに書いても修正の時に大変なのでクラスを使えば修正も簡単になるんじゃないか?と、試行錯誤しているのですがデータの受け渡しで躓いてしまったのでご教授願います。


-----クラス側-----
Public Class form_load
**
  Public Shared Sub base_exl()'--excel読み込み・配列取得処理
   **'--エクセル開く処理なので略します。
    Dim com_data(,) As Object = DirectCast(rng_com.Value, Object(,)) '---配列に範囲を取得しています。
   **'---エクセル解放処理なので略します。
  end sub

-----フォーム側-----
Private Sub Form2_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
base_exl()
ListBox9.Items.Add(com_data(1, 2))'---仮に1つだけ抜き出そうとしてます。最終的には配列をcomboboxへ流し込みます。
end sub


Public Shared Sub base_exl()の外にPublic Shared com_data(,) As Objectと指定すると、配列自体は読みに行くのですがSub base_exl()で取得している物とは別物なのか”オブジェクト参照がオブジェクト インスタンスに設定されていません。”と怒られてしまいます。
それでは、Sub base_exl()の中のcom_data(,)をPublic Sharedにすれば?
と、書いてみたものの書式がダメと怒られます。
Public Shared Sub base_exl()の外にPublic Shared com_data(,) As Objectと書くのが間違いなのか?と、Public Shared com_data(,) As Object= {{1, 2, 3}, {4, 5, 6}}と書くと、この配列は取得できる。
Public Shared Sub base_exl()内での書き方が悪いのかな?と素人考えであたりは付けてみたものの、そこから先が分かりません。
色々と調べてはみたのですが、どうにも行き詰ってしまいました。

・クラス内のPublic Shared Subの中で取得した変数(配列)をフォームへ
・フォーム内のPrivate Sub内で取得した変数(配列)を別クラスへ

これが分かれば前進できると思うのですが…
宜しくお願いします。
2012/10/11(Thu) 15:27:33 編集(投稿者)

クラス側とフォーム側の関係がよく分からないので何とも言えませんが、
Public Shared Sub base_exl()で"Shared"にしている理由は何ですか?
Sharedは共有化するためのキーワードなのですが、それはOKなのでしょうか?
4つのフォームで同様の処理を行うのですから、base_exl()で作成される
Object(,)の内容が4つのフォームで共有ということでいいのであれば
Sharedでもいいのですが、各フォームで別々のObject(,)が必要となるならば、
Sharedでなくクラスのインスタンスを作成する必要があります。

また、クラス側にパブリック変数Public Shared com_data(,) As Objectを用意するのであれば、
Public Shared Sub base_exl()内でこれと同名のローカル変数com_data(,)を定義すると、
パブリック変数のそれとは異なる変数になりますので注意してください。
(これが”オブジェクト参照がオブジェクト インスタンスに設定されていません。”の原因だと思います。)
従って、Public Shared Sub base_exl()には以下のように書くことになると思います。
(試してません。悪しからず)

  Public Shared Sub base_exl()'--excel読み込み・配列取得処理
   **'--エクセル開く処理なので略します。
    com_data = DirectCast(rng_com.Value, Object(,)) '---Dimで宣言してはいけない!
   **'---エクセル解放処理なので略します。
  end sub
バナナマンさん、ありがとうございます。

> 4つのフォームで同様の処理を行うのですから、base_exl()で作成される
> Object(,)の内容が4つのフォームで共有ということでいいのであれば
> Sharedでもいいのですが、各フォームで別々のObject(,)が必要となるならば、
> Sharedでなくクラスのインスタンスを作成する必要があります。

はい、各フォームから呼び出しに行く配列(excel)は同じものです。
その上でフォーム側で別配列にコピーして使用範囲を区分しようかな?とかんがえています。
(form1は全部使う。form2は配列の12〜14を使用しないので、そこだけダミーで埋める等です。最終的に選択した条件を別のエクセルへ書き出すのですが、フォームによって選択範囲が変化するのに出力先excelは同じものを使用するのです。ですから、同一表記順で未使用箇所は全角スペース等で表記する等しないとおじさん達から苦情が来そうなのです)

> また、クラス側にパブリック変数Public Shared com_data(,) As Objectを用意するのであれば、
> Public Shared Sub base_exl()内でこれと同名のローカル変数com_data(,)を定義すると、
> パブリック変数のそれとは異なる変数になりますので注意してください。
> (これが”オブジェクト参照がオブジェクト インスタンスに設定されていません。”の原因だと思います。)

あ、やはり2重表記なってしまうのですね。外で宣言したcom_data(,)へPublic Shared Sub base_exl()内のcom_data(,)が書き出されるのかな?と考えていたのですが、外の配列にcom_data(,) As Object = {{1, 2, 3}, {4, 5, 6}}と指定したらそれだけ読めたので変だ。と思っていたのですが


>   Public Shared Sub base_exl()'--excel読み込み・配列取得処理
>    **'--エクセル開く処理なので略します。
>     com_data = DirectCast(rng_com.Value, Object(,)) '---Dimで宣言してはいけない!
>    **'---エクセル解放処理なので略します。
>   end sub

com_data = DirectCast(rng_com.Value, Object(,)) '---Dimで宣言してはいけない!
ですが
'com_data' は宣言されていません。アクセスできない保護レベルになっています。
と怒られてしまいました。

今のプロジェクトで実験してると壊してしまいそうなので・・・
ちょっと単純にフォーム2つにクラス1つ。
変数だけやり取りする。
と、いうのを作って勉強してみます。
色々と調べてみますが、参考になるようなサイト等教えて頂けると幸いです。
> 今のプロジェクトで実験してると壊してしまいそうなので・・・
> ちょっと単純にフォーム2つにクラス1つ。
> 変数だけやり取りする。
> と、いうのを作って勉強してみます。
> 色々と調べてみますが、参考になるようなサイト等教えて頂けると幸いです。

という事で、色々と調べてみた結果

-----クラス側-----
Public Class top_form_load
Public ReadOnly Property ComExl() As Array'配列を読込みたいだけなのでReadonlyで
Get
   **'--エクセル開く処理なので略します。
    Dim com_data(,) As Object = DirectCast(rng_com.Value, Object(,)) '---配列に範囲を取得しています。
   **'---エクセル解放処理なので略します。
Return com_data
End Get
End Property

-----フォーム側-----
Private Sub Form2_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
Dim com_data As New top_form_load
MsgBox(com_data.ComExl(6, 4))
End Sub

とすると、配列データが読めるようになりました。
スマートなやり方じゃないかも知れませんが、これでまた少し前進出来そうです。
ありがとうございました。
解決済み!

DOBON.NET | プログラミング道 | プログラミング掲示板