前からの続きで、CSVデータを表示するプログラムを作っているがデータが多いとTABLE表示でブラウザが応答しなくなるのでページを分割して1ページの表示件数を少なくする処理を考えてみた。
※プログラム初心者のため、このページのプログラムソースは正常に動作しない事がありますご注意下さい。
(あっちこっちのサイトの情報を寄せ集めてるので思わぬ不具合があるかも)
概要
配列(@csv_line)の一部分を取り出すプログラム。
イメージ的には(プログラムの手法とは違うが)、配列(@csv_line)を1ページの表示件数($pageing_limit)で分割し、$pageing_nowで指定した部分を表示する。
プログラム
※本体はサブルーチンの「pageing」ですが、ループ等で使用する変数以外は変数の局所化を行っていないので
変数「@csv_line」と「$pageing_??」がサブルーチン内外で使えるようなスコープ設定が必要。
local @csv_line; #ページ処理する配列
#1.変数の定義
local $pageing_limit=10;#★1ページの表示件数(0=全件)
local $pageing_now=1; #★表示ページ(1ページから)
local $pageing_skip=0; #★移動用(スキップ指定が0以外の時は表示ページを移動)
local $pageing_hi=50; #設定値 1ページの表示最大件数
local $pageing_low=0; #設定値 1ページの表示最低件数(0=全件)
local $pageing_def=10; #設定値 1ページの表示件数初期値(hiとlowの範囲内である)
local $pageing_max; #最大ページ数(1ページから)
local $pageing_all; #ページ処理前の全データ数(0=なし/1以上)
local $pageing_part; #ページ処理後のデータ数(0=なし/1以上)
#@csv_lineにデータを書き込む(ここでは適当に1001個作成)
for($i=0;$i<=1000;$i++){$csv_line[$i]=$i;}
#ページ処理
&pageing();
#ページ処理されたデータを出力
for($i=0;$i<=$#csv_line;$i++){print "$csv_line[$i]\n";}
print "全ページ数(1~)は $pageing_max、";
print "現在ページ(0=最終ページ/1~)は $pageing_now、";
print "データの表示件数上限は(0=全件) $pageing_limit、";
print "全データ数は(1~)は $pageing_all、";
print "表示データ数は(1~)は $pageing_part、";
exit;
sub pageing{
my($i,$st,$ed,@li);
$pageing_all=$#csv_line+1; #全データ件数
#1.表示件数の決定(範囲外なら初期値を採用)
if($pageing_limit =~ /^[0-9]+$/ ){
if($pageing_limit > $pageing_hi){
$pageing_limit=$pageing_def;
}elsif($pageing_limit < $pageing_low){
$pageing_limit=$pageing_def;
}
}else{
$pageing_limit=$pageing_def;
}
if($pageing_limit<1){$pageing_limit=1;}
#2.リスト抽出
if($pageing_limit==0){ #2a.全件出力時
#@csv_lineに何もせず nowとmaxを1ページ目とする
$pageing_now=1;
$pageing_max=1;
}else{ #2b.通常出力時
#2b-1.全ページ数を計算
$pageing_max=($#csv_line+1)/$pageing_limit;
if($pageing_max > int($pageing_max)){
$pageing_max=int($pageing_max)+1;
}
if($pageing_max<1){$pageing_max=1;}
#2b-2.表示ページを決定(now+skipが範囲外なら範囲内に)
if($pageing_now =~ /^[0-9]+$/ ){
if($pageing_now==0){
$pageing_now=$pageing_max;
}
if($pageing_skip =~ /^[0-9]+$/ ){
$pageing_now=$pageing_now+$pageing_skip;
}
}else{
$pageing_now=1; #表示ページが数値外なら1ページ目
}
if($pageing_now<1){$pageing_now=1;}
if($pageing_now>$pageing_max){
$pageing_now=$pageing_max;
}
#2b-3.@csv_lineから範囲を出力
$st=$pageing_limit*($pageing_now-1);
$ed=$st+($pageing_limit-1);
if($ed>$#csv_line){$ed=$#csv_line;}
for($i=$st;$i<=$ed;$i++ ){
push(@li,$csv_line[$i]);
}
@csv_line=@li;
}
$pageing_part=$#csv_line+1; #処理後のデータ件数
}
詳細
使用するグローバル変数。
・★のある3つが管理者以外が自由に変更できる値、本来はフォームなどから入力
・設定値とある3つは管理者が決定する値、エラートラップは無いので注意
・max・all・paetの3つは処理後に値が格納される。
1ページ中に15件表示したければ「$pageing_limit=15;」とする。
全件表示は「$pageing_limit=0;」または配列以上の値を指定する。
limitはフォームなどでユーザーが切り替えれるようにしても良いが、low~hiの間である事、超えた場合は初期値(def)が代入される。
2ページが見たい時は「$pageing_now=2;」とする、1ページ以下は1ページ、最終ページ以上は最終ページとなる。
0を指定すると最終ページとなる。($pageing_nowが書き換えられる)、フォームなどからユーザーが移動できるようにようする。
「$pageing_skip」は100ページ前が見たい時などに$pageing_nowはそのままで「$pageing_skip=-100;」とすると
$pageing_nowから100ページ前を表示する事ができる。範囲外になった時は$pageing_nowと同じ。
使わない時は0または未指定。
$pageing_nowと$pageing_skipを同時に変更すると$pageing_now+$pageing_skipに移動していまうので、nowとskipはどちらかは固定して使う事