[リストへもどる]
一括表示

投稿時間:2003/04/05(Sat) 16:58
投稿者名:むろむろ
Eメール:
URL :
タイトル:
レコードセットをグリッドに表示
すいません。お願いします。
SQLを発行し、ADOのレコードセットを取得します。
それを、MSHFlexGridに表示したいのですが、
Set MSFlexGrid1.DataSouce = adoRs
てな感じで書くと、取得したレコードセットをグリッドに
表示することまでは分かったのですが、

SQL文の中にORDER句を入れて、「日付」フィールドを
新しい順などに並べかえるレコードセットを取得し、
それを上記と同じ方法でグリッドのデータソースに
セットすると、日付フィールドのソートが反映されずに
SQLサーバーにINSERTした順序のまま表示されます。

(MsgBoxにて取得したレコードセットの最初は、
正しく取得できていることは確認できました。)

これはそう言うものなのでしょうか?
ORDER句を入れたレコードセットをDO〜LOOP文を使用して
1レコードづつグリッドに表示していけば良いのでしょうが、
SET処理ができると楽だなと思って質問させて頂きます。

サーバーMSDE2000
開発VB6.0SP5

投稿時間:2003/04/07(Mon) 01:25
投稿者名:魔界の仮面弁士
Eメール:
URL :
タイトル:
Re: レコードセットをグリッドに表示
> SQL文の中にORDER句を入れて、「日付」フィールドを
> 新しい順などに並べかえるレコードセットを取得し、
> それを上記と同じ方法でグリッドのデータソースに
> セットすると、日付フィールドのソートが反映されずに
> SQLサーバーにINSERTした順序のまま表示されます。

『SQLサーバーにINSERTした順序』という意味がよくわかりませんが、
MSHFlexGridに表示される内容が、ORDER BYで指定した順序になっていない、という意味でしょうか。
(できれば、実際のコードと、その結果を提示してもらえると、回答しやすいです)

もし、ORDER BYで指定した通りに表示されないのだとしたら、問題の切り分けのために、
「Recordset取得時に、既に並び順が異なっている」のか、それとも
「グリッドにDataSouceとして渡すと、並び順が異なってしまう」のかを確認してください。


> ORDER句を入れたレコードセットをDO〜LOOP文を使用して
Clipプロパティに、RecordsetのGetStringメソッドの戻り値を渡すようにすれば、
複数のセルに、値を一括して代入できるかと思います。


> SET処理ができると楽だなと思って質問させて頂きます。
まず、サーバー側カーソルを利用している場合は、それをadUseClientに変更してみてください。
それで駄目なら、さらにSortプロパティを使って、ローカルソートをかけてみてください。

投稿時間:2003/04/07(Mon) 11:03
投稿者名:むろむろ
Eメール:
URL :
タイトル:
Re^2: レコードセットをグリッドに表示
> MSHFlexGridに表示される内容が、ORDER BYで指定した順序になっていない、という意味でしょうか。
その通りです。
> もし、ORDER BYで指定した通りに表示されないのだとしたら、問題の切り分けのために、
> 「Recordset取得時に、既に並び順が異なっている」のか、それとも
> 「グリッドにDataSouceとして渡すと、並び順が異なってしまう」のかを確認してください。
レコードセット取得後、MsgBoxにてadoRs.Fields(0).Valueは一番若い日付が表示されますので、
レコードセット取得時はあっていると思います。
それをグリッドに渡すと並び順が異なってしまいます。

> Clipプロパティに、RecordsetのGetStringメソッドの戻り値を渡すようにすれば、
> 複数のセルに、値を一括して代入できるかと思います。
すいません。やり方がわかりませんでした。

> まず、サーバー側カーソルを利用している場合は、それをadUseClientに変更してみてください。
すいません。やり方がわかりませんでした。

> それで駄目なら、さらにSortプロパティを使って、ローカルソートをかけてみてください。
Sortをしたのですが、他のフィールド年齢などはソートがかかって昇順・降順ともできるのですが
日付のみうんともすんとも言いません。

下記がコードサンプルです。
Dim adoCn As ADODB.Connection
Dim adoRs As ADODB.Recordset
Dim strSQL As String
    strSQL = "SELECT 日付, 氏名, 年齢, 性別 FROM Kokyaku " & _
             "WHERE 氏名 = '" & .txtName.Text & "' " & _
             "ORDER BY 日付 ASC"
    Set adoCn = New ADODB.Connection
    Set adoRs = New ADODB.Recordset
        adoCn.Open CS
        adoRs.Open strSQL, adoCn, adOpenStatic
Msgbox adoRs.Fields(0).Value  ←この時点はOK
If adoRs.RecordCount > 0 Then
        With .MSHFlexGrid1
            Set .DataSource = adoRs
                .Refresh
            Set .DataSource = Nothing
            .Visible = True
        End With
Else
    MsgBox "該当顧客が見つかりません"
End If
End With
で、実際のグリッドを見ると、日付が新しい順(降順)に出てしまう。

投稿時間:2003/04/07(Mon) 12:05
投稿者名:魔界の仮面弁士
Eメール:
URL :
タイトル:
Re^3: レコードセットをグリッドに表示
> レコードセット取得後、MsgBoxにてadoRs.Fields(0).Valueは一番若い日付が表示されますので、
2件目以降の順番はあっているでしょうか。

>> Clipプロパティに、RecordsetのGetStringメソッドの戻り値を渡すようにすれば、
>> 複数のセルに、値を一括して代入できるかと思います。
> すいません。やり方がわかりませんでした。
MSHFlexGridのClipプロパティは、現在選択されている範囲のセルの内容を、
各列をタブ(vbTab)文字で区切り、各行をキャリッジリターン(vbCr)で区切った文字列として返します。
(セル範囲の指定は、Row/Col/RowSel/ColSelプロパティで行います)

このClipプロパティに、vbTabとvbCrで区切られた文字列を送れば、
複数のセルの内容を、一度に設定できるわけです。

そして、このvbTab/vbCr区切りの文字列を作成するために、Recordsetオブジェクトの内容を
文字列として返してくれる「GetStringメソッド」が役に立つはずです。
GetStringの第3引数(ColumnDelimiter)にvbTabを指定し、第4引数(RowDelimiter)にvbCrを
指定すれば、vbTab/vbCr区切りの文字列を簡単に作成することができます。

>> まず、サーバー側カーソルを利用している場合は、それをadUseClientに変更してみてください。
> すいません。やり方がわかりませんでした。
「CursorLocationプロパティ」を設定してください、という事です。
つまり、
    adoRs.CursorLocation = adUseClient
    adoRs.Open strSQL, adoCn, adOpenStatic, adLockReadOnly, adCmdText
という感じです。

adoRs.CursorLocationを特に指定しなかった場合は、adoCn.CursorLocationの値が
引き継がれる事になります。なお、CursorLocationの規定値はadUseServerです。

>> それで駄目なら、さらにSortプロパティを使って、ローカルソートをかけてみてください。
なお、先の投稿で私が書いた、上記の「Sortプロパティ」というのは、
RecordsetオブジェクトのSortプロパティの事を指しています。

> Sortをしたのですが、他のフィールド年齢などはソートがかかって昇順・降順ともできるのですが
この場合のSortというのは、SQL中のORDER BYの事でしょうか?(※1)
それとも、RecordsetのSortプロパティの事でしょうか?(※2)
あるいは、MSHFlexGridの事でしょうか?(※3)

(※1) 通常は、SQLのORDER BY指定だけで、問題ないと思います。
手元にMSDE 1.0は無いのですが、SQL Server 2000の環境
(SQL Server 2000/SP3 + MDAC 2.7SP1 + VB6/SP5)で試してみた限りでは、
提示されたコードそのままで、"ORDER BY 日付 ASC"順に表示されました。

(※2) Recordset.Sortを利用するためには、RecordsetのCursorLocationが
クライアント側カーソル(adUseClient)に設定されている必要があります。

(※3) MSHFlexGrid.Sortを用いる場合は、ソートモードを確認してください。
DB側のフィールドのデータ型によっては、数値ソート(flexSortNumericAscending)や
文字列ソート(flexSortStringNoCaseAsending/flexSortStringAscending)では
対応できず、カスタムソート(flexSortCustom)を使う必要があるかも知れません。

投稿時間:2003/04/07(Mon) 13:08
投稿者名:むろむろ
Eメール:
URL :
タイトル:
Re^4: レコードセットをグリッドに表示
魔界の仮面弁士さま、ありがとうございます。
> レコードセット取得後、MsgBoxにてadoRs.Fields(0).Valueは一番若い日付が表示されますので、
> 2件目以降の順番はあっているでしょうか。
あっています。レコードセット上では私の出したい順で出ています。

> >> Clipプロパティに、RecordsetのGetStringメソッドの戻り値を渡すようにすれば、
> >> 複数のセルに、値を一括して代入できるかと思います。
やってみました。DataSouceに指定するのと同じ様に表示はできるのですが、
結果はDataSouceに指定したものと一緒で、うまく順序どおりになりませんでした。

> >> まず、サーバー側カーソルを利用している場合は、それをadUseClientに変更してみてください。
     adoRs.CursorLocation = adUseClient
>     adoRs.Open strSQL, adoCn, adOpenStatic, adLockReadOnly, adCmdText
やってみました。が、上記と同様でうまく順序どおりになりませんでした。
>
> >> それで駄目なら、さらにSortプロパティを使って、ローカルソートをかけてみてください。
私がやったのはMSHFLEXGRIDのソートです。
魔界の仮面弁士さまの言われたとおり、ソートモードを変えてみたら、グリッドに一旦
表示してからのソートはできるようになりました。ちなみにソートモードは5です。
(これって文字列を並べ替える時のものですよね。)

>Recordset.Sortを利用するためには、RecordsetのCursorLocationが
> クライアント側カーソル(adUseClient)に設定されている必要があります。
これも実施しましたが、うまい順序で出ませんでした。

で、気づいたのですが、ソートモードを5に変えて、グリッド上でのソートは
できる様になったと言うことは、日付フィールドは「文字」なのでしょうか?
MSDE上では「DateTime型」にしています。
ただし、yyyy/mm/dd形式でInsertしているので、時刻までは入っていない状態
です。
SQLのエンタープライズマネージャー上で、この形式のまま、SQLを発行して
テストしてみたのですが、正しく日付が昇順で表示されました。
ということはデータの形式はこのままで良いと思われるので、
あとはVBのグリッドにした時(する時)にどうすれば良いのでしょうか?

投稿時間:2003/04/07(Mon) 14:01
投稿者名:魔界の仮面弁士
Eメール:
URL :
タイトル:
Re^5: レコードセットをグリッドに表示
う〜ん。通常は、Sortプロパティなど使わずとも、
データソースの並び順そのままで表示されるはずなのですけれどね。
# 一体、どこに問題があるのだろう? (;_;)

MSDEへの接続文字列は、どのようになっていますか?
SQL Server/MSDE用プロバイダ(Provider=SQLOLEDB)による接続でしょうか、
それとも、ODBC接続(Provider=MSDASQL)でしょうか?


> ソートモードを変えてみたら、グリッドに一旦
> 表示してからのソートはできるようになりました。
DataSource側の並び順が反映されないとなると、その方法しか無さそうですね…。


> ちなみにソートモードは5です。
> (これって文字列を並べ替える時のものですよね。)
定数値 flexSortStringNoCaseAsending の事ですね。
出来る限り、定数値で指定された方が良いですよ。

# 定数名で書かれていれば、「大文字小文字を区別せずに、文字列順に昇順ソートされる」事が
# 読み取れますが、単に 5 と書いただけだと、後でソースを見た時に、意味が掴み難いですから。


> できる様になったと言うことは、日付フィールドは「文字」なのでしょうか?
OLE DB自体は、元のデータ型(adDateTime型など)を保持していますが、
MSHFlexGridに表示される際には、日付文字列として展開されます。

というよりも、日付であれ、数値であれ、MSHFlexGridへの表示時は、
全て「文字列」として展開される事になります。

# MSHFlexGridのTextMatrixプロパティが、(Variant型ではなく)String型を返すのも、
# データを内部で文字列化している為なのでしょうね。


> あとはVBのグリッドにした時(する時)にどうすれば良いのでしょうか?
書式化対応のコントロール(DataGridやTextBox等)であれば、StdDataFormatオブジェクトを
DataFormat/DataFormatsプロパティに割り当てる事で、書式を定義する事ができます……が、
MSHFlexGridは、DataFormatに対応していないみたいなので、データソース側で、
「文字列でソートされても、正しい並びになるような書式」に文字列化しておくか、
もしくは、Compareイベントを併用したカスタムソートを行うしかないかと思います。

MSDE側で処理する場合は、SQL発行時に、日付型をのCONVERT関数で変換しておいてください。
Compareイベントを使う場合は、SortプロパティをflexSortCustomにしておいてください。

投稿時間:2003/04/07(Mon) 18:09
投稿者名:むろむろ
Eメール:
URL :
タイトル:
解決
魔界の仮面弁士さま、いろいろとありがとうございます。
厳密に言うと、まだ解決はしていませんが、
もう一度勉強し直してやってみます。
本当にありがとうございました。