Diseño de las pantallas

Anuncio
Pantalla de inicio de Sesión
Creamos un proyecto de Windows con el nombre proTienda_MATRICULA.
Después creamos una base de datos en Access, la cual deberá llamarse
dbTienda_MATRICULA. Esta base de datos debemos ponerla en el
directorio Debug de nuestro proyecto. El directorio Debug se encuentra
dentro del Directorio Bin, el directorio Bin se encuentra en el directorio en
donde creamos nuestro proyecto.
En este ejemplo se utilizan imágenes y/o Iconos para darle una mejor
presentación al proyecto. No es obligatorio utilizarlos, pero en caso de estar
interesado en conseguirlos, puedes intentar descargarlos desde la página
de “La Web del Programador”.
Antes de realizar cualquier cosa, asegurémonos de organizar nuestro
proyecto de la siguiente manera:
Organice su proyecto tal y cual se muestra en la figura, de esta manera
evitaremos cometer errores en el momento de programar.
Contenido:
Diseño de la base de datos
Diseño de las pantallas
Programación
Diseño de la base de datos:
Tenemos 10 tablas.
Para la realización de este ejercicio solo utilizaremos la tabla USERS.
Como esta es una clase de Lenguaje de programación, omitiremos al
máximo las explicaciones relativas a Desarrollo de Base de datos. Solo se
hace la aclaración que para los motivos educativos del presente curso, la
base de datos aquí mostrada tiene el diseño óptimo.
Antes de continuar, agregamos una referencia a “System.configuration”:
Diseño de las pantallas:
Agregamos una clase y dos formularios a nuestro proyecto, como se
muestra enseguida:
El formulario Login (frmLogin), debe quedar como se muestra:
Le agregamos dos Labels, Dos TextBox y dos Button. Según la siguiente
tabla:
OBJETO
PROPEDAD
Label
Name
Label
Name
TextBox
Name
TextBox
Name
Button
Name
Button
Name
Form
Name
VALOR
lblUSER_NAME
lblPASSWORD
txtUSER_NAME
txtPASSWORD
btnOK
btnCANCEL
frmLogin
Programación:
Antes quiero hacer la aclaración de que al formulario mdiMain no se le hará
ningún diseño por el momento.
Comenzaremos por escribir el código para frmLogin.
Estructura del código:
//Directivas Using
using System;
using System.ComponentModel;
using System.Data;
using System.Data.OleDb;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
/* Comentarios:
* Programador: Lic. Juan Gabriel Castillo T.
* Carrera:
Licenciado en Computación Administrativa
* Matricula:
9921868
* Fecha:
14 de Marzo del 2025
* Materia:
Lenguaje Visual
*/
namespace proTienda_9921868.Forms
{
public partial class frmLogin : Form
{
public frmLogin()
{
//Contructor por defecto
InitializeComponent();
}
//Declaraciones
private void frmLogin_Load(object sender, EventArgs e)
{
//Form_Load
}
//Funciones y procedimientos
}
}
La sección de las directivas using, agregaremos la siguiente instrucción:
using System.Data;
using System.Data.OleDb;
En la sección Declaraciones, agregamos las siguientes variables (Algunas
correspondientes a los campos de la Tabla USERS):
//Declaraciones
int Intentos = 0;
public static bool _Logged = false;
public static string _USER_NAME = "";
public static string _PATERNO = "";
public static string _MATERNO = "";
public static string _NOMBRE = "";
public static bool _VENTAS = false;
public static bool _ADMINISTRAR = false;
public static bool _REPORTES = false;
public static bool _CATALOGOS = false;
public static bool _CONSULTAS = false;
public static bool _DESHACER_VENTA = false;
A continuación, en la sección Funciones y Procedimientos agregamos el
siguiente código:
private bool fnLogin(string prmUSER_NAME, string prmPASSWORD)
{
bool Retorno = false;
try
{
string varSQL = "SELECT USERS.USER_NAME, USERS.PATERNO, " +
" USERS.MATERNO, USERS.NOMBRE, USERS.VENTAS, " +
" USERS.ADMINISTRAR,USERS.REPORTES, " +
" USERS.CATALOGOS,
USERS.CONSULTAS, " +
" USERS.DESHACER_VENTA " +
" FROM USERS " +
" WHERE USERS.USER_NAME='" + prmUSER_NAME + "' " +
" AND USERS.USER_PASSWORD ='" + prmPASSWORD + "'";
OleDbConnection cnnLogin =
new OleDbConnection(Class.clsMain.CnnStr);
cnnLogin.Open();
OleDbCommand cmdLogin = new OleDbCommand(varSQL, cnnLogin);
OleDbDataReader drLogin = cmdLogin.ExecuteReader();
while (drLogin.Read())
{
Retorno = true;
_USER_NAME = drLogin["USER_NAME"].ToString();
_PATERNO = drLogin["PATERNO"].ToString();
_MATERNO = drLogin["MATERNO"].ToString();
_NOMBRE = drLogin["NOMBRE"].ToString();
_VENTAS = Convert.ToBoolean(drLogin["VENTAS"]);
_ADMINISTRAR = Convert.ToBoolean(drLogin["ADMINISTRAR"]);
_REPORTES = Convert.ToBoolean(drLogin["REPORTES"]);
_CATALOGOS = Convert.ToBoolean(drLogin["CATALOGOS"]);
_CONSULTAS = Convert.ToBoolean(drLogin["CONSULTAS"]);
_DESHACER_VENTA =
Convert.ToBoolean(drLogin["DESHACER_VENTA"]);
}
drLogin.Close();
cnnLogin.Close();
cmdLogin.Dispose();
return (Retorno);
}
catch (Exception ex) {
MessageBox.Show("fnLogin\n" + ex.Message,
"Información del Sistema");
return (Retorno);
}
}
Hacemos doble click en el botón btnOK y agregamos el siguiente código:
_Logged = fnLogin(txtUSER_NAME.Text, txtPASSWORD.Text);
if (Intentos >= 3)
{
_Logged = false;
MessageBox.Show("Demasiados intentos",
"Información del sistema");
this.Close();
}
if (_Logged)
this.Close();
Al botón btnCANCEL, le agregamos lo siguiente:
this.Close();
Ahora agregamos el código de clsMain, que debe quedar como se muestra:
using System;
using System.Configuration;
using System.Windows.Forms;
using System.IO;
/* Comentarios:
* Programador: Lic. Juan Gabriel Castillo T.
* Carrera:
LCA
* Matricula:
9921868
* Fecha:
14 de Marzo del 2030
* Materia:
Lenguaje Visual
*/
namespace proTienda_9921868.Class{
class clsMain{
[STAThread]
static void Main()
{
Forms.frmLogin my_frmLogin = new Forms.frmLogin();
Application.Run(my_frmLogin);
if (Forms.frmLogin._Logged == true){
Forms.mdiMain my_mdiMain = new Forms.mdiMain();
Application.Run(my_mdiMain);
}
else{
Application.Exit();
}
}
public static string CnnStr {
get {
string Retorno = "";
string varFileName = "";
try{
varFileName =
ConfigurationManager.AppSettings["DataFile1"];
if (File.Exists(varFileName)){
Retorno =
"Provider=Microsoft.Jet.OLEDB.4.0;" +
"Data Source=" +
varFileName + ";" +
"Persist Security Info=False";
}
else{
MessageBox.Show("¡El archivo de Base"+
" de datos no existe!",
"Información del sistema",
MessageBoxButtons.OK, MessageBoxIcon.Error);
}
return (Retorno);
}
catch (Exception ex) {
MessageBox.Show(ex.Message,"Información del Sistema",
MessageBoxButtons.OK, MessageBoxIcon.Error);
return (Retorno);
}
}
}
}
}
Explicaciones sobre el código:
Generalizando.- Cuando un usuario intente ingresar a nuestra aplicación le
aparecerá una pantalla de Login para que intruduzca un nombre de usuario
y una contraseña. Solo tendrá 3 oportunidades para ingresar antes de que
se cierre la aplicación. Si el usuario ingresa un nombre de usuario y
contraseña correctos, entonces entrará al sistema y verá la pantalla
principal de la aplicación.
Detalladamente.- Lo que hace la aplicación es verificar que el usuario exista
en la tabla USERS, si existe significa que puede iniciar sesión en el sistema,
y se cargan sus permisos a las variables. Tendremos un contador para
verificar la cantidad de veces que el usuario inetenta ingresar, en el
momento que exceda la cantidad de intentos permitidos la aplicación se
cerrará.
Podemos observar que utilizamos las intrucciones try-catch-finally, estas
nos ayudarán para que en el caso de que ocurra un error en nuestra
aplicación mientras es ejecutada, no tengamos mayores problemas.
Utilizamos la propiedad State de la conexión, esta nos ayuda a saber si la
conexión está abierta o cerrara. La utilizamos para evitar el error de intentar
abrir una conexión abierta o cerrar una conexión cerrada lo cual es ilógico.
La función fnLogin recibe dos parametros (Usuario y Contraseña) y retorna
un valor booleano (Falso-Verdadero). La utilizamos para organizar nuestro
código de tal manera que al ejecutarse la función podamos saber:
True: Puede iniciar sesión y se cargan los datos del usuario a las variables
False: No puede iniciar sesión por error/desconocer al escribir su nombre de
usuario y contraseña y se le cuenta un intento de acceso.
Las variables public static, son variables globales y pueden ser leidas desde
cualquier parte de la aplicación con escribir el nombre del objeto, un punto y
el nombre de la variable. Por ejemplo, si queremos saber apellido paterno el
usuario haríamos lo siguiente:
string varPATERNO = Forms.frmLogin._PATERNO;
Utilidad para configurar la conexión a la base de datos
Continuamos con el proyecto proTienda_MATRICULA.
Contenido:
• Diseño de las pantallas
• Programación
Diseño de las pantallas:
La aplicación contaba ya con una clase y dos formularios, agregaremos un
tercer formulario (frmAppConfig) para que nuestro proyecto se organice así:
Nota: aquí se muestran otros formularios, los cuales debemos pasar por alto
por el momento. Estos se realizarán posteriormente.
El nuevo formulario (frmAppConfig), debe quedar como se muestra:
Le agregamos cinco Label, cinco TextBox y tres Button. Según la siguiente
tabla:
Programación:
Antes quiero hacer la aclaración de que al formulario mdiMain no se le hará
ningún diseño por el momento.
Comenzaremos por escribir el código para frmAppConfig.
Estructura del código:
//Directivas Using
using System;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Configuration;
using System.IO;
/* Comentarios:
* Programador: Lic. Juan Gabriel Castillo T.
* Carrera:
Licenciado en Computación Administrativa
* Matricula:
9921868
* Fecha:
15 de Marzo del 2025
* Materia:
Lenguaje Visual
*/
namespace proTienda_9921868.Forms
{
public partial class frmAppConfig : Form
{
public frmAppConfig()
{
//Contructor por defecto
InitializeComponent();
}
//Declaraciones
private void frmAppConfig_Load(object sender, EventArgs e)
{
//Form_Load
}
//Funciones y procedimientos
}
}
En la sección Declaraciones, agregamos lo siguiente:
Hacemos doble clic al formulario y ponemos el siguiente código en el
Form_Load:
//Form_Load
txtFileName.Text =
ConfigurationManager.AppSettings["DataFile1"];
txtNombreNegocio.Text =
ConfigurationManager.AppSettings["NombreNegocio"];
txtRFC.Text =
ConfigurationManager.AppSettings["RFC"];
txtTelefono.Text =
ConfigurationManager.AppSettings["Telefono"];
txtDireccionFiscal.Text =
ConfigurationManager.AppSettings["DireccionFiscal"];
Hacemos doble click en el botón btnOK y agregamos el siguiente código:
if (File.Exists(txtFileName.Text))
{
System.Configuration.Configuration config =
ConfigurationManager.
OpenExeConfiguration(ConfigurationUserLevel.None);
//Borramos la configuración actual
config.AppSettings.Settings.Remove("DataFile1");
config.AppSettings.Settings.Remove("NombreNegocio");
config.AppSettings.Settings.Remove("RFC");
config.AppSettings.Settings.Remove("Telefono");
config.AppSettings.Settings.Remove("DireccionFiscal");
config.Save(ConfigurationSaveMode.Modified);
//Force a reload of the changed section.
ConfigurationManager.RefreshSection("appSettings");
//Grabamos la configuración nueva
config.AppSettings.Settings.Add("DataFile1",
txtFileName.Text);
config.AppSettings.Settings.Add("NombreNegocio",
txtNombreNegocio.Text);
config.AppSettings.Settings.Add("RFC", txtRFC.Text);
config.AppSettings.Settings.Add("Telefono",
txtTelefono.Text);
config.AppSettings.Settings.Add("DireccionFiscal",
txtDireccionFiscal.Text);
// Save the configuration file.
config.Save(ConfigurationSaveMode.Modified);
//Force a reload of the changed section.
ConfigurationManager.RefreshSection("appSettings");
this.Close();
}
else {
MessageBox.Show("¡El archivo de Base de datos no existe!",
"Información del sistema",
MessageBoxButtons.OK, MessageBoxIcon.Error);
}
Al botón btnCancel, le agregamos lo siguiente:
this.Close();
Al botón btnSearch, le ponemos el siguiente código:
OpenFileDialog m_OpenFile = new OpenFileDialog();
m_OpenFile.Title =
"Buscar Base de datos de Microsoft Access";
m_OpenFile.Filter =
"Todos los archivos(*.*)|*.*|Base de datos Access (*.mdb)|*.mdb";
m_OpenFile.FilterIndex = 2;
if (m_OpenFile.ShowDialog() == DialogResult.OK)
{
txtFileName.Text = m_OpenFile.FileName.ToString();
}
else
{
btnOK.Enabled = false;
}
Después abrimos el formulario frmLogin y le agregamos una LinkLabel
(lblDataBase), para que el formulario quede como se muestra:
Hacemos soble clic sobre lblDataBase y escribimos el siguiente código:
Forms.frmAppConfig _frmAppConfig = new frmAppConfig();
_frmAppConfig.StartPosition = FormStartPosition.CenterScreen;
_frmAppConfig.ShowDialog();
De esta manera, cuando se haga clic sobre la etiqueta, se abrirá
frmAppConfig.
Ahora editamos el código de clsMain, que debe quedar como se muestra
(he marcado con negrita la porción de código que fue afectado):
using System;
using System.Configuration;
using System.Windows.Forms;
using System.IO;
namespace proTienda_9921868.Class{
class clsMain{
[STAThread]
static void Main()
{
Forms.frmLogin my_frmLogin = new Forms.frmLogin();
Application.Run(my_frmLogin);
if (Forms.frmLogin._Logged == true){
Forms.mdiMain my_mdiMain = new Forms.mdiMain();
Application.Run(my_mdiMain);
}
else{
Application.Exit();
}
}
public static string CnnStr {
get {
string Retorno = "";
string varFileName = "";
try{
varFileName =
ConfigurationManager.AppSettings["DataFile1"];
if (File.Exists(varFileName)){
Retorno =
"Provider=Microsoft.Jet.OLEDB.4.0;" +
"Data Source=" +
varFileName + ";" +
"Persist Security Info=False";
}
else{
MessageBox.Show("¡El archivo de Base"+
" de datos no existe!",
"Información del sistema",
MessageBoxButtons.OK,
MessageBoxIcon.Error);
}
return (Retorno);
}
catch (Exception ex) {
MessageBox.Show(ex.Message,
"Información del Sistema",
MessageBoxButtons.OK,
MessageBoxIcon.Error);
return (Retorno);
}
}
}
}
}
Explicaciones sobre el código:
Generalizando. Nuestra aplicación podrá leer la ruta de la base de datos en
tiempo de ejecición. Esto nos da la gran posibilidad de poner nuestra
aplicación en red. Esto nos ayudará a que la base de datos pueda estar
localizada en cualquier parte de la Computadora o de la Red.
Detalladamente. Tenemos un formulario en el cual podemos, mediante un
archivo XML, editar la ruta en la cual se encuentra la Base de datos.
Utilizamos objetos que nos permiten Explorar los archivos de windows;
parecido a si fueramos a abrir un documento de cualquier aplicación de
Microsoft Office. Utilizamos un Archivo XML el cual es perfectamente legible
a nuestros ojos, editable con cualquier editor de texto y ligero en tamaño.
Modificamos la variable CnnStr y la convertimos en Propiedad, eso nos da
una posiblidad mayor en cuanto a lo que podemos realizar.
La utilización de Propiedades (Properties) en lugar de Campos (Fields) o
variables nos permite una mejor administración de código además de que
nos acerca mas a la programación Orienntada a Objetos.
De hecho, en estos momentos ya hemos realizado este tipo de desarrollo.
Hemos creado la clase frmLogin, la cual nos proporciona varias de las
características de la programación orientada a objetos.
También creamos la clase clsMain
Lo mejor es que antes de programar podamos hacer nuestros diagramas de
clase para tener una visión mas clara de lo que tenemos que realizar. Para
este proyecto ya me he adelantado en el análisis para que no tengamos que
detenernos en esos aspectos. Se recomienda leer bibliografia sobre UML
(Lenguaje Unificado de Modelado) para entender los diagramas.
Pantalla para administrar los usuarios del sistema
Continuamos con el proyecto proTienda_MATRICULA.
Contenido:
• Diseño de las pantallas
• Programación
Recordemos que en el primer ejercicio creamos un formulario para que los
usuarios inicien sesión en la aplicación. En esta ocasión crearemos un
formulario que nos permita administrar a los usuarios que tengan derecho a
los recursos del sistema.
Diseño de las Pantallas:
Agregaremos un formulario al cual nombraremos frmUsers.
A continuación agregaremos un ToolStrip al formulario recién creado,
Etiquetas, Cajas de Texto y casillas de verificación como se muestra a
continuación.
El formulario frmUsers, deberá quedar como se muestra:
Según la información de la siguiente tabla:
Los botones del ToolStrip (barUsers), de izquierda a derecha:
Por un momento dejaremos este formulario para hacer algunas
adecuaciones a mdiMain. Le agregaremos un MenuStrip para que quede
como se muestra a continuación:
Según la información de la siguiente tabla:
Los menús del MenuStrip deberán ser como se muestra en la siguiente
tabla:
Al menú mnuArchivo se le agregarán tres submenús, como se muestra en la
siguiente imagen:
Según la información de la siguiente tabla:
Al menú mnuAdministrar se le agregará un submenú, como se muestra en
la siguiente imagen:
Según la información de la siguiente tabla:
Programación:
Empezamos con mdiMain. Hacemos sobre clic sobre el formulario y
escribimos el siguiente código en el Form_Load:
//Form_Load
this.Text = "Módulo de Control de Ventas, usuario: " +
frmLogin._NOMBRE + " " +
frmLogin._PATERNO + " " +
frmLogin._MATERNO;
mnuVentas.Enabled = frmLogin._VENTAS;
mnuAdministrar.Enabled = frmLogin._ADMINISTRAR;
mnuReportes.Enabled = frmLogin._REPORTES;
mnuConsultas.Enabled = frmLogin._CONSULTAS;
mnuCatalogos.Enabled = frmLogin._CATALOGOS;
El código anterior se encarga de habilitar o deshabilitar los menús, siempre
dependiendo de los permisos que tenga el usuario que inició sesión en el
sistema.
Hacemos doble clic sobre el submenú “Usuarios del sistema”
(mnuUsuarios), accedemos a su código y le ponemos el siguiente:
Forms.frmUsers _frmUsers = new frmUsers();
_frmUsers.MdiParent = this;
_frmUsers.StartPosition = FormStartPosition.Manual;
_frmUsers.Show();
Hacemos doble clic sobre el submenú “Salir del sistema” (mnuSalir) para
ponerle el siguiente código:
this.Close();
Lo más interesante que hemos logrado hasta aquí es la parte de los
permisos. Si recordamos lo que hicimos en frmLogin, en la función fnLogin,
en la parte en donde le damos los valores para los permisos; bueno, pues
estos permisos se ven reflejados en esta pantalla. De esta manera podemos
observar una manera fácil de lograr que los objetos compartan sus valores y
lograr que interactuen entre ellos.
Posteriormente podremos ver mejores muestras de interacción entre los
objetos, por ahora, puedo decir que hemos aprendido a leer los valores
contenidos en las variables public static.
Quizá para muchos es complicado comprender el código aquí expuesto. Mis
disculpas a todos aquellos en quienes no he logrado hacer llegar la idea del
código que se presenta aquí. Ni el mas experto de los programadores nació
con el conocimiento, en algunas ocasiones nos vemos en la necesidad de
practicar con el código de otros para poder salir adelante con el trabajo.
Me he dispuesto a preparar este tutorial para que se den cuenta todos los
conocimientos que se requieren para la realización de un simple punto de
venta.
Ahora seguiremos con frmUsers. El código aquí mostrado es simple aunque
algo extenso. En la sección de las directivas:
using System.Data.OleDb;
using System.Data;
En la sección de declaraciones:
//Las variables van aqui
static OleDbConnection cnnUsers;
static OleDbDataAdapter daUsers;
static OleDbCommandBuilder cbUsers;
DataSet dsUsers = new DataSet("dsUsers");
CurrencyManager cmUsers;
//Aquí el Form_Load
this.Closing +=
new System.ComponentModel.
CancelEventHandler(frmUsers_Closing);
cnnUsers = new OleDbConnection(Class.clsMain.CnnStr);
daUsers = new OleDbDataAdapter();
daUsers.SelectCommand = new OleDbCommand("SELECT *" +
" FROM USERS", cnnUsers);
cbUsers = new OleDbCommandBuilder(daUsers);
if (cnnUsers.State == ConnectionState.Open)
cnnUsers.Close();
cnnUsers.Open();
dsUsers.Clear();
daUsers.Fill(dsUsers, "USERS");
txtUSER_LOGIN.DataBindings.Add("Text", dsUsers,
"USERS.USER_NAME");
txtPASSWORD.DataBindings.Add("Text", dsUsers,
"USERS.USER_PASSWORD");
txtPATERNO.DataBindings.Add("Text", dsUsers,
"USERS.PATERNO");
txtMATERNO.DataBindings.Add("Text", dsUsers,
"USERS.MATERNO");
txtNOMBRE.DataBindings.Add("Text", dsUsers,
"USERS.NOMBRE");
chkADMINISTRAR.DataBindings.Add("Checked", dsUsers,
"USERS.ADMINISTRAR", false);
chkVENTAS.DataBindings.Add("Checked", dsUsers,
"USERS.VENTAS", true);
chkREPORTES.DataBindings.Add("Checked", dsUsers,
"USERS.REPORTES", true);
chkCATALOGOS.DataBindings.Add("Checked", dsUsers,
"USERS.CATALOGOS", true);
chkCONSULTAS.DataBindings.Add("Checked", dsUsers,
"USERS.CONSULTAS", true);
chkDESHACER_VENTA.DataBindings.Add("Checked", dsUsers,
"USERS.DESHACER_VENTA", true);
cmUsers = (CurrencyManager)this.BindingContext[dsUsers, "USERS"];
cnnUsers.Close();
teclear el siguiente código, tal como se muestra:
void frmUsers_Closing(object sender,
System.ComponentModel.CancelEventArgs e){
try{
if (cnnUsers.State == ConnectionState.Open)
cnnUsers.Close();
}
catch (Exception ex) {
MessageBox.Show(ex.Message);
}
}
En btnNuevo:
//Agregar un registro
cmUsers.AddNew();
En btnCancelar:
//Cancelar
cmUsers.CancelCurrentEdit();
En btnGrabar:
//Grabar
try{
cmUsers.EndCurrentEdit();
if (cnnUsers.State == ConnectionState.Open)
cnnUsers.Close();
cnnUsers.Open();
daUsers.Update(dsUsers, "USERS");
cnnUsers.Close();
}
catch (Exception ex) {
MessageBox.Show(ex.Message + "" + ex.StackTrace);
}
En btnEliminar:
//Eliminar
try{
DialogResult Resp = new DialogResult();
Resp = MessageBox.Show("¿Desea Eliminar al usuario?",
"Eliminar", MessageBoxButtons.YesNo,
MessageBoxIcon.Question);
if (Resp == DialogResult.Yes)
{
cmUsers.RemoveAt(cmUsers.Position);
if (cnnUsers.State == ConnectionState.Open)
cnnUsers.Close();
cnnUsers.Open();
daUsers.Update(dsUsers, "USERS");
cnnUsers.Close();
}
}
catch (Exception ex){
MessageBox.Show(ex.Message);
}
Para btnInicio:
//Navegar al 1er registro
cmUsers.Position = 0;
Para btnAnterior:
//Navegar un registro hacia atraz
cmUsers.Position -= 1;
Para btnSiguiente:
//Navergar un registro hacia adelante
cmUsers.Position += 1;
Para btnFinal:
//Navegar al último registro
cmUsers.Position =
cmUsers.Count - 1;
Para btnCerrar:
this.Close();
Creación de una Librería de Clases (Dll)
El objetivo de este ejercicio es mostrar al alumno la manera de crear sus
propias Librerías de Clases.
Nos ubicamos en la parte en donde dice Solution ‘proTienda_MATRICULA’
y con el botón derecho seleccionamos “Add>New Project...”
Creamos una librería de clase llamada Ticket:
Borramos la clase que nos ofrece por defecto:
Agregamos una nueva clase llamada mPrintDocument:
Antes de continuar, agregamos varias referencias al nuevo proyecto
(utilizando el botón derecho del Mouse sobre “References”:
Una para System.Drawing
Y otra para System.Windows.Forms:
Nuestro proyecto quedará así:
Nota: en la imagen se muestran algunos formularios que aun no se han
realizado. Éstos se desarrollarán posteriormente.
Agregamos las siguientes directivas using (únicamente si no están), para
que quede mas o menos así:
using System.Drawing.Printing;
using System;
using System.Windows.Forms;
using System.Drawing;
namespace Ticket
{
class mPrintDocument
{
//Aqui irá todo el código
}
}
En la parte que dice “Aquí irá todo el código” poner lo siguiente:
//Aqui irá todo el código
/// <summary>
/// Punto de entrada de la clase
/// </summary>
/// <param name=prmText">Texto que será impreso</param>"
public mPrintDocument(string prmText){
//Constructor
InitializeComponent();
txtDocument.Text = prmText;
leftmargin = pdoc.DefaultPageSettings.Margins.Left;
topmargin = pdoc.DefaultPageSettings.Margins.Top;
}
private PrintDocument pdoc = new PrintDocument();
private TextBox txtDocument = new TextBox();
static int intCurrentChar;
private string text = "UAT-UAMCAV";
private int fontsize = 10;
private string fontname = "Courier New";
int leftmargin = 0;
int rightmargin = 0;
int topmargin = 0;
int bottommargin = 0;
protected void InitializeComponent(){
pdoc.PrintPage += new
PrintPageEventHandler(pDoc_PrintPage);
}
public string Text{
get{
return (text);
}
set{
text = value;
}
}
/// <summary>
/// Propiedad FontSize, Representa
/// el tamaño de la fuente
/// </summary>
/// <value>Representa el tamaño de la fuente</value>
public int FontSize{
set{
fontsize = value;
}
get{
return (fontsize);
}
}
/// <summary>
/// Propiedad FontName, Representa
/// el nombre de la fuente
/// </summary>
public string FontName{
set{
fontname = value;
}
get{
return (fontname);
}
}
/// <summary>
/// Representa la distancia entre el contenido
/// y el borde izquierdo de la página
/// </summary>
public int LeftMargin{
set{
leftmargin = value;
}
get{
return (leftmargin);
}
}
/// <summary>
/// Representa la distancia entre el contenido
/// y el borde derecho de la página
/// </summary>
public int RightMargin{
set{
rightmargin = value;
}
get{
return (rightmargin);
}
}
/// <summary>
/// Representa la distancia entre el contenido
/// y el borde superior de la página
/// </summary>
public int TopMargin{
set{
topmargin = value;
}
get{
return (topmargin);
}
}
/// <summary>
/// Representa la distancia entre el contenido y
/// el borde inferior de la página
/// </summary>
public int BottomMargin{
set{
bottommargin = value;
}
get{
return (bottommargin);
}
}
/// <summary>
/// Mostrar en pantalla
/// </summary>
public void PrintPreview(){
PrintPreviewDialog ppd = new PrintPreviewDialog();
try{
ppd.Document = pdoc;
ppd.ShowDialog();
}
catch{
MessageBox.Show("Error al intentar cargar " +
"la vista preeliminar el documento", this.Text,
MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
/// <summary>
/// Mandar directamente a la impresora
/// </summary>
public void Print(){
PrintDialog dialog = new PrintDialog();
dialog.Document = pdoc;
if (dialog.ShowDialog() == DialogResult.OK){
pdoc.Print();
}
}
void pDoc_PrintPage(object sender, PrintPageEventArgs e){
Font font = new Font(fontname, fontsize);
int intPrintAreaHeight;
int intPrintAreaWidth;
intPrintAreaHeight = pdoc.DefaultPageSettings.PaperSize.Height pdoc.DefaultPageSettings.Margins.Top pdoc.DefaultPageSettings.Margins.Bottom;
intPrintAreaWidth = pdoc.DefaultPageSettings.PaperSize.Width pdoc.DefaultPageSettings.Margins.Left pdoc.DefaultPageSettings.Margins.Right;
if (pdoc.DefaultPageSettings.Landscape){
int intTemp = intPrintAreaHeight;
intPrintAreaHeight = intPrintAreaWidth;
intPrintAreaWidth = intTemp;
}
int intLineCount = (int)(intPrintAreaHeight / font.Height);
RectangleF rectPrintingArea = new RectangleF(leftmargin, topmargin,
intPrintAreaWidth, intPrintAreaHeight);
StringFormat fmt = new StringFormat(StringFormatFlags.LineLimit);
int intLinesFilled;
int intCharsFitted;
e.Graphics.MeasureString(txtDocument.Text.Substring(intCurrentChar),
font,
new SizeF(intPrintAreaWidth, intPrintAreaHeight), fmt,
out intCharsFitted, out intLinesFilled);
e.Graphics.DrawString(txtDocument.Text.Substring(intCurrentChar),
font,
Brushes.Black, rectPrintingArea, fmt);
intCurrentChar += intCharsFitted;
if (intCurrentChar < (txtDocument.Text.Length - 1)){
e.HasMorePages = true;
}
else{
e.HasMorePages = false;
intCurrentChar = 0;
}
}
Una vez terminado lo anterior, nos vamos donde dice
“proTienda_MATRICULA” y, con el botón derecho del mouse,
seleccionamos “Add Reference…” como se muestra a continuación:
Nos vamos a la pestaña “Projects” y seleccionamos “Ticket”
Le damos OK.
Nuestro proyecto, finalmente quedará así:
El objetivo principal de la Librería Ticket es poder mandar a la pantalla el
ticket correspondiente a la venta, pero en realidad se podrá imprimir
prácticamente cualquier texto. En el ejercicio 5 podremos comprobarlo.
Consulta de ventas
Lo que haremos en esta ocasión es una pantalla para consultar ventas.
1. Agregar un formulario con el nombre frmConsultaVentas
2. Agregar un ListView con el nombre lvListaVentas
Propiedades del ListView:
Name= lvListaVentas
Dock=Fill
GridLines=True
Creamos este procedimiento:
private void Encabezados()
{
lvListaVentas.View = View.Details;
lvListaVentas.Columns.Add("Ticket", 90,
HorizontalAlignment.Left);
lvListaVentas.Columns.Add("Fecha", 175,
HorizontalAlignment.Left);
lvListaVentas.Columns.Add("Caja", 50,
HorizontalAlignment.Center);
lvListaVentas.Columns.Add("Cajero", 175,
HorizontalAlignment.Left);
lvListaVentas.Columns.Add("Total", 150,
HorizontalAlignment.Right);
}
Luego agregamos este otro procedimiento:
private void ReadData(){
//Este procedimiento lee los datos
//que se tranferirán y los mostrará en forma de
//lista en el ListView
try{
string varSQL = "SELECT V.FOLIO, V.FECHA,"+
" V.ID_CAJA as CAJA, "+
" U.NOMBRE + ' ' +" +
" U.PATERNO + ' ' + U.MATERNO as CAJERO,"+
" SUM(DV.CANTIDAD * DV.P_UNITARIO) AS TOTAL" +
" FROM USERS U INNER "+
" JOIN (CAT_PRODUCTOS P INNER JOIN "+
" (VENTAS V INNER "+
" JOIN DETALLE_VENTAS DV ON V.FOLIO = DV.FOLIO) "+
" ON P.ID_PRODUCTO = DV.ID_PRODUCTO)"+
" ON U.USER_NAME = V.USER_NAME"+
" GROUP BY V.FOLIO, V.FECHA, V.ID_CAJA, U.NOMBRE,"+
" U.PATERNO, U.MATERNO";
double varTOTAL = 0;
//Si la conexion esta abierta la cerramos
//en caso contrario, la abrimos
OleDbConnection cnnReadData =
new OleDbConnection(Class.clsMain.CnnStr);
if (cnnReadData.State == ConnectionState.Open)
cnnReadData.Close();
else cnnReadData.Open();
int I = 0;
OleDbCommand cmdReadData =
new OleDbCommand(varSQL, cnnReadData);
OleDbDataReader drReadData;
drReadData = cmdReadData.ExecuteReader();
lvListaVentas.Items.Clear();
while (drReadData.Read()){
lvListaVentas.Items.
Add(drReadData["FOLIO"].ToString());
lvListaVentas.Items[I].
SubItems.Add(drReadData["FECHA"].ToString());
lvListaVentas.Items[I].
SubItems.Add(drReadData["CAJA"].ToString());
lvListaVentas.Items[I].
SubItems.Add(drReadData["CAJERO"].ToString());
lvListaVentas.Items[I].
SubItems.Add(String.Format("{0:C}",
drReadData["TOTAL"]));
varTOTAL += Convert.ToDouble(drReadData["TOTAL"]);
I += 1;
}
//Agregamos un registro más
if (I != 0) {
lvListaVentas.Items.Add("");
lvListaVentas.Items[I].SubItems.Add("");
lvListaVentas.Items[I].SubItems.Add("");
lvListaVentas.Items[I].SubItems.Add("Gran Total:");
lvListaVentas.Items[I].
SubItems.Add(String.Format("{0:C}", varTOTAL));
}
drReadData.Close();
cmdReadData.Dispose();
cnnReadData.Close();
}
catch (Exception ex){
MessageBox.Show(ex.Message, "Error",
MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
Agregamos el siguiente código en el FormLoad:
Encabezados();
ReadData();
Búsqueda de productos
Lo que vamos a hacer hoy es una pantalla que nos permita buscar
productos, que los muestre en la pantalla y que podamos ver la información
que se tenga de ellos.
A partir de este momento programaremos para lograr que los objetos
(Formularios, Clases, Dll) interactúen entre sí. Por ejemplo, lograremos que
al momento de generar un ticket de venta la pantalla en la que se haga el
cobro ya sepa la cantidad que se cobrará al cliente en base al folio que
tenga el ticket. Todo esto lo haremos en base a constructores.
Agregaremos varios formularios a nuestro proyecto para que quede como
se muestra:
Si no me equivoco, frmBuscaProducto, frmCobrar, frmVentas. Hoy nos
enfocamos a frmBuscaProducto y dejamos el resto para después.
Diseñaremos frmBuscaProducto para que quede como se muestra:
Le deberemos de agregar una Label, un TextBox, un Button y un ListView,
según la siguiente tabla:
Nos vamos directamente al código y tecleamos lo siguiente en la sección de
las directivas using (únicamente si no está la línea):
using System.Data.OleDb;
En la sección de declaraciones ponemos:
//Declaraciones
public string varID_PRODUCTO = "";
Crearemos el siguiente procedimiento, el cual nos ayudará para poner
columnas en el ListView:
private void Encabezados()
{
lvProductos.View = View.Details;
lvProductos.Columns.Add("Clave producto", 0,
HorizontalAlignment.Left);
lvProductos.Columns.Add("Descripción", 250,
HorizontalAlignment.Left);
lvProductos.Columns.Add("Existencia", 90,
HorizontalAlignment.Right);
lvProductos.Columns.Add("Precio", 90,
HorizontalAlignment.Right);
}
Después agregamos el siguiente:
private void Producto()
{
try
{
if (lvProductos.Items.Count != 0)
{
varID_PRODUCTO = lvProductos.SelectedItems[0].Text;
}
else
{
varID_PRODUCTO = "";
}
this.Close();
}
catch (Exception ex)
{
MessageBox.Show("Debe seleccionar un elemento de la lista."+
" \nDescripción del error: \n" + ex.Message,
"Operación no válida", MessageBoxButtons.OK,
MessageBoxIcon.Exclamation);
}
}
Agregamos este otro procedimiento:
private void ReadData(string prmDESC_PRODUCTO){
//Este procedimiento lee los datos que se
//tranferirán y los mostrará en forma de
//lista en el ListView
try {
//Si la conexion esta abierta la cerramos;
//en caso contrario, la abrimos
OleDbConnection cnnReadData =
new OleDbConnection(Class.clsMain.CnnStr);
if (cnnReadData.State == ConnectionState.Open)
cnnReadData.Close();
else cnnReadData.Open();
int I = 0;
OleDbCommand cmdReadData =
new OleDbCommand("SELECT ID_PRODUCTO,"+
" DESC_PRODUCTO,"+
" CANTIDAD,P_U_VENTA " +
" FROM CAT_PRODUCTOS"+
" WHERE DESC_PRODUCTO like '%" +
prmDESC_PRODUCTO + "%'", cnnReadData);
OleDbDataReader drReadData;
drReadData = cmdReadData.ExecuteReader();
lvProductos.Items.Clear();
while (drReadData.Read()){
lvProductos.Items.
Add(drReadData["ID_PRODUCTO"].ToString());
lvProductos.Items[I].SubItems.
Add(drReadData["DESC_PRODUCTO"].ToString());
lvProductos.Items[I].SubItems.
Add(drReadData["CANTIDAD"].ToString());
lvProductos.Items[I].SubItems.
Add(String.Format("{0:C}",
drReadData["P_U_VENTA"]));
I += 1;
}
drReadData.Close();
cmdReadData.Dispose();
cnnReadData.Close();
}
catch (Exception ex){
MessageBox.Show(ex.Message);
}
}
Pondremos lo siguiente el Form_Load:
//Form_Load
this.lvProductos.DoubleClick +=
new System.EventHandler(this.lvProductos_DoubleClick);
this.lvProductos.KeyPress +=
new
System.Windows.Forms.KeyPressEventHandler(this.lvProductos_KeyPress);
Encabezados();
Y justo después del Form_Load ponemos lo siguiente:
void lvProductos_KeyPress(object sender,
System.Windows.Forms.KeyPressEventArgs e){
switch (e.KeyChar){
case (char)Keys.Enter:
Producto();
break;
case (char)Keys.Escape:
varID_PRODUCTO = "";
this.Close();
break;
}
}
void lvProductos_DoubleClick(object sender,
System.EventArgs e){
Producto();
}
Deberá escribirse el código tal y cual se muestra, ya que se tratan de
procedimientos creados por nosotros mismos.
Hacemos soble clic en el boton (btnBuscar) y le agregamos el siguiente
código:
ReadData(txtDESC_PRODUCTO.Text);
Si todo va bien y no nos hemos equivocado, hemos terminado
satisfactoriamente el ejercicio.
Recomendaciones:
1. Hacer respaldos del sistema según se vaya avanzando en el
desarrollo.
2. Guardar los cambios periódicamente
3. Tener mucho cuidado en donde colocamos nuestro código. Una
instrucción mal colocada puede echar a perder todo nuestro trabajo.
4. Para estos ejercicios, si lo pongo con mayúscula, es mayúscula y
viceversa. No le hagamos al héroe, aun no tenemos la experiencia
como para saber como funcionará mejor nuestro programa.
5. Nadie es perfecto. Puedo equivocarme, siempre pruebo el código
que estoy exponiendo, pero al momento de transcribirlo aquí pueden
ocurrir errores.
6. Pantalla para cobrar e imprimir el ticket de venta
Tenemos un formulario llamado frmCobrar, nos centraremos en él
para lograr nuestro objetivo.
Deberemos diseñarlo como se muestra:
Agregamos tres Label, tres TextBox y un Button. Según la siguiente
tabla:
Para lograr que tome el tamaño adecuado, diseñar al gusto
En donde las directivas using, poner una más:
7. using System.Data.OleDb;
8.
Localizamos el constructor, debe ser uno idéntico al que se muestra:
9. public frmCobrar()
{
InitializeComponent();
}
10.
Nosotros agregaremos uno más:
11. public frmCobrar(int prmFolio){
InitializeComponent();
varFolio = prmFolio;
}
12.
Justo debajo del constructor que acabamos de agregar, declaramos
dos variables:
13. int varFolio=0;
double varTotal = 0;
14.
Damos doble clic en el formulario y ponemos lo siguiente dentro del
Form_Load:
15.
//Form_Load
this.txtEfectivo.TextChanged +=
new EventHandler(txtEfectivo_TextChanged);
varTotal = fnCalculaPago(varFolio);
txtTotal.Text = String.Format("{0:C}", varTotal);
16.
Inmediatamente después del Form_Load, creamos el siguiente
procedimiento (Fuera del Form_Load):
17. void txtEfectivo_TextChanged(object sender, EventArgs e){
try{
txtCambio.Text = String.Format("{0:C}",
(Convert.ToDouble(txtEfectivo.Text) - varTotal));
}
catch (Exception ex){
txtCambio.Text = ex.Message;
}
}
18.
La línea que está marcada con negritas indica que se creará un
procedimiento para cuando una tecla sea presionada si el TextBox
tiene el foco.
También agregamos este otro procedimiento:
19. private double fnCalculaPago(int prmFolio) {
try {
OleDbConnection _cnnCalculaPago =
new OleDbConnection(Class.clsMain.CnnStr);
_cnnCalculaPago.Open();
OleDbCommand _cmdCalculaPago =
new OleDbCommand("SELECT SUM(CANTIDAD*P_UNITARIO) "+
"FROM DETALLE_VENTAS "+
"WHERE FOLIO="+ prmFolio +"", _cnnCalculaPago);
double _return =
Convert.ToDouble(_cmdCalculaPago.ExecuteScalar());
_cnnCalculaPago.Close();
_cnnCalculaPago.Dispose();
_cmdCalculaPago.Dispose();
return (_return);
}
catch (Exception ex) {
MessageBox.Show(ex.Message,"fnCalculaPago");
return (0);
}
}
20.
Hacemos soble clic sobre el botón (btnOk) y ponemos el siguiente
código:
21. if (txtEfectivo.Text != ""){
DialogResult _Resp = new DialogResult();
_Resp = MessageBox.Show("¿Desea imprimir el ticket?",
"Ticket", MessageBoxButtons.YesNo,
MessageBoxIcon.Question);
if (_Resp == DialogResult.Yes){
//Imprmmir el ticket
GenerarTicket(varFolio);
this.Close();
}
else{
this.Close();
}
}
else {
MessageBox.Show("Debe introducir una cantidad",
"Faltan datos");
}
22.
Ahora cramos el procedimiento que nos mostrará el ticket de venta:
Ojo, para que este funcione deberemos haber hecho bién el ejercicio
de la Dll.
23. private void GenerarTicket(int prmFOLIO) {
try{
string Ticket = "Nombre de la tienda: UAMCAV\n" +
"RFC:XXXXXX\n" +
"------------------------------\n" +
"ARTICULO
CANT
PRECIO
TOTAL\n" +
"------------------------------\n";
string varSQL =
"SELECT LEFT(DESC_PRODUCTO,10) as DESC_PRODUCTO," +
" CANTIDAD,P_UNITARIO,TOTAL" +
" FROM vVENTAS WHERE FOLIO=" + prmFOLIO + "";
string DetalleTicket = "";
double varGranTotal = 0;
OleDbConnection cnnTicket =
new OleDbConnection(Class.clsMain.CnnStr);
cnnTicket.Open();
OleDbCommand cmdTicket =
new OleDbCommand(varSQL, cnnTicket);
OleDbDataReader drTicket;
drTicket = cmdTicket.ExecuteReader();
while (drTicket.Read()){
DetalleTicket +=
drTicket["DESC_PRODUCTO"].ToString() + "
drTicket["CANTIDAD"].ToString() + "
" +
" +
String.Format("{0:C}",
drTicket["P_UNITARIO"]) + "
" +
String.Format("{0:C}",
drTicket["TOTAL"]) + "\n";
varGranTotal += (double)drTicket["TOTAL"];
}
DetalleTicket +=
"------------------------------\n" +
"TOTAL: " + String.Format("{0:C}",
varGranTotal);
Ticket += DetalleTicket;
mPrintDocument _mPrintDocument =
new mPrintDocument(Ticket);
_mPrintDocument.PrintPreview();
}
catch (Exception ex) {
MessageBox.Show(ex.Message);
}
}
24.
Listo,... por el momento solo debemos compilarlo para asegurarnos
de que no tenga errores
Pantalla de Ventas
Hemos llegado a la parte más difícil de esta serie de 10 ejercicios, las
ventas. Todo tiene que estar bien en los ejercicios anteriores ya que nos
serviremos de ellos para tener éxito en lo subsiguiente.
Para no tener problemas, recomiendo que lean los textos que voy a
exponer, ya que antes de empezar a escribir algún código explicaré e
intentaré dejar claro que es lo que se va a hacer, por que se va a hacer así
y, de ser posible, haré aclaraciones de el por que es la mejor manera de
hacerlo así.
Antes de comenzar, demos un vistazo sobre el funcionamiento de la
aplicación:
Iniciando sesión:
Aquí se pone el nombre de usuario y la contraseña. No tiene gran dificultad.
Si por algún motivo nuestra aplicación está en RED, podemos ubicar el
archivo de base de datos por medio del link que está subrayado de azul:
Solo bastará buscar la ruta de la base de datos entre las ubicaciones de red
disponibles y listo.
Cuando entramos, lo primero que vemos es lo siguiente:
Tiene varios menús los cuales nos llevan a diferentes opciones del sistema.
Nos centraremos en el de Ventas:
Si presionamos el botón buscar producto:
Al seleccionar uno, y haciéndole doble clic:
En este momento podemos ponerle otra cantidad para que, al presionar
Enter:
Luego, presionamos el Botón Realizar venta:
Podemos presionar Enter y ocurre lo siguiente:
Si elegimos “Yes”
Es una visión general de lo que lograremos una vez terminado este
ejercicio.
Iniciemos de una vez…
Vamos a intentar lograr lo imposible, intentaremos entender la mentalidad
de un desarrollador profesional, nos enredaremos la cabeza con código
avanzado que probablemente no entenderemos por más que nos expliquen.
Solo vamos a centrar nuestra atención en hacer las cosas al pié de la letra y
os aseguro que tendremos éxito.
Diseñaremos frmVentas como se muestra a continuación:
Agregaremos un Listview, 5 Label, 4 TextBox y 4 Button, como se muestra
en la tabla:
El cuarto botón solo es para dar una mejor vista, se pone debajo de los
otros tres, para efectos prácticos puede ser omitido.
Agregaremos un constructor, justo debajo del constructor que ofrece
predeterminadamente:
public frmVentas(string prmUSER_LOGIN,int prmID_CAJA){
InitializeComponent();
varID_CAJA = prmID_CAJA;
varUSER_LOGIN = prmUSER_LOGIN;
}
Luego declaramos unas variables:
//Declaraciones
string varUSER_LOGIN = frmLogin._USER_NAME;
int varID_CAJA=1;
La primera variable nos servirá para saber el nombre con el que inició
sesión el usuario, la segunda es por que nuestro sistema podría soportar un
indefinido número de cajas, claro que para este caso solo será una.
Ahora pondremos lo siguiente en el Form_Load:
//Form_Load
Headers();
ReadData(varUSER_LOGIN,
varID_CAJA);
this.txtCANTIDAD.KeyPress +=
new System.Windows.Forms.
KeyPressEventHandler(this.txtCANTIDAD_KeyPress);
this.txtCANTIDAD.KeyDown +=
new System.Windows.Forms.
KeyEventHandler(this.txtCANTIDAD_KeyDown);
this.txtID_PRODUCTO.KeyPress +=
new System.Windows.Forms.
KeyPressEventHandler(this.txtID_PRODUCTO_KeyPress);
this.txtID_PRODUCTO.KeyDown +=
new System.Windows.Forms.
KeyEventHandler(this.txtID_PRODUCTO_KeyDown);
El código anterior nos sirve para mandar llamar varios procedimientos que
son importantes al momento de que sea llamado el formulario. Claro que es
necesario lo siguiente para que lo anterior tenga sentido:
void Headers()
{
//Encabezados del litView
lvVenta.View = View.Details;
lvVenta.Columns.Add("Producto", 100,
HorizontalAlignment.Left);
lvVenta.Columns.Add("Descripcion", 250,
HorizontalAlignment.Left);
lvVenta.Columns.Add("Cant", 75,
HorizontalAlignment.Right);
lvVenta.Columns.Add("Prec", 75,
HorizontalAlignment.Right);
lvVenta.Columns.Add("Iva", 75,
HorizontalAlignment.Right);
lvVenta.Columns.Add("Total", 100,
HorizontalAlignment.Right);
}
void txtCANTIDAD_KeyPress(object sender,KeyPressEventArgs e){
try{
lblMensaje.Text = "";
if (!((txtID_PRODUCTO.Text == "") ||
(txtCANTIDAD.Text == ""))){
if (e.KeyChar == 13){
//Insertar código aqui
SaveTemp_Ventas(txtID_PRODUCTO.Text,
Convert.ToDouble(txtCANTIDAD.Text));
txtID_PRODUCTO.Focus();
}
}
else{
lblMensaje.Text = "Debe introducir una "+
"clave de producto y/o una cantidad";
}
}
catch (Exception ex){
MessageBox.Show(ex.Message);
}
}
void txtCANTIDAD_KeyDown(object sender, KeyEventArgs e) {
if (e.KeyCode == Keys.F5) {
RealizaVenta();
}
}
void txtID_PRODUCTO_KeyDown(object sender, KeyEventArgs e) {
if (e.KeyCode == Keys.F5) {
RealizaVenta();
}
}
void txtID_PRODUCTO_KeyPress(object sender, KeyPressEventArgs e) {
lblMensaje.Text = "";
try
{
if (!((txtID_PRODUCTO.Text == "") ||
(txtCANTIDAD.Text == ""))) {
if (e.KeyChar == 13){
//Inserttar código aqui
SaveTemp_Ventas(txtID_PRODUCTO.Text,
Convert.ToDouble(txtCANTIDAD.Text));
txtID_PRODUCTO.Focus();
}
}
else {
lblMensaje.Text = "Debe introducir una "+
"clave de producto y/o una cantidad";
}
}
catch (Exception ex) {
MessageBox.Show(ex.Message);
}
}
El código anterior actúa dependiendo del objeto del que se trate. Por
ejemplo los que dicen KeyPress, controlan el momento en que es
presionada una tebla sobre el objeto, lo mismo ocurre con KeyDown, solo
que en este caso se trata de teclas especiales como las teclas F1-F12.
void SaveTemp_Ventas(string prmID_PRODUCTO,double prmCANTIDAD) {
double[] varProductDetails = new double[1];
varProductDetails =
FindProductDetails(prmID_PRODUCTO);
double varPRECIO = varProductDetails[0];
try
{
if (varPRECIO ==0.0) {
lblMensaje.Text =
"El producto no existe!!!";
}
else
{
Temp_Ventas(varUSER_LOGIN , varID_CAJA ,
prmID_PRODUCTO , prmCANTIDAD, varPRECIO);
ReadData(varUSER_LOGIN , varID_CAJA );
}
}
catch (Exception ex) {
MessageBox.Show(ex.Message, "Error");
}
}
void ReadData(string prmUSER_NAME,int prmID_CAJA) {
lblMensaje.Text = "";
double varIVA = 0.0;
double varGRAND_TOTAL = 0.0;
try {
OleDbConnection cnnReadData =
new OleDbConnection(Class.clsMain.CnnStr);
string varSQL = "SELECT CAT_PRODUCTOS.ID_PRODUCTO, "+
" CAT_PRODUCTOS.DESC_PRODUCTO," +
" TEMP_VENTAS.CANTIDAD, "+
" TEMP_VENTAS.P_UNITARIO, "+
" TEMP_VENTAS.IVA,"+
" (TEMP_VENTAS.CANTIDAD*"+
" TEMP_VENTAS.P_UNITARIO) AS TOTAL" +
" FROM CAT_PRODUCTOS "+
" INNER JOIN TEMP_VENTAS" +
" ON CAT_PRODUCTOS.ID_PRODUCTO = "+
" TEMP_VENTAS.ID_PRODUCTO "+
" WHERE TEMP_VENTAS.USER_NAME ='" +
prmUSER_NAME + "'";
int I = 0;
OleDbCommand cmdReadData =
new OleDbCommand(varSQL, cnnReadData);
OleDbDataReader drReadData;
if(cnnReadData.State == ConnectionState.Open)
cnnReadData.Close();
cnnReadData.Open();
drReadData = cmdReadData.ExecuteReader();
lvVenta.Items.Clear();
while (drReadData.Read()) {
lvVenta.Items.
Add(drReadData["ID_PRODUCTO"].ToString());
lvVenta.Items[I].SubItems.
Add(drReadData["DESC_PRODUCTO"].ToString());
lvVenta.Items[I].SubItems.
Add(drReadData["CANTIDAD"].ToString());
lvVenta.Items[I].SubItems.
Add(drReadData["P_UNITARIO"].ToString());
lvVenta.Items[I].SubItems.
Add(drReadData["IVA"].ToString() + " %");
lvVenta.Items[I].SubItems.
Add(String.Format("{0:C}", drReadData["TOTAL"]));
//Obtenemos el Grand Total y el Iva
varGRAND_TOTAL += Convert.ToDouble(drReadData[5]);
varIVA += Convert.ToDouble(drReadData["IVA"]) *
((Convert.ToDouble(drReadData["TOTAL"]))/100);
I += 1;
}
drReadData.Close();
cmdReadData.Dispose();
cnnReadData.Close();
cnnReadData.Dispose();
txtGRAND_TOTAL.Text =
String.Format("{0:C}",
varGRAND_TOTAL);
txtIVA.Text =
String.Format("{0:C}", varIVA);
}
catch (Exception ex) {
MessageBox.Show (ex.Message);
}
}
void Temp_Ventas(string prmUSER_LOGIN,int prmID_CAJA,
string prmID_PRODUCTO,double prmCANTIDAD,
double prmPRECIO) {
//Para cargar la venta tenporal
string varSQL = "";
try {
OleDbConnection cnnTempVentas =
new OleDbConnection(Class.clsMain.CnnStr);
if (GetSale(prmUSER_LOGIN, prmID_CAJA,
prmID_PRODUCTO) == 0){
varSQL = "INSERT
INTO TEMP_VENTAS(USER_NAME,"+
"ID_PRODUCTO,CANTIDAD,P_UNITARIO,IVA)" +
" VALUES('" + prmUSER_LOGIN + "','" +
prmID_PRODUCTO +
"'," + prmCANTIDAD + "," +
prmPRECIO + ",0)";
}
else {
varSQL = "UPDATE TEMP_VENTAS "+
"SET CANTIDAD = CANTIDAD + "+
prmCANTIDAD
+"" +
" WHERE USER_NAME = '"+
prmUSER_LOGIN
+"'" +
" AND ID_PRODUCTO = '"+
prmID_PRODUCTO
+"'";
}
OleDbCommand cmdTempVentas =
new OleDbCommand(varSQL, cnnTempVentas);
if (cnnTempVentas.State == ConnectionState.Open)
cnnTempVentas.Close();
cnnTempVentas.Open();
cmdTempVentas.ExecuteNonQuery();
cnnTempVentas.Close();
cmdTempVentas.Dispose();
cnnTempVentas.Dispose();
txtID_PRODUCTO.Text = "";
txtCANTIDAD.Text = "1";
}
catch(Exception ex) {
MessageBox.Show(ex.Message,"TempVentas");
}
}
double[] FindProductDetails(string prmID_PRODUCTO){
double[] Retorno = new double[2];
try {
OleDbConnection cnnFindProductDetails =
new OleDbConnection(Class.clsMain.CnnStr);
string varSQL = "SELECT count(*) "+
"FROM CAT_PRODUCTOS "+
"WHERE ID_PRODUCTO = '" +
prmID_PRODUCTO + "'";
OleDbCommand cmdFindProductDetails =
new OleDbCommand();
cmdFindProductDetails.Connection =
cnnFindProductDetails;
cmdFindProductDetails.CommandText = varSQL;
if (cnnFindProductDetails.State == ConnectionState.Open)
cnnFindProductDetails.Close();
cnnFindProductDetails.Open();
if (!(Convert.ToInt32(cmdFindProductDetails.ExecuteScalar()) ==
0)) {
varSQL = "SELECT P_U_VENTA "+
" FROM CAT_PRODUCTOS "+
"WHERE ID_PRODUCTO ='" +
prmID_PRODUCTO + "'";
cmdFindProductDetails.CommandText = varSQL;
Retorno[0] = Convert.
ToDouble(cmdFindProductDetails.ExecuteScalar());
varSQL = "SELECT IVA "+
"FROM CAT_PRODUCTOS "+
"WHERE ID_PRODUCTO ='" +
prmID_PRODUCTO + "'";
cmdFindProductDetails.CommandText = varSQL;
Retorno[1] = Convert.
ToDouble(cmdFindProductDetails.ExecuteScalar());
}
else {
Retorno[0] = 0.0;
Retorno[1] = 0.0;
}
cmdFindProductDetails.Dispose();
cnnFindProductDetails.Close();
cnnFindProductDetails.Dispose();
return (Retorno);
}
catch (Exception ex) {
MessageBox.Show(ex.Message,
"FindProductDetails");
return (Retorno);
}
}
double GetSale(string prmUSER_LOGIN,int prmID_CAJA,
string prmID_PRODUCTO){
//Para cargar la venta tenporal
double Retorno;
try {
OleDbConnection cnnGetSale =
new OleDbConnection(Class.clsMain.CnnStr);
string varSQL = "SELECT COUNT(*) FROM TEMP_VENTAS " +
" WHERE USER_NAME = '"+ prmUSER_LOGIN
" AND ID_PRODUCTO = '"+ prmID_PRODUCTO
+"' " +
+"'";
OleDbCommand cmdGetSale =
new OleDbCommand(varSQL, cnnGetSale);
if (cnnGetSale.State == ConnectionState.Open)
cnnGetSale.Close();
cnnGetSale.Open();
Retorno = Convert.
ToDouble(cmdGetSale.ExecuteScalar());
cmdGetSale.Dispose();
cnnGetSale.Close();
cnnGetSale.Dispose();
return (Retorno);
}
catch (Exception ex){
MessageBox.Show(ex.Message,"GetSale");
return (0);
}
}
private void RealizaVenta() {
if (lvVenta.Items.Count != 0)
{
int varFolio = RealizaVenta(varUSER_LOGIN, varID_CAJA);
if (varFolio != 0)
{
frmCobrar _frmCobrar = new frmCobrar(varFolio);
_frmCobrar.StartPosition = FormStartPosition.CenterScreen;
_frmCobrar.ShowDialog();
}
}
}
private int RealizaVenta(string prmUSER_LOGIN, int prmID_CAJA){
int varFolio = 0;
try{
OleDbConnection cnnInsert =
new OleDbConnection(Class.clsMain.CnnStr);
cnnInsert.Open();
OleDbCommand cmdInsert = new OleDbCommand();
cmdInsert.Connection = cnnInsert;
//insertamos el registro padre
cmdInsert.CommandText =
"INSERT INTO VENTAS (USER_NAME,ID_CAJA,FECHA) " +
"VALUES('" + prmUSER_LOGIN +
"'," + prmID_CAJA + ",NOW())";
cmdInsert.ExecuteNonQuery();
//obtenemos el autonumerico
cmdInsert.CommandText = "SELECT @@IDENTITY";
varFolio = Convert.ToInt32(cmdInsert.ExecuteScalar());
//GENERAMOS LA VENTA
cmdInsert.CommandText =
"INSERT INTO DETALLE_VENTAS "+
" (ID_PRODUCTO,FOLIO,CANTIDAD,P_UNITARIO,IVA)"+
" SELECT ID_PRODUCTO,"+ varFolio +","+
" CANTIDAD,P_UNITARIO,IVA "+
" FROM TEMP_VENTAS "+
" WHERE USER_NAME ='"+ prmUSER_LOGIN +"'";
cmdInsert.ExecuteNonQuery();
//ACTUALIZAMOS LAS EXISTENCIAS
cmdInsert.CommandText = "UPDATE CAT_PRODUCTOS "+
" INNER JOIN TEMP_VENTAS "+
" ON CAT_PRODUCTOS.ID_PRODUCTO = "+
" TEMP_VENTAS.ID_PRODUCTO "+
" SET CAT_PRODUCTOS.CANTIDAD = "+
" CAT_PRODUCTOS.CANTIDAD-[TEMP_VENTAS].[CANTIDAD]"+
" WHERE (([TEMP_VENTAS].[USER_NAME]= "+
" '"+ prmUSER_LOGIN +"'));";
cmdInsert.ExecuteNonQuery();
//borramos las ventas temporales
cmdInsert.CommandText = "DELETE FROM TEMP_VENTAS " +
" WHERE USER_NAME = '" + prmUSER_LOGIN + "'";
cmdInsert.ExecuteNonQuery();
//LIBERAMOS LOS RECUSROS
cnnInsert.Close();
cnnInsert.Dispose();
cmdInsert.Dispose();
//mostramos la info
ReadData(varUSER_LOGIN, varID_CAJA);
return (varFolio);
}
catch (Exception ex){
MessageBox.Show(ex.Message, "RealizaVenta");
return (0);
}
}
private void DeshacerVenta(string prmUSER_LOGIN,int prmID_CAJA) {
OleDbConnection conDeshacerVenta;
OleDbCommand cmdDeshacerVenta;
string strSQL_Delete = "DELETE FROM TEMP_VENTAS " +
" WHERE USER_NAME = '" + prmUSER_LOGIN + "' ";
try{
conDeshacerVenta =
new OleDbConnection(Class.clsMain.CnnStr);
conDeshacerVenta.Open();
cmdDeshacerVenta =
new OleDbCommand(strSQL_Delete, conDeshacerVenta);
cmdDeshacerVenta.ExecuteNonQuery();
cmdDeshacerVenta.Dispose();
conDeshacerVenta.Close();
ReadData(varUSER_LOGIN, varID_CAJA);
}
catch(Exception ex){
MessageBox.Show(ex.Message,"DeshacerVenta");
}
}
Hacemos doble clic sobre btnBuscarProducto:
try{
frmBuscaProducto myForm = new frmBuscaProducto();
myForm.StartPosition = FormStartPosition.CenterScreen;
myForm.ShowDialog();
if (!(myForm.varID_PRODUCTO == "")){
txtID_PRODUCTO.Text = myForm.varID_PRODUCTO;
txtID_PRODUCTO.Focus();
}
myForm.Dispose();
}
catch (Exception ex) {
MessageBox.Show(ex.Message, "btnBuscaProducto", MessageBoxButtons.OK,
MessageBoxIcon.Error);
txtID_PRODUCTO.Text = "";
}
Luego sobre btnRealizarVenta:
RealizaVenta();
Para btnCerrar:
this.Close();
Vamos a suponer que todo lo anterior lo hemos hecho bien; lo que resta es
poner en mdiMain el código correspondiente para mandar llamar al
formulario de las ventas. Para conseguirlo deberemos hacer lo siguiente:
Hacemos doble clic sobre el menú “Punto de venta”:
Le ponemos el siguiente código:
frmVentas _frmVentas =
new frmVentas(frmLogin._USER_NAME,1);
_frmVentas.MdiParent = this;
_frmVentas.StartPosition =
FormStartPosition.Manual;
_frmVentas.Show();
Instalar la aplicación
Para instalar la aplicación basta con copiar los archivos de resultados,
generalmente contenidos en las carpetas "Debug"o "Release".
Nota: Es importante que el equipo en donde vayas a copiar los archivos
esté instalado el .Net Framework correspondiente.
Creación de un programa de instalación
Hola amigos, para crear un programa de instalación el .Net es realmente
fácil. Solo debemos agregar un nuevo proyecto a la solución, y seleccionar
"Asistente para programas de instalación". Seguir los pasos y listo.
Descargar