반응형

안녕하세요

 

코딩 연습생 입니다

 

이전 포스팅에서 직접 엑셀의 API를 활용하여 엑셀파일의 내용을 불러와 데이터그리드뷰와 연동하는 포스팅을

 

업로드했었는데요

 

https://codingman.tistory.com/100

 

[C#] 엑셀 템플릿파일 불러오기 및 값 넣기

안녕하세요 코딩 연습생입니다 아직도 코로나19로 인해서 기업들 소상인 분들 모두 참 어렵게 지내고 계시는거 같습니다 저 또한 회사원으로 회사가 많이 힘들어 지고 있다고 체감할 정도니깐요 그래도 국가에서..

codingman.tistory.com

 

이전 포스팅 방식으로 직접 구현을 해보신 분이나 관련 내용을 아시는분들이라면 아실것 같은데요

 

위의 방법으로 구현했을시(직접 엑셀을 임포트하는 방식) 제일 큰 단점은 대량을 엑셀 파일을 읽을때

 

엄청 느리다는것 입니다

 

그것을 조금이나마 해결하고자 엑셀의 문서 속성을 변경하여 이용하는데

 

https://codingman.tistory.com/101

 

[C#] 엑셀 Cells 사용시 속도 문제 해결하기

안녕하세요. 코딩연습생입니다. 정말 오랜만에 글을 쓰는거 같습니다.. 회사 프로젝트 진행 때문에 시간을 너무 빼앗겨 버리네요ㅎㅎ 근데 저도 이제 블로거가 다 된거 같습니다 하루에도 몇번씩 포스팅 걱정을 하..

codingman.tistory.com

 

이것도 전에 포스팅했었네요ㅎㅎ 근데 이 방법도 미미한 차이일뿐 사용자는 크게 느끼지 못합니다

 

그래서 이번에 포스팅할 내용은 직접 엑셀을 임포는하는 방식이 아닌 OleDbConnection을 이용한 엑셀 연동 방식으로

 

구현을 해볼려고 합니다

 

아마 이미 정보가 많이 있어서 한번쯤 구현을 해보시지 않았을까 싶은데요

 

하나씩 쉽게 이해할수 있도록 순서대로 포스팅해보도록 할께요

 

첫번재는 해당 From에서 OleDb를 사용하기 위한 선언부 입니다

 

아마 닷넷 4버전 이상을 사용하시는분이라면 기본적으로 포함되어 있을건데

 

혹시 프로젝트의 참조부분에 System.Data가 있는지 확인한 후에 없으시면 참조추가를 사용해서 추가해 줍니다

 

 

그리고 From의 제일 상단위에 다음과 같이 선언을 합니다

 

using System.Data.OleDb;

 

사실 윈도우에서 기본 사용이 가능해야 하는데 오류가 발생을 많이 합니다

 

그래서 사전 배포를 용이하게 하기 위해서 몇가지 설치 파일을 설치 해야합니다

 

해당 패키지를 설치 하지 않고 배포 하시면

 

"Microsoft.ACE.OLEDB.12.0 공급자는 로컬 컴퓨터에 등록할 수 없습니다.(System.Data)"

위와 같은 오류를 경험하게 되십니다ㅎㅎ

 

저와 같은 경험을 하지 않게 해드리기 위해서 미리 패키지 설치까지 합니다

 

http://www.microsoft.com/ko-kr/download/details.aspx?id=13255

 

Microsoft Access Database Engine 2010 재배포 가능 패키지

이 다운로드를 실행하면 2010 Microsoft Office System 파일과 Microsoft Office가 아닌 다른 응용 프로그램 사이에서 데이터를 쉽게 전송할 수 있는 구성 요소 집합이 설치됩니다.

www.microsoft.com

위의 주소로 접속해서 32비트 & 64비트 설치 파일을 모두 설치 해주세요

 

그다음 비쥬얼스튜디오로 돌아와서 From에 버튼을 하나 생성해 줍니다

 

저는 기존 소스를 이용하겠습니다

 

 

이렇게 버튼을 하나 준비해 주시구요

 

버튼의 Click 이벤트를 만들어 주세요

 

만드신 이벤트안에 아래의 소스코드를 만들어 줍니다

 

private void hoverGradientButton10_Click(object sender, EventArgs e)
        {
            OpenFileDialog openFileDialog = new OpenFileDialog();
            openFileDialog.Title = "엑셀 파일 선택하세요";
            openFileDialog.Filter = "Excel Files|*.xls;*.xlsx;*.xlsm";
            DialogResult result = openFileDialog.ShowDialog();

            if (result == DialogResult.OK)
            {
                SubForms.SplashWnd.SplashShow();

                this.Cursor = Cursors.WaitCursor;
                //엑셀 앱
                Excel.Application app = new Excel.Application();
                app.DisplayAlerts = false;
                app.Visible = false;
                app.ScreenUpdating = false;
                app.DisplayStatusBar = false;
                app.EnableEvents = false;

                Excel.Workbooks workbooks = app.Workbooks;

                //엑셀 워크북(파일경로읽어서)
                //Excel.Workbook workbook = workbooks.Open(openFileDialog.FileName);
                Excel.Workbook workbook = workbooks.Open(openFileDialog.FileName, 0, true, 5, "", "", true, Excel.XlPlatform.xlWindows, "\t", false, false, 0, true, 1, 0);
                // 엑셀 워크싯 객체
                Excel.Sheets sheets = workbook.Worksheets;
                Excel.Worksheet worksheet = (Excel.Worksheet)sheets.get_Item(1);

                // 엑셀파일 이름이 나온다
                string excelFileName = workbook.Name;
                //excelFileName = excelFileName.Substring(book.Name.Length-3);
                string[] str = excelFileName.Split('.');
                // 워크시트 첫번째 이름
                string workSheetName = worksheet.Name;

                try
                {
                    if (str[1].Equals("xls"))
                    {
                        // 연결 string
                        string constr = "provider=Microsoft.Jet.OLEDB.4.0;Data Source='"
                      + openFileDialog.FileName + "';Extended Properties=Excel 8.0;";

                        //경로까지 다 포함해서 .xls라고 뜨네;
                        //MessageBox.Show(openFileDialog.FileName);

                        // excel conn
                        OleDbConnection conn = new OleDbConnection(constr);

                        // excel cmd
                        OleDbCommand cmd = new OleDbCommand("SELECT * FROM [" + workSheetName + "$]", conn);
                        conn.Open();

                        OleDbDataAdapter sda = new OleDbDataAdapter(cmd);
                        DataTable dt = new DataTable();
                        sda.Fill(dt);
                        this.Cursor = Cursors.WaitCursor;
                        dataGridView1.DataSource = dt;
                        this.Cursor = Cursors.Default;
                        conn.Close();


                    }
                    else if (str[1].Equals("xlsx"))
                    {
                        // 연결 string
                        String constr = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" +
                        openFileDialog.FileName +
                        ";Extended Properties='Excel 12.0 XML;HDR=No;IMEX=1';";

                        //경로까지 다 포함해서 .xls라고 뜨네;
                        //MessageBox.Show(openFileDialog.FileName);

                        // excel conn
                        OleDbConnection conn = new OleDbConnection(constr);

                        // excel cmd
                        OleDbCommand cmd = new OleDbCommand("SELECT * FROM [" + workSheetName + "$]", conn);
                        conn.Open();

                        OleDbDataAdapter sda = new OleDbDataAdapter(cmd);
                        DataTable dt = new DataTable();
                        sda.Fill(dt);

                        int j = 0;
                        //dataGridView1.DataSource = dt;
                        for(int i=6; i<=dt.Rows.Count-1; i++)
                        {
                            
                            dataGridView2.Rows.Add(1);
                            dataGridView2.Rows[j].Cells[0].Value = dt.Rows[i][0].ToString();
                            dataGridView2.Rows[j].Cells[1].Value = dt.Rows[i][2].ToString();
                            dataGridView2.Rows[j].Cells[2].Value = dt.Rows[i][4].ToString();
                            dataGridView2.Rows[j].Cells[3].Value = dt.Rows[i][5].ToString();
                            dataGridView2.Rows[j].Cells[4].Value = dt.Rows[i][6].ToString();
                            dataGridView2.Rows[j].Cells[5].Value = dt.Rows[i][7].ToString();
                            dataGridView2.Rows[j].Cells[6].Value = dt.Rows[i][8].ToString();
                            dataGridView2.Rows[j].Cells[7].Value = dt.Rows[i][9].ToString();
                            dataGridView2.Rows[j].Cells[8].Value = dt.Rows[i][10].ToString();
                            dataGridView2.Rows[j].Cells[9].Value = dt.Rows[i][11].ToString();
                            dataGridView2.Rows[j].Cells[10].Value = dt.Rows[i][12].ToString();
                            dataGridView2.Rows[j].Cells[11].Value = dt.Rows[i][13].ToString();
                            dataGridView2.Rows[j].Cells[12].Value = dt.Rows[i][14].ToString();
                            dataGridView2.Rows[j].Cells[13].Value = dt.Rows[i][15].ToString();
                            dataGridView2.Rows[j].Cells[14].Value = dt.Rows[i][16].ToString();
                            dataGridView2.Rows[j].Cells[15].Value = dt.Rows[i][17].ToString();
                            dataGridView2.Rows[j].Cells[16].Value = dt.Rows[i][18].ToString();
                            dataGridView2.Rows[j].Cells[17].Value = dt.Rows[i][19].ToString();
                            dataGridView2.Rows[j].Cells[18].Value = dt.Rows[i][20].ToString();
                            dataGridView2.Rows[j].Cells[19].Value = dt.Rows[i][21].ToString();
                            dataGridView2.Rows[j].Cells[20].Value = dt.Rows[i][22].ToString();
                            dataGridView2.Rows[j].Cells[21].Value = dt.Rows[i][23].ToString();
                            dataGridView2.Rows[j].Cells[22].Value = dt.Rows[i][24].ToString();
                            dataGridView2.Rows[j].Cells[23].Value = dt.Rows[i][25].ToString();
                            dataGridView2.Rows[j].Cells[24].Value = dt.Rows[i][26].ToString();
                            dataGridView2.Rows[j].Cells[25].Value = dt.Rows[i][27].ToString();
                            dataGridView2.Rows[j].Cells[26].Value = dt.Rows[i][28].ToString();
                            dataGridView2.Rows[j].Cells[27].Value = dt.Rows[i][29].ToString();
                            dataGridView2.Rows[j].Cells[28].Value = dt.Rows[i][30].ToString();
                            dataGridView2.Rows[j].Cells[29].Value = dt.Rows[i][31].ToString();
                            dataGridView2.Rows[j].Cells[30].Value = dt.Rows[i][32].ToString();
                            dataGridView2.Rows[j].Cells[31].Value = dt.Rows[i][33].ToString();
                            dataGridView2.Rows[j].Cells[32].Value = dt.Rows[i][34].ToString();
                            dataGridView2.Rows[j].Cells[33].Value = dt.Rows[i][35].ToString();
                            dataGridView2.Rows[j].Cells[34].Value = dt.Rows[i][36].ToString();
                            dataGridView2.Rows[j].Cells[35].Value = dt.Rows[i][37].ToString();
                            dataGridView2.Rows[j].Cells[36].Value = dt.Rows[i][38].ToString();
                            dataGridView2.Rows[j].Cells[37].Value = dt.Rows[i][39].ToString();
                            dataGridView2.Rows[j].Cells[38].Value = dt.Rows[i][40].ToString();
                            dataGridView2.Rows[j].Cells[39].Value = dt.Rows[i][41].ToString();
                            dataGridView2.Rows[j].Cells[40].Value = dt.Rows[i][42].ToString();
                            dataGridView2.Rows[j].Cells[41].Value = dt.Rows[i][43].ToString();
                            dataGridView2.Rows[j].Cells[42].Value = dt.Rows[i][44].ToString();
                            dataGridView2.Rows[j].Cells[43].Value = dt.Rows[i][45].ToString();
                            dataGridView2.Rows[j].Cells[44].Value = dt.Rows[i][46].ToString();
                            dataGridView2.Rows[j].Cells[45].Value = dt.Rows[i][47].ToString();
                            dataGridView2.Rows[j].Cells[46].Value = dt.Rows[i][48].ToString();
                            dataGridView2.Rows[j].Cells[47].Value = dt.Rows[i][49].ToString();
                            dataGridView2.Rows[j].Cells[48].Value = dt.Rows[i][50].ToString();
                            dataGridView2.Rows[j].Cells[49].Value = dt.Rows[i][51].ToString();
                            dataGridView2.Rows[j].Cells[50].Value = dt.Rows[i][52].ToString();
                            dataGridView2.Rows[j].Cells[51].Value = dt.Rows[i][53].ToString();
                            dataGridView2.Rows[j].Cells[52].Value = dt.Rows[i][54].ToString();
                            dataGridView2.Rows[j].Cells[53].Value = dt.Rows[i][55].ToString();
                            dataGridView2.Rows[j].Cells[54].Value = dt.Rows[i][56].ToString();
                            dataGridView2.Rows[j].Cells[55].Value = dt.Rows[i][57].ToString();
                            dataGridView2.Rows[j].Cells[56].Value = dt.Rows[i][58].ToString();
                            dataGridView2.Rows[j].Cells[57].Value = dt.Rows[i][59].ToString();
                            dataGridView2.Rows[j].Cells[58].Value = dt.Rows[i][60].ToString();
                            dataGridView2.Rows[j].Cells[59].Value = dt.Rows[i][61].ToString();
                            dataGridView2.Rows[j].Cells[60].Value = dt.Rows[i][62].ToString();
                            dataGridView2.Rows[j].Cells[61].Value = dt.Rows[i][63].ToString();
                            dataGridView2.Rows[j].Cells[62].Value = dt.Rows[i][64].ToString();
                            dataGridView2.Rows[j].Cells[63].Value = dt.Rows[i][65].ToString();
                            dataGridView2.Rows[j].Cells[64].Value = dt.Rows[i][66].ToString();
                            dataGridView2.Rows[j].Cells[65].Value = dt.Rows[i][67].ToString();
                            dataGridView2.Rows[j].Cells[66].Value = dt.Rows[i][68].ToString();
                            dataGridView2.Rows[j].Cells[67].Value = dt.Rows[i][69].ToString();
                            dataGridView2.Rows[j].Cells[68].Value = dt.Rows[i][70].ToString();
                            dataGridView2.Rows[j].Cells[69].Value = dt.Rows[i][71].ToString();
                            dataGridView2.Rows[j].Cells[70].Value = dt.Rows[i][72].ToString();
                            dataGridView2.Rows[j].Cells[71].Value = dt.Rows[i][73].ToString();
                            dataGridView2.Rows[j].Cells[72].Value = dt.Rows[i][74].ToString();
                            dataGridView2.Rows[j].Cells[73].Value = dt.Rows[i][75].ToString();
                            dataGridView2.Rows[j].Cells[74].Value = dt.Rows[i][76].ToString();
                            dataGridView2.Rows[j].Cells[75].Value = dt.Rows[i][77].ToString();
                            dataGridView2.Rows[j].Cells[76].Value = dt.Rows[i][78].ToString();
                            dataGridView2.Rows[j].Cells[77].Value = dt.Rows[i][79].ToString();
                            dataGridView2.Rows[j].Cells[78].Value = dt.Rows[i][80].ToString();
                            dataGridView2.Rows[j].Cells[79].Value = dt.Rows[i][81].ToString();
                            dataGridView2.Rows[j].Cells[80].Value = dt.Rows[i][82].ToString();
                            dataGridView2.Rows[j].Cells[81].Value = dt.Rows[i][83].ToString();
                            
                            j++;
                        }

                        this.Cursor = Cursors.Default;
                        conn.Close();

                        Finish_Data_Insert();
                        SubForms.SplashWnd.SplashClose(this);
                    }
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.ToString());
                    workbook.Close(true, null, null);
                    app.Quit();

                    ReleaseExcelObject(worksheet);
                    ReleaseExcelObject(sheets);
                    ReleaseExcelObject(workbook);
                    ReleaseExcelObject(workbooks);
                    ReleaseExcelObject(app);
                }
                finally
                {
                    workbook.Close(true, null, null);
                    app.Quit();

                    ReleaseExcelObject(worksheet);
                    ReleaseExcelObject(sheets);
                    ReleaseExcelObject(workbook);
                    ReleaseExcelObject(workbooks);
                    ReleaseExcelObject(app);
                }
            }
        }

 

오브젝트 초기화를 위해 아래 함수로 하나 작성해 줍니다

 

private void ReleaseExcelObject(object obj)
        {
            try
            {
                if (obj != null)
                {
                    Marshal.ReleaseComObject(obj);
                    obj = null;
                }
            }
            catch (Exception ex)
            {
                obj = null;
                throw ex;
            }
            finally
            {
                GC.Collect();
            }
        }

 

이렇게 해주시고 생성하신 버튼을 누구게 되면 OpenFileDialog가 열리고 거기서 엑셀 파일을 선택해 주시면

 

해당 엑셀의 문서 내용이 데이터그리드뷰에 옴겨지게 됩니다

 

위의 소스 내용중 "SubForms.SplashWnd.SplashShow();" 구문은 주석 또는 삭제 하셔도 무관합니다

 

해당 코드는 사용자에게 진행중을 표시하기 위한 ProgressBar를 구현한것인데 없어도 구동하는데 전혀 문제가 없습니다

 

해당 내용은 다른 포스팅에서 정리해서 올리도록 할께요

 

이전 방식과 현재의 방식을 모두 구현을 하셨다면 속도 비교를 해보시면 깜짝 놀라실수 있을겁니다

 

동일 엑셀 문서기준 (대략 Row가 1000개)의 파일을 불러오기 하였을때

 

기존방식 : 10~15분 소요

현재방식 : 30초 미만

 

엄청난 차이를 보여주더라구요

 

엑셀과 연동을 구현하기 위해 고민중이시라면 위의 방법을 통해 구현해 보시길 바랍니다

반응형
반응형

안녕하세요

 

코딩연습생입니다

 

이번 시간에 포스팅하고자 하는건 제목에도 나와 있지만

 

MSSQL을 통해서 C#으로 DataGridView 컨트롤의 컬럼을 동적으로 생성하게 하여

 

한 페이지에서 여러 Data를 조회 할 수 있는 유동적인 DataGirdView를 사용하는 방법을 포스팅 해볼려고 합니다

 

말은 거창한데 결국은 데이터그리드뷰의 속성을 하나씩 설정해서 유동적으로 사용하게 하는 방법입니다

 

첫번째는 조회 타입에 따라 변화 할 그리드뷰의 속성을 MSSQL에서 프로시져로 지정 합니다

 

IF @GUBUN = 'COL_CNT_MANDO'
		BEGIN
			SELECT 37 AS CNT    --전체 컬럼 출력수
		END
		
		IF @GUBUN = 'COL_CNT_ETC'
		BEGIN
			SELECT 22 AS CNT    --전체 컬럼 출력수
		END


		IF @GUBUN = 'COL_NAD_MANDO'
		BEGIN
			SELECT '고객코드' AS COL_NM
			UNION ALL
			SELECT '고객명' AS COL_NM
			UNION ALL
			SELECT 'ERP 품번' AS COL_NM
			UNION ALL
			SELECT '거래선 도번' AS COL_NM
			UNION ALL
			SELECT '납품처코드' AS COL_NM
			UNION ALL
			SELECT '납품처명' AS COL_NM
			UNION ALL
			SELECT '차종명' AS COL_NM
			UNION ALL
			SELECT '*D+0(주간)' AS COL_NM
			UNION ALL
			SELECT '*D+0(야간)' AS COL_NM
			UNION ALL
			SELECT '*D+1(주간)' AS COL_NM
			UNION ALL
			SELECT '*D+1(야간)' AS COL_NM
			UNION ALL
			SELECT '*D+2(주간)' AS COL_NM
			UNION ALL
			SELECT '*D+2(야간)' AS COL_NM
			UNION ALL
			SELECT '*D+3(주간)' AS COL_NM
			UNION ALL
			SELECT '*D+3(야간)' AS COL_NM
			UNION ALL
			SELECT '*D+4(주간)' AS COL_NM
			UNION ALL
			SELECT '*D+4(야간)' AS COL_NM
			UNION ALL
			SELECT '*D+5(주간)' AS COL_NM
			UNION ALL
			SELECT '*D+5(야간)' AS COL_NM
			UNION ALL
			SELECT '*D+6(주간)' AS COL_NM
			UNION ALL
			SELECT '*D+6(야간)' AS COL_NM
			UNION ALL
			SELECT '*D+7(주간)' AS COL_NM
			UNION ALL
			SELECT '*D+7(야간)' AS COL_NM
			UNION ALL
			SELECT '*D+8(주간)' AS COL_NM
			UNION ALL
			SELECT '*D+8(야간)' AS COL_NM
			UNION ALL
			SELECT '*D+9(주간)' AS COL_NM
			UNION ALL
			SELECT '*D+9(야간)' AS COL_NM
			UNION ALL
			SELECT '*D+10(주간)' AS COL_NM
			UNION ALL
			SELECT '*D+10(야간)' AS COL_NM
			UNION ALL
			SELECT '*D+11(주간)' AS COL_NM
			UNION ALL
			SELECT '*D+11(야간)' AS COL_NM
			UNION ALL
			SELECT '*D+12(주간)' AS COL_NM
			UNION ALL
			SELECT '*D+12(야간)' AS COL_NM
			UNION ALL
			SELECT '*D+13(주간)' AS COL_NM
			UNION ALL
			SELECT '*D+13(야간)' AS COL_NM
		END

		IF @GUBUN = 'COL_NAD_ETC'
		BEGIN
			SELECT '고객코드' AS COL_NM
			UNION ALL
			SELECT '고객명' AS COL_NM
			UNION ALL
			SELECT 'ERP 품번' AS COL_NM
			UNION ALL
			SELECT '거래선 도번' AS COL_NM
			UNION ALL
			SELECT '납품처코드' AS COL_NM
			UNION ALL
			SELECT '납품처명' AS COL_NM
			UNION ALL
			SELECT '차종명' AS COL_NM
			UNION ALL
			SELECT '*D+0' AS COL_NM
			UNION ALL
			SELECT '*D+1' AS COL_NM
			UNION ALL
			SELECT '*D+2' AS COL_NM
			UNION ALL
			SELECT '*D+3' AS COL_NM
			UNION ALL
			SELECT '*D+4' AS COL_NM
			UNION ALL
			SELECT '*D+5' AS COL_NM
			UNION ALL
			SELECT '*D+6' AS COL_NM
			UNION ALL
			SELECT '*D+7' AS COL_NM
			UNION ALL
			SELECT '*D+8' AS COL_NM
			UNION ALL
			SELECT '*D+9' AS COL_NM
			UNION ALL
			SELECT '*D+10' AS COL_NM
			UNION ALL
			SELECT '*D+11' AS COL_NM
			UNION ALL
			SELECT '*D+12' AS COL_NM
			UNION ALL
			SELECT '*D+13' AS COL_NM
		END

위의 쿼리내용을 보게 되면 미리 타입에 따라 컬럼 갯수와 컬럼명칭을 설정해서 가져오기 위한 쿼리 입니다

 

유동적인 그리드뷰를 적용시킬 윈폼 페이지 안에 아래와 같이 코딩을 합니다

 

private void Grid_Column()
        {
            this.Cursor = Cursors.WaitCursor;   //마우스 커서를 Waitting

            dataGridView1.Rows.Clear();  //그리드뷰 초기화
            dataGridView1.Columns.Clear(); //

            string query = "";
            if (radioButton1.Checked == true)
            {
                query += "EXEC SP_SHIP_CUST_PLAN ";
                query += "     'COL_CNT_MANDO'";
                query += "    ,''";
                query += "    ,''";
                query += "    ,''";
                query += "    ,''";
                query += "    ,''";
                query += "    ,''";
                query += "    ,''";
                query += "    ,''";
                query += "    ,''";
                query += "    ,''";
                query += "    ,''";
                query += "    ,''";
                query += "    ,''";
                query += "    ,''";
                query += "    ,''";
                query += "    ,''";
                query += "    ,''";
                query += "    ,''";
                query += "    ,''";
                query += "    ,''";
                query += "    ,''";
                query += "    ,''";
                query += "    ,''";
                query += "    ,''";
                query += "    ,''";
                query += "    ,''";
                query += "    ,''";
                query += "    ,''";
                query += "    ,''";
                query += "    ,''";
                query += "    ,''";
                query += "    ,''";
                query += "    ,''";
                query += "    ,''";
                query += "    ,''";

            }
            else
            {
                query += "EXEC SP_SHIP_CUST_PLAN ";
                query += "     'COL_CNT_ETC'";
                query += "    ,''";
                query += "    ,''";
                query += "    ,''";
                query += "    ,''";
                query += "    ,''";
                query += "    ,''";
                query += "    ,''";
                query += "    ,''";
                query += "    ,''";
                query += "    ,''";
                query += "    ,''";
                query += "    ,''";
                query += "    ,''";
                query += "    ,''";
                query += "    ,''";
                query += "    ,''";
                query += "    ,''";
                query += "    ,''";
                query += "    ,''";
                query += "    ,''";
                query += "    ,''";
                query += "    ,''";
                query += "    ,''";
                query += "    ,''";
                query += "    ,''";
                query += "    ,''";
                query += "    ,''";
                query += "    ,''";
                query += "    ,''";
                query += "    ,''";
                query += "    ,''";
                query += "    ,''";
                query += "    ,''";
                query += "    ,''";
                query += "    ,''";
            }
            
            
            //MSSQL 프로바이더
            DB db = new DB();
            DataTable dt = db.ExcuteQuery(query);

            //datatable의 내용을 그리드에 display
            foreach (DataRow row in dt.Rows)
            {
                dataGridView1.ColumnCount = Convert.ToInt32(row[0].ToString());
            }

            dt.Clear();


            query = "";
            if (radioButton1.Checked == true)
            {
                query += "EXEC SP_SHIP_CUST_PLAN ";
                query += "     'COL_NAD_MANDO'";
                query += "    ,''";
                query += "    ,''";
                query += "    ,''";
                query += "    ,''";
                query += "    ,''";
                query += "    ,''";
                query += "    ,''";
                query += "    ,''";
                query += "    ,''";
                query += "    ,''";
                query += "    ,''";
                query += "    ,''";
                query += "    ,''";
                query += "    ,''";
                query += "    ,''";
                query += "    ,''";
                query += "    ,''";
                query += "    ,''";
                query += "    ,''";
                query += "    ,''";
                query += "    ,''";
                query += "    ,''";
                query += "    ,''";
                query += "    ,''";
                query += "    ,''";
                query += "    ,''";
                query += "    ,''";
                query += "    ,''";
                query += "    ,''";
                query += "    ,''";
                query += "    ,''";
                query += "    ,''";
                query += "    ,''";
                query += "    ,''";
                query += "    ,''";
            }
            else
            {
                query += "EXEC SP_SHIP_CUST_PLAN ";
                query += "     'COL_NAD_ETC'";
                query += "    ,''";
                query += "    ,''";
                query += "    ,''";
                query += "    ,''";
                query += "    ,''";
                query += "    ,''";
                query += "    ,''";
                query += "    ,''";
                query += "    ,''";
                query += "    ,''";
                query += "    ,''";
                query += "    ,''";
                query += "    ,''";
                query += "    ,''";
                query += "    ,''";
                query += "    ,''";
                query += "    ,''";
                query += "    ,''";
                query += "    ,''";
                query += "    ,''";
                query += "    ,''";
                query += "    ,''";
                query += "    ,''";
                query += "    ,''";
                query += "    ,''";
                query += "    ,''";
                query += "    ,''";
                query += "    ,''";
                query += "    ,''";
                query += "    ,''";
                query += "    ,''";
                query += "    ,''";
                query += "    ,''";
                query += "    ,''";
                query += "    ,''";
            }
            dt = db.ExcuteQuery(query);

            int i = 0;

            //datatable의 내용을 그리드에 display
            foreach (DataRow row in dt.Rows)
            {
                dataGridView1.Columns[i].Name = row["COL_NM"].ToString();
                //sGridView1.Columns[i].SortMode = DataGridViewColumnSortMode.NotSortable;

                //숫자컬럼은 앞에*를 붙였기때문에 숫자컬럼은 모두 오른쪽 정렬을 취함
                if (row["COL_NM"].ToString().Substring(0, 1) == "*")
                {
                    dataGridView1.Columns[i].DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight;  //우측정렬
                }
                //문자열은 좌측정렬구분자를 공백으로 처리
                else if (row["COL_NM"].ToString().Substring(0, 1) == " ")
                {
                    dataGridView1.Columns[i].DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleLeft;  //좌측정렬
                }
                else
                {
                    dataGridView1.Columns[i].DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter;  //가운데정렬
                }

                i++;
            }

            this.Cursor = Cursors.Default;
            dataGridView1.AllowUserToAddRows = false;
        }

 

여기서 MSSQL DB에 접속하기 위한 프로바이더는 별도 함수로 작성해서 사용하였습니다

 

함수 제작하는 방법은 아래 링크 페이지에서 확인 하시기 바랍니다

 

https://codingman.tistory.com/73

 

[C#] MSSQL 접속하고 사용하기

안녕하세요 C# 컨텐츠로 블로그를 운영중인 코딩 연습생입니다 이번 포스팅에서는 C#으로 MSSQL를 접속하고 쿼리문을 전송시켜 연동시키기까지 한번 해보도록 하겠습니다 일반적인 방법으로는 1) 접속정보 생성 2)..

codingman.tistory.com

 

이렇게 타입에 따른 그리드뷰 상세 옵션을 MSSQL에서 불러와서 그리드를 그려준뒤에 각 컬럼에 맞게 뿌려주면 됩니다

 

저는 유동적으로 생성된 그리드뷰에 엑셀파일을 불러오기로 구현하였습니다

 

private void hoverGradientButton3_Click(object sender, EventArgs e)
        {
            OpenFileDialog oFileDialog = new OpenFileDialog();
            oFileDialog.Filter = "Excel (*.xlsx)|*.xlsx|Excel 97-2003 (*.xls)|*.xls";

            if (oFileDialog.ShowDialog() != DialogResult.OK)
            {
                return;
            }

            Excel.Application xlApp;
            Excel.Workbook xlWorkBook;
            Excel.Worksheet xlWorkSheet;
            Excel.Range range;

            string str;
            int rCnt = 0;
            int cCnt = 0;
            string sCellData = "";
            double dCellData;

            xlApp = new Excel.Application();
            xlApp.DisplayAlerts = false;
            xlApp.Visible = false;
            xlApp.ScreenUpdating = false;
            xlApp.DisplayStatusBar = false;
            xlApp.EnableEvents = false;

            SplashWnd.SplashShow();

            try
            {
                xlWorkBook = xlApp.Workbooks.Open(oFileDialog.FileName, 0, true, 5, "", "", true, Excel.XlPlatform.xlWindows, "\t", false, false, 0, true, 1, 0);
                xlWorkSheet = (Excel.Worksheet)xlWorkBook.Worksheets.get_Item(1);

                range = xlWorkSheet.UsedRange;

                DataTable dt = new DataTable();

                // 첫 행을 제목으로
                for (cCnt = 1; cCnt <= range.Columns.Count; cCnt++)
                {
                    str = (string)(range.Cells[1, cCnt] as Excel.Range).Value2;
                    dt.Columns.Add(str, typeof(string));
                }

                for (rCnt = 3; rCnt <= range.Rows.Count; rCnt++)
                {
                    string sData = "";
                    for (cCnt = 1; cCnt <= range.Columns.Count; cCnt++)
                    {
                        try
                        {
                            sCellData = (string)(range.Cells[rCnt, cCnt] as Excel.Range).Value2;
                            sData += sCellData + "|";
                        }
                        catch (Exception ex)
                        {
                            dCellData = (double)(range.Cells[rCnt, cCnt] as Excel.Range).Value2;
                            sData += dCellData.ToString() + "|";
                        }
                    }
                    sData = sData.Remove(sData.Length - 1, 1);
                    dt.Rows.Add(sData.Split('|'));
                }

                int i = 0;

                if (radioButton1.Checked == true)
                {
                    foreach (DataRow row in dt.Rows)
                    {
                        dataGridView1.Rows.Add(1);

                        for (int j=0; j<= 34; j++)
                        {    
                            dataGridView1.Rows[i].Cells[j].Value = dt.DefaultView[i][j].ToString();
                        }
                       
                        i++;
                    }
                }
                else
                {
                    foreach (DataRow row in dt.Rows)
                    {
                        dataGridView1.Rows.Add(1);

                        for (int j = 0; j <= 20; j++)
                        {
                            dataGridView1.Rows[i].Cells[j].Value = dt.DefaultView[i][j].ToString();
                        }


                        i++;
                    }
                }
                
                //dataGridView1.DataSource = dt.DefaultView;

                xlWorkBook.Close(true, null, null);
                xlApp.Quit();

                releaseObject(xlWorkSheet);
                releaseObject(xlWorkBook);
                releaseObject(xlApp);

                SplashWnd.SplashClose(this);

            }
            catch (Exception ex)
            {
                MessageBox.Show("파일 열기 실패! : " + ex.Message);
                return;
            }
        }

        private void releaseObject(object obj)
        {
            try
            {
                System.Runtime.InteropServices.Marshal.ReleaseComObject(obj);
                obj = null;
            }
            catch (Exception ex)
            {
                obj = null;
                MessageBox.Show("Unable to release the Object " + ex.ToString());
            }
            finally
            {
                GC.Collect();
            }
        }

 

이렇게 되면 불러오고자 하는 엑셀 문서의 타입에 따라 데이터그리드뷰를 생성시켜 주고 그 위에 엑셀의 내용을 

 

불러오기 하여 보여질수 있게 됩니다

 

엑셀 양식 불러오기를 사용할때 고객의 종류? 양식의 타입?에 따라 변동이 많을시에 이렇게 데이터그리드뷰를 

 

유동적으로 변화시킬수 있다면 굳이 여러개의 폼을 만들지 않고 하나의 폼에서 처리가 가능하니 조금 사용자 입장에서

 

편리할수 있다고 생각해서 구현해 봤습니다

 

 

반응형
반응형

안녕하세요.

 

코딩연습생입니다.

 

정말 오랜만에 글을 쓰는거 같습니다.. 회사 프로젝트 진행 때문에 시간을 너무 빼앗겨 버리네요ㅎㅎ

 

근데 저도 이제 블로거가 다 된거 같습니다 하루에도 몇번씩 포스팅 걱정을 하고 있는거 보면 약간 전문적인 사람이

 

된거 같은 느낌이 드네요ㅎㅎㅎ

 

저번 시간에 C#으로 엑셀 파일 내보내기 포스팅을 한적이 있는데요

 

https://codingman.tistory.com/100

 

[C#] 엑셀 템플릿파일 불러오기 및 값 넣기

안녕하세요 코딩 연습생입니다 아직도 코로나19로 인해서 기업들 소상인 분들 모두 참 어렵게 지내고 계시는거 같습니다 저 또한 회사원으로 회사가 많이 힘들어 지고 있다고 체감할 정도니깐요 그래도 국가에서..

codingman.tistory.com

 

해당 예제로 구현을 해보신 분들이라면 아마 똑같은 고민을 할거 같은데요

 

Excel.Worksheet.Cells[1,1] 형태로 for문을 돌려 값 쓰기를 진행하면 테스트 결과 100건 까지는 무난합니다

 

300건이 넘거가게 되면 정말 느려지게 되는데요

 

500건 내보내기 실행시 대략 5분까지도 소요가 되네요

 

그래서 검색을 통해 임시방편으로 빠르게 해결할 수 있는 방법을 알려드릴려고 합니다

 

포스팅 내용으 겹쳐서 해당 포스팅에서는 모든 SourceCode 보단 요약 코드로 설명을 하겠습니다

 

아래는 엑셀 템플릿파일 내보내기 코드 일부 입니다

 

                ExcelApp = new Excel.Application();
                wb = ExcelApp.Workbooks.Open(ExcelPath,
                                             0,
                                             true,
                                             5,
                                             "",
                                             "",
                                             true,
                                             Excel.XlPlatform.xlWindows,
                                             "\t",
                                             false,
                                             false,
                                             0,
                                             true,
                                             1,
                                             0);
                ws = wb.Worksheets["Sheet1"] as Excel.Worksheet;

 

이렇게 Sheet1을 불러오고 난 뒤에 Cells 값을 넣기 전에 아래 구문을 추가 합니다

 

ExcelApp.DisplayAlerts = false;
ExcelApp.Visible = false;
ExcelApp.ScreenUpdating = false;
ExcelApp.DisplayStatusBar = false;
ExcelApp.Calculation = Excel.XlCalculation.xlCalculationManual;
ExcelApp.EnableEvents = false;

 

코드 설명은 다음과 같습니다

 

  • 응용 프로그램. 스크린 업데이트

    화면 업데이트를 끕니다. Application.ScreenUpdating 이 False로 설정되어 있으면 Excel에서 화면을 다시 그리지 않습니다. 코드가 실행되는 동안 화면이 빠르게 업데이트되므로 일반적으로 사용자가 각 업데이트를 볼 필요는 없습니다. 코드가 실행 된 후 화면을 한 번 업데이트하면 성능이 향상됩니다.

  • Application.DisplayStatusBar

    상태 표시 줄을 끕니다. Application.DisplayStatusBar 가 False로 설정되어 있으면 Excel에 상태 표시 줄이 표시되지 않습니다. 상태 표시 줄 설정은 화면 업데이트 설정과 별개이므로 화면이 업데이트되지 않는 동안에도 현재 작업 상태를 계속 표시 할 수 있습니다. 그러나 모든 작업의 ​​상태를 표시 할 필요가없는 경우 코드 실행 중에 상태 표시 줄을 끄면 성능도 향상됩니다.

  • 신청. 계산

    수동 계산으로 전환하십시오. Application.Calculation  xlCalculationManual 로 설정되어 xlCalculationManual Excel은 사용자가 명시 적으로 계산을 시작할 때 통합 문서 만 계산합니다. 자동 계산 모드에서 Excel은 계산시기를 결정합니다. 예를 들어 수식과 관련된 셀 값이 변경 될 때마다 Excel은 수식을 다시 계산합니다. 계산 모드를 수동으로 전환하면 통합 문서를 다시 계산하기 전에 수식과 관련된 모든 셀이 업데이트 될 때까지 기다릴 수 있습니다. 코드가 실행되는 동안 필요할 때만 통합 문서를 다시 계산하면 성능을 향상시킬 수 있습니다.

  • Application.EnableEvents

    이벤트를 끕니다. Application.EnableEvents 가 False로 설정되어 있으면 Excel에서 이벤트가 발생하지 않습니다. Excel 이벤트를 수신하는 추가 기능이있는 경우 해당 추가 기능은 이벤트를 기록 할 때 컴퓨터의 리소스를 사용합니다. 추가 기능에서 코드 실행 중 발생하는 이벤트를 기록 할 필요가없는 경우 이벤트를 끄면 성능이 향상됩니다.

  • ActiveSheet.DisplayPageBreaks

    페이지 나누기를 끕니다. ActiveSheet.DisplayPageBreaks 가 False로 설정되어 있으면 Excel에 페이지 나누기가 표시되지 않습니다. 코드가 실행되는 동안 페이지 나누기를 다시 계산할 필요는 없으며 코드가 실행 된 후 페이지 나누기를 계산하면 성능이 향상됩니다.

이렇게 엑셀에 대한 자동 기능을 해제 해줌에 따라 파일생성 시간이 많이 단축됩니다

 

동일한 조건일 경우 500개 생성시 5분 이상이 소요 되었는데

 

이렇게 수정한뒤에 1분만에 생성이 완료되어 집니다

 

예제를 따라 수행하시던 분들을 한번 수정해서 속도 테스트를 해보시기 바랍니다~

반응형
반응형

안녕하세요

 

코딩 연습생입니다

 

아직도 코로나19로 인해서 기업들 소상인 분들 모두 참 어렵게 지내고 계시는거 같습니다

 

저 또한 회사원으로 회사가 많이 힘들어 지고 있다고 체감할 정도니깐요

 

그래도 국가에서 이래저래 도움을 줄 방법을 많이 고민하고 시행할려고 하는거 같은데 어찌 될지는 잘 모르겠네요

 

그래도 저희는 의지에 한국인 아니겠습니까?

 

이 또한 잘 이겨내리라 생각하고 열심히 살아봐야겠죠!?ㅋㅋ

 

블로그를 운영하면서 참 은근히 스트레스를 받네요 빨리 빨리 더 많은 정보를 공유하고 싶은데

 

글하나 쓰기까지 참 시간이 많이 소요 됩니다~ 거기에 회사 일을 하면서 해야 하는지라 쉽지가 않네요

 

평소 인터넷 검색을 통해 많은 블로거 분들의 글을 아무 생각없이 읽어 넘겼었는데 요즘은 참 많은 생각이 듭니다

 

역시 사람을 겪어봐야 느끼는 동물이라는게 새삼 느껴지네요ㅎ

 

예전 포스팅중에 엑셀 파일을 읽어서 그리드뷰에 불러오기하는 포스팅을 올린적이 있는데

 

그거와 유사한 기능을 구현해 볼겁니다

 

https://codingman.tistory.com/11

 

[C#] 엑셀파일 내보내기(그리드뷰)

///

/// 데이타 테이블을 엑셀로 받아온다. //////원본 데이타 테이블. ///원본 데이타 테이블의 컬럼들. ///codingman.tistory.com

 

블로그 초기 운영때 올린 글이라 별다른 설명이 없이 기능 소스만 공개 했었네요ㅎ

 

위의 포스팅과 차이점은 이미 템플릿화된 파일을 프로젝트에 삽입한뒤에 DB의 값을 불러오기하여 엑셀이 뿌려주는

 

겁니다

 

그렇게 되면 엑셀파일에는 항상 최산의 데이터가 자동 삽이된 상태로 사용자가 문서를 열어볼수 있는거죠

 

구현이 어렵지는 않지만 생각의 발상 차이라고 할수 있을거 같습니다

 

첫번째로 프로젝트에 템플릿으로 사용할 엑셀 문서를 포함 시켜 줍니다

 

 

프로젝트명칭은 회사에서 사용되는 시스템을 수정한것이라 혹시 몰라 숨김 처리 하였습니다ㅎㅎ

 

저기에 삽입된 엑셀 문서에는 셀마다 자동 수식이 걸려있는 문서 말그대로 템플릿 파일입니다

 

빈 셀에 DB의 값을 넣어주면 자동으로 수식에 의해 계산이 되겠죠?

 

음...엑셀(템플릿)파일의 내용을 열어서 보여드리고 싶지만 회사정보가 나오기 때문에 생략하겠습니다

 

메인 화면에서 아래와 같이 Excel 내려받기를 실행할 버튼을 생성해 줍니다

 

 

대충 감이 오실겁니다 고객 생상 일정 정보를 토대로 회사내 출하 계획을 생성하는 프로그램을 만들고 있는 화면중에

 

하나입니다ㅎㅎㅎ

 

자 그러면 해당 버튼을 클릭했을때 시행될 이벤트 코드를 생성해야겠지요?

 

Excel 내려받기 버튼의 클릭이벤트를 생성합니다

 

 

생성된 이벤트에 다음과 같이 코딩을 해줍니다

 

private void hoverGradientButton1_Click(object sender, EventArgs e)
        {
            string ExcelPath = Environment.CurrentDirectory + @"\Excel\Shipping_semple.xlsx";
            string ExcelEndPath = Environment.CurrentDirectory + @"\Excel\Shipping_semple_" + DateTime.Now.ToString("yyyyMMdd") + ".xlsx";

            //파일생성유무 확인(기준 하루 한번 생성이 가능 재생성시 그존 파일 삭제.
            if (File.Exists(ExcelEndPath))
            {
                File.Delete(ExcelEndPath);
            }


            try
            {
                ExcelApp = new Excel.Application();
                wb = ExcelApp.Workbooks.Open(ExcelPath,
                                             0,
                                             true,
                                             5,
                                             "",
                                             "",
                                             true,
                                             Excel.XlPlatform.xlWindows,
                                             "\t",
                                             false,
                                             false,
                                             0,
                                             true,
                                             1,
                                             0);
                ws = wb.Worksheets["Sheet1"] as Excel.Worksheet;

                //엑셀 시트 인덱스 번호는 0,0 부터 시작 하는 것이 아니라 1,1 A1 부터 시작 함. 0,0 으로 시작하면 오류... 
                //시트에 값 쓰기... 
                string query = "SELECT 고객,";
                query += "             납품처,";
                query += "             품목정보,";
                query += "             목표품번,";
                query += "             제품단위,";
                query += "             제품스팩";
                query += "        FROM 품목마스터";
                
                //DB 연결 클래스 입니다
                DB db = new DB();
                
                DataTable dt = db.ExcuteQuery(query);

                if (dt.Rows.Count > 0)
                {
                    for (int i = 0; i <= dt.Rows.Count - 1; i++)
                    {
                        ws.Cells[7 + i, 1] = dt.Rows[i]["고객"].ToString();
                        ws.Cells[7 + i, 2] = dt.Rows[i]["납품처"].ToString();
                        ws.Cells[7 + i, 3] = dt.Rows[i]["품목정보"].ToString();
                        ws.Cells[7 + i, 4] = dt.Rows[i]["목표품번"].ToString();
                        ws.Cells[7 + i, 5] = dt.Rows[i]["제품단위"].ToString();
                        ws.Cells[7 + i, 6] = dt.Rows[i]["제품스팩"].ToString();
                    }

                }

                //다른 이름으로 저장하기... 
                //wb.Save(); 
                // => 오픈한 파일 그대로 저장... 
                if (File.Exists(ExcelEndPath)) File.Delete(ExcelEndPath);
                wb.SaveAs(ExcelEndPath);

                //파일 닫기... 
                wb.Close(false, Type.Missing, Type.Missing);
                wb = null;
                ExcelApp.Quit();

                MessageBox.Show("엑셀 파일 생성이 완료 되었습니다.");

            }
            catch (Exception ex)
            {
                //객체들 메모리 해제 
                ReleaseExcelObject(ws);
                ReleaseExcelObject(wb);
                ReleaseExcelObject(ExcelApp);
                GC.Collect();
            }
            finally
            {
                //객체들 메모리 해제 
                ReleaseExcelObject(ws);
                ReleaseExcelObject(wb);
                ReleaseExcelObject(ExcelApp);
                GC.Collect();
            }
        }

 

버튼을 클릭해서 템플릿 파일을 생성하게 되면 원본파일이 아닌 생성일자가 붙어 있는 신규 파일이 생성됩니다

 

 

내가 원하는 Cell위치에 DB 값이 들어가 있는 템플릿 파일이 생성된거죠

 

제가 개발로 사용하고 있는 노트북이 구형이라 속도가 많이 느릴경우 메모리를 늘려보시는것도 방법이 될거 같습니다

 

 

반응형
반응형

안녕하세요

 

포스팅으로 열공하고 있는 코딩연습생입니다

 

저번 포스팅에서 비쥬얼스튜디오 2017을 이용하여 간단한 로그인 앱 만드는 방법을 포스팅했는데요

 

그 포스팅에 이어 로그인 할때 계정이 없을 경우 회원가입을 해야 하지요?

 

그래서 MSSQL와 연동하여 회원가입이 가능하도록 한번 만들어 봤습니다

 

물론 회원가입시에 ID 중복체크, 패스워트 생성 규칙, 주소 검색, 등 많은 기능이 필요한데

 

이번 시간에는 기초적인 부분만 만들어 보았습니다

 

첫번째 ID생성(문자열)

 

두번째 패스워드(문자열)

 

세번째 이메일(문자열)

 

이렇게 3가지만 등록한뒤 생성 버튼을 클릭하면 DB에 Data가 생성되어 로그인이 되도록 하는 구조 입니다

 

이렇게 기초 적인 부분을 만든뒤 차츰차츰 기능을 하나씩 구현하는게 바로 코딩에 재미겠죠ㅎ

 

그럼 진행해 보도록 하겠습니다

 

일단 저번 시간 포스팅까지 완성이 되어야 이어서 가능하니 아래 링크를 통해서 로그인 샘플 먼저 완성해주세요

 

https://codingman.tistory.com/96

 

[Xamarin Forms] 자마린으로 간단한 로그인 앱 만들기

안녕하세요. 코딩연습생입니다 비쥬얼스튜디오 Xamarin을 이용한 로그인 창 만들기 입니다 저도 처음 접해보는 부분이라 많이 헷갈리고 연습을 하고 있습니다~ 음..일단 시작에 앞서 비쥬얼스튜디오의 Cross-Platf..

codingman.tistory.com

 

그러면 해당 프로젝트 파일 중에 해당 위치로 찾아 갑니다

 

로그인 화면에서 이미 만들어져 있는 부분인데 그 부분에서 INSERT 부분만 추가가 된것입니다

 

*SignUpPage.xaml.cs

using System;
using System.Linq;
using Xamarin.Forms;
using System.Data;
using System.Data.SqlClient;

namespace LoginNavigation
{
	public partial class SignUpPage : ContentPage
	{
		public SignUpPage ()
		{
			InitializeComponent ();
		}

		async void OnSignUpButtonClicked (object sender, EventArgs e)
		{
			var user = new User () {
				Username = usernameEntry.Text,
				Password = passwordEntry.Text,
				Email = emailEntry.Text
			};

            
            CreateSign();

			// Sign up logic goes here
			var signUpSucceeded = AreDetailsValid (user);
			if (signUpSucceeded) {
				var rootPage = Navigation.NavigationStack.FirstOrDefault ();
				if (rootPage != null) {
					App.IsUserLoggedIn = true;
					Navigation.InsertPageBefore (new MainPage (), Navigation.NavigationStack.First ());
					await Navigation.PopToRootAsync ();
				}
			} else {
				messageLabel.Text = "Sign up failed";
			}
		}

        public void CreateSign()
        {
            SqlConnectionStringBuilder sqlConnectionStringBuilder = new SqlConnectionStringBuilder();
            sqlConnectionStringBuilder.DataSource = "서버IP";
            sqlConnectionStringBuilder.InitialCatalog = "DB명";
            sqlConnectionStringBuilder.UserID = "계정";
            sqlConnectionStringBuilder.Password = "계정암호";
            sqlConnectionStringBuilder.IntegratedSecurity = false;
            SqlConnection conn = new SqlConnection(sqlConnectionStringBuilder.ConnectionString);
            conn.Open();

            try
            {
                string Query = "MERGE USER_MAST";
                Query += "            USING(SELECT 'X' AS DUAL) AS B ";
                Query += "               ON [USER_ID] = '" + usernameEntry.Text + "'";
                Query += "            WHEN MATCHED THEN";
                Query += "                 UPDATE SET USER_PSWD = '" + passwordEntry.Text + "'";
                Query += "            WHEN NOT MATCHED THEN";
                Query += "                 INSERT([USER_ID], USER_PSWD) VALUES ('" + usernameEntry.Text + "','" + passwordEntry.Text + "');";
                SqlCommand cmd = new SqlCommand();
                cmd.Connection = conn;

                cmd.CommandText = Query;
                cmd.ExecuteNonQuery();
                conn.Close();
            }
            catch (Exception Ex)
            {
                conn.Close();
            }
            finally
            {
                conn.Close();
            }
        }

        bool AreDetailsValid (User user)
		{
			return (!string.IsNullOrWhiteSpace (user.Username) && !string.IsNullOrWhiteSpace (user.Password) && !string.IsNullOrWhiteSpace (user.Email) && user.Email.Contains ("@"));
		}
	}
}

 

*SignUpPageCS.cs

using System;
using System.Linq;
using Xamarin.Forms;
using System.Data;
using System.Data.SqlClient;

namespace LoginNavigation
{
	public class SignUpPageCS : ContentPage
	{
		Entry usernameEntry, passwordEntry, emailEntry;
		Label messageLabel;

		public SignUpPageCS ()
		{
			messageLabel = new Label ();
			usernameEntry = new Entry {
				Placeholder = "username"	
			};
			passwordEntry = new Entry {
				IsPassword = true
			};
			emailEntry = new Entry ();
			var signUpButton = new Button {
				Text = "Sign Up"
			};
			signUpButton.Clicked += OnSignUpButtonClicked;

			Title = "Sign Up";
			Content = new StackLayout { 
				VerticalOptions = LayoutOptions.StartAndExpand,
				Children = {
					new Label { Text = "Username" },
					usernameEntry,
					new Label { Text = "Password" },
					passwordEntry,
					new Label { Text = "Email address" },
					emailEntry,
					signUpButton,
					messageLabel
				}
			};
		}

		async void OnSignUpButtonClicked (object sender, EventArgs e)
		{
			var user = new User () {
				Username = usernameEntry.Text,
				Password = passwordEntry.Text,
				Email = emailEntry.Text
			};

            CreateSign();

            // Sign up logic goes here

            var signUpSucceeded = AreDetailsValid (user);
			if (signUpSucceeded) {
				var rootPage = Navigation.NavigationStack.FirstOrDefault ();
				if (rootPage != null) {
					App.IsUserLoggedIn = true;
					Navigation.InsertPageBefore (new MainPageCS (), Navigation.NavigationStack.First ());
					await Navigation.PopToRootAsync ();
				}
			} else {
				messageLabel.Text = "Sign up failed";
			}
		}

        public void CreateSign()
        {
            SqlConnectionStringBuilder sqlConnectionStringBuilder = new SqlConnectionStringBuilder();
            sqlConnectionStringBuilder.DataSource = "서버IP";
            sqlConnectionStringBuilder.InitialCatalog = "DB명";
            sqlConnectionStringBuilder.UserID = "계정";
            sqlConnectionStringBuilder.Password = "계정암호";
            sqlConnectionStringBuilder.IntegratedSecurity = false;
            SqlConnection conn = new SqlConnection(sqlConnectionStringBuilder.ConnectionString);
            conn.Open();

            try
            {
                string Query = "MERGE USER_MAST";
                Query += "            USING(SELECT 'X' AS DUAL) AS B ";
                Query += "               ON [USER_ID] = '" + usernameEntry.Text + "'";
                Query += "            WHEN MATCHED THEN";
                Query += "                 UPDATE SET USER_PSWD = '" + passwordEntry.Text + "'";
                Query += "            WHEN NOT MATCHED THEN";
                Query += "                 INSERT([USER_ID], USER_PSWD) VALUES ('" + usernameEntry.Text + "','" + passwordEntry.Text + "');";
                SqlCommand cmd = new SqlCommand();
                cmd.Connection = conn;

                cmd.CommandText = Query;
                cmd.ExecuteNonQuery();
                conn.Close();
            }
            catch (Exception Ex)
            {
                conn.Close();
            }
            finally
            {
                conn.Close();
            }
        }

        bool AreDetailsValid (User user)
		{
			return (!string.IsNullOrWhiteSpace (user.Username) && !string.IsNullOrWhiteSpace (user.Password) && !string.IsNullOrWhiteSpace (user.Email) && user.Email.Contains ("@"));
		}
	}
}

 

그런데 위의 INSERT 구문을 보시면 일반적인 INSERT문하고 조금 차이가 있죠??

 

제가 올린 포스팅 내용중에 보시면 INSERT와 UPDATE를 한번에 처리하는 구문입니다

 

자세한건 아래 링크를 통해서 확인해보시면 됩니다

 

https://codingman.tistory.com/98

 

[MSSQL] MERGE를 이용한 INSERT와 UPDATE 한번에 하기

안녕하세요~ 코딩 연습생입니다 코로나 사태 여러분 괜찮으신가요?? 언제쯤 잠잠해질지 참...얼른 백신이나 대책이 나왔으면 좋겠는데 마스크 때문에 숨도 잘 안쉬어지네요~ 그래도 할건 해야겠죠?ㅎㅎ 그래서 저..

codingman.tistory.com

 

이렇게 소스코딩을 완료 하셨다면 이제 빌드를 진행하여 실행을 해봐야겠죠?

 

로그인 메인 화면에서 우측 상단에 있는 SIGN UP이라는 글씨를 클릭하면 회원가입 화면으로 이동합니다

 

 

회원 가입 페이지로 이동하게 되면 아래와 같은 화면이 보이게 됩니다

 

회원가입 화면에서 Username(계정명), Password(패스워트), Email address(이메일) 정보를 입력합니다

*굳이 저랑 똑같이 입력하지 않으셔도 됩니다

 

저는 빨간색 글씨 처럼 입력 하였습니다

 

정보 입력이 모두 되셨다면 아래 SIGN UP 버튼을 누루시면 컨텐츠 메인 화면으로 이동하게 됩니다

 

 

컨텐츠 메인 화면으로 정상적으로 이동하셨다면 다음과 같이 우측 상단의 글씨 LOGOUT으로 변경이 됩니다

 

 

그러면 MSSQL DB에 정상적으로 데이터가 입력되었는지 확인해 볼까요?

 

SQL에서 USER_MAST 테이블을 조회해 보니 정상적으로 값이 INSERT 되었네요

 

만약에 이미 USER_MAST 테이블에 "테스트"라는 계정이 존재했다면 INSERT가 아니라 UPDATE가 진행되었을 겁니다

 

 

회원가입의 기본적인 기능이 담겨 있는 내용인데요

 

이부분에서 앞써 말씀드렸던 추가적인 기능들이 첨가가 된다면 좀더 있어보이는(?)ㅎ 그런 회원가입이 되지 않을까요?ㅎ

 

저도 시간을 투자해서 좀 더 발전시켜 봐야겠습니다

 

반응형
반응형

안녕하세요~ 코딩 연습생입니다

 

코로나 사태 여러분 괜찮으신가요??

 

언제쯤 잠잠해질지 참...얼른 백신이나 대책이 나왔으면 좋겠는데 마스크 때문에 숨도 잘 안쉬어지네요~

 

그래도 할건 해야겠죠?ㅎㅎ

 

그래서 저는 매일 출근합니다;;;ㅋ

 

오늘 포스팅 주제는 MSSQL 쿼리인데요

 

MSSQL을 접해보신 분들한데는 참 쉬운 정보일수 있지만 혹시 모르시는 분들을 위해서 포스팅 합니다

 

프로그램을 작성하다가 DB와 Data를 주고 받을때 이미 있는 데이터를 처리하기 위해서 SELECT를 한번 더 해야 하고

 

중복인지 아닌지를 체크해서 중복이면 UPDATE를 신규이면 INSERT 뭐 이런식으로 프로그램을 많이 했습니다

 

그런데 이 MERGE라는 함수를 알게 되고 부턴 한번의 쿼리로 INSERT / UPDATE가 조건에 의해 한번에 처리가 되니

 

참 편하더라구요

 

그래서 이 MERGE함수 사용하는 방법을 포스팅 하겠습니다

 

일단 쿼리 작성을 위해서 MSSQL을 접속합니다

 

접속을 하신뒤 새쿼리를 눌러 쿼리를 작성합니다

 

저의 경우 USER_MAST라는 테이블을 생성하였습니다

 

*USER_MAST 테이블

  - 컬럼정보 : USER_ID, USER_NAME, USER_PSWD

 

이렇게 3개의 컬럼이 존재합니다

 

그럼 조회를 한번 해보겠습니다

 

 

보시는거와 같이 USER_MAST라는 테이블에는 TEST라는 정보가 이미 존재하고 있습니다

 

그럼 MERGE 쿼리를 작성해 볼께요

 

*Query

MERGE USER_MAST
      USING (SELECT 'x' AS DUAL) AS B
         ON [USER_ID] = 'TEST'
       WHEN MATCHED THEN
            UPDATE SET [USER_NAME] = 'TEST111111'
       WHEN NOT MATCHED THEN
            INSERT([USER_ID], [USER_NAME], USER_PSWD) VALUES('TEST', 'TEST', '');

 

쿼리의 내용을 말로 설명하자면 이렇게 됩니다

 

USER_MAST라는 테이블에 [USER_ID]가 'TEST'인 테이터가 존재하면

 

UPDATE문으로 [USER_NAME] 컬럼에 'TEST111111'을 UPDATE하고

 

존재하지 않으면 INSERT문으로 [USER_ID]가 'TEST'이고 [USER_NAME]가 'TEST'인 DATA를 생성해라

 

이렇게 됩니다 어렵지 않죠? 

 

그럼 MERGE 쿼리를 실행해 보겠습니다

 

※ 아래 이미지는 USER_PSWD가 빠져있는데 쿼리 자체게 문제는 없습니다 참고하세요

 

 

실행했으면 USER_MAST 테이블을 다시 조해해보겠습니다

 

위에서 보았듯이 이미 USER_MAST 테이블에는 TEST라는 데이터가 존재했습니다

 

그래서 USER_NAME 컬럼에 TEST111111을 UPDATE한 결과를 확인 할 수 있습니다

 

 

그럼 다음 조건을 테스트하기 위해서 USER_MAST 테이블의 값을 지워 볼께요

 

 

DELETE문을 실행했습니다

 

 

이제 USER_MAST 테이블에는 'TEST'라는 데이터는 존재하지 않습니다

 

다시 MERGE문을 실행해 보겠습니다

 

 

그럼 저희는 예측할수가 있죠

 

USER_MAST 테이블에 USER_ID컬럼이 'TEST'이고 USER_NAME컬럼이 'TEST'인 데이터가 생성되어야 합니다

 

조회 해보겠습니다

 

예상했던 결과값이 보여지네요

 

이렇게 INSERT와 UPDATE를 하나의 쿼리에서 동작할 수 있는 방법을 알아봤습니다

반응형
반응형

안녕하세요

 

코딩연습생입니다~

 

오늘 포스팅은 저번 시간 포스팅에 이어서 진행 하고자 합니다

 

저번 시간 포스팅에서 자마린 Cross-Platform을 사용해서 로그인 화면을 만들어 봤습니다

 

정보는 아래 링크를 참고해 주세요

 

https://codingman.tistory.com/96

 

[Xamarin Forms] 자마린으로 간단한 로그인 앱 만들기

안녕하세요. 코딩연습생입니다 비쥬얼스튜디오 Xamarin을 이용한 로그인 창 만들기 입니다 저도 처음 접해보는 부분이라 많이 헷갈리고 연습을 하고 있습니다~ 음..일단 시작에 앞서 비쥬얼스튜디오의 Cross-Platf..

codingman.tistory.com

 

저번 시간에 만들었던 로그인 앱에서 로그인 인증 시도 할때 

 

MSSQL과 연동시켜 인증처리 되도록 구현을 해볼려고 합니다

 

앱에서 MSSQL과 연동 할때 여러가지 방법이 있다고 합니다

 

하지만 저는 C# 개발자였기에;; 기존과 비슷한 벙법으로 MSSQL에 접속을 구현해 봤습니다

 

자마린에서 MSSQL에 접속을 하기 위해서는 몇가지 사전 준비가 필요한데요

 

Nuget을 사용해서 필요한 패키지를 설치 하면 됩니다 어렵지는 않아요

 

1. Nuget을 사용하기

    - C# 프로젝트 위치에서 Nuget 패키지 관리를 클릭 합니다

 

2. System.Data.SqlClient 설치 하기

   - Nuget  패키지 관리창에서 System.Data.SqlClient를 검색하여 설치 합니다

 

3. using문 선언

   - SQL 클래스 사용을 위한 using문을 선업합니다

using System.Data;
using System.Data.SqlClient;

 

4. 로그인 인증을 위한 단계 구성

   - 기존 로그인 앱에서 Login 버튼이 활성화 되는 위치에서 DB 정보를 불러오도록 할겁니다

 

*LiginPage.xaml.cs

 ① 해당 위치에서 로그인 버튼 클릭이 일어는 위치를 다음과 같이 수정 합니다 Connet();만 추가했습니다

 ② Connet() 구문을 추가 했습니다

async void OnLoginButtonClicked (object sender, EventArgs e)
		{
			var user = new User {
				Username = usernameEntry.Text,
				Password = passwordEntry.Text
			};

            Connet();

            var isValid = AreCredentialsCorrect (user);
			if (isValid) {
				App.IsUserLoggedIn = true;
				Navigation.InsertPageBefore (new MainPage (), this);
				await Navigation.PopAsync ();
			} else {
				messageLabel.Text = "Login failed";
				passwordEntry.Text = string.Empty;
			}
		}
public void Connet()
        {
            DataRowCollection Rs = null;

            SqlConnectionStringBuilder sqlConnectionStringBuilder = new SqlConnectionStringBuilder();
            sqlConnectionStringBuilder.DataSource = "서버IP주소";
            sqlConnectionStringBuilder.InitialCatalog = "DB명";
            sqlConnectionStringBuilder.UserID = "계정ID";
            sqlConnectionStringBuilder.Password = "계정 비밀 번호";
            sqlConnectionStringBuilder.IntegratedSecurity = false;
            SqlConnection conn = new SqlConnection(sqlConnectionStringBuilder.ConnectionString);
            conn.Open();

            try
            {
                SqlDataAdapter adapter = new SqlDataAdapter();
                string Query = "SELECT [USER_ID], USER_PSWD";
                Query += "        FROM USER_MAST";
                Query += "       WHERE 1=1";
                Query += "         AND [USER_ID] = '" + usernameEntry.Text + "'";
                adapter.SelectCommand = new SqlCommand(Query, conn);
                DataSet ds = new DataSet();
                adapter.Fill(ds);
                DataTable table = ds.Tables[0];
                Rs = table.Rows;

                if (Rs != null && Rs.Count > 0)
                {
                    Constants.Username = Rs[0]["USER_ID"].ToString();
                    Constants.Password = Rs[0]["USER_PSWD"].ToString();
                }
            }
            catch (Exception Ex)
            {
                conn.Close();
            }
            finally
            {
                if (Rs != null) { Rs.Clear(); Rs = null; }
                conn.Close();
            }
        }

 

*LoginPageCS.cs

 위와 동일하게 적용해 줍니다

async void OnLoginButtonClicked (object sender, EventArgs e)
		{
			var user = new User {
				Username = usernameEntry.Text,
				Password = passwordEntry.Text
			};

            Connet();

            var isValid = AreCredentialsCorrect (user);
			if (isValid) {
				App.IsUserLoggedIn = true;
				Navigation.InsertPageBefore (new MainPageCS (), this);
				await Navigation.PopAsync ();
			} else {
				messageLabel.Text = "Login failed";
				passwordEntry.Text = string.Empty;
			}
		}
public void Connet()
        {
            DataRowCollection Rs = null;

            SqlConnectionStringBuilder sqlConnectionStringBuilder = new SqlConnectionStringBuilder();
            sqlConnectionStringBuilder.DataSource = "서버IP주소";
            sqlConnectionStringBuilder.InitialCatalog = "DB명";
            sqlConnectionStringBuilder.UserID = "계정ID";
            sqlConnectionStringBuilder.Password = "계정 비밀 번호";
            sqlConnectionStringBuilder.IntegratedSecurity = false;
            SqlConnection conn = new SqlConnection(sqlConnectionStringBuilder.ConnectionString);
            conn.Open();

            try
            {
                SqlDataAdapter adapter = new SqlDataAdapter();
                string Query = "SELECT [USER_ID], USER_PSWD";
                Query += "        FROM USER_MAST";
                Query += "       WHERE 1=1";
                Query += "         AND [USER_ID] = '" + usernameEntry.Text + "'";
                adapter.SelectCommand = new SqlCommand(Query, conn);
                DataSet ds = new DataSet();
                adapter.Fill(ds);
                DataTable table = ds.Tables[0];
                Rs = table.Rows;

                if (Rs != null && Rs.Count > 0)
                {
                    Constants.Username = Rs[0]["USER_ID"].ToString();
                    Constants.Password = Rs[0]["USER_PSWD"].ToString();
                }
            }
            catch (Exception Ex)
            {
                conn.Close();
            }
            finally
            {
                if (Rs != null) { Rs.Clear(); Rs = null; }
                conn.Close();
            }
        }

 

이렇게 하시면 MSSQL에 접속하여 인증을 받아 로그인 성공/실패가 됩니다

 

다음시간에는 SignUpPageCS.cs부분인 회원가입 부분을 수정해서 MSSQL와 연동한

 

계정 등록 방법에 대해 포스팅 해보도록 할께요~

반응형
반응형

안녕하세요.

 

코딩연습생입니다

 

비쥬얼스튜디오 Xamarin을 이용한 로그인 창 만들기 입니다

 

저도 처음 접해보는 부분이라 많이 헷갈리고 연습을 하고 있습니다~

 

음..일단 시작에 앞서 비쥬얼스튜디오의 Cross-Platform에 대해 알아야 하는데요

 

간단하게 말해서 C#코드로 짠 앱 소스코드를 다양한 플렛폼에 간단하게 적용시킬수 있는 플랫폼이다

 

인데요...ㅎㅎ

 

아래 정말 설명을 잘 해 놓은 영상이 있어서 링크 걸어드리니 한번 보시는걸 추천 드립니다

 

https://www.youtube.com/watch?v=B_cjRSDve8Q&list=PLZiskT3TqIThspx9OPBNFY5xGKTKJFelG

 

이번에 만들 로그인창도 Cross-Platform 환경에서 제작을 할 것입니다

 

다소 복작하고 어려울수 있으나 일단 한번 따라서 완성 시키시고 나면 금방 이해가 가실거라 생각합니다

 

1. 프로젝트 생성

   - 비쥬얼스튜디오 2017환경에서 개발하엿습니다 참고해서 봐주세요

   - 파일 -> 새로만들기 -> 프로젝트

 

   - 프로젝트 형식은 Cross-Platform 형식이며, 모바일 앱(Xamarin.Forms) 형식의 폼을 구성해서 만듭니다

 

  - Cross Platform의 세부 설정입니다 빈화면에 호환되는 플랫폼의 종류 등을 설정 합니다

 

2. 폼 구성하기

   - Cross Platform 솔루션 구성을 먼저 이해해야 합니다

   - 전체 프로젝트를 감싸는 솔루션 밑에 플랫폼을 관장해야할 C# 프로젝트가 있고

     그 밑에 각 플렛폼에 따른 프로젝트가 있습니다

   - 프로젝트명.Droid : 안드로이드 플렛폼

   - 프로젝트명.IOS : 애플 플렛폼

   - 프로젝트폄.UWP : 테블릿 플렛폼

   - 저희가 수정할 부분은 C# 프로젝트 입니다

   - C#프로젝트 부분에서 App.xaml 파일을 마우스 오른쪽 버튼을 눌러 삭제 합니다

   - C# 프로젝트에서 마우스 오른쪽 버튼을 통해 새항목을 선택합니다

    - App.cs 클래스 파일을 추가합니다

 

 

 - App.cs 클래스 파일에 다음과 같이 코딩합니다

 

*App.cs

using Xamarin.Forms;

namespace LoginNavigation
{
	public class App : Application
	{
		public static bool IsUserLoggedIn { get; set; }

		public App ()
		{
			if (!IsUserLoggedIn) {
				MainPage = new NavigationPage (new LoginPage ());
			} else {
				MainPage = new NavigationPage (new LoginNavigation.MainPage ());
			}
		}

		protected override void OnStart ()
		{
			// Handle when your app starts
		}

		protected override void OnSleep ()
		{
			// Handle when your app sleeps
		}

		protected override void OnResume ()
		{
			// Handle when your app resumes
		}
	}
}

 

- 다시 C# 프로젝트에서 마우스 오른쪽 버튼을 클릭하여 클래스 파일을 추가 합니다

 

 

  - 클래스 명은 Constants.cs로 만들고 추가 합니다

 

 

- 새로 추가된 클래스 파일에 아래와 같이 코딩합니다

 

*Constants.cs

using System;
using System.Data;

namespace LoginNavigation
{
    public static class Constants
    {
        public static string Username = string.Empty;
        public static string Password = string.Empty;

	}
}

 

- 다시 항목 추가를 해줍니다

 - 이번에는 LoginPage.xaml 이름을 가진 콘텐츠 페이지를 추가합니다

 - 콘텐츠 페이지는 디자인 부분과 CS 부분의 소스가 두개로 입력됩니다

 - 처음 LoginPage.xaml 디자인 부분에 아래와 같이 코딩합니다

 

*LoginPage.xaml

<?xml version="1.0" encoding="UTF-8"?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="LoginNavigation.LoginPage" Title="Login">
	<ContentPage.ToolbarItems>
		<ToolbarItem Text="Sign Up" Clicked="OnSignUpButtonClicked" />
	</ContentPage.ToolbarItems>
	<ContentPage.Content>
		<StackLayout VerticalOptions="StartAndExpand">
			<Label Text="Username" />
			<Entry x:Name="usernameEntry" Placeholder="username" />
			<Label Text="Password" />
			<Entry x:Name="passwordEntry" IsPassword="true" />
			<Button Text="Login" Clicked="OnLoginButtonClicked" />
			<Label x:Name="messageLabel" />
		</StackLayout>
	</ContentPage.Content>
</ContentPage>

  - 다음 LoginPage.xaml.cs 부분에 아래와 같이 코딩합니다

 

*LoginPage.xaml.cs

using System;
using Xamarin.Forms;
using System.Data;
using System.Data.SqlClient;

namespace LoginNavigation
{
	public partial class LoginPage : ContentPage
	{
		public LoginPage ()
		{
			InitializeComponent ();
		}

		async void OnSignUpButtonClicked (object sender, EventArgs e)
		{
			await Navigation.PushAsync (new SignUpPage ());
		}

		async void OnLoginButtonClicked (object sender, EventArgs e)
		{
			var user = new User {
				Username = usernameEntry.Text,
				Password = passwordEntry.Text
			};

            var isValid = AreCredentialsCorrect (user);
			if (isValid) {
				App.IsUserLoggedIn = true;
				Navigation.InsertPageBefore (new MainPage (), this);
				await Navigation.PopAsync ();
			} else {
				messageLabel.Text = "Login failed";
				passwordEntry.Text = string.Empty;
			}
		}


        bool AreCredentialsCorrect (User user)
		{
            return user.Username == Constants.Username && user.Password == Constants.Password;
		}
	}
}

 

  - 다시 C# 프로젝트에서 신규 클래스 파일을 추가합니다

  - 클래스 명칭은 LoginPageCs.cs파일로 합니다

  - 신규로 생성한 클래스 파일에 아래와 같이 코딩을 합니다

 

*LoginPageCS.cs

using System;
using Xamarin.Forms;
using System.Data;
using System.Data.SqlClient;

namespace LoginNavigation
{
	public class LoginPageCS : ContentPage
	{
		Entry usernameEntry, passwordEntry;
		Label messageLabel;

		public LoginPageCS ()
		{
			var toolbarItem = new ToolbarItem {
				Text = "Sign Up"
			};
			toolbarItem.Clicked += OnSignUpButtonClicked;
			ToolbarItems.Add (toolbarItem);

			messageLabel = new Label ();
			usernameEntry = new Entry {
				Placeholder = "username"	
			};
			passwordEntry = new Entry {
				IsPassword = true
			};
			var loginButton = new Button {
				Text = "Login"
			};
			loginButton.Clicked += OnLoginButtonClicked;

			Title = "Login";
			Content = new StackLayout { 
				VerticalOptions = LayoutOptions.StartAndExpand,
				Children = {
					new Label { Text = "Username" },
					usernameEntry,
					new Label { Text = "Password" },
					passwordEntry,
					loginButton,
					messageLabel
				}
			};
		}

		async void OnSignUpButtonClicked (object sender, EventArgs e)
		{
			await Navigation.PushAsync (new SignUpPageCS ());
		}

		async void OnLoginButtonClicked (object sender, EventArgs e)
		{
			var user = new User {
				Username = usernameEntry.Text,
				Password = passwordEntry.Text
			};

            var isValid = AreCredentialsCorrect (user);
			if (isValid) {
				App.IsUserLoggedIn = true;
				Navigation.InsertPageBefore (new MainPageCS (), this);
				await Navigation.PopAsync ();
			} else {
				messageLabel.Text = "Login failed";
				passwordEntry.Text = string.Empty;
			}
		}

        bool AreCredentialsCorrect (User user)
		{
			return user.Username == Constants.Username && user.Password == Constants.Password;
		}
	}
}


 

 - 다음 MainPage.xaml 파일에 아래와 같이 코딩 해줍니다

 - 콘텐츠 페이지 이기 때문에 xaml과 cs 부분으로 나뉘어져 있으니 주의 하시기 바랍니다

 - MainPage.xaml 부분 코딩 입니다

 

*MainPage.xaml

<?xml version="1.0" encoding="UTF-8"?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="LoginNavigation.MainPage" Title="Main Page">
	<ContentPage.ToolbarItems>
		<ToolbarItem Text="Logout" Clicked="OnLogoutButtonClicked" />
	</ContentPage.ToolbarItems>
	<ContentPage.Content>
		<StackLayout>
			<Label Text="Main app content goes here" HorizontalOptions="Center" VerticalOptions="CenterAndExpand" />
		</StackLayout>
	</ContentPage.Content>
</ContentPage>

* MainPage.xaml.cs

using System;
using Xamarin.Forms;

namespace LoginNavigation
{
	public partial class MainPage : ContentPage
	{
		public MainPage ()
		{
			InitializeComponent ();
		}

		async void OnLogoutButtonClicked (object sender, EventArgs e)
		{
			App.IsUserLoggedIn = false;
			Navigation.InsertPageBefore (new LoginPage (), this);
			await Navigation.PopAsync ();
		}
	}
}

 

- 다음 다시 신규 클래스 파일을 추가 합니다

 

  - 신규 클래스의 명칭은 MainPageCS.cs파일로 지정합니다

 

- 생성된 클래스 파일에 아래와 같이 코딩 합니다

 

*MainPageCS.cs

using System;
using Xamarin.Forms;

namespace LoginNavigation
{
	public class MainPageCS : ContentPage
	{
		public MainPageCS ()
		{
			var toolbarItem = new ToolbarItem {
				Text = "Logout"
			};
			toolbarItem.Clicked += OnLogoutButtonClicked;
			ToolbarItems.Add (toolbarItem);

			Title = "Main Page";
			Content = new StackLayout { 
				Children = {
					new Label {
						Text = "Main app content goes here",
						HorizontalOptions = LayoutOptions.Center,
						VerticalOptions = LayoutOptions.CenterAndExpand
					}
				}
			};
		}

		async void OnLogoutButtonClicked (object sender, EventArgs e)
		{
			App.IsUserLoggedIn = false;
			Navigation.InsertPageBefore (new LoginPageCS (), this);
			await Navigation.PopAsync ();
		}
	}
}

 

- 다시 컨텐츠 페이지를 하나 추가 합니다

 

  - 추가될 컨텐츠 페이지의 명칭은 signUpPage.xaml 입니다

 

  - SignUpPage.xaml과 SignUpPage.xaml.cs 파일에 아래와 같이 따로 코딩을 합니다

 

*SignUpPage.xaml 

<?xml version="1.0" encoding="UTF-8"?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" 
			 xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" 
			 x:Class="LoginNavigation.SignUpPage"
			 Title="Sign Up">
	<ContentPage.Content>
		<StackLayout VerticalOptions="StartAndExpand">
			<Label Text="Username" />
			<Entry x:Name="usernameEntry" Placeholder="username" />
			<Label Text="Password" />
			<Entry x:Name="passwordEntry" IsPassword="true" />
			<Label Text="Email address" />
			<Entry x:Name="emailEntry" />
			<Button Text="Sign Up" Clicked="OnSignUpButtonClicked" />
			<Label x:Name="messageLabel" />
		</StackLayout>
	</ContentPage.Content>
</ContentPage>

*SignUpPage.xaml.cs

using System;
using System.Linq;
using Xamarin.Forms;

namespace LoginNavigation
{
	public partial class SignUpPage : ContentPage
	{
		public SignUpPage ()
		{
			InitializeComponent ();
		}

		async void OnSignUpButtonClicked (object sender, EventArgs e)
		{
			var user = new User () {
				Username = usernameEntry.Text,
				Password = passwordEntry.Text,
				Email = emailEntry.Text
			};

			// Sign up logic goes here

			var signUpSucceeded = AreDetailsValid (user);
			if (signUpSucceeded) {
				var rootPage = Navigation.NavigationStack.FirstOrDefault ();
				if (rootPage != null) {
					App.IsUserLoggedIn = true;
					Navigation.InsertPageBefore (new MainPage (), Navigation.NavigationStack.First ());
					await Navigation.PopToRootAsync ();
				}
			} else {
				messageLabel.Text = "Sign up failed";
			}
		}

		bool AreDetailsValid (User user)
		{
			return (!string.IsNullOrWhiteSpace (user.Username) && !string.IsNullOrWhiteSpace (user.Password) && !string.IsNullOrWhiteSpace (user.Email) && user.Email.Contains ("@"));
		}
	}
}

 

  - 다시 클래스 파일을 추가 합니다

 

  - 추가될 클래스 파일의 명칭은 SingUppageCS.cs 입니다

 

  - 추가된 클래스 파일에 아래와 같이 코딩 합니다

 

*SignUpPage.xaml.cs

using System;
using System.Linq;
using Xamarin.Forms;

namespace LoginNavigation
{
	public class SignUpPageCS : ContentPage
	{
		Entry usernameEntry, passwordEntry, emailEntry;
		Label messageLabel;

		public SignUpPageCS ()
		{
			messageLabel = new Label ();
			usernameEntry = new Entry {
				Placeholder = "username"	
			};
			passwordEntry = new Entry {
				IsPassword = true
			};
			emailEntry = new Entry ();
			var signUpButton = new Button {
				Text = "Sign Up"
			};
			signUpButton.Clicked += OnSignUpButtonClicked;

			Title = "Sign Up";
			Content = new StackLayout { 
				VerticalOptions = LayoutOptions.StartAndExpand,
				Children = {
					new Label { Text = "Username" },
					usernameEntry,
					new Label { Text = "Password" },
					passwordEntry,
					new Label { Text = "Email address" },
					emailEntry,
					signUpButton,
					messageLabel
				}
			};
		}

		async void OnSignUpButtonClicked (object sender, EventArgs e)
		{
			var user = new User () {
				Username = usernameEntry.Text,
				Password = passwordEntry.Text,
				Email = emailEntry.Text
			};

			// Sign up logic goes here

			var signUpSucceeded = AreDetailsValid (user);
			if (signUpSucceeded) {
				var rootPage = Navigation.NavigationStack.FirstOrDefault ();
				if (rootPage != null) {
					App.IsUserLoggedIn = true;
					Navigation.InsertPageBefore (new MainPageCS (), Navigation.NavigationStack.First ());
					await Navigation.PopToRootAsync ();
				}
			} else {
				messageLabel.Text = "Sign up failed";
			}
		}

		bool AreDetailsValid (User user)
		{
			return (!string.IsNullOrWhiteSpace (user.Username) && !string.IsNullOrWhiteSpace (user.Password) && !string.IsNullOrWhiteSpace (user.Email) && user.Email.Contains ("@"));
		}
	}
}

 

  - 다시 클래스 파일을 하나더 추가 합니다

 

   - 클래스 명칭은 User.cs 입니다

 

   - 추가된 User.cs 파일에 아래와 같이 코딩 합니다

 

*User.cs

namespace LoginNavigation
{
	public class User
	{
		public string Username { get; set; }

		public string Password { get; set; }

		public string Email { get; set; }
	}
}

 

이제 여기까지 완료 하셨다면 코딩은 모두 끝낫습니다

 

빌드를 돌려 에뮬레이터를 실행해 주세요.

 

혹시 저와 같이 디바이스 빌드를 하실 분이라면 아래 링크를 참고해 주세요

 

https://codingman.tistory.com/95

 

[Microsoft Visual Studio 2017] Xamarin 디바이스로 디버깅 하기

안녕하세요 코딩연습생입니다 요즘 코로나 때문에 난리도 아니죠?ㅠ 제 주변에도 온통 관심사가 코로나에 가있습니다 이런 시국에 회사에서는 왜이렇게 일을 많이 주는걸까요....참 이해하기 힘든...ㅋㅋ 이번 포..

codingman.tistory.com

 

빌드가 완료가 되면 앱이 실행됩니다

 

 

정말 심플한 화면이 나오게 됩니다

 

다음번 포스팅에서 MSSQL와 연동하여 로그인 시키는 부분을 포스팅 하도록 하겠습니다

 

감사합니다~

반응형

+ Recent posts