Невозможно удалить пустые имена столбцов в datatable в C # - PullRequest
1 голос
/ 07 октября 2019

У меня есть Excel, который бизнес-пользователи обновят и отправят нам. Робот Blue Prism выберет файл и загрузит его в таблицу базы данных SQL, используя этап кода (гораздо быстрее использовать этап кода). Для этого я написал код на C #, однако большую часть времени он терпит неудачу из-за пробелов в столбце.

В результате, когда код использует используемый диапазон, он также занимает пробелы и создает таблицу данных симя столбца F16, F17 ... (когда число столбцов равно 15)

Я хотел обработать это динамически. т.е. независимо от количества столбцов и столбцов пробелов, код должен работать, удаляя эти столбцы пробелов из таблиц данных

Я написал код, чтобы справиться с этим, но он не работал. Выдает ошибку:

Коллекция была изменена;операция перечисления может не выполняться [duplicate]

try
{
    string excelConnectionString = string.Format("Provider=Microsoft.ACE.OLEDB.12.0;Data Source={0};Extended Properties=Excel 8.0", Path);
    using (OleDbConnection xlConnection = new OleDbConnection(excelConnectionString)) 
    { 
        OleDbCommand oleDbCmd = new OleDbCommand ("Select * FROM [" + SheetName + "$]", xlConnection); 

        xlConnection.Open(); 

        // Create DbDataReader to Data Worksheet 
        using (DbDataReader dbDtRdr = oleDbCmd.ExecuteReader()) 
        { 
                //Remove Empty Rows
                var dtTable = new DataTable();
                dtTable.Load(dbDtRdr);

                for (int i = dtTable.Rows.Count - 1; i>=0;i--)
                {
                    if(dtTable.Rows[i][1] == DBNull.Value)
                        dtTable.Rows[i].Delete();
                }

                dtTable.AcceptChanges();

                //Remove Empty Columns
                int z = 1;

                foreach(DataRow r in dtTable.Rows)
                {
                    foreach(DataColumn c in dtTable.Columns)
                    {   
                        if (c.ColumnName=="F" + z.ToString())
                            dtTable.Columns.Remove(c.ColumnName);
                    }
                }

                dtTable.AcceptChanges();

                // SQL Server Connection String 
                string sqlConnectionString = @"Data Source=" + SQLServerName + ";Initial Catalog=" + SQLDBName + ";Integrated Security=True"; 

                // Bulk Copy to SQL Server 
                using (SqlBulkCopy bulkCopy = new SqlBulkCopy(sqlConnectionString)) 
                { 
                    bulkCopy.DestinationTableName = TableName; 
                    bulkCopy.WriteToServer(dtTable); 
                }
        } 

        xlConnection.Close();
    }

    Success = true;
    Message = "Success";
}
catch (System.IO.IOException e)
{
    Message = e.Message;
    Success = false;        
}

Похоже, я не могу удалить столбцы в таблице данных с помощью команды удаления в приведенном выше коде

Это будеточень помогите, если кто-нибудь поможет мне в этом.

Примечание: я пытался использовать цикл For Next, чтобы повторить его в обратном порядке, как показано ниже, и все еще столкнулся с проблемой

                for (int z = dtTable.Columns.Count - 1; z>=0;z--)
                    {
                            if (dtTable.Columns[z].ColumnName.ToString()=="F" + (z).ToString())
                            dtTable.Columns.Remove(dtTable.Columns[z].ColumnName.ToString());
                        }
                        dtTable.AcceptChanges();

1 Ответ

0 голосов
/ 17 октября 2019

В соответствии с комментарием, данным JohnPete22, приведенным ниже, он работает нормально

Если вы подумаете об этом, вы просматриваете каждый DataColumn, а затем одновременно удаляете из этой Коллекции,что не может случиться. Вам нужен цикл For, а затем цикл в обратном направлении до 0 (который, как вы можете видеть, происходит чуть выше этой линии). Общее эмпирическое правило: не очень хорошая идея удалять из коллекции, которую вы просматриваете, одновременно, если вы не работаете в обратном направлении

Также следует отметить пункт ниже

Я пытался использовать решение Джона ранее, но не сработало. Затем я понял, что использовал if (dtTable.Columns [z] .ColumnName.ToString () == "F" + (z) .ToString ()), однако это должно быть if (dtTable.Columns [z] .ColumnName. ToString () == "F" + (z + 1) .ToString ()), поскольку в качестве имени дополнительного пробела используется индекс 1, а не 0 для столбцов.

...