[リストへもどる]   [VBレスキュー(花ちゃん)]
一括表示

投稿時間:2007/04/19(Thu) 16:08
投稿者名:ひろ
Eメール:
URL :
タイトル:
約○○件中 ○〜○件を表示2
お世話になっております。前スレが長くなってしまったので新しく立てます。すみません。。

現在ADOと接続をした後、以下のようにしています。
  a = "1"

    '表示する内容をグリッドに表示
    Adodc1.CommandType = adCmdText
    'Adodc1.RecordSource = " select * from "
    Adodc1.RecordSource = " select * from ( " & _
    " select row_number() over (order by NUM desc) NO, CODE " & _
    " , NAME, NUM , YEAR, TERM, REG_DAY, UPDATE_DAY from test order by NUM " & _
    " ) where NO >= " & a & " and NO <= " & a + 19
    
'レコードセットを更新する
    Adodc1.Refresh
'ADOのレコードソースをデータグリッドコントロールに連結する
    Set DataGrid1.DataSource = Adodc1.Recordset

フォームロード時に1〜20件を表示しています。
変数「a」に同じフォームにあるコマンドボタンを押すことによってプラス20ずつして表示
出来たらと思うのですが、コマンドボタンのコードがうまく書けない状態です。
どのようにしたら、うまく「a」に変数が入るのでしょうか?

投稿時間:2007/04/19(Thu) 16:11
投稿者名:ひろ
Eメール:
URL :
タイトル:
Re: 約○○件中 ○〜○件を表示2
魔界の仮面弁士様の
>カーソルモードにもよりますが、Recordset の
>PageSize/PageCount/AbsolutePage プロパティを使うとか。
についても調べてみました。この方法はすごくよいと思ったのですが、
全件取得しての表示ではないかと思い、使用には悩んでおります。。。

投稿時間:2007/04/19(Thu) 19:11
投稿者名:魔界の仮面弁士
Eメール:
URL :
タイトル:
回答に非ず
# 直接の回答では無いので、読む必要はないかも。

> 全件取得しての表示ではないかと思い、使用には悩んでおります。。。
最初の投稿で、
>>> 「約97件中  81〜97件を表示」と表示したいです。
と書かれていましたよね。

97件ぐらいなら、全件取得した方が効率が良い気もしますが、たとえば数万件クラスの
データであれば、最初に SELECT COUNT(*) でサーバ側に件数を問い合わせて、逐次、
「○○〜○○件目だけを取得するための SQL」を投げるスタイルの方が良いでしょうね。
(ただし、他の接続などによって、途中で件数が変化した場合のことも考慮しないといけませんが)

>> PageSize/PageCount/AbsolutePage プロパティを使うとか。
> についても調べてみました。この方法はすごくよいと思ったのですが、

良い場合もあれば、悪い場合もあります。使用するOLE DBプロバイダやデータ量など、
さまざまな要件によって、適切な解というのは異なりますから、サーバ/クライアント両者の
負荷率を調査しつつ、実際に『試して』みないと分からないと思います。
# 机上の理論だけで進めていくと、あとで泣きをみるかもしれません。

> 全件取得しての表示ではないかと思い、使用には悩んでおります。。。
だからこその、
> > keyset カーソルなどを選択する必要があるでしょう。
という回答なわけで。

既に Recordset を開いているのであれば、CursorType プロパティを確認してください。
これが静的カーソルになっているのなら、全件取得されることになります。

一方、キーセットカーソルなら、「全件分の主キー情報」+「CacheSize に指定された件数のレコード」が
読み込まれ、実際にその行に移動するまでは、データを取りに行かない仕様になっています。
ですから、サーバ・クライアント間の通信負荷は、それほど高くはなりません。

もし、キー情報さえも、全件分取得するのに抵抗があるのであれば、動的カーソルという
選択肢もあります。動的カーソルは、仕組み的にはキーセットと同様ですが、
一度に取得されるキー情報が、CasheSize で指定された件数分のみとなっています。
(動的カーソルは取扱いが面倒なので、あまりお奨めはしませんが)

ちなみに、データ量が多い場合でも、あえて静的カーソルが選択される場合もあります。
いわゆる“切断された Recordset”を使った開発手法です。

更新頻度の低い割に、利用頻度が高い情報の場合には、毎回サーバに問い合わせを行うのではなく、
最初に「切断型レコードセット」に全件分キャッシュしておいてから、クライアント上だけで
抽出してやった方が、はるかに高速に処理できます。接続型レコードセットと切断型レコードセットとでは、
フィールド値の読み書きの速度や、レコード間の移動速度でさえ、かなりの差が生じますからね。

投稿時間:2007/04/20(Fri) 10:23
投稿者名:YK
Eメール:
URL :
タイトル:
Re: 回答に非ず
こんにちは。

> 97件ぐらいなら、全件取得した方が効率が良い気もしますが、たとえば数万件クラスの
> データであれば、最初に SELECT COUNT(*) でサーバ側に件数を問い合わせて、逐次、
> 「○○〜○○件目だけを取得するための SQL」を投げるスタイルの方が良いでしょうね。

私はSQL Server を使用しているのですが
「○○〜○○件目だけを取得するための SQL」などと出来るのでしょうか?
Top n とかは出来るのですが途中からのは考えつかないです。
宜しければご伝授お願いします。

投稿時間:2007/04/20(Fri) 20:07
投稿者名:魔界の仮面弁士
Eメール:
URL :
タイトル:
Re^2: 回答に非ず
> 「○○〜○○件目だけを取得するための SQL」などと出来るのでしょうか?
> Top n とかは出来るのですが途中からのは考えつかないです。

SQL Server なら、こういうイメージでできませんかね? 未検証ですけれども。

1ページ目:SELECT TOP 10 〜 FROM 〜 WHERE (条件)
2ページ目:SELECT TOP 10 〜 FROM 〜 WHERE (条件) AND (主キー列 > [1ページ目の最終レコードの値])
3ページ目:SELECT TOP 10 〜 FROM 〜 WHERE (条件) AND (主キー列 > [2ページ目の最終レコードの値])

http://support.microsoft.com/kb/318131/en-us

投稿時間:2007/04/21(Sat) 07:24
投稿者名:YK
Eメール:
URL :
タイトル:
Re^3: 回答に非ず
こんにちは。

有り難う御座いました。
思いつきませんでした。

> SQL Server なら、こういうイメージでできませんかね? 未検証ですけれども。
>
> 1ページ目:SELECT TOP 10 〜 FROM 〜 WHERE (条件)
> 2ページ目:SELECT TOP 10 〜 FROM 〜 WHERE (条件) AND (主キー列 > [1ページ目の最終レコードの値])
> 3ページ目:SELECT TOP 10 〜 FROM 〜 WHERE (条件) AND (主キー列 > [2ページ目の最終レコードの値])
>
> http://support.microsoft.com/kb/318131/en-us

投稿時間:2007/04/23(Mon) 09:12
投稿者名:ひろ
Eメール:
URL :
タイトル:
Re^4: 回答に非ず
> こんにちは。
>
> 有り難う御座いました。
> 思いつきませんでした。
>
> > SQL Server なら、こういうイメージでできませんかね? 未検証ですけれども。
> >
> > 1ページ目:SELECT TOP 10 〜 FROM 〜 WHERE (条件)
> > 2ページ目:SELECT TOP 10 〜 FROM 〜 WHERE (条件) AND (主キー列 > [1ページ目の最終レコードの値])
> > 3ページ目:SELECT TOP 10 〜 FROM 〜 WHERE (条件) AND (主キー列 > [2ページ目の最終レコードの値])
> >
> > http://support.microsoft.com/kb/318131/en-us

自分は、row_number使って取得したのですが、それは使えませんか?

投稿時間:2007/04/23(Mon) 09:21
投稿者名:魔界の仮面弁士
Eメール:
URL :
タイトル:
Re^5: 回答に非ず
ひろさんは Oracle を利用されていますが、YK さんは SQL Server ですね。

> 自分は、row_number使って取得したのですが、それは使えませんか?
SQL Server 2005 ならば利用できます。2000 以下ではサポートされていません。

投稿時間:2007/04/23(Mon) 09:53
投稿者名:YK
Eメール:
URL :
タイトル:
Re^5: 回答に非ず
こんにちは。
> 自分は、row_number使って取得したのですが、それは使えませんか?

魔界の仮面弁士さんの言われるようにSQL Server 2000です。
2005を使用するときに参考にさせて頂きます。

投稿時間:2007/04/19(Thu) 17:18
投稿者名:シュウ
Eメール:
URL :
タイトル:
Re: 約○○件中 ○〜○件を表示2
> お世話になっております。前スレが長くなってしまったので新しく立てます。すみません。。
>
> 現在ADOと接続をした後、以下のようにしています。
>   a = "1"
>
>     '表示する内容をグリッドに表示
>     Adodc1.CommandType = adCmdText
>     'Adodc1.RecordSource = " select * from "
>     Adodc1.RecordSource = " select * from ( " & _
>     " select row_number() over (order by NUM desc) NO, CODE " & _
>     " , NAME, NUM , YEAR, TERM, REG_DAY, UPDATE_DAY from test order by NUM &quo
t; & _
>     " ) where NO >= " & a & " and NO <= " & a
+ 19
>    
> 'レコードセットを更新する
>     Adodc1.Refresh
> 'ADOのレコードソースをデータグリッドコントロールに連結する
>     Set DataGrid1.DataSource = Adodc1.Recordset
>
> フォームロード時に1〜20件を表示しています。
> 変数「a」に同じフォームにあるコマンドボタンを押すことによってプラス20ずつして表示
> 出来たらと思うのですが、コマンドボタンのコードがうまく書けない状態です。
> どのようにしたら、うまく「a」に変数が入るのでしょうか?

とりあえず、どこにも定義がないので「a」の正体がよくわかりませんが…。
まあ、「a」はモジュール変数で定義するべきでしょうね。(個人的にはLONG型をお勧めします)
フォームロード時に上記の処理が実行されたとして、
後は、コマンドボタン押下時の処理に、
「a」に1を入れる を 「a」に20を追加 と変更して、
後は同じ処理をしてやればいいんじゃないでしょうか?

投稿時間:2007/04/19(Thu) 19:20
投稿者名:魔界の仮面弁士
Eメール:
URL :
タイトル:
Re: 約○○件中 ○〜○件を表示2
>     " ) where NO >= " & a & " and NO <= " & a + 19
NO 値を変える度に、SQL を毎回作り直すのは効率が悪いのでは。

Prepared な Command オブジェクトを使って、NO 値を Parameter として
渡した方が、前回処理した SQL が活かされるかと思いますよ。

>     Adodc1.Refresh
ADODC はコネクションやトランザクションを管理しにくいので、あまり使わない方が良いかと。
DataEnvironment で代用するか、自分で Connection を生成して使った方が無難です。

投稿時間:2007/04/23(Mon) 09:11
投稿者名:ひろ
Eメール:
URL :
タイトル:
Re^2: 約○○件中 ○〜○件を表示2
お返事遅れました。すみません・・・。
何とか、「a」に変数を渡して表示できるようになりました。
(「a」は変数で定義してあります)
うまく理解出来ない部分などあったのにも関わらず、
親切に教えていただきましてありがとうございました!

まだまだ、分からないことばかりですがアドバイスしていただいたことを
理解して生かしていきたいなと思ってます。ありがとうございましたm(_ _)m