Librería de Snippets para VB.NET !! (Compartan aquí sus snippets)

<< < (116/119) > >>

Eleкtro:
Convertir un objeto Datatable a una tabla en formato Markdown:

Código
''' ----------------------------------------------------------------------------------------------------
''' <summary>
''' Converts the elements of a <see cref="DataTable"/> into a Markdown table.
''' </summary>
''' ----------------------------------------------------------------------------------------------------
''' <example> This is a code example that shows how to convert a DataTable object to Markdown table.
''' <code language="VB.NET">
''' Dim dt As New DataTable()
''' dt.Columns.Add("ID", GetType(Integer))
''' dt.Columns.Add("Name", GetType(String))
''' dt.Rows.Add(1, "John")
''' dt.Rows.Add(2, "Doe")
'''
''' Dim markdownTable As String = EnumerableToMarkdownTable(dt)
''' Console.WriteLine(markdownTable.ToString())
''' </code>
''' </example>
''' ----------------------------------------------------------------------------------------------------
''' <param name="table">
''' The source <see cref="DataTable"/>.
''' </param>
''' ----------------------------------------------------------------------------------------------------
''' <returns>
''' A string representing the Markdown table.
''' </returns>
''' ----------------------------------------------------------------------------------------------------
Public Shared Function DataTableToMarkdownTable(table As DataTable) As String
 
   If table Is Nothing Then
       Throw New ArgumentNullException(paramName:=NameOf(table))
   End If
 
   If table.Rows.Count = 0 Then
       Throw New ArgumentNullException("The source table does not contain any row.", paramName:=NameOf(table))
   End If
 
   Dim columnNames As IEnumerable(Of String) = table.Columns.Cast(Of DataColumn)().Select(Function(column) column.ColumnName)
   Dim maxColumnValues As Integer() = columnNames.Select(Function(name) table.AsEnumerable().Max(Function(row) If(row.IsNull(name), 0, row(name).ToString().Length))).ToArray()
 
   Dim headerLine As String = "| " & String.Join(" | ", columnNames) & " |"
   Dim headerDataDividerLine As String = "| " & String.Join(" | ", maxColumnValues.Select(Function(length) New String("-"c, length))) & " |"
 
   Dim lines As IEnumerable(Of String) = {headerLine, headerDataDividerLine}.Concat(
       table.AsEnumerable().Select(
           Function(row) "| " & String.Join(" | ", columnNames.Select(Function(name, i) If(row.IsNull(name), "".PadRight(maxColumnValues(i)), row(name).ToString().PadRight(maxColumnValues(i))))) & " |"
       )
   )
 
   Return String.Join(Environment.NewLine, lines)
 
End Function


Convertir un objeto IEnumerable a una tabla en formato Markdown:

Código
''' ----------------------------------------------------------------------------------------------------
''' <summary>
''' Converts the elements of an <see cref="IEnumerable(Of T)"/> into a Markdown table.
''' </summary>
''' ----------------------------------------------------------------------------------------------------
''' <remarks>
''' Original C# concept: <see href="https://github.com/jpierson/to-markdown-table/blob/develop/src/ToMarkdownTable/LinqMarkdownTableExtensions.cs"/>
''' </remarks>
''' ----------------------------------------------------------------------------------------------------
''' <example> This is a code example that shows how to convert a List(Of String) object to Markdown table.
''' <code language="VB.NET">
''' Dim list As New List(Of String)
''' list.Add("John")
''' list.Add("Doe")
'''
''' Dim markdownTable As String = EnumerableToMarkdownTable(list)
''' Console.WriteLine(markdownTable.ToString())
''' </code>
''' </example>
''' ----------------------------------------------------------------------------------------------------
''' <example> This is a code example that shows how to convert a List of a custom type to Markdown table.
''' <code language="VB.NET">
''' Public Class TestClass
'''     Public Property ID As Integer
'''     Public Property Name As String
'''     Public Property Age As Integer
''' End Class
'''
''' Dim list As New List(Of TestClass) From {
'''     New TestClass() With {.ID = 1, .Name = "John", .Age = 30},
'''     New TestClass() With {.ID = 2, .Name = "Doe" , .Age = 40}
''' }
'''
''' Dim markdownTable As String = EnumerableToMarkdownTable(list)
''' Console.WriteLine(markdownTable.ToString())
''' </code>
''' </example>
''' ----------------------------------------------------------------------------------------------------
''' <typeparam name="T">
''' The type of elements in the collection.
''' </typeparam>
'''
''' <param name="source">
''' The generic collection to convert into a Markdown table.
''' </param>
''' ----------------------------------------------------------------------------------------------------
''' <returns>
''' A string representing the Markdown table.
''' </returns>
''' ----------------------------------------------------------------------------------------------------
Public Shared Function EnumerableToMarkdownTable(Of T)(source As IEnumerable(Of T)) As String
   If source Is Nothing OrElse Not source.Any() Then
       Throw New ArgumentNullException(paramName:=NameOf(source))
   End If
 
   If GetType(T).IsPrimitive OrElse GetType(T) = GetType(String) Then
       Return $"| Items |{Environment.NewLine}| ----- |{Environment.NewLine}{String.Join(Environment.NewLine, source.Select(Function(s) $"| {s} |"))}"
   End If
 
   Dim properties As PropertyInfo() = GetType(T).GetProperties(BindingFlags.Instance Or BindingFlags.Public Or BindingFlags.GetProperty)
   Dim fields As IEnumerable(Of FieldInfo) = GetType(T).GetRuntimeFields().Where(Function(f) f.IsPublic)
 
   Dim gettables As IEnumerable(Of MarkdownColumnData) =
       Enumerable.Union(properties.Select(Function(p As PropertyInfo)
                                              Return New MarkdownColumnData With {
                                                  .Name = p.Name,
                                                  .GetValue = Function(obj) p.GetValue(obj),
                                                  .Type = p.PropertyType
                                              }
                                          End Function),
                        fields.Select(Function(f As FieldInfo)
                                          Return New MarkdownColumnData With {
                                              .Name = f.Name,
                                              .GetValue = Function(obj) f.GetValue(obj),
                                              .Type = f.FieldType
                                          }
                                      End Function))
 
   Dim maxColumnValues As Integer() = source.
           Select(Function(x) gettables.Select(Function(p) If(p.GetValue(x)?.ToString()?.Length, 0))).
           Union({gettables.Select(Function(p) p.Name.Length)}).
           Aggregate(
               Enumerable.Repeat(0, gettables.Count()).AsEnumerable(),
               Function(accumulate, x) accumulate.Zip(x, Function(a, b) System.Math.Max(a, b))).
           ToArray()
 
   Dim columnNames As IEnumerable(Of String) =
       gettables.Select(Function(p) p.Name)
 
   Dim headerLine As String =
       "| " & String.Join(" | ", columnNames.Select(Function(n, i) n.PadRight(maxColumnValues(i)))) & " |"
 
   Dim isNumeric As Func(Of Type, Boolean) =
       Function(type As Type)
           Return type = GetType(Byte) OrElse type = GetType(SByte) OrElse type = GetType(UShort) OrElse type = GetType(UInteger) OrElse type = GetType(ULong) OrElse type = GetType(Short) OrElse type = GetType(Integer) OrElse type = GetType(Long) OrElse type = GetType(Decimal) OrElse type = GetType(Double) OrElse type = GetType(Single)
       End Function
 
   Dim rightAlign As Func(Of Type, String) =
       Function(type As Type)
           Return If(isNumeric(type), ":", " "c)
       End Function
 
   Dim headerDataDividerLine As String =
           "| " &
           String.Join("| ", gettables.Select(Function(g, i) New String("-"c, maxColumnValues(i)) & rightAlign(g.Type))) &
           "|"
 
   Dim lines As IEnumerable(Of String) =
       {
           headerLine,
           headerDataDividerLine
       }.Union(source.
           Select(Function(s)
                      Return "| " & String.Join(" | ", gettables.Select(Function(n, i) If(n.GetValue(s)?.ToString(), "").PadRight(maxColumnValues(i)))) & " |"
                  End Function))
 
   Return lines.Aggregate(Function(p, c) p & Environment.NewLine & c)
End Function

Eleкtro:
Los dos siguientes métodos sirven para truncar nombres de archivos que superen los 255 caracteres (incluyendo la longitud de la extensión del archivo), acortando la longitud cuanto sea necesario para no sobrepasar dicho límite, y añadiendo puntos suspensivos (…) al final del nombre del archivo.

Eso es lo que hace con los nombres de archivo (file name), no con las rutas (file path).

En caso de enviar como parámetro a cualquiera de estos dos métodos una ruta de archivo (file path), aparte de realizar los ajustes mencionados con el nombre del archivo y, en caso de que la ruta exceda el límite máximo permitido de 260 caracteres (definido en MAX_PATH), se añadirá el prefijo "\\?\" a la ruta para garantizar la compatibilidad de uso con sistemas NTFS que tengan habilitado el soporte para rutas de longitud extendida (es decir, mayores de 260 caracteres).

De esta forma, y además de prevenir el uso de nombres de archivo (file names) inválidos / demasiado largos, además se garantiza que la aplicación que utilice estos métodos para la manipulación o creación de archivos sea "LONG PATH AWARE".

Nota: Los métodos han pasado pruebas usando rutas locales (relativas y absolutas). No han sido probados con rutas UNC ni adaptados para ello.

Leer con detenimiento el bloque de documentación XML para más información.

Código
''' ----------------------------------------------------------------------------------------------------
''' <summary>
''' If needed, truncates the length of the specified file name or full file path  
''' to comply with Windows OS maximum file name length of 255 characters
''' (including the file extension length).
''' <para></para>
''' If the file name exceeds this limit, it truncates it and
''' adds a ellipsis (…) at the end of the file name.
''' <para></para>
''' If the path exceeds the MAX_PATH limit (260 characters),
''' it adds the "\\?\" prefix to support extended-length paths.
''' <para></para>
''' See also: <see href="https://learn.microsoft.com/en-us/windows/win32/fileio/maximum-file-path-limitation"/>
''' </summary>
''' ----------------------------------------------------------------------------------------------------
''' <remarks>
''' This method is particularly useful when dealing with file names or file paths that might exceed
''' the maximum allowed length, preventing potential errors related to file name length limitations
''' when creating files in the drive.
''' </remarks>
''' ----------------------------------------------------------------------------------------------------
''' <param name="filePath">
''' The file name or full file path.
''' </param>
'''
''' <param name="maxFileNameLength">
''' Optional. The maximum character length that the file name can have.
''' Default (and maximum) value is 255.
''' </param>
''' ----------------------------------------------------------------------------------------------------
''' <returns>
''' The truncated file name or full file path.
''' </returns>
''' ----------------------------------------------------------------------------------------------------
<DebuggerStepThrough>
Public Shared Function TruncateLongFilePath(filePath As String, Optional maxFileNameLength As Byte = 255) As String
 
   If String.IsNullOrEmpty(filePath) Then
       Throw New ArgumentNullException(paramName:=NameOf(filePath))
   End If
 
   If filePath.StartsWith("\\?\", StringComparison.Ordinal) Then
       filePath = filePath.Substring(4)
   End If
 
   Dim fileInfo As New FileInfo(If(filePath.Length <= 255, filePath, $"\\?\{filePath}"))
   TruncateLongFilePath(fileInfo, maxFileNameLength)
   Return fileInfo.FullName
 
End Function
 
''' ----------------------------------------------------------------------------------------------------
''' <summary>
''' If needed, truncates the length of the file name in
''' the source <see cref="FileInfo"/> object to comply with
''' Windows OS maximum file name length of 255 characters
''' (including the file extension length).
''' <para></para>
''' If the file name exceeds this limit, it truncates it and
''' adds a ellipsis (…) at the end of the file name.
''' <para></para>
''' If the path exceeds the MAX_PATH limit (260 characters),
''' it adds the "\\?\" prefix to support extended-length paths.
''' <para></para>
''' See also: <see href="https://learn.microsoft.com/en-us/windows/win32/fileio/maximum-file-path-limitation"/>
''' </summary>
''' ----------------------------------------------------------------------------------------------------
''' <remarks>
''' This method is particularly useful when dealing with file paths that might exceed
''' the maximum allowed length, preventing potential errors related to file name length limitations
''' when creating files in the drive.
''' </remarks>
''' ----------------------------------------------------------------------------------------------------
''' <param name="refFileInfo">
''' The source <see cref="FileInfo"/> object representing a full file path.
''' <para></para>
''' When this method returns, this object contains the file path with the file name truncated.
''' </param>
'''
''' <param name="maxFileNameLength">
''' Optional. The maximum character length that the file name can have.
''' Default (and maximum) value is 255.
''' </param>
''' ----------------------------------------------------------------------------------------------------
<DebuggerStepThrough>
Public Shared Sub TruncateLongFilePath(ByRef refFileInfo As FileInfo, Optional maxFileNameLength As Byte = 255)
 
   If refFileInfo Is Nothing Then
       Throw New ArgumentNullException(paramName:=NameOf(refFileInfo))
   End If
 
   If maxFileNameLength = 0 Then
       Throw New ArgumentException("Value must be greater than zero.", paramName:=NameOf(maxFileNameLength))
   End If
 
   If refFileInfo.Name.Length >= maxFileNameLength Then
       Dim fileExt As String = refFileInfo.Extension
       Dim fileName As String = refFileInfo.Name.Substring(0, maxFileNameLength - 1 - fileExt.Length) & $"…{fileExt}"
 
       Dim directoryName As String = Path.GetDirectoryName(refFileInfo.FullName)
       If directoryName.Equals("\\?", StringComparison.Ordinal) Then
           refFileInfo = New FileInfo($"\\?\{fileName}")
 
       ElseIf directoryName.StartsWith("\\?\", StringComparison.Ordinal) Then
           refFileInfo = New FileInfo(Path.Combine(refFileInfo.DirectoryName, fileName))
 
       Else
           Dim fullpath As String = Path.Combine(refFileInfo.DirectoryName, fileName)
           refFileInfo = If(fullpath.Length >= 260, ' MAX_PATH
                         New FileInfo($"\\?\{fullpath}"),
                         New FileInfo(fullpath))
       End If
   End If
 
End Sub

Parado_larga_duracion_ESP:
Dejo un repositorio de utilidades de Excel. Tiene 3 ficheros a día de hoy.

1. Para pasar y leer JSONs
2. Demo de carga de datos por AJAX
3. Utilidades varias, incluida REGEX_MATCH. Va bien para validar formatos en Excel.

https://github.com/allnulled/excel-framework/tree/main

Eleкtro:
La siguiente función, por nombre "GetAssemblyNetTargetType", sirve para determinar si el tipo de un archivo de ensamblado es .NET Framework, .NET Standard o .NET Core.

Modo de empleo:
Código
Dim assembly As Assembly = Assembly.LoadFile("C:\Assembly.dll")
Dim assemblyType As NetTargetType = GetAssemblyNetTargetType(assembly)
Console.WriteLine(assemblyType.ToString())

La función contiene tres validaciones diferentes, separadas por Regiones, aunque por lo general solamente se procesará el bloque de código de la primera validación.

Se ha diseñado así con la intención de funcionar correctamente en diversos escenarios, con errores esperados e inesperados de Reflection, y ya sea teniendo en cuenta si se usa esta función desde una aplicación .NET Framework, o .NET Core.

Código
''' <summary>
''' Specifies the type of a .NET assembly.
''' </summary>
Public Enum NetTargetType
   ''' <summary>
   ''' An assembly that targets .NET Framework.
   ''' </summary>
   NetFramework
 
   ''' <summary>
   ''' An assembly that targets .NET Standard.
   ''' </summary>
   NetStandard
 
   ''' <summary>
   ''' An assembly that targets .NET Core.
   ''' </summary>
   NetCore
End Enum

Código
''' ----------------------------------------------------------------------------------------------------
''' <summary>
''' Determines whether the specified assembly ia a .NET Framework, .NET Standard or .NET Core assembly.
''' </summary>
''' ----------------------------------------------------------------------------------------------------
''' <returns>
''' A <see cref="NetTargetType"/> value that indicates the type of assembly.
''' </returns>
''' ----------------------------------------------------------------------------------------------------
<DebuggerStepThrough>
Public Shared Function GetAssemblyNetTargetType(assembly As Assembly) As NetTargetType
 
#Region " Primary validation "
   Dim parimaryValidationException As Exception = Nothing
 
   Dim attrib As TargetFrameworkAttribute
   Try
       attrib = assembly.GetCustomAttributes.OfType(Of TargetFrameworkAttribute).SingleOrDefault()
       If attrib?.FrameworkName.StartsWith(".NETFramework", StringComparison.OrdinalIgnoreCase) Then
           Return NetTargetType.NetFramework
 
       ElseIf attrib?.FrameworkName.StartsWith(".NETStandard", StringComparison.OrdinalIgnoreCase) Then
           Return NetTargetType.NetStandard
 
       ElseIf attrib?.FrameworkName.StartsWith(".NETCore", StringComparison.OrdinalIgnoreCase) Then
           Return NetTargetType.NetCore
 
       Else
           Throw New NotImplementedException($"Cannot determine type of {NameOf(TargetFrameworkAttribute)}.")
 
       End If
 
   Catch ex As FileNotFoundException When ex.FileName.StartsWith("System.Runtime", StringComparison.OrdinalIgnoreCase)
       ' This exception will be thrown generally when the current
       ' running application is targetting .NET Framework
       ' and Reflection (via method "GetCustomAttributes")
       ' tries to load "System.Runtime" assembly.
 
       Dim assName As New AssemblyName(ex.FileName)
       If assName.Version.Major >= 4 AndAlso assName.Version.Minor <> 0 Then
           Return NetTargetType.NetCore
       Else
           ' Ignore and continue with the alternative .NET Core validation.
       End If
 
   Catch ex As Exception
       parimaryValidationException = ex
       ' Ignore for now, and continue with the alternative validations.
 
   End Try
#End Region
 
#Region " .NET Standard alternative validation (when Primary validation failed) "
   Dim isNetStandard As Boolean =
       assembly.GetReferencedAssemblies().
                Any(Function(x) x.Name.Equals("netstandard", StringComparison.OrdinalIgnoreCase))
 
   If isNetStandard Then
       Return NetTargetType.NetStandard
   End If
#End Region
 
#Region " .NET Core alternative validation (when Primary validation failed) "
Dim isNetCore As Boolean =
   assembly.GetReferencedAssemblies().
            Any(Function(x As AssemblyName)
                    Return (x.Name.Equals("System.Runtime", StringComparison.OrdinalIgnoreCase) _
                            AndAlso x.Version.Major >= 4 _
                            AndAlso x.Version.Minor <> 0) _
                            OrElse ({"System.Collections",
                                     "System.ComponentModel.Primitives",
                                     "System.Drawing.Primitives",
                                     "System.Windows.Forms"
                                    }.Contains(x.Name) _
                            AndAlso x.Version.Major > 4)
                End Function)
 
   If isNetCore Then
       Return NetTargetType.NetCore
   End If
#End Region
 
   If parimaryValidationException IsNot Nothing Then
       Throw parimaryValidationException
   End If
   Throw New Exception("Cannot determine type of assembly.")
End Function

Eleкtro:
Dos métodos que manipulan el registro de Windows. El primero sirve para crear una nueva entrada en el menú contextual del explorador de Windows al hacer click derecho sobre un tipo de archivo, lo que por lo general sirve para asociar un programa a un tipo/extensión de archivo y poder cargar el archivo haciendo click en esa entrada del menú contextual.

Y el segundo método sirve para borrar la entrada.

Nota: el primer método sirve para crear entradas individuales, no sirve para crear submenús.

Código
''' <summary>
''' Creates a registry key that represents a new entry in the Explorer's context-menu for the specified file type.
''' </summary>
'''
''' <param name="fileType">
''' The file type (typically a file extension) for which to create the entry in the Explorer's context-menu.
''' </param>
'''
''' <param name="keyName">
''' The name of the registry key.
''' </param>
'''
''' <param name="text">
''' The display text for the entry in the Explorer's context-menu.
''' <para></para>
''' This value can be null, in which case <paramref name="keyName"/> will be used as text.
''' </param>
'''
''' <param name="position">
''' The position of the entry in the Explorer's context-menu.
''' <para></para>
''' Valid values are: "top", "middle" and "bottom".
''' <para></para>
''' This value can be null.
''' </param>
'''
''' <param name="icon">
''' The icon to show for the entry in the Explorer's context-menu.
''' <para></para>
''' This value can be null.
''' </param>
'''
''' <param name="command">
''' The command to execute when the entry is clicked in the Explorer's context-menu.
''' </param>
<DebuggerStepThrough>
Public Shared Sub CreateFileTypeRegistryMenuEntry(fileType As String, keyName As String,
                                                 text As String, position As String,
                                                 icon As String, command As String)
 
   If String.IsNullOrWhiteSpace(fileType) Then
       Throw New ArgumentNullException(paramName:=NameOf(fileType))
   End If
 
   If String.IsNullOrWhiteSpace(keyName) Then
       Throw New ArgumentNullException(paramName:=NameOf(keyName))
   End If
 
   If String.IsNullOrWhiteSpace(command) Then
       Throw New ArgumentNullException(paramName:=NameOf(command))
   End If
 
   If String.IsNullOrEmpty(text) Then
       text = keyName
   End If
 
   Using rootKey As RegistryKey = Registry.ClassesRoot,
         subKey As RegistryKey = rootKey.CreateSubKey($"{fileType}\shell\{keyName}", writable:=True),
         subKeyCommand As RegistryKey = subKey.CreateSubKey("command", writable:=True)
 
       subKey.SetValue("", text, RegistryValueKind.String)
       subKey.SetValue("icon", icon, RegistryValueKind.String)
       subKey.SetValue("position", position, RegistryValueKind.String)
 
       subKeyCommand.SetValue("", command, RegistryValueKind.String)
   End Using
 
End Sub

Código
''' <summary>
''' Deletes an existing registry key representing an entry in the Explorer's context-menu for the specified file type.
''' </summary>
'''
''' <param name="fileType">
''' The file type associated with the registry entry.
''' </param>
'''
''' <param name="keyName">
''' The name of the registry key to delete.
''' </param>
'''
''' <param name="throwOnMissingsubKey">
''' Optional. If <see langword="True"/>, throws an exception if the registry key is not found.
''' <para></para>
''' Default value is <see langword="True"/>.
''' </param>
<DebuggerStepThrough>
Public Shared Sub DeleteFileTypeRegistryMenuEntry(fileType As String, keyName As String, Optional throwOnMissingsubKey As Boolean = True)
 
   If String.IsNullOrWhiteSpace(fileType) Then
       Throw New ArgumentNullException(paramName:=NameOf(fileType))
   End If
 
   If String.IsNullOrWhiteSpace(keyName) Then
       Throw New ArgumentNullException(paramName:=NameOf(keyName))
   End If
 
   Using rootKey As RegistryKey = Registry.ClassesRoot
       rootKey.DeleteSubKeyTree($"{fileType}\shell\{keyName}", throwOnMissingsubKey)
   End Using
 
End Sub

Navegación

[0] Índice de Mensajes

[#] Página Siguiente

[*] Página Anterior