IT/C#

[C#] 가계부 프로그램 만들기 DAY4.수입,지출 등 내역 불러오기

Ella.J 2020. 3. 3. 11:26
728x90
반응형

이번 포스팅은 가계부를 입력하고 Main에서 보여지는 내용에 대해 포스팅해보겠습니다!

먼저, Main 화면에서 보고자 하는 내용은 다음과 같습니다.

  1. 총 누적 수입, 지출 금액
  2. 당월 전체 수입, 지출 금액
  3. 당월 계정별 수입, 지출 금액
  4. 내 계좌별 현재 잔액 및 전체 잔액

아래의 실행 예시 첨부했습니다. (예시입니다. 저는 돈이 쥐꼬리만큼 있습니다. ㅠㅠㅠ)

처음에 개발을 때는 DB 쿼리로 조회하여 내용을 금액 SUM으로 가져오려 했으나, DB 너무 많이 부르는 바람에 속도가 ~~ 느려져서  바꿔서 Select 가져온 DataSet(Config.books) 통해서 C#에서 돌리는 방향으로 했습니다.

 

각각의 수입내역, 지출내역 등 계산을 위해 int 변수를 위와 같이 선언해줍니다.

 

프로그램 Form_Load 이벤트에서 가지 함수를 호출해주는데,

InitSetting();

InitAccount();

InitMain();

으로 위의 개는 이전 포스팅에서 참고해주시면 되고, 마지막 InitMain() 함수 아래에 첨부해 두었습니다.

코드가 길어져서 코드별 주석으로 설명을 일일이 달았습니다. 주석을 참고해 주세요!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
public void InitMain()
{
    //각 변수 초기화
    iTotalImport = 0;
    iTotalExport = 0;
    iTotalMImport = 0;
    iTotalMExport = 0;
    iTotalAccount = 0;
 
    //각 계정별, 계좌별 금액 계산을 위한 배열
    int[] importCostM = new int[Config.ImportInfo.Length];
    int[] exportCostM = new int[Config.ExportInfo.Length];
    int[] accountCost = new int[Config.AccountName.Length];
            
    foreach (DataRow r in Config.books.Tables[0].Rows) //가계부 내역 전체
    {
        //DataSet에 들어가 있는 C# Date 형식은 ("1/3/2020 12:00:00 AM") 처럼 현재 Window 형식을 따라가기 때문에
        //다음과 같이 DB Date 형식 ("2020-03-01") 으로 비교하기 편하게 변경해줍니다.
        DateTime dt = DateTime.Parse(r["날짜"].ToString());
        string date = dt.ToString("yyyy-MM-dd");
                
        if (r["구분"].ToString() == "수입"//수입의 경우
        {
            iTotalImport += Convert.ToInt32(r["금액"]); //전체 수입 금액 SUM
            if(date.Contains($"{today.Year}-{today.Month.ToString("00")}-")) //당월 수입 내역인지?
            {
                for (int j = 0; j < Config.ImportInfo.Length; j++)
                {
                    if (r["계정"].ToString() == Config.ImportInfo[j])
                    {
                        importCostM[j] += Convert.ToInt32(r["금액"].ToString()); //계정별 수입 금액
                        iTotalMImport += Convert.ToInt32(r["금액"].ToString()); //당월 총 수입 금액
                    }
                }
            }
        }
        else if (r["구분"].ToString() == "지출"//지출의 경우
        {
            iTotalExport += Convert.ToInt32(r["금액"]); //전체 지출 금액 SUM
            for (int j = 0; j < Config.ExportInfo.Length; j++)
            {
                if (date.Contains($"{today.Year}-{today.Month.ToString("00")}-")) //당월 지출 내역인지?
                {
                    if (r["계정"].ToString() == Config.ExportInfo[j])
                    {
                        exportCostM[j] += Convert.ToInt32(r["금액"].ToString()); //계정별 지출 금액
                        iTotalMExport += Convert.ToInt32(r["금액"].ToString()); //당월 총 지출 금액
                    }
                }
            }
        }
        iTotalAccount = iTotalImport - iTotalExport; //총 금액 = 총 수입 내역 - 총 지출 내역
    }
    //화면에 보여질 때의 String Format 지정
    txtTotalAccount.Text = iTotalAccount.ToString("###,##0");
    txtTotalImport.Text = iTotalImport.ToString("###,##0");
    txtTotalExport.Text = iTotalExport.ToString("###,##0");
    txtMImport.Text = iTotalMImport.ToString("###,##0");
    txtMExport.Text = iTotalMExport.ToString("###,##0");
 
    foreach (DataRow r in Config.books.Tables[0].Rows) //가계부 내역 전체
    {
        for (int i = 0; i < Config.AccountName.Length; i++//계좌별 잔액 SUM
        {
            //계좌이동의 경우 돈이 입출금구분 계좌 -> 입출금기준 계좌 로 이동 
            if (r["입출금구분"].ToString() == Config.AccountName[i])
            {
                if (r["구분"].ToString() == "계좌이동") accountCost[i] -= Convert.ToInt32(r["금액"].ToString());
                else if (r["구분"].ToString() == "신카출금") accountCost[i] -= Convert.ToInt32(r["금액"].ToString());
            }
            else if (r["입출금기준"].ToString() == Config.AccountName[i] || r["입출금기준"].ToString() == Config.ConnectCard[i])
            {
                if (r["구분"].ToString() == "수입") accountCost[i] += Convert.ToInt32(r["금액"].ToString());
                else if (r["구분"].ToString() == "지출") accountCost[i] -= Convert.ToInt32(r["금액"].ToString());
                else if (r["구분"].ToString() == "계좌이동") accountCost[i] += Convert.ToInt32(r["금액"].ToString());
                else if (r["구분"].ToString() == "신카출금") accountCost[i] -= Convert.ToInt32(r["금액"].ToString());
            }
        }
    }
    iTotalAccount = 0;
    for (int i = 0; i < accountCost.Length; i++//계좌별 최초잔액 SUM
    {
        accountCost[i] += Convert.ToInt32(Config.accountds.Tables[0].Rows[i]["최초잔액"]);
        iTotalAccount += accountCost[i];
    }
    txtTotal.Text = iTotalAccount.ToString("###,##0");
 
    //당월 계정별 수입 테이블 생성 (컬럼 2개 추가)
    Config.importdt = new DataTable("importdt");
    Config.importdt.Columns.Add("계정");
    Config.importdt.Columns.Add("금액");
    Config.importdt.Columns[1].DataType = typeof(Int32);
    DataRow imdr;
    for (int i = 0; i < Config.ImportInfo.Length; i++)
    {
        imdr = Config.importdt.NewRow(); //NewRow 사용
        imdr["계정"= Config.ImportInfo[i]; //수입 계정 정보 추가
        imdr["금액"= importCostM[i]; //위에서 SUM 했던 계정별 수입 금액
        Config.importdt.Rows.Add(imdr);
    }
    dvImportList.DataSource = Config.importdt; //셍성한 테이블 DataSource 바인딩
    dvImportList.Columns[1].DefaultCellStyle.Format = "###,##0";
    dvImportList.Columns[1].DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight;
 
    //당월 계정별 지출 테이블 생성 (컬럼 2개 추가)
    Config.exportdt = new DataTable("exportdt");
    Config.exportdt.Columns.Add("계정");
    Config.exportdt.Columns.Add("금액");
    Config.exportdt.Columns[1].DataType = typeof(Int32);
    DataRow exdr;
    for (int i = 0; i < Config.ExportInfo.Length; i++)
    {
        exdr = Config.exportdt.NewRow(); //NewRow 사용
        exdr["계정"= Config.ExportInfo[i]; //지출 계정 정보 추가
        exdr["금액"= exportCostM[i]; //위에서 SUM 했던 계정별 지출 금액
        Config.exportdt.Rows.Add(exdr);
    }
    dvExportList.DataSource = Config.exportdt; //생성한 테이블 DataSource 바인딩
    dvExportList.Columns[1].DefaultCellStyle.Format = "###,##0";
    dvExportList.Columns[1].DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight;
 
    //전체 계좌별 잔액 조회 테이블 생성 (컬럼 3개 추가)
    Config.totaldt = new DataTable("exportdt");
    Config.totaldt.Columns.Add("계좌");
    Config.totaldt.Columns.Add("은행");
    Config.totaldt.Columns.Add("금액");
    Config.totaldt.Columns[2].DataType = typeof(Int32);
    DataRow accountdr;
    for (int i = 0; i < Config.AccountName.Length; i++)
    {
        accountdr = Config.totaldt.NewRow(); //NewRow 사용
        accountdr["계좌"= Config.AccountName[i]; //계좌 정보 추가 
        accountdr["은행"= Config.accountds.Tables[0].Rows[i]["은행명"]; //계좌별 은행 이름 추가
        accountdr["금액"= accountCost[i]; //위에서 SUM 했던 계좌별 금액
        Config.totaldt.Rows.Add(accountdr);
    }
    dvAccountList.DataSource = Config.totaldt; //생성한 테이블 DataSource 바인딩
    dvAccountList.Columns[2].DefaultCellStyle.Format = "###,##0";
    dvAccountList.Columns[2].DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight;
}
 
cs

 

++ 당월 가계부 내역인지 아닌지를 파악하기 위해 string.Contains("") 사용했습니다.

date.Contains($"{today.Year}-{today.Month.ToString("00")}-")

 

++ 전에는 DB에서 쿼리로 Select 내용을 바로 DataSet, DataTable 넣었는데, 이번에는 계정별, 계좌별 금액을 합계로 계산하고 DataTable 넣기 위해서 DataTable 따로 생성 해줘야 했습니다.

Table 이름넣고 객체 생성 다음에 Column 추가하고, NewRow 로 Row 추가해줬습니다.

1
2
3
4
5
6
7
8
9
10
11
12
    Config.importdt.Columns.Add("계정");
    Config.importdt.Columns.Add("금액");
    Config.importdt.Columns[1].DataType = typeof(Int32);
    DataRow imdr;
    for (int i = 0; i < Config.ImportInfo.Length; i++)
    {
        imdr = Config.importdt.NewRow(); //NewRow 사용
        imdr["계정"= Config.ImportInfo[i]; //수입 계정 정보 추가
        imdr["금액"= importCostM[i]; //위에서 SUM 했던 계정별 수입 금액
        Config.importdt.Rows.Add(imdr);
    }
    dvImportList.DataSource = Config.importdt; //셍성한 테이블 DataSource 바인딩
cs

 

++ 추가로, 아래에 DB 쿼리 이용해서 데이터 바인딩 했을 때의 쿼리 코드 2개를 첨부했습니다.

주요한 쿼리로는

SUM(IF(조건문, True일 때, False일 때)),

SUM(CASE WHEN 조건문 THEN True일 때),

LIKE '%-비교String-%'있습니다.

1
2
3
4
5
6
7
8
9
10
11
12
string str = $"account as a, sum(if(use_type='수입', use_cost, 0)) as b";
DataSet ds = _db.SelectDetail(Config.Tables[(int)Config.eTName._book], str, 
    $"where account='{Config.ImportInfo[i].ToString()}'" +
    $" AND use_date like '%-{DateTime.Now.Month.ToString("00")}-%'"); //This Month Import
 
string str = $"ie_standard as a, ie_type as b, sum(case use_type when '수입' then +use_cost " + 
    "when '계좌이동' then +use_cost when '지출' then -use_cost end) as c";
DataSet ds = _db.SelectDetail(Config.Tables[(int)Config.eTName._book], str, 
    $"where ie_standard='{Config.AccountName[i].ToString()}' or ie_standard='{Config.ConnectCard[i].ToString()}'");
string str2 = $"sum(case use_type when '계좌이동' then +use_cost when '신카출금' then +use_cost end) as c";
DataSet ds2 = _db.SelectDetail(Config.Tables[(int)Config.eTName._book], str2, 
    $"where ie_type='{Config.AccountName[i].ToString()}'");
cs

 

마지막으로, Form_Load 이벤트 이외에도 가계부 내역 입력 시에나 변경 Main 화면에 Update 필요할 때도 InitMain() 호출해주면 금액이 들어오고 나오는 내용을 화면에 반영시킬 있습니다.


신용카드 사용 금액도 따로 계산해서 당월 출금일에 얼마가 빠져나갈지 확인하는 기능도 추가했고,

사용자 로그인 기능, 사용자 생성 수정 기능도 추가했으나 처음 언급한데로 기본적인 내용만 쓰기로 했기 때문에 가계부 프로그램 만들기는 여기까지 포스팅을 끝내겠습니다 ㅎㅎ

다들 따라하셔서 가계부 프로그램으로 사용했으면 좋겠네요 : )

저는 그럼 사용 동영상을 마지막으로 포스팅 마치겠습니다! 고생했다 나자신!

(동영상에 콤보박스 내용이나, 폼이 뜨는 화면은 안 나오는 점 참고 바랍니다)

BYE!

728x90
반응형