Samla in en lista för ForEach-loopen med skriptuppgiften

Gäller för:SQL Server SSIS Integration Runtime i Azure Data Factory

Foreach från variabeluppräknaren enumererar över elementen i en lista som skickas till den i en variabel och utför samma uppgifter på varje objekt. Du kan använda anpassad kod i en Script-uppgift för att fylla i en lista för detta ändamål. För mer information om enumeratorn, se Foreach Loop Container.

Note

Om du vill skapa en uppgift som du lättare kan återanvända över flera paket, överväg att använda koden i detta Script-uppgiftsexempel som utgångspunkt för en anpassad uppgift. Mer information finns i Utveckla en anpassad uppgift.

Description

Följande exempel använder metoder från System.IO namnrymden för att samla in en lista över Excel arbetsböcker på datorn som är antingen nyare eller äldre än ett antal dagar som användaren angav i en variabel. Den söker rekursivt i kataloger på Drive C efter filer med filändelsen .xls och undersöker datumet då varje fil senast ändrades för att avgöra om filen hör hemma i listan. Den lägger till kvalificerande filer i en ArrayList och sparar ArrayList till en variabel för senare användning i en Foreach Loop-container. Foreach Loop-containern är konfigurerad att använda Foreach from Variable enumerator.

Note

Variabeln som du använder med Foreach från Variabeluppräknaren måste vara av typen Objekt. Objektet som du placerar i variabeln måste implementera ett av följande gränssnitt: System.Collections.IEnumerable, System.Runtime.InteropServices.ComTypes.IEnumVARIANT, System.ComponentModel IListSource eller Microsoft. SqlServer.Dts.Runtime.Wrapper.ForEachEnumeratorHost. En Array eller ArrayList används ofta. ArrayList kräver en referens och ett Imports-sats för System.Collections-namnrymden.

Du kan experimentera med denna uppgift genom att använda olika positiva och negativa värden för paketvariabeln FileAge . Till exempel kan du skriva in 5 för att söka efter filer skapade under de senaste fem dagarna, eller slå in -3 för att söka efter filer som skapades för mer än tre dagar sedan. Denna uppgift kan ta en minut eller två på en enhet med många mappar att söka i.

För att konfigurera detta exempel på Script Task

  1. Skapa en paketvariabel med namnet FileAge heltalstyp och ange ett positivt eller negativt heltalsvärde. När värdet är positivt söker koden efter filer som är nyare än det angivna antalet dagar; när negativt, för filer äldre än det angivna antalet dagar.

  2. Skapa en paketvariabel med namnet FileListObject för att ta emot listan över filer som samlats in av Script-uppgiften för senare användning av Foreach from Variable Enumerator.

  3. Lägg till variabeln FileAge i Script-uppgiftens egenskap ReadOnlyVariables , och lägg till variabeln FileList i egenskapen ReadWriteVariables .

  4. I din kod, importera System.Collections och de System.IO namnrymderna.

Kod

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