2010-12-14 51 views
7

Tôi có bảng tính được máy chủ khác cập nhật (ngoài tầm kiểm soát của tôi) và tôi cần tự động đưa dữ liệu đó vào SQL 2005. Dữ liệu luôn là trang đầu tiên của bảng tính. Tuy nhiên, tên của trang tính đó thay đổi tùy thuộc vào số hàng.Nhập dữ liệu từ Excel bằng SSIS mà không biết tên trang tính

Có cách nào để chạy công việc SSIS lấy dữ liệu từ Excel mà không biết trước tên trang tính không? Dường như nó dựa vào tên trang tính làm nguồn dữ liệu, nhưng tôi đang tìm cách nói với nó "trang tính số 1" hoặc một cái gì đó tương tự.

+0

Bạn có thể truy vấn "bảng" (trang tính) trong tệp Excel và sau đó chỉ sử dụng bảng đầu tiên? – Gabe

+0

Ý nghĩ hay, nhưng có ý tưởng nào không? –

Trả lời

5

Tôi sẽ viết tên bảng tính thành Biến số người dùng SSIS. Nếu bạn không phải là trái ngược với cách chèn một nhiệm vụ kịch bản vào gói SSIS bạn thử điều này: (Dựa trên 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

Đây là lựa chọn tốt nhất trong quan điểm của tôi, và nếu tôi phải tiếp cận vấn đề này một lần nữa, tôi sẽ thử tuyến đường này trước. Cảm ơn AdamA! Dự án tôi đã làm việc đã được sử dụng tự động hóa giao diện người dùng, vì vậy, tôi đã kết thúc chỉ cần thêm một kịch bản để tự động thay đổi tên. –

+0

Cập nhật: Tôi tìm thấy tài liệu tham khảo Excel của tôi ở đây: C: \ Program Files (x86) \ Microsoft Visual Studio 11.0 \ Công cụ Visual Studio cho Office \ PIA \ Office14 \ Microsoft.Office.Interop.Excel.dll. Tôi làm cách nào để tham chiếu đến "Excel.Application"? Tôi có cần thêm một tài liệu tham khảo DLL không? Tôi đang chạy Excel 64-bit với "Microsoft Access Database Engine 2010 Redistributable" được cài đặt để cho phép tôi sử dụng nguồn Excel trong SSIS. – PeterX

+1

Có vẻ như giá trị "xlWorkBook" bị gián đoạn trong phương thức Open trong mã của bạn ở trên. – PeterX

1

Tôi không nghĩ vậy ... Tôi không biết bất kỳ cú pháp tham chiếu thứ tự nào, ví dụ: Trang tính [0] mà bạn có thể sử dụng.

Vì vậy, nếu bạn không thể lấy dữ liệu mà không biết tên trang tính - bạn chỉ cần tìm kiếm động tên trang tính. Liên kết này trên getting Excel schema info in SSIS sẽ giúp bạn làm điều đó. Một khi bạn có điều đó, bạn có thể chuyển tên trang tính vào dưới dạng biến, và bạn sẽ đi.

1

Tôi đã từng gặp vấn đề tương tự trong quá khứ và không thể tìm thấy giải pháp để đọc tệp Excel trong đó có thay đổi tên trang tính từ tệp thành tệp.

Tôi đoán, điều mà tôi không thể làm việc, sẽ sử dụng các biểu thức trong thuộc tính của kết nối dữ liệu. Bạn sẽ cần phải bằng cách nào đó đọc tên trang tính thành một biến, sau đó sử dụng kết quả của biến đó trong tên trang tính cho kết nối dữ liệu.

Chúc bạn may mắn và xin lỗi tôi không thể trợ giúp thêm.

3

Tôi đã có một vấn đề tương tự. Các giải pháp mà tôi thực hiện lần đầu tiên được đọc các tập tin excel bằng cách sử dụng kết nối OleDB. Mở kết nối và sau đó lấy tất cả các tên trang tính. Dưới đây là một ví dụ

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 

tất cả các mã này được viết ASPX.VB và sau đó tôi đang thực hiện các gói SSIS qua mã phía sau và đi qua các giá trị đầu tiên trong lstSheetName biến (lstSheetName(0).ToString())

Đây là

4

Chỉ cần cho các hồ sơ, tôi đang sử dụng mã này trong Script Task để giải quyết vấn đề. Các biến được sử dụng là: Tên tệp, Tên bảng.

Lưu ý rằng tên tệp Excel của tôi là động.

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

Điều này đã giúp tôi, cảm ơn! – KathyBlue

1

Nếu có ai gặp sự cố với trình điều khiển JET, bạn có thể sử dụng trình điều khiển AccessDatabase ngay bây giờ. Điều này đã được điều chỉnh từ trên cao và được xác minh khi làm việc trên máy tính của tôi, không cần thêm tài liệu tham khảo cho điều này.

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(); 
     } 
    } 
Các vấn đề liên quan