Todas las entradas de: peplluis

El proveedor ‘Microsoft.Jet.OLEDB.4.0’ no está registrado en el equipo local

Sorprendentemente continúan llegando inquietudes preguntando cómo se abre una BD de Access en las nuevas versiones de VB.  Algunos asiduos a este formato han sufrido el desconcertante mensaje… no está en el equipo local? Cuando la realidad es que no esta implementado!

Para dar una buena explicación, recibimos este mensaje cuando utilizamos ‘OLEDB’ en un sistema X64 y ese es el detalle. No existe una implementación de ‘OLEDB’ para 64 bits.

La única solución es desarrollar en 32Bits, aunque esto ultimo NO signifique que tengamos que reinstalar el sistema operativo… tan solo nesitaremos seleccionar ‘X86’ como ‘CPU de destino’ en las ‘Opciones de Compilación Avanzadas’ de la pestaña ‘Compilar’ en las propiedades de ‘My Project’

Espero que esto os ahorre alguna que otra hora de busqueda.
Pep Lluis,

Error de sintaxis en la instrucción INSERT INTO.

Este es uno de los textos de error que mas amenudo se enfrenta a los que intentan actualizar la informacion enlazada de un DGV’s y una MDB.

Aunque en muchos otros foros/post se advierte de debemos utilizar nombres de campo que no esten reservados, caemos y volvemos a caer en el error de usar nombres con caracteres no admitidos. Un simple espacio al nombrar el campo provocara una excepcion tanto en la operación de ‘INSERT’ Como ‘UPDATE’. Suerte que a grandes males… grandes remedios J

Ejemplo :   el Nombre ‘Columna A’ generara una excepcion
Sin embargo  el nombre ‘Columna_A’ no genera ninguna excepcion… asi de simple.

Os recuerdo el enlace con la lista de palabras reservadas que no pueden utilizarse para nombrar los campos de una MDB que posteriormente utilizaremos enlazada con un DataGridView y un ‘OleDb.OleDbCommandBuilder(MiMdbAdaptador)’

http://support.microsoft.com/kb/248738

En caso contrario las únicas opciones disponibles para continuar utilizando dichos nombres, será construir el’INSERT’… ‘UPDATE’ commands de forma manual o utilizar la opción de ‘Origen de Datos’ generado por Visual Studio.

Saludos,
Pep Lluis,

Yo solo quiero Numeros!

Independientemente de las mil y una formas para filtrar/formatear entradas de texto, me gustan las sencillas sin retorcimientos. Aquí te dejo una idea de cómo aplicar reglas cuando se trata de todo un form, aunque trabajandolo puedes customizar el comportamiento en funcion al control que tiene el foco. No olvides que tambien dispones de un espacio de nombres sensacional :

Imports System.Text.RegularExpressions

Aunque como te digo, en determinadas ocasiones cabe aplicar lo sencillo si con ello cubrimos las necesidades. 😉
El siguiente ejemplo demuestra como filtrar la pulsación de cualquier tecla que no sea numerica o coma.

Private Sub Form1_Load() Handles MyBase.Load
    Me.KeyPreview = True
End Sub 

Protected Overrides Function ProcessDialogKey(ByVal keyData As System.Windows.Forms.Keys) As Boolean
    Select Case keyData
        ‘ 48 a 57  = numericas encima teclado alfabetico
        ‘ 97 a 106 = Numericas teclado numerico
        Case 48 To 57, 97 To 106, Keys.Oemcomma
            ‘Solo devolver las pulsaciones que pasan el filtro
            Return MyBase.ProcessDialogKey(keyData)
        Case Else
            ‘Evitar la propagacion de la pulsacion
            ‘de teclas que no nos interesan
            Return True
    End Select
End Function

Lo Bueno y simple… Dos veces bueno!
Pep Lluis

De XLS a MDB

Desde la aparición de VB.NET y a pesar de las grandes prestaciones SQL Express frente al extinto MSDE, una de las inquietudes que en más ocasiones he visto solicitadas por los desarrolladores, ha sido la portabilidad y la manejabilidad de formatos MDB, XLS, TXT, como moneda de cambio entre aplicaciones, a pesar de todo, supongo que continuamos dependiendo de los antiguos compañeros de viaje.

Son muchas las ocasiones en que se pregunta cómo convertir el contenido de un ‘DataGridBView’ a una Base de datos Access o transportar el contenido de una tabla a un Excel. Creo que este ejercicio puede ser útil como punto de entradilla a ese tipo de aplicaciones “Atípicas” J.  Así que finalmente me he decidido por investigar un poquito para poder llegar a ciertas conclusiones y limitaciones del trabajo con MDB’s usando VB 9. Aquí os dejo una muestra de los resultados, ya sabéis que no es habitual en mí, pero no he tenido tiempo de comentar el código y ponerlo bonito, a pesar de ello a todos los que tengáis un especial interés, os animo a contactar, para poder enviaros el proyecto de pruebas.

Veamos entonces como procesar una hoja de cálculo de Excel para crear un nuevo catalogo en una BD, diseñando la tabla a partir de las columnas del ‘DGV’ y rellenándola con el contenido de celdas.

Evidentemente el punto de partida será esta bonita hoja:

Un Simple XLS

 el segundo paso … Nuestro POgrama pa leer lescel!

    Private Sub LeerXls()
        ‘Abrir y llenar el DGV con la hoja de excel
        MiXlsConexion = New OleDbConnection _
        («Provider=Microsoft.Jet.OLEDB.4.0;» + _
         «Extended Properties = ‘Excel 8.0’;» + _
         «Data Source=|DataDirectory|\libro1.xls;»)
        MiXlsAdaptador = New OleDbDataAdapter(«SELECT * FROM [Hoja1$]», MiXlsConexion)
        MiXlsConexion.Open()
        MiXlsAdaptador.Fill(MiXlsDataSet)
        MiXlsDGV.DataSource = MiXlsDataSet.Tables(0)
    End Sub

Nuestra Aplicacion

Al pulsar sobre «Generar Archivo» obtendremos …



‘ crear estructura de la tabla en funcion a columnas de la hoja
Dim Campos As String = «Create Table [« + NombreDe_MiTabla + «] («
For Each col As DataGridViewTextBoxColumn In MiXlsDGV.Columns
     If Campos.EndsWith(«)») Then Campos += «, «
     Campos += «[« + Regex.Replace(col.DataPropertyName, » «, «_») + «] Text(50)»
Next
Campos += «)»
Dim MiMandato As New OleDbCommand(Campos, MiMDBConexion)
MiMandato.ExecuteNonQuery()




Dim Registro As DataRow
‘Añadir las filas del DGV a la tabla del DataSet
For Each row As DataGridViewRow In MiXlsDGV.Rows
    If row.Index < MiXlsDGV.RowCount – 1 Then
        Registro = MiMdbDataSet.Tables(0).NewRow
        For Each col As DataGridViewColumn In MiXlsDGV.Columns
            ‘Añadir una entrada por celda
             Registro(col.Index) = row.Cells(col.Index).Value
        Next
        ‘Añadir una linea por fila
        MiMdbDataSet.Tables(0).Rows.Add(Registro)
    End If
Next
MiMdbAdaptador.Update(MiMdbDataSet)

 

Hecho!

Sin trampa ni carton, en la carpeta de la aplicacion veremos aparecer un misterisoso Bd1.Mdb

La Prueba

Los Mas desconfiados podeis hacer clic … e volila!

El Resultado

Saludos,
Pep Lluis,

 

De Excel a Texto pasando por un DataGridView

»
» Crear un archivo de texto con el contenido
» de las celdas de un DataGridView de los
» datos cargados de una hoja de excel.
»


Hoja



Imports System.Data.OleDb

Public Class Form1
    ‘Definir conexion,adaptador y Dataset
    Private MiConexion As New OleDbConnection _
    («Provider=Microsoft.Jet.OLEDB.4.0;» + _
     «Extended Properties = ‘Excel 8.0’;» + _
     «Data Source=|DataDirectory|\libro1.xls;»)
    Private MiAdaptador As New OleDbDataAdapter(«SELECT * FROM [Hoja1$]», MiConexion)
    Private MiDataSet As New DataSet()

    Private Sub Form1_Load() Handles MyBase.Load
        ‘Abrir y llenar el DGV con la hoja de excel
        MiConexion.Open()
        MiAdaptador.Fill(MiDataSet)
        Me.DataGridView1.DataSource = MiDataSet.Tables(0)
        ‘Crear un documento de texto
        Dim ATexto = IO.File.CreateText(«MiExport.txt»)
        For Each row As DataGridViewRow In Me.DataGridView1.Rows
            For Each col As DataGridViewColumn In Me.DataGridView1.Columns
                ‘Añadir una entrada por celda
                ATexto.Write(row.Cells(col.Index).Value)
                ‘separar con un tabulador
                ATexto.Write(Chr(Keys.Tab))
            Next
            ‘Añadir una linea por fila
            ATexto.WriteLine()
        Next
        ATexto.Close()
    End Sub

End Class

Bloc
🙂
 

Como saber las unidades logicas que corresponden a una conexion de Red

Atendiendo a la consulta de Cesar, os dejo un fragmento de código, explicando cómo enumerar las unidades que corresponden a conexiones de Red. De hecho es una variacion del anterior post ‘Enumerar las unidades logicas de nuestros discos’.

Sub
Main() Handles MyBase.Load
    ‘ Obtener todas las unidades logicas de mi equipo
    Dim MisUnidades = From Unidad In My.Computer.FileSystem.Drives _
      Select Unidad.Name
    ‘ Componer la informacion que visualizare de mis unidades
    ‘ que correspondan a conexiones de red.

    Dim InfoUnidad = From info In MisUnidades _
       Where My.Computer.FileSystem.GetDriveInfo(info).DriveType = IO.DriveType.Network _
       Select Unidad = My.Computer.FileSystem.GetDriveInfo(info).Name, _
       Tipo = My.Computer.FileSystem.GetDriveInfo(info).DriveType

    Dim miVista As New DataGridView
    miVista.Dock = DockStyle.Fill
    Me.Controls.Add(miVista)
    miVista.DataSource = InfoUnidad.ToList
End Sub

Este es el resultado
UnidadesDeRed

Saludos,
Pep Lluis,

Totalizar una Columna en un DataGridView

Siguiendo la consulta de Jesús Pérez, preguntando como totalizar la suma de una columna de un DataGridView, poniendo como ejemplo recorrer las filas de una columna y efectuar las operaciones que consideremos oportunas.

Aquí tenéis el enlace para resolverlo según MSDN:
http://msdn.microsoft.com/es-es/library/system.data.datatable.compute.aspx

' Computar la suma de la columna 'Capital'
Dim total As Object = dt.Compute("SUM(Capital)", Nothing)
' visualizar el resultado en la barra
Me.Text = total.ToString

Si por el contrario optamos por hacerlo recorriendo las filas de la Columna… (tal i como me habéis solicitado) el código seria algo similar al siguiente :

... Load()
'Disparar el calculo cada vez que editamos 
AddHandler Me.dataGridView1.CellEndEdit, AddressOf Sumar
'Calcular totalizando la columna 3 "Salario"
Me.dataGridView1.Columns(3).HeaderText = "Sueldo"
Me.dataGridView1.AllowUserToAddRows = False
Me.dataGridView1.CurrentCell = dataGridView1.Rows(0).Cells(3)
Sumar()
... End Sub
'
' Sumar las cantidades de una columna
'
Private Columna As Integer = 3
Sub Sumar()
    Dim Total As Integer = 0      
    'Acumular el total
    Dim UltimaFila As Integer = Me.dataGridView1.Rows.Count
    'Solo calculamos si modificamos la columna
    If Me.dataGridView1.CurrentCell.ColumnIndex = Columna Then
        For Each row As DataGridViewRow In Me.dataGridView1.Rows
            If row.Index < UltimaFila - 1 Then Total += row.Cells(Columna).Value
        Next
        Me.dataGridView1.Rows(UltimaFila - 1).Cells(3).Value = Total.ToString
    End If
End Sub

Pd. No dudeis en pedirme el proyecto completo si estais interesados, o si quereis comentar alguna parte del codigo.

 

Dos Tablas y sus relaciones en un DataGridView a traves de un ‘ComboBoxColumn’

Ejemplo de cómo añadir una columna de selección unida a una tabla de ‘maestros’ y relacionada con su identificador en la tabla ‘detalles’, en casos reales solo teneis que substituir las tablas por los ‘sources’ de las tablas en vuestra BD.
Me gustara recibir vuestros comentarios… 😉


Combo3
 


Imports System
Imports System.Data

Public Class Form1
    Private dataGridView1 As New DataGridView()


    Private Sub Form1_Load() Handles Me.Load
       
        ‘ Simular tabla con los Detalles
       
        Dim Detalles As New DataTable(«Detalle»)
        Detalles.Columns.Add(«Actividad»)
        Detalles.Columns.Add(«Nombre»)
        Detalles.Columns.Add(«Telefono»)
        Detalles.Rows.Add(«001», «Pep Lluis», «231.321.321»)
        Detalles.Rows.Add(«002», «Luis Franco», «Internacional»)
        Detalles.Rows.Add(«003», «Marc Rubiño», «111.222.333»)
        Detalles.Rows.Add(«004», «Javier Conesa», «91.244.32.32»)
       
        ‘ Simular tabla con los Id’s Maestros
       
        Dim Maestros As New DataTable(«Maestro»)
        Maestros.Columns.Add(«Actividad»)
        Maestros.Columns.Add(«Descripcion»)
        Maestros.Rows.Add(«001», «POgramaor»)
        Maestros.Rows.Add(«002», «Torero»)
        Maestros.Rows.Add(«003», «Banderillero»)
        Maestros.Rows.Add(«004», «ANALista»)

       
        ‘ Construir el DS y establecer relaciones
       
        Dim MiDataSet As New DataSet
        MiDataSet.Tables.Add(Detalles)
        MiDataSet.Tables.Add(Maestros)
        MiDataSet.Relations.Add(«Actividad», _
              MiDataSet.Tables(«Maestro»).Columns(«Actividad»),_
              MiDataSet.Tables(«Detalle»).Columns(«Actividad»))
        
        ‘ Añadir una columna ‘ComboBox’
        ‘ Conteniendo la tabla ‘Maestro’
       
        Dim MiBoxColumn As New DataGridViewComboBoxColumn
        MiBoxColumn.DisplayMember = «Descripcion»
        MiBoxColumn.ValueMember = «Actividad»
        MiBoxColumn.DataPropertyName = «Actividad»
        MiBoxColumn.DataSource = MiDataSet.Tables(«Maestro»)
        Me.dataGridView1.Columns.Add(MiBoxColumn)
       
        ‘ Visualizar el DGV con la columna combo ‘Maestro’
        ‘ y las columnas y tablas de ‘Detalle’
       
        Me.dataGridView1.Dock = DockStyle.Fill
        Me.Controls.Add(dataGridView1)
        Me.dataGridView1.DataSource = MiDataSet.Tables(«Detalle»)

   End Sub
End Class


Si os interesa en determinadas situaciones podeis «camuflar» el combo para que tenga un aspecto como este :



Combo4


De esta forma no podran modificar ni desplegar las opciones y su aspecto sera como el de cualquier otra columna.
Ajustando las propiedades :


        MiBoxColumn.DisplayStyle = DataGridViewComboBoxDisplayStyle.Nothing
        MiBoxColumn.ReadOnly = True


Saludos,
Pep Lluis,


PD. Agradecemos la participacion de los actores secundarios (Javier, Luis i Marc), aunque tengo mis dudas sobre si son personajes reales o ficticios 😉