단점은 그리드뷰와 엑셀의 셀형식과 구조 같아야하고, 행의 수를 조정해 줘야 한다는게 단점입니다
그래도 일단 기초적인 구조를 설명드리고 개선은 여러분의 노력이겠지요?ㅎ
[*개발 환경]
- 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);
}
}