使用SSIS从Excel导入数据而不知道工作表名称

时间:2010-12-14 20:58:21

标签: sql excel ssis

我有一个由另一台服务器更新的电子表格(我无法控制),我需要自动将这些数据导入SQL 2005.数据始终是电子表格的第一页。但是,该工作表的名称会根据行数而变化。

有没有办法在不事先知道工作表名的情况下运行从Excel中提取数据的SSIS作业?它似乎依赖于工作表名称作为数据源,但我希望将其称为“工作表编号1”或类似的东西。

6 个答案:

答案 0 :(得分:6)

我会将工作表名称编写为SSIS用户变量。如果您不反对将脚本任务插入SSIS包,请尝试:(基于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 */

答案 1 :(得分:4)

仅供记录,我在Script Task中使用此代码来解决问题。使用的变量是:文件名 SheetName

请注意,我的Excel文件名是动态的。

// 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;
}

答案 2 :(得分:3)

我有类似的问题。我实现的解决方案是首先使用OleDB连接读取excel文件。打开连接,然后检索所有工作表名称。这是一个例子

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

这个代码全部写成ASPX.VB然后我通过代码执行SSIS包并传递lstSheetName变量(lstSheetName(0).ToString())中的第一个值

这是

答案 3 :(得分:1)

我不这么认为......我不知道任何序数参考语法,例如你可以使用的Sheets [0]。

因此,如果您在不知道工作表名称的情况下无法获取数据,则只需动态找出工作表名称即可。 getting Excel schema info in SSIS上的此链接可以帮助您实现这一目标。完成后,您可以将工作表名称作为变量传递,然后离开。

答案 4 :(得分:1)

我过去曾遇到过同样的问题,而且无法找到一个解决方案,要求读取一个Excel文件,其中的工作表名称会因文件而异。

我的猜测,我无法开始工作,将在数据连接的属性中使用表达式。您需要以某种方式将工作表名称读取到变量中,然后在数据连接的工作表名称中使用该变量的结果。

祝你好运,对不起,我无法提供更多帮助。

答案 5 :(得分:1)

如果有任何人遇到JET驱动程序问题,您现在可以使用AccessDatabase驱动程序。这是从上面改编而来,经验证在我的机器上工作,不需要额外的参考。

> suppressWarnings(suppressMessages(result <- flights %>% 
+         select(year:day, hour, origin, dest, tailnum, carrier) %>% 
+         left_join(airlines)))
>