データグリッドの縦スクロールバーで32594以上スクロールさせるには?

解決


にっちゃん  2005-03-22 17:32:34  No: 120389

現在、データグリッドを使用して、
10万行超のデータベースファイルを
表示させようとしております。
データベースはADODCを使用してリンクしています。
データグリッドの縦スクロールバーで最終行を表示しようとすると、
強制的に32594行を表示します。
縦スクロールバーのスクロール位置も、
一番下から自動的に32594行に戻ってしまいます。
どうも符号付整数の制限に引っ掛かっているようです。
上記のような制限を解除する有効な手段はないものでしょうか?
なお、当方の開発環境はVB6.0(SP6)、WindowsXP Pro SP2です。
どなたかご教授くださいますよう、よろしくお願い申し上げます。


特攻隊長まるるう  2005-03-23 00:33:25  No: 120390

>10万行超のデータベースファイルを
>表示させようとしております。
これは無茶な仕様では無いのでしょうか?人間が見るのであれば
そんなに表示しても理解できないでしょうし、必要ないと思います。
人間が見ないのであれば DataGrid を使う必要もありませんし。
データとしては10万件扱うとしても、一度に表示しなければならない
理由があるものなのでしょうか?。メモリと言う有限の資源を使う
以上、限界はあります。実行環境に応じて表示数の制限を作っておく
のはこういったアプリを作る上では常識です。

それを踏まえた上で、

色々な条件下でテストして、もっと原因を特定しないと何とも言えません。
以下の環境で何の問題もなく表示されました。データグリッド自身の
スクロールバーで上下させてレコードも選択してみましたが、特定の
行に移動されたり、移動が制限される現象は起こりませんでした。
ちなみに10万件まではやりました。…何の問題も無いです。…表示までに
8秒くらいは掛かりますが。

[VB6.0(Sp5),Win2000(Sp4),CPU1.60GHz,物理メモリ26MB]
Option Explicit
Private mLocalRs As ADODB.Recordset

Private Sub Form_Load()
    Dim i As Long
    Set mLocalRs = New ADODB.Recordset
    With mLocalRs.Fields
        Call .Append(LocalRecordsetColumn.ID, adInteger, , adFldIsNullable)
        Call .Append(LocalRecordsetColumn.Namex, adVarChar, 50, adFldIsNullable)
        Call .Append(LocalRecordsetColumn.Text, adBSTR, , adFldIsNullable)
    End With
    
    With mLocalRs
        Call .Open
        For i = 1 To 35000
            .AddNew
            .Fields(CStr(LocalRecordsetColumn.ID)) = i
            If i Mod 2 = 0 Then
                .Fields(CStr(LocalRecordsetColumn.Namex)) = "Name" & i \ 2
            End If
            .Fields(CStr(LocalRecordsetColumn.Text)) = "Text" & 2 - i Mod 2
        Next
    End With
        
    Set Me.Adodc1.Recordset = mLocalRs
    Set Me.DataGrid1.DataSource = Adodc1
End Sub


特攻隊長まるるう  2005-03-23 00:49:01  No: 120391

あ、大事な宣言も消しちゃってるよw…まぁ、引数の型が分かってれば想像は付くだろうケド
Private Enum LocalRecordsetColumn
    ID
    Namex
    Text
End Enum


にっちゃん  2005-03-23 02:32:34  No: 120392

自己レスです。
データグリッドをサブクラス化し、
WM_VSCROLL、SB_THUMBTRACK時の
動作を強制的にスクロールするように
考えてみました。

Private Function WindowProc( _
     ByVal hWnd As Long, _
     ByVal uMsg As Long, _
     ByVal wParam As Long, _
     ByVal lParam As Long) As Long
    Dim Lo As Long
    Dim Hi As Long
    
    Select Case uMsg
        Case WM_VSCROLL     'wParamの下位ワード:スクロール操作
                            'wParamの上位ワード:ドラッグドロップ量
            Lo = LOWORD(wParam)
            Hi = HIWORD(wParam)
            Select Case Lo
                Case SB_LINEUP
                    Me.DateGrid1.Scroll 0, -1
                Case SB_LINEDOWN
                    Me.DateGrid1.Scroll 0, 1
                Case SB_PAGEUP
                    Me.DateGrid1.Scroll 0, -Me.DateGrid1.VisibleRows
                Case SB_PAGEDOWN
                    Me.DateGrid1.Scroll 0, Me.DateGrid1.VisibleRows
                Case SB_THUMBPOSITION
                    Me.DateGrid1.Scroll 0, Hi
            End Select
    End Select

    WindowProc = CallWindowProc(P_hwndNext, hWnd, uMsg, wParam, lParam)
End Function

'下位ワードの取得
Public Function LOWORD(lng As Long) As Integer
    CopyMemory LOWORD, lng, 2
End Function

'上位ワードの取得
Public Function HIWORD(lng As Long) As Integer
    CopyMemory HIWORD, ByVal VarPtr(lng) + 2, 2
End Function

上記のような関数を作成している途中で気がつきましたが、
WindowProcのwParamがLongで、
wParamの上位ワードがスクロール量なので、
基本的にIntegerを超える量はスクロールさせることは
不可能なのでしょうか?


特命希望  2005-03-23 03:18:25  No: 120393

10万件を表示させようとするのが、そもそも無茶っぽいんだけど、その 32594(7f52) と 32767(7fff) の差は何が原因だろう。内部キャッシュサイズかな??

> 基本的にIntegerを超える量はスクロールさせることは
> 不可能なのでしょうか?

DataGridは、OS標準のコントロールではないので、内部動作についてはブラックボックスでしょう。WM_VSCROLLでの移動量が10だったとしても、レコード移動数が10件なのか、10ページ分なのか、100件分なのかは、コントロール側の実装に依存するでしょうし、WM_VSCROLL 以外のスクロール用メッセージが用意されているかも不明です。

どうしても10万件のデータを処理したいなら、メーカーのサポートに問い合わせてみては? サポートしてくれるかどうかはわかりませんが。


にっちゃん  2005-03-23 18:56:09  No: 120394

自己レスです。
ご協力くださった方々には申し訳ございませんが、
1つのデータグリッドで、データベース全件を
表示することはあきらめました。
コンボボックスで3万件ごとに切り分けて表示することにします。
ありがとうございました。


特攻隊長まるるう  2005-03-23 19:40:51  No: 120395

終始自己レスですか…その割に表示件数が無茶だという事だけは
受け入れて頂けたようで。
子曰く、学びて思はざれば則ち罔く、思ひて学ばざれば則ち殆し。

…結局、何に依存したエラーなのか調べられて無いから、公の
掲示板を利用した割に…意味が薄いスレッドとなってしまいました。


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

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






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