excel - электронной - типы данных в электронных таблицах



OleDB и смешанные типы данных Excel: отсутствующие данные (4)

@Brian Уэллс Спасибо, ваше предложение сделал трюк, но не полностью ... Работал для смешанной поля int-string, но столбцы datetime пошли со странными символами после этого, поэтому я применил «взломать» над «хаком», ,

1. Создайте файл System.Io.File.Copy и создайте копию файла excel.

2.- Изменять заголовки столбцов Datetime программно во время выполнения на что-то в формате datetime, то есть «01/01/0001».

3. Сохраните excel, а затем примените трюк, выполняющий запрос с HDR = NO, к модифицированному файлу.

Трудно, да, но работал, и разумно быстро, если у кого-то есть альтернатива этому, я буду рад услышать.

Приветствую.

PD Извините мой английский, это не мой родной язык.

https://src-bin.com

У меня есть рабочий лист Excel, который я хочу прочитать в виде данных - все хорошо, за исключением одного столбца в моем листе Excel. Столбец «ProductID» представляет собой сочетание значений, таких как ########## и n######### .

Я попытался позволить OleDB обрабатывать все сам по себе автоматически , читая его в наборе данных / datatable, но любые значения в «ProductID», такие как n###### , отсутствуют, игнорируются и остаются пустыми. Я попытался вручную создать свой DataTable, перейдя по каждой строке с помощью datareader, но с теми же результатами.

Вот код:

// add the column names manually to the datatable as column_1, column_2, ...
for (colnum = 0; colnum < num_columns; colnum ++){
  ds.Tables["products"].Columns.Add("column_" +colnum , System.Type.GetType("System.String")); 
}
while(myDataReader.Read()){
  // loop through each excel row adding a new respective datarow to my datatable 
  DataRow a_row = ds.Tables["products"].NewRow();
  for (col = 0; col < num_columns; col ++){
    try {  a_row[col] = rdr.GetString(col);  }
    catch {  a_row[col] = rdr.GetValue(col).ToString(); }
  }
  ds.Tables["products"].Rows.Add(a_row);
}

Я не понимаю, почему это не позволит мне читать значения, такие как n###### . Как я могу это сделать?


Answer #1

Без проблем sh4, рад, что это помогает с проблемой смешанного типа.

Столбец DateTime - это все другое животное, которое, как я помню, вызвало у меня горе в прошлом ... у нас есть один файл excel, который мы обрабатываем, что OleDbDataAdapter иногда преобразует даты в двойной тип данных (очевидно, Excel хранит даты как удваивает, которые кодируют число дней, прошедших с 0 января 1900 года).

Обходной путь состоял в том, чтобы использовать:

OleDbConnection mobjExcelConn = new OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + txtExcelFile.Text + @";Extended Properties=""Excel 8.0;IMEX=1;HDR=Yes;""");

OleDbDataAdapter mobjExcelDataAdapter = new OleDbDataAdapter("Select * from [" + txtSheet.Text + "$] where [Supplier ID] <> '' ", mobjExcelConn);


DateTime dtShipStatus = DateTime.MinValue;
shipStatusOrig = excelRow["Est Ship Date"].ToString(); // excelRow is DataRow in the DataSet via the OleDbDataAdapter             

if (shipStatusOrig != string.Empty)
{
    // Date may be read in via oledb adapter as a double
    if (IsNumeric(shipStatusOrig))
    {
        double d = Convert.ToDouble(shipStatusOrig);
        dtShipStatus = DateTime.FromOADate(d);

        if (DateTime.TryParse(dtShipStatus.ToString(), out dtShipStatus))
        {
            validDate = true;
            Debug.WriteLine("{0} converted: ", dtShipStatus.ToString("s"));
        }
    }
    else
    {
        if (ValidateShipDate(shipStatusOrig))
        {
            dtShipStatus = DateTime.Parse(shipStatusOrig);
            validDate = true;
            Debug.WriteLine("{0} converted: ", dtShipStatus.ToString("s"));
        }
        else
        {
            validDate = false;
            MessageBox.Show("Invalid date format in the Excel spreadsheet.\nLine # " + progressBar1.Value + ", the 'Ship Status' value '" + shipStatusOrig + "' is invalid.\nDate should be in a valid date time format.\ne.g. M/DD/YY, M.D.Y, YYYY-MM-DD, etc.", "Invaid Ship Status Date");
        }
    }
...
}
        public static Boolean IsNumeric (Object Expression)
        {
            if(Expression == null || Expression is DateTime)
                return false;

            if(Expression is Int16 || Expression is Int32 || Expression is Int64 || Expression is Decimal || Expression is Single || Expression is Double || Expression is Boolean)
                return true;

            try
            {
                if(Expression is string)
                    Double.Parse(Expression as string);
                else
                   Double.Parse(Expression.ToString());
                return true;
            } catch {} // just dismiss errors but return false

            return false;
        }

        public bool ValidateShipDate(string shipStatus)
        {
            DateTime startDate;
            try
            {
                startDate = DateTime.Parse(shipStatus);
                return true;
            }
            catch
            {
                return false;
            }
        }

Answer #2

Несколько форумов, которые я нашел, утверждают, что добавив IMEX=1;TypeGuessRows=0;ImportMixedTypes=Text в расширенные свойства в строке подключения исправит проблему, но это было не так. Я, наконец, решил эту проблему, добавив «HDR = NO» к расширенным свойствам в строке соединения (как показывает Брайан Уэллс выше), чтобы я мог импортировать смешанные типы.

Затем я добавил некоторый общий код, чтобы назвать столбцы после первой строки данных, а затем удалить первую строку.

    public static DataTable ImportMyDataTableFromExcel(string filePath)
    {
        DataTable dt = new DataTable();

        string fullPath = Path.GetFullPath(filePath);

        string connString =
           "Provider=Microsoft.Jet.OLEDB.4.0;" +
           "Data Source=\"" + fullPath + "\";" +
           "Extended Properties=\"Excel 8.0;HDR=No;IMEX=1;\"";

        string sql = @"SELECT * FROM [sheet1$]";

        using (OleDbDataAdapter dataAdapter = new OleDbDataAdapter(sql, connString))
        {
            dataAdapter.Fill(dt);
        }

        dt = BuildHeadersFromFirstRowThenRemoveFirstRow(dt);

        return dt;
    }

    private static DataTable BuildHeadersFromFirstRowThenRemoveFirstRow(DataTable dt)
    {
        DataRow firstRow = dt.Rows[0];

        for (int i = 0; i < dt.Columns.Count; i++)
        {
            if(!string.IsNullOrWhiteSpace(firstRow[i].ToString())) // handle empty cell
              dt.Columns[i].ColumnName = firstRow[i].ToString().Trim();
        }

        dt.Rows.RemoveAt(0);

        return dt;
    }

Answer #3

Существует два способа обработки смешанных типов данных и excel.

Способ 1

  • Откройте таблицу Excel и установите формат столбца в желаемый формат вручную. В этом случае «Текст».

Способ 2





oledb