본문 바로가기
프로그래밍/C#

[C#] 데이터 그리드뷰 붙여넣기 만들기

by 코딩연습생 2020. 7. 21.
반응형

안녕하세요

 

코딩연습생입니다

 

이번 포스팅은 C#에서 데이터뷰로 많이 사용하는 기본컨트롤러인 데이터 그리드뷰에서

 

엑셀의 자료를 복사하여 붙여넣기 하는 기능을 구현해보고자 합니다

 

장점은 대량의 자료를 한번에 가져올수 있다는게 장점이고

 

단점은 그리드뷰와 엑셀의 셀형식과 구조 같아야하고, 행의 수를 조정해 줘야 한다는게 단점입니다

 

그래도 일단 기초적인 구조를 설명드리고 개선은 여러분의 노력이겠지요?ㅎ

 

[*개발 환경]

- Microsoft Visual Studio 2017

 

신규 폼을 하나 생성하고 그 위에 데이터드리드 뷰 컨트롤러를 배치 합니다

(간단한 부분이라 상세 설명은 생략하고 완성 이미지를 보여드릴께요)

폼 Init부분에 그리드에 대한 속성을 설정 합니다

(저의 폼 이름은 subCustList입니다)

        public subCustList()
        {
            InitializeComponent();

            //데이터그리드뷰 복&붙을 위한 초기 설정.
            this.dataGridView1.AllowUserToDeleteRows = false;
            this.dataGridView1.AllowUserToOrderColumns = true;
            this.dataGridView1.AllowUserToResizeRows = false;
            this.dataGridView1.RowHeadersVisible = false;
            this.dataGridView1.SelectionMode = System.Windows.Forms.DataGridViewSelectionMode.CellSelect;
            this.dataGridView1.KeyUp += new System.Windows.Forms.KeyEventHandler(this.dataGridView_KeywordBidAmt_KeyUp);
        }

 

다음 KeyUp과 Null값 처리를 위한 함수를 작성 합니다

private void dataGridView_KeywordBidAmt_KeyUp(object sender, KeyEventArgs e)
        {
            //if user clicked Shift+Ins or Ctrl+V (paste from clipboard)
            DataGridView grid = sender as DataGridView;
            if (e.Control && e.KeyCode == Keys.V)
            {
                try
                {
                    char[] rowSplitter = { '\r', '\n' };
                    char[] columnSplitter = { '\t' };
                    int[] columnsOrderArray = dataGridView1.Columns.Cast<DataGridViewColumn>().Where(x => x.Visible).OrderBy(x => x.DisplayIndex).Select(x => x.Index).ToArray();

                    //get the text from clipboard
                    IDataObject dataInClipboard = Clipboard.GetDataObject();
                    string stringInClipboard = (string)dataInClipboard.GetData(DataFormats.Text);

                    //split it into lines
                    string[] rowsInClipboard = stringInClipboard.Split(rowSplitter, StringSplitOptions.RemoveEmptyEntries);

                    //get the row and column of selected cell in grid
                    int r = grid.SelectedCells[0].RowIndex;
                    int c = columnsOrderArray[grid.SelectedCells[0].ColumnIndex];

                    //add rows into grid to fit clipboard lines
                    if (grid.Rows.Count < (r + rowsInClipboard.Length))
                    {
                        grid.Rows.Add(r + rowsInClipboard.Length - grid.Rows.Count);
                    }

                    // loop through the lines, split them into cells and place the values in the corresponding cell.
                    for (int iRow = 0; iRow < rowsInClipboard.Length; iRow++)
                    {
                        //split row into cell values
                        string[] valuesInRow = rowsInClipboard[iRow].Split(columnSplitter);

                        //cycle through cell values
                        for (int iCol = 0; iCol < valuesInRow.Length; iCol++)
                        {
                            //assign cell value, only if it within columns of the grid
                            if (columnsOrderArray.Count() - 1 >= c + iCol)
                            {
                                int idx = columnsOrderArray[c + iCol];
                                grid.Rows[r + iRow].Cells[idx].Value = valuesInRow[iCol];
                            }
                        }
                    }
                }
                catch (Exception ex)
                {
                    MessageBox.Show("알 수 없는 데이터 형식입니다. Excel에서 복사 후 붙여넣기해주세요" + Environment.NewLine + ex.Message);
                }
            }

            if (e.KeyCode == Keys.Delete)
            {
                foreach (DataGridViewCell cell in grid.SelectedCells)
                {
                    //선택된 Cell을 모두 null로 변경해버린다.
                    cell.Value = null;
                }

                NullDataGridViewRowDelete(grid);
            }

        }

        private void NullDataGridViewRowDelete(DataGridView dgv)
        {
            //아 머리아파서 짜기 귀찮어 그냥 맨뒤꺼인 추가안된에 제외하고 나머지 모두삭제 이때 역순으로 해야지 인덱스안꼬여
            List<DataGridViewRow> temp = dgv.Rows.Cast<DataGridViewRow>().Where(x => x.Cells.Cast<DataGridViewCell>().Where(y => y.Value == null || string.IsNullOrEmpty(y.Value.ToString())).Count() == x.Cells.Count).ToList();
            for (int i = temp.Count() - 2; i >= 0; i--)
            {
                dgv.Rows.RemoveAt(temp[i].Index);
            }
        }

 

그리고 버튼을 통해 Row를 추가 하는 기능을 만듭니다

 

제일 상단 부분에 DataTable를 하나 선언합니다

 

private DataTable dt;

 

그리고 버튼을 하나 생성하고 버튼 클릭 이벤트에 다음과 같이 작성합니다

 

                        dt = new DataTable();
                        dt = dataGridView1.DataSource as DataTable;
                        string[] row0 = { "", "", "", "", "", "", "", "", "", "", "" };
                        dt.Rows.Add(row0);
                        dataGridView1.DataSource = dt;

 

추가 버튼을 통한 Row가 추가된 화면

버튼을 눌러 붙여넣기 할 만큼의 Row를 미리 생성한뒤에 붙여 넣기 하면 그리드뷰에 데이터가 붙여넣기가 됩니다

 

 

Ctl + V를 통해 붙여넣기 된 화면

 

이상 C#에서 데이터그리드뷰에 Clipboard를 이용한 붙여넣기 구현 방법이였습니다

 

감사합니다~

반응형

댓글