#include "wsubform.h"	//サブフォーム専用ヘッダファイルをインクルードする。

#define Textbox	1	//操作関数用(サンプルを参照)
#define Grid	2	//操作関数用(サンプルを参照)
#define Panel	3	//操作関数用(サンプルを参照)

#define Tret	199	//textboxでファンクションキーが返す番号
#define Gret	299	//gridでファンクションキーが返す番号
#define Pret	399	//paneltextでファンクションキーが返す番号

extern int wmode;	//挿入／上書のモード切替用
extern char gridtitles[MAX_POS][MAX_LEN];	//wsubformが利用するgridのタイトル。

extern TextBox	 *begin;	//textboxで使用する連鎖ポインタの開始位置
extern TextBox	 *tp;	//textboxで使用する連鎖ポインタ

typedef struct stat Dir;	//ファイル操作用
static Dir dirptr;
static Dir  *fileptr = &dirptr;

char tmp[MAX_STR];
static int sqlcode = 0;	//PostgreSQLの返すコード
static int DBcount = 0;	//wsubformで利用するDBの現在の最大行数

int DBConnect(void)
{
	// DB接続用変数宣言
	EXEC SQL BEGIN DECLARE SECTION;
		char dbname[12];
		char user[12];
		char passwd[12];
	EXEC SQL END DECLARE SECTION;

	strcpy(dbname,"apsch");
	strcpy(user,"cms");
	strcpy(passwd,"cms");

#ifdef DEBUG
	// ECPGデバッグ文出力
	ECPGdebug (0, stderr);
#endif

	// 接続
	memset (sqlca.sqlstate, '0', 5);
	EXEC SQL CONNECT TO :dbname AS dbConnection user :user USING :passwd;
	if (memcmp (sqlca.sqlstate, "00", 2) != 0)
	{
		sprintf(tmp,"CONNECT エラー。終了します。:%d - %s",sqlca.sqlcode,sqlca.sqlerrm.sqlerrmc);
		popmsg((COLS/2)-24,(LINES/2)-4,tmp);
		exit (EXIT_FAILURE);
	}
}

int Fetch_schtbl(int no)
{
	static char DBbuff[MAX_STR];
	int i = 0;

	DBConnect();

	memset (sqlca.sqlstate, '0', 5);

	EXEC SQL BEGIN DECLARE SECTION;
		int rec_count;
		char	schedule_name[16 + 1];	//TEXT
		char	schedule_date[8 + 1];	//TEXT
		char	online_start[14 + 1];	//TEXT
		char	online_end[14 + 1];	//TEXT
		int		weekly_sun;		//NUMERIC
		int		weekly_mon;		//NUMERIC
		int		weekly_tue;		//NUMERIC
		int		weekly_wed;		//NUMERIC
		int		weekly_thu;		//NUMERIC
		int		weekly_fri;		//NUMERIC
		int		weekly_sat;		//NUMERIC
		char	specific1[6 + 1];	//TEXT
		char	specific2[6 + 1];	//TEXT
		char	specific3[6 + 1];	//TEXT
		char	specific4[6 + 1];	//TEXT
		char	specific5[6 + 1];	//TEXT
		char	specific6[6 + 1];	//TEXT
		char	specific7[6 + 1];	//TEXT
		char	schedule_time[4 + 1];	//TEXT
		int		max_retry_count;		//NUMERIC
		char	cmd_line[256 + 1];	//TEXT
	EXEC SQL END DECLARE SECTION;

	sqlcode = 0;
	DBcount = 0;

	rec_count = 0;

	// DBの行数を取得
	EXEC SQL 
	SELECT 
	COUNT(*)
	INTO :rec_count
	FROM	schtbl;
//	EXEC SQL END;

	// SELECTエラー 
	if(memcmp (sqlca.sqlstate, "00", 2) != 0)
	{
		sprintf(tmp,"データベースSELECT COUNTエラー:%d - %s",sqlca.sqlcode,sqlca.sqlerrm.sqlerrmc);
		popmsg((COLS/2)-24,(LINES/2)-4,tmp);
		return(-1) ;
	}

	DBcount = rec_count;

	EXEC SQL DECLARE schtbl_CURSOR CURSOR FOR 
	SELECT 
		coalesce(schedule_name,' ','0'),
		coalesce(schedule_date,' ','0'),
		coalesce(online_start,' ','0'),
		coalesce(online_end,' ','0'),
		weekly_sun,
		weekly_mon,
		weekly_tue,
		weekly_wed,
		weekly_thu,
		weekly_fri,
		weekly_sat,
		coalesce(specific1,' ','0'),
		coalesce(specific2,' ','0'),
		coalesce(specific3,' ','0'),
		coalesce(specific4,' ','0'),
		coalesce(specific5,' ','0'),
		coalesce(specific6,' ','0'),
		coalesce(specific7,' ','0'),
		coalesce(schedule_time,' ','0'),
		max_retry_count,
		coalesce(cmd_line,' ','0')
	FROM	schtbl
	ORDER BY schedule_name;
//	EXEC SQL END;

	// カーソルオープン
	EXEC SQL OPEN schtbl_CURSOR;

	// SELECT OPENエラー 
	if (memcmp (sqlca.sqlstate, "00", 2) != 0)
	{
		sprintf(tmp,"データベースSELECT OPENエラー:%d - %s",sqlca.sqlcode,sqlca.sqlerrm.sqlerrmc);
		popmsg((COLS/2)-24,(LINES/2)-4,tmp);
		return(-1);
	}

	for(i=0;i<DBcount;i++)
	{
		EXEC SQL FETCH schtbl_CURSOR INTO
			:schedule_name,
			:schedule_date,
			:online_start,
			:online_end,
			:weekly_sun,
			:weekly_mon,
			:weekly_tue,
			:weekly_wed,
			:weekly_thu,
			:weekly_fri,
			:weekly_sat,
			:specific1,
			:specific2,
			:specific3,
			:specific4,
			:specific5,
			:specific6,
			:specific7,
			:schedule_time,
			:max_retry_count,
			:cmd_line;

		if (memcmp (sqlca.sqlstate, "00", 2) != 0)
		{
			sprintf(tmp,"データベースFETCHエラー:%d - %s",sqlca.sqlcode,sqlca.sqlerrm.sqlerrmc);
			popmsg((COLS/2)-24,(LINES/2)-4,tmp);
			return(-1);
		}
	// テーブル項目をsplitbDBbuff[][]にセットする
		sf_assgetDB(no,i,0,schedule_name,16 + 1);
		sf_assgetDB(no,i,1,schedule_date,8 + 1);
		sf_assgetDB(no,i,2,online_start,14 + 1);
		sf_assgetDB(no,i,3,online_end,14 + 1);
		sf_to_text(weekly_sun,DBbuff);	//NUMERIC型(int)を文字に変換する。
		sf_assgetDB(no,i,4,DBbuff,1 + 1);
		sf_to_text(weekly_mon,DBbuff);	//NUMERIC型(int)を文字に変換する。
		sf_assgetDB(no,i,5,DBbuff,1 + 1);
		sf_to_text(weekly_tue,DBbuff);	//NUMERIC型(int)を文字に変換する。
		sf_assgetDB(no,i,6,DBbuff,1 + 1);
		sf_to_text(weekly_wed,DBbuff);	//NUMERIC型(int)を文字に変換する。
		sf_assgetDB(no,i,7,DBbuff,1 + 1);
		sf_to_text(weekly_thu,DBbuff);	//NUMERIC型(int)を文字に変換する。
		sf_assgetDB(no,i,8,DBbuff,1 + 1);
		sf_to_text(weekly_fri,DBbuff);	//NUMERIC型(int)を文字に変換する。
		sf_assgetDB(no,i,9,DBbuff,1 + 1);
		sf_to_text(weekly_sat,DBbuff);	//NUMERIC型(int)を文字に変換する。
		sf_assgetDB(no,i,10,DBbuff,1 + 1);
		sf_assgetDB(no,i,11,specific1,6 + 1);
		sf_assgetDB(no,i,12,specific2,6 + 1);
		sf_assgetDB(no,i,13,specific3,6 + 1);
		sf_assgetDB(no,i,14,specific4,6 + 1);
		sf_assgetDB(no,i,15,specific5,6 + 1);
		sf_assgetDB(no,i,16,specific6,6 + 1);
		sf_assgetDB(no,i,17,specific7,6 + 1);
		sf_assgetDB(no,i,18,schedule_time,4 + 1);
		sf_to_text(max_retry_count,DBbuff);	//NUMERIC型(int)を文字に変換する。
		sf_assgetDB(no,i,19,DBbuff,5 + 1);
		sf_assgetDB(no,i,20,cmd_line,256 + 1);

		if (memcmp (sqlca.sqlstate, "00", 2) != 0)
		{
			EXEC SQL CLOSE schtbl_CURSOR;
		//	EXEC SQL END;
			sprintf(tmp,"データベースFETCHエラー:%d - %s",sqlca.sqlcode,sqlca.sqlerrm.sqlerrmc);
			popmsg((COLS/2)-24,(LINES/2)-4,tmp);
			return(-1);
		}
	}
	// カーソルクローズ 
	EXEC SQL CLOSE schtbl_CURSOR;
//	EXEC SQL END;

	DBcount = rec_count;

	// 結果チェック
	if (sqlca.sqlcode != 0)
	{
		sprintf(tmp,"データベースFETCH結果チェック:%d - %s",sqlca.sqlcode,sqlca.sqlerrm.sqlerrmc);
		popmsg((COLS/2)-24,(LINES/2)-4,tmp);
		return(0);
	}
	// 切断
	sqlca.sqlcode = 0;
	EXEC SQL DISCONNECT dbConnection;
	return(0);
}

int Insert_schtbl(int no)
{
	static char DBbuff[MAX_STR];
	int i = 0;

	DBConnect();

	memset (sqlca.sqlstate, '0', 5);

	EXEC SQL BEGIN DECLARE SECTION;
		int rec_count;
		char	schedule_name[16 + 1];	//TEXT
		char	schedule_date[8 + 1];	//TEXT
		char	online_start[14 + 1];	//TEXT
		char	online_end[14 + 1];	//TEXT
		int		weekly_sun;		//NUMERIC
		int		weekly_mon;		//NUMERIC
		int		weekly_tue;		//NUMERIC
		int		weekly_wed;		//NUMERIC
		int		weekly_thu;		//NUMERIC
		int		weekly_fri;		//NUMERIC
		int		weekly_sat;		//NUMERIC
		char	specific1[6 + 1];	//TEXT
		char	specific2[6 + 1];	//TEXT
		char	specific3[6 + 1];	//TEXT
		char	specific4[6 + 1];	//TEXT
		char	specific5[6 + 1];	//TEXT
		char	specific6[6 + 1];	//TEXT
		char	specific7[6 + 1];	//TEXT
		char	schedule_time[4 + 1];	//TEXT
		int		max_retry_count;		//NUMERIC
		char	cmd_line[256 + 1];	//TEXT
	EXEC SQL END DECLARE SECTION;

	sqlcode = 0;

	// インサート
	// テーブル項目をsplitbDBbuff[]からDB配列にセットする
	sf_assputDB(no,0,schedule_name,16 + 1);
	sf_assputDB(no,1,schedule_date,8 + 1);
	sf_assputDB(no,2,online_start,14 + 1);
	sf_assputDB(no,3,online_end,14 + 1);
	sf_assputDB(no,4,DBbuff,1 + 1);
	weekly_sun = sf_to_integer(DBbuff);	//文字(char)をNUMERIC型(int)に変換する。
	sf_assputDB(no,5,DBbuff,1 + 1);
	weekly_mon = sf_to_integer(DBbuff);	//文字(char)をNUMERIC型(int)に変換する。
	sf_assputDB(no,6,DBbuff,1 + 1);
	weekly_tue = sf_to_integer(DBbuff);	//文字(char)をNUMERIC型(int)に変換する。
	sf_assputDB(no,7,DBbuff,1 + 1);
	weekly_wed = sf_to_integer(DBbuff);	//文字(char)をNUMERIC型(int)に変換する。
	sf_assputDB(no,8,DBbuff,1 + 1);
	weekly_thu = sf_to_integer(DBbuff);	//文字(char)をNUMERIC型(int)に変換する。
	sf_assputDB(no,9,DBbuff,1 + 1);
	weekly_fri = sf_to_integer(DBbuff);	//文字(char)をNUMERIC型(int)に変換する。
	sf_assputDB(no,10,DBbuff,1 + 1);
	weekly_sat = sf_to_integer(DBbuff);	//文字(char)をNUMERIC型(int)に変換する。
	sf_assputDB(no,11,specific1,6 + 1);
	sf_assputDB(no,12,specific2,6 + 1);
	sf_assputDB(no,13,specific3,6 + 1);
	sf_assputDB(no,14,specific4,6 + 1);
	sf_assputDB(no,15,specific5,6 + 1);
	sf_assputDB(no,16,specific6,6 + 1);
	sf_assputDB(no,17,specific7,6 + 1);
	sf_assputDB(no,18,schedule_time,4 + 1);
	sf_assputDB(no,19,DBbuff,5 + 1);
	max_retry_count = sf_to_integer(DBbuff);	//文字(char)をNUMERIC型(int)に変換する。
	sf_assputDB(no,20,cmd_line,256 + 1);

	// 対象レコードをADD
	EXEC SQL INSERT INTO schtbl
	(
		schedule_name,
		schedule_date,
		online_start,
		online_end,
		weekly_sun,
		weekly_mon,
		weekly_tue,
		weekly_wed,
		weekly_thu,
		weekly_fri,
		weekly_sat,
		specific1,
		specific2,
		specific3,
		specific4,
		specific5,
		specific6,
		specific7,
		schedule_time,
		max_retry_count,
		cmd_line
	)
	VALUES
	(
		coalesce(:schedule_name,' ','0'),
		coalesce(:schedule_date,' ','0'),
		coalesce(:online_start,' ','0'),
		coalesce(:online_end,' ','0'),
		:weekly_sun,
		:weekly_mon,
		:weekly_tue,
		:weekly_wed,
		:weekly_thu,
		:weekly_fri,
		:weekly_sat,
		coalesce(:specific1,' ','0'),
		coalesce(:specific2,' ','0'),
		coalesce(:specific3,' ','0'),
		coalesce(:specific4,' ','0'),
		coalesce(:specific5,' ','0'),
		coalesce(:specific6,' ','0'),
		coalesce(:specific7,' ','0'),
		coalesce(:schedule_time,' ','0'),
		:max_retry_count,
		coalesce(:cmd_line,' ','0')
	);
//	EXEC SQL END;

	// 登録エラー
	if (memcmp (sqlca.sqlstate, "00", 2) != 0)
	{
		// ロールバック
		EXEC SQL ROLLBACK WORK;
		EXEC SQL END;
		sprintf(tmp,"データベースINSERTエラー:%d - %s",sqlca.sqlcode,sqlca.sqlerrm.sqlerrmc);
		popmsg((COLS/2)-24,(LINES/2)-4,tmp);
		return(-1);
	}

	// コミット
	EXEC SQL COMMIT;
	EXEC SQL END;

	// 結果チェック
	if (sqlca.sqlcode != 0)
	{
		sprintf(tmp,"データベースINSERT結果チェック:%d - %s",sqlca.sqlcode,sqlca.sqlerrm.sqlerrmc);
		popmsg((COLS/2)-24,(LINES/2)-4,tmp);
		return(0);
	}

	// 切断
	sqlca.sqlcode = 0;
	EXEC SQL DISCONNECT dbConnection;
	return(0);
}

int	Update_schtbl(int no,const char* key1,const char* key2,int sqlcode,int line)
{
	static char DBbuff[MAX_STR];
	int i = 0;

	DBConnect();

	memset (sqlca.sqlstate, '0', 5);

	EXEC SQL BEGIN DECLARE SECTION;
		int rec_count;
		char	schedule_name[16 + 1];	//TEXT
		char	schedule_date[8 + 1];	//TEXT
		char	online_start[14 + 1];	//TEXT
		char	online_end[14 + 1];	//TEXT
		int		weekly_sun;		//NUMERIC
		int		weekly_mon;		//NUMERIC
		int		weekly_tue;		//NUMERIC
		int		weekly_wed;		//NUMERIC
		int		weekly_thu;		//NUMERIC
		int		weekly_fri;		//NUMERIC
		int		weekly_sat;		//NUMERIC
		char	specific1[6 + 1];	//TEXT
		char	specific2[6 + 1];	//TEXT
		char	specific3[6 + 1];	//TEXT
		char	specific4[6 + 1];	//TEXT
		char	specific5[6 + 1];	//TEXT
		char	specific6[6 + 1];	//TEXT
		char	specific7[6 + 1];	//TEXT
		char	schedule_time[4 + 1];	//TEXT
		int		max_retry_count;		//NUMERIC
		char	cmd_line[256 + 1];	//TEXT
	EXEC SQL END DECLARE SECTION;

	sqlcode = 0;

	strncpy((char *)schedule_name,key1,sizeof(schedule_name));	//KEY1
	strncpy((char *)schedule_date,key2,sizeof(schedule_date));	//KEY2
	// アップデート
	// テーブル項目をsplitbDBbuff[]からDB配列にセットする
	sf_assputDB(no,0,schedule_name,16 + 1);
	sf_assputDB(no,1,schedule_date,8 + 1);
	sf_assputDB(no,2,online_start,14 + 1);
	sf_assputDB(no,3,online_end,14 + 1);
	sf_assputDB(no,4,DBbuff,1 + 1);
	weekly_sun = sf_to_integer(DBbuff);	//文字(char)をNUMERIC型(int)に変換する。
	sf_assputDB(no,5,DBbuff,1 + 1);
	weekly_mon = sf_to_integer(DBbuff);	//文字(char)をNUMERIC型(int)に変換する。
	sf_assputDB(no,6,DBbuff,1 + 1);
	weekly_tue = sf_to_integer(DBbuff);	//文字(char)をNUMERIC型(int)に変換する。
	sf_assputDB(no,7,DBbuff,1 + 1);
	weekly_wed = sf_to_integer(DBbuff);	//文字(char)をNUMERIC型(int)に変換する。
	sf_assputDB(no,8,DBbuff,1 + 1);
	weekly_thu = sf_to_integer(DBbuff);	//文字(char)をNUMERIC型(int)に変換する。
	sf_assputDB(no,9,DBbuff,1 + 1);
	weekly_fri = sf_to_integer(DBbuff);	//文字(char)をNUMERIC型(int)に変換する。
	sf_assputDB(no,10,DBbuff,1 + 1);
	weekly_sat = sf_to_integer(DBbuff);	//文字(char)をNUMERIC型(int)に変換する。
	sf_assputDB(no,11,specific1,6 + 1);
	sf_assputDB(no,12,specific2,6 + 1);
	sf_assputDB(no,13,specific3,6 + 1);
	sf_assputDB(no,14,specific4,6 + 1);
	sf_assputDB(no,15,specific5,6 + 1);
	sf_assputDB(no,16,specific6,6 + 1);
	sf_assputDB(no,17,specific7,6 + 1);
	sf_assputDB(no,18,schedule_time,4 + 1);
	sf_assputDB(no,19,DBbuff,5 + 1);
	max_retry_count = sf_to_integer(DBbuff);	//文字(char)をNUMERIC型(int)に変換する。
	sf_assputDB(no,20,cmd_line,256 + 1);

	// 対象レコードをUPDATE
//	for(i=0;i<DBcount;i++)
//	{
		EXEC SQL UPDATE schtbl
		SET
			schedule_name =	coalesce(:schedule_name,' ','0'),
			schedule_date =	coalesce(:schedule_date,' ','0'),
			online_start =	coalesce(:online_start,' ','0'),
			online_end =	coalesce(:online_end,' ','0'),
			weekly_sun = 	:weekly_sun,
			weekly_mon = 	:weekly_mon,
			weekly_tue = 	:weekly_tue,
			weekly_wed = 	:weekly_wed,
			weekly_thu = 	:weekly_thu,
			weekly_fri = 	:weekly_fri,
			weekly_sat = 	:weekly_sat,
			specific1 =	coalesce(:specific1,' ','0'),
			specific2 =	coalesce(:specific2,' ','0'),
			specific3 =	coalesce(:specific3,' ','0'),
			specific4 =	coalesce(:specific4,' ','0'),
			specific5 =	coalesce(:specific5,' ','0'),
			specific6 =	coalesce(:specific6,' ','0'),
			specific7 =	coalesce(:specific7,' ','0'),
			schedule_time =	coalesce(:schedule_time,' ','0'),
			max_retry_count = 	:max_retry_count,
			cmd_line =	coalesce(:cmd_line,' ','0')
		WHERE schedule_name = :schedule_name AND schedule_date = :schedule_date;
		EXEC SQL END;
//	}

	if (memcmp (sqlca.sqlstate, "00", 2) != 0)
	{
	// 更新エラー
		// ロールバッ
		EXEC SQL ROLLBACK WORK;
		EXEC SQL END;
		sprintf(tmp,"データベースUPDATEエラー:%d - %s",sqlca.sqlcode,sqlca.sqlerrm.sqlerrmc);
		popmsg((COLS/2)-24,(LINES/2)-4,tmp);
		return(-1);
	}

	//コミットする
	EXEC SQL COMMIT;
	EXEC SQL END;


	// 結果チェック
	if (sqlca.sqlcode != 0)
	{
		sprintf(tmp,"データベースUPDATE結果チェック:%d - %s",sqlca.sqlcode,sqlca.sqlerrm.sqlerrmc);
		popmsg((COLS/2)-24,(LINES/2)-4,tmp);
		return(0);
	}

	// 切断
	sqlca.sqlcode = 0;
	EXEC SQL DISCONNECT dbConnection;
	return(0);
}

int	Delete_schtbl(const char *key1,char *key2,int sqlcode)
{
	static char DBbuff[MAX_STR];
	int i = 0;

	DBConnect();

	memset (sqlca.sqlstate, '0', 5);

	EXEC SQL BEGIN DECLARE SECTION;
		char	schedule_name[16 + 1];	//TEXT
		char	schedule_date[8 + 1];	//TEXT
		char	online_start[14 + 1];	//TEXT
		char	online_end[14 + 1];	//TEXT
		int		weekly_sun;		//NUMERIC
		int		weekly_mon;		//NUMERIC
		int		weekly_tue;		//NUMERIC
		int		weekly_wed;		//NUMERIC
		int		weekly_thu;		//NUMERIC
		int		weekly_fri;		//NUMERIC
		int		weekly_sat;		//NUMERIC
		char	specific1[6 + 1];	//TEXT
		char	specific2[6 + 1];	//TEXT
		char	specific3[6 + 1];	//TEXT
		char	specific4[6 + 1];	//TEXT
		char	specific5[6 + 1];	//TEXT
		char	specific6[6 + 1];	//TEXT
		char	specific7[6 + 1];	//TEXT
		char	schedule_time[4 + 1];	//TEXT
		int		max_retry_count;		//NUMERIC
		char	cmd_line[256 + 1];	//TEXT
	EXEC SQL END DECLARE SECTION;

	sqlcode = 0;

		// キー項目設定
	memset((char *)schedule_name, '\0', sizeof(schedule_name));
	memset((char *)schedule_date, '\0', sizeof(schedule_date));
	strncpy((char *)schedule_name,key1,sizeof(schedule_name));	//KEY1
	strncpy((char *)schedule_date,key2,sizeof(schedule_date));	//KEY2

	// 削除対象レコードをDELETE
	EXEC SQL DELETE FROM schtbl
	WHERE schedule_name = :schedule_name AND schedule_date = :schedule_date;
	EXEC SQL END;

	if (memcmp (sqlca.sqlstate, "00", 2) != 0)
	{
	// 削除エラー
		// ロールバック
		EXEC SQL ROLLBACK WORK;
		EXEC SQL END;
		sprintf(tmp,"データベースUPDATEエラー:%d - %s",sqlca.sqlcode,sqlca.sqlerrm.sqlerrmc);
		popmsg((COLS/2)-24,(LINES/2)-4,tmp);
		return(-1);
	}

	//コミットする
	EXEC SQL COMMIT;
	EXEC SQL END;


	// 結果チェック
	if (sqlca.sqlcode != 0)
	{
		sprintf(tmp,"データベースUPDATE結果チェック:%d - %s",sqlca.sqlcode,sqlca.sqlerrm.sqlerrmc);
		popmsg((COLS/2)-24,(LINES/2)-4,tmp);
		return(0);
	}

	// 切断
	sqlca.sqlcode = 0;
	EXEC SQL DISCONNECT dbConnection;
	return(0);
}

//以下の二つの関数は入出力画面(ウインドウ)とのインターフェース関数です。
//FETCHしたgridにDBの行列を書き込みます。
int schdytbl_disp(int no, int startline, int maxcol)
{
	int i, j;
	char s[MAX_TMP];
//	char tmp[MAX_TMP];

	if((Fetch_schtbl(no)) == 0)
	{
		for(i=startline;i<DBcount;i++)
		{
			for(j=0;j<maxcol;j++)
			{
				sf_gputDB(no,i,j,startline,s);
			//	sf_ggetDB(no,i,j,startline,tmp);
			//	popmsg((COLS/2)-24,(LINES/2)-4,tmp);
			}
		}
		return(0);
	}
	else
	{
		return(-1);
	}
}

//DBから入出力(画面)ウインドウに書き込みます。
void inputwin_write(int no, int get, int line,int maxcol)
{
	int i;
	char s[MAX_TMP];
	
	sf_tbegin();
	for(i=0;tp->next != (TextBox *)NULL;i++)
	{
		sprintf(s,"%s",ft[get].splitDBbuff[line][i]);
		sf_tput(no,i,s);
		sf_tnext();
	}
	sprintf(s,"%s",ft[get].splitDBbuff[line][i]);
	sf_tput(no,i,s);
}


int subform(void)
{
	int i,j,k;
	int ret;
	char f[256];
	int xcol,rows;
	int maxtext;
	char s[MAX_STR];

	int xcol2;
	int maxcol;
	int startline;
	
	int line;
	char key1[MAX_STR];
	char key2[MAX_STR];
	char key3[MAX_STR];

	sprintf(f,"%s","_schtbl.def");
	initscr();

	xcol = COLS;
	rows = LINES;

	cbreak();
	noecho();
	keypad(stdscr, TRUE);
	meta(stdscr, TRUE);

	if(stat(f,fileptr) != 0)
	{
		popmsg((COLS/2)-24,(LINES/2)-4,"メイングリッドフォーム定義ファイルがありあません。");
		echo();
		endwin();
		exit(0);
	}
	if(stat("_inputwin2.def",fileptr) != 0)
	{
		popmsg((COLS/2)-24,(LINES/2)-4,"入力用テキストボックスフォーム定義ファイルがありあません。");
		echo();
		endwin();
		exit(0);
	}
	if(stat("_header.def",fileptr) != 0)
	{
		popmsg((COLS/2)-24,(LINES/2)-4,"ヘッダータイトル用グリッドフォーム定義ファイルがありあません。");
		echo();
		endwin();
		exit(0);
	}
	if(stat("_footer.def",fileptr) != 0)
	{
		popmsg((COLS/2)-24,(LINES/2)-4,"ファンクションキー用グリッドフォーム定義ファイルがありあません。");
		echo();
		endwin();
		exit(0);
	}
//------------------------------------------------------------------------
	xcol = sf_wsubform(3,144,24,1,25,"_inputwin.def");	//入力用テキストボックスセル定義ファイルを開く。
//------------------------------------------------------------------------
//Automatic Subform Editor v3.0.0 からの出力ファイル _schtbl.def.c を挿入してみる。

	xcol = 144;
	rows = 44;

//for grid
	static int cell_length[] = {16,8,8,8,1,1,1,1,1,1,1,6,6,6,6,6,6,6,4,5,23,0};
	static int cell_align[] = {2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,0};
	static int cell_action[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
	static int grid_field[] = {1,1,1,1,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,2,1,0};
	static int grid_skipstep[] = {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0};
//	char *grid_titles[22][128] = {"Grid_1","Grid_2","Grid_3","Grid_4","Grid_5","Grid_6","Grid_7","Grid_8","Grid_9","Grid_10","Grid_11","Grid_12","Grid_13","Grid_14","Grid_15","Grid_16","Grid_17","Grid_18","Grid_19","Grid_20","Grid_21",""};
	char *grid_titles[22][128] = {"schedule_name","schedule_date","online_start","online_end","weekly_sun","weekly_mon","weekly_tue","weekly_wed","weekly_thu","weekly_fri","weekly_sat","specific1","specific2","specific3","specific4","specific5","specific6","specific7","schedule_time","max_retry_count","cmd_line",0};
	static int grid_sx = 0;
	static int grid_ex = 140;
	static int grid_sy = 2;
//	static int grid_ey = 23;
	static int grid_ey = 21;

	static int no = 0;

	char **gt;

	gt = (char **)&grid_titles;

	xcol = MakeWsubForm(no,xcol,rows,0,2,grid_sx,grid_sy,grid_ex,grid_ey,cell_length,cell_align,cell_action,grid_field,grid_skipstep,gt,21);

//------------------------------------------------------------------------
//元の構文は以下のようになっている。MakeWsubform() は一ヶ所のみに挿入可能。
//	xcol = sf_wsubform(0,144,44,1,2,f);	//メイングリッドフォーム定義ファイルを開く。
//maxtext = sf_textbox(3,1,25,"_inputwin.def");	//テキストボックスセルを展開する。x,y はsf_wsubform()に重ならないように合わせる。
//------------------------------------------------------------------------

//
//Automatic Subform Editor v3.0.0
//以下の関数は定義ファイルを利用しないインターフェースで利用可能
//他のソースファイルの initscr() 以下の行に挿入して利用可能
//	xcol = 144;
//	rows = 24;

//for label
	static int label_length[] = {17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,0};
	static int label_no[] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,0};
	static int label_align[] = {2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0};
	static char *label_text[22][128] = {"Label_1","Label_2","Label_3","Label_4","Label_5","Label_6","Label_7","Label_8","Label_9","Label_10","Label_11","Label_12","Label_13","Label_14","Label_15","Label_16","Label_17","Label_18","Label_19","Label_20","Label_21",""};
	static int label_x[] = {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0};
	static int label_y[] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,0};
//for textbox
	static int textbox_length[] = {16,8,8,8,1,1,1,1,1,1,1,6,6,6,6,6,6,6,4,5,120,0};
	static int textbox_no[] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,0};
	static int textbox_align[] = {2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,0};
	static int textbox_action[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
	static int textbox_skipstep[] = {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0};
	static int textbox_field[] = {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,1,0};
	static int textbox_x[] = {19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,0};
	static int textbox_y[] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,0};

	no = 3;

	char **lt;
//	char **gt;

	lt = (char **)&label_text;

	maxtext = MakeTextBox(no,1,25,xcol,rows,label_no,lt,label_x,label_y,label_length,textbox_no,textbox_x,textbox_y,textbox_length,textbox_align,textbox_action,textbox_field,textbox_skipstep, 21);
//

//------------------------------------------------------------------------

	wrefresh(xt[0].form);

	xcol = sf_wsubform(2,144,rows,0,46,"_footer.def");
	sf_gcep(2,0,0,3,"入力画面へ");
//	sf_gcep(2,0,0,3,"Input");
	sf_gcep(2,12,0,3,"ESC-Exit");
	wrefresh(xt[2].form);

	for(i=0;i<MAX_POS;i++)
		memset(gridtitles[i],'\0',MAX_LEN);

	xcol = sf_wsubform(1,144,rows,0,0,"_header.def");
	sf_gcep(1,0,0,1,"v1.0.3");
	sprintf(ft[1].cp[0][0].s,"%s","APscheduler");
	mvwprintw(ft[1].st[0][0].vs,0,1,"%s",ft[1].cp[0][0].s);
	sf_wrefreshcell(1,0,0);
	sf_wrefreshform(1);

	sf_startcell(0);

	ret = Gret;

	while(1)
	{
		startline = sf_getstartline(0);	//DBgrid()の持っているスクロールに必要なＤＢグリッドの画面初期行の位置情報。
		if(schdytbl_disp(0,startline,maxtext) == -1)	//*splitDBbuff[][]をグリッドに書き込み表示する。
		{
			popmsg(12,12,"schtbl_disp():error");
		}
		ret = sf_DBgrid(0,maxtext,140,0,DBcount,maxtext);	//データベース連結用グリッド。*splitDBbuff[][]を表示する。
		switch(ret)
		{
		case -1:
			echo();
			endwin();
			exit(0);
			break;

		//for grid
		case 200: //ESC　キーでプログラムを終了する。
			if(popmsg((COLS/2)-24,(LINES/2)-4,"Exit grid area in Subform?") == 1)
				goto end;
			ret = Pret;
			break;
		case 201: //F1
		//DBへの入力用ウインドウの作成
			line = sf_status(0,Grid,'D');
			inputwin_write(3,0,line,maxtext);
			/*
			sf_gcep(2,0,0,3,"ret");
			sf_gcep(2,4,0,3,"update");
			sf_gcep(2,5,0,3,"insert");
			sf_gcep(2,6,0,3,"delete n+d+t");
			sf_gcep(2,7,0,3,"delete n+d");
			sf_gcep(2,8,0,3,"delete < d");
			*/
			sf_gcep(2,0,0,3,"戻る");
			sf_gcep(2,4,0,3,"更新");
			sf_gcep(2,5,0,3,"追加");
			sf_gcep(2,6,0,3,"削除 n+d+t");
			sf_gcep(2,7,0,3,"削除 n+d");
			sf_gcep(2,8,0,3,"削除 < d");
			while(1)
			{
				ret = sf_formtext(3,maxtext, 140);
				switch(ret)
				{
				case -1:
					echo();
					endwin();
					exit(0);
					break;
				case 100:
					if(popmsg((COLS/2)-24,(LINES/2)-4,"Exit grid area in Subform?") == 1)
						goto end;
					break;
				case 101:
					goto mainwin;
					break;
				case 102:
					break;
				case 105:
					sf_tgetDBall(3);	//入出力用ウインドウの各項目をメモリ確保してsplitDBbuff[]に書き込む。
					sprintf(key1,"%s",ft[0].splitDBbuff[line][0]);
					sprintf(key2,"%s",ft[0].splitDBbuff[line][1]);
					//確保されたメモリはDB操作時に時動的に開放される。
					if(Update_schtbl(0,key1,key2,sqlcode,line) == -1)
					{
						popmsg((COLS/2)-24,(LINES/2)-4,"データベースが更新出来ません。");
					}
					goto mainwin;
					break;
				case 106:
					sf_tgetDBall(3);	//入出力用ウインドウの各項目をメモリ確保してsplitDBbuff[]に書き込む。
					sprintf(key1,"%s",ft[0].splitDBbuff[line][0]);
					sprintf(key2,"%s",ft[0].splitDBbuff[line][1]);
					//確保されたメモリはDB操作時に時動的に開放される。
					if(Insert_schtbl(0) == -1)
					{
						popmsg((COLS/2)-24,(LINES/2)-4,"データベースが追加出来ません。");
					}
					goto mainwin;
					break;
				case 107:
					if(popmsg((COLS/2)-24,(LINES/2)-4,"名前と日付と実行時間でデータを削除しますか？") == 1)
					{
					//	schdytbl_write(line);
						sprintf(key1,"%s",ft[0].splitDBbuff[line][0]);
						sprintf(key2,"%s",ft[0].splitDBbuff[line][1]);
					//	schdytbl_write(line);
						if(Delete_schtbl(key1,key2,sqlcode) == -1)
						{
							popmsg((COLS/2)-24,(LINES/2)-4,"データベースから削除出来ません。");
						}
					}
					else
					{
						goto mainwin;
					}
					goto cleardisp;
					break;
				case 108:
					if(popmsg((COLS/2)-24,(LINES/2)-4,"名前と日付でデータを削除しますか？") == 1)
					{
						sprintf(key1,"%s",ft[0].splitDBbuff[line][0]);
						sprintf(key2,"%s",ft[0].splitDBbuff[line][1]);
						if(Delete_schtbl(key1,key2,sqlcode) == -1)
						{
							popmsg((COLS/2)-24,(LINES/2)-4,"データベースから削除出来ません。");
						}
					}
					else
					{
						goto mainwin;
					}
					goto cleardisp;
					break;
				case 109:
					sf_tget(3,1,s);
					sprintf(tmp,"%s の日付以前の全てのデータを削除しますか？",s);
					if(popmsg((COLS/2)-24,(LINES/2)-4,tmp) == 1)
					{
						sprintf(key1,"%s",ft[0].splitDBbuff[line][1]);
						if(Delete_schtbl(key1,key2,sqlcode) == -1)
						{
							popmsg((COLS/2)-24,(LINES/2)-4,"データベースから削除出来ません。");
						}
					}
					else
					{
						goto mainwin;
					}
					goto cleardisp;
					break;
				case 110:
					break;
				}
			}
			cleardisp:
			sf_initgridcell(0);
			mainwin:
			sf_gcep(2,0,0,3,"入力画面へ");
			sf_gcep(2,4,0,3,"          ");
			sf_gcep(2,5,0,3,"          ");
			sf_gcep(2,6,0,3,"          ");
			sf_gcep(2,7,0,3,"          ");
			sf_gcep(2,8,0,3,"          ");
			ret = Pret;
			break;
		case 202: //F2
			ret = Pret;
			break;
		case 203: //F3　現在のセルの位置を調べた後、セル内文字を読みとりセンター詰めで書き込む。
			ret = Pret;
			break;
		case 204: //F4　現在のセルの位置を調べた後、数値"999999"を"999,999"で書き込む。
			ret = Pret;
			break;
		case 205: //F5
			ret = Pret;
			break;
		case 206: //F6　セル内文字を読みとりメッセージウインドウに表示する。
			ret = Pret;
			break;
		case 207: //F7　現在のセルの位置を調べた後、セルカーソルの移動場所を選択する。最後にNUMERIC型のセルに移動
			ret = Pret;
			break;
		case 208: //F8　セルの属性をメッセージウインドウに表示。
			ret = Pret;
			break;
		case 209: //F9　カンマ付き１１桁数値を全てのセルに書き込む。
			ret = Pret;
			break;
		case 210: //F10　全てのセルに番号を書き込む。
			ret = Pret;
			break;
		case 211: //F11　セルに番号を書き込む。
			ret = Pret;
			break;

		default:
			break;
		}
		sf_freeDB(0,DBcount,maxtext);	//新たにDBからテーブルを読み込むためにsplitDBbuff[][]を開放する。
	}

end:
	echo();
	endwin();
}

int main(void)
{
	subform();
}

