2011-03-03 30 views
9

Sé que este tipo de preguntas se realizan de vez en cuando, pero no puedo encontrar ninguna solución satisfactoria.Microsoft.ACE.OLEDB.12.0 CSV ConnectionString

¿Cómo puedo abrir un archivo CSV utilizando MS ACE OLEDB 12? Lo intento con el siguiente código.

DbConnection connection = new OleDbConnection(); 
connection.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\\Documents;Extended Properties=\"Text;HDR=Yes\""; 
connection.Open(); 
DbCommand cmd; 

cmd = connection.CreateCommand(); 
cmd.CommandText = "SELECT * FROM [Mappe1#csv]"; 
DbDataReader reader = cmd.ExecuteReader(); 

while (reader.Read()) 
{ 
    for (int i = 0; i < reader.FieldCount; i++) 
     Console.Write("(" + reader.GetValue(i).ToString() + ")"); 

    Console.WriteLine(); 
} 

cmd.Dispose(); 
connection.Dispose(); 
Console.WriteLine("Done"); 
Console.ReadKey(); 

El problema es que solo se encuentra una columna. El texto está delimitado por ';' Incluso cuando especifico el delimitador con "Delimited (|)" f.e. no funcionará.

No puedo encontrar ninguna documentación para este proveedor ...

+0

Nos estamos alejando cada vez más de ACE. Tiene muchos problemas (casi sin documentación, sin soporte, problemas con caracteres específicos en los datos o nombres de la hoja de trabajo, ...). Descubrimos que, si tiene un diseño limpio, es más rápido, más fácil y más confiable usar Interop que ACE. Adicional para CSV, estamos utilizando otra API (lector de CSV de LumenWorks: http://www.codeproject.com/Articles/9258/A-Fast-CSV-Reader) – SACO

Respuesta

0

Probar:

connection.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\\Documents;Extended Properties=\"Text;HDR=Yes;FORMAT=Delimited\""; 

(inserción de "FORMATO = delimitado" en las propiedades extendidas de la cadena de conexión ...)

+0

No; ningún cambio. También probé FMT = TabDelimited (para un archivo Tab). – SACO

+0

Es difícil de decir, entonces ... Esa es la cadena de conexión exacta que uso en mi proyecto para leer un csv y funciona como un amuleto. La única otra diferencia estaría en la declaración de selección. Tengo "select * from file.csv", especificando el nombre de archivo directamente. No he visto antes la sintaxis "[mappe1 # csv]" - ¿es el nombre del archivo "mappe1 # csv" o es solo otra forma de especificar "mappe1.csv"? He tenido un error antes si la extensión del archivo no es ".csv". – blech

+1

Lo intentaré. mappe1 # csv es el nombre que será proporcionado por connection.GetSchema(). – SACO

6

Esto me ayudó a conseguir un csv delimitado por punto y coma para analizar en C# usando ACE.OLEDB.12.0: http://sqlserverpedia.com/blog/sql-server-bloggers/use-ace-drivers-and-powershell-to-talk-to-text-files/:

Cre comió un archivo de texto schema.ini en el mismo directorio que el archivo CSV que desea importar con el siguiente contenido:

[fileIwantToImport.csv] 
Format=Delimited(;) 
ColNameHeader=True 

a mí me funcionó. Pero tan asqueroso

Parece que el FORMAT=Delimited(;) en la cadena de conexión ha pasado de moda ...

+2

Bruto, pero funciona! –

-1

¿Usted ha considerado la creación de conjunto de datos?

public static DataSet ConvertTabFiles(string File, string TableName, string delimiter) 
    { 
     //The DataSet to Return 
     DataSet result = new DataSet(); 

     //Open the file in a stream reader. 
     StreamReader s; 
     try 
     { 
      s = new StreamReader(@File); 
     } 
     catch 
     { 
      MessageBox.Show("Can't perform operation on file: " + File); 
      return result; 
     } 

     //Split the first line into the columns 
     string[] columns = null; 
     try 
     { 
      columns = s.ReadLine().Split(delimiter.ToCharArray()); 
     } 
     catch 
     { 
      MessageBox.Show("Can't parse the file " + File + ", please try again!"); 
      return result; 
     } 

     //Add the new DataTable to the RecordSet 
     result.Tables.Add(TableName); 
     //MessageBox.Show("Add the new DataTable to the RecordSet"); 

     //Cycle the colums, adding those that don't exist yet 
     //and sequencing the one that do. 
     foreach (string col in columns) 
     { 
      bool added = false; 
      string next = ""; 
      int i = 0; 
      while (!added) 
      { 
       //Build the column name and remove any unwanted characters. 
       string columnname = col + next; 

       //See if the column already exists 
       if (!result.Tables[TableName].Columns.Contains(columnname)) 
       { 
        //if it doesn't then we add it here and mark it as added 
        result.Tables[TableName].Columns.Add(columnname); 
        added = true; 
       } 
       else 
       { 
        //if it did exist then we increment the sequencer and try again. 
        i++; 
        next = "_" + i.ToString(); 
       } 
      } 
     } 

     //Read the rest of the data in the file.   
     string AllData = s.ReadToEnd(); 

     string[] rows = AllData.Split("\r\n".ToCharArray()); 

     //Now add each row to the DataSet   
     foreach (string r in rows) 
     { 
      //Split the row at the delimiter. 
      string[] items = r.Split(delimiter.ToCharArray()); 
      //Add the item 
      result.Tables[TableName].Rows.Add(r); 
     } 
     //Return the imported data. 
     return result; 
    } 
+0

Esto es como implementar su propio CSV-Reader. Actualmente estamos usando otro CSV-Reader. – SACO

+1

Esto fallará en los datos con delimitadores incrustados, por ejemplo, una coma dentro de lo que debería ser un solo campo en un Archivo CSV. –

Cuestiones relacionadas