2010-12-14 40 views
7

Tengo una hoja de cálculo que es actualizada por otro servidor (fuera de mi control) y necesito automatizar el ingreso de esos datos a SQL 2005. Los datos son siempre la primera página del hoja de cálculo. Sin embargo, el nombre de esa hoja cambia según el número de filas.Importar datos de Excel utilizando SSIS sin conocer el nombre de la hoja

¿Hay alguna forma de ejecutar un trabajo SSIS que extraiga datos de Excel sin conocer el nombre de la hoja de antemano? Parece depender del nombre de la hoja como fuente de datos, pero estoy buscando decir "hoja número 1" o algo similar.

+0

¿Puede consultar las "tablas" (hojas) en el archivo de Excel y luego simplemente usar la primera? – Gabe

+0

Buena idea, pero ¿alguna idea de cómo hacer eso? –

Respuesta

5

Escribo el nombre de la hoja de trabajo en una variable de usuario SSIS. Si no se opone a la inserción de una tarea de secuencia de comandos en su paquete SSIS intente lo siguiente: (Basado en link text)

Excel.Application xlApp = new Excel.ApplicationClass(); 
Excel.Workbook xlWorkBook = xlApp.Workbooks.Open("<Name of your excel app>.xls", 0, xlWorkBook true, 5, "", "", true, Microsoft.Office.Interop.Excel.XlPlatform.xlWindows, "\t", false, false, 0, true, 1, 0); 
// Look up worksheet by index 
Excel.Worksheet xlWorkSheet =(Excel.Worksheet)xlWorkBook.Worksheets.get_Item(1); 

user::worksheetname = xlWorkSheet.Name; 

/* Do clean up. Working with COM object */ 
+0

Esta es la mejor opción en mi opinión, y si tuviera que abordar este problema nuevamente, probaría esta ruta primero. Gracias AdamA! Sin embargo, el proyecto en el que trabajaba ya utilizaba la automatización de la interfaz de usuario, así que terminé agregando un script para automatizar el cambio del nombre. –

+0

Actualización: encontré mi referencia de Excel aquí: C: \ Archivos de programa (x86) \ Microsoft Visual Studio 11.0 \ Herramientas de Visual Studio para Office \ PIA \ Office14 \ Microsoft.Office.Interop.Excel.dll. ¿Cómo obtengo una referencia a "Excel.Application"? ¿Debo agregar una referencia de DLL? Estoy ejecutando Excel de 64 bits con el "Microsoft Access Database Engine 2010 Redistributable" instalado para permitirme usar el código fuente de Excel en SSIS. – PeterX

+1

También parece haber un valor "xlWorkBook" extraviado en el método Open en su código anterior. – PeterX

1

No lo creo ... No conozco ninguna sintaxis de referencia ordinal, por ejemplo, Hojas [0] que pueda usar.

Así que si no puede obtener los datos sin conocer el nombre de la hoja, solo tiene que averiguar dinámicamente el nombre de la hoja. Este enlace en getting Excel schema info in SSIS debería ayudarlo a hacer eso. Una vez que tenga eso, puede pasar el nombre de la hoja como una variable, y listo.

1

He tenido este mismo problema yo mismo en el pasado y no he podido encontrar una solución para tener un archivo de Excel en el que se ha leído su nombre de hoja de archivo en archivo.

Mi suposición, que no pude conseguir para trabajar, sería usar expresiones en las propiedades de la conexión de datos. Necesitaría de alguna manera leer el nombre de la hoja en una variable, luego usar el resultado de esa variable en el nombre de la hoja para la conexión de datos.

La mejor de las suertes para ti, y lo siento, no podría ser de más ayuda.

3

que tenía un problema similar. La solución que implementé fue leer primero el archivo Excel usando la conexión OleDB. Abra la conexión y luego recupere todos los nombres de las hojas. Este es un ejemplo

Dim strConnectionString As String = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\ABC.xls;Extended Properties=""EXCEL 8.0;""" 

Dim lstSheetName As List(Of String) = Nothing 
Try 
objConn = New OleDbConnection(Me.ConnectionString) 
objConn.Open() 
lstSheetName = New List(Of String) 
Using dtSheetTable As DataTable =  objConn.GetOleDbSchemaTable(OleDbSchemaGuid.Tables,Nothing) 

    For Each drRow As DataRow In dtSheetTable.Rows 
    lstSheetName.Add("[" & drRow("TABLE_NAME").ToString().Replace("'", "''") & "]") 
    Next 
End Using 
Catch ex as Exception 
Throw 
Finally 
If objConn.State = ConnectionState.Open Then objConn.Close() 
objConn.Dispose() 
End Try 

Esta todo el código está escrito ASPX.VB y luego estoy ejecutando el paquete SSIS través de código detrás y pasando el primer valor de la variable de lstSheetName (lstSheetName(0).ToString())

Ésta era

4

Solo para el registro, estoy usando este código en Script Task para resolver el problema. Las variables utilizadas son: Nombre de archivo, Nombre de hoja.

Tenga en cuenta que mi nombre de archivo de Excel es dinámico.

// GET NAME OF FIRST SHEET 
string filename = (string)Dts.Variables["Filename"].Value; 
string sheetName = null; 

string connStr = 
    String.Format("Provider=Microsoft.Jet.OLEDB.4.0;Data Source={0};Extended Properties=\"EXCEL 8.0;IMEX=1;\"", filename); 

var conn = new OleDbConnection(connStr); 
try 
{   
    conn.Open(); 

    using(var dtSheet = conn.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, null)) 
    { 
     var row0 = dtSheet.Rows[0]; 
     sheetName = row0["TABLE_NAME"].ToString(); 
    } 
} 
catch (Exception) 
{ 
    throw; 
} 
finally 
{ 
    conn.Close(); 
    conn.Dispose(); 
} 

if (!String.IsNullOrEmpty(sheetName)) 
{ 
    Dts.Variables["SheetName"].Value = sheetName; 
    Dts.Events.FireInformation(1, "User::SheetName", sheetName, "", 0, ref dummy); 
    Dts.TaskResult = (int)ScriptResults.Success; 
} 
else 
{ 
    Dts.Events.FireError(0, "User::SheetName", "No SheetName found!", String.Empty, 0); 
    Dts.TaskResult = (int)ScriptResults.Failure; 
} 
+0

Esto me ayudó, ¡gracias! – KathyBlue

1

Si alguien tiene problemas con el JET Driver, puede utilizar los controladores AccessDatabase ahora. Esto fue adaptado desde arriba y se verifica trabajando en mi máquina, no se necesitan referencias adicionales para esto.

using System; 
using System.Data; 
using Microsoft.SqlServer.Dts.Runtime; 
using System.Windows.Forms; 
using System.Data.OleDb; 

    public void Main() 
    { 
     // GET NAME OF FIRST SHEET 
     string filename = Dts.Variables["User::ActiveFileName"].Value.ToString(); 
     string sheetName = null; 
     bool dummy = true; 

     string connStr = 
      String.Format("Provider=Microsoft.ACE.OLEDB.12.0;Data Source={0};Extended Properties=\"EXCEL 12.0 XML;HDR=YES\";", filename); 
     var conn = new OleDbConnection(connStr); 
     try 
     { 
      conn.Open(); 

      using(var dtSheet = conn.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, null)) 
      { 
       var row0 = dtSheet.Rows[0]; 
       sheetName = row0["TABLE_NAME"].ToString(); 
      } 

      if (!String.IsNullOrEmpty(sheetName)) 
      { 
       Dts.Variables["SheetName"].Value = sheetName; 
       Dts.Events.FireInformation(1, "User::SheetName", sheetName, "", 0, ref dummy); 
       Dts.TaskResult = (int)ScriptResults.Success; 
      } 
      else 
      { 
       throw new Exception("No SheetName found!"); 
      } 
     } 
     catch (Exception ex) 
     { 
      Dts.Events.FireError(0, "User::SheetName", ex.Message, String.Empty, 0); 
      Dts.TaskResult = (int)ScriptResults.Failure; 
     } 
     finally 
     { 
      conn.Close(); 
      conn.Dispose(); 
     } 
    } 
Cuestiones relacionadas