Revisión del 30/Mar/1998
Actualizado: 05/Ago/2003
Pulsa este link para ver la versión del
05/Ago/2003
Pulsa este link
para ver la nueva versión del 30/Abr/2001
(muy mejorada)
En esta página tienes la
última versión del 29/Mar/2007
Me imagino que no seré el único al que el reloj del sistema se le va la "olla", es más, últimamente el reloj de mi equipo es un "chivato", ya que se queda con la fecha y hora que tenía cuando lo apagué. Al menos si lo dejo reposar unas cuantas horillas.
Lo de chivato es porque así no puedo "meter" una trola diciéndo que me he quedado hasta tal o cual hora, ya que sólo hay que encenderlo y ver si es así o no... pero eso son cosas mías... (desde luego Guille, ¿a quién le importa eso? es que algunas veces, con tal de enrollarte...)Después cuando lo enciendo, no me fijo en ese detalle, (realmente: no me fijaba, ya que ahora si que lo hago), y los ficheros que guardo, pues están "mal" al menos en lo que a la fecha y hora se refiere y como me gusta que los ficheros tengan la fecha y hora que deben tener... ya que sino a la hora de hacer una copia de los más recientes, puede que se queden sin copiar por culpa de un despiste.
De lo que se trata es de poder cambiar la fecha y hora de los ficheros que queramos, para que en casos como este que indico, estén como deben, ya que si usas un programa de copia de seguridad, puede que sea casi "imprescindible" que ese atributo esté bien.
Así que, aquí te traigo otra pequeña utilidad, para cambiar la fecha y la hora de los ficheros indicados.
Como quiero que sea ahora la costumbre, no me voy a conformar con darte los listados y/o el ejecutable y dejar que te comas el coco intentando navegar entre las líneas de código. Aunque ahora estoy intentando comentarlas más, algunas veces no viene mal una pequeña explicación. Además así te sirve para que tengas más claros los conceptos, ya que de eso se trata.
Por supuesto, si ya estás más experimentado en esto de la programación con el VB, puedes ir al final de la página y bajarte los listados y/o el ejecutable. Tanto los listados como el EXE están creados con el VB5. Así que si quieres usar el ejecutable, tendrás que disponer del runtime del VB5 SP3, ya sabes que lo puedes bajar de estas direcciones:
http://www.elguille.info/ftp/msvbvm50.zip o de http://www.chez.com/guille/ftp/Msvbvm50.zip
¿Cómo funciona esta utilidad?
Básicamente, para cambiar a un fichero la fecha y hora, lo que hay que hacer es re-grabarlo. De esta forma el sistema le asignará la fecha y hora en que se grabó.
Este método, así a "pelo", tiene un par de inconvenientes:
1.- La fecha/hora que se asigna es la actual... y lo mismo queremos indicar otra.
2.- Si el fichero en cuestión es muy grande, puede que la cosa sea lenta.¿Cómo solucionamos estos problemillas?
En primer lugar, para que sea una utilidad "útil", deberíamos poder decidir que fecha y hora asignar. Esto lo conseguimos asignando al reloj del sistema la fecha y hora que queremos "plasmar" en cada uno de los ficheros, de esta forma, cuando se guarde, será la fecha/hora que queremos, la que se asigne.
Por supuesto, que tendremos la precaución de "recordar" la fecha/hora real, para volver a poner las cosas en orden, o al menos como estaban antes de asignar una nueva fecha a los ficheros.El tema de que el fichero sea grande o pequeño, no es ningún inconveniente, ya que no vamos a leerlo entero, sólo hay que hacer una pequeña modificación, sin cambiar nada, claro, para que al guardarlo se asigne la fecha que hemos indicado.
Lo que hace el programa es abrir el fichero en modo binario, leer el primer byte y volver a guardarlo.
Osea que no hay inconveniente en el tamaño del los ficheros a procesar.
¿Que interface usar?
En principio el diseño de esta utilidad no tiene demasiada complicación, todo lo que hay que hacer es permitir al usuario poder seleccionar los ficheros que quiere modificar, indicar la fecha y hora a "plasmar" en los ficheros seleccionados y asignar esa fecha y hora.
Para seleccionar los ficheros, podríamos hacerlo de varias formas:
1.- Que el usuario escriba en un cuadro de texto el fichero al que le quiere cambiar la fecha.
2.- Usar controles Drive, Dir y FileListbox para la selección
3.- Usar un control CommonDialog para seleccionarlos.Esta última me parece la más correcta y simple de implementar, demás de también la primera, pero las dos juntas dan más posiblidades de elección.
Aunque después veremos que no se va a usar el control (OCX) de los diálogos comunes, entre otras cosas para hacerla más fácil de "distribuir", así nos evitamos el tener que distribuir ese control.
El aspecto del programa
Antes de entrar en detalles, vamos a ver el aspecto que tendrá la aplicación de cara al usuario.
El aspecto de la aplicaciónComo es natural, para poder cambiar la fecha/hora a los ficheros, antes hay que especificar que ficheros.
Para seleccionarlos, pulsaremos en el botón Examinar. Nos mostrará un cuadro de diálogo para que escojamos los que queramos, una vez que hayamos aceptado, esos ficheros se añadirán a la lista.
En el cuadro de texto, puedes indicar el path que mostrará el cuadro de diálogo.También puedes especificar en este cuadro los ficheros a incluir en la lista, sin necesidad de pulsar en Examinar, para que esos ficheros se añadan a la lista, deberás pulsar en Añadir.
Si lo que especificas tiene signos comodines, una vez que se procesen los ficheros de la lista, la utilidad se encargará de "interpretar" esos nombres, es decir, puedes añadir: C:\VB5\*.BAS y después el programa se encargará de desmenuzar esa especificación en cada uno de los ficheros que concuerden con ella. Pero al darle a añadir no se "interpretan" los nombres.De la lista puedes eliminar los ficheros que quieras, (bueno, eliminar no, sino quitar de la lista, no sea que pienses que se borrarán del disco); para ello, simplemente selecciona los que quieras quitar y pulsa SUPRIMIR.
Por supuesto, para poder asignar la fecha y la hora, tendrás que indicarlo en las cajas de texto que hay para ello. Por defecto indicará la fecha y hora actual, realmente de cuando arranques el programa. Y a pesar de que se indica el "formato" a usar, lo que debes tener en cuenta es que la fecha/hora introducida sea una fecha y/o hora válida, da igual que uses otro formato, el programa se encarga de convertirlo a ese formato.
Por ejemplo, en la fecha puedes especificar 31 Mar 1998 y el programa lo entenderá, porque es una fecha correcta, no porque el programa sea "listo"... ¡que conste!
Una vez que tienes los ficheros seleccionados y la fecha y hora que quieres "imprimirles", pues le das al botoncico ese que pone Asignar y ya está.
Una vez procesados los ficheros, un mensaje te indicará los ficheros procesados y los fallos que se hayan podido producir.
Como ves, no tiene nada de especial.
Ahora veamos el código empleado
Para seleccionar los ficheros, al pulsar en Examinar, no uso un control CommonDialog, ya que ello implicaría el uso de un OCX, y aunque es uno bastante común... puede que los usuarios no VB-maníacos no lo tengan instalado. Para solucionar ese "inconveniente", he usado una clase para este propósito.
Esta clase sólo muestra el cuadro de diálogo ABRIR, pero con eso tenemos más que suficiente. Además en la clasehe incorporado unas funciones que pueden ser útiles en otros contextos.
Una de ellas ya las he puesto antes en mis páginas, y sirve para cambiar o quitar los caracteres indicados a una cadena.
Las otras cosillas que tiene se usan para manejar los ficheros, por ejemplo hay una función para añadir a un listbox los ficheros seleccionados, cuando se han seleccionado múltiples ficheros, esto es una ventaja, así no hay que prepararse ninguan rutina que los manipule.El único "fallillo" que tiene esta clase, no se aún si es culpa mia o del sistema operativo, pero cuando seleccionas, de forma múltiple, muchos ficheros, no se devuelven esos ficheros.
En las comprobaciones que he hecho, es la DLL usada la que no devuelve los ficheros, pero no se si será porque no la tengo bien "implementada".
En caso de que te ocurra eso, es decir que selecciones muchos ficheros y no te devuelva ninguno, lo que debes hacer es seleccionar menos y hacerlo en un par de veces.
Para comprobar esto que digo, selecciona de un directorio cuatro o cinco columnas de ficheros, verás cómo no te los devuelve todos... En fin...NOTA: Acabo de comprobarlo con el control CommonDialog y también le ocurre...
No voy a explicar todo el código de la clase que maneja el diálogo de Abrir, salvo las cosas que crea necesaria, cuando estemos dentro del listado ya veré...
Antes de ver el código que se usa en cada uno de los botones, vamos a echarle una visual a "pequeños" detalles.
Si te has fijado, encima del botón SALIR hay una línea 3D de separación. Para conseguir esta línea, he usado dos controles LINE, uno con el BorderWidth = 2, y el BorderColor a gris oscuro, la otra línea, tiene un borde igual a 1 y el color es blanco, también debe estar encima de la oscura. Ambas en la misma posición, al menos en lo que a la "altura" se refiere, ya que el programa se encarga de adaptarlas al ancho del form.
Este es el código a usar en el evento Form_Resize:Private Sub Form_Resize() If WindowState <> vbMinimized Then Line1(0).X1 = 0 Line1(0).X2 = ScaleWidth Line1(1).X1 = Line1(0).X1 Line1(1).X2 = Line1(0).X2 End If End SubComo ves no es nada del otro mundo y le da un look "mu guai".
La comparación If WindowState <> vbMinimized Then, es para que sólo se "pinte" cuando esté el form en modo no minimizado, ya que si está minimizado, para que queremos las líneas...
A continuación, situamos una de ellas totalmente a la izquierda, para ello hay que asignar CERO a la propiedad X1, si fuese otro control "no gráfico", la propiedad a asignar sería LEFT. Ahora tenemos que hacer que llegue la línea hasta la otra esquina del form, ahora lo que hacemos es asignarle a la propiedad X2, el ancho del form y asunto arreglado. En otros controles, la propiedad a la que se le asignaría el ScaleWidth sería Width.
La verdad es que esto de que tenga otros "nombres" es un poco coñazillo, ya que si usasemos alguna rutina genérica para "colocar" los controles, habría que tener en cuenta que no todos los controles tienen las mismas propiedades para situarlos en la pantalla... pero en fin...Cuando el programa se inicia, como ya te comenté antes, se asigna a las cajas de texto correspondientes, la fecha y hora actual. Esto se hace en el evento Form_Load:
Private Sub Form_Load() 'poner la fecha y hora actual txtFecha = Format$(Now, "dd/mm/yyyy") txtHora = Format$(Now, "hh:mm") End SubCreo que esto no necesita ningún comentario extra...
Vamos a por los botones:
El código del botón Añadir, lo que hace es agregar al ListBox lo que haya en el cuadro de texto del fichero:Private Sub cmdAñadir_Click() 'Si hay algo en el textBox, añadirlo Dim sTmp As String sTmp = Trim$(txtFichero) If Len(sTmp) Then List1.AddItem sTmp End If End SubAquí lo que se comprueba es que si el contenido de ese textbox no está vacio, se añade a la lista de ficheros a procesar.
El código del botón Examinar es algo más largo, ya que tenemos que hacer una serie de cosillas.
Veamos el código y después las explicaciones:Private Sub cmdExaminar_Click() 'Seleccionar los ficheros a añadir a la lista Dim CommonDialog1 As New cComDlgOpen On Local Error Resume Next 'añadir archivo With CommonDialog1 .hwnd = Me.hwnd .CancelError = True .FileName = txtFichero 'Seleccionar ficheros a añadir a la lista .DialogTitle = "Seleccionar archivos" .Filter = "Todos los archivos (*.*)|*.*" .Flags = OFN_HIDEREADONLY Or OFN_ALLOWMULTISELECT _ Or OFN_LONGNAMES Or OFN_EXPLORER Or OFN_PATHMUSTEXIST Or OFN_FILEMUSTEXIST .ShowOpen If Err = 0 Then 'Añadimos la selección al List1 .AgregarALista .FileName, List1 End If End With Err = 0 Set CommonDialog1 = Nothing End SubAquí se crea una variable del tipo de la clase de diálogos comunes, el nombre lo he dejado como CommonDialog1, por si prefieres usar el control para este menester, en lugar de la clase. Aunque la clase te seguirá haciendo falta, salvo que agregues manualmente el procedimiento AgregarALista, además de otro que se encargue de "entender" las selecciones múltiples.
Como ves uso, el With para facilitar el manejo de las propiedades de esta clase.
La propiedad hWnd, no es propia del control OCX, pero en este caso la uso para que el cuadro de diálogo "pertenezca" al formulario, de esta forma, es como si se hiciera modal y hasta que no se cierre no se podrá pasar a nuestro formulario, prueba a no asignar el hWnd y verás que puedes "pasar" del diálogo y volver al formulario, pero no te recomiendo que lo hagas... a no ser que quieras que ocurran cosas "imprevisibles"... nada graves, pero...
Lo del CancelError es para que sepamos que no hemos elegido nada, es decir cuando pulsemos en cancelar, se producirá un error, como tenemos la rutina que los detecta, pues sólo tendremos que comprobar si el "objeto" Err vale cero, en caso de que sea así, es que no hemos pulsado cancelar y podremos "procesar" los ficheros seleccionados.
Fijate en los valores que he asignado a la propiedad FLAGS:
.Flags = OFN_HIDEREADONLY Or OFN_ALLOWMULTISELECT _
Or OFN_LONGNAMES Or OFN_EXPLORER Or OFN_PATHMUSTEXIST Or OFN_FILEMUSTEXISTEstas variables se corresponden con las del Visual Basic, lo único que en el VB empiezan por: cdlOFN en lugar de OFN_, pero la utilidad es la misma.
Si se especifica AllowMultiselect, es decir: permitir multiple selección, el diálogo cambia al formato "antiguo", tanto en mi clase como en el OCX, para que se pueda ver como es habitual en el Windows de 32 bits, hay que asignar los valores Explorer y LongNames, para que permita nombres largos. Los otros valores son habituales, es decir que el fichero indicado exista y el path también.Antes de continuar, voy a comentarte una cosa que no es "visible" en este código, pero que debes saber si quieres usar el control OCX para procesar múltiples ficheros.
Cuando a la propiedad Flags, se le da el valor AllowMultiselect, lo que se devuelve en FileName es el nombre de todos los ficheros seleccionados, pero el Path se indica sólo en el primero de ellos, además cada uno de los ficheros está sepaqrado por un carácter CHR$(0), en el manual dice que por espacios, pero eso no es cierto.
Así que si usas el control OCX, deberás "filtrar" los códigos CHR$(0) y cambiarlos por un espacio, sino no verás más que el primer fichero seleccionado.
Por supuesto que deberás usar una función como AgregarALista para "convertir" esos nombres en algo "entendible".
En este caso AgregarALista añade el path a cada uno de los ficheros, par que todos tengan el path completo.Este procedimiento no sólo añade los ficheros a un ListBox, también permite añadirlos a un combo, o a cualquier objeto que tenga el método Additem..., veamos el listado:
'Esta función pertenece a mi clase de diálogos comunes Public Sub AgregarALista(ByVal sArchivos As String, queControl As Control, _ Optional ByVal vAlPrincipio As Variant, _ Optional ByVal vConDir As Boolean = True) 'Agregar los archivos indicados a la lista 'Parámetros: ' sArchivos Los archivos estarán separados por ' espacios y dentro de comillas ' o simplemente será un archivo ' queControl será un List o un Combo 'Parámetros opcionales ' vAlPrincipio si True se añade al principio de la lista ' Por defecto= False ' vConDir Si el primer parámetro es un directorio ' Por defecto= True ' Dim i&, j& Dim sTmp$, sDir$ Dim bAlPrincipio As Boolean Dim colArchivos As New Collection sArchivos = Trim$(sArchivos) If Len(sArchivos) = 0 Then Exit Sub sDir = "" If IsMissing(vAlPrincipio) Then bAlPrincipio = False Else bAlPrincipio = CBool(vAlPrincipio) End If If InStr(sArchivos, Chr$(34)) Then 'hay comillas, es que hay varios archivos j = 0 Do While Len(sArchivos) Do While Left$(sArchivos, 1) = Chr$(34) sArchivos = Trim$(Mid$(sArchivos, 2)) Loop i = InStr(sArchivos, Chr$(34)) If i Then sTmp = Left$(sArchivos, i - 1) sArchivos = Trim$(Mid$(sArchivos, i + 1)) If j Then colArchivos.Add sDir & sTmp Else 'si se considera el primer parámetro 'como un directorio If vConDir Then 'El primer parámetro es el directorio j = j + 1 sDir = sTmp 'Si no tiene la barra ponersela If Right$(sDir, 1) <> "\" Then sDir = sDir & "\" End If Else 'Si no es así, añadirlo como fichero colArchivos.Add sTmp End If End If Else Exit Do End If Loop If Len(sArchivos) Then colArchivos.Add sDir & sArchivos End If 'Por si sólo se selecciona un archivo If colArchivos.Count = 0 Then colArchivos.Add sTmp End If Else 'no hay comillas, es sólo un archivos colArchivos.Add sArchivos End If For i = colArchivos.Count To 1 Step -1 If bAlPrincipio Then queControl.AddItem colArchivos(i), 0 Else queControl.AddItem colArchivos(i) End If Next Set colArchivos = Nothing End SubFijate que hay dos parámetros Opcionales, el segundo de ellos tiene asignado un valor "predeterminado", es decir que si no se especifica ese parámetro, se le da el valor indicado, en este caso True. El otro parámetro no tiene ningún valor predeterminado, pero podría tenerlo, ya que después se comprueba si se ha omitido y en caso de que sea así, se asigna un valor False a la variable que va a controlar si se añaden al principio de la lista o no.
A continuación se comprueba si el nombre con los ficheros tiene el signo de comillas CHR$(34), en caso de que sea así se considera que son varios los nombres que hay, de forma que se procesan cada uno de ellos, añadiendolos a una colección temporal. Si se indica True en el valor vConDir, entonces se interpreta que el primer parámetro será el nombre del directorio, esto siempre es cierto cuando se hace múltiple selección, por eso su valor por defecto es True.
La variable j es la que lleva la cuenta de los ficheros añadidos a la colección, cuando vale cero, es que es el primero, por tanto asigna ese nombre a la variable que guardará el nombre del directorio.
Otro detalle es que cuando se asignan los nombres al ListBox, se hacen desde atrás hacia adelante, por eso el bucle se hace desde colArchivos.Count hasta 1, esto es necesario, porque la librería de Diálogos comunes invierte el orden de los ficheros seleccionados, no se si te habrás fijado cuando seleccionas varios ficheros en el Explorador de Windows, los copias y después los pegas en otra carpeta, se invierte el orden de la selección... un detallico sin importancia, pero que en esta rutina se tiene en cuenta...Ahora le toca el turno al botón clave de esta utilidad: Asignar.
Empecemos viendo el código y después explico:Private Sub cmdAsignar_Click() 'Asignar la fecha/hora indicada a los ficheros de la lista Dim vFecha As Date Dim vHora As Date Dim i As Long Dim sTmp As String Dim Ficheros As Long Dim Fallos As Long Dim TotalFicheros As Long Dim TotalFallos As Long Dim Procesados As Double On Local Error Resume Next If List1.ListCount = 0 Then MsgBox "No hay ficheros a procesar" txtFichero.SetFocus Else If Len(Trim$(txtFecha)) = 0 Then vFecha = Format$(Now, "dd/mm/yyyy") Else vFecha = txtFecha End If vFecha = Format$(vFecha, "dd/mm/yyyy") If Err Then MsgBox "La fecha introducida no es correcta" txtFecha.SetFocus Else If Len(Trim$(txtHora)) = 0 Then vHora = Format$(Now, "hh:mm") Else vHora = txtHora End If vHora = Format$(vHora, "hh:mm") If Err Then MsgBox "La hora no es correcta" txtHora.SetFocus Else For i = 0 To List1.ListCount - 1 sTmp = List1.List(i) Procesados = ProcesaEspec(sTmp, vFecha, vHora) Ficheros = Fix(Procesados) sTmp = CStr(Procesados - Ficheros) Fallos = Val(Mid$(sTmp, 3)) TotalFicheros = TotalFicheros + Ficheros TotalFallos = TotalFallos + Fallos Next MsgBox "Se han procesado un total de " & TotalFicheros & vbCrLf & _ "se han producido " & TotalFallos & " fallos" End If End If End If Err = 0 End SubFijate que no se usa ningún tipo de función para comprobar si la fecha introducida es correcta, lo único que hago es detectar que se produzca un error, en caso de que sea así, quiere decir que no es una fecha "buena".
Aquí te darás cuenta que si se deja en blanco alguno de los dos campos de fecha y hora, se asigna la actual. También se podría haber hecho que si no se especificaba alguna de ellas, que se dejara la que tuviese el fichero, pero eso es complicarse un poco más la vida...
Bien, este procedimiento relamente no cambia la fecha/hora de los ficheros, simplemente se encarga de enviar el contenido de cada elemento de la lista a una función (ProcesaEspec) la cual recibe una cadena con un nombre, el cual puede tener comodines, con lo cual se pueden especificar distintos grupos de ficheros que cumplan un "patrón"; el segundo y tercer parámetro es la fecha y la hora a asignar a ese fichero o grupo de ficheros.
El valor devuelto por esta función, contiene realmente dos valores, uno en la parte entera, será el número de ficheros procesados y el otro, que estará en la parte decimal, serán los fallos que se han producido, estos fallos pueden ser porque el fichero sea de sólo lectura, etcétera.Como el número devuelto por esa función está compuesto de dos valores, (como ya he mencionado, uno de ellos estará en la parte entera y el otro en la parte fraccionaria), hay que "desmenuzarlo", para ello, asignamos a la variable Ficheros el valor sin decimales, fijate que uso FIX en lugar de INT, esto es para que no se "redondee" el número.
Como sabrás, FIX toma la parte entera sin hacer ningún tipo de redondeo.Para convertir el valor fraccionario en un entero, lo que hago es restarle al número devuelto el que ya he obtenido de la parte entera y después lo asigno a la variable Fallos. Realmente he usado una conversión previa a cadena de caracteres.
De esta forma, le quito el cero y el signo de decimales y me quedo con el número entero.
Puede que parezca demasiado rebuscado, pero... es lo mejor que he encontrado...Estos valores se van guardando en unas variables para que una vez procesados todos los "elementos" del ListBox, se muestre un cuadro de diálogo con el resultado de los "fallos" que hayan podido producirse.
Veamos lo que hace la función ProcesaEspec:
Private Function ProcesaEspec( ByVal sFic As String, _ ByVal vFecha As Date, _ ByVal vHora As Date) As Double 'Procesar los ficheros especificados y asignar la fecha/hora Dim sTmp As String Dim Ficheros As Long Dim Fallos As Long Dim sDir As String On Local Error Resume Next 'Obtener el path de este fichero o especificación sDir = elPath(sFic) sTmp = Dir$(sFic) If Err Then Ficheros = 1 Fallos = 1 Else Do While Len(sTmp) Ficheros = Ficheros + 1 If AsignarHora(sDir & sTmp, vFecha, vHora) Then Fallos = Fallos + 1 End If sTmp = Dir$ Loop End If sTmp = CStr(Ficheros) & "." & CStr(Fallos) ProcesaEspec = Val(sTmp) Err = 0 End FunctionEn esta función se usa DIR$ para procesar cada uno de los ficheros, en caso de que se haya usado algún commodín, que se indican en sFic.
El bucle Do While Len(sTmp) se repetirá como mínimo una vez, en caso de que no se haya producido un error a la hora de asignar a sTmp el valor devuelto por Dir$.
Dentro de este bucle se llama a otra función, que, ahora si, es la que asigna la fecha y hora.
Fijate que se ha averiguado el Path del fichero o especificación, para que en caso de introdicir C:\VB5\*.BAS,se procesen realmente todos los ficheros BAS de ese directorio, ya que si no usaramos el path, se intentaría cambiar la fecha y hora de los ficheros con esa extensión, pero en el directorio actual.
Esa función (AsignarHora) devolverá TRUE en caso de que se haya producido un error, con lo cual se incrementará la variable que cuenta los fallos.
Al final de la función se convierten los Ficheros procesados y los fallos en un Double, ya sabes que el valor entero es el número de ficheros procesados y la parte fraccionaria es el número de fallos.Ahora vamos a ver el "corazón" de esta función:
Private Function AsignarHora(ByVal sFic As String, _ ByVal vFecha As Date, ByVal vHora As Date) As Boolean 'Asignar la fecha y hora al fichero indicado Dim FechaActual As Date Dim HoraActual As Date Dim nFic As Long Dim unChar As String * 1 FechaActual = Format$(Now, "dd/mm/yyyy") HoraActual = Format$(Now, "hh:mm") On Local Error Resume Next 'Asignar la fecha/hora a estampar Date$ = Format$(vFecha, "mm-dd-yyyy") Time = Format$(vHora, "hh:mm") nFic = FreeFile 'Abrirlo en modo binario y compartido Open sFic For Binary Shared As nFic Get nFic, 1, unChar Put nFic, 1, unChar Close nFic 'Asignar la fecha/hora del sistema Date$ = Format$(FechaActual, "mm-dd-yyyy") Time = Format$(HoraActual, "hh:mm") AsignarHora = CBool(Err) Err = 0 End FunctionLo primero que se hace, es guardar la fecha y la hora actual, a continuación se asigna al sistema la fecha y hora que queremos darle al fichero, después abrimos el fichero como binario y compartido, leemos el primer carácter y lo volvemos a grabar, en cuanto cerramos el fichero, se habrá asignado la fecha y hora que queriamos. Ahora sólo nos queda volver a asignar al sistema la hora que tenía antes de todo esto... no creo que sea significativo el "lapsus" de tiempo en procesar el fichero, ya que de serlo... nos encontraríamos conque el reloj del ordenador habría retrasado... En cuanto haga pruebas con miles de ficheros haré una media de cuanto es lo que tarda y pondré la correspondiente "corrección" a esta utilidad.
Para devolver True si se produjo un error, se convierte el valor del objeto Err a Boolean, de esta forma si hubo un error se devolverá TRUE.
Bueno, ya está todo lo que realmente interesa de esta utilidad.
Lo que queda es una mejora: Poder "soltar" ficheros en el listbox, de esta forma podrás usar el Explorador de Windows para seleccionar los ficheros a procesar.
Para conseguir esto, se deben asignar la propiedad OLEDropMode del ListBox a 1-Manual, la propiedad OLEDragMode, dejala con el valor 0-Manual.
Escribe este código en el evento OLEDragDrop:Private Sub List1_OLEDragDrop(Data As DataObject, Effect As Long, Button As Integer, Shift As Integer, X As Single, Y As Single) Add2Lista Data, List1 End SubEste es el procedimiento que añade a la lista los ficheros soltados:
Private Sub Add2Lista(Data As DataObject, unaLista As Control, _ Optional ByVal sExtension As String = "") 'Añadir los archivos soltados a la lista (16/Nov/97) Dim i As Long Dim conExt As Boolean If Len(Trim$(sExtension)) Then conExt = True End If With Data.Files For i = 1 To .Count 'Añadir a la lista 'Si se especifica la extensión... If conExt Then If InStr(.Item(i), sExtension) Then unaLista.AddItem .Item(i) End If Else unaLista.AddItem .Item(i) End If Next End With End SubLo que se hace es recorrer los ficheros soltado, que están en la colección Files del objeto Data, y añadirlos al ListBox, hay un parámetro sExtension, que lo uso cuando quiero que sólo se añadan a la lista ficheros de una determinada extensión, esto es útil si por ejemplo sólo quieres que "suelten" ficheros de un tipo determinado.
Bueno, ahora si que está todo... o casi, ya que hay parte del código que no he puesto, como por ejemplo que se hace para quitar del ListBox los ficheros seleccionados... además de la clase de Diálogos Comunes. Esa a lo mejor lo explico con otra utilidad.
Para bajarte los listados, recuerda que son para VB5, pulsa en este link. (gsSetDT_cod.zip 8.30 KB)
Este otro link es para que descargues el ejecutable, también muy pequeñito pero... (gsSetDT.zip 9.64KB)Te recuerdo que son para VB5 con el runtime del SP3, aunque en la versión diga que es SP2.
Espero tu comentario, si crees que esta utilidad te sirve para algo, claro... Si no es así, al menos confío que toda la explicación y el código pueda resultarte interesante.
¡Que lo disfrutes!
Nos vemos.
Guillermo