何個のスレッド数が適正かを判断するために、スレッド数は可変、外からわたすようにしておきます。
最初のメソッドです。ここからワーカーコマンドで別スレッドで実行するメソッドを呼び出します。スレッド数と担当番号を渡します。
//CW_RIM_pick_MD_Init //20171228 yabe C_LONGINT($1;$numOfThread) $numOfThread:=$1 C_LONGINT($winRef;$i;$myNum) $winRef:=Current form window //途中経過表示用のフォーム For ($i;1;$numOfThread) $cw_name:="cw_"+String($i) $myNum:=$i-1 CALL WORKER($cw_name;"CW_MD_Add";$cw_name;$winRef;$numOfThread;$myNum) End for
呼び出された側では、OPテーブルの全レコードについて、担当番号のレコードだけ処理します。全レコード数をスレッド数で割った余りが自分の担当番号と一致した場合にだけ処理する、というロジックにしました。テーブルとフィールドはコンポーネント化を考慮してポインタで参照しています。第4引数のフォームに、CALL FORMを呼び出して進捗状況を表示します。
最後にすべての処理が終わったところで自分自身をKILL WORKERしています。このため親メソッドからワーカー名(第1引数)をもらっています。
//CW_MD_Add
//20171228 wat
//コンポーネントメソッド、見出しのリンクを更新
C_TEXT($1;$cw_name)
$cw_name:=$1
C_LONGINT($2;$winRef)
$winRef:=$2
C_LONGINT($3;$numOfThread)
$numOfThread:=$3
C_LONGINT($4;$myNum)
$myNum:=$4
MD_DefInit
SN_DefInit
HB_DefInit
HB_cache_make
C_POINTER($OPptr)
C_POINTER($OP_HTMLptr)
C_POINTER($OP_ORG_FNAMEptr)
C_LONGINT($i;$numOfRecs)
C_LONGINT($hb_id)
C_BOOLEAN($done)
C_TEXT($html)
//見出しテーブルをクリアして、シリアル番号をリセット
JCL_tbl_DelAll (vMDptr)
JCL_tbl_ResetSN ("MD_ID";"MIDASI")
//オーピーの全レコードについて見出しを抽出
$OPptr:=JCL_tbl_GetPtr_byName ("V_ORG_PAGE")
$OP_HTMLptr:=JCL_tbl_GetFldPtr ($OPptr;"OP_HTML")
$OP_ORG_FNAMEptr:=JCL_tbl_GetFldPtr ($OPptr;"OP_ORG_FNAME")
READ ONLY($OPptr->)
ALL RECORDS($OPptr->)
FIRST RECORD($OPptr->)
READ WRITE(vMDptr->)
$numOfRecs:=Records in selection($OPptr->)
$i:=1
While (($i<=$numOfRecs) & ($done=False))
CALL FORM($winRef;"CW_RIM_pick_MD_Pgs";$myNum;$i;$numOfRecs;$start;$numOfThread)
If (($i%$numOfThread)=$myNum)
// OPのレコードに対して実行
GOTO SELECTED RECORD($OPptr->;$i)
$html:=$OP_HTMLptr->
hb_id:=HB_cache_find($OP_ORG_FNAMEptr->)
// 見出しテーブルにレコードを追加
MD_Add ($html;$hb_id)
End if
// ユーザによるキャンセルがあれば$doneをfalseにセットする
$i:=$i+1
End while
UNLOAD RECORD(vMDptr->)
READ ONLY(vMDptr->)
KILL WORKER($cw_name)
以下は、CALL FORMで現在の進捗を表示するメソッドです。ホストプロジェクトで画面に表示されているフォームの進捗バーと文字列に、処理数を渡しています。
//CW_RIM_pick_MD_Pgs
//20171228 yabe
C_LONGINT($1;$myNum)
$myNum:=$1+1
C_LONGINT($2;$count)
$count:=$2
C_LONGINT($3;$all)
$all:=$3
C_LONGINT($4;$start)
$start:=$4
C_LONGINT($5;$numOfThread)
$numOfThread:=$5
C_POINTER($ptr)
$ptr:=OBJECT Get pointer(Object named;"vC01_lstCW_Count")
$ptr->{$myNum}:=$count
C_LONGINT($sum)
$sum:=Sum($ptr->)
$ptr:=OBJECT Get pointer(Object named;"vC01_Thermo")
$ptr->:=$sum/$numOfThread/$all*100
C_TEXT($msg)
$msg:="No."+String($myNum)+" "
$msg:=$msg+String($count)+" / "+String($all)
$msg:=$msg+" ("+String((Milliseconds-$start)/1000)+"sec)"
$ptr:=OBJECT Get pointer(Object named;"vC01_lstCW_CountStr")
$ptr->{$myNum}:=$msg
【注意】
この例では、ユーザによる途中キャンセルが実装されていません。
