MFCで物品購入承認システム作成 11

前回までの話。

MFCで物品購入承認システム作成 1

MFCで物品購入承認システム作成 2

MFCで物品購入承認システム作成 3

MFCで物品購入承認システム作成 4

MFCで物品購入承認システム作成 5

MFCで物品購入承認システム作成 6

MFCで物品購入承認システム作成 7

MFCで物品購入承認システム作成 8

MFCで物品購入承認システム作成 9

MFCで物品購入承認システム作成 10

リストコントロール表示処理作成

今回はメイン画面のリストコントロール内に、
自分の申請状況を表示させる処理を作ります。

まず初めに、マップの作製。

ユーザ情報表示のやり方だとどうもうまくいかず、
グループや項目の表示方法はうまくいったので、
今回はマップを採用します。

作り方は項目マップと同じです。

構造体定義

SupplyRequestManager.hに、以前KoumokuValueなる構造体を定義しました。

今回はその履歴版です。

struct RecordValue
{
	CString strGroupName;		// グループ名称
	CString strKoumokuName;		// 項目名称
	CString strPrice;			// 項目値段
	CString strApproval;		// 承認状態
};

リストコントロール内に表示させる内容です。

マップ定義

SupplyRequestManagerDlg.hに、メンバマップを定義します。
また、リスト表示させる準備も。

private:
	std::unordered_map<int, RecordValue> m_MapRecord;	// 履歴テーブル格納
	CListCtrl m_ctrlListRecord;	// リストコントロール
	void ShowRecordMap();	//申請履歴表示関数
public:
	std::unordered_map<int, RecordValue>* GetMapRecord() { return &m_MapRecord; }

取得処理

項目マップと同じく、OnInitDialogに取得処理を書きます。

BOOL CSupplyRequestManagerDlg::OnInitDialog()
{
	CDialogEx::OnInitDialog();

    // 略

	CMySQLManager GroupKoumokuGetter;
	GroupKoumokuGetter.GetConnection();	//接続確立

	GroupKoumokuGetter.SetGroupMap(GetMapGroup());		// グループテーブルデータをマップに格納
	GroupKoumokuGetter.SetKoumokuMap(GetMapKoumoku());	// 項目テーブルデータをマップに格納
	GroupKoumokuGetter.SetRecordMap(GetMapRecord());	// 履歴テーブルデータをマップに格納

	// 列設定
	m_ctrlListRecord.InsertColumn(0, _T("ID"), LVCFMT_LEFT, 100);
	m_ctrlListRecord.InsertColumn(0, _T("グループ"), LVCFMT_LEFT, 200);
	m_ctrlListRecord.InsertColumn(0, _T("項目"), LVCFMT_LEFT, 200);
	m_ctrlListRecord.InsertColumn(0, _T("値段"), LVCFMT_LEFT, 100);
	m_ctrlListRecord.InsertColumn(0, _T("承認状態"), LVCFMT_LEFT, 100);

	ShowRecordMap();	// リスト再表示

	UpdateData(FALSE);

	return TRUE;  // フォーカスをコントロールに設定した場合を除き、TRUE を返します。
}

12行目以降を追加しました。
例によってSetRecordMapはまだ定義していないので現段階ではエラーが出ます。
GroupKoumokuGetterはGroupKoumokuRecordGetterとかに変更した方がいいかもしれませんね。
そこはお好みで。

そして、先ほど定義したメンバ変数m_ctrlListRecordとリストコントロールを紐づけます。

void CSupplyRequestManagerDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialogEx::DoDataExchange(pDX);
	DDX_Control(pDX, IDC_LIST_MAIN, m_ctrlListRecord);
}

表示処理

履歴テーブルから取得してマップに格納したデータを表示させます。
こちらも、項目を表示させたのと同じ手法で。

/**
 * @fn
 * @brief	リスト再表示処理
 * @param	なし
 * @return	なし
 */
void CSupplyRequestManagerDlg::ShowRecordMap()
{
	// すべてのアイテム(行)を削除
	m_ctrlListRecord.DeleteAllItems();

	int iRow = 0;	// 行番号
	LVITEM lvItem{};
	lvItem.mask = LVIF_TEXT;

	for (const auto& pair : m_MapRecord)
	{
		// ID列
		lvItem.iSubItem = 0;
		CString strTemp;
		strTemp.Format(_T("%d"), pair.first);
		lvItem.pszText = strTemp.GetBuffer();
		m_ctrlListRecord.InsertItem(&lvItem);

		//	グループ名称列
		lvItem.iSubItem = 1;
		strTemp = pair.second.strGroupName;
		lvItem.pszText = strTemp.GetBuffer();
		m_ctrlListRecord.SetItem(&lvItem);

		//	項目名称列
		lvItem.iSubItem = 2;
		strTemp = pair.second.strKoumokuName;
		lvItem.pszText = strTemp.GetBuffer();
		m_ctrlListRecord.SetItem(&lvItem);

		//	値段列
		lvItem.iSubItem = 3;
		strTemp = pair.second.strPrice;
		lvItem.pszText = strTemp.GetBuffer();
		m_ctrlListRecord.SetItem(&lvItem);

		//	承認状態列
		lvItem.iSubItem = 4;
		strTemp = pair.second.strApproval;
		lvItem.pszText = strTemp.GetBuffer();
		m_ctrlListRecord.SetItem(&lvItem);

		iRow++;
	}
}

1列目に申請Id、2列目に申請したグループ名称、
3列目に申請した項目名称、4列目に申請した値段、
5列目に承認状態を表示させます。

これで表示はOK。

SQL文作成

recordテーブルからデータを取得し、マップに格納させます。

MySQLManager.hに関数定義。

public:
	// 申請履歴マップセット
	void SetRecordMap(std::unordered_map<int, RecordValue>* MapRecord);

MySQLManager.cppで具体的に処理を書いていきます。

/**
 * @fn
 * @brief	申請履歴テーブルセット
 * @param	std::unordered_map<int, RecordValue>* マップポインタ
 * @return	なし
 */
void CMySQLManager::SetRecordMap(std::unordered_map<int, RecordValue>* MapRecord)
{
    try
    {
        m_con->setSchema(SCHEMA);

        CSupplyRequestManagerApp* pApp = static_cast<CSupplyRequestManagerApp*>(AfxGetApp());
        CString strUserId = pApp->strGetUserId();   // ユーザID取得
        sql::SQLString strsqlUserID = strConverter(strUserId);  // ユーザID型変換

        sql::SQLString strSQL = "SELECT  " + TABLE_RECORD + ".Id AS RecordID, ";    // recordテーブルのID
        strSQL += TABLE_GROUP + ".Name AS GroupName, ";                             // groupテーブルのグループ名称
        strSQL += TABLE_KOUMOKU + ".Name AS KoumokuName, ";                         // koumokuテーブルの項目名称
        strSQL += TABLE_KOUMOKU + ".Price AS KoumokuPrice, ";                       // koumokuテーブルの項目値段
        strSQL += TABLE_RECORD + ".Approval AS RecordApproval ";                    // recordテーブルの承認状態
        strSQL += "FROM " + TABLE_RECORD;

        strSQL += " JOIN " + TABLE_KOUMOKU + " ON " + TABLE_RECORD + ".KoumokuId = " + TABLE_KOUMOKU + ".Id";
        strSQL += " JOIN " + TABLE_GROUP + " ON " + TABLE_KOUMOKU + ".GroupId = " + TABLE_GROUP + ".Id";
        
        strSQL += " WHERE " + TABLE_RECORD + ".UserId = " + strsqlUserID;           // recordテーブルでユーザIDが現ユーザ

        // クエリを実行
        std::unique_ptr<sql::PreparedStatement> pstmt(m_con->prepareStatement(strSQL));
        std::unique_ptr<sql::ResultSet> res(pstmt->executeQuery());

        // 結果を処理
        if (res->next())
        {
            do
            {
                int iRecordId = 0;
                CString strGroupName = _T("");
                CString strKoumokuName = _T("");
                CString strKoumokuPrice = _T("");
                int iApproval = 0;
                CString strApproval = _T("");

                std::string strsqlCol = res->getString("RecordID");             // ID列の取得
                CString strCol = strConvertFromUTF8ToUTF16(strsqlCol);          // 型変換
                iRecordId = _ttoi(strCol);

                strsqlCol = res->getString("GroupName");                        // グループ名称列の取得
                strCol = strConvertFromUTF8ToUTF16(strsqlCol);                  // 型変換
                strGroupName = strCol;

                strsqlCol = res->getString("KoumokuName");                      // 項目グループID列の取得
                strCol = strConvertFromUTF8ToUTF16(strsqlCol);                  // 型変換
                strKoumokuName = strCol;

                strsqlCol = res->getString("KoumokuPrice");                     // 値段列の取得
                strCol = strConvertFromUTF8ToUTF16(strsqlCol);                  // 型変換
                strKoumokuPrice = strCol;

                strsqlCol = res->getString("RecordApproval");                   // 承認状態の取得
                strCol = strConvertFromUTF8ToUTF16(strsqlCol);                  // 型変換
                iApproval = _ttoi(strCol);

                if ((ApprovalMode)iApproval == enPending)
                {
                    strApproval = _T("申請中");
                }
                else if ((ApprovalMode)iApproval == enApprovaled)
                {
                    strApproval = _T("承認済");
                }
                else if ((ApprovalMode)iApproval == enRejected)
                {
                    strApproval = _T("拒否");
                }
                else
                {
                    CString strMes = _T("");
                    strMes.Format(_T("データに問題があります。管理者へ連絡を!\r\nrecord ID:%d"), iRecordId);
                    AfxMessageBox(strMes);
                    return;
                }

                (*MapRecord)[iRecordId] = { strGroupName, strKoumokuName, strKoumokuPrice, strApproval };
            } while (res->next());
        }
        else
        {
            // 該当データが何もないけどそれは問題ない
        }

    }
    catch (sql::SQLException& e)
    {
        // 実行できなかった
        ErrSQLException(e);
        return;
    }
}

やってることは、グループマップや項目マップ作成と変わりありません。
テーブルからデータ取得して、マップに入れてるだけです。

強いて言えば、SQLが少しだけ複雑になってますね。
SQL久しぶりに書いたせいでちょっと手こずったのは内緒…。

変数を使わないとこうなります。

SELECT
	record.Id AS RecordID,
	'group'.Name AS GroupName,
	koumoku.Name AS KoumokuName,
	koumoku.price AS KoumokuPrice,
	record.Approval AS RecordApproval
FROM
	record
JOIN
	koumoku ON record.KoumokuId = koumoku.Id
JOIN
	'group' ON koumoku.GroupId = 'group'.Id
WHERE
	record.UserId = ●●●	// 現ユーザ

以上で、メイン画面のリストコントロールに表示させる処理ができたはず。

動作確認

今回、ユーザを複数人作ってみました。

ソートがうまくできてないですが、今回の作成範囲外なので…。

IDが11111、22222、33333でログインし、それぞれ申請を行ってみます。

色々申請を行い、テーブルはこんな感じに。

11111が4回、22222が2回、33333が3回申請しています。

さて、それぞれでログインすると…。

微妙にID順になってないー(;´∀`)

でも取りたい内容はちゃんと取得できていました。

項目IDから、ちゃんとグループ名称も取れてます。

ちょっと感動。

CListCtrlでソーする関数があるようですが、
今回は力尽きたので諦めます。

終わりに

今回はメイン画面の申請状況を取得する処理を作りました。

ようやく終わりが見えてきた…。

誰だよこんな画面数多い機能作ろうとしたやつ

何回か書いてますが、課題はリストコントロールのソートですかね。
そこはまた機会があれば調べてみます。

今回はここまで。

MFCで物品購入承認システム作成 12
前回までの話。MFCで物品購入承認システム作成 1MFCで物品購入承認システム作成 2MFCで物品購入承認システム作成 3MFCで物品購入承認システム作成 4MFCで物品購入承認システム作成 5MFCで物品購入承認システム作成 6MFCで物...

コメント

タイトルとURLをコピーしました