現在、データグリッドを使用して、
10万行超のデータベースファイルを
表示させようとしております。
データベースはADODCを使用してリンクしています。
データグリッドの縦スクロールバーで最終行を表示しようとすると、
強制的に32594行を表示します。
縦スクロールバーのスクロール位置も、
一番下から自動的に32594行に戻ってしまいます。
どうも符号付整数の制限に引っ掛かっているようです。
上記のような制限を解除する有効な手段はないものでしょうか?
なお、当方の開発環境はVB6.0(SP6)、WindowsXP Pro SP2です。
どなたかご教授くださいますよう、よろしくお願い申し上げます。
>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
あ、大事な宣言も消しちゃってるよw…まぁ、引数の型が分かってれば想像は付くだろうケド
Private Enum LocalRecordsetColumn
ID
Namex
Text
End Enum
自己レスです。
データグリッドをサブクラス化し、
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を超える量はスクロールさせることは
不可能なのでしょうか?
10万件を表示させようとするのが、そもそも無茶っぽいんだけど、その 32594(7f52) と 32767(7fff) の差は何が原因だろう。内部キャッシュサイズかな??
> 基本的にIntegerを超える量はスクロールさせることは
> 不可能なのでしょうか?
DataGridは、OS標準のコントロールではないので、内部動作についてはブラックボックスでしょう。WM_VSCROLLでの移動量が10だったとしても、レコード移動数が10件なのか、10ページ分なのか、100件分なのかは、コントロール側の実装に依存するでしょうし、WM_VSCROLL 以外のスクロール用メッセージが用意されているかも不明です。
どうしても10万件のデータを処理したいなら、メーカーのサポートに問い合わせてみては? サポートしてくれるかどうかはわかりませんが。
自己レスです。
ご協力くださった方々には申し訳ございませんが、
1つのデータグリッドで、データベース全件を
表示することはあきらめました。
コンボボックスで3万件ごとに切り分けて表示することにします。
ありがとうございました。
終始自己レスですか…その割に表示件数が無茶だという事だけは
受け入れて頂けたようで。
子曰く、学びて思はざれば則ち罔く、思ひて学ばざれば則ち殆し。
…結局、何に依存したエラーなのか調べられて無いから、公の
掲示板を利用した割に…意味が薄いスレッドとなってしまいました。
ツイート | ![]() |