1

理想的には次のような SSIS パッケージを作成しています。

  • フォルダを読み通す
  • 最新ファイルのファイル名とシート名を取得する
  • ファイル名とシート名を接続マネージャーに渡します
  • 最新のファイルのみをシートごとに抽出してデータベースに読み込みます

フォルダは、ファイルの最新バージョンで定期的に更新されます。問題のファイルには 3 つのシートがあり、特定の順序で順番にロードされます。できれば、ファイル名を使用する代わりに、ファイルの最新の書き込み時刻を介してファイルを取得したいと思います。ファイル名自体はアップロードごとに異なります。

シートをデータベースにロードする際に正しい順序で抽出とロードを行う制御フローを作成しましたが、Excel 接続マネージャーで指定されたファイルからのみ読み取ります。

  • Sheet1: Excel ソース -> OLE DB 宛先
  • Sheet2: Excel ソース -> OLE DB 宛先
  • Sheet3: Excel ソース -> OLE DB 宛先

私が見つけたのは、ファイル名を変数として接続マネージャーに渡すことですが、シート名も考慮した例は見つかりませんでした。誰かがこれをより動的にするのを手伝ってくれませんか?

私は SQL Server 2012 を使用しており、Visual Studio 2010 で設計しています。

4

2 に答える 2

0

VS 2008 でシート名を取得するのを手伝うことができます (おそらく 2010 でも同じです)。

オブジェクト型の変数を作成する (objExcelSheets) スクリプト タスクを作成します。ファイル名/パス変数をスクリプトに追加します (読み取り専用) オブジェクト変数を読み取り/書き込み変数に追加します

スクリプト タスクのコードを次に示します。

Private Sub GetExcelSheets()
    Dim excelFile, connstr, curTable As String
    Dim excelConnection As OleDb.OleDbConnection
    Dim tablesInFile As DataTable
    Dim tablenameInFile As DataRow
    Dim tableCount As Integer = 0
    Dim tableIndex As Integer = 0
    Dim excelTables As String()
    Dim blnFound As Boolean = False

    ReDim excelTables(0)
    excelFile = Dts.Variables("sFilePath").Value.ToString
    connstr = GetExcelConnString()

    excelConnection = New OleDb.OleDbConnection(connstr)
    excelConnection.Open()

    tablesInFile = excelConnection.GetSchema("Tables")
    tableCount = tablesInFile.Rows.Count

    For Each tablenameInFile In tablesInFile.Rows
        curTable = tablenameInFile.Item("TABLE_NAME").ToString.Trim.ToLower

        If curTable.IndexOf("SOMETHING_IN_THE_SHEETS_TO_PROCESS") >= 0 Then
            blnFound = True
            ReDim excelTables(tableIndex)
            excelTables(tableIndex) = "[" + curTable + "]"
            tableIndex += 1
        End If
    Next

    If IsNothing(excelTables(0)) Then excelTables(0) = String.Empty

    excelConnection.Close()

    Dts.Variables("objExcelSheet").Value = excelTables
End Sub

Private Function GetExcelConnString() As String
    Dim sExtendedProperties, sExtension, sFilePath, sExcelConn As String

    sFilePath = Dts.Variables("sFilePath").Value.ToString
    sExtension = sFilePath.Substring(sFilePath.LastIndexOf("."))
    If sExtension.ToLower = ".xlsx" Then
        sExtendedProperties = ";Extended Properties=""EXCEL 12.0;HDR=NO"";"
    ElseIf sExtension.ToLower = ".xls" Then
        sExtendedProperties = ";Extended Properties=""EXCEL 8.0;HDR=NO;IMEX=1"";"
    Else
        sExtendedProperties = String.Empty
    End If

    sExcelConn = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & sFilePath & sExtendedProperties

    Return sExcelConn
End Function

これには ACE ドライバーをインストールする必要があることに注意してください。それらがない場合は、ファイルの接続文字列が何であれ、sExcelConn を置き換える必要があります。

これにより、シート名に SOMETHING_IN_THE_SHEETS_TO_PROCESS が含まれているすべての Excel シートがオブジェクト変数 objExcelSheet に配置されます。これを必要なものに置き換えたり、まとめて削除したりできます。

その後、ForEach ループを実行して各シートを処理できます。

変数列挙子からの Foreach - 変数 = objExcelSheet

変数マッピング - 変数 (インデックス 0 の WorksheetName)

これは、処理するシートを動的に選択し、そこから必要なことを実行できる場所で、必要なものを取得するのに役立ちます。

于 2013-11-13T22:05:05.277 に答える