ユーザー定義型に格納するには?

解決


バロシュ  2007-02-18 06:44:33  No: 98060

VB初心者のバロシュといいます。
またまた質問させていただきたいと思います。
環境はVB6でSPREAD/OCX V2.5Jを使用しています。

今回、SQLで読み込んだものを一度ユーザー定義型に格納し、そこから欲しいものを
指定してスプレッドに表示、ということをしたいのですが、格納する段階で詰まって
しまっています。
Private Type kousi_date
    code As Long
    name As String
    kubun As String
    runk As String
    tanka As Integer
End Type

Private Sub Form_Load()

With spd
    '* 列数、行数設定
'    .ColWidth(-1) =
   ' .MaxCols = 5
    '* セルへの直接入力禁止
    '.Col = -1
    '.Row = -1
    '.Protect = True
    '.Lock = True
End With

'Oracle 接続
Set OraSession = CreateObject("OracleInProcServer.XOraSession")
Set OraDatabase = OraSession.DbOpenDatabase("aaa", "aaa/aaa", 0&)

Dim strSQL      As String   'SQL文
Dim ResultSet   As Object   'レコード受取
Dim kDate       As kousi_date

'SQL文作成
strSQL = "SELECT * FROM " & TABLE_NAME
'SQL文発行
Set ResultSet = OraDatabase.DbCreateDynaset(strSQL, 0&)

kDate = ResultSet

End Sub

というものを作ったのですが、表示以前にうまく格納することが出来ません。
どうして格納できないのかアドバイスをいただきたく書き込みました。
よろしくお願いします.


ガッ  2007-02-19 18:38:51  No: 98061

型が違うからです
横着せずに個々のメンバに代入するしかないでしょう


バロシュ  2007-02-20 05:27:16  No: 98062

返信ありがとうございます。
ですが実は「SQLで読み込んだデータを変数に保持、その際変数にはユーザー
定義型の配列を使用」という制約がありまして、個々に代入するわけにはいかないのです。
そこで今回は(ほとんど同じですが)次のようなものを作ってみました。

Private Type kousi_date
    code As Long
    name As String
    kubun As String
    runk As String
    tanka As Integer
End Type

Private OraSession   As Object   
Private OraDatabase  As Object
   
Private Sub Form_Load()

'Oracle 接続
Set OraSession = CreateObject("OracleInProcServer.XOraSession")
Set OraDatabase = OraSession.DbOpenDatabase("aaa", "aaa/aaa", 0&)

Dim strSQL      As String  
Dim ResultSet   As Object   
Dim kDate       As kousi_date
 
    strSQL = "SELECT * FROM " & TABLE_NAME
    Set ResultSet = OraDatabase.DbCreateDynaset(strSQL, 0&)

kDate = ResultSet
End Sub
これですと型で怒られることはなくなったのですが、かわりに
「パブリックオブジェクトモジュールで定義されたユーザー定義型に限り、
変数に割り当てることができ、実行時バインディングの関数を渡すことができます」
というエラーがでるようになってしまいました。
自分で調べてみたのですが正直なところエラーメッセージの意味さえ理解する
ことが出来ませんでした。
基礎知識が足りていないということは承知しているのですが、
どうかアドバイスをお願いします。


大吉末吉  2007-02-20 06:17:40  No: 98063

> SQLで読み込んだデータを変数に保持、
>その際変数にはユーザー定義型の配列を使用

と言う制限は、

> 個々に代入するわけにはいかないのです
と言う意味には、ならないのでは・・・

> 横着せずに個々のメンバに代入するしかないでしょう

は、「ユーザ定義型を使うのを止める」と言う意味ではなく。

『ユーザ定義型の各メンバ(つまり「code 」「name」「kubun」「runk」「tanka」)に対して、
別々に(つまり合計5回に分けて)代入する』
と言う意味です。

例えば・・・
-------------------------------------------
kDate.code = ResultSet.Fields(0).Value
kDate.name = ResultSet.Fields(1).Value
kDate.kubun = ResultSet.Fields(2).Value
kDate.runk = ResultSet.Fields(3).Value
kDate.tanka = ResultSet.Fields(4).Value
-------------------------------------------

> 基礎知識が足りていないということは承知しているのですが

なら、「制約抜き」で先ず「とりあえず動作するプログラム」を作ってみては?

> 型で怒られることはなくなったのですが
「エラーが出なくなったらOK」とか思っていませんよね?

#エラーが出なくなっても、論理的に間違っていたら、そのプログラムは動きません。


バロシュ  2007-02-21 06:11:42  No: 98064

返信ありがとうございます。
あのあと
Private Type kousi_date
    code As Long
    name As String
    kubun As String
    runk As String
    tanka As Integer
End Type
Private insKdate As kousi_date

Set ResultSet = OraDatabase.DbCreateDynaset(strSQL, 0&)
j = 0
For i = 0 To spd.MaxRows
    With insKdate
        .code = ResultSet.Fields(0 + j).Value
        .kubun = ResultSet.Fields(1 + j).Value
        .name = ResultSet.Fields(2 + j).Value
        .runk = ResultSet.Fields(3 + j).Value
        .tanka = ResultSet.Fields(4 + j).Value
    End With
    With spd
        .Row = i + 1
        .Col = 1
        .Text = insKdate.code
        .Col = 2
        .Text = insKdate.kubun
        .Col = 3
        .Text = insKdate.name
        .Col = 4
        .Text = insKdate.runk
        .Col = 5
        .Text = insKdate.tanka
    End With
    j = j + 5
Next
というものを作ってみたのですが、「オブジェクト変数またはWithブロック変数が
設定されていません。」
というエラーがでてしまいます。
自分なりに調べてみたところ
ResultSet.Fields(5).Valueで止まっているようです。
つまり()内が5以上になると上記のようなエラーがでてしまうようなのですが、
なぜエラーになってしまうのでしょうか?
私のイメージとしてはcode(0)〜tanka(4)はSQLで求めた1行目、(5)〜は2行目
以降に移る、といったイメージだったのですが実際はどうすれば2行目
以降を
表示することが出来るでしょうか?
アドバイスをお願いします。


GOD  2007-02-21 08:02:04  No: 98065

つMoveNext


大吉末吉  2007-02-21 18:29:47  No: 98066

> 私のイメージとしてはcode(0)〜tanka(4)はSQLで求めた1行目、
> (5)〜は2行目以降に移る、といったイメージ

これが、間違っていますね。

RecordSetに(一度に)含まれるのは、1レコード分のデータだけです。

#スプレッドのイメージで考えるなら、1行分と考えればよいでしょう。
#で、項目の番号(Fieldsで指定する番号)は、
#どのレコードでも一定です(Colを指定するイメージ?)

GODさんも指摘されていますが、別のレコード(別の行)を参照(や編集)する場合、
レコード移動のコマンド(MoveNext以外もあります)を実行してください。


バロシュ  2007-02-22 06:21:24  No: 98067

ありがとうございます。
MoveNextを使うことによって無事スプレッドに表示することが出来ました。
また質問させていただくこともあると思うのですが、その時は
宜しくお願いします。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加