August 2010 - Posts
Una de las consultas comúnmente solicitadas a través del Blog, tiene que ver con la actualización de datos de dos tablas relacionadas en una BD de SQL, o sea actualizar una vista maestro-detalle vinculadas a sendas tablas.
Aunque por obvio y sencillo, las explicaciones acostumbran a ser de lo más diversas y finalmente te das cuenta que la mayoría de ejemplos se inician con un "desparrame" de jergas incomprensivas para la mayoría. Me decido postearos el ejemplo más básico posible, para que a partir de este punto podáis hacerlo crecer a vuestra necesidad.
Espero que os sea útil y despeje vuestras jaquecas cuando se trata de lidiar con diversas tablas.
PepLluis,
(Para ejecutar el ejemplo, iniciar Visual Studio y crear un nuevo proyecto 'Winform', añadir dos DataGridView y un Button, copiar / pegar codigo y por supuesto F5)
Imports System.Data.SqlClient
Public Class Form1
Private Maestro As SqlDataAdapter
Private Detalle As SqlDataAdapter
Private ConjuntoDeDatos As DataSet
Private Sub Form1_Load() Handles MyBase.Load
Dim miConexion As New SqlConnection("Data Source=.\SQLExpress;Initial Catalog=MaestroDetalle;Integrated Security=True")
Maestro = New SqlDataAdapter("Select * From Maestro", miConexion)
Dim MaestroCmdBuilder As New SqlCommandBuilder(Maestro)
Detalle = New SqlDataAdapter("Select * From Detalle", miConexion)
Dim DetalleCmdBuilder As New SqlCommandBuilder(Detalle)
ConjuntoDeDatos = New DataSet
Maestro.Fill(ConjuntoDeDatos, "Maestro")
Me.DataGridView1.DataSource = ConjuntoDeDatos
Me.DataGridView1.DataMember = "Maestro"
Detalle.Fill(ConjuntoDeDatos, "Detalle")
Me.DataGridView2.DataSource = ConjuntoDeDatos
ConjuntoDeDatos.Relations.Add("Fk", ConjuntoDeDatos.Tables("Maestro").Columns("IdMaestro"),
ConjuntoDeDatos.Tables("Detalle").Columns("IdDetalle"))
Me.DataGridView2.DataMember = "Maestro.Fk"
End Sub
Private Sub Actualizar() Handles Button1.Click
If ConjuntoDeDatos.HasChanges Then
Maestro.Update(ConjuntoDeDatos, "Maestro")
Detalle.Update(ConjuntoDeDatos, "Detalle")
End If
End Sub
End Class
Discutiendo sobre la proliferación de núcleos en los procesadores y como sacarle más provecho, os introduzco a la inicialización de colecciones con 'Query's' en Linq utilizando el pragma 'asParallel' de esa forma podemos añadir ese atractivo "Extra" a funciones que normalmente dejan que decir por la falta de agilidad al ejecutarse.
' Ejemplo de inicializacion de Query's paralelas
' En este caso usando una coleccion de respuestas sobre una peticion de ping.
' Pep Lluis 2010
Module Module1
Sub Main()
'Si el sistema dispone de mas de un nucleo
If System.Environment.ProcessorCount > 1 Then
'Definir una lista de IP's... por ejemplo :
Dim Ips = {"localhost", "192.168.1.2", "192.168.1.3"}
'Construccion de la Linq parallel query
Dim PingP = From ip In Ips.AsParallel
Select New System.Net.NetworkInformation.Ping().Send(ip)
Dim asParallel As DateTime = DateTime.Now 'Tomar tiempo de incio proceso
'Procesar las respuestas
ProcessPings(PingP)
'Mostrar el tiempo empleado (Desde el inicio hasta el proceso de respuestas)
Console.WriteLine("Tiempo empleado, usando 'AsParallel' : {0}", DateTime.Now - asParallel)
'Query sin 'asParallel'
Dim PingS = From ip In Ips
Select New System.Net.NetworkInformation.Ping().Send(ip)
Dim noParallel As DateTime = DateTime.Now 'Tomar Tiempo de Inicio
ProcessPings(PingS)
Console.WriteLine("Tiempo Empleado sin Parallel Query : {0}", DateTime.Now - noParallel)
Else
Console.WriteLine("No se puede realizar el test con un solo nucleo.")
End If
Console.ReadLine()
End Sub
'Procesar respuestas
Sub ProcessPings(ByVal Pings)
For Each ping In Pings
Console.WriteLine("{0} : {1}", ping.Status, ping.Address)
Next
End Sub
End Module
Espero vuestas opiniones,
Pep Lluis,
I have this post in English version, no doubt in contact with me if needed.
Debido a la insistencia de algunos lectores de este blog, me complace retomar un antiguo ejemplo donde rellenamos un DGV con los datos de una hoja XLS y posteriormente creamos una BD con la tabla correspondiente y en formato MDB. Por lo tanto seguro que con las nuevas herramientas podremos realizar tareas similares con mucho menos código, por eso matizo que se trata de un ejemplo reanimado de 2005 al 2010 J
Las versiones tanto de la XLS como la MDB corresponden al 97-2003. Para poder ejecutar este ejemplo necesitas crear un nuevo proyecto 'Winforms' en VB y simplemente copiar y pegar el código en el 'form1'.
Tenéis que tener en cuenta para que funcione necesitas guardar tu hoja en la carpeta del proyecto 'Bin/Debug' (o reléase) según estés compilando y con el nombre 'Libro1.xls'.
No dudéis en contactar conmigo para aclarar cualquier duda, además si necesitas el proyecto el completo estaré encantado de facilitártelo (Lo tengo para Visual Studio 2010).
Espero vuestras valoraciones.
Happy reentrada!
Pep Lluis,
' --------------------------------------------------------------------------------------------
' * AVISO IMPORTANTE * Este programa es propiedad (c)2010 Pep Lluis Bano.
' * AVISO IMPORTANTE * Se autoriza su uso, solo con fines formativos.
'
' EL USO DE ESTA APLICACION IMPLICA LA ACEPTACION DE LAS CONDICIONES DE USO QUE SE APLICAN
' AL PROGRAMARIO "Open Source", ESTE PROGRAMA SE PROPORCIONA "COMO ESTA", NO OBLIGANDO AL
' AUTOR A CONTRAER COMPROMISO ALGUNO PARA CON QUIENES LO UTILICEN, ASI COMO DECLINANDO
' CUALQUIER REPONSABILIDAD DIRECTA O INDIRECTA, CONTRAIDA POR LOS MISMOS EN SU UTILIZACION
' FUERA DE LOS PROPOSITOS PARA EL QUE FUE ESCRITO Y DISEÑADO.
'
' CUALQUIER MODIFICACIÓN Y DISTRIBUCION DEL MISMO DEBERA CONTENER Y CITAR SU FUENTE Y ORIGEN.
'
' ASI MISMO EL AUTOR AGRADECERA CUALQUIER COMENTARIO o CORRECCION QUE LOS LECTORES CONSIDEREN
' CONTRIBUYENDO ESTOS ULTIMOS A MEJORAR LA APLICACION CON FINES FORMATIVOS.
' CONSIDEREN ENVIAR SUS COMENTARIOS ulizando la opcion [Contact]
' --------------------------------------------------------------------------------------------
Imports ADOX
Imports System.Data.OleDb
Imports System.Text.RegularExpressions
Public Class Form1
'Definir conexion,adaptador y Dataset
Private MiXlsConexion As OleDbConnection
Private MiXlsAdaptador As OleDbDataAdapter
Private MiXlsDataSet As New DataSet()
Private MiXlsDGV As New DataGridView
Private MiMdbConexion As New OleDbConnection
Private MiMdbAdaptador As New OleDbDataAdapter
Private MiMdbDataSet As New DataSet()
Private Mienlazador As New BindingSource
Private MiMdbDGV As New DataGridView
Private Sub Form1_FormClosing(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
MiMdbConexion.Close()
End Sub
Private Sub Form1_Load() Handles MyBase.Load
Dim MiXlsEtiqueta As New Label
MiXlsEtiqueta.Text = "Contenido de la Hoja Excel"
MiXlsEtiqueta.TextAlign = ContentAlignment.MiddleCenter
MiXlsEtiqueta.BorderStyle = BorderStyle.Fixed3D
MiXlsEtiqueta.BackColor = Color.Green
MiXlsEtiqueta.ForeColor = Color.White
MiXlsEtiqueta.Dock = DockStyle.Top
Dim MiXlsDGBPanel As New Panel
MiXlsDGBPanel.AutoSize = True
MiXlsDGV.Dock = DockStyle.Top
MiXlsDGBPanel.Controls.AddRange(New Control() {MiXlsDGV, MiXlsEtiqueta})
Dim MiMdbEtiqueta As New Label
MiMdbEtiqueta.Text = "Contenido de la BD resultante"
MiMdbEtiqueta.TextAlign = ContentAlignment.MiddleCenter
MiMdbEtiqueta.BorderStyle = BorderStyle.Fixed3D
MiMdbEtiqueta.BackColor = Color.Maroon
MiMdbEtiqueta.ForeColor = Color.White
MiMdbEtiqueta.Dock = DockStyle.Top
Dim MiMdbDGBPanel As New Panel
MiMdbDGBPanel.AutoSize = True
MiMdbDGV.Dock = DockStyle.Top
MiMdbDGBPanel.Controls.AddRange(New Control() {MiMdbDGV, MiMdbEtiqueta})
Dim BotonDeActualizar As New Button
BotonDeActualizar.Dock = DockStyle.Bottom
BotonDeActualizar.Text = "Generar Archivo MDB"
Me.AutoSize = True
Me.Text = "De XLS a MDB"
MiXlsDGBPanel.Dock = DockStyle.Top
MiMdbDGBPanel.Dock = DockStyle.Top
Me.Controls.AddRange(New Control() {MiMdbDGBPanel, MiXlsDGBPanel, BotonDeActualizar})
AddHandler BotonDeActualizar.Click, AddressOf GenerarMdb
LeerXls()
End Sub
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
Private Sub GenerarMdb()
'Eliminar la BD1 si existe
If My.Computer.FileSystem.FileExists("Bd1.mdb") Then
My.Computer.FileSystem.DeleteFile("Bd1.mdb")
End If
'
Dim Nombrede_MiBd = "Bd1.mdb"
Dim NombreDe_MiTabla = "Detalles"
' Para crear una nueva BD de Access, me viene a la
' memoria la funcion Catalog del ADOX.DLL
Dim Catalogo As New ADOX.Catalog()
Catalogo.Create("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & Nombrede_MiBd)
'
' Una vez creado el nuevo catalogo añadiremos
' la tabla utilizando el suministrador OLEDB
MiXlsConexion = New OleDb.OleDbConnection("PROVIDER=Microsoft.Jet.OLEDB.4.0;Data Source =" & Nombrede_MiBd)
'
' Obtenendremos el esquema de la nueva BD
MiXlsConexion.Open()
Dim MiEsquema As DataTable = MiXlsConexion.GetOleDbSchemaTable(OleDb.OleDbSchemaGuid.Tables, _
New Object() {Nothing, Nothing, NombreDe_MiTabla, "Detalles"})
'
' El ultimo paso sera crear la estructura en funcion a las columnas de la hoja
Dim Campos As String = "Create Table [" + NombreDe_MiTabla + "] ("
For Each col As DataGridViewTextBoxColumn In MiXlsDGV.Columns
If Campos.EndsWith(")") Or Campos.EndsWith("Key") Then Campos += ", "
Campos += "[" + Regex.Replace(col.DataPropertyName, " ", "_") + "] Text(50)"
Next
Campos += ")"
Dim MiMandato As New OleDbCommand(Campos, MiXlsConexion)
MiMandato.ExecuteNonQuery()
MiXlsConexion.Close()
'
' Añadir todos las filas como registros a la BD
MiMdbConexion = New OleDb.OleDbConnection("PROVIDER=Microsoft.Jet.OLEDB.4.0;Data Source =" & Nombrede_MiBd)
MiMdbAdaptador = New OleDbDataAdapter("SELECT * FROM Detalles", MiMdbConexion)
Dim commandbuilder As New OleDb.OleDbCommandBuilder(Me.MiMdbAdaptador)
MiMdbConexion.Open()
MiMdbAdaptador.Fill(MiMdbDataSet)
Dim Registro As DataRow
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)
MiMdbDGV.DataSource = MiMdbDataSet.Tables(0)
MiMdbConexion.Close()
End Sub
End Class
Error HTTP 500.21 – Internal error server
|
Pregunta: estoy intentando desplegar mi aplicación web en una instalación nueva de Windows Server 2008, pero después configurarlo cuándo abro la aplicación por defecto aparece "Error HTTP 500.21 - error interno del servidor" hablando "Integrado de PageHandlerFactory"
Esta es una pregunta .repetida para muchos de los que después de instalar desde cero "Server 2008" agregan el rol de servidor web después de instalar el Framework 4.0 completo.
Para solucionar esto simplemente debes ejecutar de nuevo la instalación del framework 4.0 seleccionando la opción de 'reparar' y recuerda agregar el rol de "servidor web" antes del framework la próxima vez.
|
Question : I'm trying deploy my web app in a fresh setup of Windows Server 2008, but after configure when open default web site I get "Error HTTP 500.21 - Internal error server" talking about control "PageHandlerFactory-Integrated"
This is a question asked by people installing a fresh copy of "Server 2008" and adding web server ROL after Framework 4.0 setup.
To solve this just run again framework 4.0 using 'repair' option, and remember add web server rol before framework the next time :-)
|
Regards,
PepLluis,