Para convertir un MemoryStream en un array de bytes basta con una sola línea de código:
Private Function GetStreamAsByteArray(ByVal stream As MemoryStream) As Byte() Return stream.ToArray() End Function
Cadena JSON a Objeto
Para convertir una cadena en formato JSON en una clase concreta se puede usar el siguiente ejemplo:
Public Function CadenaJSON_a_Objeto(Cadena_JSON As String) As Mi_Tipo Dim Mi_Objeto As Mi_Tipo Mi_Objeto = Newtonsoft.Json.JsonConvert.DeserializeObject(Of Mi_Tipo)(Cadena_JSON) Return Mi_Objeto End Function
En el caso de que se tenga una aplicación de escritorio, se pueden capturar todas las excepciones que no se hayan tenido en cuenta dentro de los distintos formularios. Para ello se añaden un par de funciones para controlar dichos eventos en el fichero app.vb:
Private Sub Application_ThreadException(ByVal sender As Object, ByVal e As ThreadExceptionEventArgs) 'tratamiento de la excepcion End Sub
Private Sub CurrentDomain_UnhandledException(ByVal sender As Object, ByVal e As UnhandledExceptionEventArgs) 'tratamiento de la excepción End Sub
Posteriormente se asignan las excepciones al arrancar la aplicación en el main():
Public Sub Main() AddHandler Application.ThreadException, AddressOf Application_ThreadException Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException) AddHandler AppDomain.CurrentDomain.UnhandledException, AddressOf CurrentDomain_UnhandledException Application.EnableVisualStyles() Application.Run(New Formulario_Principal_dela_Aplicacion()) End Sub
Esto mismo se puede hacer dentro de un formulario WinForm, creando las funciones anteriores en el código VB.NET del formulario, y posteriormente asignado las excepciones a dichas funciones, por ejemplo, añadiendo un par de líneas en el evento Load:
Private Sub Formulario_Principal_dela_Aplicacion_Load(sender As Object, e As EventArgs) Handles Me.Load AddHandler Application.ThreadException, AddressOf Application_ThreadException AddHandler AppDomain.CurrentDomain.UnhandledException, AddressOf CurrentDomain_UnhandledException End Sub
En las propiedades del proyecto, abrir la pestaña de recursos y luego cambiar de tipo imagen a tipo Audio. Posteriormente darle al botón de Agregar recurso. Para reproducirlo ejecutar lo siguiente:
Primero se crea el proceso, después de lanza y finalmente se pone la orden WaitForExit que deja el programa invocador parado hasta que el proceso externo acaba:
Dim p As New Process Dim psi As New ProcessStartInfo("c:windows otepad.exe", "c: mpy1.txt") p.StartInfo = psi p.Start() p.WaitForExit() MsgBox("Acabado")
En el caso de que se quiera comprobar periódicamente si ha acabado se puede sustituir el WaitForExit por un bucle que comprueba periódicamente si ha terminado:
While Not p.HasExited Thread.Sleep(3000) End While MsgBox("Acabado")
En el caso de que el archivo de texto venga en formato ANSI, se puede leer correctamente con la codificación ASCII:
Dim stream As FileStream stream = File.Open(rutaFichero, FileMode.Open, FileAccess.Read) Dim tamanio = stream.Length 'el array se crea con una posición más lo que hace que el fichero acabe con un cero de más, para evitar esto se pone el -1 Dim Buffer(CInt(tamanio - 1)) As Byte stream.Read(Buffer, 0, CInt(tamanio)) stream.Close() stream.Dispose() Dim texto as String = System.Text.Encoding.ASCII.GetString(Buffer)
La fecha que es independiente del lugar en el que nos encontremos, la UTC se puede obtener con DataTime.UtcNow Esta fecha se puede volver a la que corresponde con el sitio en el que se está con ToLocalTime Si luego al pasarla a texto se quiere indicar la zona horaria se pudede poner “zzz” en el formato:
Dim dt as DateTime = DateTime.UtcNow Dim output as String = dt.ToLocalTime().ToString("MMM dd, yyyy HH:mm:ss tt ""GMT"" zzz") Console.WriteLine(output) 'Outputs Aug 23, 2017 11:16:29 AM GMT +01:00
Para un formulario WinForm se puede fijar su posición en el evento Load con SetDesktopLocation Además, se puede saber su tamaño con Width y Height:
Private Sub FrmAyudaPlanificador_Load(sender As Object, e As EventArgs) Handles Me.Load Dim Coordenada_X as Integer = 200 Dim Coordenada_Y as Integer = 100 Me.SetDesktopLocation(Coordenada_X, Coordenada_Y) Console.WriteLine(Me.Width) Console.WriteLine(Me.Height) End Sub
Formulario con trasparencia
Si se quiere que lo que hay detrás de un formulario se vea hay que cambiar la propiedad Opacity del formulario a un valor menor de 100% Si se quiere que el color del formulario opaco sea gris se pone la propiedad ForeColor y BackColor a Black, de esta manera cuando se multiplique por la opacidad da un gris Si se quiere hacer una máscara para ver nítidamente lo que hay detrás del formulario en un hueco del mismo hay que fijar el color de la propiedad TransparencyKey, por ejemplo a White. De esta manera si ponemos, por ejemplo, un objeto System.Windows.Forms.Panel de color blanco, en el formulario, la zona que ocupa se ve transparente con lo que deja ver nítidamente lo que hay detrás del formulario.
Si se tiene un control DateTimePicker en un formulario WinForm, se puede especificar el formato de la fecha que contiene con la propiedad CustomFormat, que se puede, por ejemplo configurar en la carga del formulario:
Private Sub MiFormulario_Load(sender As Object, e As EventArgs) Handles Me.Load MiControlFecha.CustomFormat = "dd/MM/yyyy - HH:mm:ss" End Sub
Se usa la función OrderBy o OrderByDescending, según interese Por ejemplo, para devolver un array de cadenas con los nombres de los fichero pdf de una carpeta:
Dim ListaFicheros as String() = Directory.GetFiles(“c: mp”, "*.pdf").OrderBy(Function(x) x)
Se puede crear un objeto JSON para que por ejemplo, un controlador lo devuelva como resultado de una Petición AJAX hecha con Javascript. Para ello se usa la librería de JSON de Newtonsoft. Para crear un objeto JSON a partir de un objeto .NET se usa FromObject, para añadirle propiedades se usa la función Add, para crear dichas propiedades se usa JProperty.
Public Function Devolver_JSON() As Object Dim Resultado As New JObject 'se crea el objeto JSON vacío Dim JFecha As JObject JFecha = JObject.FromObject(Today) 'se crea un objeto JSON con la fecha de hoy Resultado.Add(New JProperty("Fecha", JFecha)) 'al objeto vacío se le añade una primera propiedad que es el objeto JSON fecha Resultado.Add(New JProperty("Numero", CInt(45))) 'se le añade otra propiedad, el número 45 Resultado.Add(New JProperty("Condicion", False)) Return Resultado End Function
Con la librería Newtonsoft JSON se puede leer un objeto JSON de forma dinámica si se conocen sus propiedades. Esto se puede usar para recibir una petición AJAX en un controlador .NET:
Public Function Leer_JSON(<FromBody()> Peticion_AJAX As Object) As String Dim Parametros As JObject Dim Mi_Objeto As DataTable Parametros = Newtonsoft.Json.JsonConvert.DeserializeObject(Of JObject)(Peticion_AJAX.ToString()) ' el objeto JSON se convierte a cadena y se deserializa Console.WriteLine(CDate(Parametros("fecha").ToString)) 'se sabe que tiene una propiedad fecha que se obtiene Console.WriteLine(CInt(Parametros("entero").ToString)) 'tiene una propiedad entera que se lee Mi_Objeto = Newtonsoft.Json.JsonConvert.DeserializeObject(Of DataTable)(Parametros("miobjeto").ToString) 'Se obtiene un objeto de un tipo DataTable Return "OK" End Function
Seperador de miles y decimales
Si se quiere crear una cadena de texto que represente un número con separador de miles y dos decimales se puede hacer con una máscara que se pone en la función ToString. Hay que tener en cuenta que redondea hacía arriba desde 5, es decir:
(1234567.855).ToString("##,#.00")
Devuelve: "1.234.567,86" Mientras que:
(1234567.854).ToString("##,#.00")
Devuelve: "1.234.567,85"
Llamada API Web
Para llamar a un controlador de una API Web que, por ejemplo, se haya creado antes en .NET se usa el objeto httpclient. Se puede enviar un contenido en formato JSON para que lo capture el servidor. Por ejempo:
Sub Enviar_Mensaje(Mensaje As String) Dim Respuesta As HttpResponseMessage Dim Cliente_API_WEB As HttpClient
Dim Ruta_Controlador As String = "api/MiControl/Mensaje"
Cliente_API_WEB = New HttpClient Cliente_API_WEB.BaseAddress = New Uri("http://miservidor/") Cliente_API_WEB.DefaultRequestHeaders.Accept.Clear() Cliente_API_WEB.DefaultRequestHeaders.Accept.Add(New MediaTypeWithQualityHeaderValue("application/json"))
Respuesta = Cliente_API_WEB.PostAsync(Ruta_Controlador, New StringContent(New JavaScriptSerializer().Serialize(Mensaje), Encoding.UTF8, "application/json")).Result
Respuesta.EnsureSuccessStatusCode()
If Respuesta.StatusCode = HttpStatusCode.OK Then 'el mensaje ha ido bien Else 'el mensaje no se ha podido enviar End If
End Sub
La clase del controlador que recibe la llamada sería esta:
Public Class MiControlController Inherits ApiController
Public Function Mensaje(<FromBody()> Mensaje As String) As String
Return "OK" End Function End Class
Expresiones Regex
Con la clase Regex se pueden hacer operaciones de comprobación, reemplazo, etc. Un ejemplo es comprobar un NIF que va precedido del código del país, por ejemplo: ES-R12345678 La expresión Regex es "^[A-Z]{2}-[A-Z]{1}[0-9]{7,8}$", y se determina porque describe lo siguiente: - comienzo de la cadena "^" - dos primeras letras mayúsculas "[A-Z]{2}" - un guión "-" - después una letra mayúscula "[A-Z]{1}" - después de 7 a 8 dígitos "[0-9]{7,8}" - se acaba la cadena "$":
Function NIF_con_Pais(cadena As String) As Boolean Return Regex.IsMatch(cadena, "^[A-Z]{2}-[A-Z]{1}[0-9]{7,8}$") End Function
Para comprobar y generar expresiones Regex se puede usar la siguiente página: https://regex101.com/
Para limitar los valores posibles de una cadena se puede usar un objeto enumerado que sólo tenga una serie de valores posibles. Si se tiene la cadena de texto se puede convertir al objeto de tipo enumerado con Tryparse de la clase [Enum] Por ejemplo se tiene el enumerado:
Public Enum Colores_Semaforo Rojo Amarillo Verde End Enum
Si tenemos la cadena “verde” y se quiere convertir al enumerado sin diferenciar entre mayúsculas y minúsculas:
Dim MiColor as Colores_Semaforo If [Enum].TryParse(“verde”, True, MiColor) Then Console.WriteLine(“Conversión correcta”) End If
Es posible obtener el valor de una propiedad en tiempo real si se sabe como se llama dicha propiedad. La función CallByName puede devolver el valor si la cadena de texto coincide con una propiedad del objeto, por ejemplo:
Dim MiObjeto as new MiTipoObjeto MiObjeto.MiPropiedad = 15 Dim MiPropiedad As Integer = CallByName(MiObjeto, "MiPropiedad", Microsoft.VisualBasic.CallType.Get, Nothing)
Se puede generar un objeto tipo documento XML (XMLDocument) a partir de otro tipo de objeto serializable cualquiera con la función Serialize, por ejemplo:
Public Shared Function SerializarObjeto_a_XmlDoc(ByVal MiObjeto As MiTipoObjeto) As XmlDocument Dim document = New XmlDocument() Dim navigator = document.CreateNavigator()
Using writer = navigator.AppendChild() Dim serializer = New XmlSerializer(GetType(MiObjeto)) serializer.Serialize(writer, MiObjeto) End Using
Si se tiene un documento XML en forma de cadena de texto, se puede crear un objeto que se corresponda con su estructura haciendo una deserialización, por ejemplo:
Using currentStringReader As New StringReader(MiTextoXML) Dim xml As New XmlSerializer(GetType(MiTipoObjeto)) Dim MiObjeto As MiTipoObjeto = TryCast(xml.Deserialize(currentStringReader), MiTipoObjeto) End Using
Una forma sencilla de pasar de un Datatable a una tabla HTML es integrando lo que es el código HTML con el código .NET. Esto hace que se visualice muy rápido cual va a ser el resultado, por ejemplo:
Public Function ConvertDataTableToHTML(ByVal dt As DataTable) As String ConvertDataTableToHTML = <table border="1"> <thead> <tr> <%= From col As DataColumn In dt.Columns.Cast(Of DataColumn)() Select <th><%= " style='font-size:10.0pt;'\>>" & col.ColumnName %></th> %> </tr> </thead> <tbody> <%= From row As DataRow In dt.Rows.Cast(Of DataRow)() Select <tr> <%= From col As DataColumn In dt.Columns.Cast(Of DataColumn)() Select <td><%= " style='font-size:8.0pt;'\>>" & row(col).ToString %></td> %> </tr> %> </tbody> </table>.ToString() End Function
Con la instalación del Visual Studio de Microsoft, viene una aplicación que es capaz de crear un objeto .Net a partir de uno o varios esquemas XSD relacionados entre si. Por ejemplo, por línea de comandos se llama a: