Pensé en hacerlo en VB.net.
El código del compañero @Mad Antrax está muy pero que muy bien, sin embargo, al escucharte decir eso me han entrado ganas de mostrarte un ejemplo alternativo e iguálmente funcional en dicho lenguaje, ya que igual que tengo bien sabido que @
Mad Antrax ama VBS, yo amo Vb.Net
. Si lo hicieras en .Net (VB.Net o C#) la eficacia general del código aumentaria considerablemente en comparación con un lenguaje de scripting limitado (sobre todo si hablamos de Batch), aunque en realidad, con VBS tienes más que suficiente para llevar a cabo esa tarea.
Aquí tienes el archivo de la solución de
Visual Studio 2013, como ya he mencionado cumple todas las funciones que has pedido, eso sí, lo que quieras añadir o modificar ya es cosa tuya. Si tienes preguntas sobre este lenguaje por favor hazlas en el subforo correspondiente, no desviemos más el tema aquí.
http://www.mediafire.com/download/4qoklj8s64jwuvv/WindowsApplication6.rarY aquí te muestro parte del código fuente. El resto del código que no muestro aquí simplemente es el código generado automaticamente por VS, el código de la UI.
Por mencionar algo de este código que te puede interesar rehutilizable para el futuro, en la función
GetMonthName utilizo un objeto de globalización ,
CultureInfo, del cual obtengo de forma administrada los nombres de los meses en la cultura específica, en este caso "es-ES".
Te lo he dejado todo con varios comentarios para que te ayuden a comprender lo que hago.
MainForm.vb
Imports System
Imports System.IO
Imports System.Linq
Imports System.Windows.Forms
Public NotInheritable Class MainForm : Inherits Form
Private year As Integer = DateTime.Today.Year ' O... '2015'
Private sourceDir As String = Directory.GetCurrentDirectory() ' O... ".\"
Public Sub New()
Me.InitializeComponent()
With Me.DTPMonth ' Personalizo el formato de entrada del DateTimePicker.
.CustomFormat = "MM" ' 01-12
.Format = DateTimePickerFormat.Custom
.Value = DateTime.Today
End With
End Sub
Private Sub BtAccept_Click(ByVal sender As Object, ByVal e As EventArgs) _
Handles BtAccept.Click
' Obtengo la ruta absoluta del directorio con fecha. (ej. "C:\Ruta\Octubre2015")
Dim monthNumber As Integer = Me.DTPMonth.Value.Month
Dim dateDir As String = DateUtil.GetDateDirPath("es-ES", Me.sourceDir, Me.year, monthNumber)
' Creo el directorio con fecha (si no existe).
DateUtil.CreateDirectory(dateDir)
' Muevo los directorios (si alguno) con formato de fecha específico (ej. "yyyyMMdd"), del directorio fuente, al directorio de destino.
DateUtil.MoveDateDirectories(Me.year, monthNumber, DateUtil.DirNameFormat, sourceDir, dateDir)
End Sub
Private Sub BtCancel_Click(ByVal sender As Object, ByVal e As EventArgs) _
Handles BtCancel.Click
' Cierro este form, y con él termina la ejecución de la aplicación.
Me.Close()
End Sub
End Class
+
DateUtil.vb
Imports System
Imports System.Globalization
Imports System.IO
Imports System.Linq
Imports System.Security.AccessControl
Imports System.Security.Principal
Public Module DateUtil
''' <summary>
''' El formato por defecto del nombre de directorio. ("yyyyMMdd" equivale a "AñoMesDia").
''' </summary>
''' <remarks>
''' El formato se puede cambiar, pero respetando los especificadores actuales, que son "yyyy", "MM" y "dd", los cuales son intercambiables entre si.
''' Para usar otros especificadores haría falta una refactorización del código (el método <see cref="MoveDateDirectories"/>) para implementar su soporte.
''' Los especificadores disponibles se pueden encontrar en la documentación online de MSDN:
''' https://msdn.microsoft.com/en-us/library/8kb3ddd4%28v=vs.110%29.aspx
''' </remarks>
Public Const DirNameFormat As String = "yyyyMMdd" ' ej. "20150131"
''' <summary>
''' Devuelve el nombre de un mes del año, en el lenguaje específicado.
''' </summary>
Public Function GetMonthName(ByVal cultureName As String,
ByVal month As Integer) As String
If (month < 1I) OrElse (month > 12I) Then
Throw New ArgumentOutOfRangeException(paramName:="month", message:="A value from range '1' to '12' is required.")
ElseIf Not (From ci As CultureInfo In CultureInfo.GetCultures(CultureTypes.InstalledWin32Cultures)
Where ci.Name.Equals(cultureName, StringComparison.OrdinalIgnoreCase)).Any Then
Throw New NotImplementedException(message:=String.Format("Culture '{0}' not recognized, maybe name is wrong typed or culture is not installed.", cultureName))
Else
Dim ci As CultureInfo = CultureInfo.GetCultureInfo(cultureName)
Return ci.TextInfo.ToTitleCase(ci.DateTimeFormat.MonthNames(month - 1))
End If
End Function
''' <summary>
''' Devuelve la ruta absoluta del directorio de destino con el nombre de la fecha, en el lenguaje específicado.
''' ej. "C:\Ruta\Octubre2015"
''' </summary>
Public Function GetDateDirPath(ByVal cultureName As String,
ByVal targetDir As String,
ByVal year As Integer,
ByVal month As Integer) As String
If (CStr(year).Length <> 4I) Then
Throw New ArgumentOutOfRangeException(paramName:="year", message:="A value of 4 digits' is required.")
ElseIf (month < 1I) OrElse (month > 12I) Then
Throw New ArgumentOutOfRangeException(paramName:="month", message:="A value from range '1' to '12' is required.")
Else
Return Path.Combine(targetDir, String.Format("{0}{1}", DateUtil.GetMonthName(cultureName, month), year))
End If
End Function
''' <summary>
''' Crea un directorio en el directorio especificado.
''' </summary>
Public Sub CreateDirectory(ByVal targetDir As String)
' Le asigno permisos de usuario personalizados a la carpeta existente o la carpeta que se creará.
Dim userId As SecurityIdentifier = WindowsIdentity.GetCurrent.User
Dim dirSec As New DirectorySecurity
With dirSec
.AddAccessRule(New FileSystemAccessRule(userId, FileSystemRights.CreateDirectories, AccessControlType.Allow))
.AddAccessRule(New FileSystemAccessRule(userId, FileSystemRights.CreateFiles, AccessControlType.Allow))
.AddAccessRule(New FileSystemAccessRule(userId, FileSystemRights.ListDirectory, AccessControlType.Allow))
.AddAccessRule(New FileSystemAccessRule(userId, FileSystemRights.ReadAndExecute, AccessControlType.Allow))
.AddAccessRule(New FileSystemAccessRule(userId, FileSystemRights.Write, AccessControlType.Allow))
' .AddAccessRule(New FileSystemAccessRule(userId, FileSystemRights.FullControl, AccessControlType.Allow))
End With
If Directory.Exists(targetDir) Then
Directory.SetAccessControl(targetDir, dirSec)
Else
Directory.CreateDirectory(targetDir, directorySecurity:=dirSec)
End If
End Sub
''' <summary>
''' Mueve los directorios cuyo nombre contenga un formato de fecha especifico (intercambiable entre "yyyy", "MM", y "dd") al directorio de destino especificado.
''' </summary>
Public Sub MoveDateDirectories(ByVal year As Integer,
ByVal month As Integer,
ByVal dateFormat As String,
ByVal sourceDir As String,
ByVal targetDir As String)
If (CStr(year).Length <> 4I) Then
Throw New ArgumentOutOfRangeException(paramName:="year", message:="A value of 4 digits' is required.")
ElseIf (month < 1I) OrElse (month > 12I) Then
Throw New ArgumentOutOfRangeException(paramName:="month", message:="A value from range '1' to '12' is required.")
ElseIf (dateFormat.Replace("y", "").Replace("M", "").Replace("d", "").Length <> 0) Then
Throw New NotImplementedException(message:="Specified date format is not implemented, only 'yyyy', 'MM' and 'dd' are interchangeable.")
ElseIf Not Directory.Exists(sourceDir) Then
Throw New DirectoryNotFoundException(message:=String.Format("Source directory not found: '{0}'", sourceDir))
ElseIf Not Directory.Exists(targetDir) Then
Throw New DirectoryNotFoundException(message:=String.Format("Target directory not found: '{0}'", targetDir))
Else
Dim sourceDirInfo As New DirectoryInfo(sourceDir)
Dim targetDirInfo As New DirectoryInfo(targetDir)
' Obtengo una colección con los nombres de directorio con el formato de fecha especificado. (ej. de Octubre 2015: 20151001 ... 20151031)
Dim dateDirNames As IEnumerable(Of String) =
From day As Integer In Enumerable.Range(1, DateTime.DaysInMonth(year, month))
Select dateFormat.Replace("yyyy", CStr(year)).
Replace("MM", CStr(month).PadLeft(2, "0"c)).
Replace("dd", CStr(day).PadLeft(2, "0"c))
' Obtengo una colección con las rutas absolutas de los directorios que cumplen las condiciones de formato de fecha.
Dim directories As IEnumerable(Of DirectoryInfo) =
From dirInfo As DirectoryInfo In sourceDirInfo.EnumerateDirectories("*", SearchOption.TopDirectoryOnly)
Where dateDirNames.Contains(dirInfo.Name)
' Un simple mensaje de información o aviso cuando no se encuentra ningún directorio el cual mover.
If (Not directories.Any) Then
Dim msg As String = String.Format("No ha sido encontrado ningún directorio en '{0}' que cumpla las condiciones de formato de fecha.", sourceDirInfo.FullName)
MessageBox.Show(msg, "By Elektro", MessageBoxButtons.OK, MessageBoxIcon.Information)
Else
' Por último, muevo los directorios que cumplieron las condiciones de formato de fecha.
For Each dirInfo As DirectoryInfo In directories
Debug.
WriteLine(String.
Format("Moviendo: {0}", dirInfo.
FullName))
Try
dirInfo.MoveTo(Path.Combine(targetDirInfo.FullName, dirInfo.Name))
Catch ex As Exception
Throw ex
#Else
MessageBox.Show(ex.Message & Environment.NewLine & ex.StackTrace, "By Elektro", MessageBoxButtons.OK, MessageBoxIcon.Error)
#End If
End Try
Next dirInfo
End If ' Not directories.Any
End If ' dateFormat...
End Sub
End Module
Que lo apreveches.
Saludos!