【问题标题】:Get name of the first Excel sheet dynamically and affect it to a variable动态获取第一个 Excel 工作表的名称并将其影响到变量
【发布时间】:2019-06-07 21:46:30
【问题描述】:

我使用 SSIS 加载具有不同工作表名称但结构相同的 xlsx 文件。我只需要加载每个文件的第一张纸,但每次名称不能相同,因此无论名称如何,我都需要始终指向第一张纸。我认为在 Excel 源任务中的数据访问模式下无法使用 index(1st) 这就是为什么我尝试使用任务脚本来获取每个文件的第一张工作表的名称并将其放入变量 Sheet_name 和在每个文件的数据访问模式下使用它。

上面的代码有异常,不知道怎么解决。

我试图在不使用脚本的情况下寻找解决方案,但没有找到,这就是我试图让我的代码工作的原因。

 public void Main()
 {
        String FolderPath = 
  Dts.Variables["User::Folder_To_Be_Processed_Path"].Value.ToString();
  String File_Name = Dts.Variables["User::File_Name"].Value.ToString();
  string fileFullPath = "";
  fileFullPath = FolderPath + "\\" + File_Name;
  string connString = "Provider=Microsoft.Jet.OLEDB.12.0;Data Source=" + 
 fileFullPath + ";Extended Properties=\"Excel 12.0;HDR=YES\";";  

 using (OleDbConnection conn = new OleDbConnection(connString))
{
conn.Open();
MessageBox.Show(connString);
dtSchema = conn.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, new object[] { 
null, null, null, "TABLE" });
Dts.Variables["User::Sheet_Name"].Value= dtSchema.Rows[0].Field<string> 
("TABLE_NAME");
}
    Dts.TaskResult = (int)ScriptResults.Success;
}

【问题讨论】:

    标签: c# sql-server excel ssis etl


    【解决方案1】:

    StackOverflow 和其他社区上有很多类似的帖子,主要思想是 OLEDB 不会按照在 Excel 工作簿中找到的相同顺序检索 Sheet 名称或者您需要对结果表进行排序。

    使用 OLEDB 获取工作表名称

    您应该按 ORDINAL_POSITION 列对 DataTable dtSchema 进行排序,因为 OLEDB 提供程序不会按该顺序返回它们。

    使用互操作库获取工作表名称

    从这个MSDN - post,版主提到:

    恐怕 OLEDB 不会像在 Excel 中那样保留工作表顺序。你必须使用 OLEDB 吗?获取工作表名称的另一种方法是使用 office 互操作类。

    并提供以下代码来获取工作表名称:

    Microsoft.Office.Interop.Excel.Application xlApp = new Microsoft.Office.Interop.Excel.Application();
    Microsoft.Office.Interop.Excel.Workbook excelBook = xlApp.Workbooks.Open("D:\\Book1.xlsx"); 
    
    String[] excelSheets = new String[excelBook.Worksheets.Count];
    int i = 0;
    foreach(Microsoft.Office.Interop.Excel.Worksheet wSheet in excelBook.Worksheets)    
    {
      excelSheets[i] = wSheet.Name;
      i++;
    }
    

    其他有用的链接

    【讨论】:

    • 感谢您的回答@Hadi,您的脚本看起来可以正常工作,因为我添加了一个消息框,我得到的和我文件中的工作表一样多。但是当我将工作表名称影响到我的外部变量时,我仍然遇到异常: Dts.Variables["@User::Sheet_Name"].Value = excelSheets[0];我只需要第一个工作表名称。请帮忙
    • @M.ECH 还注意到变量名区分大小写
    • @M.ECH 确保在脚本 ReadWrite variables 中选择了该变量
    • 它有效,非常感谢您的宝贵答案和宝贵的帮助。感谢大家的帮助。我怎样才能用你的答案结束这个问题,或者这是你的选择?
    • 已经完成了,如果我这边有更多必要的行动,请您检查一下并通知 pe。谢谢。
    【解决方案2】:

    动态检索excel文件表名

     using (OleDbConnection conn = new OleDbConnection(connString))
    {
        conn.Open();
        dtSchema = conn.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, new object[] { null, null, null, "TABLE" });
        Sheet1= dtSchema.Rows[0].Field<string>("TABLE_NAME");
    }
    

    【讨论】:

    • 感谢您的回答@Mohammed Alghanem,但我仍然对 conn.Open(); 的调用有例外。谢谢你的帮助先生。
    • 在适应您的代码后,我已经编辑了我的第一个代码。感谢您的帮助。
    • @M.ECH 请告诉我异常详情是什么?
    • Aghanem,DTS 脚本任务在用户代码中遇到异常:调用的目标抛出异常 System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor ) 在 System.Reflection.RuntimeMethodInfo.UnsafeInvokeInternal(Object obj, Object[] parameters, Object[] arguments) 在 System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfoculture)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多