Serie ficheros virtuales



C Ficheros virtuales



B.II.3 La clase CMagic para cuadrados mágicos y sudokus. 

 

  B.II.3.1 Introducción

 B.II.3.2 La clase CMagic interfaz del servicio SRMagic, sintetización algorítmica del programa de generación de cuadrados mágicos y  sudokus PMagic

 B.II.3.3 Lista completa de métodos de la clase CMagic

 B.II.3.4 El programa de presentación en VisualBasic “Magic”

 B.II.3.5 Ampliación de componentes

 

                                                                                                                                                 _______

 

B.II.3.1 Introducción

 

En el capítulo A.II.1 se presentó un programa para generar cuadrados mágicos y sudokus, con un interfaz Visual C++.

 

Por su parte, en el capítulo B.1.3, se tomó el programa y se extrajo la parte algorítmica desarrollando la DLL SRMagic.

 

A este servicio se le proporcionó un interfaz COM, COMMagic, que finalmente se utilizó en un programa de presentación escrito en Visual Basic NET.

 

                                                                                                                                                 _______

 

 

B.II.3.2 La clase CMagic como interfaz del servicio SRMagic, sintetización algorítmica del programa PMagic de generación de cuadrados

         mágicos y sudokus

 

Ahora se verá como desarrollar una biblioteca de clases .net contenedora, la DLL CMagic, que se utilizará en el mismo programa Visual Basic que utilizaba el servicio COM y del que mostramos ahora una imagen

 

 

 

 

y ahora la imagen de una evolución posterior tras activar el temporizador

 

 

 

 

Se presenta a continuación el fragmento inicial del código de la clase CMagic, representativa del resto de la codificación, y en donde se han resaltado las instrucciones principales de enlace con los servicios de SRMagic:

 

 

// Cmagic.h



 

// Inclusión de servicios comunes

 

#pragma once

 

#using <mscorlib.dll>

using namespace System;

 

 

// Inclusión de los servicios de SRMagic, como código no administrado

 

#pragma unmanaged

#include "srmagicx.h"

#pragma managed

 

 

namespace Cmagic

{

 

 //----------------------------------------------------------------------------------

 // Clase Cmagic. Interfaz de SRmagic para uso NET

 //----------------------------------------------------------------------------------

 

 

 public __gc class Cmagic

 {

  // TODO: agregar aquí los métodos de la clase.

 

  private: long m_N; // Receptor de la dimensión del cuadro

 

 

  public:

 

 

  // Constructor. Apertura de proceso

 

  Cmagic(void)

  {

   long lresul = 0; // Control de resultados intermedios

 

   lresul = SRmagic_Open();

 

   return;

  }

 

 

 // Cierre de proceso (Destructor efectivo de la parte no .NET)

 

 short int Close(void)

 {

  return SRmagic_Close();

 }

 

 

 // Activar la visualización de una celda i,j

 

 long Activa(long i, long j)

 {

  return SRmagic_Activar(i, j);

 }

 

 . . .

 

                                                                                                                                                 _______

 

 

B.II.3.3 Lista completa de métodos de la clase CMagic

 

 

Apertura y cierre de proceso

 

 Cmagic(void)          // Constructor. Apertura de proceso

 

 short int Close(void) // Cierre de proceso. Destructor de la parte no .NET

 

 

Rutina de generación principal

 

 void Genera(short int iSudoku, long N) // Rutina de generación principal

 

 

 

Control de visualización

 

 long Activa(long i, long j)    // Activa la visualización de una celda i,j

 

 long Desactiva(long i, long j) // Desactiva la visualización de una celda i,j

 

 

 

Informativas

 

 short int RecuperaEstado(long i, long j) // Recupera el estado de una celda

 

 long Read(long indice)                   // Lectura secuencial. Devuelve IJ [= (I-1) * m_N + J]

 

 long ReadActiva(long indice)             // Lectura secuencial de IJ de celdas activas.

 

 long ReadDesactiva(long indice)          // Lectura secuencial de IJ de celdas ocultas.

 

 long RecuperaNumActivas(void)            // Recupera el nºde celdas con visualización activa

 

 long RecuperaNumDesactivas(void)         // Recupera el nºde celdas con visualización oculta

 

 long RecuperaValor(long i, long j)       // Recupera el valor de una celda

 

 long SumaColumna(long j)                 // Recupera el valor de la suma de una columna

 

 long SumaFila(long j)                    // Recupera el valor de la suma de una fila

 

 

 

Auxiliares

 

 String* EditaValor(long k)  // Devuelve el valor editado de una celda

 

 long IdeIJ(long ij, long N) // Recupera el valor I de un índice IJ = J + (I-1) * N

 

 long JdeIJ(long ij, long N) // Recupera el valor J de un índice IJ = J + (I-1) * N

 

 long Rand(long N)           // Genera un nº aleatorio 1..N

 

 long RandCuadrado(long N)   // Genera un nº aleatorio 1..N de tipo n*n

 

 long RandImpar(long N)      // Genera un nº aleatorio 1..N IMPAR

 

                                                                                                                                                 _______

 

 

B.II.3.4 El programa de presentación en VisualBasic “Magic”

 

Como se anticipó, al disponer de la clase .Net CMagic, se pueden desarrollar interfaces en cualquier lenguaje .Net, particularmente veremos ahora la implementación principal del programa “Magic” desarrollado en VisualBasic.Net (cuya imagen se presentó al comienzo del capítulo):



 

// Magic. Código principal, expurgado de rutinas del sistema

 

Public Class Form1

 

 Inherits System.Windows.Forms.Form



 

 ' Variables globales

 

 Dim lN As Integer         ' Tamaño cuadrado

 Dim lNmuestras As Integer ' Contador de muestras de cuadros generadas

 Dim lNpruebas As Integer  ' Contador de pruebas de valores

 Dim lNaciertos As Integer ' De ellas, las que fueron aciertos

 Dim dPaciertos As Double  ' En %

 Dim lSudoku As Short      ' 0/1 Marca de sudoku activa

 Dim II As Long            ' Paso de coordenada i de celda seleccionada

 Dim JJ As Long            ' Paso de coordenada j de celda seleccionada

 Dim IIa As Long           ' II anterior

 Dim JJa As Long           ' JJ anterior

 

 

 Dim Cmagic As New Cmagic.Cmagic ' Inclusión de la clase CMagic

 

 

 . . .

 

 

' Carga del formulario

 

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

 

 Dim lNID As Integer ' Identificador Cmagic. 0=Error

 

 

 ' Inicializa parámetros

 

 lN = 9      ' Tamaño del cuadrado

 lSudoku = 1 ' Por defecto activa la marca de sudoku

 

 

 ' Activa el reloj y lo detiene hasta que se solicite su reanudación por pantalla

 

 Timer1.Enabled = True

 Timer1.Stop()

 

 

 ' Generación inicial

 

 Generar_Click(sender, e)

 

End Sub

 

 

 

' Cierre del programa (manual)

 

Private Sub Salir_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Salir.Click

 

 Dim lError As Short

 

 lError = Cmagic.Close()

 

 End

 

End Sub

 

 

 

' Cierre del programa (sistema)

 

Private Sub Form1_Closing . . . (Misma codificación [Sin el End])

 

 

 

' Generación de un nuevo cuadro

 

Private Sub Generar_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Generar.Click

 

 

 ' Actualiza el contador de muestras

 

 lNmuestras += 1

 

 

 ' Inicializa parametros de selección

 

 Magic_Enter(sender, e)

 

 

 ' Pasa parámetros a pantalla

 

 N.Text = lN.ToString

 Nmuestras.Text = lNmuestras.ToString

 

 

 ' Genera un nuevo cuadro

 

 Cmagic.Genera(lSudoku, lN)

 

 

 ' Presenta resultados

 

 Presentar_Click(sender, e)

 

End Sub

 

 

 

' Presentación (Rutina principal)

 

Private Sub Presentar_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Presentar.Click

 

 Dim dtmagic As New DataTable ' Tabla soporte grid

 Dim drmagic As DataRow       ' Soporte filas grid

 

 Dim dtNumeroFilas As New DataTable ' Tabla soporte nºfilas

 Dim drNumeroFilas As DataRow       ' Filas de nºfilas

 

 Dim i As Integer            ' Contador de for

 Dim j As Integer            ' Contador de for

 Dim lValor As Integer       ' Valor de celdilla

 Dim bEditado As String      ' Valor editado

 Dim bEditado2 As String     ' Valor editado adicional

 Dim lEstado As Short        ' 0/1 ocupada

 Dim lResul As Integer       ' Control de resultados Cmagic

 Dim lSumaFila As Integer    ' Wk.Suma fila

 Dim lSumaColumna As Integer ' Wk.Suma columna

 

 Dim lActivos As Integer ' NºActivos

 Dim lOcultos As Integer ' NºOcultos

 

 

 

 ' Información estadística. Activos y ocultos

 

 lActivos = Cmagic.RecuperaNumActivas()

 lOcultos = Cmagic.RecuperaNumDesactivas()

 

 Activos.Text = lActivos.ToString

 Desactivos.Text = lOcultos.ToString

 

 

 

 ' Carga del grid principal

 

 

 ' Crea columnas de soporte 1 + N + 1

 

 bEditado = Cmagic.EditaValor(0)

 dtmagic.Columns.Add(New DataColumn(bEditado, GetType(String)))

 

 For j = 1 To lN

 

  bEditado = Cmagic.EditaValor(j)

  dtmagic.Columns.Add(New DataColumn(bEditado, GetType(String)))

 

 Next j

 

 dtmagic.Columns.Add(New DataColumn(" S", GetType(String)))

 

 

 

 ' Crea filas de soporte N (+ 1)

 

 For i = 1 To lN

 

  drmagic = dtmagic.NewRow()

 

 

  ' Cabecera en [1] + N + 1

 

  bEditado = Cmagic.EditaValor(i)

  bEditado2 = Cmagic.EditaValor(0)

  drmagic(bEditado2) = bEditado

 

 

  ' Importes en 1 + [ N ] + 1

 

  For j = 1 To lN

 

   lValor = Cmagic.RecuperaValor(lN - i + 1, j)

   lEstado = Cmagic.RecuperaEstado(lN - i + 1, j)

 

   If lEstado = 1 Then

 

    bEditado = Cmagic.EditaValor(lValor)

    bEditado2 = Cmagic.EditaValor(j)

    drmagic(bEditado2) = bEditado

 

   Else

   

    bEditado2 = Cmagic.EditaValor(j)

    drmagic(bEditado2) = " "

 

   End If

 

  Next j

 

 

  ' Añade SumaFila en 1 + N + [1]

 

  lSumaFila = Cmagic.SumaFila(lN - i + 1)

bEditado = Cmagic.EditaValor(lSumaFila)

drmagic(" S") = bEditado

 

 

' Añade fila a la tabla

 

dtmagic.Rows.Add(drmagic)

 

Next i

 

 

 

' Añade SumaColumnas

 

drmagic = dtmagic.NewRow()

 

bEditado2 = Cmagic.EditaValor(0)

drmagic(bEditado2) = " "

 

 

For j = 1 To lN

 

lSumaColumna = Cmagic.SumaColumna(j)

bEditado = Cmagic.EditaValor(lSumaColumna)

bEditado2 = Cmagic.EditaValor(j)

drmagic(bEditado2) = bEditado

 

Next j

 

 

 

' En la última columna se pone el importe de la suma completa

 

lSumaColumna = lN * (lN + 1) / 2

bEditado = Cmagic.EditaValor(lSumaColumna)

drmagic(" S") = bEditado

 

 

' Añade fila de sumas a la tabla

 

dtmagic.Rows.Add(drmagic)

 

 

' Aplica al grid

 

With Magic

.Visible = True

.DataSource = New DataView(dtmagic)

End With

 

 

 

 

' Carga del grid nºfilas

 

 

' Crea columna de soporte [1] en el esquema [1] + N + 1

 

bEditado2 = Cmagic.EditaValor(0)

dtNumeroFilas.Columns.Add(New DataColumn(bEditado2, GetType(String)))

 

 

 

' Crea filas de soporte

 

For i = 1 To lN

 

drNumeroFilas = dtNumeroFilas.NewRow()

 

bEditado = Cmagic.EditaValor(i)

drNumeroFilas(bEditado2) = bEditado

 

 

' Añade fila a la tabla

 

dtNumeroFilas.Rows.Add(drNumeroFilas)

 

Next i

 

 

 

' Añade línea de cabecera de la línea de sumas

 

drNumeroFilas = dtNumeroFilas.NewRow()

drNumeroFilas(bEditado2) = " S"

dtNumeroFilas.Rows.Add(drNumeroFilas)

 

 

' Aplica al grid

 

With NumeroFilas

.Visible = True

.DataSource = New DataView(dtNumeroFilas)

End With

 

End Sub

 

 

 

' Activa la visualización de una celda

 

Private Sub VerCelda_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles VerCelda.Click

 

Dim lActiva As Short

Dim lResul As Long

 

 

' Evalua el estado de la celda solicitada

 

lActiva = Cmagic.RecuperaEstado(lN - II, JJ)

 

 

' Activa y visualiza la celda solicitada si procede

 

If lActiva = 0 Then

 

lResul = Cmagic.Activa(lN - II, JJ)

 

Presentar_Click(sender, e)

 

End If

 

End Sub

 

 

 

' Código asociado al botón de prueba de un valor por el usuario

 

Private Sub Probar_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Probar.Click

 

Dim lValorPrueba As Integer

Dim lValorChain As Integer

Dim lEstado As Integer

Dim lResul As Integer

 

 

' Filtro de cursor situado en una celda

 

If JJ <= 0 Then

ResultadoPrueba.Text = "Seleccione y pruebe!"

Exit Sub

End If

 

 

' Filtra celda ya visualizable previamente

 

lEstado = Cmagic.RecuperaEstado(lN - II, JJ)

 

If lEstado = 1 Then

 

ResultadoPrueba.Text = "Ya se ve!"

 

Exit Sub

 

End If

 

 

' Aumenta contador de pruebas

 

lNpruebas += 1

Npruebas.Text = lNpruebas.ToString

 

 

' Toma valor guardado y propuesto y los compara

 

lValorChain = Cmagic.RecuperaValor(lN - II, JJ)

 

lValorPrueba = ValorPrueba.Text

 

ResultadoPrueba.Text = "Pruebe!"

If lValorPrueba = lValorChain Then

ResultadoPrueba.Text = "OK"

lResul = Cmagic.Activa(lN - II, JJ)

lNaciertos += 1

End If

 

dPaciertos = (100 * lNaciertos) / lNpruebas

Naciertos.Text = lNaciertos.ToString

Paciertos.Text = dPaciertos.ToString

 

 

' Representación

 

Presentar_Click(sender, e)

 

End Sub

 

 

 

' Selección de una celda del grid

 

Private Sub Magic_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Magic.MouseDown

 

Dim myGrid As DataGrid = CType(sender, DataGrid)

 

Dim hti As System.Windows.Forms.DataGrid.HitTestInfo

 

 

hti = myGrid.HitTest(e.X, e.Y)

 

Select Case hti.Type

Case System.Windows.Forms.DataGrid.HitTestType.None

' Console.WriteLine("You clicked the background.")

 

 

Case System.Windows.Forms.DataGrid.HitTestType.Cell

' Console.WriteLine("You clicked cell at row " & hti.Row & ",

' col " & hti.Column)

 

 

' Pasa las coordenadas de la celda seleccionada

 

II = hti.Row

JJ = hti.Column

 

iCeldaSeleccionada.Text = (II + 1).ToString

jCeldaSeleccionada.Text = JJ.ToString

 

 

' Representación

 

Presentar_Click(sender, e)

 

 

End Select

 

 

 

' Cambio de estado de una celda del grid

 

Private Sub Magic_DoubleClick(ByVal sender As Object, ByVal e As System.EventArgs) Handles Magic.DoubleClick

 

Dim lActiva As Integer

Dim lResul As Long

 

 

' Filtro selección de celda

 

If JJ = 0 Then

Exit Sub

End If

 

 

' Si repite la celda, es cambiar de estado

 

If II = IIa And JJ = JJa Then

 

 

' Evalua el estado de la celda solicitada

 

lActiva = Cmagic.RecuperaEstado(lN - II, JJ)

 

 

' Cambio de estado

 

If lActiva = 0 Then

 

lResul = Cmagic.Activa(lN - II, JJ)

 

Else

 

lResul = Cmagic.Desactiva(lN - II, JJ)

 

End If

 

 

' Visualización

 

Presentar_Click(sender, e)

 

 

Exit Sub

 

End If

 

 

' Actualiza "valor anterior"

 

IIa = II

JJa = JJ

 

End Sub

 

 

 

' Rutina de relleno automático por temporizador

 

Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick

 

Dim i As Integer ' Indice i de celda

Dim j As Integer ' Indice j de celda

Dim ii As Integer ' Indice ii = i*lN

Dim ij As Integer ' Indice ij = j + (i-1)*lN

Dim lError As Integer ' Control de error

Dim lEstadoCelda As Integer ' Estado 0/1 de celda activa

Dim lResul As Integer ' Control de resultados

Dim lValorCelda As Integer ' Valor de celda

Dim lNumDesactivas As Integer ' NºCeldas desactivas

Dim lNumRandom As Integer ' Nº Aleatorio para activar

 

 

' Recupera el nº de celdas desactivas

 

lNumDesactivas = Cmagic.RecuperaNumDesactivas()

 

 

' Regeneración por agotamiento

 

If lNumDesactivas = 0 Then

 

Generar_Click(sender, e)

 

Exit Sub

 

End If

 

 

' Obtiene random a generar

 

lNumRandom = lNumDesactivas

If lNumDesactivas > 1 Then

 

lNumRandom = Cmagic.Rand(lNumDesactivas)

 

End If

 

 

' Recupera parámetros de la celda a activar

 

ij = Cmagic.ReadDesactiva(lNumRandom)

 

i = Cmagic.IdeIJ(ij, lN)

j = Cmagic.JdeIJ(ij, lN)

 

lValorCelda = Cmagic.RecuperaValor(i, j)

lEstadoCelda = Cmagic.RecuperaEstado(i, j)

 

 

' Activa la celda solicitada

 

lResul = Cmagic.Activa(i, j)

 

 

' Presentación

 

Presentar_Click(sender, e)

 

End Sub

 

 

End Class

 

                                                                                                                                                 _______

 

B.II.3.5 Ampliación de componentes

 

Veamos el proceso a seguir en caso de desear ampliar los componentes. Por ejemplo, supongamos que se desea agregar una fila y una columna que indique el número de celdas activas del sudoku en curso, de forma que el interfaz presentara el siguiente aspecto al comienzo de esta muestra:

 

 

y este aspecto

 

 

al terminar su presentación.

 
 

 

Entonces, hay que seguir los siguientes pasos:

 

 

Paso 0) Reservar el desarrollo original.

 

 

        Basta copiar la carpeta de desarrollo “Magic” en una ubicación de reserva

 

 


 

Paso 1) Ampliar el modelo C++ subyacente

 

 

        Desarrollando las nuevas funciones SRMAGIC_NumActivasFila y SRMAGIC_NumActivasColumna

 

 

[ Para ello se añade el código en srmagic.cpp y los prototipos de importación en

srmagic.h y de exportación srmagicx.h, como se se muestra a continuación:

 

 

// Prototipos

 

__declspec(dllexport) long SRmagic_NumActivasFila(long i)

__declspec(dllimport) long SRmagic_NumActivasFila(long i)

 

__declspec(dllexport) long SRmagic_NumActivasColumna(long j)

__declspec(dllimport) long SRmagic_NumActivasColumna(long j)

 

 

 

// Código de SRmagic_NumActivasFila (El de Srmagic_NumActivasColumna es similar)

 

//-----------------------------------------------------------------------------

// SRmagic_NumActivasFila: Devuelve el nº de celdas activas en una fila

//

//

// Precondición:

//

// Fichero PMAGIC soporte de la aplicación cargado

//

//

// Parámetros:

// i: Identificación de la fila a evaluar

//

// Retorno: Número de celdas activas en la fila solicitada

// Si es -1 se desprende que no existía

// precondición que tratar o que se ha solicitado una fila imposible

//

//-----------------------------------------------------------------------------

__declspec(dllexport) long SRmagic_NumActivasFila(long i)

{

 short int er = 0; // Control de errores

 long j = 0; // Recorrido en j de i

 long lresul = 0; // Control de resultados

 long lNumActivasFila = 0; // Valor de retorno

 

 

 // Recupera información de estado

 

 er = SRRCW_INF("PMAGIC", &iDimC, &lDimD, &lNITEM, &lBAJAS, &lNIDD);

 if (er) return -1;

 

 lNITEM -= lBAJAS;

 if (lNITEM <= 0) return -1;

 

 long n = (long) sqrt((double)lNITEM); // Nº de filas/columnas

 

 

 // Filtros

 

 if (i<=0) return -1;

 if (i>n) return -1;

 

 

 // Bucle de evaluación de celdas activas

 

 for (j=1;j<=n;++j)

 {

  lresul = SRmagic_VerActiva(i, j);

  if (lresul) ++lNumActivasFila;

 }

 

 

 // Devuelve el nº de celdas activas en la fila solicitada

 

 return lNumActivasFila;

}

 

]

 

A continuación el código se compila, depurándose en su caso. Luego se recompila el interfaz original en C++ Pmagic al que en esta ocasión no se le van a aplicar los cambios simplemente para mantenerle en línea.

 


 

 

Paso 2) Ampliar el modelo COM

 

Lo más sencillo es editar directamente en COMmagic los fuentes SRmagic.h y SRmagic.cpp y añadir los nuevos STDMETHOD:

 


 

En SRmagic.h

 

[id(16), helpstring("method NumActivasFila")] HRESULT NumActivasFila([in] LONG i, [out] LONG* NumeroActivas);

[id(17), helpstring("method NumActivasColumna")] HRESULT NumActivasColumna([in] LONG j, [out] LONG* NumeroActivas);

 

+

 

STDMETHOD(NumActivasFila)(LONG i, LONG* NumeroActivas);

STDMETHOD(NumActivasColumna)(LONG j, LONG* NumeroActivas);

 

 

 

Y en Srmagic.cpp

 

 

STDMETHODIMP CSRmagic::NumActivasFila(LONG i, LONG* NumeroActivas)

{

 

 *NumeroActivas = SRmagic_NumActivasFila(i);

 

 return S_OK;

}

 

STDMETHODIMP CSRmagic::NumActivasColumna(LONG j, LONG* NumeroActivas)

{

 

 *NumeroActivas = SRmagic_NumActivasColumna(j);

 

 return S_OK;

}

 


 

 

Paso 3) Ampliar el modelo net

 

Añadiendo los métodos interfaz en Cmagic.h

 

 

// Recupera el nºde celdas con visualización activa en una fila

 

long RecuperaNumActivasFila(long i)

{

 return SRmagic_NumActivasFila(i);

}

 

 

// Recupera el nºde celdas con visualización activa en una columna

 

long RecuperaNumActivasColumna(long j)

{

 return SRmagic_NumActivasColumna(j);

}

 

 


 

Paso 4) Aplicar a la pantalla interfaz “Magic”

 

Agregando una nueva fila y columna donde explotar los métodos incorporados en Cmagic. El código resultante en Form1.vb, donde se resaltan las sentencias añadidas, es

 

 

Private Sub Presentar_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Presentar.Click

 

Dim dtmagic As New DataTable ' Tabla soporte grid

Dim drmagic As DataRow       ' Soporte filas grid

 

Dim dtNumeroFilas As New DataTable ' Tabla soporte nºfilas

Dim drNumeroFilas As DataRow       ' Filas de nºfilas

 

Dim i As Integer            ' Contador de for

Dim j As Integer            ' Contador de for

Dim lValor As Integer       ' Valor de celdilla

Dim bEditado As String      ' Valor editado

Dim bEditado2 As String     ' Valor editado adicional

Dim lEstado As Short        ' 0/1 ocupada

Dim lResul As Integer       ' Control de resultados Cmagic

Dim lSumaFila As Integer    ' Wk.Suma fila

Dim lSumaColumna As Integer ' Wk.Suma columna

 

Dim lNumActivosFila As Integer    ' Wk.NumActivos fila

Dim lNumActivosColumna As Integer ' Wk.NumActivos columna

 

Dim lActivos As Integer ' NºActivos

Dim lOcultos As Integer ' NºOcultos

 

 

' Información estadística. Activos y ocultos

 

lActivos = Cmagic.RecuperaNumActivas()

lOcultos = Cmagic.RecuperaNumDesactivas()

 

Activos.Text = lActivos.ToString

Desactivos.Text = lOcultos.ToString

 

 

 

' Carga del grid principal

 

 

' Crea columnas de soporte 1 + N + 1 + 1

 

bEditado = Cmagic.EditaValor(0)

dtmagic.Columns.Add(New DataColumn(bEditado, GetType(String)))

 

For j = 1 To lN

 

bEditado = Cmagic.EditaValor(j)

dtmagic.Columns.Add(New DataColumn(bEditado, GetType(String)))

 

Next j

 

dtmagic.Columns.Add(New DataColumn(" N", GetType(String)))

dtmagic.Columns.Add(New DataColumn(" S", GetType(String)))

 

 

 

 

' Crea filas de soporte [1] + N + 1 + 1

 

For i = 1 To lN

 

drmagic = dtmagic.NewRow()

 

 

' Cabecera en [1] + N + 1 + 1

 

bEditado = Cmagic.EditaValor(i)

bEditado2 = Cmagic.EditaValor(0)

drmagic(bEditado2) = bEditado

 

 

' Importes en 1 + [ N ] + 1 + 1

 

For j = 1 To lN

 

lValor = Cmagic.RecuperaValor(lN - i + 1, j)

lEstado = Cmagic.RecuperaEstado(lN - i + 1, j)

 

If lEstado = 1 Then

 

 bEditado = Cmagic.EditaValor(lValor)

 bEditado2 = Cmagic.EditaValor(j)

 drmagic(bEditado2) = bEditado

 

Else

 

 bEditado2 = Cmagic.EditaValor(j)

 drmagic(bEditado2) = " "

 

End If

 

Next j

 

 

 

' Añade NumActivosFila en 1 + N + [1] + 1

 

lNumActivosFila = Cmagic.RecuperaNumActivasFila(lN - i + 1)

bEditado = Cmagic.EditaValor(lNumActivosFila)

drmagic(" N") = bEditado

 

 

 

' Añade SumaFila en 1 + N + 1 + [1]

 

lSumaFila = Cmagic.SumaFila(lN - i + 1)

bEditado = Cmagic.EditaValor(lSumaFila)

drmagic(" S") = bEditado

 

 

 

' Añade fila completa a la tabla

 

dtmagic.Rows.Add(drmagic)

 

Next i

 

 

 

 

 

' Añade fila de nºde activos por columna

 

drmagic = dtmagic.NewRow()

 

bEditado2 = Cmagic.EditaValor(0)

drmagic(bEditado2) = " "

 

 

For j = 1 To lN

 

lNumActivosColumna = Cmagic.RecuperaNumActivasColumna(j)

bEditado = Cmagic.EditaValor(lNumActivosColumna)

bEditado2 = Cmagic.EditaValor(j)

drmagic(bEditado2) = bEditado

 

Next j

 

 

' En la penúltima columna se pone N

 

bEditado = Cmagic.EditaValor(lN)

drmagic(" N") = bEditado

 

 

' En la última columna se pone ' '

 

drmagic(" S") = " "

 

 

' Añade fila de nºde activos por columna a la tabla

 

dtmagic.Rows.Add(drmagic)

 

 

 

 

' Añade SumaColumnas

 

drmagic = dtmagic.NewRow()

 

bEditado2 = Cmagic.EditaValor(0)

drmagic(bEditado2) = " "

 

 

For j = 1 To lN

 

lSumaColumna = Cmagic.SumaColumna(j)

bEditado = Cmagic.EditaValor(lSumaColumna)

bEditado2 = Cmagic.EditaValor(j)

drmagic(bEditado2) = bEditado

 

Next j

 

 

 

' En la penúltima columna se pone ' '

 

drmagic(" N") = " "

 

 

' En la última columna se pone el importe de la suma completa

 

lSumaColumna = lN * (lN + 1) / 2

bEditado = Cmagic.EditaValor(lSumaColumna)

drmagic(" S") = bEditado

 

 

' Añade fila de sumas a la tabla

 

dtmagic.Rows.Add(drmagic)

 

 

 

' Aplica al grid

 

With Magic

.Visible = True

.DataSource = New DataView(dtmagic)

End With

 

 

 

 

' Carga del grid nºfilas

 

 

' Crea columna de soporte [1] en el esquema [1] + N + 1

 

bEditado2 = Cmagic.EditaValor(0)

dtNumeroFilas.Columns.Add(New DataColumn(bEditado2, GetType(String)))

 

 

' Crea filas de soporte

 

For i = 1 To lN

 

drNumeroFilas = dtNumeroFilas.NewRow()

 

bEditado = Cmagic.EditaValor(i)

drNumeroFilas(bEditado2) = bEditado

 

 

' Añade fila a la tabla

 

dtNumeroFilas.Rows.Add(drNumeroFilas)

 

Next i

 

 

 

' Añade línea de cabecera de la línea de nºitems por columna

 

drNumeroFilas = dtNumeroFilas.NewRow()

drNumeroFilas(bEditado2) = " N"

dtNumeroFilas.Rows.Add(drNumeroFilas)

 

 

 

' Añade línea de cabecera de la línea de sumas

 

drNumeroFilas = dtNumeroFilas.NewRow()

drNumeroFilas(bEditado2) = " S"

dtNumeroFilas.Rows.Add(drNumeroFilas)

 

 

' Aplica al grid

 

With NumeroFilas

.Visible = True

.DataSource = New DataView(dtNumeroFilas)

End With

 

End Sub

                                                                                                                                                 _______



La codificación completa extractada aquí se adjunta en el apéndice

"C5 Relación de programas de muestra desarrollados en el libro"

 

                                                                                                                                                   _______