スクリプト タスクによる ForEach ループの一覧の収集

Foreach from Variable 列挙子は、変数で渡された一覧の項目を列挙し、各項目に対して同じタスクを実行します。 スクリプト タスクでカスタム コードを使用して、このための一覧を設定することができます。 この列挙子の詳細については、「Foreach ループ コンテナー」を参照してください。

注意

複数のパッケージでより簡単に再利用できるタスクを作成する場合は、このスクリプト タスク サンプルのコードを基にした、カスタム タスクの作成を検討してください。 詳細については、「カスタム タスクの開発」を参照してください。

説明

次の例は、System.IO 名前空間のメソッドを使用して、ユーザーが変数で指定した日数より新しいまたは古い Excel ブックの一覧をコンピューターで収集します。 拡張子 .xls を持つファイルを探して C ドライブのディレクトリを再帰的に検索し、各ファイルの最終更新日を調べて、一覧に属するかどうかを判定します。 該当するファイルを ArrayList に追加した後、その ArrayList を変数に保存して、後に Foreach ループ コンテナーで使用できるようにします。 この Foreach ループ コンテナーは、Foreach from Variable 列挙子を使用するように構成されています。

注意

Foreach from Variable 列挙子で使用する変数は、Object 型である必要があります。 変数に配置するオブジェクトは、System.Collections.IEnumerable、System.Runtime.InteropServices.ComTypes.IEnumVARIANT、System.ComponentModel IListSource、Microsoft.SqlServer.Dts.Runtime.Wrapper.ForEachEnumeratorHost のいずれかのインターフェイスを実装する必要があります。 Array または ArrayList が一般に使用されます。 ArrayList は、System.Collections 名前空間に対する参照と Imports ステートメントを必要とします。

このタスクは、FileAge パッケージ変数に対して正および負のさまざまな値を使用することによってテストできます。 たとえば、この 5 日間に作成されたファイルを検索するには 5 を入力し、3 日前よりも前に作成されたファイルを検索するには -3 を入力します。 このタスクは、検索するフォルダーの数が多いドライブの場合、実行に 1 ~ 2 分かかることがあります。

このスクリプト タスクの例を構成するには

  1. FileAge という integer 型のパッケージ変数を作成し、正または負の整数値を入力します。 値が正の場合は、指定した日数より新しいファイルが検索され、値が負の場合は、指定した日数より古いファイルが検索されます。

  2. スクリプト タスクによって収集されたファイルの一覧を受け取るために、FileList という Object 型のパッケージ変数を作成します。この変数を後に Foreach from Variable 列挙子で使用します。

  3. FileAge 変数をスクリプト タスクの ReadOnlyVariables プロパティに追加し、FileList 変数を ReadWriteVariables プロパティに追加します。

  4. コードに System.Collections および System.IO 名前空間をインポートします。

コード

Imports System
Imports System.Data
Imports System.Math
Imports Microsoft.SqlServer.Dts.Runtime
Imports System.Collections
Imports System.IO

Public Class ScriptMain

  Private Const FILE_AGE As Integer = -50

  Private Const FILE_ROOT As String = "C:\"
  Private Const FILE_FILTER As String = "*.xls"

  Private isCheckForNewer As Boolean = True
  Dim fileAgeLimit As Integer
  Private listForEnumerator As ArrayList

  Public Sub Main()

    fileAgeLimit = DirectCast(Dts.Variables("FileAge").Value, Integer)

    ' If value provided is positive, we want files NEWER THAN n days.
    '  If negative, we want files OLDER THAN n days.
    If fileAgeLimit < 0 Then
      isCheckForNewer = False
    End If
    ' Extract number of days as positive integer.
    fileAgeLimit = Math.Abs(fileAgeLimit)

    listForEnumerator = New ArrayList

    GetFilesInFolder(FILE_ROOT)

    ' Return the list of files to the variable
    '  for later use by the Foreach from Variable enumerator.
    System.Windows.Forms.MessageBox.Show("Matching files: " & listForEnumerator.Count.ToString, "Results", Windows.Forms.MessageBoxButtons.OK, Windows.Forms.MessageBoxIcon.Information)
    Dts.Variables("FileList").Value = listForEnumerator

    Dts.TaskResult = ScriptResults.Success

  End Sub

  Private Sub GetFilesInFolder(ByVal folderPath As String)

    Dim localFiles() As String
    Dim localFile As String
    Dim fileChangeDate As Date
    Dim fileAge As TimeSpan
    Dim fileAgeInDays As Integer
    Dim childFolder As String

    Try
      localFiles = Directory.GetFiles(folderPath, FILE_FILTER)
      For Each localFile In localFiles
        fileChangeDate = File.GetLastWriteTime(localFile)
        fileAge = DateTime.Now.Subtract(fileChangeDate)
        fileAgeInDays = fileAge.Days
        CheckAgeOfFile(localFile, fileAgeInDays)
      Next

      If Directory.GetDirectories(folderPath).Length > 0 Then
        For Each childFolder In Directory.GetDirectories(folderPath)
          GetFilesInFolder(childFolder)
        Next
      End If

    Catch
      ' Ignore exceptions on special folders such as System Volume Information.
    End Try

  End Sub

  Private Sub CheckAgeOfFile(ByVal localFile As String, ByVal fileAgeInDays As Integer)

    If isCheckForNewer Then
      If fileAgeInDays <= fileAgeLimit Then
        listForEnumerator.Add(localFile)
      End If
    Else
      If fileAgeInDays > fileAgeLimit Then
        listForEnumerator.Add(localFile)
      End If
    End If

  End Sub

End Class
using System;
using System.Data;
using System.Math;
using Microsoft.SqlServer.Dts.Runtime;
using System.Collections;
using System.IO;

public partial class ScriptMain : Microsoft.SqlServer.Dts.Tasks.ScriptTask.VSTARTScriptObjectModelBase
    {

        
        private const int FILE_AGE = -50;

        private const string FILE_ROOT = "C:\\";
        private const string FILE_FILTER = "*.xls";

        private bool isCheckForNewer = true;
        int fileAgeLimit;
        private ArrayList listForEnumerator;

        public void Main()
  {

    fileAgeLimit = (int)(Dts.Variables["FileAge"].Value);

    // If value provided is positive, we want files NEWER THAN n days.
    // If negative, we want files OLDER THAN n days.
    if (fileAgeLimit<0)
    {
      isCheckForNewer = false;
    }
    // Extract number of days as positive integer.
    fileAgeLimit = Math.Abs(fileAgeLimit);

    ArrayList listForEnumerator = new ArrayList();

    GetFilesInFolder(FILE_ROOT);

    // Return the list of files to the variable
    // for later use by the Foreach from Variable enumerator.
    System.Windows.Forms.MessageBox.Show("Matching files: "+ listForEnumerator.Count, "Results", 
MessageBoxButtons.OK, MessageBoxIcon.Information);
    Dts.Variables["FileList"].Value = listForEnumerator;

    Dts.TaskResult = (int)ScriptResults.Success;

  }

        private void GetFilesInFolder(string folderPath)
        {

            string[] localFiles;
            DateTime fileChangeDate;
            TimeSpan fileAge;
            int fileAgeInDays;

            try
            {
                localFiles = Directory.GetFiles(folderPath, FILE_FILTER);
                foreach (string localFile in localFiles)
                {
                    fileChangeDate = File.GetLastWriteTime(localFile);
                    fileAge = DateTime.Now.Subtract(fileChangeDate);
                    fileAgeInDays = fileAge.Days;
                    CheckAgeOfFile(localFile, fileAgeInDays);
                }

                if (Directory.GetDirectories(folderPath).Length > 0)
                {
                    foreach (string childFolder in Directory.GetDirectories(folderPath))
                    {
                        GetFilesInFolder(childFolder);
                    }
                }

            }
            catch
            {
                // Ignore exceptions on special folders, such as System Volume Information.
            }

        }

        private void CheckAgeOfFile(string localFile, int fileAgeInDays)
        {

            if (isCheckForNewer)
            {
                if (fileAgeInDays <= fileAgeLimit)
                {
                    listForEnumerator.Add(localFile);
                }
            }
            else
            {
                if (fileAgeInDays > fileAgeLimit)
                {
                    listForEnumerator.Add(localFile);
                }
            }

        }

    }
Integration Services のアイコン (小) 最新の Integration Services の入手

マイクロソフトが提供する最新のダウンロード、アーティクル、サンプル、ビデオ、およびコミュニティで選択されたソリューションについては、MSDN の Integration Services のページを参照してください。


これらの更新が自動で通知されるようにするには、ページの RSS フィードを定期受信します。

関連項目

タスク

Foreach ループ コンテナーを構成する

概念

Foreach ループ コンテナー