viernes, 31 de octubre de 2014

No es un miembro de 'System.Collections.Generic.List(Of String)

Reconozco que esto una chorrada , pero vale para que no siempre nos fiemos del entorno

“error BC30456: 'Intersect' no es un miembro de 'System.Collections.Generic.List(Of String)'.”


Por mucho que le demos al botón de derecho no lo resuelve solo.
Opciones
  1. Añadir Imports System.Linq
    Imports System.Linq
    Public Class Form1
        Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
            Dim lstOne As New List(Of String)() From {"Jim", "Jack", "Kate", "Nope"}
            Dim lstTwo As New List(Of String)() From {"Jack", "Nope", "Jim"}
            Dim lstNew As IEnumerable(Of String) = Nothing
            lstNew = lstOne.Intersect(lstTwo, StringComparer.OrdinalIgnoreCase)
        End Sub
    End Class
  2. Modificar las propiedades de proyecto, en la pestaña referencias

Personalmente me quedo con la opción 1.

viernes, 24 de octubre de 2014

Server Management Studio.



Una herramienta muy útil para el Microsoft Sql  Server Management Studio.
Para mi poder ver el contenido de un columna en binario simplemente genial.

sábado, 30 de agosto de 2014

Mostrar un xml en un treeview

Esto es un ejemplo muy sencillo de como mostrar un xml con un treeview.

Documentación:
Código:


Public Class frmXML
    Private m_ruta As String = "Contactos.xml"
    Private Sub frmXML_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
        Dim doc As XDocument = XDocument.Load(m_ruta)
        Dim root As XElement = doc.Root
        Dim x = GetNodes(New TreeNode(root.Name.LocalName), root).ToArray()
        TreeView1.Nodes.AddRange(x)
    End Sub
    Private Function GetNodes(ByVal node As TreeNode, ByVal element As XElement) As IEnumerable(Of TreeNode)
        If element.HasElements Then
            Return TreeNodeEx.AddRange(node, (From item In element.Elements() _
                      Let tree = New TreeNode(item.Name.LocalName) _
                      From newNode In GetNodes(tree, item) _
                      Select newNode))
        Else
            node.Text = element.Name.LocalName & " = " & element.Value
            Return New TreeNode() {node}
        End If
    End Function
End Class
Public Class TreeNodeEx
    Public Shared Function AddRange(ByVal collection As TreeNode, ByVal nodes As IEnumerable(Of TreeNode)) As IEnumerable(Of TreeNode)
        Dim items = nodes.ToArray()
        collection.Nodes.AddRange(items)
        Return New TreeNode() {collection}
    End Function
End Class
Salida:

Nota: el xml lo dejo por si alguno le interesa pero valdría cualquiera,  el código no tiene ninguna referencia a los elementos del xml
<contacts>
   <contact>
      <name>Patrick Hines</name>
      <phone type="home">206-555-0144</phone>
      <phone type="work">425-555-0145</phone>
      <address>
         <street1>123 Main St</street1>
         <city>Mercer Island</city>       
         <state>WA</state>
         <postal>68042</postal>
      </address>
      <netWorth>10</netWorth>
   </contact>
   <contact>
      <name>Gretchen Rivas</name>
      <phone type="mobile">206-555-0163</phone>
      <address>
         <street1>123 Main St</street1>
         <city>Mercer Island</city>
         <state>WA</state>
         <postal>68042</postal>
      </address>
      <netWorth>11</netWorth>
   </contact>
   <contact>
      <name>Scott MacDonald</name>
      <phone type="home">925-555-0134</phone>
      <phone type="mobile">425-555-0177</phone>
      <address>
         <street1>345 Stewart St</street1>
         <city>Chatsworth</city>
         <state>CA</state>
         <postal>91746</postal>
      </address>
      <netWorth>500000</netWorth>
   </contact>
</contacts>

sábado, 23 de agosto de 2014

Enum


Cuando en un código se comparan cadenas, siempre me pregunto porque no usaron enum o constantes.Tal vez no venga mal hacer un recordatorio de que es un enum.
La primera cosa que hay que saber es que son enteros, representa un valor numérico. (MSDN)


Como Char
Esto tal vez para alguno sea un problema, porque lo que queríamos era tener un char. La cantidad de veces que en la base de datos tenemos un char que significa algo.

Ejemplo:
Son valores, numéricos así que siempre puedes transformarlo a su valor ASCII
Public Enum Respuestas
    undefine = AscW(" ")
    SI = AscW("S")
    NO = AscW("N")
End Enum

Dim omiRespuesta As Respuestas = [Enum].Parse(GetType(Respuestas), "SI")
Console.WriteLine("MiRespuesta  {0:D},  como texto {0}", omiRespuesta)
omiRespuesta = [Enum].Parse(GetType(Respuestas), AscW("S"))
Console.WriteLine("MiRespuesta  {0:D}, como texto {0}", omiRespuesta)
Salida
MiRespuesta 83, como texto SI
MiRespuesta 83, como texto SI


Por supuesto que soluciones hay varias.. pero esta es la que me parece más elegante.

Usarlos como un conjunto de marcas
Hay que considerar que los valores deben ser potencias de 2 (MSDN)

Ejemplo:
<FlagsAttribute()> _
Public Enum DiasSemana
    undefine = 1 << 0
    Lunes = 1 << 1
    Martes = 1 << 2
    Miercoles = 1 << 3
    Jueves = 1 << 4
    Viernes = 1 << 5
    Sabado = 1 << 6
    Domingo = 1 << 7
    DiasLaborables = Lunes Or Martes Or Miercoles Or Jueves Or Viernes
    FinDeSemana = Sabado Or Domingo
End Enum
Dim aux As DiasSemana = DiasSemana.Lunes
       
Dim cad As String = String.Join(",",[Enum].GetValues(GetType(DiasSemana)).Cast(Of DiasSemana).ToList().FindAll(Function(x) DiasSemana.FinDeSemana.HasFlag(x) AndAlso x <> DiasSemana.FinDeSemana))
Console.WriteLine("El fin de semana son los: " & cad)
Console.WriteLine(" ------ ")
If DiasSemana.DiasLaborables.HasFlag(aux) Then
                Console.WriteLine(" el {0} es {1}. Num {0:d} - {1:d} ", aux, DiasSemana.DiasLaborables)
Else
                Console.WriteLine("el {0} no es {1}. Num {0:d} - {1:d}", aux, DiasSemana.DiasLaborables)
End If
Console.WriteLine("  ------ ")
Console.WriteLine("el {0}  or   {1}  :  {2}. {0:d} or  {1:d} :{2:d}", aux, DiasSemana.DiasLaborables, aux Or DiasSemana.DiasLaborables)
Console.WriteLine("el {0} xor   {1}  :  {2}. {0:d} Xor {1:d} :{2:d}", aux, DiasSemana.DiasLaborables, aux Xor DiasSemana.DiasLaborables)
Console.WriteLine("el {0} and   {1}  :  {2}. {0:d} and {1:d} :{2:d}", aux, DiasSemana.DiasLaborables, aux And DiasSemana.DiasLaborables)
Console.WriteLine("  ------ ")
If aux.HasFlag(DiasSemana.DiasLaborables) Then
       Console.WriteLine("el {0} es {1}. Num {0:d} - {1:d} ", aux, DiasSemana.DiasLaborables)
Else
       Console.WriteLine("el {0} no es {1}. Num {0:d} - {1:d}", aux, DiasSemana.DiasLaborables)
End If         

Salida
El fin de semana son los: Sabado,Domingo
------
el Lunes es DiasLaborables. Num 2 - 62
------
el Lunes or DiasLaborables : DiasLaborables. 2 or 62 :62
el Lunes xor DiasLaborables : Martes, Miercoles, Jueves, Viernes. 2 Xor 62 :60
el Lunes and DiasLaborables : Lunes. 2 and 62 :2
------
el Lunes no es DiasLaborables. Num 2 - 62

Hay que tener algunas consideraciones con esto. Normalmente usamos los enum de manera exclusiva. Si por ejemplo estamos en un select case como este:
Dim dias As DiasSemana = DiasSemana.Lunes Or DiasSemana.Martes
Select Case dias
Case DiasSemana.Lunes
Console.WriteLine("  Lunes ")
Case DiasSemana.Martes
Console.WriteLine("  Martes ")
Case DiasSemana.DiasLaborables
Console.WriteLine("  laborable ")
Case Else
Console.WriteLine("  otro ")
End Select
La salida será otro ¡!!

Una opción es crear un diccionario  con lo que queremos hacer cada día de la semana y obtener todas la acciones que cumplen con nuestra condición.  
Dim lstQueHacer As Dictionary(Of DiasSemana, Action) = New Dictionary(Of DiasSemana, Action)
lstQueHacer.Add(DiasSemana.Lunes, Sub() Console.WriteLine("hacer los lunes.."))
lstQueHacer.Add(DiasSemana.Martes, Sub() Console.WriteLine("hacer los  martes.."))
lstQueHacer.Add(DiasSemana.Miercoles, Sub() Console.WriteLine("hacer los  miercoles.."))
lstQueHacer.Add(DiasSemana.DiasLaborables, Sub() Console.WriteLine("hacer todos los dias laborables.."))

Dim flags As List(Of DiasSemana) = [Enum].GetValues(GetType(DiasSemana)).Cast(Of DiasSemana).ToList().FindAll(Function(x) dias.HasFlag(x) Or x.HasFlag(dias))
For Each oDia As DiasSemana In flags
                lstQueHacer(oDia)()
Next
Salida
hacer los lunes..
hacer los martes..
hacer todos los dias laborables..

Como verás he hecho dias.HasFlag(x) Or x.HasFlag(dias)) esto es asi porque yo quería que me dijera que hacer los lunes, los martes y las cosas comunes para los días laborables.

Dejo este enlace por si alguno tiene otras dudas


viernes, 6 de junio de 2014

IDENTITY - Error de desbordamiento aritmético

Bueno problemilla de hoy.

Tenemos una tabla con un campo id que es identity de tipo smallint
En la tabla hacemos una consulta y solo hay 10 registros
El mayor id es 11
Cuando queremos hacer un insert da un error

Mens. 8115, Nivel 16, Estado 1, Línea 1
Error de desbordamiento aritmético al convertir IDENTITY al tipo de datos smallint.
Desbordamiento aritmético.

Antes de que te vuelvas loco, tal vez se borraron registros y por eso no lo ves (que es lo nos pasó a nosotros)
La solución es resetear el valor de la identidad y se puede hacer por linea de comandos


También es posible hacer un trucante

viernes, 2 de mayo de 2014

Seguridad & Applet & Java


Una curiosidad que nos ha llevado un rato (posiblemente para otros sea obvio)

Creamos un Applet,las utilidades pueden ser vario-pintas. Desde las nuevas versiones de Java, se obliga a que el Applet este firmado por una entidad de confianza. De hecho, si no está firmado bloquea el Applet. Esto es un paso “más” en la seguridad: desde mi punto de vista relativo, estamos suponiendo que los usuarios verán (porque leer es más que improbable) el mensaje del Java y sabrán lo que significa (lo cual es mucho suponer)

Por supuesto hay documentación al respecto:
http://www.java.com/es/download/help/appsecuritydialogs.xml

Cómo firmar el Applet:
http://docs.oracle.com/javase/7/docs/technotes/tools/windows/jarsigner.html

Supongamos que lo hemos hecho todo, y después de repasarlo aún tenemos el mensaje de aviso. La pregunta sería: ¿estamos usando una firma valida?. Esa firma la usas para otras cosas, está emitida por una entidad que tú entiendes que es válida. ¿Seguro?

Que entiende Oracle por certificación (CA) de confianza?? Estará en google, pero yo no lo he visto. Lo que es seguro es que está en tu máquina:

En Windows (panel de control/ programas/ java )



Si tu firma no está emitido por un CA valido incluida en esa lista, siempre tendrás el mensajes de aviso. Para que te salga el aviso en azul, tus usuarios tendrán que agregar el certificado de la entidad que generó la firma. Pero nunca verán el logo de Java en el mensaje.
La solución real, es usar un certificado de una CA Valida y tendras el logo de Java