Función que devuelve el tamaño de un directorio y sus subdirectorios en bytes, KB, megas ….., según el parámetro pasado
// Resumen: Devuelve el tamaño del contenido de un directorio // y todos sus subdirectorios // // Sintaxis: //[ <Result> = ] gfSizeFolder (<pcDirectorio> is string // [, <pcTipeReturn> is string [, <sError> is string]]) // // Parámetros: // pcDirectorio (ANSI string): Ruta <root> del // directorio a tratar // pcTipeReturn (ANSI string - valor // predeterminado="B"): // Devolver el valor como: B (defecto) // , KB, MB, GB, TB, PB, EB // sError (ANSI string - valor predeterminado=""): // Si se produce un error, se devuelve // el mensaje del error // Valor de retorno: // numeric: Un valor correspondiente al parámetro /7 "pcTipeReturn" o -1 si ocurre un error // // Ejemplo: // gfSizeFolder("c:\temp","MB") // PROCEDURE gfSizeFolder(LOCAL pcDirectorio is string, LOCAL pcTipeReturn is string = "B", LOCAL sError is string = "") //*--------------------------------------------------------------- //* //* Devuelve el tamaño del directorio pasado como parámetro (y //* subdirectorios) //* NOTA: if ocurre Error, devuelve -1 //* //* Exabyte (EB) //* Petabyte (PB) //* Terabyte (TB) //* Gigabyte (GB) //* Megabyte (MB) //* Kilobyte (KB) //* byte (B) //* //*--------------------------------------------------------------- lnSizeBytes, lnSizeReturn are numeric WHEN EXCEPTION IN lnSizeBytes = fDirSize(pcDirectorio) // Si ha ocurrido un error IF ErrorOccurred THEN // Lanzamos la excepción para capturar el error ExceptionThrow(1,ErrorInfo(errMessage)) END SWITCH pcTipeReturn CASE "KB" lnSizeReturn = lnSizeBytes / 1024 CASE "MB" lnSizeReturn = lnSizeBytes / (1024^2) CASE "GB" lnSizeReturn = lnSizeBytes / (1024^3) CASE "TB" lnSizeReturn = lnSizeBytes / (1024^4) CASE "PB" lnSizeReturn = lnSizeBytes / (1024^5) CASE "EB" lnSizeReturn = lnSizeBytes / (1024^6) OTHER CASE lnSizeReturn = lnSizeBytes END DO lnSizeReturn = -1 sError = ExceptionInfo(errMessage) END RESULT (lnSizeReturn)
Cómo obtener una imagen de la web y mostrarlo en un control IMAGEN
// Obtenemos la imagen IF HTTPRequest("https://www.flasof.com/web/image/website/1/logo/Flash%20Software") sHeader is string = HTTPGetResult(httpHeader) // Si la cabecera ha devuelto un OK (código 200) IF Left(ExtractString(sHeader,2," "),3) = "200" // Cargamos al imagen en el control de imagen IMG_SinNombre1 = HTTPGetResult(httpResult) ELSE // Error, no se carga imagen IMG_SinNombre1="" END END
Novedades WinDev 27
Controlar excepciones
Al igual que otros lenguajes de programación, Windev dispone de varias opciones para controlar las excepciones que puedan ocurrir en la ejecución de los distintos procesos. Para más información, consultar la siguiente dirección https://ayuda.windev.es/es-ES/?3034004
También es posible, aunque no siempre recomendable, el uso de una EXCEPCIÓN GENERAL que se ejecutará siempre que ocurra un error fuera de la gestión de otro control de EXCEPCIÓN. Para ver más información, consultar la siguiente dirección https://ayuda.windev.es/es-ES/?3034001
Si ponemos el siguiente código en el inicio de nuestro proyecto, cuando ocurra un error, fuera del otro control de excepciones, se grabará el error en el fichero de LOG y se cerrará la aplicación (aquí se podría personalizar nuestro método de registro de errores y avisos al usuario)
gdDiaInicio is Date = Today() gtHoraInicio is Time = TimeSys() // Este código se ejecuta cuando ocurre un error fuera de un control de EXCEPCIÓN. // Se captura cualquier error que se produzca y se muestra el mensaje siguiente y se finaliza la aplicación WHEN EXCEPTION fSaveText("Errores_generales.log",gdDiaInicio.ToString("DD:MM:YYYY") + " " + gtHoraInicio.ToString("HH:MM:SS") + CR + "Error: " + ExceptionInfo()) EndProgram() END
NOTA: En FoxPro se puede poner el siguiente comando: “ ON ERROR * ”, lo que hará es que la aplicación no muestre ni trate ninguno de los errores que se produzcan, continuando el código siguiente al error producido. En Windev, si se hace uso del código anterior y no se finaliza el programa, al ocurrir un segundo error no se ejecutaría dicho código, ya que solo se puede ejecutar una vez.
Exportar a Excel
A la hora de exportar los grids, haciendo uso de la opción del botón derecho, se hace con los valores por defecto, pero se pueden configurar más opciones con la función AAFConfigure ( https://ayuda.windev.es/es-ES/?1000022108&name=AAFConfigurar&lf=us )
Por ejemplo, si se quiere que se exporten los títulos y que conserve la posición de la columna del usuario y el aspecto del grid (colores), se debe poner la siguiente instrucción (mejor en la inicialización del proyecto para que afecte a todas las exportaciones de los grids):
AAFConfigure(aafTableToExcel, taColumnsTitles + taColumnDisplayedOrder + taWithLayout)
Lentitud del editor
Puede ser que tu editor le cueste cargarse cuando trabajas con tablas de 100.000 registros y en remoto. Para que no te cargue esos registros tienes en las propiedades del proyecto la opción DATA LIVE / VIEW
Campos de un DataSource
El siguiente código te devuelve los nombres de campo del Data Source entre comillas y separador por TAB
// Resumen: Devuelve una cadena con los nombres de campo del // Data Source entre comillas y separados por TAB // Descripción de los parámetros de entrada/salida de 'GetDataSourceEncabezado': // // Sintaxis: //[ <Result> = ] GetDataSourceEncabezado (<dsTabla> is data source) // // Parámetros: // dsTabla (data source): <indique aquí el rol de dsTabla> // Valor de retorno: // ANSI string: // Ninguno // // Ejemplo: // Indique un ejemplo. // PROCEDURE GetDataSourceEncabezado(LOCAL dsTabla is Data Source):string sReturn is string sListItm is string WHEN EXCEPTION IN // Lista campos en el Data Source sListItm = HListItem(dsTabla) // Componemos la cabecera FOR EACH STRING sAnItem OF sListItm SEPARATED BY CR sReturn += [TAB] + """"+sAnItem + """" END DO sReturn = "" Error( ExceptionInfo(errMessage) ) END RESULT (sReturn)
Volcar el contenido de un Datasource a un fichero ASCII
Seguramente pensarás en ExportToCSV y la verdad es que funciona para pequeñas cantidades de registros como 3.000 ó 4.000 registros.
Yo me tuve que enfrentar a una exportación de 500.000 registros y la verdad se moria… Cuando habían pasado 45 minutos, cancelé el proceso y busque otra forma de hacerlo. Aquí está el resultado que realizó el mismo proceso en menos de 1 minuto.
// Resumen: Vuelca el contenido de un Data Source a un fichero // ASCII, entrecomillando los campos y separando con un TABULADOR // // Sintaxis: // //[ <Result> = ] DataSourceToCSV (<nFileNum> is int, <dsTabla> // is data source, <sTextoProgressBar> is string) // // Parámetros: // nFileNum (int): Identificador creado por FOPEN. // Será usado para escribir en el fichero // dsTabla (data source): Data source a tratar // sTextoProgressBar (ANSI string): Texto que se // mostrará en la barra de status junto al // ProgressBar // nFactorEscrituras (int OPCIONAL): Sirve para reducir // el número de veces que se escribe en disco. // Se acumulan tantas líneas como el factor // especificado y cuando se cumple, se escribe // en el fichero // Valor de retorno: // boolean: // Ninguno // // PROCEDURE DataSourceToCSV(LOCAL nFileNum is int, LOCAL dsTabla is Data Source, LOCAL sTextoProgressBar is string, LOCAL nFactorEscrituras is int = 100):boolean bReturn is boolean = True nLinea, nLineas are int vValue is Variant sLineToWrite is string sListItm is string // Cadena de texto que se usará para acumular texto y reducir el número // de escrituras en disco sCadenaTextoParaEscribir is string WHEN EXCEPTION IN nLinea = 1 // Número de registros en el Data Source nLineas = HNbRec(dsTabla) // Lista campos en el Data Source sListItm = HListItem(dsTabla) sCadenaTextoParaEscribir = "" ProgressBar(nLinea, nLineas,sTextoProgressBar, DarkBlue) Multitask(-1) // Procesamos todos los registros HReadFirst(dsTabla) WHILE HOut(dsTabla) = False sLineToWrite = "" // Creamos el contenido entre comillas y separado por TAB FOR EACH STRING sAnItem OF sListItm SEPARATED BY CR vValue = {"dsTabla." + sAnItem, indItem} sLineToWrite += [TAB] + """"+ vValue + """" END // Si se cumple el factor, escribimos la cadena en el fichero IF modulo(nLinea, nFactorEscrituras) = 0 THEN // Si la ventana tiene una barra de estado con una barra // de progreso, se muestra en ella ProgressBar(nLinea, nLineas,sTextoProgressBar, DarkBlue) Multitask(-1) // Añadimos la línea sin CR al final, ya que la función: fWriteLine, lo añadirá sCadenaTextoParaEscribir += sLineToWrite // Escribimos la línea fWriteLine(nFileNum, sCadenaTextoParaEscribir) sCadenaTextoParaEscribir = "" ELSE // Añadimos un retorno de carro sCadenaTextoParaEscribir += sLineToWrite + CR END nLinea ++ HReadNext(dsTabla) END // Si ha quedado texto sin escribir IF sCadenaTextoParaEscribir <> "" THEN // Escribimos la línea fWriteLine(nFileNum, sCadenaTextoParaEscribir) END DO bReturn = False Error( ExceptionInfo(errMessage) ) END RESULT(bReturn)
Recorrer una cadena XML y llenar un Grid
xmlDoc is a xmlDocument <description="xxx"> = XMLOpen("c:\temp\xxx.xml",fromFile) xmlRegistro is a xmlNode <description="xxx.VFPData.registro"> FOR EACH xmlRegistro IN xmlDoc.VFPData TableAddLine(TABLE_SinNombre1,xmlRegistro.t22codart, xmlRegistro.t22nart, xmlRegistro.t22cfami) END