Compartir a través de


Recopilar una lista para el bucle Foreach con la tarea Script

El enumerador de variable para Foreach enumera los elementos de una lista que le se pasa en una variable y realiza las mismas tareas en cada elemento. Puede utilizar código personalizado en una tarea Script para rellenar una lista con este fin. Para obtener más información sobre el enumerador, vea Contenedor Foreach Loop.

[!NOTA]

Si desea crear una tarea que pueda reutilizar más fácilmente en varios paquetes, considere la posibilidad de utilizar el código de este ejemplo de tarea Script como punto inicial de una tarea personalizada. Para obtener más información, vea Desarrollar una tarea personalizada.

Descripción

En el ejemplo siguiente se utilizan métodos del espacio de nombres System.IO para recopilar una lista de libros de Excel del equipo que son posteriores o anteriores a un número de días especificado por el usuario en una variable. Busca de forma recursiva en los directorios de la unidad C los archivos que tienen la extensión .xls y examina la fecha en la que cada archivo se modificó por última vez para determinar si el archivo pertenece a la lista. Agrega los archivos correspondientes a un objeto ArrayList y guarda el objeto ArrayList en una variable para el uso posterior en un contenedor de bucles Foreach. El contenedor de bucles Foreach se configura para utilizar el enumerador de variable para Foreach.

[!NOTA]

La variable que utiliza con el enumerador de variable para Foreach debe ser del tipo Object. El objeto que incluye en la variable debe implementar una de las interfaces siguientes: System.Collections.IEnumerable, System.Runtime.InteropServices.ComTypes.IEnumVARIANT, System.ComponentModel IListSource o Microsoft.SqlServer.Dts.Runtime.Wrapper.ForEachEnumeratorHost. Normalmente se utiliza Array o ArrayList. ArrayList requiere una referencia y una instrucción Imports para el espacio de nombres System.Collections.

Puede experimentar con esta tarea utilizando diferentes valores positivos y negativos en la variable de paquete FileAge. Por ejemplo, puede escribir 5 para buscar archivos creados en los cinco últimos días o escribir -3 para buscar archivos creados hace más de tres días. Esta tarea puede tardar un minuto o dos en una unidad de disco con un gran número de carpetas donde buscar.

Para configurar este ejemplo de tarea Script

  1. Cree una variable de paquete denominada FileAge del tipo entero y escriba un valor entero positivo o negativo. Cuando el valor es positivo, el código busca archivos posteriores al número especificado de días; cuando es negativo, archivos anteriores al número especificado de días.

  2. Cree una variable de paquete denominada FileList de tipo Object para recibir la lista de archivos recopilada por la tarea Script para su uso posterior en el enumerador de variable para Foreach.

  3. Agregue la variable FileAge a la propiedad ReadOnlyVariables de la tarea Script y la variable FileList a la propiedad ReadWriteVariables.

  4. En el código, importe los espacios de nombres System.Collections y System.IO.

Código

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

        }

    }
Icono de Integration Services (pequeño) Manténgase al día con Integration Services

Para obtener las más recientes descargas, artículos, ejemplos y vídeos de Microsoft, así como soluciones seleccionadas de la comunidad, visite la página de Integration Services en MSDN o TechNet:

Para recibir notificaciones automáticas de estas actualizaciones, suscríbase a las fuentes RSS disponibles en la página.