/*
 * Copyright (c) 2009 The openGion Project.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
 * either express or implied. See the License for the specific language
 * governing permissions and limitations under the License.
 */
package org.opengion.hayabusa.taglib;

import org.opengion.fukurou.system.OgRuntimeException;							// 6.4.2.0 (2016/01/29)
import org.opengion.fukurou.system.OgCharacterException;						// 6.5.0.1 (2016/10/21)
import org.opengion.fukurou.system.ThrowUtil;									// 6.4.2.0 (2016/01/29)
import org.opengion.fukurou.util.ErrorMessage;
import org.opengion.fukurou.util.StringUtil;
import org.opengion.fukurou.util.ToString;										// 6.1.1.0 (2015/01/17)
import org.opengion.fukurou.util.FileInfo;										// 6.2.0.0 (2015/02/27)
import org.opengion.fukurou.util.ArraySet;										// 6.4.3.4 (2016/03/11)
import org.opengion.hayabusa.common.HybsSystem;
import org.opengion.hayabusa.common.HybsSystemException;
import org.opengion.hayabusa.common.HybsOverflowException;						// 6.2.2.0 (2015/03/27)
import org.opengion.hayabusa.db.DBTableModelUtil;								// 6.2.1.0 (2015/03/13)
import org.opengion.hayabusa.db.DBTableModel;
import org.opengion.hayabusa.db.DBColumn;
import org.opengion.hayabusa.db.ColumnActionListener;							// 6.2.2.0 (2015/03/27)
import org.opengion.hayabusa.io.TableReader;
import org.opengion.hayabusa.io.HybsFileOperationFactory;						// 8.0.0.1 (2021/10/08)

import static org.opengion.fukurou.util.StringUtil.nval;
import static org.opengion.fukurou.system.HybsConst.BR;							// 6.1.0.0 (2014/12/26) refactoring

import java.util.Locale;
import java.util.List;															// 6.2.5.0 (2015/06/05)
import java.util.Set;															// 6.4.3.4 (2016/03/11)
import java.util.ArrayList;														// 6.2.5.0 (2015/06/05)
import java.util.Map;															// 6.4.6.0 (2016/05/27)
import java.util.HashMap;														// 6.4.6.0 (2016/05/27)
import java.io.File;

/**
 * 指定のﾌｧｲﾙを DBTableModelｵﾌﾞｼﾞｪｸﾄに読み取るﾌｧｲﾙ入力ﾀｸﾞです｡
 *
 * ﾃﾞｰﾀ(DBTableModel)と､ｺﾝﾄﾛｰﾗ(ReadTableﾀｸﾞ)を与えて､外部からｺﾝﾄﾛｰﾙすることで､
 * 各種形式で ﾃﾞｰﾀ(DBTableModel)を表示させることが できます｡
 * ReadTableﾀｸﾞ に対して､ｺﾏﾝﾄﾞを与えることにより､内部のｺﾝﾄﾛｰﾗの実装に対応した
 * 形式でﾃﾞｰﾀを作成します｡
 * すべての読取の初期ｸﾗｽ名を ﾘｿｰｽﾌｧｲﾙの TABLE_READER_DEFAULT_CLASS で指定可能です｡
 * その場合､AutoReader を指定すると､Excel と Text(ﾃｷｽﾄ) を以下の順番で試します｡
 * Excel,Calc,Text(UnicodeLittle),Text(Windows-31J),Text(UTF-8),Text(EUC-JP),POI
 * UTF-8 のTEXTとWindows-31JのTEXTは､ﾍｯﾀﾞｰ部での区別ができないため､正確なTextの自動読取できません｡
 *
 * ※ 6.2.5.0 (2015/06/05) 仕様変更
 *    ･AutoReader で､encode を指定すると､Text(encode) を先に試します｡
 *    ･Textで､encode を指定しない場合は､ｼｽﾃﾑ変数の FILE_ENCODE を使用します｡
 *
 * 入力件数を"DB.COUNT" ｷｰでﾘｸｴｽﾄにｾｯﾄしています｡
 *
 * ※ 7.3.1.3 (2021/03/09) DB.NAMES , DB.ORGNAMES
 *    #NAME や columns で指定したｶﾗﾑは､{&#064;DB.NAMES} で取り出すことが可能です｡
 *    ﾌｧｲﾙにかかれた､ｵﾘｼﾞﾅﾙの #NAME は､{&#064;DB.ORGNAMES} で取り出すことが可能です｡
 *
 * @og.formSample
 * ●形式：
 *     &lt;og:readTable
 *         command      = "NEW"
 *         fileURL      = "{&#064;USER.ID}"     読取元ﾃﾞｨﾚｸﾄﾘ名
 *         filename     = "{&#064;filename}"    読取元ﾌｧｲﾙ名
 *         encode       = "UnicodeLittle"       読取元ﾌｧｲﾙｴﾝｺｰﾄﾞ名
 *         maxRowCount  = "10000"               読取最大件数(初期値:0:[無制限])
 *     /&gt;
 * ●body：なし
 *
 * ●Tag定義：
 *   &lt;og:readTable
 *       readerClass        【TAG】実際に読み出すｸﾗｽ名の略称(TableReader_**** の ****)をｾｯﾄします
 *                                  (初期値:TABLE_READER_DEFAULT_CLASS[={@og.value SystemData#TABLE_READER_DEFAULT_CLASS}])
 *       command            【TAG】ｺﾏﾝﾄﾞ (NEW,RENEW)をｾｯﾄします(初期値:NEW)
 *       fileURL            【TAG】読取元ﾃﾞｨﾚｸﾄﾘ名を指定します(初期値:FILE_URL)
 *       filename           【TAG】ﾌｧｲﾙを読み出すときのﾌｧｲﾙ名をｾｯﾄします (初期値:FILE_FILENAME[=file.xls])
 *       encode             【TAG】ﾌｧｲﾙを読み出すときのﾌｧｲﾙｴﾝｺｰﾃﾞｨﾝｸﾞ名をｾｯﾄします(初期値:FILE_ENCODE)
 *       skipRowCount       【TAG】(通常は使いません)ﾃﾞｰﾀの読み飛ばし件数を設定します
 *       maxRowCount        【TAG】読取時の最大取り込み件数をｾｯﾄします (初期値:0:[無制限])
 *       errRowCount        【TAG】読取時の最大ｴﾗｰ件数をｾｯﾄします (初期値:{@og.value #ERROR_ROW_COUNT})(0:[無制限])
 *       separator          【TAG】可変長ﾌｧｲﾙを読み出すときの項目区切り文字をｾｯﾄします
 *       columns            【TAG】読取元ﾌｧｲﾙのｶﾗﾑ列を､外部(ﾀｸﾞ)よりCSV形式で指定します
 *       omitNames          【TAG】読取対象外のｶﾗﾑ列を､外部(ﾀｸﾞ)よりCSV形式で指定します
 *       modifyType         【TAG】ﾌｧｲﾙ取り込み時の ﾓﾃﾞｨﾌｧｲﾀｲﾌﾟ(A(追加),C(更新),D(削除))を指定します
 *       displayMsg         【TAG】query の結果を画面上に表示するﾒｯｾｰｼﾞIDを指定します(初期値:VIEW_DISPLAY_MSG[={@og.value SystemData#VIEW_DISPLAY_MSG}]))
 *       overflowMsg        【TAG】読取ﾃﾞｰﾀが最大検索数をｵｰﾊﾞｰした場合に表示するﾒｯｾｰｼﾞﾘｿｰｽIDを指定します (初期値:MSG0007[検索結果が､制限行数を超えましたので､残りはｶｯﾄされました])
 *       notfoundMsg        【TAG】検索結果がｾﾞﾛ件の場合に表示するﾒｯｾｰｼﾞﾘｿｰｽIDを指定します(初期値:MSG0077[対象ﾃﾞｰﾀはありませんでした])
 *  ※   sheetName          【TAG】EXCELﾌｧｲﾙを読み込むときのｼｰﾄ名を設定します(初期値:指定なし)
 *  ※   sheetNos           【TAG】EXCELﾌｧｲﾙを読み込むときのｼｰﾄ番号を複数設定できます(初期値:0)
 *  ※   sheetConstKeys     【TAG】EXCELﾌｧｲﾙを読み込むときの固定値となるｶﾗﾑ名(CSV形式)
 *  ※   sheetConstAdrs     【TAG】EXCELﾌｧｲﾙを読み込むときの固定値となるｱﾄﾞﾚｽ(行-列,行-列,･･･)
 *       nullBreakClm       【TAG】ｶﾗﾑ列に NULL が現れた時点で読取を中止します(複数Sheetの場合は､次のSheetを読みます)｡
 *       nullSkipClm        【TAG】ｶﾗﾑ列に NULL が現れたﾚｺｰﾄﾞは読み飛ばします｡
 *       useNumber          【TAG】行番号情報を､使用している/していない[true/false]を指定します(初期値:true)
 *       useRepeatClms      【TAG】読取処理で横持ちﾃﾞｰﾀの繰り返しが存在する場合に､trueを指定します(初期値:false) 7.3.0.0 (2021/01/06)
 *       useRenderer        【TAG】読取処理でKEY:VAL形式のｺｰﾄﾞﾘｿｰｽから､KEYを取り出す処理を行うかどうかを指定します(初期値:USE_TABLE_READER_RENDERER[=false])
 *       adjustColumns      【TAG】読取元ﾌｧｲﾙのﾃﾞｰﾀ変換を行うｶﾗﾑ列をｶﾝﾏ指定します("*" で全ｶﾗﾑ)
 *       checkColumns       【TAG】読取元ﾌｧｲﾙの整合性ﾁｪｯｸを行うｶﾗﾑ列をｶﾝﾏ指定します("*" で全ｶﾗﾑ)
 *       useStrict          【TAG】整合性ﾁｪｯｸ時に､厳密にﾁｪｯｸするかどうか[true/false]を指定します(初期値:true) 7.3.2.0 (2021/03/19)
 *       nullCheck          【TAG】NULL ﾁｪｯｸすべきｶﾗﾑ列をCSV形式(CSV形式)で指定します
 *       matchKeys          【TAG】ﾚｺｰﾄﾞの読取条件指定時のｶﾗﾑ列をCSV形式で指定します 6.4.6.0 (2016/05/27)
 *       matchVals          【TAG】ﾚｺｰﾄﾞの読取条件指定時のｶﾗﾑ列に対応する正規表現ﾃﾞｰﾀをCSV形式で指定します 6.4.6.0 (2016/05/27)
 *       language           【TAG】ﾀｸﾞ内部で使用する言語ｺｰﾄﾞ[ja/en/zh/…]を指定します
 *       stopZero           【TAG】読込件数が０件のとき処理を続行するかどうか[true/false]を指定します(初期値:false[続行する])
 *       mainTrans          【TAG】(通常は使いません)ﾀｸﾞで処理される処理がﾒｲﾝとなるﾄﾗﾝｻﾞｸｼｮﾝ処理かどうかを指定します(初期値:false)
 *       tableId            【TAG】(通常は使いません)sessionから所得する DBTableModelｵﾌﾞｼﾞｪｸﾄの ID
 *       scope              【TAG】ｷｬｯｼｭする場合のｽｺｰﾌﾟ[request/page/session/application]を指定します(初期値:session)
 *       useSLabel          【TAG】7.0.7.0 (2019/12/13) ｴﾗｰﾒｯｾｰｼﾞにSLABELを利用するかどうか[true/false]を指定します(初期値:false)
 *       useLocal           【TAG】ｼｽﾃﾑ定数でｸﾗｳﾄﾞ設定されていても､ｸﾗｳﾄﾞ環境を使用しない場合､trueを指定します(初期値:false) 8.0.1.0 (2021/10/29)
 *       caseKey            【TAG】このﾀｸﾞ自体を利用するかどうかの条件ｷｰを指定します(初期値:null) 5.7.7.2 (2014/06/20)
 *       caseVal            【TAG】このﾀｸﾞ自体を利用するかどうかの条件値を指定します(初期値:null) 5.7.7.2 (2014/06/20)
 *       caseNN             【TAG】指定の値が､null/ｾﾞﾛ文字列 でない場合(Not Null=NN)は､このﾀｸﾞは使用されます(初期値:判定しない) 5.7.7.2 (2014/06/20)
 *       caseNull           【TAG】指定の値が､null/ｾﾞﾛ文字列 の場合は､このﾀｸﾞは使用されます(初期値:判定しない) 5.7.7.2 (2014/06/20)
 *       caseIf             【TAG】指定の値が､true/TRUE文字列の場合は､このﾀｸﾞは使用されます(初期値:判定しない)
 *       debug              【TAG】ﾃﾞﾊﾞｯｸﾞ情報を出力するかどうか[true/false]を指定します(初期値:false)
 *   /&gt;
 *
 * ●使用例
 *
 *     &lt;og:readTable
 *         command        = "NEW"
 *         readerClass    = "Text"                ﾃｷｽﾄﾌｧｲﾙの読取
 *         modifyType     = "{&#064;modifyType}"  読取時のﾓﾃﾞｨﾌｧｲﾀｲﾌﾟ(A,C等)
 *         fileURL        = "{&#064;USER.ID}"     読取元ﾃﾞｨﾚｸﾄﾘ名
 *         filename       = "{&#064;filename}"    読取元ﾌｧｲﾙ名
 *         encode         = "Shift_JIS"           読取元ﾌｧｲﾙｴﾝｺｰﾄﾞ名
 *         maxRowCount    = "10000"               読取最大件数(0:[無制限])
 *         columns        = "OYA,KO,HJO,SU,DYSTR,DYEND"   #NAME に対応するｶﾗﾑ列
 *         useNumber      = "false"               行番号の存在しないﾃﾞｰﾀを読取ます｡
 *         adjustColumns  = "OYA,KO,HJO,SU"       ﾃﾞｰﾀ変換するｶﾗﾑ列("*" で全ｶﾗﾑ)
 *         checkColumns   = "OYA,KO,HJO,SU"       整合性ﾁｪｯｸするｶﾗﾑ列("*" で全ｶﾗﾑ)
 *         nullCheck      = "OYA,KO,SU"           NULLﾁｪｯｸを実行します("*" で全ｶﾗﾑ)
 *         stopZero       = "true"                取得0件の場合に以降の処理を停止します
 *         skipRowCount   = "4"                   ﾃﾞｰﾀの読み飛ばし件数(読み込み開始は､この数字＋１行目から)
 *     /&gt;
 *
 * @og.group ﾌｧｲﾙ入力
 *
 * @version  4.0
 * @author   Kazuhiko Hasegawa
 * @since    JDK5.0,
 */
public class ReadTableTag extends CommonTagSupport {
	/** このﾌﾟﾛｸﾞﾗﾑのVERSION文字列を設定します｡	{@value} */
	private static final String VERSION = "8.1.2.3 (2022/05/20)" ;
	private static final long serialVersionUID = 812320220520L ;

	private static final int ERROR_ROW_COUNT = 200 ;	// 4.0.0 (2007/05/25)

	/** command 引数に渡す事の出来る ｺﾏﾝﾄﾞ  新規作成 {@value} */
	public static final String CMD_NEW   = "NEW" ;
	/** command 引数に渡す事の出来る ｺﾏﾝﾄﾞ  再検索 {@value} */
	public static final String CMD_RENEW = "RENEW" ;

	// 6.4.3.4 (2016/03/11) String配列 から､Setに置き換えます｡
	private static final Set<String> COMMAND_SET = new ArraySet<>( CMD_NEW , CMD_RENEW );

	// 6.2.0.0 (2015/02/27) AutoReaderの対応方法変更｡拡張子に応じて､ﾁｪｯｸ対象を変更する｡null は全対象
	// 6.2.2.0 (2015/03/27) ﾏｸﾛ付Excel(.xlsm)対応
	// 6.2.5.0 (2015/06/05) 文字列配列から､内部ｸﾗｽに変更
	// 6.4.5.1 (2016/04/28) 順番の変更と､CSV対応

	private static final List<AutoReaderParam> AUTO_READER_PARAM = new ArrayList<>() ;
	static {
		AUTO_READER_PARAM.add( new AutoReaderParam( "Excel"	,	null			,	"xls,xlsx,xlsm"	) );
		AUTO_READER_PARAM.add( new AutoReaderParam( "CSV"	,	"Windows-31J"	,	"csv"			) );			// 6.4.5.1 (2016/04/28) 追加
		AUTO_READER_PARAM.add( new AutoReaderParam( "CSV"	,	"UTF-8"			,	"csv"			) );			// 6.4.5.1 (2016/04/28) 追加
		AUTO_READER_PARAM.add( new AutoReaderParam( "Text"	,	"UnicodeLittle"	,	null			) );
		AUTO_READER_PARAM.add( new AutoReaderParam( "Text"	,	"Windows-31J"	,	null			) );
		AUTO_READER_PARAM.add( new AutoReaderParam( "Text"	,	"UTF-8"			,	null			) );
		AUTO_READER_PARAM.add( new AutoReaderParam( "Text"	,	"EUC-JP"		,	null			) );
		AUTO_READER_PARAM.add( new AutoReaderParam( "POI"	,	null			,	"ppt,pptx,doc,docx,xls,xlsx,xlsm" ) );		// 6.2.5.0 (2015/06/05) 追加
		AUTO_READER_PARAM.add( new AutoReaderParam( "Calc"	,	null			,	"ods"			) );			// 6.4.5.1 (2016/04/28) 位置変更
	}

	/** 項目区切り文字 */
	protected	String	separator		= TableReader.TAB_SEPARATOR;				// 項目区切り文字 6.2.0.0 (2015/02/27) protected化
	private		String	fileURL 		= HybsSystem.sys( "FILE_URL"		);
	private		String	filename		= HybsSystem.sys( "FILE_FILENAME"	);		// ﾌｧｲﾙ名
	/** ﾌｧｲﾙｴﾝｺｰﾃﾞｨﾝｸﾞ */
	protected	String	encode			;											// 6.2.5.0 (2015/06/05) ﾌｧｲﾙｴﾝｺｰﾃﾞｨﾝｸﾞ
	/** 読取ｸﾗｽ名 */
	protected	String	readerClass		;											// 6.2.0.0 (2015/02/27) protected化
	/** 最大行 */
	protected	int		maxRowCount		;											// 6.2.0.0 (2015/02/27) 初期値を無制限に変更
	/** ﾃﾞｨｽﾌﾟﾚｲﾒｯｾｰｼﾞ */
	protected	String	displayMsg		= HybsSystem.sys( "VIEW_DISPLAY_MSG" );		// 6.2.0.0 (2015/02/27) protected化
	private		String	overflowMsg		= "MSG0007";	// 検索結果が､制限行数を超えましたので､残りはｶｯﾄされました｡
	private		String	notfoundMsg		= "MSG0077";	// 対象ﾃﾞｰﾀはありませんでした｡
	/** 実行件数 */
	protected	int 	executeCount	= -1;			// 検索/実行件数
	private		String	modifyType		;

	private transient DBTableModel table	;
	private		String	command			= CMD_NEW;
	private		String	tableId			= HybsSystem.TBL_MDL_KEY ;
	/** ｼｰﾄ名 */
	protected	String	sheetName		;				// 3.5.4.2 (2003/12/15)
	/** ｼｰﾄ番号 */
	protected	String	sheetNos		;				// 5.5.7.2 (2012/10/09) 複数ｼｰﾄを指定できるようにｼｰﾄ番号を指定できるようにする｡
	/** 固定値となるｶﾗﾑ名 */
	protected	String	sheetConstKeys	;				// 5.5.8.2 (2012/11/09) 固定値となるｶﾗﾑ名(CSV形式)
	/** 固定値となるｱﾄﾞﾚｽ */
	protected	String	sheetConstAdrs	;				// 5.5.8.2 (2012/11/09) 固定値となるｱﾄﾞﾚｽ(行-列,行-列,･･･)
	/** 取込み条件/Sheet BREAK条件 */
	protected	String	nullBreakClm	;				// 5.5.8.2 (2012/11/09) 取込み条件/Sheet BREAK条件
	/** 行読み飛ばし */
	protected	String	nullSkipClm		;				// 6.2.3.0 (2015/05/01) 行読み飛ばし

	/** 3.5.4.5 (2004/01/23) 外部よりｶﾗﾑ列(CSV形式)を指定できるようにする｡	*/
	protected String columns			;				// 6.2.0.0 (2015/02/27) protected化
	/** 6.1.0.0 (2014/12/26) 読取対象外のｶﾗﾑ列を､外部(ﾀｸﾞ)より指定する｡	*/
	protected	boolean	useNumber		= true;			// 3.7.0.5 (2005/04/11)
//	/** 7.3.0.0 (2021/01/06) useRepeatClms 属性を追加｡	*/
//	protected	boolean	useRepeatClms	;				// 7.3.0.0 (2021/01/06)
	/** stopZero属性 */
	protected	boolean	stopZero		;				// 4.3.7.0 (2009/06/01) stopZero属性追加

	private		boolean	isMainTrans		= true;			// 5.1.6.0 (2010/05/01) DBLastSqlの処理の見直し
	/** ﾃﾞｰﾀの読み飛ばし設定 */
	protected	int		skipRowCount	;				// 5.1.6.0 (2010/05/01) ﾃﾞｰﾀの読み飛ばし設定

	/** 6.2.2.0 (2015/03/27) ColumnAction ｲﾝﾅｰｸﾗｽでﾊﾟﾗﾒｰﾀを整理する｡	*/
	protected	transient	ColumnAction clmAct	= new ColumnAction();	// 6.3.9.0 (2015/11/06) transient 追加

	// 6.3.6.1 (2015/08/28) DirectTableInsertTag でSQLException発生時にｾｯﾄする｡（暫定対応）
	// 8.1.1.0 (2022/02/04) sqlError ﾌﾗｸﾞでの判定は、DirectTableInsertTag のみで行います。
//	protected	boolean		sqlError	;				// 6.3.6.1 (2015/08/28)

	/** 7.0.7.0 (2019/12/13) ｴﾗｰﾒｯｾｰｼﾞにSLABELを利用するかどうか[true/false]を指定します(初期値:false)	*/
	protected	boolean		useSLabel	;

	private		boolean		useLocal	;				// 8.0.1.0 (2021/10/29) ｸﾗｳﾄﾞ設定を使用しない場合は､true

	/**
	 * ﾃﾞﾌｫﾙﾄｺﾝｽﾄﾗｸﾀｰ
	 *
	 * @og.rev 6.4.2.0 (2016/01/29) PMD refactoring. Each class should declare at least one constructor.
	 */
	public ReadTableTag() { super(); }		// これも､自動的に呼ばれるが､空のﾒｿｯﾄﾞを作成すると警告されるので､明示的にしておきます｡

	/**
	 * Taglibの終了ﾀｸﾞが見つかったときに処理する doEndTag() を ｵｰﾊﾞｰﾗｲﾄﾞします｡
	 *
	 * @og.rev 3.0.1.4 (2003/03/17) displayMsg が ０Byteの場合は､件数も表示しないように変更｡
	 * @og.rev 3.1.1.2 (2003/04/04) Tomcat4.1 対応｡release2() を doEndTag()で呼ぶ｡
	 * @og.rev 3.5.4.1 (2003/12/01) 引数の BufferedReader を､InputStream に変更｡
	 * @og.rev 3.5.4.3 (2004/01/05) 引数の InputStream を､ BufferedReader に戻す｡
	 * @og.rev 3.5.6.5 (2004/08/09) 暫定的に､DBTableModelを先行削除します｡
	 * @og.rev 3.6.0.0 (2004/09/24) DBTableModel の先行削除は､scope="session" の場合のみ｡
	 * @og.rev 3.6.0.2 (2004/10/04) 取り込み時ﾁｪｯｸ用に､checkColumns,adjustColumns 属性追加
	 * @og.rev 3.6.0.8 (2004/11/19) DBTableModel をｾｰﾌﾞする時に､ﾄﾗﾝｻﾞｸｼｮﾝﾁｪｯｸを行います｡
	 * @og.rev 3.8.5.3 (2006/08/07) readerClassが "Excel"でｴﾗｰが発生したとき､もう一度Defaultで再読取を行います｡
	 * @og.rev 4.0.0.0 (2007/10/12) checkTableColumn 前に､modifyType 設定を行います｡
	 * @og.rev 4.0.0.0 (2007/10/18) ﾒｯｾｰｼﾞﾘｿｰｽ統合( getResource().getMessage ⇒ getResource().getLabel )
	 * @og.rev 4.3.1.1 (2008/10/08) columnsが指定されている場合は､AutoReader禁止
	 * @og.rev 4.3.7.0 (2009/06/01) stopZero機能,DB.COUNTﾘｸｴｽﾄｷｰへ読込件数ｾｯﾄを追加
	 * @og.rev 5.1.6.0 (2010/05/01) DBLastSqlの処理は､DBTableModelが新規作成された処理でのみ行う｡
	 * @og.rev 5.1.8.0 (2010/07/01) AutoReaderのCalc対応
	 * @og.rev 5.1.9.0 (2010/08/01) AutoReaderでのExceptionの判定をThrowableに変更
	 * @og.rev 5.7.1.2 (2013/12/20) tempMsg.toString() ⇒ errMsg 変更
	 * @og.rev 5.7.7.2 (2014/06/20) caseKey,caseVal,caseNN,caseNull 属性を追加
	 * @og.rev 6.0.2.5 (2014/10/31) debug=true 時のｴﾗｰ情報を増やします｡
	 * @og.rev 6.2.0.0 (2015/02/27) TableReader ｸﾗｽの呼び出し元ﾒｿｯﾄﾞの共通化(EXCEL,TEXT)
	 * @og.rev 6.2.0.0 (2015/02/27) EXCEL出力のparamLevel初期値変更 3:標準推奨 → 4:個人設定可
	 * @og.rev 6.2.2.0 (2015/03/27) ColumnAction ｲﾝﾅｰｸﾗｽでﾊﾟﾗﾒｰﾀを整理する｡
	 * @og.rev 6.2.3.0 (2015/05/01) 複数処理を考慮して､例外処理は発行しない｡
	 * @og.rev 6.2.3.0 (2015/05/01) columnsが指定されていても､AutoReader を使えるようにします｡
	 * @og.rev 6.2.4.2 (2015/05/29) ｴﾗｰを画面に出します｡
	 * @og.rev 6.2.5.0 (2015/06/05) AutoReaderの仕様変更｡
	 * @og.rev 6.3.6.1 (2015/08/28) DirectTableInsertTag でSQLException発生時のみ throwする｡
	 * @og.rev 6.4.2.0 (2016/01/29) StringUtil#ogStackTrace(Throwable) を､ThrowUtil#ogStackTrace(String,Throwable) に置き換え｡
	 * @og.rev 6.4.3.4 (2016/03/11) String配列 から､Setに置き換えます｡
	 * @og.rev 6.4.5.1 (2016/04/28) CSV 指定時は､readerClass="Text" , separator="," に､再設定します｡
	 * @og.rev 6.5.0.1 (2016/10/21) Throwable ではなく､OgCharacterException をｷｬｯﾁして､処理を継続します｡
	 * @og.rev 7.0.4.0 (2019/05/31) encode指定時の処理順序変更
	 * @og.rev 7.0.5.0 (2019/09/09) OgCharacterExceptionでは､取りこぼしがあるため､OgRuntimeException も継続処理するように変更｡
	 * @og.rev 8.0.0.1 (2021/10/08) ｸﾗｳﾄﾞ対応
	 * @og.rev 8.0.0.2 (2021/10/15) TableReader系は､ｸﾗｳﾄﾞから､ﾛｰｶﾙﾌｧｲﾙに移してから処理する｡
	 * @og.rev 8.1.1.0 (2022/02/04) sqlError ﾌﾗｸﾞでの判定は、DirectTableInsertTag のみで行います。
	 * @og.rev 8.1.2.3 (2022/05/20) readerClass が AutoReader の時、readerClass が Text になるﾊﾞｸﾞ修正
	 *
	 * @return	後続処理の指示
	 */
	@Override
	public int doEndTag() {
		debugPrint();		// 4.0.0 (2005/02/28)
		// 5.7.7.2 (2014/06/20) caseKey,caseVal,caseNN,caseNull 属性を追加
		if( !useTag() ) { return EVAL_PAGE ; }

		int rtnCode = EVAL_PAGE;

		if( check( command, COMMAND_SET ) ) {
			useMainTrans( isMainTrans );			// 5.1.6.0 (2010/05/01) DBLastSqlの処理の見直し
			startQueryTransaction( tableId );		// 3.6.0.8 (2004/11/19)

			// 3.5.6.5 (2004/08/09) 削除するのは､ｾｯｼｮﾝのｵﾌﾞｼﾞｪｸﾄでよい｡
			// 3.6.0.0 (2004/09/24) 削除するのは､scope="session" の場合のみ｡
			if( "session".equals( getScope() ) ) {
				removeSessionAttribute( tableId );
				removeSessionAttribute( HybsSystem.VIEWFORM_KEY );
			}

			// 6.2.5.0 (2015/06/05) AutoReaderの仕様変更｡

			// 6.2.0.0 (2015/02/27) EXCEL出力のparamLevel初期値変更 3:標準推奨 → 4:個人設定可
			if( readerClass == null ) {
				readerClass = nval( sys( "TABLE_READER_DEFAULT_CLASS" ) , "AutoReader" );
			}

			// ﾌｧｲﾙ の読み込み：AutoReader 処理
			// 6.2.5.0 (2015/06/05) AutoReaderParam 内部ｸﾗｽを使用します｡
			final List<AutoReaderParam> readerParam = new ArrayList<>() ;

			if( "AutoReader".equalsIgnoreCase( readerClass ) ) {
				// 4.3.1.1 (2008/10/08)
	//			// 6.2.3.0 (2015/05/01) columnsが指定されていても､AutoReader を使えるようにします｡
	//			if( columns != null && columns.length() > 0 ) {
	//				final String errMsg = "columnsが指定されている場合は､readerClass=\"AutoReader\"は使えません";
	//				throw new HybsSystemException( errMsg );	// 4.3.4.4 (2009/01/01)
	//			}
				// 6.2.5.0 (2015/06/05) AutoReaderParam 内部ｸﾗｽを使用します｡
				// 6.5.0.1 (2016/10/21) encode 指定時の優先は､拡張子が､txt か､csv のみとします｡
	//			if( encode != null ) { readerParam.add( new AutoReaderParam( "Text" , encode , null ) ); }				// encode 指定時は優先
//				if( encode != null ) { readerParam.add( new AutoReaderParam( "Text" , encode , "csv,txt,xls" ) ); }		// encode 指定時は優先
//				if( encode != null ) { readerParam.add( new AutoReaderParam( "Text" , encode , "txt,csv,xls" ) ); }		// encode 指定時は優先  7.0.4.0 (2019/05/31) 順序変更
				if( encode != null ) {
					readerParam.add( new AutoReaderParam( "Text" , encode , "txt,csv,xls" ) );		// encode 指定時は優先  7.0.4.0 (2019/05/31) 順序変更
					readerParam.add( new AutoReaderParam( "Text" , encode , null          ) );		// 7.1.0.0 (2020/01/20) 拡張子に関係ない分も追加
				}
				readerParam.addAll( AUTO_READER_PARAM );		// 標準のﾊﾟﾗﾒｰﾀを追加します｡
			}
			else {
				// 6.2.5.0 (2015/06/05) readerClass が "Text" で､encode が null の場合は､FILE_ENCODE を使用する｡
				if( "Text".equalsIgnoreCase( readerClass ) && encode == null ) { encode = HybsSystem.sys( "FILE_ENCODE" ); }
				readerParam.add( new AutoReaderParam( readerClass , encode , null ) );	// 8.1.2.3 (2022/05/20) 復活
//				readerParam.add( new AutoReaderParam( "Text" , encode , null ) );		// 8.1.1.0 (2022/02/04) 勘違い?
			}

			final String directory = HybsSystem.url2dir( fileURL );
			final File file = new File( directory,filename );
			// 8.0.0.2 (2021/10/15) TableReader系は､ｸﾗｳﾄﾞから､ﾛｰｶﾙﾌｧｲﾙに移してから処理する｡
			// ※ readなので､ｸﾗｳﾄﾞに戻す必要はない｡
			HybsFileOperationFactory.cloud2local( useLocal,() -> file );

//			// 8.0.0.1 (2021/10/08) ｸﾗｳﾄﾞ対応
//			final File file = HybsFileOperationFactory.create( directory, filename );

			final String sufix = FileInfo.getSUFIX( file ) ;		// 6.2.3.0 (2015/05/01) 拡張子に応じて､ﾁｪｯｸを変更する｡

			StringBuilder tempMsg = new StringBuilder( BUFFER_MIDDLE );
			// 6.2.5.0 (2015/06/05) AutoReaderParam 内部ｸﾗｽを使用します｡
			for( final AutoReaderParam arParam : readerParam ) {
				// 6.2.0.0 (2015/02/27) 拡張子に応じて､ﾁｪｯｸを変更する｡
				if( !arParam.useSufix( sufix ) ) { continue; }		// false:対象外の場合は､次のreaderClassを使う｡

				readerClass = arParam.CLASS;
				encode      = arParam.ENCODE;

				// 6.4.5.1 (2016/04/28) CSV 指定時は､readerClass="Text" , separator="," に､再設定します｡
				if( "CSV".equalsIgnoreCase( readerClass ) || "CSV".equalsIgnoreCase( sufix ) ) {
					readerClass = "Text";
					separator   = ",";
				}

				if( isDebug() ) {
					final String errMsg = "File=[" + file + "] , class=[" + readerClass + "] , encode=[" + encode + "]" + BR ;
					jspPrint( errMsg );
					System.out.println( errMsg );
				}

				try {
					clmAct.isDebug = isDebug();
//					sqlError = false;	// 6.3.6.1 (2015/08/28) DirectTableInsertTag でSQLException発生時のみ処理する｡
					create( file );		// 6.2.0.0 (2015/02/27) TableReader ｸﾗｽの呼び出し元ﾒｿｯﾄﾞの共通化(EXCEL,TEXT)

					// 成功すれば､ｴﾗｰﾒｯｾｰｼﾞをｸﾘｱして､その場で抜ける｡
					tempMsg = null;
					break;
				}
				// 6.2.2.0 (2015/03/27) HybsOverflowException処理をﾀｸﾞ側で行う｡
				catch( final HybsOverflowException ex ) {
					// table.setOverflow( true ); は､処理済み｡ﾙｰﾌﾟから抜けて処理を継続する｡
					tempMsg = null;
					break;
				}
				// 6.3.6.1 (2015/08/28) DirectTableInsertTag でSQLException発生時のみ処理する｡
				catch( final HybsSystemException ex ) {
//					if( sqlError ) { throw ex; }	// SQLException発生時は処理中止
					// 8.1.1.0 (2022/02/04) sqlError ﾌﾗｸﾞでの判定は、DirectTableInsertTag のみで行います。
					tempMsg.append( "File=["  ).append( file )
							.append( "] , Class=["   ).append( readerClass )
							.append( "] , Encode=["  ).append( encode )
							.append( "] Error!"      ).append( CR )
							.append( ex.getMessage() ).append( CR ) ;
				}
				// 3.8.5.3 (2006/08/07) readerClassが "Excel"でｴﾗｰが発生したとき､もう一度Defaultで再読取を行います｡
				// 5.1.9.0 (2010/08/01) RuntimeException系のExceptionがｷｬｯﾁできないため､Throwableで受ける
				// 6.5.0.1 (2016/10/21) Throwable ではなく､OgCharacterException をｷｬｯﾁして､処理を継続します｡
				catch( final OgCharacterException ex ) {
					tempMsg.append( "File=["  ).append( file )
							.append( "] , Class=["   ).append( readerClass )
							.append( "] , Encode=["  ).append( encode )
							.append( "] Error!"      ).append( CR )
							.append( ex.getMessage() ).append( CR ) ;
	//				if( isDebug() ) {
	//					jspPrint( "<pre>" + tempMsg.toString() + "</pre>" );				// 6.2.4.2 (2015/05/29) 画面にも出力します｡
	//					tempMsg.append( ThrowUtil.ogStackTrace( ex ) ).append( CR ) ;		// 6.4.2.0 (2016/01/29)
	//				}
				}
				// 7.0.5.0 (2019/09/09) OgCharacterExceptionでは､取りこぼしがあるため､OgRuntimeException も継続処理するように変更｡
				catch( final OgRuntimeException ex ) {
					tempMsg.append( "File=["  ).append( file )
							.append( "] , Class=["   ).append( readerClass )
							.append( "] , Encode=["  ).append( encode )
							.append( "] Error!"      ).append( CR )
							.append( ex.getMessage() ).append( CR ) ;

					// 拡張子が､xls 以外は､処理を停止します｡
	//				if( !"xls".equalsIgnoreCase( sufix ) ) {
					// 8.1.1.0 (2022/02/04) 拡張子は、xls,xlsx 以外とする。
					if( !"xls".equalsIgnoreCase( sufix ) || !"xlsx".equalsIgnoreCase( sufix ) ) {
						tempMsg.append( ThrowUtil.ogStackTrace( ex ) ).append( CR ) ;
	//					break;		様子見｡当面は､止めません｡
					}
				}
				// 6.5.0.1 (2016/10/21) Throwable をｷｬｯﾁして､処理を中断します｡
				catch( final Throwable th ) {
					tempMsg.append( "File=["  ).append( file )
							.append( "] , Class=["   ).append( readerClass )
							.append( "] , Encode=["  ).append( encode )
							.append( "] Error!"      ).append( CR )
							.append( ThrowUtil.ogStackTrace( th ) ).append( CR ) ;		// 6.4.2.0 (2016/01/29)
					break;
				}
			}

			// 6.2.3.0 (2015/05/01) 複数処理を考慮して､例外処理は発行しない｡
			// 6.4.1.1 (2016/01/16) PMD refactoring. Avoid if (x != y) ..; else ..;
			if( tempMsg == null ) {
				// 6.2.2.0 (2015/03/27) #afterEnd() ﾒｿｯﾄﾞ 新規作成｡
				rtnCode = afterEnd();
			}
			else {								// 最後までｴﾗｰがあれば､例外処理を発行します｡
				final String errMsg = tempMsg.toString();
				System.err.print( errMsg );
				jspPrint( "<pre>" + errMsg + "</pre>" );		// 6.2.4.0 (2015/05/15) ｴﾗｰを画面に出します｡
				rtnCode = SKIP_PAGE;							// 6.2.4.2 (2015/05/29) ｴﾗｰ時はSKIP
			}
		}

		return rtnCode ;
	}

	/**
	 * #doEndTag() の後続処理を記述します｡
	 *
	 * これは､ｻﾌﾞｸﾗｽで､DBTableModel以外の処理を行う場合に､
	 * 処理内容を分けるために用意します｡
	 *
	 * @og.rev 6.2.2.0 (2015/03/27) #afterEnd() ﾒｿｯﾄﾞ 新規作成｡
	 * @og.rev 6.2.4.2 (2015/05/29) executeCount の設定がおかしい｡ReadTableTagでは､設定されていなかった｡
	 * @og.rev 6.2.5.0 (2015/06/05) ｴﾗｰ処理は､継承先でも行うので､ﾒｿｯﾄﾞ化します｡
	 * @og.rev 7.0.7.0 (2019/12/13) useSLabel 属性を追加｡
	 *
	 * @return	後続処理の指示
	 */
	protected int afterEnd() {
		if( table != null ) {
			// 6.2.4.2 (2015/05/29) executeCount が設定されなくなった件
			executeCount = table.getRowCount();

			// 3.6.0.2 (2004/10/04)
			// 4.0.0.0 (2007/10/12) checkTableColumn 前に､modifyType 設定を行います｡

			// 6.2.5.0 (2015/06/05) ｴﾗｰ処理は､継承先でも行うので､ﾒｿｯﾄﾞ化します｡
			final ErrorMessage errMsg = clmAct.getErrorMessage();
			if( !errMsg.isOK() ) {
//				jspPrint( TaglibUtil.makeHTMLErrorTable( errMsg,getResource() ) );
				jspPrint( TaglibUtil.makeHTMLErrorTable( errMsg,getResource(),useSLabel ) );		// 7.0.7.0 (2019/12/13)
				return SKIP_PAGE ;
			}
		}

		// 3.6.0.8 (2004/11/19) ﾄﾗﾝｻﾞｸｼｮﾝﾁｪｯｸを行います｡
		if( ! commitTableObject( tableId, table ) ) {
			jspPrint( "ReadTableTag Query処理が割り込まれました｡DBTableModel は登録しません｡" );
			return SKIP_PAGE ;
		}

		final StringBuilder buf = new StringBuilder( BUFFER_MIDDLE );

		// 実行件数の表示 command="NEW" のときのみ､displayMsg を表示させます｡
		// 4.0.0 (2005/11/30) 出力順の変更｡一番最初に出力します｡
		if( CMD_NEW.equals( command ) ) {
			if( executeCount > 0 && displayMsg != null && displayMsg.length() > 0 ) {
				buf.append( executeCount )
					.append( getResource().getLabel( displayMsg ) )
					.append( BR );
			}
			else if( executeCount == 0 && notfoundMsg != null && notfoundMsg.length() > 0 ) {
				buf.append( getResource().getLabel( notfoundMsg ) )
					.append( BR );
			}
		}

		// 4.3.7.0 (2009/06/01) 読込件数を､"DB.COUNT" ｷｰでﾘｸｴｽﾄにｾｯﾄする｡
		setRequestAttribute( "DB.COUNT"   , String.valueOf( executeCount ) );

		// 6.2.0.0 (2015/02/27) ｵｰﾊﾞｰﾌﾛｰ時のﾒｯｾｰｼﾞを表示
		if( table != null && table.isOverflow() && overflowMsg != null && overflowMsg.length() > 0  ) {
			buf.append( getResource().getLabel( overflowMsg ) )
				.append( BR );
		}

		jspPrint( buf.toString() );

		// 4.3.7.0 (2009/06/01) stopZero機能を追加
		return executeCount == 0 && stopZero ? SKIP_PAGE : EVAL_PAGE ;
	}

	/**
	 * ﾀｸﾞﾘﾌﾞｵﾌﾞｼﾞｪｸﾄをﾘﾘｰｽします｡
	 * ｷｬｯｼｭされて再利用されるので､ﾌｨｰﾙﾄﾞの初期設定を行います｡
	 *
	 * @og.rev 2.0.0.4 (2002/09/27) ｶｽﾀﾑﾀｸﾞの release() ﾒｿｯﾄﾞを､追加
	 * @og.rev 3.1.1.2 (2003/04/04) Tomcat4.1 対応｡release2() を doEndTag()で呼ぶ｡
	 * @og.rev 3.1.3.0 (2003/04/10) FILE_ENCODE から､ｴﾝｺｰﾄﾞ情報を取得する｡
	 * @og.rev 3.1.4.0 (2003/04/18) command 属性に､初期値(NEW)を設定する｡
	 * @og.rev 3.5.4.2 (2003/12/15) EXCELのｼｰﾄ名を指定できるように変更｡
	 * @og.rev 3.5.4.5 (2004/01/23) 外部よりｶﾗﾑ列(CSV形式)を指定できるようにする｡
	 * @og.rev 3.6.0.2 (2004/10/04) checkColumns,adjustColumns,allColumnCheck 属性追加
	 * @og.rev 3.7.0.5 (2005/04/11) useNumber 属性を追加します｡
	 * @og.rev 3.8.0.2 (2005/06/30) nullCheck 属性追加
	 * @og.rev 3.8.5.3 (2006/08/07) readerClass 属性の初期値をｼｽﾃﾑﾘｿｰｽより取得します｡
	 * @og.rev 4.3.7.0 (2009/06/01) stopZero属性追加
	 * @og.rev 5.1.6.0 (2010/05/01) DBLastSqlの処理は､DBTableModelが新規作成された処理でのみ行う｡
	 * @og.rev 5.1.6.0 (2010/05/01) ﾃﾞｰﾀの読み飛ばし設定 skipRowCount 属性追加
	 * @og.rev 5.2.1.0 (2010/10/01) 読取処理でｺｰﾄﾞﾘｿｰｽのﾗﾍﾞﾙ変換を行うかどうか useRenderer 属性追加
	 * @og.rev 5.5.7.2 (2012/10/09) 複数ｼｰﾄを指定できるようにｼｰﾄ番号を指定できるように､sheetNos属性追加
	 * @og.rev 5.5.8.2 (2012/11/09) 固定値となるｶﾗﾑ名､ｱﾄﾞﾚｽの指定のための､sheetConstKeys､sheetConstAdrs属性追加
	 * @og.rev 5.5.8.2 (2012/11/09) ｶﾗﾑ列に NULL が現れた時点で読取を中止する､nullBreakClm属性追加
	 * @og.rev 6.1.0.0 (2014/12/26) omitNames 属性を追加
	 * @og.rev 6.2.0.0 (2015/02/27) ｵｰﾊﾞｰﾌﾛｰ時のﾒｯｾｰｼﾞを表示
	 * @og.rev 6.2.0.0 (2015/02/27) EXCEL出力のparamLevel初期値変更 3:標準推奨 → 4:個人設定可
	 * @og.rev 6.2.2.0 (2015/03/27) ColumnAction ｲﾝﾅｰｸﾗｽでﾊﾟﾗﾒｰﾀを整理する｡
	 * @og.rev 6.2.3.0 (2015/05/01) 行読み飛ばし nullSkipClm追加
	 * @og.rev 6.2.5.0 (2015/06/05) ﾌｧｲﾙｴﾝｺｰﾄﾞの初期化を遅らせます｡
	 * @og.rev 7.0.7.0 (2019/12/13) useSLabel 属性を追加｡
	 * @og.rev 8.0.1.0 (2021/10/29) useLocal 属性を追加｡
	 */
	@Override
	protected void release2() {
		super.release2();
		separator		= TableReader.TAB_SEPARATOR;			// 項目区切り文字
		fileURL			= HybsSystem.sys( "FILE_URL" );
		filename		= HybsSystem.sys( "FILE_FILENAME" );	// ﾌｧｲﾙ名
		encode			= null;									// 6.2.5.0 (2015/06/05) ﾌｧｲﾙｴﾝｺｰﾃﾞｨﾝｸﾞ
		readerClass		= null;													// 6.2.0.0 (2015/02/27)
		maxRowCount		= 0 ;													// 6.2.2.0 (2015/03/27)
		displayMsg		= HybsSystem.sys( "VIEW_DISPLAY_MSG" );
		overflowMsg		= "MSG0007";	// 検索結果が､制限行数を超えましたので､残りはｶｯﾄされました｡
		notfoundMsg		= "MSG0077";	// 対象ﾃﾞｰﾀはありませんでした｡
		executeCount	= -1;			// 検索/実行件数
		modifyType		= null;
		command			= CMD_NEW;
		table			= null;
		tableId			= HybsSystem.TBL_MDL_KEY ;
		sheetName		= null;		// 3.5.4.2 (2003/12/15)
		sheetNos		= null;		// 5.5.7.2 (2012/10/09) 複数ｼｰﾄを指定できるようにｼｰﾄ番号を指定できるようにする｡
		sheetConstKeys	= null;		// 5.5.8.2 (2012/11/09) 固定値となるｶﾗﾑ名(CSV形式)
		sheetConstAdrs	= null;		// 5.5.8.2 (2012/11/09) 固定値となるｱﾄﾞﾚｽ(行-列,行-列,･･･)
		nullBreakClm	= null;		// 5.5.8.2 (2012/11/09) 取込み条件/Sheet BREAK条件
		nullSkipClm		= null;		// 6.2.3.0 (2015/05/01) 行読み飛ばし
		columns			= null;		// 3.5.4.5 (2004/01/23)
		useNumber		= true;		// 3.7.0.5 (2005/04/11)
//		useRepeatClms	= false;	// 7.3.0.0 (2021/01/06)
		stopZero		= false;	// 4.3.7.0 (2009/06/01) soptZero追加
		isMainTrans		= true;		// 5.1.6.0 (2010/05/01) DBLastSqlの処理の見直し
		skipRowCount	= 0;		// 5.1.6.0 (2010/05/01) ﾃﾞｰﾀの読み飛ばし設定
		clmAct			= new ColumnAction();									// 6.2.2.0 (2015/03/27)
		useSLabel		= false;	// 7.0.7.0 (2019/12/13) ｴﾗｰﾒｯｾｰｼﾞにSLABELを利用するかどうか[true/false]を指定します(初期値:false)
		useLocal		= false;	// 8.0.1.0 (2021/10/29) ｸﾗｳﾄﾞ設定を使用しない場合は､true
	}

	/**
	 * TableReader の実ｵﾌﾞｼﾞｪｸﾄを生成して，BufferedReader に書き込みます｡
	 *
	 * @og.rev 3.5.4.1 (2003/12/01) 引数の BufferedReader を､InputStream に変更｡
	 * @og.rev 3.5.4.2 (2003/12/15) TableReader のｻﾌﾞｸﾗｽ名変更｡
	 * @og.rev 3.5.4.2 (2003/12/15) EXCELのｼｰﾄ名を指定できるように変更｡
	 * @og.rev 3.5.4.3 (2004/01/05) 引数の InputStream を､ BufferedReader に戻す｡
	 * @og.rev 3.5.4.5 (2004/01/23) TableReader に､encode を渡すように変更｡
	 * @og.rev 3.5.6.0 (2004/06/18) 各種ﾌﾟﾗｸﾞｲﾝ関連付け設定を､ｼｽﾃﾑﾊﾟﾗﾒｰﾀ に記述します｡
	 * @og.rev 3.7.0.5 (2005/04/11) useNumber 属性を追加します｡
	 * @og.rev 4.0.0.0 (2005/01/31) ｷｰの指定を､TableReader. から､TableReader_ に変更します｡
	 * @og.rev 4.0.0.0 (2005/01/31) lang ⇒ ResourceManager へ変更
	 * @og.rev 5.1.6.0 (2010/05/01) ﾃﾞｰﾀの読み飛ばし設定 skipRowCount 属性追加
	 * @og.rev 5.2.1.0 (2010/10/01) 読取処理でｺｰﾄﾞﾘｿｰｽのﾗﾍﾞﾙ変換を行うかどうか設定 useRenderer 属性追加
	 * @og.rev 5.5.7.2 (2012/10/09) 複数ｼｰﾄを指定できるようにｼｰﾄ番号を指定できるように､sheetNos属性追加
	 * @og.rev 5.5.8.2 (2012/11/09) 固定値となるｶﾗﾑ名､ｱﾄﾞﾚｽの指定のための､sheetConstKeys､sheetConstAdrs属性追加
	 * @og.rev 5.5.8.2 (2012/11/09) ｶﾗﾑ列に NULL が現れた時点で読取を中止する､nullBreakClm属性追加
	 * @og.rev 6.0.4.0 (2014/11/28) NullPointerException が発生するので､事前にﾁｪｯｸします｡
	 * @og.rev 6.2.0.0 (2015/02/27) TableReader ｸﾗｽの呼び出し元ﾒｿｯﾄﾞの共通化(EXCEL,TEXT)
	 * @og.rev 6.2.2.0 (2015/03/27) ColumnAction ｲﾝﾅｰｸﾗｽでﾊﾟﾗﾒｰﾀを整理する｡
	 * @og.rev 6.2.2.0 (2015/03/27) ColumnActionListener 対応｡
	 * @og.rev 6.2.3.0 (2015/05/01) 行読み飛ばし nullSkipClm追加
	 * @og.rev 6.4.1.2 (2016/01/22) setColumnActionListener は､内部処理が走るため､他の設定が終わってから呼び出す｡
	 * @og.rev 6.4.3.3 (2016/03/04) HybsSystem.newInstance(String,String) への置き換え｡
	 * @og.rev 7.3.0.0 (2021/01/06) ColumnActionListenerｲﾝﾀｰﾌｪｰｽを無名内部ｸﾗｽから､内部ｸﾗｽへ｡
	 * @og.rev 7.3.0.0 (2021/01/06) 横持ちﾃﾞｰﾀの繰り返し対応
	 *
	 * @param	file	出力するFileｵﾌﾞｼﾞｪｸﾄ
	 */
	protected void create( final File file )  {
		table = DBTableModelUtil.newDBTable();			// 6.2.1.0 (2015/03/13)

		final ColumnActionListener listener = new NormalCAListener();

		final TableReader reader = HybsSystem.newInstance( "TableReader_" , readerClass );	// 3.5.5.3 (2004/04/09)

		reader.setSeparator( separator );
		reader.setColumns( columns );					// 3.5.4.5 (2004/01/23) ､6.2.0.0 (2015/02/27) 削除
		reader.setUseNumber( useNumber );				// 3.7.0.5 (2005/04/11)
		reader.setSkipRowCount( skipRowCount );			// 5.1.6.0 (2010/05/01)
		reader.setDebug( isDebug() );					// 5.5.7.2 (2012/10/09) ﾃﾞﾊﾞｯｸﾞ情報を出力するかどうかを指定
		// 6.2.0.0 (2015/02/27) EXCELでない場合でも､ﾒｿｯﾄﾞは呼び出す｡(空振りします)
		reader.setSheetName( sheetName );			// 3.5.4.2 (2003/12/15)
		reader.setSheetNos( sheetNos );				// 5.5.7.2 (2012/10/09) 複数ｼｰﾄを指定できるようにｼｰﾄ番号を指定できるようにする｡
		reader.setSheetConstData( sheetConstKeys,sheetConstAdrs ) ;		// 5.5.8.2 (2012/11/09) 固定値となるｶﾗﾑ名､ｱﾄﾞﾚｽの指定
		reader.setNullBreakClm( nullBreakClm ) ;	// 5.5.8.2 (2012/11/09) 取込み条件/Sheet BREAK条件
		reader.setNullSkipClm( nullSkipClm ) ;		// 6.2.3.0 (2015/05/01) 行読み飛ばし
		// 6.4.1.2 (2016/01/22) setColumnActionListener は､内部処理が走るため､他の設定が終わってから呼び出す｡
		reader.setColumnActionListener( listener );		// 6.2.2.0 (2015/03/27)
		reader.readDBTable( file,encode );			// 6.2.0.0 (2015/02/27) 追加
	}

	/**
	 * ColumnActionListenerｲﾝﾀｰﾌｪｰｽの内部ｸﾗｽ
	 *
	 * @og.rev 6.2.2.0 (2015/03/27) ColumnActionListener 対応｡
	 * @og.rev 7.3.0.0 (2021/01/06) ColumnActionListenerｲﾝﾀｰﾌｪｰｽを無名内部ｸﾗｽから､内部ｸﾗｽへ｡
	 * @og.rev 7.3.1.1 (2021/02/25) ｶﾗﾑ列を､"DB.NAMES" ｷｰでﾘｸｴｽﾄにｾｯﾄする｡
	 *
	 * @param names ｶﾗﾑ名配列
	 */
	private final class NormalCAListener implements ColumnActionListener {
//	final ColumnActionListener listener = new ColumnActionListener() {
		private DBColumn[] dbClms ;				// 6.3.9.1 (2015/11/27) 修飾子を､なし → private に変更｡

		/**
		 * ﾃﾞﾌｫﾙﾄｺﾝｽﾄﾗｸﾀｰ
		 *
		 * @og.rev 7.3.0.0 (2021/01/06) PMD refactoring. Each class should declare at least one constructor.
		 */
		public NormalCAListener() { super(); }		// これも､自動的に呼ばれるが､空のﾒｿｯﾄﾞを作成すると警告されるので､明示的にしておきます｡

		/**
		 * ｶﾗﾑ名の配列が設定された場合に､呼び出されます｡
		 *
		 * @og.rev 6.2.2.0 (2015/03/27) ColumnActionListener 対応｡
		 * @og.rev 7.3.1.1 (2021/02/25) ｶﾗﾑ列を､"DB.NAMES" ｷｰでﾘｸｴｽﾄにｾｯﾄする｡
		 *
		 * @param names ｶﾗﾑ名配列
		 */
		@Override
		public void columnNames( final String[] names ) {
			final String[] nms = clmAct.makeNames( names );
			table.init( nms.length );
			dbClms = new DBColumn[nms.length];
			final StringBuilder nmsBuf = new StringBuilder( BUFFER_MIDDLE );		// 7.3.1.1 (2021/02/25)
			for( int no=0; no<nms.length; no++ ) {
				nmsBuf.append( ',' ).append( nms[no] );								// 7.3.1.1 (2021/02/25)
				dbClms[no] = getDBColumn( nms[no] );
				table.setDBColumn( no,dbClms[no] );
			}

			if( nmsBuf.length() > 1 ) {		// 7.3.1.1 (2021/02/25) 最初のｶﾝﾏを削除して､DB.NAMES で登録する｡
				setRequestAttribute( "DB.NAMES" , nmsBuf.substring(1) );
			}
		}

		/**
		 * #NAME のｵﾘｼﾞﾅﾙｶﾗﾑ名配列がそろった段階で､ｲﾍﾞﾝﾄが発生します｡
		 *
		 * @og.rev 7.3.1.3 (2021/03/09) #NAMEのｵﾘｼﾞﾅﾙを取得できるようにします｡
		 *
		 * @param   names  ｶﾗﾑ名配列
		 */
		@Override
		public void originalNames( final String[] names ) {
			if( names != null && names.length > 0 ) {
				final StringBuilder nmsBuf = new StringBuilder( BUFFER_MIDDLE );
				for( int no=0; no<names.length; no++ ) {
					nmsBuf.append( ',' ).append( names[no] );
				}

				if( nmsBuf.length() > 1 ) {		// 7.3.1.1 (2021/02/25) 最初のｶﾝﾏを削除して､DB.NAMES で登録する｡
					setRequestAttribute( "DB.ORGNAMES" , nmsBuf.substring(1) );
				}
			}
		}

		/**
		 * １行分のﾃﾞｰﾀが設定された場合に､呼び出されます｡
		 *
		 * @og.rev 6.2.2.0 (2015/03/27) ColumnActionListener 対応｡
		 * @og.rev 6.4.6.0 (2016/05/27) ﾚｺｰﾄﾞの読取条件指定を追加｡条件に一致しなければ､null が返されます｡
		 * @og.rev 7.3.0.0 (2021/01/06) 横持ちﾃﾞｰﾀの繰り返し対応
		 *
		 * @param   vals    文字列値の１行分の配列
		 * @param   rowNo   行番号(0～)
		 */
		@Override
		public void values( final String[] vals, final int rowNo ) {
			if( maxRowCount > 0 && rowNo > maxRowCount ) {		// 読み取り件数ｵｰﾊﾞｰﾌﾛｰ
				table.setOverflow( true );
				throw new HybsOverflowException();
			}

			// 7.3.0.0 (2021/01/06) 横持ちﾃﾞｰﾀの繰り返し対応｡
//			final String[] newVals = clmAct.clmAction( vals , dbClms , rowNo );
//			// 6.4.6.0 (2016/05/27) ﾚｺｰﾄﾞの読取条件指定を追加｡条件に一致しなければ､null が返されます｡
//			if( newVals != null ) {
//				table.addColumnValues( newVals,modifyType,true );	// 値配列､変更ﾀｲﾌﾟ､書込許可
//			}
			final List<String[]> valsList = clmAct.clmAction( vals , dbClms , rowNo );
			for( final String[] newVals : valsList ) {
				table.addColumnValues( newVals,modifyType,true );	// 値配列､変更ﾀｲﾌﾟ､書込許可
			}
		}

		/**
		 * 新しくEXCELのｼｰﾄを処理する際に､ｼｰﾄ名をｾｯﾄするときに呼び出されます｡
		 *
		 * @og.rev 7.3.1.1 (2021/02/25) 現在実行中のｼｰﾄ名を､"DB.SHEET_NAME" ｷｰでﾘｸｴｽﾄにｾｯﾄする｡
		 *
		 * @param   sheetName   現在実行中のｼｰﾄ名
		 */
		@Override
		public void shtName( final String sheetName ) {
			setRequestAttribute( "DB.SHEET_NAME" , sheetName );
		}
	}

	/**
	 * 【TAG】(通常は使いません)結果のDBTableModelを､sessionに登録するときのｷｰを指定します
	 *		(初期値:HybsSystem#TBL_MDL_KEY[={@og.value HybsSystem#TBL_MDL_KEY}])｡
	 *
	 * @og.tag
	 * 検索結果より､DBTableModelｵﾌﾞｼﾞｪｸﾄを作成します｡これを､下流のviewﾀｸﾞ等に
	 * 渡す場合に､通常は､session を利用します｡その場合の登録ｷｰです｡
	 * query ﾀｸﾞを同時に実行して､結果を求める場合､同一ﾒﾓﾘに配置される為､
	 * この tableId 属性を利用して､ﾒﾓﾘ空間を分けます｡
	 *		(初期値:HybsSystem#TBL_MDL_KEY[={@og.value HybsSystem#TBL_MDL_KEY}])｡
	 *
	 * @param	id ﾃｰﾌﾞﾙID (sessionに登録する時のID)
	 */
	public void setTableId( final String id ) {
		tableId = nval( getRequestParameter( id ), tableId );
	}

	/**
	 * 【TAG】可変長ﾌｧｲﾙを作成するときの項目区切り文字をｾｯﾄします｡
	 *
	 * @og.tag 可変長ﾌｧｲﾙを作成するときの項目区切り文字をｾｯﾄします｡
	 *
	 * @param   separator 項目区切り文字
	 */
	public void setSeparator( final String separator ) {
		this.separator = nval( getRequestParameter( separator ),this.separator );
	}

	/**
	 * 【TAG】読取元ﾃﾞｨﾚｸﾄﾘ名を指定します
	 *		(初期値:FILE_URL[={@og.value SystemData#FILE_URL}])｡
	 *
	 * @og.tag
	 * この属性で指定されるﾃﾞｨﾚｸﾄﾘより､ﾌｧｲﾙを読取ます｡
	 * 指定方法は､通常の fileURL 属性と同様に､先頭が､'/' (UNIX) または､２文字目が､
	 * ":" (Windows)の場合は､指定のURLそのままのﾃﾞｨﾚｸﾄﾘに､そうでない場合は､
	 * fileURL = "{&#064;USER.ID}" と指定すると､FILE_URL 属性で指定のﾌｫﾙﾀﾞの下に､
	 * さらに､各個人ID別のﾌｫﾙﾀﾞを作成して､そこを操作します｡
	 * (初期値:ｼｽﾃﾑ定数のFILE_URL[={@og.value SystemData#FILE_URL}])｡
	 *
	 * @og.rev 4.0.0.0 (2005/01/31) StringUtil.urlAppend ﾒｿｯﾄﾞの利用
	 * @og.rev 4.0.0.0 (2007/11/20) 指定されたﾃﾞｨﾚｸﾄﾘ名の最後が"\"or"/"で終わっていない場合に､"/"を付加する｡
	 * @og.rev 6.4.2.1 (2016/02/05) URLの最後に､"/" を追加する処理を廃止｡
	 *
	 * @param	url 読取元ﾃﾞｨﾚｸﾄﾘ名
	 * @see		org.opengion.hayabusa.common.SystemData#FILE_URL
	 */
	public void setFileURL( final String url ) {
		final String furl = nval( getRequestParameter( url ),null );
		if( furl != null ) {
			fileURL = StringUtil.urlAppend( fileURL,furl );
		}
	}

	/**
	 * 【TAG】ﾌｧｲﾙを作成するときのﾌｧｲﾙ名をｾｯﾄします
	 *		(初期値:FILE_FILENAME[={@og.value SystemData#FILE_FILENAME}])｡
	 *
	 * @og.tag ﾌｧｲﾙを作成するときのﾌｧｲﾙ名をｾｯﾄします｡
	 * (初期値:ｼｽﾃﾑ定数のFILE_FILENAME[={@og.value SystemData#FILE_FILENAME}])｡
	 *
	 * @param   filename ﾌｧｲﾙ名
	 * @see		org.opengion.hayabusa.common.SystemData#USE_SQL_INJECTION_CHECK
	 */
	public void setFilename( final String filename ) {
		this.filename = nval( getRequestParameter( filename ),this.filename );
	}

	/**
	 * 【TAG】ﾌｧｲﾙを作成するときのﾌｧｲﾙｴﾝｺｰﾃﾞｨﾝｸﾞ名をｾｯﾄします
	 *		(初期値:FILE_ENCODE[={@og.value SystemData#FILE_ENCODE}])｡
	 *
	 * @og.tag
	 * readerClass="AutoReader" の場合､ここで設定した encode が優先されます｡
	 * readerClass="Text" の場合､encode が指定されていない場合は､初期値 の FILE_ENCODE が使用されます
	 *
	 * Shift_JIS,MS932,Windows-31J,UTF-8,ISO-8859-1,UnicodeLittle
	 * (初期値:ｼｽﾃﾑ定数のFILE_ENCODE[={@og.value SystemData#FILE_ENCODE}])｡
	 *
	 * @og.rev 2.2.0.0 (2002/12/17) 中国語(国際化)対応 ｴﾝｺｰﾄﾞの取得方法変更
	 * @og.rev 3.1.3.0 (2003/04/10) FILE_ENCODE から､ｴﾝｺｰﾄﾞ情報を取得する｡
	 *
	 * @param   enc ﾌｧｲﾙｴﾝｺｰﾃﾞｨﾝｸﾞ名
	 * @see     <a href="http://www.iana.org/assignments/character-sets">IANA Charset Registry</a>
	 * @see		org.opengion.hayabusa.common.SystemData#FILE_ENCODE
	 */
	public void setEncode( final String enc ) {
		encode = nval( getRequestParameter( enc ),encode );
	}

	/**
	 * 【TAG】実際に読み出すｸﾗｽ名の略称(TableReader_**** の ****)をｾｯﾄします
	 *		(初期値:TABLE_READER_DEFAULT_CLASS[={@og.value SystemData#TABLE_READER_DEFAULT_CLASS}])｡
	 *
	 * @og.tag
	 * 実際に読み出すｸﾗｽ名(の略称)をｾｯﾄします｡
	 * これは､org.opengion.hayabusa.io 以下の TableReader_**** ｸﾗｽの **** を
	 * 与えます｡これらは､TableReader ｲﾝﾀｰﾌｪｰｽを継承したｻﾌﾞｸﾗｽです｡
	 * 属性ｸﾗｽ定義の {@link org.opengion.hayabusa.io.TableReader TableReader} を参照願います｡
	 * {@og.doc03Link readerClass TableReader_**** ｸﾗｽ}
	 * @og.rev 3.1.3.0 (2003/04/10) FILE_ENCODE から､ｴﾝｺｰﾄﾞ情報を取得する｡
	 *
	 * "AutoReader" は特別な名前で､Excel と Text(ﾃｷｽﾄ) を以下の順番で試します｡
	 * Excel,Calc,Text(UnicodeLittle),Text(Windows-31J),Text(Windows-31J),Text(UTF-8),Text(EUC-JP)
	 * Excel については､拡張子を自動判定して､(xlsx か xls) 適切な処理を行います｡
	 * 従来からの 拡張子のみ､xls のﾃｷｽﾄﾌｧｲﾙは､#NAME を見つけることができないため､ｴﾗｰになり､
	 * 次のText読み取りにゆだねられます｡
	 * UTF-8 のTEXTとWindows-31JのTEXTは､ﾍｯﾀﾞｰ部での区別ができないため､java.nio.file.Files と Pathを
	 * 使用した読み取り方式に変更しています｡
	 * "AutoReader" に設定した場合は､上記の様に､encode を順番に確かめるため､encode属性の指定は無視されます｡
	 *		(初期値:TABLE_READER_DEFAULT_CLASS[={@og.value SystemData#TABLE_READER_DEFAULT_CLASS}])｡
	 *
	 * @og.rev 6.2.1.0 (2015/03/13) Default廃止に伴い､Defaultが指定された場合は､Textに置き換える｡
	 *
	 * @param   readerCls ｸﾗｽ名(の略称)
	 * @see		org.opengion.hayabusa.io.TableReader  TableReaderのｻﾌﾞｸﾗｽ
	 */
	public void setReaderClass( final String readerCls ) {
		readerClass = nval( getRequestParameter( readerCls ),readerClass );

		// 6.2.1.0 (2015/03/13) 互換性の為｡
		if( "Default".equals( readerClass ) ) { readerClass = "Text" ; }
	}

	/**
	 * 【TAG】読取時の最大取り込み件数をｾｯﾄします(初期値:0:無制限)｡
	 *
	 * @og.tag
	 * DBTableModelのﾃﾞｰﾀとして登録する最大件数をこの値に設定します｡
	 * ｻｰﾊﾞｰのﾒﾓﾘ資源と応答時間の確保の為です｡
	 * 0 をｾｯﾄすると､無制限になります｡
	 * (初期値:0:無制限)
	 *
	 * @og.rev 5.5.8.5 (2012/11/27) 0を無制限として処理します｡
	 * @og.rev 6.2.2.0 (2015/03/27) 初期値を､無制限に変更
	 *
	 * @param   count 最大件数
	 */
	public void setMaxRowCount( final String count ) {
		maxRowCount = nval( getRequestParameter( count ),maxRowCount );
	}

	/**
	 * 【TAG】読取時の最大ｴﾗｰ件数をｾｯﾄします (初期値:{@og.value #ERROR_ROW_COUNT})｡
	 *
	 * @og.tag
	 * DBTableModelのﾃﾞｰﾀﾁｪｯｸを行う場合､ｴﾗｰの最大件数をこの値に設定します｡
	 * ｴﾗｰ最大件数がこの値を超えると､処理を打ち切ります｡
	 * 0 をｾｯﾄすると､無制限になります｡
	 * (初期値:{@og.value #ERROR_ROW_COUNT})｡
	 *
	 * @og.rev 6.2.2.0 (2015/03/27) 読取時の最大ｴﾗｰ件数(errRowCount) を新規追加
	 *
	 * @param   count 最大件数
	 */
	public void setErrRowCount( final String count ) {
		clmAct.errRowCount = nval( getRequestParameter( count ),ERROR_ROW_COUNT );
	}

	/**
	 * 【TAG】ｺﾏﾝﾄﾞ (NEW,RENEW)をｾｯﾄします(初期値:NEW)｡
	 *
	 * @og.tag
	 * ｺﾏﾝﾄﾞは,HTMLから(get/post)指定されますので,CMD_xxx で設定される
	 * ﾌｨｰﾙﾄﾞ定数値のいづれかを､指定できます｡
	 * 何も設定されない､または､null の場合は､"NEW" が初期値にｾｯﾄされます｡
	 *
	 * @param	cmd ｺﾏﾝﾄﾞ (public static final 宣言されている文字列)
	 * @see		<a href="../../../../constant-values.html#org.opengion.hayabusa.taglib.ReadTableTag.CMD_NEW">ｺﾏﾝﾄﾞ定数</a>
	 */
	public void setCommand( final String cmd ) {
		final String cmd2 = getRequestParameter( cmd );
		if( cmd2 != null && cmd2.length() > 0 ) { command = cmd2.toUpperCase(Locale.JAPAN); }
	}

	/**
	 * 【TAG】query の結果を画面上に表示するﾒｯｾｰｼﾞIDを指定します
	 *		(初期値:VIEW_DISPLAY_MSG[={@og.value SystemData#VIEW_DISPLAY_MSG}])｡
	 *
	 * @og.tag
	 * ここでは､検索結果の件数や登録された件数をまず出力し､
	 * その次に､ここで指定したﾒｯｾｰｼﾞをﾘｿｰｽから取得して
	 * 表示します｡
	 * 件数を表示させる場合は､displayMsg = "MSG0033"[　件検索しました] をｾｯﾄしてください｡
	 * 表示させたくない場合は, displayMsg = "" をｾｯﾄしてください｡
	 * (初期値:ｼｽﾃﾑ定数のVIEW_DISPLAY_MSG[={@og.value SystemData#VIEW_DISPLAY_MSG}])｡
	 *
	 * @og.rev 6.2.0.0 (2015/02/27) ﾘｸｴｽﾄ変数を使用できるように修正｡
	 *
	 * @param	id 処理結果表示ﾒｯｾｰｼﾞID
	 */
	public void setDisplayMsg( final String id ) {
		final String ids = getRequestParameter( id );
		if( ids != null ) { displayMsg = ids; }
	}

	/**
	 * 【TAG】読取ﾃﾞｰﾀが最大検索数をｵｰﾊﾞｰした場合に表示するﾒｯｾｰｼﾞﾘｿｰｽIDを指定します
	 *		(初期値:MSG0007[検索結果が､制限行数を超えましたので､残りはｶｯﾄされました])｡
	 *
	 * @og.tag
	 * 読取結果が､maxRowCount で設定された値より多い場合､何らかのﾃﾞｰﾀは読取されず
	 * 切り捨てられたことになります｡
	 * ここでは､displayMsg を表示した後､必要に応じて､このﾒｯｾｰｼﾞを表示します｡
	 * 表示させたくない場合は, overflowMsg = "" をｾｯﾄしてください｡
	 * 初期値は､MSG0007[検索結果が､制限行数を超えましたので､残りはｶｯﾄされました]です｡
	 *
	 * @og.rev 6.2.0.0 (2015/02/27) ｵｰﾊﾞｰﾌﾛｰ時のﾒｯｾｰｼﾞを表示
	 *
	 * @param	id 検索数ｵｰﾊﾞｰ時ﾒｯｾｰｼﾞID
	 */
	public void setOverflowMsg( final String id ) {
		final String ids = getRequestParameter( id );
		if( ids != null ) { overflowMsg = ids; }
	}

	/**
	 * 【TAG】検索結果がｾﾞﾛ件の場合に表示するﾒｯｾｰｼﾞﾘｿｰｽIDを指定します(初期値:MSG0077[対象ﾃﾞｰﾀはありませんでした])｡
	 *
	 * @og.tag
	 * ここでは､検索結果がｾﾞﾛ件の場合のみ､特別なﾒｯｾｰｼﾞを表示させます｡
	 * 従来は､displayMsg と兼用で､『0　件検索しました』という表示でしたが､
	 * displayMsg の初期表示は､OFF になりましたので､ｾﾞﾛ件の場合のみ別に表示させます｡
	 * 表示させたくない場合は, notfoundMsg = "" をｾｯﾄしてください｡
	 * 初期値は､MSG0077[対象ﾃﾞｰﾀはありませんでした]です｡
	 *
	 * @param	id ｾﾞﾛ件時表示ﾒｯｾｰｼﾞID
	 */
	public void setNotfoundMsg( final String id ) {
		final String ids = getRequestParameter( id );
		if( ids != null ) { notfoundMsg = ids; }
	}

	/**
	 * 【TAG】ﾌｧｲﾙ取り込み時の 更新ﾀｲﾌﾟ [A:追加/C:更新/D:削除]を指定します｡
	 *
	 * @og.tag
	 * ﾌｧｲﾙ読み込み時に､そのﾃﾞｰﾀをA(追加)､C(更新)､D(削除)の
	 * 更新ﾀｲﾌﾟをつけた状態にします｡
	 * その状態で､そのまま､update する事が可能になります｡
	 *
	 * @param   type 更新ﾀｲﾌﾟ [A:追加/C:更新/D:削除]
	 */
	public void setModifyType( final String type ) {
		modifyType = getRequestParameter( type );
	}

	/**
	 * 【TAG】EXCELﾌｧｲﾙを読み込むときのｼｰﾄ名を設定します(初期値:指定なし)｡
	 *
	 * @og.tag
	 * EXCELﾌｧｲﾙを読み込む時に､ｼｰﾄ名を指定します｡これにより､複数の形式の
	 * 異なるﾃﾞｰﾀを順次読み込むことや､ｼｰﾄを指定して読み取ることが可能になります｡
	 * sheetNos と sheetName が同時に指定された場合は､sheetNos が優先されます｡ｴﾗｰにはならないのでご注意ください｡
	 * 初期値は､指定なしです｡
	 *
	 * @og.rev 3.5.4.2 (2003/12/15) 新規追加
	 *
	 * @param   sheet EXCELﾌｧｲﾙのｼｰﾄ名
	 * @see		#setSheetNos( String )
	 */
	public void setSheetName( final String sheet ) {
		sheetName = nval( getRequestParameter( sheet ),sheetName );
	}

	/**
	 * 【TAG】EXCELﾌｧｲﾙを読み込むときのｼｰﾄ番号を指定します(初期値:0)｡
	 *
	 * @og.tag
	 * EXCEL読み込み時に複数ｼｰﾄをﾏｰｼﾞして取り込みます｡
	 * ｼｰﾄ番号は､0 から始まる数字で表します｡
	 * ﾍｯﾀﾞｰは､最初のｼｰﾄのｶﾗﾑ位置に合わせます｡（ﾍｯﾀﾞｰﾀｲﾄﾙの自動認識はありません｡）
	 * よって､指定するｼｰﾄは､すべて同一ﾚｲｱｳﾄでないと取り込み時にｶﾗﾑのずれが発生します｡
	 *
	 * ｼｰﾄ番号の指定は､CSV形式で､複数指定できます｡また､N-M の様にﾊｲﾌﾝで繋げることで､
	 * N 番から､M 番のｼｰﾄ範囲を一括指定可能です｡また､"*" による､全ｼｰﾄ指定が可能です｡
	 * これらの組み合わせも可能です｡（ 0,1,3,5-8,10-* ）
	 * ただし､"*" に関しては例外的に､一文字だけで､すべてのｼｰﾄを表すか､N-* を最後に指定するかの
	 * どちらかです｡途中には､"*" は､現れません｡
	 * ｼｰﾄ番号は､重複(1,1,2,2)､逆転(3,2,1) での指定が可能です｡これは､その指定順で､読み込まれます｡
	 * sheetNos と sheetName が同時に指定された場合は､sheetNos が優先されます｡ｴﾗｰにはならないのでご注意ください｡
	 *
	 * 初期値は､0（第一ｼｰﾄ） です｡
	 *
	 * @og.rev 5.5.7.2 (2012/10/09) 新規追加
	 *
	 * @param   sheet EXCELﾌｧｲﾙのｼｰﾄ番号（0から始まる）
	 * @see		#setSheetName( String )
	 */
	public void setSheetNos( final String sheet ) {
		sheetNos = nval( getRequestParameter( sheet ),sheetNos );
		if( sheetNos != null && sheetNos.length() > 0 ) {
			boolean errFlag = false;
			for( int i=0; i<sheetNos.length(); i++ ) {
				final char ch = sheetNos.charAt(i);
				if( ch == '-' || ch == ',' ) { continue; }
				if( ch == '*' && ( i==0 || i==sheetNos.length()-1 ) ) { continue; }
				if( ch < '0' || ch > '9' ) { errFlag = true; break; }
			}
			if( errFlag ) {
				final String errMsg = "sheetNos の指定を見直してください｡sheetNos=[" + sheetNos + "]";
				throw new HybsSystemException( errMsg );
			}
		}
	}

	/**
	 * 【TAG】EXCELﾌｧｲﾙを読み込むときのｼｰﾄ単位の固定値を設定するためのｶﾗﾑ名を指定します｡
	 *
	 * @og.tag
	 * ｶﾗﾑ名は､CSV形式で指定します｡
	 * これにより､ｼｰﾄの一か所に書かれている情報を､DBTableModel のｶﾗﾑに固定値として
	 * 設定することができます｡
	 * 例として､DB定義書で､ﾃｰﾌﾞﾙ名をｼｰﾄの全ﾚｺｰﾄﾞに設定したい場合などに使います｡
	 * このﾒｿｯﾄﾞは､isExcel() == true の場合のみ利用されます｡
	 *
	 * @og.rev 5.5.8.2 (2012/11/09) 新規追加
	 *
	 * @param   constKeys 固定値となるｶﾗﾑ名 (CSV形式)
	 * @see		#setSheetConstAdrs( String )
	 */
	public void setSheetConstKeys( final String constKeys ) {
		sheetConstKeys = nval( getRequestParameter( constKeys ),null );
	}

	/**
	 * 【TAG】EXCELﾌｧｲﾙを読み込むときのｼｰﾄ単位の固定値を設定するためのｶﾗﾑ名に対応するｱﾄﾞﾚｽを指定します｡
	 *
	 * @og.tag
	 * ｱﾄﾞﾚｽは､EXCEL上の行-列をCSV形式で指定します｡
	 * 行列は､EXCELｵﾌﾞｼﾞｪｸﾄに準拠するため､０から始まる整数です｡
	 * 0-0 ⇒ A1 , 1-0 ⇒ A2 , 0-1 ⇒ B1 になります｡
	 * これにより､ｼｰﾄの一か所に書かれている情報を､DBTableModel のｶﾗﾑに固定値として
	 * 設定することができます｡
	 * 例として､DB定義書で､ﾃｰﾌﾞﾙ名をｼｰﾄの全ﾚｺｰﾄﾞに設定したい場合などに使います｡
	 * このﾒｿｯﾄﾞは､isExcel() == true の場合のみ利用されます｡
	 *
	 * 5.7.6.3 (2014/05/23) より､
	 *   ①EXCEL表記に準拠した､A1,A2,B1 の記述も処理できるように対応します｡
	 *     なお､A1,A2,B1 の記述は､必ず､英字1文字＋数字 にしてください｡(A～Zまで)
	 *   ②処理中のEXCELｼｰﾄ名をｶﾗﾑに割り当てるために､"SHEET" という記号に対応します｡
	 * 例えば､sheetConstKeys="CLM,LANG,NAME" とし､sheetConstAdrs="0-0,A2,SHEET" とすると､
	 * NAMEｶﾗﾑには､ｼｰﾄ名を読み込むことができます｡
	 * これは､内部処理の簡素化のためです｡
	 *
	 * ちなみに､EXCELのｾﾙに､ｼｰﾄ名を表示させる場合の関数は､下記の様になります｡
	 * =RIGHT(CELL("filename",$A$1),LEN(CELL("filename",$A$1))-FIND("]",CELL("filename",$A$1)))
	 *
	 * @og.rev 5.5.8.2 (2012/11/09) 新規追加
	 *
	 * @param   constAdrs 固定値となるｱﾄﾞﾚｽ (行-列,行-列,･･･)
	 * @see		#setSheetConstKeys( String )
	 */
	public void setSheetConstAdrs( final String constAdrs ) {
		sheetConstAdrs = nval( getRequestParameter( constAdrs ),null );
	}

	/**
	 * 【TAG】ここに指定されたｶﾗﾑ列に NULL が現れた時点で読取を中止します｡
	 *
	 * @og.tag
	 * これは､指定のｶﾗﾑは必須という事を条件に､そのﾚｺｰﾄﾞだけを読み取る処理を行います｡
	 * 複数Sheetの場合は､次のSheetを読みます｡
	 * 現時点では､Excel の場合のみ有効です｡
	 *
	 * @og.rev 5.5.8.2 (2012/11/09) 新規追加
	 *
	 * @param   clm ｶﾗﾑ列
	 */
	public void setNullBreakClm( final String clm ) {
		nullBreakClm = nval( getRequestParameter( clm ),null );
	}

	/**
	 * 【TAG】ここに指定されたｶﾗﾑ列に NULL が現れたﾚｺｰﾄﾞは読み飛ばします｡
	 *
	 * @og.tag
	 * 例えば､更新対象ｶﾗﾑで､null の場合は､何もしない､などのｹｰｽで使用できます｡
	 * 複数ｶﾗﾑの場合は､AND条件やOR条件などが､考えられるため､
	 * ｶﾗﾑを一つにまとめて､指定してください｡
	 *
	 * @og.rev 6.2.3.0 (2015/05/01) 行読み飛ばし nullSkipClm追加
	 *
	 * @param   clm ｶﾗﾑ列
	 */
	public void setNullSkipClm( final String clm ) {
		nullSkipClm = nval( getRequestParameter( clm ),null );
	}

	/**
	 * 【TAG】読取元ﾌｧｲﾙのｶﾗﾑ列を､外部(ﾀｸﾞ)より指定します｡
	 *
	 * @og.tag
	 * 読取元ﾌｧｲﾙのｶﾗﾑ列を､外部(ﾀｸﾞ)より指定します｡
	 * ﾌｧｲﾙに記述された #NAME より優先して使用されます｡
	 * これは､元ﾌｧｲﾙのｶﾗﾑを順番に指定のｶﾗﾑ名に割り当てる機能で
	 * ﾌｧｲﾙの特定のｶﾗﾑ列を抜き出して取り込む機能ではありません｡
	 *
	 * ※ 7.2.6.0 (2020/06/30)
	 *      readerClass="POI"の場合､TEXT(ﾃｷｽﾄ)､CMNT(ｺﾒﾝﾄ)の位置は変えられません｡
	 *      また､ｶﾗﾑ数も､必ず､2以上必要です｡
	 *      それより多い場合は､null値のｶﾗﾑが作成されます｡
	 *
	 * @og.rev 3.5.4.5 (2004/01/23) 新規作成
	 *
	 * @param   clms 読取元ﾌｧｲﾙのｶﾗﾑ列 (CSV形式)
	 */
	public void setColumns( final String clms ) {
		columns = nval( getRequestParameter( clms ),columns );
	}

	/**
	 * 【TAG】読取対象外のｶﾗﾑ列を､外部(ﾀｸﾞ)よりCSV形式で指定します｡
	 *
	 * @og.tag
	 * 指定するｶﾗﾑ名に対して､読取処理を行いません｡
	 * ここで指定するｶﾗﾑ名は､ﾌｧｲﾙの #NAME または､columns で
	 * 指定するｶﾗﾑ名に対して､含まれている必要はありません｡
	 * その場合は､ここでの指定は無視されます｡
	 *
	 * @og.rev 6.1.0.0 (2014/12/26) omitNames 属性を追加
	 * @og.rev 6.2.2.0 (2015/03/27) ColumnAction ｲﾝﾅｰｸﾗｽでﾊﾟﾗﾒｰﾀを整理する｡
	 *
	 * @param   clms 読取対象外のｶﾗﾑ列 (CSV形式)
	 */
	public void setOmitNames( final String clms ) {
		clmAct.omitNames = nval( getRequestParameter( clms ),null );
	}

	/**
	 * 読取対象外のｶﾗﾑ列を､追加指定します｡
	 *
	 * 内部的な処理で､DirectTableInsertTag で､WRITABLE,ROWID などの
	 * ﾃﾞｰﾀﾍﾞｰｽに存在しないｶﾗﾑを､omit するための機能です｡
	 * 属性定義してもよいのですが､統一的な処理方法が決まらないので､
	 * 取りあえず､暫定的に､ｻﾌﾞｸﾗｽからのみ､して可能にしておきます｡
	 * このﾒｿｯﾄﾞは､setOmitNames( String ) が呼び出された後でしか
	 * 有効に機能しません｡
	 *
	 * @og.rev 6.2.4.0 (2015/05/15) 無条件でOMITする名称を指定します｡
	 *
	 * @param   omit 読取対象外の追加ｶﾗﾑ列 (CSV形式)
	 */
	protected void addOmitNames( final String omit ) {
		if( clmAct.omitNames == null ) {
			clmAct.omitNames = omit;
		}
		else {
			clmAct.omitNames = "," + omit ;
		}
	}

	/**
	 * 【TAG】読取元ﾌｧｲﾙの整合性ﾁｪｯｸを行うｶﾗﾑ列をｶﾝﾏ指定します｡
	 *
	 * @og.tag
	 * ｶﾗﾑｵﾌﾞｼﾞｪｸﾄのDBType属性に対応したﾁｪｯｸを行います｡
	 * 指定のｶﾗﾑ名をCSV形式(CSV)で複数指定できます｡
	 * 全てのｶﾗﾑのﾁｪｯｸを行う場合は､"*" を指定して下さい｡
	 * 分解方法は､通常のﾊﾟﾗﾒｰﾀ取得後に､CSV分解します｡
	 *
	 * @og.rev 3.6.0.2 (2004/10/04) 新規追加 取り込み時ﾁｪｯｸ用
	 * @og.rev 3.8.8.5 (2007/03/09) 通常のﾊﾟﾗﾒｰﾀ取得後に､CSV分解に戻します｡
	 * @og.rev 6.2.2.0 (2015/03/27) ColumnAction ｲﾝﾅｰｸﾗｽでﾊﾟﾗﾒｰﾀを整理する｡
	 *
	 * @param   clms 整合性ﾁｪｯｸを行うｶﾗﾑ列 (CSV形式)
	 */
	public void setCheckColumns( final String clms ) {
		clmAct.checkColumns = nval( getRequestParameter( clms ),null );
	}

	/**
	 * 【TAG】整合性ﾁｪｯｸ時に､厳密にﾁｪｯｸするかどうか[true/false]を指定します(初期値:true)｡
	 *
	 * @og.tag
	 * checkColumnsで､読取元ﾌｧｲﾙの整合性ﾁｪｯｸを行う際に､厳密なﾁｪｯｸを行うかどうかを指定します｡
	 * 従来は､厳密なﾁｪｯｸのみでしたが､動的に作成したｶﾗﾑで､DB登録に無関係な場合は､
	 * official(ｶﾗﾑﾘｿｰｽから作成されたかどうか)が｣falseになり､必ずｴﾗｰになっていました｡
	 * isStrict=false を指定すると､甘い目でｶﾗﾑﾁｪｯｸすると同時に､official ﾁｪｯｸも行いません｡
	 * 初期値は､互換性を考慮して､true になります｡
	 *
	 * @og.rev 7.3.2.0 (2021/03/19) isStrict:整合性ﾁｪｯｸ時に､厳密にﾁｪｯｸするかどうか[true/false]追加(初期値:true)
	 *
	 * @param   flag 厳密ﾁｪｯｸか [true:厳密/false:甘い]
	 */
	public void setUseStrict( final String flag ) {
		clmAct.isStrict = nval( getRequestParameter( flag ),clmAct.isStrict );
	}

	/**
	 * 【TAG】読取元ﾌｧｲﾙのﾃﾞｰﾀ変換を行うｶﾗﾑ列をｶﾝﾏ指定します｡
	 *
	 * @og.tag
	 * ｶﾗﾑｵﾌﾞｼﾞｪｸﾄのDBType属性に対応したﾃﾞｰﾀ変換を行います｡
	 * 指定のｶﾗﾑ名をCSV形式(CSV)で複数指定できます｡
	 * 全てのｶﾗﾑをﾃﾞｰﾀ変換する場合は､"*" を指定して下さい｡
	 * 分解方法は､通常のﾊﾟﾗﾒｰﾀ取得後に､CSV分解します｡
	 *
	 * @og.rev 3.6.0.2 (2004/10/04) 新規追加 取り込み時ﾃﾞｰﾀ変換
	 * @og.rev 3.8.8.5 (2007/03/09) 通常のﾊﾟﾗﾒｰﾀ取得後に､CSV分解に戻します｡
	 * @og.rev 6.2.2.0 (2015/03/27) ColumnAction ｲﾝﾅｰｸﾗｽでﾊﾟﾗﾒｰﾀを整理する｡
	 *
	 * @param   clms ﾃﾞｰﾀ変換を行うｶﾗﾑ列 (CSV形式)
	 */
	public void setAdjustColumns( final String clms ) {
		clmAct.adjustColumns = nval( getRequestParameter( clms ),null );
	}

	/**
	 * 【TAG】NULL ﾁｪｯｸすべきｶﾗﾑ列をCSV形式(CSV形式)で指定します｡
	 *
	 * @og.tag nullCheck="AAA,BBB,CCC,DDD"
	 * 分解方法は､通常のﾊﾟﾗﾒｰﾀ取得後に､CSV分解します｡
	 *
	 * @og.rev 3.8.0.2 (2005/06/30) 新規追加
	 * @og.rev 3.8.8.5 (2007/03/09) 通常のﾊﾟﾗﾒｰﾀ取得後に､CSV分解に戻します｡
	 * @og.rev 6.2.2.0 (2015/03/27) ColumnAction ｲﾝﾅｰｸﾗｽでﾊﾟﾗﾒｰﾀを整理する｡
	 *
	 * @param   clms ｶﾗﾑ列(CSV形式)
	 */
	public void setNullCheck( final String clms ) {
		clmAct.nullCheck = nval( getRequestParameter( clms ),null );
	}

	/**
	 * 【TAG】行番号情報を､使用している/していない[true/false]を指定します(初期値:true)｡
	 *
	 * @og.tag
	 * 通常のﾌｫｰﾏｯﾄでは､各行の先頭に行番号が出力されています｡
	 * 読取時に､#NAME 属性を使用する場合は､この行番号を無視しています｡
	 * #NAME 属性を使用せず､columns 属性でｶﾗﾑ名を指定する場合(他ｼｽﾃﾑの
	 * 出力ﾌｧｲﾙを読み取るｹｰｽ等)では､行番号も存在しないｹｰｽがあり､
	 * その様な場合に､useNumber="false" を指定すれば､ﾃﾞｰﾀの最初から読取始めます｡
	 * この場合､出力ﾃﾞｰﾀのｶﾗﾑの並び順が変更された場合､columns 属性も
	 * 指定しなおす必要がありますので､できるだけ､#NAME 属性を使用するように
	 * してください｡
	 * なお､EXCEL 入力には､この設定は適用されません｡(暫定対応)
	 * 初期値は､true(使用する) です｡
	 *
	 * @og.rev 3.7.0.5 (2005/04/11) 新規追加
	 *
	 * @param   useNo 行番号情報 [true:使用する/false:使用しない]
	 */
	public void setUseNumber( final String useNo ) {
		useNumber = nval( getRequestParameter( useNo ),useNumber );
	}

	/**
	 * 【TAG】読取処理で横持ちﾃﾞｰﾀの繰り返しが存在する場合に､trueを指定します(初期値:false)｡
	 *
	 * @og.tag
	 * ﾃﾞｰﾀを取り込む際､1行に繰り返しｶﾗﾑが存在する場合に､true に設定します｡
	 * 例えば､注文番号,品番,納期1,数量1,納期2,数量2…納期31,数量31,備考 のようなﾃﾞｰﾀ形式です｡
	 * これを､
	 * 注文番号,品番,備考,納期1,数量1
	 * 注文番号,品番,備考,納期2,数量2
	 * ･･･
	 * 注文番号,品番,備考,納期31,数量31
	 * のように､縦型のﾃﾞｰﾀに変更します｡
	 *
	 * 繰り返しｶﾗﾑの廃位を [] で囲います｡先の例でいうと､
	 * 注文番号,品番,[納期1,数量1],[納期2,数量2]…[納期31,数量31],備考 になります｡
	 *
	 * 従来の取込と同じく､ｶﾗﾑが空欄(,,,,などと指定)の場合は､読み飛ばします｡
	 * なお､[] で囲われていないｶﾗﾑは､固定ｶﾗﾑで､繰り返しｶﾗﾑより前に来ます｡
	 * 先の例でいうと､備考は､品番の次に来ます｡
	 * 繰り返しｶﾗﾑの指定は､1度だけできます｡複数の繰り返しｶﾗﾑには対応していません｡
	 * 初期値は､false(使用しない) です｡
	 *
	 * @og.rev 7.3.0.0 (2021/01/06) 横持ちﾃﾞｰﾀの繰り返し対応｡
	 *
	 * @param   useRepeat 横持ちﾃﾞｰﾀの繰り返し [true:使用する/false:使用しない]
	 */
	public void setUseRepeatClms( final String useRepeat ) {
//		useRepeatClms = nval( getRequestParameter( useRepeat ),useRepeatClms );
		clmAct.useRepeatClms( nval( getRequestParameter( useRepeat ),false ) );
	}

	/**
	 * 【TAG】読込件数が０件のとき処理を続行するかどうか[true/false]を指定します(初期値:false[続行する])｡
	 *
	 * @og.tag
	 * 初期値は､false(続行する)です｡
	 *
	 * @og.rev 4.3.7.0 (2009/06/01) 新規追加
	 *
	 * @param	flag	０件時停止可否 [true:処理を中止する/false:続行する]
	 */
	public void setStopZero( final String flag ) {
		stopZero = nval( getRequestParameter( flag ), stopZero );
	}

	/**
	 * 【TAG】(通常は使いません)ﾀｸﾞで処理される処理がﾒｲﾝとなるﾄﾗﾝｻﾞｸｼｮﾝ処理かどうかを指定します(初期値:true)｡
	 *
	 * @og.tag
	 * この値は､ﾌｧｲﾙﾀﾞｳﾝﾛｰﾄﾞ処理に影響します｡この値がtrueに指定された時にcommitされたDBTableModelが
	 * ﾌｧｲﾙﾀﾞｳﾝﾛｰﾄﾞの対象の表になります｡
	 *
	 * このﾊﾟﾗﾒｰﾀｰは､通常､各ﾀｸﾞにより実装され､ﾕｰｻﾞｰが指定する必要はありません｡
	 * 但し､1つのJSP内でDBTableModelが複数生成される場合に､前に処理したDBTableModelについてﾌｧｲﾙﾀﾞｳﾝﾛｰﾄﾞをさせたい
	 * 場合は､後ろでDBTableModelを生成するﾀｸﾞで､明示的にこの値をfalseに指定することで､ﾌｧｲﾙﾀﾞｳﾝﾛｰﾄﾞ処理の対象から
	 * 除外することができます｡
	 *
	 * @og.rev 5.1.6.0 (2010/05/01) 新規作成
	 *
	 * @param  flag ﾒｲﾝﾄﾗﾝｻﾞｸｼｮﾝかどうか [true:ﾒｲﾝ/false:その他]
	 */
	public void setMainTrans( final String flag ) {
		isMainTrans = nval( getRequestParameter( flag ),isMainTrans );
	}

	/**
	 * 【TAG】(通常は使いません)ﾃﾞｰﾀの読み飛ばし件数を設定します｡
	 *
	 * @og.tag
	 * TAB区切りﾃｷｽﾄやEXCEL等のﾃﾞｰﾀの読み始めの初期値を指定します｡
	 * ﾌｧｲﾙの先頭行が､０行としてｶｳﾝﾄしますので､設定値は､読み飛ばす
	 * 件数になります｡(１と指定すると､１件読み飛ばし､２行目から読み込みます｡)
	 * 読み飛ばしは､ｺﾒﾝﾄ行などは､無視しますので､実際の行数分読み飛ばします｡
	 * ＃NAME属性や､columns 属性は､有効です｡
	 *
	 * @og.rev 5.1.6.0 (2010/05/01) 新規作成
	 *
	 * @param	count 読み始めの初期値
	 */
	public void setSkipRowCount( final String count ) {
		skipRowCount = nval( getRequestParameter( count ),skipRowCount );
	}

	/**
	 * 【TAG】読取処理でKEY:VAL形式のｺｰﾄﾞﾘｿｰｽから､KEYを取り出す処理を行うかどうかを指定します
	 *		(初期値:USE_TABLE_READER_RENDERER[={@og.value SystemData#USE_TABLE_READER_RENDERER}])｡
	 *
	 * @og.tag
	 * TableWriter_Renderer 系のｸﾗｽで出力した場合は､ｺｰﾄﾞﾘｿｰｽがﾗﾍﾞﾙで出力されます｡
	 * そのﾌｧｲﾙを読み取ると､当然､ｴﾗｰになります｡
	 * ここでは､ｺｰﾄﾞﾘｿｰｽのｶﾗﾑに対して､ﾗﾍﾞﾙからｺｰﾄﾞを求める逆変換を行うことで､
	 * Renderer 系で出力したﾌｧｲﾙを取り込むことができるようにします｡
	 *
	 * ここでは､TableWriter 系と同様に､TableReader_Renderer 系のｸﾗｽを作るのではなく､
	 * 属性値のﾌﾗｸﾞで､制御します｡
	 * 将来的には､TableWriter 系も廃止して､同様のﾌﾗｸﾞで制御するように変更する予定です｡
	 * (初期値:ｼｽﾃﾑ定数のUSE_TABLE_READER_RENDERER[={@og.value SystemData#USE_TABLE_READER_RENDERER}])｡
	 *
	 * @og.rev 5.2.1.0 (2010/10/01) 新規作成
	 * @og.rev 6.2.2.0 (2015/03/27) ColumnAction ｲﾝﾅｰｸﾗｽでﾊﾟﾗﾒｰﾀを整理する｡
	 *
	 * @param  flag ﾗﾍﾞﾙ逆変換を行うかどうか [true:行う/false:行わない]
	 * @see		org.opengion.hayabusa.common.SystemData#USE_TABLE_READER_RENDERER
	 */
	public void setUseRenderer( final String flag ) {
		clmAct.useRenderer = nval( getRequestParameter( flag ),HybsSystem.sysBool( "USE_TABLE_READER_RENDERER" ) );
	}

	/**
	 * 【TAG】matchKeysをCSV形式で指定します｡
	 *
	 * @og.tag
	 * ﾌｧｲﾙから特定の行のみを読み取るためのmatchKeysを指定します｡
	 * matchKeysで指定したｶﾗﾑに対して､matchValsの正規表現でﾁｪｯｸします｡
	 * 何も指定しない場合は､読取対象になります｡
	 * matchVals と個数を合わせてください｡
	 *
	 * @og.rev 6.4.6.0 (2016/05/27) 新規追加
	 *
	 * @param   keys ｶﾗﾑ列(CSV形式文字)
	 * @see		#setMatchVals( String )
	 */
	public void setMatchKeys( final String keys ) {
		clmAct.matchKeys = getCSVParameter( keys );
	}

	/**
	 * 【TAG】matchValsをCSV形式で指定します｡
	 *
	 * @og.tag
	 * ﾌｧｲﾙから特定の行のみを読み取るためのmatchValsを指定します｡
	 * matchKeysで指定したｶﾗﾑに対して､matchValsの正規表現でﾁｪｯｸします｡
	 * この機能はTableReader_Defaultのみ有効です｡
	 * 何も指定しない場合は､読取対象になります｡
	 * matchKeys と個数を合わせてください｡
	 *
	 * @og.rev 6.4.6.0 (2016/05/27) 新規追加
	 *
	 * @param   vals ｶﾗﾑ列に対する正規表現(CSV形式文字)
	 * @see		#setMatchKeys( String )
	 */
	public void setMatchVals( final String vals ) {
		clmAct.matchVals = getCSVParameter( vals );
	}

	/**
	 * 【TAG】ｴﾗｰﾒｯｾｰｼﾞにSLABELを利用するかどうか[true/false]を指定します(初期値:false)｡
	 *
	 * @og.tag
	 * 通常のｴﾗｰﾒｯｾｰｼﾞは､ﾗﾍﾞﾙ（長）が使われますが､これをﾗﾍﾞﾙ（短）を使いたい場合に､true にｾｯﾄします｡
	 * ここでのﾗﾍﾞﾙ（短）は､ﾀｸﾞ修飾なしの､ﾗﾍﾞﾙ（短）です｡
	 * 標準はfalse:利用しない=ﾗﾍﾞﾙ（長）です｡
	 * true/false以外を指定した場合はfalse扱いとします｡
	 *
	 * ﾗﾍﾞﾙﾘｿｰｽの概要説明があれば表示しますが､useSLabel="true" 時は､概要説明を表示しません｡
	 *
	 * @og.rev 7.0.7.0 (2019/12/13) 新規追加
	 *
	 * @param prm SLABEL利用 [true:利用する/false:利用しない]
	 */
	public void setUseSLabel( final String prm ) {
		useSLabel = nval( getRequestParameter( prm ),useSLabel );
	}

	/**
	 * 【TAG】ｼｽﾃﾑ定数でｸﾗｳﾄﾞ設定されていても､ｸﾗｳﾄﾞ環境を使用しない場合､trueを指定します(初期値:false)｡
	 *
	 * @og.tag
	 * ｸﾗｳﾄﾞ設定は､ｼｽﾃﾑ定数の『CLOUD_TARGET』と『CLOUD_BUCKET』の設定で自動的に使用しますが､
	 * どうしてもﾛｰｶﾙでのみ使いたい場合は､この属性を true に設定します｡
	 * 標準はfalse:設定どおりとなります｡
	 * true/false以外を指定した場合はfalse扱いとします｡
	 *
	 * @og.rev 8.0.1.0 (2021/10/29) useLocal 属性を追加｡
	 *
	 * @param flag ﾛｰｶﾙ環境のみ [true:ﾛｰｶﾙのみ/false:設定どおり]
	 */
	public void setUseLocal( final String flag ) {
		useLocal = nval( getRequestParameter( flag ),useLocal );
	}

	/**
	 * ｶﾗﾑ処理を行う､内部ｸﾗｽ
	 *
	 * ｶﾗﾑ個別に行う処理をまとめたｸﾗｽです｡
	 * omitNames        ： 読取対象外のｶﾗﾑ列を､外部(ﾀｸﾞ)よりCSV形式で指定します
	 * adjustColumns    ： 読取元ﾌｧｲﾙのﾃﾞｰﾀ変換を行うｶﾗﾑ列をｶﾝﾏ指定します
	 * checkColumns     ： 読取元ﾌｧｲﾙの整合性ﾁｪｯｸを行うｶﾗﾑ列をｶﾝﾏ指定します
	 * nullCheck        ： NULL ﾁｪｯｸすべきｶﾗﾑ列をCSV形式(CSV形式)で指定します
	 *
	 * 名前配列設定で対象のｶﾗﾑをﾋﾟｯｸｱｯﾌﾟし､値設定処理で､個々に処理します｡
	 *
	 * @og.rev 6.2.2.0 (2015/03/27) ColumnAction 新規作成
	 */
	protected static final class ColumnAction {
		private String	omitNames		;		// 読取対象外のｶﾗﾑ列を､外部(ﾀｸﾞ)よりCSV形式で指定します
		private String	adjustColumns	;		// 読取元ﾌｧｲﾙのﾃﾞｰﾀ変換を行うｶﾗﾑ列をｶﾝﾏ指定します
		private String	checkColumns	;		// 読取元ﾌｧｲﾙの整合性ﾁｪｯｸを行うｶﾗﾑ列をｶﾝﾏ指定します
		private boolean	isStrict		;		// 7.3.2.0 (2021/03/19) 厳密にﾁｪｯｸするかどうか[true/false]を指定します(初期値:true)
		private String	nullCheck		;		// NULL ﾁｪｯｸすべきｶﾗﾑ列をCSV形式(CSV形式)で指定します
		private int		errRowCount		= ERROR_ROW_COUNT;		// NULL ﾁｪｯｸすべきｶﾗﾑ列をCSV形式(CSV形式)で指定します
		private boolean	useRenderer		;		// 読取処理でKEY:VAL形式のｺｰﾄﾞﾘｿｰｽから､KEYを取り出す処理を行うかどうかを指定
		private boolean	isDebug			;		// debug ﾌﾗｸﾞ
		private ErrorMessage errMsgObj	;		// 6.2.5.0 (2015/06/05) 初期化します｡

		private int[]		clmNos		;		// 新名前配列に対応した､値配列のｱﾄﾞﾚｽ
		private int[]		actFlg		;		// ｶﾗﾑ処理の実行有無のﾌﾗｸﾞ管理
		private String[]	mtVals		;		// 6.4.6.0 (2016/05/27) 新名前配列に対応した､判定処理用のﾃﾞｰﾀ(正規表現)

		private String[]	matchKeys	;		// 6.4.6.0 (2016/05/27) ﾚｺｰﾄﾞの読取条件指定時のｶﾗﾑ列を配列で指定します
		private String[]	matchVals	;		// 6.4.6.0 (2016/05/27) ﾚｺｰﾄﾞの読取条件指定時のｶﾗﾑ列に対応する正規表現ﾃﾞｰﾀを配列で指定します

		private boolean useRepeat ;				// 7.3.0.0 (2021/01/06) 横持ちﾃﾞｰﾀの繰り返し [true:使用する/false:使用しない]
		private RepeatDataChenge repDataCng ;	// 7.3.0.0 (2021/01/06) 横持ちﾃﾞｰﾀの繰り返し対応｡

		private static final int OMIT    = -1;		// OMIT だけ別｡clmNosで､OMITﾌﾗｸﾞは除外する｡
		private static final int ADJUST  = 1;		// adjustColumns 処理ﾌﾗｸﾞ
		private static final int CHECK   = 2;		// checkColumns 処理ﾌﾗｸﾞ
		private static final int NULL_CH = 4;		// nullCheck  処理ﾌﾗｸﾞ
		private static final int MAT_KYS = 8;		// 6.4.6.0 (2016/05/27) matchKeys  処理ﾌﾗｸﾞ

		/**
		 * 名前配列が設定された場合に､対象ｶﾗﾑのﾋﾟｯｸｱｯﾌﾟを行います｡
		 * このｸﾗｽでは､名前の再設定で､初期化されます｡
		 *
		 * @og.rev 6.2.2.0 (2015/03/27) ColumnAction 新規作成
		 * @og.rev 6.2.5.0 (2015/06/05) ErrorMessage を､初期化します｡
		 * @og.rev 6.4.6.0 (2016/05/27) ﾚｺｰﾄﾞの読取条件指定を追加
		 * @og.rev 7.3.0.0 (2021/01/06) 横持ちﾃﾞｰﾀの繰り返し対応｡
		 *
		 * @param	orgNms ｵﾘｼﾞﾅﾙ名前配列
		 * @return	OMIT等考慮した､新名前配列
		 */
		public String[] makeNames( final String[] orgNms ) {
			if( useRepeat ) { repDataCng = new RepeatDataChenge(); }	// 7.3.0.0 (2021/01/06) 初期化します｡(Autoreaderﾁｪｯｸで､複数回呼ばれると重複するため)
			errMsgObj = new ErrorMessage( "Check Columns Error!" );		// 6.2.5.0 (2015/06/05) 初期化します｡

			// omit だけ､他のﾌﾗｸﾞｾｯﾄと異なり､処理された数は､除外されるので逆になります｡
			final int[] temp = new int[orgNms.length];
			final int size = orgNms.length - actionFlagSet( omitNames, orgNms, OMIT, temp );

			if( size == 0 ) {	// 有りえないが､omitNames="*" を誤って指定した場合にはありうる｡
				final String errMsg = "ｶﾗﾑがありません｡omitNames=[" + omitNames + "]";
				throw new HybsSystemException( errMsg );
			}

			final String[] names = new String[size];
			clmNos = new int[size];
			int no = 0;
			for( int i=0; i<temp.length; i++ ) {
				if( temp[i] != OMIT ) {				// 除外しない場合
					names[no] = orgNms[i];			// 名前配列に､ｵﾘｼﾞﾅﾙの名前をｾｯﾄ
					clmNos[no]= i;					// ｶﾗﾑｱﾄﾞﾚｽをｾｯﾄ(TableModelのｶﾗﾑ番号になる)
					no++ ;
				}
			}

			actFlg = new int[size];					// 新名前配列に対応した､処理ﾌﾗｸﾞを作成(ﾌﾗｸﾞを加算)
			actionFlagSet( adjustColumns, names, ADJUST,  actFlg );		// それぞれのﾌﾗｸﾞが加算される｡
			actionFlagSet( checkColumns,  names, CHECK,   actFlg );
			actionFlagSet( nullCheck,     names, NULL_CH, actFlg );

			// 6.4.6.0 (2016/05/27) ﾚｺｰﾄﾞの読取条件指定を追加｡ほとんど使わない機能｡
			if( matchKeys != null && matchKeys.length > 0 ) {
				final Map<String,String> keyMap = makeMatchMap( matchKeys , matchVals );
				mtVals = new String[size];
				for( int i=0; i<size; i++ ) {
					mtVals[i] = keyMap.get( names[i] );
					if( mtVals[i] != null ) { actFlg[i] += MAT_KYS; }		// 一致するｶﾗﾑにﾌﾗｸﾞを加算する｡
				}
			}

			// 7.3.0.0 (2021/01/06) 横持ちﾃﾞｰﾀの繰り返し対応
//			return names;
			return useRepeat ? repDataCng.newNames( names ) : names ;
		}

		/**
		 * 値配列に対して､変換処理､ﾁｪｯｸ処理を行った結果を返します｡
		 *
		 * @og.rev 6.2.2.0 (2015/03/27) ColumnAction 新規作成
		 * @og.rev 6.3.9.0 (2015/11/06) ｺﾝｽﾄﾗｸﾀで初期化されていないﾌｨｰﾙﾄﾞを null ﾁｪｯｸなしで利用している(findbugs)
		 * @og.rev 6.4.1.2 (2016/01/22) HybsOverflowException をthrow するとき､最大件数を引数に渡す｡
		 * @og.rev 6.4.6.0 (2016/05/27) ﾚｺｰﾄﾞの読取条件指定を追加
		 * @og.rev 7.2.9.4 (2020/11/20) spotbugs:null になっている可能性があるﾒｿｯﾄﾞの戻り値を利用している
		 * @og.rev 7.3.0.0 (2021/01/06) 横持ちﾃﾞｰﾀの繰り返し対応｡
		 * @og.rev 7.3.2.0 (2021/03/19) isStrict:整合性ﾁｪｯｸ時に､厳密にﾁｪｯｸするかどうか[true/false]追加(初期値:true)
		 *
		 * @param	vals	値配列
		 * @param	dbClms	ｶﾗﾑｵﾌﾞｼﾞｪｸﾄ配列
		 * @param	row		行番号(ｴﾗｰﾒｯｾｰｼﾞの表示用)
		 * @return	変換､ﾁｪｯｸ処理結果の値配列｡このﾚｺｰﾄﾞを使用しない場合は､null を返します｡
		 */
//		public String[] clmAction( final String[] vals , final DBColumn[] dbClms , final int row ) {
		public List<String[]> clmAction( final String[] vals , final DBColumn[] dbClms , final int row ) {
			// 6.3.9.0 (2015/11/06) ｺﾝｽﾄﾗｸﾀで初期化されていないﾌｨｰﾙﾄﾞを null ﾁｪｯｸなしで利用している(findbugs)
			// 7.3.0.0 (2021/01/06) SpotBugs ｺﾝｽﾄﾗｸﾀで初期化されていないﾌｨｰﾙﾄﾞを null ﾁｪｯｸなしで null 値を利用している
//			if( clmNos == null || actFlg == null ) {
			if( clmNos == null || actFlg == null || errMsgObj == null ) {
				final String errMsg = "#makeNames(String[])を先に実行しておいてください｡" ;
				throw new OgRuntimeException( errMsg );
			}

			final String[] rtnVals = new String[clmNos.length] ;
			boolean isError = false;

			for( int no=0; no<clmNos.length; no++ ) {
				String val = vals[clmNos[no]];
				if( useRenderer ) {												// useRenderer(KEY:VAL) 処理
					val = dbClms[no].getReaderValue( val );
				}
				if( (actFlg[no] & ADJUST) == ADJUST ) {							// adjustColumns 処理
					val = dbClms[no].valueSet( val );
				}
				if( (actFlg[no] & CHECK)  == CHECK  ) {							// checkColumns 処理
//					final ErrorMessage msg = dbClms[no].valueCheck( val );
					final ErrorMessage msg = dbClms[no].valueCheck( val,isStrict );	// 7.3.2.0 (2021/03/19)
					if( msg.getKekka() > ErrorMessage.OK ) {
						isError = true;
						errMsgObj.append( row+1,msg );
					}
				}
				if( (actFlg[no] & NULL_CH) == NULL_CH ) {						// nullCheck 処理
					if( val == null || val.isEmpty() ) {
						isError = true;
						// ERR0012 : 指定のﾃﾞｰﾀがｾｯﾄされていません｡(NULLｴﾗｰ)｡key={0}
						errMsgObj.addMessage( row+1,ErrorMessage.NG,"ERR0012",dbClms[no].getLabel() );
					}
				}
				// 6.4.6.0 (2016/05/27) ﾚｺｰﾄﾞの読取条件指定を追加
				// 6.9.8.0 (2018/05/28) FindBugs:ｺﾝｽﾄﾗｸﾀで初期化されていないﾌｨｰﾙﾄﾞを null ﾁｪｯｸなしで null 値を利用している
				// このﾌﾗｸﾞが立っているということは､mtVals も､その値も､null ではない｡
//				if( (actFlg[no] & MAT_KYS) == MAT_KYS && !val.matches( mtVals[no] ) ) { return null; }	// ﾏｯﾁしない場合は､null を返します｡
				if( (actFlg[no] & MAT_KYS) == MAT_KYS && mtVals != null && !val.matches( mtVals[no] ) ) { return null; }	// ﾏｯﾁしない場合は､null を返します｡

				rtnVals[no] = val;
			}

			// 5.5.7.2 (2012/10/09) ｴﾗｰ時のﾃﾞﾊﾞｯｸﾞ出力
			if( isDebug && isError ) {
				errMsgObj.addMessage( row+1,ErrorMessage.NG,"Debug",vals );
			}

			// isDebug == true 時には､件数は倍になるが､仕方がない｡
			if( errMsgObj.size() > errRowCount ) { throw new HybsOverflowException( errRowCount ); }		// 6.4.1.1 (2016/01/16)

			// adjustColumns 処理結果を反映させます｡
			// 7.3.0.0 (2021/01/06) 横持ちﾃﾞｰﾀの繰り返し対応
//			return rtnVals;
			if( useRepeat && repDataCng != null ) {
				return repDataCng.newValuesList( rtnVals ) ;
			}
			else {
				final List<String[]> rtnList = new ArrayList<>();
				rtnList.add( rtnVals );
				return rtnList;
			}
		}

		/**
		 * ErrorMessageｵﾌﾞｼﾞｪｸﾄを返します｡
		 *
		 * @og.rev 6.2.5.0 (2015/06/05) 新規作成
		 *
		 * @return	ErrorMessageｵﾌﾞｼﾞｪｸﾄ
		 */
		public ErrorMessage getErrorMessage() {
			return errMsgObj ;
		}

		/**
		 * 読取処理で横持ちﾃﾞｰﾀの繰り返しが存在する場合に､trueを指定します(初期値:false)｡
		 *
		 * @og.rev 7.3.0.0 (2021/01/06) 横持ちﾃﾞｰﾀの繰り返し対応｡
		 *
		 * @param   useRepeat 横持ちﾃﾞｰﾀの繰り返し [true:使用する/false:使用しない]
		 */
		public void useRepeatClms( final boolean useRepeat ) {
			this.useRepeat = useRepeat ;
		}

		/**
		 * 処理実行可否を判断し､ﾌﾗｸﾞをｾｯﾄします｡
		 *
		 * ﾌﾗｸﾞのｾｯﾄは､"|"(論理和)するのが良いのですが､OMITもここで判定している関係で､
		 * 単なる加算にしています｡
		 * (ﾏｲﾅｽをﾌﾗｸﾞにしているので､ﾏｲﾅｽの論理和が良く判らないためです(^^))
		 *
		 * @og.rev 6.2.2.0 (2015/03/27) ColumnAction 新規作成
		 *
		 * @param	clms	指定のｶﾗﾑ名 (CSV形式)
		 * @param	names	名前配列
		 * @param	flag	設定するﾌﾗｸﾞ(既存の配列に加算)
		 * @param	actFlg	ｵﾘｼﾞﾅﾙ名前配列
		 * @return	処理を行った件数
		 */
		private int actionFlagSet( final String clms , final String[] names , final int flag , final int[] actFlg ) {
			int cnt = 0;
			if( clms != null ) {
				final String clmStr = ',' + clms.replaceAll( " ","" ) + ',' ;		// 前後に ｶﾝﾏ(',') を追加､中間ｽﾍﾟｰｽ削除
				for( int i=0; i<names.length; i++ ) {
					// "*" はﾙｰﾌﾟの外で判定して､２回それぞれでﾙｰﾌﾟを回す方が早い･･･かな？
					if( "*".equals( clms ) || clmStr.indexOf( ',' + names[i] + ',' ) >= 0 ) {
						cnt++ ;
						actFlg[i] += flag;			// 一致するｶﾗﾑにﾌﾗｸﾞを加算する｡
					}
				}
			}
			return cnt ;
		}

		/**
		 * ｺｰﾄﾞの読取条件指定のｷｰと値を関連付けるMapを作成します｡
		 *
		 * ほとんど使用しない処理なので､できるだけ本体処理の影響が無いように､
		 * ﾒｿｯﾄﾞを分けています｡
		 * このﾒｿｯﾄﾞは､keys の､nullﾁｪｯｸを行ったうえで呼び出しています｡
		 * key,vals の個数が異なる場合は､ｴﾗｰにしています｡
		 *
		 * @og.rev 6.4.6.0 (2016/05/27) 新規作成
		 *
		 * @param	keys	指定のｶﾗﾑ名配列(呼び出し前に､nullでないことを確認済み)
		 * @param	vals	指定の値配列
		 * @return	ｶﾗﾑ名と値のMap
		 * @og.rtnNotNull
		 */
		private Map<String,String> makeMatchMap( final String[] keys , final String[] vals ) {

			// 6.4.6.0 (2016/05/27) ﾚｺｰﾄﾞの読取条件指定を追加｡個数判定
			if( vals != null && keys.length != vals.length ) {
				final String errMsg = "keys属性とvals属性の個数が合いません｡"							 + CR
									+ " keys=[" + keys.length + "]:KEYS=" + StringUtil.array2csv( keys ) + CR
									+ " vals=[" + vals.length + "]:VLAS=" + StringUtil.array2csv( vals ) + CR ;
				throw new HybsSystemException( errMsg );
			}

			final Map<String,String> keyMap = new HashMap<>();		// 6.4.9.1 (2016/08/05)
			for( int i=0; i<keys.length; i++ ) {
				keyMap.put( keys[i] , vals[i] );
			}

			return keyMap;
		}
	}

	/**
	 * 繰り返しｶﾗﾑ処理を行う内部ｸﾗｽ
	 *
	 * 繰り返しｶﾗﾑの廃位を [] で囲います｡
	 * 注文番号,品番,[納期1,数量1],[納期2,数量2]…[納期31,数量31],備考 と指定した場合､
	 *
	 * 注文番号,品番,備考,納期1,数量1
	 * 注文番号,品番,備考,納期2,数量2
	 * ･･･
	 * 注文番号,品番,備考,納期31,数量31
	 * のように､縦型のﾃﾞｰﾀに変更します｡
	 *
	 * @og.rev 7.3.0.0 (2021/01/06) useRepeatClms 属性を追加｡
	 */
	protected static final class RepeatDataChenge {
		private final List<Integer>		  ad1 = new ArrayList<>();		// 固定ｶﾗﾑのｱﾄﾞﾚｽ
		private final List<List<Integer>> ad2 = new ArrayList<>();		// 繰り返しｶﾗﾑのｱﾄﾞﾚｽ
		// 8.0.0.0 (2021/07/31) Avoid using redundant field initializer for ***
//		private int   cnst = 0;											// 固定ｶﾗﾑの個数
//		private int   rpet = 0;											// 繰り返しｶﾗﾑの個数([～]の間のｶﾗﾑの数)
		private int   cnst ;											// 固定ｶﾗﾑの個数
		private int   rpet ;											// 繰り返しｶﾗﾑの個数([～]の間のｶﾗﾑの数)

		/**
		 * ｶﾗﾑ名の配列を､繰り返しのｱﾄﾞﾚｽ設定と､繰り返し変換後のｶﾗﾑ配列を生成します｡
		 *
		 * @param nms ｶﾗﾑ名配列
		 * @return 変換後のｶﾗﾑ名配列
		 */
		public String[] newNames( final String[] nms ) {
			final List<String> nms1 = new ArrayList<>();				// 固定ｶﾗﾑの名称
			final List<String> nms2 = new ArrayList<>();				// 繰り返しｶﾗﾑの名称

			List<Integer> lad = null ;									// 繰り返しｶﾗﾑの中間ｱﾄﾞﾚｽのﾘｽﾄ

			boolean repCheck = true;									// 繰り返しｶﾗﾑ名の取得は最初だけ
			boolean inFlag   = false;									// "[" でIN(true) "]" でOUT(false) の判定
			for( int i=0; i<nms.length; i++ ) {
				if( nms[i].startsWith( "[" ) ) {						// 繰り返しｶﾗﾑ IN
					if( repCheck ) { nms2.add( nms[i].substring(1) ); }	// 最初だけｶﾗﾑ名取得("["を削る)
					lad = new ArrayList<>();
					lad.add(i);
					inFlag = true;
				}
				else if( nms[i].endsWith( "]" ) ) {						// 繰り返しｶﾗﾑ OUT
					if( repCheck ) { nms2.add( nms[i].substring(0,nms[i].length()-1) ); repCheck = false; }		// ｶﾗﾑ名取得終了
					lad.add(i);
					ad2.add( lad );										// 繰り返しｶﾗﾑの塊([～]の間)をまとめてｾｯﾄ
					inFlag = false;
				}
				else if( inFlag ) {										// 繰り返しｶﾗﾑの範囲内
					if( repCheck ) { nms2.add( nms[i] ); }				// 最初だけｶﾗﾑ名取得
					lad.add(i);
				}
				else {													// 固定ｶﾗﾑ
					nms1.add( nms[i] );
					ad1.add(i);
				}
			}

			cnst = nms1.size();											// 固定ｶﾗﾑの個数
			rpet = nms2.size();											// 繰り返しｶﾗﾑの個数([～]の間のｶﾗﾑの数)

			final List<String> names = new ArrayList<>( nms1 );				// 最終形のｶﾗﾑ一覧
			names.addAll( nms2 );

			return names.toArray( new String[names.size()] ) ;
		}

		/**
		 * １行分のﾃﾞｰﾀが設定された場合に､呼び出されます｡
		 *
		 * 繰り返しﾃﾞｰﾀに拡張したﾘｽﾄの中に､繰り返し変換後のﾃﾞｰﾀ配列をｾｯﾄして返します｡
		 *
		 * @param   vals    文字列値の１行分の配列
		 * @return  変換後のﾃﾞｰﾀ配列のﾘｽﾄ
		 */
		public List<String[]> newValuesList( final String[] vals ) {
			final List<String[]> valList = new ArrayList<>();

			// 6.4.6.0 (2016/05/27) ﾚｺｰﾄﾞの読取条件指定を追加｡条件に一致しなければ､null が返されます｡
			if( vals != null ) {
				final String[] cnstVals = new String[cnst];				// 固定ｶﾗﾑの取得
				for( int i=0;i<cnst; i++ ) {
					cnstVals[i] = vals[ad1.get(i)];						// 固定ｶﾗﾑのｱﾄﾞﾚｽから取得する｡
				}

				for( int j=0; j<ad2.size(); j++ ) {						// 繰り返しｶﾗﾑ群の個数だけﾙｰﾌﾟする｡
					final String[] allVals = new String[cnst + rpet];	// DBTableModelにｾｯﾄするﾃﾞｰﾀ(繰り返し毎に新規作成)
					System.arraycopy(cnstVals,0,allVals,0,cnst);		// 固定ｶﾗﾑのﾃﾞｰﾀをｺﾋﾟｰする｡

					int k = cnst;
					final List<Integer> lad = ad2.get(j) ;				// 繰り返しｶﾗﾑのｱﾄﾞﾚｽ
					boolean isNN = false;								// 繰り返しｶﾗﾑのすべてのﾃﾞｰﾀが null(空文字列)の場合は､登録しない｡
					for( int i=0; i<rpet; i++ ) {
						final String val = vals[lad.get(i)];
						if( !isNN && val != null && !val.trim().isEmpty() ) { isNN = true; }
						allVals[k++] = val;
					}
					if( isNN ) {
						valList.add( allVals );							// 値配列
					}
				}
			}
			return valList;
		}
	}

	/**
	 * AutoReader用の 簡易ﾊﾟﾗﾒｰﾀ管理用の内部ｸﾗｽです｡
	 *
	 * ３つのﾊﾟﾗﾒｰﾀ(ｸﾗｽ､ｴﾝｺｰﾄﾞ､ｻﾌｨｯｸｽ)を管理します｡
	 *
	 * CLASS	TableReader_**** ｸﾗｽ の ****部分を指定します｡(Excel,Calc,Text,PIO など)
	 * ENCODE	ｸﾗｽが､Text の場合のｴﾝｺｰﾄﾞ(UnicodeLittle,Windows-31J,UTF-8,EUC-JP など)
	 * SUFIX	処理対象の拡張子(xls,xlsx,xlsm,ods など)
	 *
	 * @og.rev 6.2.5.0 (2015/06/05) 新規追加｡AutoReader用の 簡易ﾊﾟﾗﾒｰﾀ管理用の内部ｸﾗｽ
	 */
	private static final class AutoReaderParam {
		public final String CLASS	;
		public final String ENCODE	;
		public final String SUFIX	;

		/**
		 * AutoReader用の 簡易ﾊﾟﾗﾒｰﾀ管理用の内部ｸﾗｽのｺﾝｽﾄﾗｸﾀｰです｡
		 *
		 * ３つのﾊﾟﾗﾒｰﾀ(ｸﾗｽ､ｴﾝｺｰﾄﾞ､ｻﾌｨｯｸｽ)を管理します｡
		 *
		 * @og.rev 6.2.5.0 (2015/06/05) 新規追加｡AutoReader用の 簡易ﾊﾟﾗﾒｰﾀ管理用の内部ｸﾗｽ
		 *
		 * @param	cls	TableReader_**** ｸﾗｽ の ****部分を指定します｡(Excel,Calc,Text,PIO など)
		 * @param	enc	ｸﾗｽが､Text の場合のｴﾝｺｰﾄﾞ(UnicodeLittle,Windows-31J,UTF-8,EUC-JP など)
		 * @param	sfx	処理対象の拡張子(xls,xlsx,xlsm,ods など) nullの場合は､すべてを対象とする｡
		 */
		public AutoReaderParam( final String cls , final String enc , final String sfx ) {
			CLASS	= cls ;
			ENCODE	= enc ;
			SUFIX	= sfx == null ? null : ',' + sfx + ',' ;		// 判定用なので､
		}

		/**
		 * 引数のｻﾌｨｯｸｽが､対象かどうか､判定します｡
		 * 対象の場合は､true ､対象でない場合は､false を返します｡
		 *
		 * @og.rev 6.2.5.0 (2015/06/05) 新規追加｡AutoReader用の 簡易ﾊﾟﾗﾒｰﾀ管理用の内部ｸﾗｽ
		 *
		 * @param	sufix	比較対象の拡張子(小文字のみ判定可能)
		 * @return	対象かどうか[true:対象/false:対象外]
		 */
		public boolean useSufix( final String sufix ) {
			return SUFIX == null || SUFIX.contains( ',' + sufix + ',' ) ;
		}

		/**
		 * ｵﾌﾞｼﾞｪｸﾄの文字列表現を返します｡
		 * 対象の場合は､true ､対象でない場合は､false を返します｡
		 *
		 * @og.rev 6.2.5.0 (2015/06/05) 新規追加｡AutoReader用の 簡易ﾊﾟﾗﾒｰﾀ管理用の内部ｸﾗｽ
		 *
		 * @return	このｵﾌﾞｼﾞｪｸﾄの文字列表現
		 */
		@Override
		public String toString() {
			return "class=[" + CLASS + "] , encode=[" + ENCODE + "] , sufix=[" + SUFIX + "]" ;
		}
	}

	/**
	 * このｵﾌﾞｼﾞｪｸﾄの文字列表現を返します｡
	 * 基本的にﾃﾞﾊﾞｯｸﾞ目的に使用します｡
	 *
	 * @return このｸﾗｽの文字列表現
	 * @og.rtnNotNull
	 */
	@Override
	public String toString() {
		return ToString.title( this.getClass().getName() )
				.println( "VERSION"			,VERSION	)
				.println( "separator"		,separator		)
				.println( "fileURL" 		,fileURL 		)
				.println( "filename"		,filename		)
				.println( "encode"			,encode			)
				.println( "readerClass" 	,readerClass 	)
				.println( "maxRowCount"		,maxRowCount	)
				.println( "displayMsg"		,displayMsg		)
				.println( "executeCount"	,executeCount	)
				.println( "modifyType"		,modifyType		)
				.println( "command"			,command		)
				.println( "tableId"			,tableId		)
				.println( "sheetName"		,sheetName		)
				.println( "sheetNos"		,sheetNos		)		// 5.5.7.2 (2012/10/09)
				.println( "columns"			,columns		)
				.println( "useNumber"		,useNumber		)
				.println( "Other..."	,getAttributes().getAttribute() )
				.fixForm().toString() ;
	}
}
