web-dev-qa-db-ja.com

Excelデータを空のDataGridViewに貼り付ける-インデックスが範囲外の例外

次のExcelシートがあります。

enter image description here

したがって、私が達成しようとしているのは、これをExcelからコピーして、空のDataGridViewビューに貼り付けることです。

これは私がこれまでに持っているコードです:

private void PasteClipboard(DataGridView myDataGridView)
{
    DataObject o = (DataObject)Clipboard.GetDataObject();
    if (o.GetDataPresent(DataFormats.Text))
    {
        string[] pastedRows = Regex.Split(o.GetData(DataFormats.Text).ToString().TrimEnd("\r\n".ToCharArray()), "\r\n");
        foreach (string pastedRow in pastedRows)
        {
            string[] pastedRowCells = pastedRow.Split(new char[] { '\t' });
            using (DataGridViewRow myDataGridViewRow = new DataGridViewRow())
            {
                for (int i = 0; i < pastedRowCells.Length; i++)
                    myDataGridViewRow.Cells[i].Value = pastedRowCells[i];

                myDataGridView.Rows.Add(myDataGridViewRow);
            }
        }
    }
}

コードを実行すると、次のエラーが発生します。

enter image description here

私はこの手元のタスクに間違ってアプローチしていますか?

11
Latheesan

少し調べたところ、最初に列を追加してから、新しい行を追加し、新しく作成した行の行インデックスを取得して、セルの値を設定する必要があることに気付きました。

更新されたコードは次のとおりです。

DataObject o = (DataObject)Clipboard.GetDataObject();
if (o.GetDataPresent(DataFormats.Text))
{
    if (myDataGridView.RowCount > 0)
        myDataGridView.Rows.Clear();

    if (myDataGridView.ColumnCount > 0)
        myDataGridView.Columns.Clear();

    bool columnsAdded = false;
    string[] pastedRows = Regex.Split(o.GetData(DataFormats.Text).ToString().TrimEnd("\r\n".ToCharArray()), "\r\n");
    foreach (string pastedRow in pastedRows)
    {
        string[] pastedRowCells = pastedRow.Split(new char[] { '\t' });

        if (!columnsAdded)
        {
            for (int i = 0; i < pastedRowCells.Length; i++)
                myDataGridView.Columns.Add("col" + i, pastedRowCells[i]);

            columnsAdded = true;
            continue;
        }

        myDataGridView.Rows.Add();
        int myRowIndex = myDataGridView.Rows.Count - 1;

        using (DataGridViewRow myDataGridViewRow = myDataGridView.Rows[myRowIndex])
        {
            for (int i = 0; i < pastedRowCells.Length; i++)
                myDataGridViewRow.Cells[i].Value = pastedRowCells[i];
        }
    }
}

}

そしてここでそれは働いています:

enter image description here

これを改善する上での批判と有用なヒントを喜んで受け入れてください。 このコードはかなり遅いです...

8
Latheesan

数年後のことですが、この問題の解決策を探していたところ、BASAによるLatheesanのコードの変更が見つかりました。それは部分的にしか機能しなかったので、変更して、将来のブラウザーにこのソリューションを追加したいと思います。

private void Paste(DataGridView d)
    {
        DataObject o = (DataObject)Clipboard.GetDataObject();
        if (o.GetDataPresent(DataFormats.StringFormat))
        {
            string[] pastedRows = Regex.Split(o.GetData(DataFormats.StringFormat).ToString().TrimEnd("\r\n".ToCharArray()), "\r");
            int j = 0;
            try { j = d.CurrentRow.Index; } catch { }
            foreach (string pastedRow in pastedRows)
            {
                DataGridViewRow r = new DataGridViewRow();
                r.CreateCells(d, pastedRow.Split(new char[] { '\t' }));
                d.Rows.Insert(j, r);
                j++;
            }
        }
    }
4

最初に列を定義する必要がない場合は、gridview列を定義してください。

private void PasteClipboard(DataGridView myDataGridView)
{
    DataObject o = (DataObject)Clipboard.GetDataObject();
    if (o.GetDataPresent(DataFormats.Text))
    {
        string[] pastedRows = Regex.Split(o.GetData(DataFormats.Text).ToString().TrimEnd("\r\n".ToCharArray()), "\r\n");
        foreach (string pastedRow in pastedRows)
        {
            string[] pastedRowCells = pastedRow.Split(new char[] { '\t' });
            using (DataGridViewRow myDataGridViewRow = new DataGridViewRow())
            {
                myDataGridViewRow = (DataGridViewRow) myDataGridView.RowTemplate.Clone();
                for (int i = 0; i < pastedRowCells.Length; i++)
                    myDataGridViewRow.Cells[i].Value = pastedRowCells[i];

                myDataGridView.Rows.Add(myDataGridViewRow);
            }
        }
    }
}

列を確定していない場合

private void PasteClipboard(DataGridView myDataGridView)
{
    //Create COlumns in datagridView
    myDataGridView = new DataGridView();
    myDataGridView.Columns.Add("col1", "Col1");
    myDataGridView.Columns.Add("col2", "Col2");
    myDataGridView.Columns.Add("col3", "Col3");
    myDataGridView.Columns.Add("col4", "Col4");

    DataObject o = (DataObject)Clipboard.GetDataObject();
    if (o.GetDataPresent(DataFormats.Text))
    {
        string[] pastedRows = Regex.Split(o.GetData(DataFormats.Text).ToString().TrimEnd("\r\n".ToCharArray()), "\r\n");
        foreach (string pastedRow in pastedRows)
        {
            string[] pastedRowCells = pastedRow.Split(new char[] { '\t' });
            using (DataGridViewRow myDataGridViewRow = new DataGridViewRow())
            {
                myDataGridViewRow = (DataGridViewRow) myDataGridView.RowTemplate.Clone();
                for (int i = 0; i < pastedRowCells.Length; i++)
                    myDataGridViewRow.Cells[i].Value = pastedRowCells[i];

                myDataGridView.Rows.Add(myDataGridViewRow);
            }
        }
    }
}
3
Pratik Bhoir

ここに完璧なコード:(ボタンに記入)

DataObject o = (DataObject)Clipboard.GetDataObject();
if (o.GetDataPresent(DataFormats.Text))
{
    if (myDataGridView.RowCount > 0)
        myDataGridView.Rows.Clear();

    if (myDataGridView.ColumnCount > 0)
        myDataGridView.Columns.Clear();

    bool columnsAdded = false;
    string[] pastedRows = Regex.Split(o.GetData(DataFormats.Text).ToString().TrimEnd("\r\n".ToCharArray()), "\r\n");
    int j=0;
    foreach (string pastedRow in pastedRows)
    {
        string[] pastedRowCells = pastedRow.Split(new char[] { '\t' });

        if (!columnsAdded)
        {
            for (int i = 0; i < pastedRowCells.Length; i++)
                myDataGridView.Columns.Add("col" + i, pastedRowCells[i]);

            columnsAdded = true;
            continue;
        }

        myDataGridView.Rows.Add();
        int myRowIndex = myDataGridView.Rows.Count - 1;

        using (DataGridViewRow myDataGridViewRow = myDataGridView.Rows[j])
        {
            for (int i = 0; i < pastedRowCells.Length; i++)
                myDataGridViewRow.Cells[i].Value = pastedRowCells[i];
        }
        j++;
    }
}

Latheesanのコード から変更。

3
BALA s

本当にいい解決策が投稿されました ここ

ただし、1行を変更する必要があります。

 if (dgv.Rows.Count < (r + rowsInClipboard.Length))
            dgv.Rows.Add(r + rowsInClipboard.Length - dgv.Rows.Count);

次のように変更する必要があります:

 if (dgv.Rows.Count < (r + rowsInClipboard.Length))
            dgv.Rows.Add(r + rowsInClipboard.Length+1 - dgv.Rows.Count);

この行が変更されていない場合、貼り付けられた最後の行はSQLに渡されません。

2
mrliioadin