Contestando a la pregunta de como ejecutar un proceso de 32 bits en el IIS del Win 2008…
Desde la configuracion avanzada del Grupo de aplicaciones :
Saludos,
Pep Lluis,
Contestando a la pregunta de como ejecutar un proceso de 32 bits en el IIS del Win 2008…
Desde la configuracion avanzada del Grupo de aplicaciones :
Saludos,
Pep Lluis,
‘ A tren de una consulta de como duplicar filas de un DGV a otro
‘ a petición de Raul os dejo esta idea (muy básica) de como
‘ componer un «albarán» a partir de un DGV con los datos del articulo.
‘
‘ Al realizar un doble clic sobre una fila de artículos
‘ se abrirá un cuadro de dialogo pidiendo la cantidad
‘ una vez introducida, crearemos una nueva línea en un
‘ DataGridView personalizado para contener la entradas
‘ de un albarán… evidentemente ficticio.
‘Ejemplo utilizando VB2008
Imports System.Data.OleDb
Public Class Form1
‘
‘Definir objectos de conexion a base de datos
Private MiConexion As New OleDbConnection(«Provider=Microsoft.Jet.OLEDB.4.0; Data Source=MiBd.mdb;»)
Private MiAdaptador As New OleDbDataAdapter(«SELECT * FROM Articulos», MiConexion)
Private MiDataSet As New DataSet()
Private MiEnlazador As New BindingSource
‘
‘tareas en tiempo de carga de la aplicación
Private Sub Form1_Load() Handles MyBase.Load
‘Abrir conexion y llenar el dataset
MiConexion.Open()
MiAdaptador.Fill(MiDataSet)
Dim commandbuilder As New OleDb.OleDbCommandBuilder(Me.MiAdaptador)
‘Asignamos el origen de datos para del DataGridView
Me.DataGridView1.DataSource = MiDataSet.Tables(0)
‘Cerrar la conexión
MiConexion.Close()
‘Clonar o…
‘Reproducir la estructura del 1er dataGrid en DataGridView2
‘añadiendo una columna para la cantidad y otra para totalizar
Me.DataGridView2.ColumnCount = Me.DataGridView1.ColumnCount + 1
Me.DataGridView2.Columns(0).Name = «Cantidad»
Me.DataGridView2.Columns(0).HeaderText = «Cantidad»
For x = 1 To Me.DataGridView1.ColumnCount – 1
Me.DataGridView2.Columns(x).Name = Me.DataGridView1.Columns(x).Name
Me.DataGridView2.Columns(x).HeaderText = Me.DataGridView1.Columns(x).HeaderText
Next
Me.DataGridView2.Columns(DataGridView1.ColumnCount).Name = «Total»
Me.DataGridView2.Columns(DataGridView1.ColumnCount).HeaderText = «Total»
Me.DataGridView2.AllowUserToAddRows = False
End Sub
‘
‘ Al hacer doble click sobre la fila del articulo esta se duplica en el segundo grid
‘
Private Sub DataGridView1_DoubleClick(….) Handles DataGridView1.DoubleClick
If DataGridView1.SelectedRows.Count > 0 Then
‘Añadir los valores obtenidos de la fila seleccionada
‘al segundo datagridview
Dim Unidades = InputBox(«Numero de unidades para :» _
+ DataGridView1.SelectedRows.Item(0).Cells(1).Value, «Cantidad»)
If Unidades.Length > 0 Then
Me.DataGridView2.Rows.Add( _
FilaAlbaran( _
Unidades, _
DataGridView1.SelectedRows.Item(0)) _
)
End If
End If
End Sub
‘
‘ Componer la nueva entrada al DGV del albaran
‘
Function FilaAlbaran(ByVal cantidad As String, ByVal fila As DataGridViewRow) As String()
‘Dimensionar el array al tamaño de columnas del DGV + una de total
Dim Contenido(Me.DataGridView1.ColumnCount) As String
‘La primera columna corresponde a la cantidad
Contenido(0) = cantidad
‘Rellenar el contenido con el valor de las celdas de la fila
For Ndx = 1 To Contenido.Length – 2
Contenido(Ndx) = fila.Cells(Ndx).Value
Next
‘Calcular y mover a la columna total el resultado de la cantidad por el precio
Contenido(Contenido.Length – 1) = cantidad * Contenido(Contenido.Length – 2)
Return Contenido
End Function
End Class
Atendiendo a la consulta de Javier..
Hola Pep Lluis, he leído varias veces las soluciones que das en los diferentes espacios y foros, y quizá esta pregunta te la hayan hecho ya, pero la verdad ando algo atorado con este problemilla… ahí va :
La idea es tener 2 datagrid’s : el1er Datagrid : Muestra el resultado de una búsqueda, de este datagrid deben seleccionar 1 o varios registros y deberán pasarse al 2do Datagrid : Que debe mostrar los registros seleccionados en el 1er datagrid.Si paso un registro del Datagrid 1 al 2, el registro desaparecerá del 1 y aparecerá en el 2, y viceversa.
____
Supongo que existen diversas formas de conseguir lo mismo y sin duda más sofisticadas pero como siempre buscando la simplicidad y en pro de la comprensión os muestro el siguiente ejemplo evitando a exprofeso estructuras complejas difíciles de seguir.
Para poder tener visión sobre dos maneras distintas de hacerlo, he decido mostrar el primer DGV unido a una estructura de datos y el segundo “clonado” pero sin estar enlazado a ninguna BD, por lo tanto deberéis situar el ejemplo como un punto de partida, en ningún caso como una solución concreta y mucho menos pensando en dos DGV’s enlazados a datos y con relaciones… pues la cosa puede complicarse ligeramente y como os digo no es el propósito ni alcance de este corto.
Tampoco contempla en qué orden y como se ordenan los registros o filas que se copian o mueven de un lado a otro J, también he obviado procesar la excepciones para concentrarnos solo en el código que puede interesarnos… por lo que no está libre de ‘errores’.
Para utilizar este código tienes que crear un nuevo proyecto “Windows Form Application” desde el menú de Visual Basic y arrastrar y soltar dos DGV’s, dos CheckBox y dos Botones de la ventana de herramientas, a continuación solo debes copiar y pegar este código substituyendo el generado por el ‘wizard’. También debes crear una BD de Access en la carpeta ‘debug’ conteniendo la tabla de la BD referenciada en la cadena de conexión, para poder leer tanto código comodamente,.me he tomado la libertad de eliminar las firmas de las funciones, por lo que tendréis de substituir el “(….)” Por el ‘ByVal sender As System.Object, ByVal e As System.EventArgs’ correspondiente en VB2005 o dejarlo simplemente () en VB2008.
Espero que os sea útil,
Saludos!
Pep Lluis,
Imports System.Data.OleDb
Public Class Form1
‘
‘Definir objectos de conexion a base de datos
Private MiConexion As New OleDbConnection(«Provider=Microsoft.Jet.OLEDB.4.0; Data Source=TuBd.mdb;»)
Private MiAdaptador As New OleDbDataAdapter(«SELECT * FROM TuTabla», MiConexion)
Private MiDataSet As New DataSet()
Private MiEnlazador As New BindingSource
‘
‘tareas en tiempo de carga de la aplicación
Private Sub Form1_Load(….) Handles MyBase.Load
‘Abrir conexion y llenar el dataset
MiConexion.Open()
MiAdaptador.Fill(MiDataSet)
Dim commandbuilder As New OleDb.OleDbCommandBuilder(Me.MiAdaptador)
‘Asignamos el origen de datos para del DataGridView
Me.DataGridView1.DataSource = MiDataSet.Tables(0)
‘Cerrar la conexión
MiConexion.Close()
‘Clonar o…
‘Reproducir la estructura del 1er dataGrid en DataGridView2
Me.DataGridView2.ColumnCount = Me.DataGridView1.ColumnCount
For x = 0 As Integer To Me.DataGridView1.ColumnCount – 1
Me.DataGridView2.Columns(x).Name = Me.DataGridView1.Columns(x).Name
Me.DataGridView2.Columns(x).HeaderText = Me.DataGridView1.Columns(x).HeaderText
Next
Me.CheckBox1.Checked = True ‘por defecto al iniciar seleccionamos
Me.CheckBox2.Checked = False ‘Operaciones origen DGV1, destino DGV2
End Sub
‘
‘Boton Copiar
Private Sub Btn_Copiar_Click(….) Handles Btn_Copiar.Click
‘determinar la direccion de copiar entre DGV1 y 2
If CheckBox1.Checked Then
‘Comprobar que existen columnas seleccionadas
If DataGridView1.SelectedRows.Count > 0 Then
CopiarSeleccionadosDGV1aDGV2()
End If
Else
If DataGridView2.SelectedRows.Count > 0 Then
CopiarSeleccionadosDGV2aDGV1()
End If
End If
End Sub
‘
‘Boton Mover
Private Sub Btn_Mover_Click(….) Handles Btn_Mover.Click
‘determinar la direccion de mover entre DGV1 y 2
If CheckBox1.Checked Then
‘Comprobar que existen columnas seleccionadas
If DataGridView1.SelectedRows.Count > 0 Then
MoverSeleccionadosDGV1aDGV2()
End If
Else
If DataGridView2.SelectedRows.Count > 0 Then
MoverSeleccionadosDGV2aDGV1()
End If
End If
End Sub
‘
‘Copiar los elementos seleccionados del DGV1 al DGV2
Sub CopiarSeleccionadosDGV1aDGV2()
For Each Seleccion As DataGridViewRow In DataGridView1.SelectedRows
Me.DataGridView2.Rows.Add(ObtenerValoresFila(Seleccion))
Next
DataGridView1.ClearSelection()
End Sub
‘
‘Copiar los elementos seleccionados del DGV1 al DGV2
Sub CopiarSeleccionadosDGV2aDGV1()
For Each Seleccion As DataGridViewRow In DataGridView2.SelectedRows
Me.MiDataSet.Tables(0).Rows.Add(ObtenerValoresFila(Seleccion))
Next
DataGridView2.ClearSelection()
End Sub
‘
‘Mover los elementos seleccionados del DGV1 al DGV2
Sub MoverSeleccionadosDGV1aDGV2()
‘Para cada fila seleccionada
For Each Seleccion As DataGridViewRow In DataGridView1.SelectedRows
‘Añadir los valores obtenidos de la fila seleccionada
‘al segundo datagridview
Me.DataGridView2.Rows.Add(ObtenerValoresFila(Seleccion))
‘eliminar la fila del DataGridView origen
DataGridView1.Rows.Remove(Seleccion)
Next
End Sub
‘
‘Mover los elementos seleccionados del DGV1 al DGV2
Sub MoverSeleccionadosDGV2aDGV1()
‘Para cada fila seleccionada
For Each Seleccion As DataGridViewRow In DataGridView2.SelectedRows
‘Añadir los valores obtenidos de la fila seleccionada
‘al segundo datagridview
Me.MiDataSet.Tables(0).Rows.Add(ObtenerValoresFila(Seleccion))
‘eliminar la fila del DataGridView origen
DataGridView2.Rows.Remove(Seleccion)
Next
End Sub
‘
‘Obtener el contenido de la fila en un string()
‘con el proposito de copiarlo o moverlo
‘
‘Recibe el ‘row’ y retorna su contenido en un array tipo string
Function ObtenerValoresFila(ByVal fila As DataGridViewRow) As String()
‘Dimensionar el array al tamaño de columnas del DGV
Dim Contenido(Me.DataGridView1.ColumnCount – 1) As String
‘Rellenar el contenido con el valor de las celdas de la fila
For Ndx As Integer = 0 To Contenido.Length – 1
Contenido(Ndx) = fila.Cells(Ndx).Value
Next
Return Contenido
End Function
‘
‘Seleccionar la direccion en que se efectuara la copia
Private Sub CheckBox1_CheckedChanged(….) Handles CheckBox1.CheckedChanged
CheckBox2.Checked = Not CheckBox1.Checked
End Sub
Private Sub CheckBox2_CheckedChanged(….) Handles CheckBox2.CheckedChanged
CheckBox1.Checked = Not CheckBox2.Checked
End Sub
End Class
En muchas situaciones, sobre todo cuando hablamos de PIC’s se plantean cuestiones en torno como manejar un simple aplicación de intercambio de datos utilizando el IO.Ports.
A falta de un ejemplo concreto os facilito este código, aunque en anteriores Post’s podéis aprender algunas observaciones y consideraciones a tener en cuenta.
El siguiente ejemplo, envía una petición al micro-controlador cada 100ms, siempre y cuando no este ocupado esperando una respuesta. La respuesta se compone del Byte enviado mas un ‘0’ o un ‘1’, por lo tanto después de identificar la respuesta añadiremos el estado a un ‘Label1’ que acumulara todas las respuestas o dicho de otro modo todos los Ceros y Unos J
No dudéis en seguir la conversación si os interesa discutir algún aspecto en concreto. Pero como siempre estos ejemplos son muy ligeros, pretendiendo ser una idea inicial para demostrar que es posible, aunque distan mucho de ser la solución completa o ideal.
Saludos,
Pep Lluis,
Public Class Form1
Private PuertoSerie As New IO.Ports.SerialPort
Private Temporizado As New System.Timers.Timer
Private IOEncurso As Boolean = False
Delegate Sub ActualizarTexto(ByVal Texto As String)
Private Sub Form1_Load(….) Handles MyBase.Load
Temporizado.Interval = 100
‘cada 100ms ejecutar la funcion TareasTemporizadas
AddHandler Temporizado.Elapsed, AddressOf TareasTemporizadas
‘Abrir el puerto serie
PuertoSerie = My.Computer.Ports.OpenSerialPort(«COM1», 115200, IO.Ports.Parity.Even, 7, IO.Ports.StopBits.Two)
‘ejecutar la funcion recepcion al recibir datos
AddHandler PuertoSerie.DataReceived, AddressOf Recepcion
Temporizado.Start()
End Sub
‘Buffer de recepcion
Private Dato(1) As Byte
Sub Recepcion()
Try
‘Añadir la recepcion actual al buffer
If PuertoSerie.BytesToRead > 1 Then
‘Leer dos bytes
PuertoSerie.Read(Dato, 0, 2)
‘Verificar que el primero identifica inicio
Select Case Chr(Dato(0))
Case «R»
‘añadir el status leido (0 o 1) al Label
Actualizar_Etiqueta(Label1.Text + Chr(Dato(1)))
Case Else
‘descartar el contenido del buffer
‘pues el dato(0) no corresponde a inicio
PuertoSerie.DiscardInBuffer()
End Select
‘Dar por finalizada la respuesta
IOEncurso = False
End If
Catch ex As Exception
MessageBox.Show(ex.Message)
IOEncurso = False
End Try
End Sub
‘
‘Utilizamos el INVOKE de LABEL1 Para evitar error..
‘ Operación no válida a través de subprocesos:
‘ Se tuvo acceso al control ‘Label1’ desde
‘ un subproceso distinto a aquel en que lo creó.
Private Sub Actualizar_Etiqueta(ByVal [texto] As String)
‘Mostrar los bytes recibidos en el Label1
If Me.Label1.InvokeRequired Then
Dim delegado As New ActualizarTexto(AddressOf Actualizar_Etiqueta)
Me.Invoke(delegado, New Object() {[texto]})
Else
Me.Label1.Text = [texto]
End If
End Sub
‘
‘Controlar el envio de peticiones
‘ en nuestro caso cada 100ms
Sub TareasTemporizadas()
‘Solo enviar una nueva peticion
‘si se ha completado la anterior
If Not IOEncurso Then
PuertoSerie.Write(«R»)
IOEncurso = True
End If
End Sub
End Class
Para finalizar y dar otros puntos de vista, según las escuelas pueden utilizarse formas tales como:
Dim PuertoSerie As New IO.Ports.SerialPort
PuertoSerie = My.Computer.Ports.OpenSerialPort(«COM1»)
….
….
PuertoSerie.Write(«Peticion»)
System.Threading.Thread.Sleep(100) ‘Dar tiempo al dispotivo
Dim Resultado() As Byte(Longitud)
PuertoSerie.Read(Resultado, 0, Longitud, 10000)
‘ donde 10000 es el timepo predefinido para
‘ que el puerto serie dispare una excepcion
‘ por tiempo de expera excedido
A pesar de que en mi opinión, utilizar ‘Sleeps’ y técnicas de esperar un fuera de tiempo no cumple con las expectativas de un programa que se precie. Pero esto ultimo no deja de ser una opinión muy personal.
Considerando interesante la pregunta y con el permiso de Cream, me gustaría compartir esta pequeña cuestión en tanto a la metodología en la recepción de datos usando el IO.Ports.
La pregunta:
“no siempre recibo bien los datos o no los capturo por el puerto serie”.. el código que estoy usando actualmente es el siguiente :
puertoSerie.write(«R») ‘enviamos carácter
dato=Asc(puertoSerie.ReadExisting.Chars(1)) ‘leemos y cogemos valor de x
Una de las características de las comunicaciones serie en uno de sus modos, es que son asíncronas… lo que significa que los ‘Bytes’ se serializan y transmiten sin que el receptor conozca el momento preciso. Es decir el bit de ‘start’ indica al receptor el envío de un ‘byte’ pero en ningún caso y por ausencia de protocolo conocemos de antemano la cantidad de ‘bytes’ que vamos a recibir asi como el intervalo de tiempo que va a transcurrir en la transmision entre byte’s.
Como tu bien dices y expresas en tus razonamientos, estas ejecutando la lectura directamente sin esperar al evento de ‘Data Received’, es presumible que en la rapidez de proceso del PC nos dispare la excepción de “index out of range exception” pues estas intentando procesar la posición del segundo carácter que evidentemente aun no has recibido y por lo tanto es inexistente.
El mandato ReadExisting, lee los bytes recibidos que actualmente permanecen en el buffer, en tu caso y en ocasiones, dependiendo del flujo de ejecución, en el buffer debes tener por leer, 0, quizas 1 o cuando te funciona bien2 bytes.
La práctica correcta es formalizar el intercambio de tramas delimitándolas con un carácter de inicio y otro de fin… por ejemplo la mayoría implementan el CR o Chr(13) como fin de trama, algunos fabricantes optan por utilizar como fin de trama secuencias tales como 2 bytes de FCS + Un Carácter identificativo + LF + CR, en fin como siempre hay para todos los gustos. Al menos con este método podrás estar seguro de que la transmisión a finalizado correctamente.
Deberías implementar el disparo de recepción y procesar los datos una vez se ha completado la recepción. En todo caso otra opción podría ser algo parecido a:
‘String de recepción utilizado como buffer
Private PortSerie_Recepcion As String = «»
‘Anadir el manipulador de recepción en la sub New, Load…
AddHandler Serie.DataReceived, AddressOf Rx
Sub Rx(ByVal sender As Object, _
ByVal e As serialDataReceivedEventArgs)
Try
‘Añadir la recepción actual al buffer
PortSerie_Recepcion += Serie.ReadExisting
If PortSerie_Recepcion.Contains(Chr(13)) Then
….PROCESAR LA INFORMACION
PortSerie_Recepcion = «»
End If
Catch ex As Exception
‘En caso de excepción
End Try
End Sub
Si la longitud de tus tramas es de 2 bytes… una idea muy básica puede ser controlar el número de caracteres que están en el buffer pendientes de ser leídos y antes de procesarlos con: PuertoSerie.BytesToRead
‘ Prohibido definitivamente
‘
If PuertoSerie.BytesToRead = 2 Then
dato = Asc(PuertoSerie.ReadExisting.Chars(1))
End If
‘ Definitivamente NO ES RECOMENDABLE!
‘
If PuertoSerie.BytesToRead > 2 Then
dato = Asc(PuertoSerie.ReadExisting.Chars(1))
End If
El problema utilizando el primer caso es que nunca se procesara el dato si no se reciben exactamente dos caracteres, por ende y peor aún si BytesToRead es > 2 nunca procesara los bytes recibidos, poniendo en apuros a nuestra aplicación cuando él se desborde el buffer de recepción. En segundo caso y en determinadas situaciones de intercambios muy rápidos o con interferencias podria perder la secuencia lecturas de pares de bytes y procesar inadecuadamente por desplazamiento de posiciones… como mal menor necesitarías usar PuertoSerie.BytesToRead > 2 conjuntamente con PuertoSerie.Read(Dato(),0,2), aunque insisto lo mejor es incluir un fin de trama en cada transmisión desde el firmware del dispositivo.
‘ una propuesta… Quizas
‘
Dim Trama() As Char
If PuertoSerie.BytesToRead > 2 Then
PuertoSerie.Read(Trama, 0, 2)
dato = Asc(Trama(1))
End If
Saludos,
Pep Lluis,
Efectivamente… para responder a la pregunta de si podemos ordenar la consulta, añadiremos simplemente el ‘Order By’ antes del select, tal y como sigue :
(From procesos In ProcesosLocales _
Order By procesos.Id _
Select _
New MiProcessInfo() With {.Id = procesos.Id, _
.Nombre = procesos.ProcessName} _
).ToList
‘ En este caso obtenemos la lista ordenada por el Id
(From procesos In ProcesosLocales _
Order By procesos.ProcessName _
Select _
New MiProcessInfo() With {.Id = procesos.Id, _
.Nombre = procesos.ProcessName} _
).ToList
‘ En este caso obtenemos la lista ordenada por el Nombre
No olvideis que se puede ordenar de mayor a menor o Viceversa usando la opcion ‘Ascending‘ o ‘Descending‘ justo despues del nombre del campo a ordenar.
Saludos,
Pep Lluis,
PD. la ‘V’ de Vice por gentileza de Fran… jajajajaja.
A peticion de Ariel, me complace compartir este sencillo ejemplo de cómo enlazar el Combobox visualizando el valor de una columna asignando el conocido ‘DisplayMember’ y obteniendo el valor de otra columna con su ‘ValueMember’. De esa forma entre otras muchas aplicaciones, lo tendremos disponible y podremos visualizarlo en un textbox por poner un ejemplo.
Public Class Form1
Private MiComboBox As New ComboBox
Private MiTextBox As New TextBox
Private Sub Form1_Load(… ..) Handles MyBase.Load
‘
‘ Simular tabla Maestros
‘
Dim Maestros As New DataTable(«Maestro»)
Maestros.Columns.Add(«Nombre»)
Maestros.Columns.Add(«Matricula»)
Maestros.Rows.Add(«Juan Jose», «1001 BCN»)
Maestros.Rows.Add(«Alberto Juan», «2002 ABC»)
Maestros.Rows.Add(«Antonio Miguel», «3003 NJR»)
Maestros.Rows.Add(«Jose Maria», «4004 FCB»)
‘
‘ Construir el DataSet
‘
Dim MiDataSet As New DataSet
MiDataSet.Tables.Add(Maestros)
‘
‘ Añadir un ‘ComboBox’
‘ Conteniendo la tabla ‘Maestro’
‘ mostrando la columna ‘Nombre’
‘ y señalando como valor a la matricula
‘
MiComboBox.DisplayMember = «Nombre»
MiComboBox.ValueMember = «Matricula»
MiComboBox.DataSource = MiDataSet.Tables(«Maestro»)
MiComboBox.Dock = DockStyle.Top
Me.Controls.Add(MiComboBox)
AddHandler MiComboBox.SelectedIndexChanged, AddressOf ActualizarTextBox
MiTextBox.Dock = DockStyle.Bottom
Me.Controls.Add(MiTextBox)
ActualizarTextBox()
End Sub
‘
‘ Mover el valor seleccionado del combo al textbox
Private Sub ActualizarTextBox()
MiTextBox.Text = MiComboBox.SelectedValue
End Sub
End Class
»
» Saber de los procesos que se estan ejecutando
»
Public Class Form1
Private Sub Form1_Load(….) Handles MyBase.Load
‘Obtener la lista de procesos en ejecucion
Dim ProcesosLocales As Process() = Process.GetProcesses
‘Construir un DataGridView para visualizar
Dim MiDgv As New DataGridView
‘Acoplarlo al form rellenandolo en su totalidad
MiDgv.Dock = DockStyle.Fill
Me.Controls.Add(MiDgv)
‘ Podriamos utilizar : MiDgv.DataSource = ProcesosLocales.ToList
‘ aunque antes deberiamos contemplar las excepciones
‘ derivadas de la falta de privilegios en el
‘ acceso a ciertas propiedades de los procesos
MiDgv.DataSource = _
(From procesos In ProcesosLocales Select _
New MiProcessInfo() With {.Id = procesos.Id, _
.Nombre = procesos.ProcessName} _
).ToList
End Sub
End Class
Class MiProcessInfo
‘
‘Leer/Asignar su Id
Private m_Id As String
Public Property Id() As Integer
Get
Return m_Id
End Get
Set(ByVal value As Integer)
m_Id = value
End Set
End Property
‘
‘Leer/Asignar su Nombre
Private m_Nombre As String
Public Property Nombre() As String
Get
Return m_Nombre
End Get
Set(ByVal value As String)
m_Nombre = value
End Set
End Property
End Class
Mas que un ‘Post’… una nota, en primer lugar por descubrirme la gran cantidad de personas que visitáis este humilde blog cada día, en segundo lugar para pediros paciencia y tiempo para poder responder a todas las preguntas y comentarios que durante este mes habéis dejado tan amablemente, en tercer lugar y para finalizar agradeceros los comentarios tan alentadores que por supuesto dan sentido a las horas dedicadas.
Es excitante estar de nuevo aquí con la esperanza de aportar un poquito de lo mucho que nos espera encarando la última etapa de este año.
Contento de saludaros de nuevo!
Pep Lluis,
Para los que se fueron, para los que se van, para los que volvieron y para los que se quedaron.
Que disfrutéis de, que tengáis, que hayáis tenido, que no perdais la esperanza de tener ….
unos felices días de paz y descanso!
[ip]
Nos vemos,
Pep Lluis,