FiveTech Support Forums

FiveWin / Harbour / xBase community
Board index FiveWin para Harbour/xHarbour Ejemplo sencillo de factura
Posts: 53
Joined: Tue Aug 18, 2015 07:34 PM
Ejemplo sencillo de factura
Posted: Tue Apr 12, 2016 08:37 PM

Hola a todos de regreso aqui con un pedido de ejemplo

Alguien que me pueda ayudar o facilitarme de como iniciar una captura sencilla de factura,su encabezado y tenga botones de Altas agregar registro,modificar registro y eliminar registro y con browse mi correo es rositatun@gmail.com ,espero no pedir mucho lo que solicito para tablas dbfs

gracias

Rosa

Posts: 7317
Joined: Thu Oct 18, 2012 07:17 PM
Re: Ejemplo sencillo de factura
Posted: Tue Apr 12, 2016 09:49 PM
use xbrowse ...symply





aBrowse := {{"PAITEM" ,i18n("Codice") ,nil ,50 },;
{ "PADESC" ,i18n("Descrizione") ,nil ,290 },;
{ "PAQTY" ,i18n("Quantit脿") ,"9999" ,45 },;
{ "PAMISURA" ,i18n("Misura") ,nil ,37 },;
{ "PAUNITARIO" ,i18n("Unitario") ,pict_money_Euro ,80 },;
{ "PASCONTO" ,i18n("%Sconto") , nil ,60 },;
{ "PAPROVV" ,i18n("%Provv.") ,'@ 999.99%' ,50 },;
{ "PARIT" ,i18n("Ritenuta") ,nil ,80 },;
{ "PAIVA" ,i18n("Iva") ,"99%" ,36 },;
{ "PATOTALE" ,i18n("Importo") ,pict_money_Euro ,80 }}




@ 0, 0.2 XBROWSE oBrw ;
OF oFld:adialogs[1] DATASOURCE "TB" ;
COLUMNS aBrowse CELL LINES FOOTERS NOBORDER FONT oFont


WITH OBJECT oBrw
WITH OBJECT oBrw:aCols[1]
:nEditType := EDIT_BUTTON
:bEditBlock := { | nRow, nCol, oCol, nKey | LookArt( nRow, nCol, oCol, nKey ) }
END


...


end

oBrw:SetRDD()
oBrw:CreateFromCode()
oBrw:=.t.
oBrw:MakeTotals()
oBrw:RefreshFooters()

...return nil


Function LookArt( nRow, nCol, oCol, nKey )


return nil
Since from 1991/1992 ( fw for clipper Rel. 14.4 - Momos)

I use : FiveWin for Harbour March-April 2024 - Harbour 3.2.0dev (harbour_bcc770_32_20240309) - Bcc7.70 - xMate ver. 1.15.3 - PellesC - mail: silvio[dot]falconi[at]gmail[dot]com
Posts: 53
Joined: Tue Aug 18, 2015 07:34 PM
Re: Ejemplo sencillo de factura
Posted: Tue Apr 12, 2016 11:49 PM
Silvio.Falconi wrote:use xbrowse ...symply





aBrowse := {{"PAITEM" ,i18n("Codice") ,nil ,50 },;
{ "PADESC" ,i18n("Descrizione") ,nil ,290 },;
{ "PAQTY" ,i18n("Quantit脿") ,"9999" ,45 },;
{ "PAMISURA" ,i18n("Misura") ,nil ,37 },;
{ "PAUNITARIO" ,i18n("Unitario") ,pict_money_Euro ,80 },;
{ "PASCONTO" ,i18n("%Sconto") , nil ,60 },;
{ "PAPROVV" ,i18n("%Provv.") ,'@ 999.99%' ,50 },;
{ "PARIT" ,i18n("Ritenuta") ,nil ,80 },;
{ "PAIVA" ,i18n("Iva") ,"99%" ,36 },;
{ "PATOTALE" ,i18n("Importo") ,pict_money_Euro ,80 }}




@ 0, 0.2 XBROWSE oBrw ;
OF oFld:adialogs[1] DATASOURCE "TB" ;
COLUMNS aBrowse CELL LINES FOOTERS NOBORDER FONT oFont


WITH OBJECT oBrw
WITH OBJECT oBrw:aCols[1]
:nEditType := EDIT_BUTTON
:bEditBlock := { | nRow, nCol, oCol, nKey | LookArt( nRow, nCol, oCol, nKey ) }
END


...


end

oBrw:SetRDD()
oBrw:CreateFromCode()
oBrw:=.t.
oBrw:MakeTotals()
oBrw:RefreshFooters()

...return nil


Function LookArt( nRow, nCol, oCol, nKey )


return nil



gracias,pero buscaba mas funcional con sus botones de a帽adir nuevo registro y bajas de registro y modificacion de registro

alguien que me pueda apoyar con un trozo de codigo fuente de una captura de factura se los agradecere si me apoyan

Rosa
Posts: 2064
Joined: Fri Jan 06, 2006 09:28 PM
Re: Ejemplo sencillo de factura
Posted: Wed Apr 13, 2016 01:50 AM
Saludos, aca te envio un codigo completo pero usando mysql, te servira de ejemplo y cualquier duda avisas y te ayudo adaptarlo, ya subire la imagen para q veas como se, gracias, saludos... :-)



Code (fw): Select all Collapse
#include "FiveWin.ch"
#include "XBrowse.ch"
#include "Splitter.ch"
#include "Dtpicker.ch"
#include "InKey.ch"

MEMVAR oDatos

FUNCTION mfacventas()

聽 聽LOCAL oDlg, nFor := 0, oError, oQBtn[2] ,;
聽 聽 聽 聽 聽cQryCli, oQryCli, cQryVen, oQryVen, cQryTrn, oQryTrn ,;
聽 聽 聽 聽 聽oBrw, oCol, aItems := {} ,;
聽 聽 聽 聽 聽aBtn[10], aVar[30], aGet[30] ,;
聽 聽 聽 聽 聽aCondi := { "CONTADO", "CREDITO" } ,;
聽 聽 聽 聽 聽aStatus := { "ACTIVA ", "PAGADA ", "ANULADA" }

// APERTURA DE TABLAS RELACIONADAS...
聽 聽cQryCli := "SELECT * FROM clientes ORDER BY cli_codigo ASC"
聽 聽TRY
聽 聽 聽oQryCli := TDolphinQry():New( cQryCli, oDatos:oConex )
聽 聽CATCH oError
聽 聽 聽 MSGSTOP( oError:description() + CRLF + CRLF + ;
聽 聽 聽 聽 聽 聽 聽 聽"Error Ejecuci贸n de Sentencia en Tabla(clientes): " + ;
聽 聽 聽 聽 聽 聽 聽 聽CRLF + CRLF + cQryCli, oDatos:cTitMsg )
聽 聽 聽 RETURN( NIL )
聽 聽END

聽 聽cQryVen := "SELECT * FROM vendedores ORDER BY ven_codigo ASC"

聽 聽TRY
聽 聽 聽oQryVen := TDolphinQry():New( cQryVen, oDatos:oConex )
聽 聽CATCH oError
聽 聽 聽 MSGSTOP( oError:description() + CRLF + CRLF + ;
聽 聽 聽 聽 聽 聽 聽 聽"Error Ejecuci贸n de Sentencia en Tabla(vendedores): " + ;
聽 聽 聽 聽 聽 聽 聽 聽CRLF + CRLF + cQryVen, oDatos:cTitMsg )
聽 聽 聽 RETURN( NIL )
聽 聽END

聽 聽cQryTrn := "SELECT * FROM transporte ORDER BY trn_codigo ASC"

聽 聽TRY
聽 聽 聽oQryTrn := TDolphinQry():New( cQryTrn, oDatos:oConex )
聽 聽CATCH oError
聽 聽 聽 MSGSTOP( oError:description() + CRLF + CRLF + ;
聽 聽 聽 聽 聽 聽 聽 聽"Error Ejecuci贸n de Sentencia en Tabla(transporte): " + ;
聽 聽 聽 聽 聽 聽 聽 聽CRLF + CRLF + cQryTrn, oDatos:cTitMsg )
聽 聽 聽 RETURN( NIL )
聽 聽END
// FIN APERTURA DE TABLAS RELACIONADAS...

// DEFINICION VARIABLES
聽 聽aVar[1] := SPACE(10) // COD.CLIENTE
聽 聽aVar[2] := SPACE(50) // NOMB.CLIENTE
聽 聽aVar[3] := SPACE(10) // COD.VENDEDOR
聽 聽aVar[4] := SPACE(50) // NOMB.VENDEDOR
聽 聽aVar[5] := SPACE(10) // COD.TRANS.
聽 聽aVar[6] := SPACE(50) // NOMB.TRANS.
聽 聽aVar[7] := SPACE(10) // COMENTARIOS(memo)
聽 聽aVar[8] := 1 // CONDICIONES(combo.box)
聽 聽aVar[9] := 0 // DIAS PLAZO CREDITO
聽 聽aVar[10] := 1 // ESTADO FACT.(combo.box)
聽 聽aVar[11] := DATE() // FCH.FACT.
聽 聽aVar[12] := DATE() // FCH.VENCE.
聽 聽aVar[13] := 0 // NUM.CONTROL
聽 聽aVar[14] := 0 // NUM.FACTURA

聽 聽FOR nFor := 15 TO 24 // INICIALIZO var EN CERO
聽 聽 聽 aVar[nFor] := 0.00
聽 聽 聽 if nFor == 23
聽 聽 聽 聽 聽aVar[nFor] := -700
聽 聽 聽 endif
聽 聽NEXT

聽 聽aVar[17] := oDatos:oQryCnf:por_iva // VALOR DE TABLA config

聽 聽DEFINE DIALOG oDlg RESOURCE "FAC_COM-VTA" ;
聽 聽 聽 TITLE oDatos:cTitDlg + " - VENTAS - Facturas de Ventas" ;
聽 聽 聽 GRADIENT { { 1, nRGB( 125, 155, 175 ), nRGB( 125, 155, 175 ) } }

// EMPIEZA xBROWSE FACTURA...
聽 聽REDEFINE xBrowse oBrw ID 100 of oDlg ;
聽 聽 聽 HEADERS "CODIGO", "DESCRIPCION", "UNIDAD", "CANTIDAD", "PRECIO", "DESC", "SUB-TOTAL" ;
聽 聽 聽 COLUMNS 1, 2, 3, 4, 5, 6, 7 ;
聽 聽 聽 COLSIZES 100, 200, 70, 70, 70, 70, 70 ;
聽 聽 聽 JUSTIFY AL_LEFT, AL_LEFT, AL_LEFT, AL_RIGHT, AL_RIGHT, AL_RIGHT, AL_RIGHT ;
聽 聽 聽 PICTURES , , , "@E 9,999,999", "@E 9,999,999.99", "@E 999.99%", "@E 9,999,999.99" ;
聽 聽 聽 ARRAY aItems FASTEDIT LINES

// CONFIGURACION DEL xBROWSE
聽 聽WITH OBJECT oBrw
* 聽 聽 聽:nMarqueeStyle 聽 聽:= MARQSTYLE_HIGHLROW // NO PERMITE EDICION CELDA AUTO.
聽 聽 聽 :nMarqueeStyle 聽 聽:= MARQSTYLE_HIGHLCELL
聽 聽 聽 :nColDividerStyle := LINESTYLE_BLACK
聽 聽 聽 :nStretchCol 聽 聽 聽:= STRETCHCOL_LAST
聽 聽 聽 :bRClicked := { || msginfo( "pulsastes boton derecho..." ) } 聽// LLAMA MENU-POPUP CON BOTON DERECHO
聽 聽 聽 :lColDividerComplete := .t.
聽 聽 聽 :nHeaderHeight := 30 // ANCHO CABEZERA
聽 聽 聽 :l2007 := .t.
聽 聽 聽 :lFooter := .t.
* 聽 聽 聽:lRecordSelector := .t. // SI/NO 1RA.COL.IZQ.QUE TIENE LA FLECHITA NEGRA
聽 聽 聽 :lAllowColHiding := .f. // SI/NO BOTON DERECHO SOBRE CABEZERA, MUESTRE ARRAY COL.
聽 聽 聽 :lAllowColSwapping := .f. // SI/NO INTERCAMBIAR COL.
聽 聽 聽 :bClrStd := {|| IF( oBrw:nArrayAt % 2 == 0, {CLR_BLACK, CLR_WHITE}, {0, RGB(203, 226, 254)} ) }
聽 聽 聽 :bKeyDown := {| nKey | teclado( nKey, oBrw, aVar, aGet ) } // CONTROLA VIRTUAL KEY
***:bPastEof := { || addrow( oBrw ) } // HACE EDICION DE CELDA AUTOMATICAMENTE CON FLECHA ABAJO...
聽 聽END WITH

// COLOR GRADIANTE EN XBROWSE...
oBrw:bClrGrad := { | lInvert | IF( ! lInvert, ;
聽 聽{ { 0.710,8388608,16777215 }, ;
聽 聽{ 聽 0.710,16777215,8388608 } }, ;
聽 聽{ { 0.710,8388608,16777215 }, ;
聽 聽{ 聽 0.710,16777215,8388608 } } ) }

// COL.1 - CODIGO PRODUCTO
聽 聽WITH OBJECT oBrw:aCols[1]
聽 聽 聽 :bStrData := {|| IIF( LEN( aItems ) = 0, SPACE(10) ,;
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 aItems[oBrw:nArrayAt, 1] ) }
聽 聽 聽 :cEditPicture := "@X"
聽 聽 聽 聽 :nEditType聽 聽 := EDIT_GET_BUTTON // EDIT_GET // EDIT_GET_LISTBOX
聽 聽 聽 :bEditBlock 聽 := { || alert("Llamar maestro de Inventario") } // VALID BUTTON EN GET
聽 聽 聽 聽 :bEditValid 聽 := { | oGet, oCol | IF( !novacio( oGet:value ) , .f. ,;
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 buscacodigo( oGet, oCol, oBrw ) ) } // VALIDA ANTES DE PERDER FOCUS
聽 聽 聽 聽 :bOnPostEdit 聽:= { | oCol, xVal, nKey | IF( nKey <> VK_ESCAPE ,; // DESPUES DE LA EDICION
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 ( oCol:value := xVal ,;
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽aItems[oBrw:nArrayAt, 2] := "DESCRIPCION DEL PRODUCTO" ,;
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽oBrw:SelectCol( 4 ) ), ) } // MUEVO PUNTERO A COL(n)
聽 聽 聽 :bEditWhen 聽 聽 := {|| LEN( oBrw:aArrayData ) > 0 } // REVISAR ESTO....DA ERROR DE RANGO ARRAY....
聽 聽 聽 :bLClickHeader := { || alert("pulsaste boton izq.sobre cabecera col.") }
聽 聽 聽 :cToolTip := "usando ToolTips..."
聽 聽END WITH

// COL.2 - NOMBRE/DESCRIPCION
聽 聽WITH OBJECT oBrw:aCols[2]
聽 聽 聽 :bStrData := {|| IIF( LEN( aItems ) = 0, SPACE(10) ,;
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 aItems[oBrw:nArrayAt, 2] ) }
聽 聽 聽 :nEditType聽 聽 聽 := EDIT_BUTTON // EDIT_GET // EDIT_GET_LISTBOX
聽 聽END WITH

// COL.3 - UNIDAD
聽 聽WITH OBJECT oBrw:aCols[3]
聽 聽 聽 :bStrData 聽 聽 聽:= {|| IIF( LEN( aItems ) = 0, SPACE(10) ,;
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽aItems[oBrw:nArrayAt, 3] ) }
聽 聽 聽 :cFooter 聽 聽 聽 := "ITEMS =>"
聽 聽 聽 :nFootStrAlign := AL_RIGHT // ALINEA DATA FOOTER
聽 聽 聽 聽 :nEditType 聽 聽 := EDIT_LISTBOX
聽 聽 聽 :aEditListTxt 聽:= { "UNIDAD", "AGRU1", "AGRU2" }
聽 聽 聽 :bEditWhen 聽 聽 := {|| IF( EMPTY( aItems[oBrw:nArrayAt, 1] ), .f., .t. ) }
聽 聽 聽 聽 :bOnPostEdit 聽 := { | oCol, xVal, nKey | If( nKey <> VK_ESCAPE ,;
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽( oCol:value:= xVal, alert(xVal) ), ) }
聽 聽END WITH

// COL.4 - CANTIDAD
聽 聽WITH OBJECT oBrw:aCols[4]
聽 聽 聽 :bStrData 聽 聽 聽:= {|| IIF( LEN( aItems ) = 0, SPACE(10) ,;
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽aItems[oBrw:nArrayAt, 4] ) }
聽 聽 聽 :cEditPicture 聽:= "@E 9,999,999"
聽 聽 聽 :nFootStrAlign := AL_RIGHT // ALINEA DATA FOOTER
聽 聽 聽 :lTotal 聽 聽 聽 聽:= .t. // PARA TOTALIZAR COL.
聽 聽 聽 :nTotal 聽 聽 聽 聽:= 0 // PARA TOTALIZAR COL.
聽 聽 聽 :nFooterType 聽 := AGGR_SUM // PARA TOTALIZAR COL.
聽 聽 聽 聽 :nEditType聽 聽 聽:= EDIT_GET
聽 聽 聽 :bEditValid 聽 聽:= { | oGet, oCol | mayorqcero( oGet:value() ) }
聽 聽 聽 聽 :bOnPostEdit 聽 := { | oCol, xVal, nKey | If( nKey <> VK_ESCAPE ,;
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽( oCol:value := xVal ) , ) }
聽 聽 聽 :bEditWhen 聽 聽 := {|| !EMPTY( aItems[oBrw:nArrayAt, 1] ) }
聽 聽END WITH

// COL.5 - PVP
聽 聽WITH OBJECT oBrw:aCols[5]
聽 聽 聽 :bStrData 聽 聽 聽:= {|| IIF( LEN( aItems ) = 0, SPACE(10) ,;
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽aItems[oBrw:nArrayAt, 5] ) }
聽 聽 聽 :cEditPicture 聽:= "@E 9,999,999.99"
聽 聽 聽 :nFootStrAlign := AL_RIGHT
聽 聽 聽 聽 :nEditType聽 聽 聽:= EDIT_GET_BUTTON
聽 聽 聽 :bEditBlock 聽 := { || alert("Seleccionar Varios Precios...") }
聽 聽 聽 :bEditValid 聽 聽:= { | oGet, oCol | mayorqcero( oGet:value() ) }
聽 聽 聽 聽 :bOnPostEdit 聽 := { | oCol, xVal, nKey | If( nKey <> VK_ESCAPE ,;
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽( oCol:value := xVal ,;
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽totalinea( oBrw, aVar, aGet ) ), ) }
聽 聽 聽 :bEditWhen 聽 聽 := {|| !EMPTY( aItems[oBrw:nArrayAt, 1] ) }
聽 聽END WITH

// COL.6 - % DESCUENTO
聽 聽WITH OBJECT oBrw:aCols[6]
聽 聽 聽 :bStrData 聽 聽 := {|| IIF( LEN( aItems ) = 0, SPACE(10) ,;
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽aItems[oBrw:nArrayAt, 6] ) }
聽 聽 聽 :cFooter 聽 聽 聽:= "SUB-TOTAL=>"
聽 聽 聽 :cEditPicture := "@E 999.99 %"
聽 聽 聽 聽 :nEditType聽 聽 := EDIT_GET
聽 聽 聽 :bEditValid 聽 := { | oGet, oCol | IF( menorqcero( oGet:value() ) ,;
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 menorqcien( oGet:value() ), .f. ) }
聽 聽 聽 聽 :bOnPostEdit 聽 := { | oCol, xVal, nKey | If( nKey <> VK_ESCAPE ,;
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽( oCol:value := xVal ,;
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽totalinea( oBrw, aVar, aGet ) ,;
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽addrow( oBrw ) ) , ) }
聽 聽 聽 :bEditWhen 聽 聽:= {|| !EMPTY( aItems[oBrw:nArrayAt, 1] ) .and. ;
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽aItems[oBrw:nArrayAt, 5] > 0 }
聽 聽END WITH

// COL.7 - TOTAL LINEA
聽 聽WITH OBJECT oBrw:aCols[7]
聽 聽 聽 :bStrData 聽 聽 聽:= {|| IIF( LEN( aItems ) = 0, SPACE(10) ,;
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽aItems[oBrw:nArrayAt, 7] ) }
聽 聽 聽 :cEditPicture 聽:= "@E9,999,999.99"
聽 聽 聽 :nFootStrAlign := AL_RIGHT // ALINEA DATA FOOTER
聽 聽 聽 :lTotal 聽 聽 聽 聽:= .t. // PARA TOTALIZAR COL.
聽 聽 聽 :nTotal 聽 聽 聽 聽:= 0 // PARA TOTALIZAR COL.
聽 聽 聽 :nFooterType 聽 := AGGR_SUM 聽 // PARA TOTALIZAR COL.
聽 聽 聽 :cToolTip := "Columna 7"
聽 聽END WITH

聽 聽oBrw:MakeTotals()
聽 聽oBrw:Refresh()

// DATOS CLIENTE
聽 聽REDEFINE GET aGet[1] VAR aVar[1] ID 101 OF oDlg PICTURE "@!" UPDATE ; // COD.CLIENTE
聽 聽 聽 ACTION ( oQBtn := llamabrow( oQryCli, aVar[1], {"cli_codigo", "cli_nombre"} ,;
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽{"C贸digo", "Nombre"} ) ,;
聽 聽 聽 聽 聽 聽 聽 聽IIF( !oQBtn[1] ,;
聽 聽 聽 聽 聽 聽 聽 聽 聽 ( alert("DEBE SELECCIONAR CLIENTE o ZERO PARA CLIENTE VARIOS...") ,;
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 aVar[2] := nil, aGet[2]:REFRESH(), .f. ) ,;
聽 聽 聽 聽 聽 聽 聽 聽 聽 ( aVar[1] := oQBtn[2]:cli_codigo, aGet[1]:REFRESH() ,;
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 aVar[2] := oQBtn[2]:cli_nombre, aGet[2]:REFRESH() ,;
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 aGet[3]:SetFocus(), .t. ) ) ) ;
聽 聽 聽 VALID ( IIF( oQryCli:Seek( aVar[1], "cli_codigo" ) == 0 ,;
聽 聽 聽 聽 聽 聽 聽 聽 聽( oQBtn := llamabrow( oQryCli, aVar[1], {"cli_codigo", "cli_nombre"} ,;
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽{"C贸digo", "Nombre"} ) ,;
聽 聽 聽 聽 聽 聽 聽 聽 聽( IIF( !oQBtn[1] ,;
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 ( alert("DEBE SELECCIONAR CLIENTE o ZERO PARA CLIENTE VARIOS...") ,;
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 aVar[2] := nil, aGet[2]:REFRESH(), .f. ) ,;
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 ( aVar[1] := oQBtn[2]:cli_codigo, aGet[1]:REFRESH() ,;
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 aVar[2] := oQBtn[2]:cli_nombre, aGet[2]:REFRESH(), .t. ) ) ) ) ,;
聽 聽 聽 聽 聽 聽 聽 聽 聽( alert("ENTRO VALOR QUE EXISTE") ,;
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽aVar[1] := oQryCli:cli_codigo, aGet[1]:REFRESH() ,;
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽aVar[2] := oQryCli:cli_nombre, aGet[2]:REFRESH(), .t. ) ) )

聽 聽REDEFINE GET aGet[2] VAR aVar[2] ID 102 OF oDlg UPDATE READONLY // NOMB.CLIENTE

聽 聽REDEFINE GET aGet[3] VAR aVar[3] ID 103 OF oDlg PICTURE "@!" UPDATE ; // COD.VENDEDOR
聽 聽 聽 ACTION ( oQBtn := llamabrow( oQryVen, aVar[3], {"ven_codigo", "ven_nombres"} ,;
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽{"C贸digo", "Nombre"} ) ,;
聽 聽 聽 聽 聽 聽 聽 聽IIF( !oQBtn[1] ,;
聽 聽 聽 聽 聽 聽 聽 聽 聽 ( alert("DEBE SELECCIONAR VENDEDOR...") ,;
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 aVar[4] := nil, aGet[4]:REFRESH(), .f. ) ,;
聽 聽 聽 聽 聽 聽 聽 聽 聽 ( aVar[3] := oQBtn[2]:ven_codigo, aGet[3]:REFRESH() ,;
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 aVar[4] := ALLTRIM( oQBtn[2]:ven_nombres ) + " " + ;
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽ALLTRIM( oQBtn[2]:ven_apellidos ) ,;
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 aGet[4]:REFRESH() ,;
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 aGet[5]:SetFocus(), .t. ) ) ) ;
聽 聽 聽 VALID ( IIF( oQryVen:Seek( aVar[3], "ven_codigo" ) == 0 ,;
聽 聽 聽 聽 聽 聽 聽 聽 聽( oQBtn := llamabrow( oQryVen, aVar[3], {"ven_codigo", "ven_nombres"} ,;
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽{"C贸digo", "Nombre"} ) ,;
聽 聽 聽 聽 聽 聽 聽 聽 聽( IIF( !oQBtn[1] ,;
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 ( alert("DEBE SELECCIONAR VENDEDOR...") ,;
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 aVar[4] := nil, aGet[4]:REFRESH(), .f. ) ,;
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 ( aVar[3] := oQBtn[2]:ven_codigo, aGet[3]:REFRESH() ,;
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 aVar[4] := ALLTRIM( oQBtn[2]:ven_nombres ) + " " + ;
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽ALLTRIM( oQBtn[2]:ven_apellidos ) ,;
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 aGet[4]:REFRESH(), .t. ) ) ) ) ,;
聽 聽 聽 聽 聽 聽 聽 聽 聽( alert("ENTRO VALOR QUE EXISTE") ,;
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽aVar[3] := oQryVen:ven_codigo, aGet[3]:REFRESH() ,;
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽aVar[4] := oQryVen:ven_nombres, aGet[4]:REFRESH(), .t. ) ) )

聽 聽REDEFINE GET aGet[4] VAR aVar[4] ID 104 OF oDlg UPDATE READONLY // NOMB.VENDEDOR

聽 聽REDEFINE GET aGet[5] VAR aVar[5] ID 105 OF oDlg PICTURE "@!" UPDATE ; // COD.TRANS.
聽 聽 聽 ACTION ( oQBtn := llamabrow( oQryTrn, aVar[5], {"trn_codigo", "trn_nombre"} ,;
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽{"C贸digo", "Nombre"} ) ,;
聽 聽 聽 聽 聽 聽 聽 聽IIF( !oQBtn[1] ,;
聽 聽 聽 聽 聽 聽 聽 聽 聽 ( alert("DEBE SELECCIONAR TRANSPORTE...") ,;
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 aVar[6] := nil, aGet[6]:REFRESH(), .f. ) ,;
聽 聽 聽 聽 聽 聽 聽 聽 聽 ( aVar[5] := oQBtn[2]:trn_codigo, aGet[5]:REFRESH() ,;
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 aVar[6] := oQBtn[2]:trn_nombre, aGet[6]:REFRESH() ,;
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 aGet[7]:SetFocus(), .t. ) ) ) ;
聽 聽 聽 VALID ( IIF( oQryTrn:Seek( aVar[5], "trn_codigo" ) == 0 ,;
聽 聽 聽 聽 聽 聽 聽 聽 聽( oQBtn := llamabrow( oQryTrn, aVar[5], {"trn_codigo", "trn_nombre"} ,;
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽{"C贸digo", "Nombre"} ) ,;
聽 聽 聽 聽 聽 聽 聽 聽 聽( IIF( !oQBtn[1] ,;
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 ( alert("DEBE SELECCIONAR TRANSPORTE...") ,;
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 aVar[6] := nil, aGet[6]:REFRESH(), .f. ) ,;
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 ( aVar[5] := oQBtn[2]:trn_codigo, aGet[5]:REFRESH() ,;
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 aVar[6] := oQBtn[2]:trn_nombre, aGet[6]:REFRESH(), .t. ) ) ) ) ,;
聽 聽 聽 聽 聽 聽 聽 聽 聽( alert("ENTRO VALOR QUE EXISTE") ,;
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽aVar[5] := oQryTrn:trn_codigo, aGet[5]:REFRESH() ,;
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽aVar[6] := oQryTrn:trn_nombre, aGet[6]:REFRESH(), .t. ) ) )

聽 聽REDEFINE GET aGet[6] VAR aVar[6] ID 106 OF oDlg UPDATE READONLY // NOMB.TRANS.

聽 聽REDEFINE GET aGet[7] VAR aVar[7] MEMO ID 107 OF oDlg MULTILINE // COMENTARIOS

聽 聽REDEFINE COMBOBOX aGet[8] VAR aVar[8] ITEMS aCondi ID 108 OF oDlg UPDATE // CONDICIONES

聽 聽REDEFINE GET aGet[9] VAR aVar[9] ID 109 OF oDlg PICTURE "@E 9,999" UPDATE ; // DIAS PLAZO
聽 聽 聽 VALID( menorqcero( aVar[9] ) ) ;
聽 聽 聽 WHEN ( aVar[8] == 2 )

聽 聽REDEFINE COMBOBOX aGet[10] VAR aVar[10] ITEMS aStatus ID 110 OF oDlg UPDATE // STATUS

聽 聽REDEFINE DTPICKER aGet[11] VAR aVar[11] ID 111 OF oDlg UPDATE ; // FCH.FACT.
聽 聽 聽 VALID( IIF( !validfecha( aVar[11] ), .f. ,;
聽 聽 聽 聽 聽 聽 聽 聽 ( aVar[12] := aVar[11] + aVar[9], aGet[12]:REFRESH(), .t. ) ) )

聽 聽REDEFINE GET aGet[12] VAR aVar[12] ID 112 OF oDlg UPDATE READONLY // FCH.VENCE

聽 聽REDEFINE GET aGet[13] VAR aVar[13] ID 113 OF oDlg PICTURE "9999999999" UPDATE ; // NUM.CONTROL
聽 聽 聽 VALID( IIF( !mayorqcero( aVar[13] ), .f., ( aVar[13] := STRZERO( aVar[13], 10 ) ,;
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽aGet[13]:REFRESH() ,;
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽addrow( oBrw ), .t. ) ) )

聽 聽REDEFINE GET aGet[14] VAR aVar[14] ID 114 OF oDlg PICTURE "9999999999" UPDATE ; // NUM.FACTURA
聽 聽 聽 READONLY

// DESC. IVA Y TOTALES FACTURA
// DESCUENTOS
聽 聽REDEFINE GET aGet[15] VAR aVar[15] ID 115 OF oDlg PICTURE "@E 999.99" UPDATE ; // % DESC.SOBRE MTO.BRUTO
聽 聽 聽 VALID( IIF( aVar[15] >= 0, netopagar( aVar[18], aVar, aGet ), .t. ) )

聽 聽REDEFINE GET aGet[16] VAR aVar[16] ID 116 OF oDlg PICTURE "@E 9,999,999.99" UPDATE ; // MTO.DESC.SOBRE MTO.BRUTO
聽 聽 聽 VALID( IIF( aVar[16] >= 0, netopagar( aVar[18], aVar, aGet ), .t. ) )
// IVA
聽 聽REDEFINE GET aGet[17] VAR aVar[17] ID 117 OF oDlg PICTURE "@E 999.99" // % IVA
// TOTALES
聽 聽REDEFINE GET aGet[18] VAR aVar[18] ID 118 OF oDlg PICTURE "@E 9,999,999.99" UPDATE // MTO.SIN IVA
聽 聽REDEFINE GET aGet[19] VAR aVar[19] ID 119 OF oDlg PICTURE "@E 9,999,999.99" UPDATE // MTO.DESC.
聽 聽REDEFINE GET aGet[20] VAR aVar[20] ID 120 OF oDlg PICTURE "@E 9,999,999.99" UPDATE // MTO.IVA
聽 聽REDEFINE GET aGet[21] VAR aVar[21] ID 121 OF oDlg PICTURE "@E 9,999,999.99" UPDATE // MTO.NETO PAGAR
聽 聽REDEFINE GET aGet[22] VAR aVar[22] ID 122 OF oDlg PICTURE "@E 9,999,999.99" UPDATE // MTO.SIN IVA - MTO.DESC.
聽 聽REDEFINE GET aGet[23] VAR aVar[23] ID 123 OF oDlg PICTURE "@E 9,999,999.99" UPDATE // MTO.EXENTO(no paga imp.)

// BOTONES CUERPO FACTURA
聽 聽REDEFINE BUTTONBMP aBtn[1] ID 201 OF oDlg UPDATE ; // INC.REG.
聽 聽 聽 ACTION ( addrow( oBrw ) ) ;
聽 聽 聽 BITMAP "incluir32" PROMPT "Incluir" + CRLF + "[F2]"

聽 聽REDEFINE BUTTONBMP aBtn[2] ID 202 OF oDlg ; // MOD.REG.
聽 聽 聽 ACTION ( alert("en construccion...") ) ;//ACTION ( modrow( oBrw ) ) ;
聽 聽 聽 BITMAP "modificar32" PROMPT "Modificar" + CRLF + "[F3]" ;
聽 聽 聽 WHEN ( LEN( oBrw:aArrayData ) > 0 ) UPDATE

聽 聽REDEFINE BUTTONBMP aBtn[3] ID 203 OF oDlg ; // ELI.REG.
聽 聽 聽 ACTION ( delrow( oBrw, aVar, aGet ) ) ;
聽 聽 聽 BITMAP "eliminar32" PROMPT "E&liminar" + CRLF + "[F4]" ;
聽 聽 聽 WHEN ( LEN( oBrw:aArrayData ) > 0 ) UPDATE

聽 聽REDEFINE BUTTONBMP aBtn[4] ID 204 OF oDlg ; // BUSCAR REG.
聽 聽 聽 ACTION ( alert("buscar reg.") ) ;
聽 聽 聽 BITMAP "buscar32" PROMPT "B&uscar" + CRLF + "[F5]" ;
聽 聽 聽 WHEN ( LEN( oBrw:aArrayData ) > 0 ) UPDATE

聽 聽REDEFINE BUTTONBMP aBtn[5] ID 205 OF oDlg UPDATE ; // CANCELAR FACT.
聽 聽 聽 ACTION ( oDlg:END() ) ;
聽 聽 聽 BITMAP "Cancelar32" PROMPT "Cancelar" + CRLF + "[F6]"

聽 聽REDEFINE BUTTONBMP aBtn[6] ID 206 OF oDlg UPDATE ; // FINALIZAR FACT.
聽 聽 聽 ACTION ( alert("Fin Factura"), grabafactu( .t., .t., aVar, oBrw ), oDlg:END() ) ;
聽 聽 聽 BITMAP "finalizar32" PROMPT "&Finalizar" + CRLF + "[F7]" ;//WHEN ( aVar[21] > 0 )

聽 聽REDEFINE BUTTONBMP aBtn[7] ID 207 OF oDlg ; // IMP.RENGLONES
聽 聽 聽 ACTION ( alert("Importar renglon desde...") ) ;
聽 聽 聽 BITMAP "importar32" PROMPT "&Importar" + CRLF + "[F12]" ;
聽 聽 聽 WHEN ( LEN( oBrw:aArrayData ) > 0 ) UPDATE

聽 聽aBtn[5]:lCancel := .t.

// FIN BOTONES CUERPO FACTURA

聽 聽ACTIVATE DIALOG oDlg CENTER

聽 聽oQryCli:END(); oQryVen:END(); oQryTrn:END()

RETURN ( .t. )

STATIC FUNCTION buscacodigo( oGet, oCol, oBrw ) // BUSCO CODIGO
* 聽 ? "busco codigo..."
RETURN ( .t. )

STATIC FUNCTION addrow( oBrw ) // ADICIONO REGISTRO

聽 聽IF LEN( oBrw:aArrayData ) > 0
聽 聽 聽 oBrw:GoBottom()

聽 聽 聽 IF oBrw:aArrayData[ oBrw:nArrayAt, 7] > 0
聽 聽 聽 聽 聽AADD( oBrw:aArrayData ,;
聽 聽 聽 聽 聽 聽 聽{ , , "UNIDAD", 0, 0, 0, 0 } )
聽 聽 聽 ENDIF
聽 聽ELSE
聽 聽 聽 AADD( oBrw:aArrayData ,;
聽 聽 聽 聽 聽 { , , "UNIDAD", 0, 0, 0, 0 } )
聽 聽ENDIF

聽 聽oBrw:SetPos( , 1, ) // MUEVE PUNTO A COL.1
聽 聽oBrw:GoBottom()
聽 聽oBrw:Refresh()
聽 聽oBrw:SetFocus()

RETURN nil

STATIC FUNCTION modirow( oBrw ) // MODIFICAR REGISTRO

聽 聽oBrw:SetPos( , 1, ) // MUEVE PUNTO A COL.1
聽 聽oBrw:Refresh()
聽 聽oBrw:SetFocus()

RETURN nil

STATIC FUNCTION totalinea( oBrw, aVar, aGet ) // TOTAL POR RENGLON CON Y SIN DESC.
// TOTAL = CANTIDAD * PRECIO
聽 聽oBrw:aArrayData[oBrw:nArrayAt, 7] := ;
聽 聽 聽 聽( oBrw:aArrayData[oBrw:nArrayAt, 4] * oBrw:aArrayData[oBrw:nArrayAt, 5] )

// TOTAL = TOTAL - MTO.DESCUENTO
聽 聽oBrw:aArrayData[oBrw:nArrayAt, 7] := ;
聽 聽 聽 聽oBrw:aArrayData[oBrw:nArrayAt, 7] - ;
聽 聽 聽 聽( oBrw:aArrayData[oBrw:nArrayAt, 7] * oBrw:aArrayData[oBrw:nArrayAt, 6] / 100 )

聽 聽oBrw:MakeTotals(); oBrw:Refresh()
聽 聽netopagar( oBrw:aCols[7]:nTotal, aVar, aGet ) // CALCULA NETO PAGAR

RETURN nil

STATIC FUNCTION netopagar( nSTotal, aVar, aGet ) // CALCULA NETO PAGAR

聽 聽LOCAL nFor := 0

聽 聽aVar[18] := nSTotal // MTO.SIN IVA NI DESCUENTO
聽 聽aVar[19] := aVar[16] + ( aVar[18] * aVar[15] ) / 100 // MTO.DESCUENTO GENERAL
聽 聽aVar[22] := aVar[18] - aVar[19]
聽 聽aVar[20] := ( ( ( aVar[18]-aVar[19] ) * aVar[17] ) / 100 ) // MTO.IVA SEGUN TASA ACTIVA
聽 聽aVar[21] := ( aVar[18] - aVar[19] ) + aVar[20]

聽 聽FOR nFor := 18 TO 22
聽 聽 聽 aGet[nFor]:REFRESH()
聽 聽NEXT

RETURN ( .t. )

STATIC FUNCTION delrow( oBrw, aVar, aGet ) // ELIMINO REGISTRO

聽 聽IF LEN( oBrw:aArrayData ) == 0
聽 聽 聽 MSGINFO( "No hay Registro(s) para Eliminar...", oDatos:cTitMsg )
聽 聽 聽 RETURN nil
聽 聽ENDIF

聽 聽IF MSGNOYES( "Seguro Desea ELIMINAR el Registro: " + ;
聽 聽 聽 ALLTRIM( cValToChar( oBrw:aArrayData[oBrw:nArrayAt, 1] ) ) + " ?", oDatos:cTitMsg )
聽 聽 聽 IF oBrw:nLen > 0
聽 聽 聽 聽 聽ADEL( oBrw:aArrayData, oBrw:nArrayAt )
聽 聽 聽 聽 聽ASIZE( oBrw:aArrayData, oBrw:nLen - 1 )
聽 聽 聽 ENDIF
聽 聽ENDIF

聽 聽oBrw:GOTOP()
聽 聽oBrw:SetFocus()
聽 聽oBrw:MakeTotals()
聽 聽oBrw:Refresh()

聽 聽netopagar( oBrw:aCols[7]:nTotal, aVar, aGet ) // CALCULA NETO PAGAR

RETURN nil

FUNCTION grabafactu( lNew, lTipoVta, aVar, oBrwMFV ) // GRABO FACTURA Y CUERPO FACTURA
// lNew -> FACTURA NUEVA/MODIFICADA
// lTipoVta -> CONTROLA TIPO VTA. FACT.VTA.CON PRODUCTOS(.t.) / DOCUMENTO(.f.)
// aVar -> DATOS CABEZERA Y TOTALES DE FV.
// oBrwMFV -> MAESTRO DE FV.

聽 聽LOCAL cQryFV, cQryMFV, cQryCNF, oError ,;
聽 聽 聽 聽 聽nFor := 0, nFactura := 0

聽 聽IF aVar[21] == 0 // SI POR ALGUN MOTIVO LLEGA SIN MONTO
聽 聽 聽 alert("factura sin mto.neto...")
聽 聽 聽 RETURN .t.
聽 聽ENDIF

聽 聽oDatos:oQryCnf:REFRESH() // REFRESCO TABLA config, QUERY PUBLICO
聽 聽nFactura := oDatos:oQryCnf:num_factura
聽 聽nFactura := nFactura + 1 // DEBO HACER nFac = AL No.MAS ALTO EN config + 1

聽 聽IF oDatos:oQryCnf:LastRec() = 0 // VERIFICO SI TABLA ESTA VACIA
聽 聽 聽 cQryCNF := "INSERT INTO config SET num_factura = ' " + ClipValue2SQL( nFactura ) + "'"
聽 聽ELSE
聽 聽 聽 cQryCNF := "UPDATE config SET num_factura = ' " + ClipValue2SQL( nFactura ) + "'"
聽 聽ENDIF

聽 聽TRY
聽 聽 聽 oDatos:oConex:Execute( cQryCNF )
聽 聽CATCH oError
聽 聽 聽 MSGSTOP( oError:Description + CRLF + "Error Grabando en Tabla (config), Sentencia" + ;
聽 聽 聽 聽 聽 聽 聽 聽CRLF + CRLF + cQryCNF, oDatos:cTitMsg )
聽 聽END

聽 聽oDatos:oQryCnf:REFRESH()

聽 聽aVar[14] := nFactura // ACTUALIZO NUM.FACT.PARA GRABAR EN facturas

// GRABO FACTURA
聽 聽IF lNew
聽 聽 聽 cQryFV := "INSERT INTO facturas SET "
聽 聽 聽 cQryFV += "fac_numfac=" + ClipValue2SQL( aVar[14] ) + ","
聽 聽ELSE
聽 聽 聽 cQryFV := "UPDATE facturas SET "
聽 聽ENDIF

聽 聽cQryFV += "fac_codicli=" 聽 聽 + ClipValue2SQL( aVar[1] ) + ","
聽 聽cQryFV += "fac_nombcli=" 聽 聽 + ClipValue2SQL( aVar[2] ) + ","
聽 聽cQryFV += "fac_codiven=" 聽 聽 + ClipValue2SQL( aVar[3] ) + ","
聽 聽cQryFV += "fac_nombven=" 聽 聽 + ClipValue2SQL( aVar[4] ) + ","
聽 聽cQryFV += "fac_coditrans=" 聽 + ClipValue2SQL( aVar[5] ) + ","
聽 聽cQryFV += "fac_nombtrans=" 聽 + ClipValue2SQL( aVar[6] ) + ","
聽 聽cQryFV += "fac_comentarios=" + ClipValue2SQL( Val2Escape( aVar[7] ) ) + ","
聽 聽cQryFV += "fac_condiciones=" + ClipValue2SQL( aVar[8] ) + ","
聽 聽cQryFV += "fac_diasplazo=" 聽 + ClipValue2SQL( aVar[9] ) + ","
聽 聽cQryFV += "fac_status=" 聽 聽 聽+ ClipValue2SQL( aVar[10] ) + ","
聽 聽cQryFV += "fac_fchfac=" 聽 聽 聽+ ClipValue2SQL( aVar[11] ) + ","
聽 聽cQryFV += "fac_fchvence=" 聽 聽+ ClipValue2SQL( aVar[12] ) + ","
聽 聽cQryFV += "fac_numctrl=" 聽 聽 + ClipValue2SQL( aVar[13] ) + ","
//
聽 聽cQryFV += "fac_pordesc=" 聽 聽 + ClipValue2SQL( aVar[15] ) + ","
聽 聽cQryFV += "fac_mtodesc=" 聽 聽 + ClipValue2SQL( aVar[16] ) + ","
聽 聽cQryFV += "fac_poriva=" 聽 聽 聽+ ClipValue2SQL( aVar[17] ) + ","
聽 聽cQryFV += "fac_mtototal=" 聽 聽+ ClipValue2SQL( aVar[18] ) + ","
聽 聽cQryFV += "fac_totdesc=" 聽 聽 + ClipValue2SQL( aVar[19] ) + ","
聽 聽cQryFV += "fac_mtosobre=" 聽 聽+ ClipValue2SQL( aVar[22] ) + ","
聽 聽cQryFV += "fac_mtoiva=" 聽 聽 聽+ ClipValue2SQL( aVar[20] ) + ","
聽 聽cQryFV += "fac_mtoexento=" 聽 + ClipValue2SQL( aVar[23] ) + ","
聽 聽cQryFV += "fac_neto=" 聽 聽 聽 聽+ ClipValue2SQL( aVar[21] ) + ","
聽 聽cQryFV += "usuario=" 聽 聽 聽 聽 + ClipValue2SQL( Val2Escape( "JL" ) ) + ","
聽 聽cQryFV += "fchcrea=" 聽 聽 聽 聽 + ClipValue2SQL( DATE() )


聽 聽TRY // GRABO EN LA TABLA...
聽 聽 聽 oDatos:oConex:Execute( cQryFV )
聽 聽CATCH oError
聽 聽 聽 MSGSTOP( oError:Description + CRLF + "Error Grabando en Tabla (factura), Sentencia" + ;
聽 聽 聽 聽 聽 聽 聽 聽CRLF + CRLF + cQryFV, oDatos:cTitMsg )
聽 聽END
// FIN GRABO DATOS FACTURA / DOCUMENTO

return .t.

聽 聽IF !lTipoVta // VTA.DOCUMENTO
聽 聽 聽 RETURN .t.
聽 聽ENDIF

// GRABO CUERPO FACTURA
聽 聽IF lNew // SIEMPE ES NUEVA, SI SE USA MODIFICAR FV SE CAMBIARA
聽 聽 聽 FOR nFor := 1 TO LEN( oBrwMFV:aArrayData )
聽 聽 聽 聽 聽cQryMFV := "INSERT INTO movi_facturas SET "
聽 聽 聽 聽 聽cQryMFV += "cod_producto=" + ClipValue2SQL( oBrwMFV:aArrayData[nFor,1] ) + ","
聽 聽 聽 聽 聽cQryMFV += "nom_producto=" + ClipValue2SQL( oBrwMFV:aArrayData[nFor,2] ) + ","
聽 聽 聽 聽 聽cQryMFV += "cantidad=" + ClipValue2SQL( oBrwMFV:aArrayData[nFor,3] ) + ","
聽 聽 聽 聽 聽cQryMFV += "pvp=" + ClipValue2SQL( oBrwMFV:aArrayData[nFor,4] ) + ","
聽 聽 聽 聽 聽cQryMFV += "stotal=" + ClipValue2SQL( oBrwMFV:aArrayData[nFor,5] ) + ","
聽 聽 聽 聽 聽cQryMFV += "poriva=" + ClipValue2SQL( oDatos:oQryCnf:por_iva ) + ","
聽 聽 聽 聽 聽//
聽 聽 聽 聽 聽cQryMFV += "cedula=" + ClipValue2SQL( Val2Escape( aVar[1] ) ) + ","
聽 聽 聽 聽 聽cQryMFV += "num_inscripcion=" + ClipValue2SQL( aVar[2] ) + ","
聽 聽 聽 聽 聽cQryMFV += "num_factura=" + ClipValue2SQL( aVar[4] ) + ","
聽 聽 聽 聽 聽cQryMFV += "fch_movimiento=" + ClipValue2SQL( aVar[3] ) + ","
聽 聽 聽 聽 聽cQryMFV += "cod_asesor=" + ClipValue2SQL( Val2Escape( aVar[11] ) ) + ","
聽 聽 聽 聽 聽cQryMFV += "nom_asesor=" + ClipValue2SQL( Val2Escape( aVar[12] ) ) + ","
聽 聽 聽 聽 聽cQryMFV += "grupo=" + ClipValue2SQL( Val2Escape( aVar[14] ) ) + ","
聽 聽 聽 聽 聽//
聽 聽 聽 聽 聽cQryMFV += "usuario=" + ClipValue2SQL( 00 ) + ","
聽 聽 聽 聽 聽cQryMFV += "fchcrea=" 聽 聽+ ClipValue2SQL( DATE() ) //+ ","

聽 聽 聽 聽 聽TRY // GRABO EN LA TABLA...
聽 聽 聽 聽 聽 聽 oDatos:oConex:Execute( cQryMFV )
聽 聽 聽 聽 聽CATCH oError
聽 聽 聽 聽 聽 聽 MSGSTOP( oError:Description + CRLF + "Error Grabando en Tabla (movi_facturas), Sentencia" + ;
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽CRLF + CRLF + cQryMFV, oDatos:cTitMsg )
聽 聽 聽 聽 聽END
聽 聽 聽 NEXT
聽 聽ENDIF
// FIN GRABO CUERPO FACTURA

RETURN .t. //( aVar )

STATIC FUNCTION teclado( nKey, oBrw, aVar, aGet ) // CONTROLA TECLA PRESIONADA CUANDO xBRW TIENE FOCUS

聽 聽DO CASE
聽 聽 聽 CASE nKey == VK_DELETE .or. nKey == VK_F4 // ELIMINAR REGISTRO(Supr/F4)
聽 聽 聽 聽 聽 聽delrow( oBrw, aVar, aGet )

聽 聽 聽 CASE nKey == VK_F2 // ADICIONA REGISTRO CON TECLA DE FUNCION...
聽 聽 聽 聽 聽 聽addrow( oBrw )

聽 聽 聽 CASE nKey == VK_F3 // MODIFICAR REGISTRO CON TECLA DE FUNCION...
聽 聽 聽 聽 聽 聽modirow( oBrw )

聽 聽 聽 CASE nKey == VK_F7
聽 聽 聽 聽 聽 聽alert("F7...")
聽 聽 聽 聽 聽 聽grabafactu( .t., .t., aVar, oBrw )

聽 聽 聽 CASE nKey == VK_F12
聽 聽 聽 聽 聽 聽alert("pulso F12")

聽 聽 聽 CASE nKey == VK_F11
聽 聽 聽 聽 聽 聽alert("pulso F11")

聽 聽 聽 CASE nKey == VK_F10 聽 聽 // NO FUNCIONA
聽 聽 聽 聽 聽 聽alert("pulso F10")

聽 聽 聽 CASE nKey == VK_F9
聽 聽 聽 聽 聽 聽alert("pulso F9")

聽 聽 聽 CASE nKey == VK_F8
聽 聽 聽 聽 聽 聽alert("pulso F8")

聽 聽 聽 CASE nKey == VK_F6
聽 聽 聽 聽 聽 聽alert("pulso F6")

聽 聽 聽 CASE nKey == VK_F5
聽 聽 聽 聽 聽 聽alert("pulso F5")

聽 聽 聽 CASE nKey == VK_INSERT
聽 聽 聽 聽 聽 聽alert("insertar Reg.")

聽 聽 聽 CASE nKey == VK_DOWN
聽 聽 聽 聽 聽 聽alert("pa麓bajo")

聽 聽 聽 CASE nKey == VK_UP
聽 聽 聽 聽 聽 聽alert("pa麓rriba")

聽 聽END CASE

RETURN nil
Dios no est谩 muerto...



Gracias a mi Dios ante todo!
Posts: 53
Joined: Tue Aug 18, 2015 07:34 PM
Re: Ejemplo sencillo de factura
Posted: Wed Apr 13, 2016 02:24 PM
joseluisysturiz wrote:Saludos, aca te envio un codigo completo pero usando mysql, te servira de ejemplo y cualquier duda avisas y te ayudo adaptarlo, ya subire la imagen para q veas como se, gracias, saludos... :-)



Code (fw): Select all Collapse
#include "FiveWin.ch"
#include "XBrowse.ch"
#include "Splitter.ch"
#include "Dtpicker.ch"
#include "InKey.ch"

MEMVAR oDatos

FUNCTION mfacventas()

聽 聽LOCAL oDlg, nFor := 0, oError, oQBtn[2] ,;
聽 聽 聽 聽 聽cQryCli, oQryCli, cQryVen, oQryVen, cQryTrn, oQryTrn ,;
聽 聽 聽 聽 聽oBrw, oCol, aItems := {} ,;
聽 聽 聽 聽 聽aBtn[10], aVar[30], aGet[30] ,;
聽 聽 聽 聽 聽aCondi := { "CONTADO", "CREDITO" } ,;
聽 聽 聽 聽 聽aStatus := { "ACTIVA ", "PAGADA ", "ANULADA" }

// APERTURA DE TABLAS RELACIONADAS...
聽 聽cQryCli := "SELECT * FROM clientes ORDER BY cli_codigo ASC"
聽 聽TRY
聽 聽 聽oQryCli := TDolphinQry():New( cQryCli, oDatos:oConex )
聽 聽CATCH oError
聽 聽 聽 MSGSTOP( oError:description() + CRLF + CRLF + ;
聽 聽 聽 聽 聽 聽 聽 聽"Error Ejecuci贸n de Sentencia en Tabla(clientes): " + ;
聽 聽 聽 聽 聽 聽 聽 聽CRLF + CRLF + cQryCli, oDatos:cTitMsg )
聽 聽 聽 RETURN( NIL )
聽 聽END

聽 聽cQryVen := "SELECT * FROM vendedores ORDER BY ven_codigo ASC"

聽 聽TRY
聽 聽 聽oQryVen := TDolphinQry():New( cQryVen, oDatos:oConex )
聽 聽CATCH oError
聽 聽 聽 MSGSTOP( oError:description() + CRLF + CRLF + ;
聽 聽 聽 聽 聽 聽 聽 聽"Error Ejecuci贸n de Sentencia en Tabla(vendedores): " + ;
聽 聽 聽 聽 聽 聽 聽 聽CRLF + CRLF + cQryVen, oDatos:cTitMsg )
聽 聽 聽 RETURN( NIL )
聽 聽END

聽 聽cQryTrn := "SELECT * FROM transporte ORDER BY trn_codigo ASC"

聽 聽TRY
聽 聽 聽oQryTrn := TDolphinQry():New( cQryTrn, oDatos:oConex )
聽 聽CATCH oError
聽 聽 聽 MSGSTOP( oError:description() + CRLF + CRLF + ;
聽 聽 聽 聽 聽 聽 聽 聽"Error Ejecuci贸n de Sentencia en Tabla(transporte): " + ;
聽 聽 聽 聽 聽 聽 聽 聽CRLF + CRLF + cQryTrn, oDatos:cTitMsg )
聽 聽 聽 RETURN( NIL )
聽 聽END
// FIN APERTURA DE TABLAS RELACIONADAS...

// DEFINICION VARIABLES
聽 聽aVar[1] := SPACE(10) // COD.CLIENTE
聽 聽aVar[2] := SPACE(50) // NOMB.CLIENTE
聽 聽aVar[3] := SPACE(10) // COD.VENDEDOR
聽 聽aVar[4] := SPACE(50) // NOMB.VENDEDOR
聽 聽aVar[5] := SPACE(10) // COD.TRANS.
聽 聽aVar[6] := SPACE(50) // NOMB.TRANS.
聽 聽aVar[7] := SPACE(10) // COMENTARIOS(memo)
聽 聽aVar[8] := 1 // CONDICIONES(combo.box)
聽 聽aVar[9] := 0 // DIAS PLAZO CREDITO
聽 聽aVar[10] := 1 // ESTADO FACT.(combo.box)
聽 聽aVar[11] := DATE() // FCH.FACT.
聽 聽aVar[12] := DATE() // FCH.VENCE.
聽 聽aVar[13] := 0 // NUM.CONTROL
聽 聽aVar[14] := 0 // NUM.FACTURA

聽 聽FOR nFor := 15 TO 24 // INICIALIZO var EN CERO
聽 聽 聽 aVar[nFor] := 0.00
聽 聽 聽 if nFor == 23
聽 聽 聽 聽 聽aVar[nFor] := -700
聽 聽 聽 endif
聽 聽NEXT

聽 聽aVar[17] := oDatos:oQryCnf:por_iva // VALOR DE TABLA config

聽 聽DEFINE DIALOG oDlg RESOURCE "FAC_COM-VTA" ;
聽 聽 聽 TITLE oDatos:cTitDlg + " - VENTAS - Facturas de Ventas" ;
聽 聽 聽 GRADIENT { { 1, nRGB( 125, 155, 175 ), nRGB( 125, 155, 175 ) } }

// EMPIEZA xBROWSE FACTURA...
聽 聽REDEFINE xBrowse oBrw ID 100 of oDlg ;
聽 聽 聽 HEADERS "CODIGO", "DESCRIPCION", "UNIDAD", "CANTIDAD", "PRECIO", "DESC", "SUB-TOTAL" ;
聽 聽 聽 COLUMNS 1, 2, 3, 4, 5, 6, 7 ;
聽 聽 聽 COLSIZES 100, 200, 70, 70, 70, 70, 70 ;
聽 聽 聽 JUSTIFY AL_LEFT, AL_LEFT, AL_LEFT, AL_RIGHT, AL_RIGHT, AL_RIGHT, AL_RIGHT ;
聽 聽 聽 PICTURES , , , "@E 9,999,999", "@E 9,999,999.99", "@E 999.99%", "@E 9,999,999.99" ;
聽 聽 聽 ARRAY aItems FASTEDIT LINES

// CONFIGURACION DEL xBROWSE
聽 聽WITH OBJECT oBrw
* 聽 聽 聽:nMarqueeStyle 聽 聽:= MARQSTYLE_HIGHLROW // NO PERMITE EDICION CELDA AUTO.
聽 聽 聽 :nMarqueeStyle 聽 聽:= MARQSTYLE_HIGHLCELL
聽 聽 聽 :nColDividerStyle := LINESTYLE_BLACK
聽 聽 聽 :nStretchCol 聽 聽 聽:= STRETCHCOL_LAST
聽 聽 聽 :bRClicked := { || msginfo( "pulsastes boton derecho..." ) } 聽// LLAMA MENU-POPUP CON BOTON DERECHO
聽 聽 聽 :lColDividerComplete := .t.
聽 聽 聽 :nHeaderHeight := 30 // ANCHO CABEZERA
聽 聽 聽 :l2007 := .t.
聽 聽 聽 :lFooter := .t.
* 聽 聽 聽:lRecordSelector := .t. // SI/NO 1RA.COL.IZQ.QUE TIENE LA FLECHITA NEGRA
聽 聽 聽 :lAllowColHiding := .f. // SI/NO BOTON DERECHO SOBRE CABEZERA, MUESTRE ARRAY COL.
聽 聽 聽 :lAllowColSwapping := .f. // SI/NO INTERCAMBIAR COL.
聽 聽 聽 :bClrStd := {|| IF( oBrw:nArrayAt % 2 == 0, {CLR_BLACK, CLR_WHITE}, {0, RGB(203, 226, 254)} ) }
聽 聽 聽 :bKeyDown := {| nKey | teclado( nKey, oBrw, aVar, aGet ) } // CONTROLA VIRTUAL KEY
***:bPastEof := { || addrow( oBrw ) } // HACE EDICION DE CELDA AUTOMATICAMENTE CON FLECHA ABAJO...
聽 聽END WITH

// COLOR GRADIANTE EN XBROWSE...
oBrw:bClrGrad := { | lInvert | IF( ! lInvert, ;
聽 聽{ { 0.710,8388608,16777215 }, ;
聽 聽{ 聽 0.710,16777215,8388608 } }, ;
聽 聽{ { 0.710,8388608,16777215 }, ;
聽 聽{ 聽 0.710,16777215,8388608 } } ) }

// COL.1 - CODIGO PRODUCTO
聽 聽WITH OBJECT oBrw:aCols[1]
聽 聽 聽 :bStrData := {|| IIF( LEN( aItems ) = 0, SPACE(10) ,;
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 aItems[oBrw:nArrayAt, 1] ) }
聽 聽 聽 :cEditPicture := "@X"
聽 聽 聽 聽 :nEditType聽 聽 := EDIT_GET_BUTTON // EDIT_GET // EDIT_GET_LISTBOX
聽 聽 聽 :bEditBlock 聽 := { || alert("Llamar maestro de Inventario") } // VALID BUTTON EN GET
聽 聽 聽 聽 :bEditValid 聽 := { | oGet, oCol | IF( !novacio( oGet:value ) , .f. ,;
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 buscacodigo( oGet, oCol, oBrw ) ) } // VALIDA ANTES DE PERDER FOCUS
聽 聽 聽 聽 :bOnPostEdit 聽:= { | oCol, xVal, nKey | IF( nKey <> VK_ESCAPE ,; // DESPUES DE LA EDICION
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 ( oCol:value := xVal ,;
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽aItems[oBrw:nArrayAt, 2] := "DESCRIPCION DEL PRODUCTO" ,;
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽oBrw:SelectCol( 4 ) ), ) } // MUEVO PUNTERO A COL(n)
聽 聽 聽 :bEditWhen 聽 聽 := {|| LEN( oBrw:aArrayData ) > 0 } // REVISAR ESTO....DA ERROR DE RANGO ARRAY....
聽 聽 聽 :bLClickHeader := { || alert("pulsaste boton izq.sobre cabecera col.") }
聽 聽 聽 :cToolTip := "usando ToolTips..."
聽 聽END WITH

// COL.2 - NOMBRE/DESCRIPCION
聽 聽WITH OBJECT oBrw:aCols[2]
聽 聽 聽 :bStrData := {|| IIF( LEN( aItems ) = 0, SPACE(10) ,;
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 aItems[oBrw:nArrayAt, 2] ) }
聽 聽 聽 :nEditType聽 聽 聽 := EDIT_BUTTON // EDIT_GET // EDIT_GET_LISTBOX
聽 聽END WITH

// COL.3 - UNIDAD
聽 聽WITH OBJECT oBrw:aCols[3]
聽 聽 聽 :bStrData 聽 聽 聽:= {|| IIF( LEN( aItems ) = 0, SPACE(10) ,;
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽aItems[oBrw:nArrayAt, 3] ) }
聽 聽 聽 :cFooter 聽 聽 聽 := "ITEMS =>"
聽 聽 聽 :nFootStrAlign := AL_RIGHT // ALINEA DATA FOOTER
聽 聽 聽 聽 :nEditType 聽 聽 := EDIT_LISTBOX
聽 聽 聽 :aEditListTxt 聽:= { "UNIDAD", "AGRU1", "AGRU2" }
聽 聽 聽 :bEditWhen 聽 聽 := {|| IF( EMPTY( aItems[oBrw:nArrayAt, 1] ), .f., .t. ) }
聽 聽 聽 聽 :bOnPostEdit 聽 := { | oCol, xVal, nKey | If( nKey <> VK_ESCAPE ,;
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽( oCol:value:= xVal, alert(xVal) ), ) }
聽 聽END WITH

// COL.4 - CANTIDAD
聽 聽WITH OBJECT oBrw:aCols[4]
聽 聽 聽 :bStrData 聽 聽 聽:= {|| IIF( LEN( aItems ) = 0, SPACE(10) ,;
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽aItems[oBrw:nArrayAt, 4] ) }
聽 聽 聽 :cEditPicture 聽:= "@E 9,999,999"
聽 聽 聽 :nFootStrAlign := AL_RIGHT // ALINEA DATA FOOTER
聽 聽 聽 :lTotal 聽 聽 聽 聽:= .t. // PARA TOTALIZAR COL.
聽 聽 聽 :nTotal 聽 聽 聽 聽:= 0 // PARA TOTALIZAR COL.
聽 聽 聽 :nFooterType 聽 := AGGR_SUM // PARA TOTALIZAR COL.
聽 聽 聽 聽 :nEditType聽 聽 聽:= EDIT_GET
聽 聽 聽 :bEditValid 聽 聽:= { | oGet, oCol | mayorqcero( oGet:value() ) }
聽 聽 聽 聽 :bOnPostEdit 聽 := { | oCol, xVal, nKey | If( nKey <> VK_ESCAPE ,;
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽( oCol:value := xVal ) , ) }
聽 聽 聽 :bEditWhen 聽 聽 := {|| !EMPTY( aItems[oBrw:nArrayAt, 1] ) }
聽 聽END WITH

// COL.5 - PVP
聽 聽WITH OBJECT oBrw:aCols[5]
聽 聽 聽 :bStrData 聽 聽 聽:= {|| IIF( LEN( aItems ) = 0, SPACE(10) ,;
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽aItems[oBrw:nArrayAt, 5] ) }
聽 聽 聽 :cEditPicture 聽:= "@E 9,999,999.99"
聽 聽 聽 :nFootStrAlign := AL_RIGHT
聽 聽 聽 聽 :nEditType聽 聽 聽:= EDIT_GET_BUTTON
聽 聽 聽 :bEditBlock 聽 := { || alert("Seleccionar Varios Precios...") }
聽 聽 聽 :bEditValid 聽 聽:= { | oGet, oCol | mayorqcero( oGet:value() ) }
聽 聽 聽 聽 :bOnPostEdit 聽 := { | oCol, xVal, nKey | If( nKey <> VK_ESCAPE ,;
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽( oCol:value := xVal ,;
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽totalinea( oBrw, aVar, aGet ) ), ) }
聽 聽 聽 :bEditWhen 聽 聽 := {|| !EMPTY( aItems[oBrw:nArrayAt, 1] ) }
聽 聽END WITH

// COL.6 - % DESCUENTO
聽 聽WITH OBJECT oBrw:aCols[6]
聽 聽 聽 :bStrData 聽 聽 := {|| IIF( LEN( aItems ) = 0, SPACE(10) ,;
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽aItems[oBrw:nArrayAt, 6] ) }
聽 聽 聽 :cFooter 聽 聽 聽:= "SUB-TOTAL=>"
聽 聽 聽 :cEditPicture := "@E 999.99 %"
聽 聽 聽 聽 :nEditType聽 聽 := EDIT_GET
聽 聽 聽 :bEditValid 聽 := { | oGet, oCol | IF( menorqcero( oGet:value() ) ,;
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 menorqcien( oGet:value() ), .f. ) }
聽 聽 聽 聽 :bOnPostEdit 聽 := { | oCol, xVal, nKey | If( nKey <> VK_ESCAPE ,;
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽( oCol:value := xVal ,;
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽totalinea( oBrw, aVar, aGet ) ,;
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽addrow( oBrw ) ) , ) }
聽 聽 聽 :bEditWhen 聽 聽:= {|| !EMPTY( aItems[oBrw:nArrayAt, 1] ) .and. ;
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽aItems[oBrw:nArrayAt, 5] > 0 }
聽 聽END WITH

// COL.7 - TOTAL LINEA
聽 聽WITH OBJECT oBrw:aCols[7]
聽 聽 聽 :bStrData 聽 聽 聽:= {|| IIF( LEN( aItems ) = 0, SPACE(10) ,;
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽aItems[oBrw:nArrayAt, 7] ) }
聽 聽 聽 :cEditPicture 聽:= "@E9,999,999.99"
聽 聽 聽 :nFootStrAlign := AL_RIGHT // ALINEA DATA FOOTER
聽 聽 聽 :lTotal 聽 聽 聽 聽:= .t. // PARA TOTALIZAR COL.
聽 聽 聽 :nTotal 聽 聽 聽 聽:= 0 // PARA TOTALIZAR COL.
聽 聽 聽 :nFooterType 聽 := AGGR_SUM 聽 // PARA TOTALIZAR COL.
聽 聽 聽 :cToolTip := "Columna 7"
聽 聽END WITH

聽 聽oBrw:MakeTotals()
聽 聽oBrw:Refresh()

// DATOS CLIENTE
聽 聽REDEFINE GET aGet[1] VAR aVar[1] ID 101 OF oDlg PICTURE "@!" UPDATE ; // COD.CLIENTE
聽 聽 聽 ACTION ( oQBtn := llamabrow( oQryCli, aVar[1], {"cli_codigo", "cli_nombre"} ,;
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽{"C贸digo", "Nombre"} ) ,;
聽 聽 聽 聽 聽 聽 聽 聽IIF( !oQBtn[1] ,;
聽 聽 聽 聽 聽 聽 聽 聽 聽 ( alert("DEBE SELECCIONAR CLIENTE o ZERO PARA CLIENTE VARIOS...") ,;
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 aVar[2] := nil, aGet[2]:REFRESH(), .f. ) ,;
聽 聽 聽 聽 聽 聽 聽 聽 聽 ( aVar[1] := oQBtn[2]:cli_codigo, aGet[1]:REFRESH() ,;
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 aVar[2] := oQBtn[2]:cli_nombre, aGet[2]:REFRESH() ,;
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 aGet[3]:SetFocus(), .t. ) ) ) ;
聽 聽 聽 VALID ( IIF( oQryCli:Seek( aVar[1], "cli_codigo" ) == 0 ,;
聽 聽 聽 聽 聽 聽 聽 聽 聽( oQBtn := llamabrow( oQryCli, aVar[1], {"cli_codigo", "cli_nombre"} ,;
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽{"C贸digo", "Nombre"} ) ,;
聽 聽 聽 聽 聽 聽 聽 聽 聽( IIF( !oQBtn[1] ,;
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 ( alert("DEBE SELECCIONAR CLIENTE o ZERO PARA CLIENTE VARIOS...") ,;
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 aVar[2] := nil, aGet[2]:REFRESH(), .f. ) ,;
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 ( aVar[1] := oQBtn[2]:cli_codigo, aGet[1]:REFRESH() ,;
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 aVar[2] := oQBtn[2]:cli_nombre, aGet[2]:REFRESH(), .t. ) ) ) ) ,;
聽 聽 聽 聽 聽 聽 聽 聽 聽( alert("ENTRO VALOR QUE EXISTE") ,;
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽aVar[1] := oQryCli:cli_codigo, aGet[1]:REFRESH() ,;
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽aVar[2] := oQryCli:cli_nombre, aGet[2]:REFRESH(), .t. ) ) )

聽 聽REDEFINE GET aGet[2] VAR aVar[2] ID 102 OF oDlg UPDATE READONLY // NOMB.CLIENTE

聽 聽REDEFINE GET aGet[3] VAR aVar[3] ID 103 OF oDlg PICTURE "@!" UPDATE ; // COD.VENDEDOR
聽 聽 聽 ACTION ( oQBtn := llamabrow( oQryVen, aVar[3], {"ven_codigo", "ven_nombres"} ,;
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽{"C贸digo", "Nombre"} ) ,;
聽 聽 聽 聽 聽 聽 聽 聽IIF( !oQBtn[1] ,;
聽 聽 聽 聽 聽 聽 聽 聽 聽 ( alert("DEBE SELECCIONAR VENDEDOR...") ,;
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 aVar[4] := nil, aGet[4]:REFRESH(), .f. ) ,;
聽 聽 聽 聽 聽 聽 聽 聽 聽 ( aVar[3] := oQBtn[2]:ven_codigo, aGet[3]:REFRESH() ,;
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 aVar[4] := ALLTRIM( oQBtn[2]:ven_nombres ) + " " + ;
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽ALLTRIM( oQBtn[2]:ven_apellidos ) ,;
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 aGet[4]:REFRESH() ,;
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 aGet[5]:SetFocus(), .t. ) ) ) ;
聽 聽 聽 VALID ( IIF( oQryVen:Seek( aVar[3], "ven_codigo" ) == 0 ,;
聽 聽 聽 聽 聽 聽 聽 聽 聽( oQBtn := llamabrow( oQryVen, aVar[3], {"ven_codigo", "ven_nombres"} ,;
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽{"C贸digo", "Nombre"} ) ,;
聽 聽 聽 聽 聽 聽 聽 聽 聽( IIF( !oQBtn[1] ,;
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 ( alert("DEBE SELECCIONAR VENDEDOR...") ,;
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 aVar[4] := nil, aGet[4]:REFRESH(), .f. ) ,;
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 ( aVar[3] := oQBtn[2]:ven_codigo, aGet[3]:REFRESH() ,;
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 aVar[4] := ALLTRIM( oQBtn[2]:ven_nombres ) + " " + ;
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽ALLTRIM( oQBtn[2]:ven_apellidos ) ,;
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 aGet[4]:REFRESH(), .t. ) ) ) ) ,;
聽 聽 聽 聽 聽 聽 聽 聽 聽( alert("ENTRO VALOR QUE EXISTE") ,;
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽aVar[3] := oQryVen:ven_codigo, aGet[3]:REFRESH() ,;
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽aVar[4] := oQryVen:ven_nombres, aGet[4]:REFRESH(), .t. ) ) )

聽 聽REDEFINE GET aGet[4] VAR aVar[4] ID 104 OF oDlg UPDATE READONLY // NOMB.VENDEDOR

聽 聽REDEFINE GET aGet[5] VAR aVar[5] ID 105 OF oDlg PICTURE "@!" UPDATE ; // COD.TRANS.
聽 聽 聽 ACTION ( oQBtn := llamabrow( oQryTrn, aVar[5], {"trn_codigo", "trn_nombre"} ,;
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽{"C贸digo", "Nombre"} ) ,;
聽 聽 聽 聽 聽 聽 聽 聽IIF( !oQBtn[1] ,;
聽 聽 聽 聽 聽 聽 聽 聽 聽 ( alert("DEBE SELECCIONAR TRANSPORTE...") ,;
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 aVar[6] := nil, aGet[6]:REFRESH(), .f. ) ,;
聽 聽 聽 聽 聽 聽 聽 聽 聽 ( aVar[5] := oQBtn[2]:trn_codigo, aGet[5]:REFRESH() ,;
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 aVar[6] := oQBtn[2]:trn_nombre, aGet[6]:REFRESH() ,;
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 aGet[7]:SetFocus(), .t. ) ) ) ;
聽 聽 聽 VALID ( IIF( oQryTrn:Seek( aVar[5], "trn_codigo" ) == 0 ,;
聽 聽 聽 聽 聽 聽 聽 聽 聽( oQBtn := llamabrow( oQryTrn, aVar[5], {"trn_codigo", "trn_nombre"} ,;
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽{"C贸digo", "Nombre"} ) ,;
聽 聽 聽 聽 聽 聽 聽 聽 聽( IIF( !oQBtn[1] ,;
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 ( alert("DEBE SELECCIONAR TRANSPORTE...") ,;
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 aVar[6] := nil, aGet[6]:REFRESH(), .f. ) ,;
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 ( aVar[5] := oQBtn[2]:trn_codigo, aGet[5]:REFRESH() ,;
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 aVar[6] := oQBtn[2]:trn_nombre, aGet[6]:REFRESH(), .t. ) ) ) ) ,;
聽 聽 聽 聽 聽 聽 聽 聽 聽( alert("ENTRO VALOR QUE EXISTE") ,;
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽aVar[5] := oQryTrn:trn_codigo, aGet[5]:REFRESH() ,;
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽aVar[6] := oQryTrn:trn_nombre, aGet[6]:REFRESH(), .t. ) ) )

聽 聽REDEFINE GET aGet[6] VAR aVar[6] ID 106 OF oDlg UPDATE READONLY // NOMB.TRANS.

聽 聽REDEFINE GET aGet[7] VAR aVar[7] MEMO ID 107 OF oDlg MULTILINE // COMENTARIOS

聽 聽REDEFINE COMBOBOX aGet[8] VAR aVar[8] ITEMS aCondi ID 108 OF oDlg UPDATE // CONDICIONES

聽 聽REDEFINE GET aGet[9] VAR aVar[9] ID 109 OF oDlg PICTURE "@E 9,999" UPDATE ; // DIAS PLAZO
聽 聽 聽 VALID( menorqcero( aVar[9] ) ) ;
聽 聽 聽 WHEN ( aVar[8] == 2 )

聽 聽REDEFINE COMBOBOX aGet[10] VAR aVar[10] ITEMS aStatus ID 110 OF oDlg UPDATE // STATUS

聽 聽REDEFINE DTPICKER aGet[11] VAR aVar[11] ID 111 OF oDlg UPDATE ; // FCH.FACT.
聽 聽 聽 VALID( IIF( !validfecha( aVar[11] ), .f. ,;
聽 聽 聽 聽 聽 聽 聽 聽 ( aVar[12] := aVar[11] + aVar[9], aGet[12]:REFRESH(), .t. ) ) )

聽 聽REDEFINE GET aGet[12] VAR aVar[12] ID 112 OF oDlg UPDATE READONLY // FCH.VENCE

聽 聽REDEFINE GET aGet[13] VAR aVar[13] ID 113 OF oDlg PICTURE "9999999999" UPDATE ; // NUM.CONTROL
聽 聽 聽 VALID( IIF( !mayorqcero( aVar[13] ), .f., ( aVar[13] := STRZERO( aVar[13], 10 ) ,;
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽aGet[13]:REFRESH() ,;
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽addrow( oBrw ), .t. ) ) )

聽 聽REDEFINE GET aGet[14] VAR aVar[14] ID 114 OF oDlg PICTURE "9999999999" UPDATE ; // NUM.FACTURA
聽 聽 聽 READONLY

// DESC. IVA Y TOTALES FACTURA
// DESCUENTOS
聽 聽REDEFINE GET aGet[15] VAR aVar[15] ID 115 OF oDlg PICTURE "@E 999.99" UPDATE ; // % DESC.SOBRE MTO.BRUTO
聽 聽 聽 VALID( IIF( aVar[15] >= 0, netopagar( aVar[18], aVar, aGet ), .t. ) )

聽 聽REDEFINE GET aGet[16] VAR aVar[16] ID 116 OF oDlg PICTURE "@E 9,999,999.99" UPDATE ; // MTO.DESC.SOBRE MTO.BRUTO
聽 聽 聽 VALID( IIF( aVar[16] >= 0, netopagar( aVar[18], aVar, aGet ), .t. ) )
// IVA
聽 聽REDEFINE GET aGet[17] VAR aVar[17] ID 117 OF oDlg PICTURE "@E 999.99" // % IVA
// TOTALES
聽 聽REDEFINE GET aGet[18] VAR aVar[18] ID 118 OF oDlg PICTURE "@E 9,999,999.99" UPDATE // MTO.SIN IVA
聽 聽REDEFINE GET aGet[19] VAR aVar[19] ID 119 OF oDlg PICTURE "@E 9,999,999.99" UPDATE // MTO.DESC.
聽 聽REDEFINE GET aGet[20] VAR aVar[20] ID 120 OF oDlg PICTURE "@E 9,999,999.99" UPDATE // MTO.IVA
聽 聽REDEFINE GET aGet[21] VAR aVar[21] ID 121 OF oDlg PICTURE "@E 9,999,999.99" UPDATE // MTO.NETO PAGAR
聽 聽REDEFINE GET aGet[22] VAR aVar[22] ID 122 OF oDlg PICTURE "@E 9,999,999.99" UPDATE // MTO.SIN IVA - MTO.DESC.
聽 聽REDEFINE GET aGet[23] VAR aVar[23] ID 123 OF oDlg PICTURE "@E 9,999,999.99" UPDATE // MTO.EXENTO(no paga imp.)

// BOTONES CUERPO FACTURA
聽 聽REDEFINE BUTTONBMP aBtn[1] ID 201 OF oDlg UPDATE ; // INC.REG.
聽 聽 聽 ACTION ( addrow( oBrw ) ) ;
聽 聽 聽 BITMAP "incluir32" PROMPT "Incluir" + CRLF + "[F2]"

聽 聽REDEFINE BUTTONBMP aBtn[2] ID 202 OF oDlg ; // MOD.REG.
聽 聽 聽 ACTION ( alert("en construccion...") ) ;//ACTION ( modrow( oBrw ) ) ;
聽 聽 聽 BITMAP "modificar32" PROMPT "Modificar" + CRLF + "[F3]" ;
聽 聽 聽 WHEN ( LEN( oBrw:aArrayData ) > 0 ) UPDATE

聽 聽REDEFINE BUTTONBMP aBtn[3] ID 203 OF oDlg ; // ELI.REG.
聽 聽 聽 ACTION ( delrow( oBrw, aVar, aGet ) ) ;
聽 聽 聽 BITMAP "eliminar32" PROMPT "E&liminar" + CRLF + "[F4]" ;
聽 聽 聽 WHEN ( LEN( oBrw:aArrayData ) > 0 ) UPDATE

聽 聽REDEFINE BUTTONBMP aBtn[4] ID 204 OF oDlg ; // BUSCAR REG.
聽 聽 聽 ACTION ( alert("buscar reg.") ) ;
聽 聽 聽 BITMAP "buscar32" PROMPT "B&uscar" + CRLF + "[F5]" ;
聽 聽 聽 WHEN ( LEN( oBrw:aArrayData ) > 0 ) UPDATE

聽 聽REDEFINE BUTTONBMP aBtn[5] ID 205 OF oDlg UPDATE ; // CANCELAR FACT.
聽 聽 聽 ACTION ( oDlg:END() ) ;
聽 聽 聽 BITMAP "Cancelar32" PROMPT "Cancelar" + CRLF + "[F6]"

聽 聽REDEFINE BUTTONBMP aBtn[6] ID 206 OF oDlg UPDATE ; // FINALIZAR FACT.
聽 聽 聽 ACTION ( alert("Fin Factura"), grabafactu( .t., .t., aVar, oBrw ), oDlg:END() ) ;
聽 聽 聽 BITMAP "finalizar32" PROMPT "&Finalizar" + CRLF + "[F7]" ;//WHEN ( aVar[21] > 0 )

聽 聽REDEFINE BUTTONBMP aBtn[7] ID 207 OF oDlg ; // IMP.RENGLONES
聽 聽 聽 ACTION ( alert("Importar renglon desde...") ) ;
聽 聽 聽 BITMAP "importar32" PROMPT "&Importar" + CRLF + "[F12]" ;
聽 聽 聽 WHEN ( LEN( oBrw:aArrayData ) > 0 ) UPDATE

聽 聽aBtn[5]:lCancel := .t.

// FIN BOTONES CUERPO FACTURA

聽 聽ACTIVATE DIALOG oDlg CENTER

聽 聽oQryCli:END(); oQryVen:END(); oQryTrn:END()

RETURN ( .t. )

STATIC FUNCTION buscacodigo( oGet, oCol, oBrw ) // BUSCO CODIGO
* 聽 ? "busco codigo..."
RETURN ( .t. )

STATIC FUNCTION addrow( oBrw ) // ADICIONO REGISTRO

聽 聽IF LEN( oBrw:aArrayData ) > 0
聽 聽 聽 oBrw:GoBottom()

聽 聽 聽 IF oBrw:aArrayData[ oBrw:nArrayAt, 7] > 0
聽 聽 聽 聽 聽AADD( oBrw:aArrayData ,;
聽 聽 聽 聽 聽 聽 聽{ , , "UNIDAD", 0, 0, 0, 0 } )
聽 聽 聽 ENDIF
聽 聽ELSE
聽 聽 聽 AADD( oBrw:aArrayData ,;
聽 聽 聽 聽 聽 { , , "UNIDAD", 0, 0, 0, 0 } )
聽 聽ENDIF

聽 聽oBrw:SetPos( , 1, ) // MUEVE PUNTO A COL.1
聽 聽oBrw:GoBottom()
聽 聽oBrw:Refresh()
聽 聽oBrw:SetFocus()

RETURN nil

STATIC FUNCTION modirow( oBrw ) // MODIFICAR REGISTRO

聽 聽oBrw:SetPos( , 1, ) // MUEVE PUNTO A COL.1
聽 聽oBrw:Refresh()
聽 聽oBrw:SetFocus()

RETURN nil

STATIC FUNCTION totalinea( oBrw, aVar, aGet ) // TOTAL POR RENGLON CON Y SIN DESC.
// TOTAL = CANTIDAD * PRECIO
聽 聽oBrw:aArrayData[oBrw:nArrayAt, 7] := ;
聽 聽 聽 聽( oBrw:aArrayData[oBrw:nArrayAt, 4] * oBrw:aArrayData[oBrw:nArrayAt, 5] )

// TOTAL = TOTAL - MTO.DESCUENTO
聽 聽oBrw:aArrayData[oBrw:nArrayAt, 7] := ;
聽 聽 聽 聽oBrw:aArrayData[oBrw:nArrayAt, 7] - ;
聽 聽 聽 聽( oBrw:aArrayData[oBrw:nArrayAt, 7] * oBrw:aArrayData[oBrw:nArrayAt, 6] / 100 )

聽 聽oBrw:MakeTotals(); oBrw:Refresh()
聽 聽netopagar( oBrw:aCols[7]:nTotal, aVar, aGet ) // CALCULA NETO PAGAR

RETURN nil

STATIC FUNCTION netopagar( nSTotal, aVar, aGet ) // CALCULA NETO PAGAR

聽 聽LOCAL nFor := 0

聽 聽aVar[18] := nSTotal // MTO.SIN IVA NI DESCUENTO
聽 聽aVar[19] := aVar[16] + ( aVar[18] * aVar[15] ) / 100 // MTO.DESCUENTO GENERAL
聽 聽aVar[22] := aVar[18] - aVar[19]
聽 聽aVar[20] := ( ( ( aVar[18]-aVar[19] ) * aVar[17] ) / 100 ) // MTO.IVA SEGUN TASA ACTIVA
聽 聽aVar[21] := ( aVar[18] - aVar[19] ) + aVar[20]

聽 聽FOR nFor := 18 TO 22
聽 聽 聽 aGet[nFor]:REFRESH()
聽 聽NEXT

RETURN ( .t. )

STATIC FUNCTION delrow( oBrw, aVar, aGet ) // ELIMINO REGISTRO

聽 聽IF LEN( oBrw:aArrayData ) == 0
聽 聽 聽 MSGINFO( "No hay Registro(s) para Eliminar...", oDatos:cTitMsg )
聽 聽 聽 RETURN nil
聽 聽ENDIF

聽 聽IF MSGNOYES( "Seguro Desea ELIMINAR el Registro: " + ;
聽 聽 聽 ALLTRIM( cValToChar( oBrw:aArrayData[oBrw:nArrayAt, 1] ) ) + " ?", oDatos:cTitMsg )
聽 聽 聽 IF oBrw:nLen > 0
聽 聽 聽 聽 聽ADEL( oBrw:aArrayData, oBrw:nArrayAt )
聽 聽 聽 聽 聽ASIZE( oBrw:aArrayData, oBrw:nLen - 1 )
聽 聽 聽 ENDIF
聽 聽ENDIF

聽 聽oBrw:GOTOP()
聽 聽oBrw:SetFocus()
聽 聽oBrw:MakeTotals()
聽 聽oBrw:Refresh()

聽 聽netopagar( oBrw:aCols[7]:nTotal, aVar, aGet ) // CALCULA NETO PAGAR

RETURN nil

FUNCTION grabafactu( lNew, lTipoVta, aVar, oBrwMFV ) // GRABO FACTURA Y CUERPO FACTURA
// lNew -> FACTURA NUEVA/MODIFICADA
// lTipoVta -> CONTROLA TIPO VTA. FACT.VTA.CON PRODUCTOS(.t.) / DOCUMENTO(.f.)
// aVar -> DATOS CABEZERA Y TOTALES DE FV.
// oBrwMFV -> MAESTRO DE FV.

聽 聽LOCAL cQryFV, cQryMFV, cQryCNF, oError ,;
聽 聽 聽 聽 聽nFor := 0, nFactura := 0

聽 聽IF aVar[21] == 0 // SI POR ALGUN MOTIVO LLEGA SIN MONTO
聽 聽 聽 alert("factura sin mto.neto...")
聽 聽 聽 RETURN .t.
聽 聽ENDIF

聽 聽oDatos:oQryCnf:REFRESH() // REFRESCO TABLA config, QUERY PUBLICO
聽 聽nFactura := oDatos:oQryCnf:num_factura
聽 聽nFactura := nFactura + 1 // DEBO HACER nFac = AL No.MAS ALTO EN config + 1

聽 聽IF oDatos:oQryCnf:LastRec() = 0 // VERIFICO SI TABLA ESTA VACIA
聽 聽 聽 cQryCNF := "INSERT INTO config SET num_factura = ' " + ClipValue2SQL( nFactura ) + "'"
聽 聽ELSE
聽 聽 聽 cQryCNF := "UPDATE config SET num_factura = ' " + ClipValue2SQL( nFactura ) + "'"
聽 聽ENDIF

聽 聽TRY
聽 聽 聽 oDatos:oConex:Execute( cQryCNF )
聽 聽CATCH oError
聽 聽 聽 MSGSTOP( oError:Description + CRLF + "Error Grabando en Tabla (config), Sentencia" + ;
聽 聽 聽 聽 聽 聽 聽 聽CRLF + CRLF + cQryCNF, oDatos:cTitMsg )
聽 聽END

聽 聽oDatos:oQryCnf:REFRESH()

聽 聽aVar[14] := nFactura // ACTUALIZO NUM.FACT.PARA GRABAR EN facturas

// GRABO FACTURA
聽 聽IF lNew
聽 聽 聽 cQryFV := "INSERT INTO facturas SET "
聽 聽 聽 cQryFV += "fac_numfac=" + ClipValue2SQL( aVar[14] ) + ","
聽 聽ELSE
聽 聽 聽 cQryFV := "UPDATE facturas SET "
聽 聽ENDIF

聽 聽cQryFV += "fac_codicli=" 聽 聽 + ClipValue2SQL( aVar[1] ) + ","
聽 聽cQryFV += "fac_nombcli=" 聽 聽 + ClipValue2SQL( aVar[2] ) + ","
聽 聽cQryFV += "fac_codiven=" 聽 聽 + ClipValue2SQL( aVar[3] ) + ","
聽 聽cQryFV += "fac_nombven=" 聽 聽 + ClipValue2SQL( aVar[4] ) + ","
聽 聽cQryFV += "fac_coditrans=" 聽 + ClipValue2SQL( aVar[5] ) + ","
聽 聽cQryFV += "fac_nombtrans=" 聽 + ClipValue2SQL( aVar[6] ) + ","
聽 聽cQryFV += "fac_comentarios=" + ClipValue2SQL( Val2Escape( aVar[7] ) ) + ","
聽 聽cQryFV += "fac_condiciones=" + ClipValue2SQL( aVar[8] ) + ","
聽 聽cQryFV += "fac_diasplazo=" 聽 + ClipValue2SQL( aVar[9] ) + ","
聽 聽cQryFV += "fac_status=" 聽 聽 聽+ ClipValue2SQL( aVar[10] ) + ","
聽 聽cQryFV += "fac_fchfac=" 聽 聽 聽+ ClipValue2SQL( aVar[11] ) + ","
聽 聽cQryFV += "fac_fchvence=" 聽 聽+ ClipValue2SQL( aVar[12] ) + ","
聽 聽cQryFV += "fac_numctrl=" 聽 聽 + ClipValue2SQL( aVar[13] ) + ","
//
聽 聽cQryFV += "fac_pordesc=" 聽 聽 + ClipValue2SQL( aVar[15] ) + ","
聽 聽cQryFV += "fac_mtodesc=" 聽 聽 + ClipValue2SQL( aVar[16] ) + ","
聽 聽cQryFV += "fac_poriva=" 聽 聽 聽+ ClipValue2SQL( aVar[17] ) + ","
聽 聽cQryFV += "fac_mtototal=" 聽 聽+ ClipValue2SQL( aVar[18] ) + ","
聽 聽cQryFV += "fac_totdesc=" 聽 聽 + ClipValue2SQL( aVar[19] ) + ","
聽 聽cQryFV += "fac_mtosobre=" 聽 聽+ ClipValue2SQL( aVar[22] ) + ","
聽 聽cQryFV += "fac_mtoiva=" 聽 聽 聽+ ClipValue2SQL( aVar[20] ) + ","
聽 聽cQryFV += "fac_mtoexento=" 聽 + ClipValue2SQL( aVar[23] ) + ","
聽 聽cQryFV += "fac_neto=" 聽 聽 聽 聽+ ClipValue2SQL( aVar[21] ) + ","
聽 聽cQryFV += "usuario=" 聽 聽 聽 聽 + ClipValue2SQL( Val2Escape( "JL" ) ) + ","
聽 聽cQryFV += "fchcrea=" 聽 聽 聽 聽 + ClipValue2SQL( DATE() )


聽 聽TRY // GRABO EN LA TABLA...
聽 聽 聽 oDatos:oConex:Execute( cQryFV )
聽 聽CATCH oError
聽 聽 聽 MSGSTOP( oError:Description + CRLF + "Error Grabando en Tabla (factura), Sentencia" + ;
聽 聽 聽 聽 聽 聽 聽 聽CRLF + CRLF + cQryFV, oDatos:cTitMsg )
聽 聽END
// FIN GRABO DATOS FACTURA / DOCUMENTO

return .t.

聽 聽IF !lTipoVta // VTA.DOCUMENTO
聽 聽 聽 RETURN .t.
聽 聽ENDIF

// GRABO CUERPO FACTURA
聽 聽IF lNew // SIEMPE ES NUEVA, SI SE USA MODIFICAR FV SE CAMBIARA
聽 聽 聽 FOR nFor := 1 TO LEN( oBrwMFV:aArrayData )
聽 聽 聽 聽 聽cQryMFV := "INSERT INTO movi_facturas SET "
聽 聽 聽 聽 聽cQryMFV += "cod_producto=" + ClipValue2SQL( oBrwMFV:aArrayData[nFor,1] ) + ","
聽 聽 聽 聽 聽cQryMFV += "nom_producto=" + ClipValue2SQL( oBrwMFV:aArrayData[nFor,2] ) + ","
聽 聽 聽 聽 聽cQryMFV += "cantidad=" + ClipValue2SQL( oBrwMFV:aArrayData[nFor,3] ) + ","
聽 聽 聽 聽 聽cQryMFV += "pvp=" + ClipValue2SQL( oBrwMFV:aArrayData[nFor,4] ) + ","
聽 聽 聽 聽 聽cQryMFV += "stotal=" + ClipValue2SQL( oBrwMFV:aArrayData[nFor,5] ) + ","
聽 聽 聽 聽 聽cQryMFV += "poriva=" + ClipValue2SQL( oDatos:oQryCnf:por_iva ) + ","
聽 聽 聽 聽 聽//
聽 聽 聽 聽 聽cQryMFV += "cedula=" + ClipValue2SQL( Val2Escape( aVar[1] ) ) + ","
聽 聽 聽 聽 聽cQryMFV += "num_inscripcion=" + ClipValue2SQL( aVar[2] ) + ","
聽 聽 聽 聽 聽cQryMFV += "num_factura=" + ClipValue2SQL( aVar[4] ) + ","
聽 聽 聽 聽 聽cQryMFV += "fch_movimiento=" + ClipValue2SQL( aVar[3] ) + ","
聽 聽 聽 聽 聽cQryMFV += "cod_asesor=" + ClipValue2SQL( Val2Escape( aVar[11] ) ) + ","
聽 聽 聽 聽 聽cQryMFV += "nom_asesor=" + ClipValue2SQL( Val2Escape( aVar[12] ) ) + ","
聽 聽 聽 聽 聽cQryMFV += "grupo=" + ClipValue2SQL( Val2Escape( aVar[14] ) ) + ","
聽 聽 聽 聽 聽//
聽 聽 聽 聽 聽cQryMFV += "usuario=" + ClipValue2SQL( 00 ) + ","
聽 聽 聽 聽 聽cQryMFV += "fchcrea=" 聽 聽+ ClipValue2SQL( DATE() ) //+ ","

聽 聽 聽 聽 聽TRY // GRABO EN LA TABLA...
聽 聽 聽 聽 聽 聽 oDatos:oConex:Execute( cQryMFV )
聽 聽 聽 聽 聽CATCH oError
聽 聽 聽 聽 聽 聽 MSGSTOP( oError:Description + CRLF + "Error Grabando en Tabla (movi_facturas), Sentencia" + ;
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽CRLF + CRLF + cQryMFV, oDatos:cTitMsg )
聽 聽 聽 聽 聽END
聽 聽 聽 NEXT
聽 聽ENDIF
// FIN GRABO CUERPO FACTURA

RETURN .t. //( aVar )

STATIC FUNCTION teclado( nKey, oBrw, aVar, aGet ) // CONTROLA TECLA PRESIONADA CUANDO xBRW TIENE FOCUS

聽 聽DO CASE
聽 聽 聽 CASE nKey == VK_DELETE .or. nKey == VK_F4 // ELIMINAR REGISTRO(Supr/F4)
聽 聽 聽 聽 聽 聽delrow( oBrw, aVar, aGet )

聽 聽 聽 CASE nKey == VK_F2 // ADICIONA REGISTRO CON TECLA DE FUNCION...
聽 聽 聽 聽 聽 聽addrow( oBrw )

聽 聽 聽 CASE nKey == VK_F3 // MODIFICAR REGISTRO CON TECLA DE FUNCION...
聽 聽 聽 聽 聽 聽modirow( oBrw )

聽 聽 聽 CASE nKey == VK_F7
聽 聽 聽 聽 聽 聽alert("F7...")
聽 聽 聽 聽 聽 聽grabafactu( .t., .t., aVar, oBrw )

聽 聽 聽 CASE nKey == VK_F12
聽 聽 聽 聽 聽 聽alert("pulso F12")

聽 聽 聽 CASE nKey == VK_F11
聽 聽 聽 聽 聽 聽alert("pulso F11")

聽 聽 聽 CASE nKey == VK_F10 聽 聽 // NO FUNCIONA
聽 聽 聽 聽 聽 聽alert("pulso F10")

聽 聽 聽 CASE nKey == VK_F9
聽 聽 聽 聽 聽 聽alert("pulso F9")

聽 聽 聽 CASE nKey == VK_F8
聽 聽 聽 聽 聽 聽alert("pulso F8")

聽 聽 聽 CASE nKey == VK_F6
聽 聽 聽 聽 聽 聽alert("pulso F6")

聽 聽 聽 CASE nKey == VK_F5
聽 聽 聽 聽 聽 聽alert("pulso F5")

聽 聽 聽 CASE nKey == VK_INSERT
聽 聽 聽 聽 聽 聽alert("insertar Reg.")

聽 聽 聽 CASE nKey == VK_DOWN
聽 聽 聽 聽 聽 聽alert("pa麓bajo")

聽 聽 聽 CASE nKey == VK_UP
聽 聽 聽 聽 聽 聽alert("pa麓rriba")

聽 聽END CASE

RETURN nil


Buenos dias gracias mi estimado Jose Luis,no conozco esos comandos me parece como de sql,y es parecido a lo que pueda adaptar a mi base de datos dbf?

solo quiero controlar numero de folio y fecha desde encabezado y de ahi agregar nuevos registros a mi browse que vaya alimentando informacion y con los botones de nuevo registro, modificar registro y eliminar, estudiare su codigo y aplicarlo a mi sistema .

Gracias y saludos Jose Luis
Rosa
Posts: 2064
Joined: Fri Jan 06, 2006 09:28 PM
Re: Ejemplo sencillo de factura
Posted: Wed Apr 13, 2016 03:54 PM

Buen dia Rosa, estas en lo cierto, como te dije en mi primer comentario uso es MYSQL, pero la logica de trabajo es la misma, solo debes usar tus comando para DBF, alli controlo numero de documento, busqueda de cliente y el AME de los items a facturar Agregar, Modificar, Eliminar(AME), espero te sirva de incio y cualquier duda, estoy a la orden...saludos... :shock:

Dios no est谩 muerto...



Gracias a mi Dios ante todo!
Posts: 53
Joined: Tue Aug 18, 2015 07:34 PM
Re: Ejemplo sencillo de factura
Posted: Wed Apr 13, 2016 05:01 PM
joseluisysturiz wrote:Buen dia Rosa, estas en lo cierto, como te dije en mi primer comentario uso es MYSQL, pero la logica de trabajo es la misma, solo debes usar tus comando para DBF, alli controlo numero de documento, busqueda de cliente y el AME de los items a facturar Agregar, Modificar, Eliminar(AME), espero te sirva de incio y cualquier duda, estoy a la orden...saludos... :-)



Gracias mi estimado Jose Luis,voy lenta entendiendo tu codigo fuente y escribirlo en una hoja de trabajo para entenderlo mas claro que debo o que no debo hacer en el boton de agregar no veo la logica de si es nuevo registro que la logica sea asi

if agrenuevo registro si es verdadero o falso
append()
endif

pero si es modificar desde donde o como ejecutar si es falso desde browse al darle enter o desde botones de modificar registro en eliminar espero no sea problema mi duda son esos dos botones como seria su comportamiento agregar y modificar,algo medio confuso pero voy anotando en mi cuadernillo y transcribir en mi archivo prg.

gracias y saludos
su amiga Rosa
Posts: 53
Joined: Tue Aug 18, 2015 07:34 PM
Re: Ejemplo sencillo de factura
Posted: Wed Apr 13, 2016 05:36 PM
Rosita wrote:
joseluisysturiz wrote:Buen dia Rosa, estas en lo cierto, como te dije en mi primer comentario uso es MYSQL, pero la logica de trabajo es la misma, solo debes usar tus comando para DBF, alli controlo numero de documento, busqueda de cliente y el AME de los items a facturar Agregar, Modificar, Eliminar(AME), espero te sirva de incio y cualquier duda, estoy a la orden...saludos... :-)



Gracias mi estimado Jose Luis,voy lenta entendiendo tu codigo fuente y escribirlo en una hoja de trabajo para entenderlo mas claro que debo o que no debo hacer en el boton de agregar no veo la logica de si es nuevo registro que la logica sea asi

if agrenuevo registro si es verdadero o falso
append()
endif

pero si es modificar desde donde o como ejecutar si es falso desde browse al darle enter o desde botones de modificar registro en eliminar espero no sea problema mi duda son esos dos botones como seria su comportamiento agregar y modificar,algo medio confuso pero voy anotando en mi cuadernillo y transcribir en mi archivo prg.
Que programa me recomiendan para crear mi pantalla de recursos como el que tienes Jose Luis

gracias y saludos
su amiga Rosa
Posts: 53
Joined: Tue Aug 18, 2015 07:34 PM
Re: Ejemplo sencillo de factura
Posted: Wed Apr 13, 2016 06:14 PM
Rosita wrote:
Rosita wrote:
joseluisysturiz wrote:Buen dia Rosa, estas en lo cierto, como te dije en mi primer comentario uso es MYSQL, pero la logica de trabajo es la misma, solo debes usar tus comando para DBF, alli controlo numero de documento, busqueda de cliente y el AME de los items a facturar Agregar, Modificar, Eliminar(AME), espero te sirva de incio y cualquier duda, estoy a la orden...saludos... :-)



Gracias mi estimado Jose Luis,voy lenta entendiendo tu codigo fuente y escribirlo en una hoja de trabajo para entenderlo mas claro que debo o que no debo hacer en el boton de agregar no veo la logica de si es nuevo registro que la logica sea asi

if agrenuevo registro si es verdadero o falso
append()
endif

pero si es modificar desde donde o como ejecutar si es falso desde browse al darle enter o desde botones de modificar registro en eliminar espero no sea problema mi duda son esos dos botones como seria su comportamiento agregar y modificar,algo medio confuso pero voy anotando en mi cuadernillo y transcribir en mi archivo prg.
Que programa me recomiendan para crear mi pantalla de recursos como el que tienes Jose Luis

gracias y saludos
su amiga Rosa


Que programa me recomiendan para crear mi pantalla de recursos como el que tienes Jose Luis
jajajaja mi estimado Jose Luis aun no me queda claroo, por lo que entiendo agregas tus registros pero a modo de edicion del browser amigo???
Dos a mi modo de editar desde boton de agregar registros puedo llamar a un dialogo y editar los campos de detalle a capturar y agregarme en mi browser o no se puede y a fuerza tiene que ser desde modo edicion de browse o como seria desde dialogo de detalle a editar mis campsos y luego grabarlo mi registros estyoy algo confundida :-) :-) por favor echenle la mano :-)

gracias saludos
Rosa
Posts: 2064
Joined: Fri Jan 06, 2006 09:28 PM
Re: Ejemplo sencillo de factura
Posted: Thu Apr 14, 2016 02:04 AM

Rosa, uso el editor de recurso PELLES C que es totalmente gratuito como muchos otro y muy facil de manejar.
En relacion al manejo de los registros puedes usar varias formas:
- edicion directa en el xbrose, para mi lamas comoda, rapida y menos codigo
- llamando un dialogo donde solicites y modifiques los registros, codigo, monto, precio, etc.
- creando encima del xbrowse GET con codigo, nombre, cantidad, precio, etc...para evitar el llamado de otro DLG

dime cual te parec mejor y te doy un sample de dise帽o, saludos... :shock:

skype: joseluisy

joseluisysturiz@yahoo.com

Dios no est谩 muerto...



Gracias a mi Dios ante todo!
Posts: 2064
Joined: Fri Jan 06, 2006 09:28 PM
Re: Ejemplo sencillo de factura
Posted: Thu Apr 14, 2016 02:21 AM
Rosita wrote:
joseluisysturiz wrote:Buen dia Rosa, estas en lo cierto, como te dije en mi primer comentario uso es MYSQL, pero la logica de trabajo es la misma, solo debes usar tus comando para DBF, alli controlo numero de documento, busqueda de cliente y el AME de los items a facturar Agregar, Modificar, Eliminar(AME), espero te sirva de incio y cualquier duda, estoy a la orden...saludos... :-)



Gracias mi estimado Jose Luis,voy lenta entendiendo tu codigo fuente y escribirlo en una hoja de trabajo para entenderlo mas claro que debo o que no debo hacer en el boton de agregar no veo la logica de si es nuevo registro que la logica sea asi

if agrenuevo registro si es verdadero o falso
append()
endif

pero si es modificar desde donde o como ejecutar si es falso desde browse al darle enter o desde botones de modificar registro en eliminar espero no sea problema mi duda son esos dos botones como seria su comportamiento agregar y modificar,algo medio confuso pero voy anotando en mi cuadernillo y transcribir en mi archivo prg.

gracias y saludos
su amiga Rosa

Tratare explicarte de la manera mas sencilla q es lo q hago en AGREGAR/MODIFICAR, en mi caso como hago la edicion directa en el xbrowse hago todo el trabajo en un array y no hay gran cosa q hacer y para mi es mas facil...si usas un DLG editando el registro, cuando agregar digamos es facil, solo agregar un registro al array usando AADD(), cuando modificas un registro, entonces lees los datos del xbrowse y los llevas a los get, como el codigo del producto y nombre no deberian cambiar...esos campos los validas con un WHEN, alli es donde entra en juego los de una VAR logica, si es .t., es un registro nuevo y si es .f. entonces es una modificacion, el punto esta que si modificas algun valor del registro en modificacion, llamese cantidad o precio, entonces deberias eliminar del array el registro que editastes y luego agregas el mismo pero con los nuevos valores...espero no haberte confundido mas, o si algun otro colega tenga alguna explicacion o forma de hacerlo mas facil y/o comodo, sigo a la orden, saludos... :-)

Post Data: de donde eres..? si no es imprudente la pregunta, gracias.
Dios no est谩 muerto...



Gracias a mi Dios ante todo!
Posts: 53
Joined: Tue Aug 18, 2015 07:34 PM
Re: Ejemplo sencillo de factura
Posted: Thu Apr 14, 2016 02:38 AM
joseluisysturiz wrote:
Rosita wrote:
joseluisysturiz wrote:Buen dia Rosa, estas en lo cierto, como te dije en mi primer comentario uso es MYSQL, pero la logica de trabajo es la misma, solo debes usar tus comando para DBF, alli controlo numero de documento, busqueda de cliente y el AME de los items a facturar Agregar, Modificar, Eliminar(AME), espero te sirva de incio y cualquier duda, estoy a la orden...saludos... :-)



Gracias mi estimado Jose Luis,voy lenta entendiendo tu codigo fuente y escribirlo en una hoja de trabajo para entenderlo mas claro que debo o que no debo hacer en el boton de agregar no veo la logica de si es nuevo registro que la logica sea asi

if agrenuevo registro si es verdadero o falso
append()
endif

pero si es modificar desde donde o como ejecutar si es falso desde browse al darle enter o desde botones de modificar registro en eliminar espero no sea problema mi duda son esos dos botones como seria su comportamiento agregar y modificar,algo medio confuso pero voy anotando en mi cuadernillo y transcribir en mi archivo prg.

gracias y saludos
su amiga Rosa

Tratare explicarte de la manera mas sencilla q es lo q hago en AGREGAR/MODIFICAR, en mi caso como hago la edicion directa en el xbrowse hago todo el trabajo en un array y no hay gran cosa q hacer y para mi es mas facil...si usas un DLG editando el registro, cuando agregar digamos es facil, solo agregar un registro al array usando AADD(), cuando modificas un registro, entonces lees los datos del xbrowse y los llevas a los get, como el codigo del producto y nombre no deberian cambiar...esos campos los validas con un WHEN, alli es donde entra en juego los de una VAR logica, si es .t., es un registro nuevo y si es .f. entonces es una modificacion, el punto esta que si modificas algun valor del registro en modificacion, llamese cantidad o precio, entonces deberias eliminar del array el registro que editastes y luego agregas el mismo pero con los nuevos valores...espero no haberte confundido mas, o si algun otro colega tenga alguna explicacion o forma de hacerlo mas facil y/o comodo, sigo a la orden, saludos... :-)

Post Data: de donde eres..? si no es imprudente la pregunta, gracias.


Hola buenas noches muy amable en responder a mis dudas y inquietudes y por tu apreciable ayuda Jose Luis,he estado mirando en el foro y leo y releo que es facil codificar xbrowse con arrays pero como todavia soy muy nueva en este lenguaje aun no tengo la suficiente capacidad de crearlo aunque no parece dificil pero algo para entenderle el codigo a desarrollar y por ahora no quiero entrar a modo de edicion directa,solo necesito a modo de dialogo desde el boton de agregar nuevo registro y modificar registro al igual a modo de dialogo y no encontre nada parecido en el foro, solo edicion directa y con qry sql y no en dbf,ustedes ya tienen un buen abance y experiencias en sus proyectos,pero espero poder hacerlo a modo de dialogo y cual seria recomendadle con arras o directo en dbf y sus ventajas y desventajas y como se guardaria el contenido en un array son muchas cosas que aun no logro entenderle mas claro

gracias saludos
Rosa
Posts: 2064
Joined: Fri Jan 06, 2006 09:28 PM
Re: Ejemplo sencillo de factura
Posted: Thu Apr 14, 2016 06:07 PM
Aca te mando otra forma de como lo hago en otro sistema sin ser edicion directa en xbrowse...saludos.. :-)

Code (fw): Select all Collapse
PROCEDURE factura()

// DEFINICION BROWSE
聽 聽oBrw := TXBrowse():New( oDlg )

聽 聽WITH OBJECT oBrw
聽 聽 聽 :nMarqueeStyle 聽 聽:= MARQSTYLE_HIGHLROW
聽 聽 聽 :nColDividerStyle := LINESTYLE_BLACK
聽 聽 聽 :lAllowColSwapping := .f.
聽 聽 聽 :lAllowColHiding := .f.
聽 聽 聽 :lColDividerComplete := .t.
聽 聽 聽 :nHeaderHeight := 30
聽 聽 聽 :l2007 := .t.
聽 聽 聽 :lFooter := .t.
聽 聽 聽 :lRecordSelector := .t.
聽 聽 聽 :bClrStd := {|| IF( oBrw:nArrayAt % 2 == 0, {CLR_BLACK, CLR_WHITE} ,;
聽 聽 聽 聽 聽{0, RGB(203, 226, 254)} ) }
聽 聽END WITH
//
聽 聽oCol := oBrw:AddCol()
聽 聽oCol:cHeader 聽 聽 聽 := "C贸digo"
聽 聽oCol:nWidth 聽 聽 聽 聽:= 70
聽 聽oCol:bStrData 聽 聽 聽:= {|| IIF( LEN( aProductos ) == 0, SPACE(10) ,;
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 aProductos[oBrw:nArrayAt, 1] ) }
聽 聽oCol:nHeadStrAlign := AL_CENTER
聽 聽oCol:nDataStrAlign := AL_LEFT
聽 聽oCol:nArrayCol := 1
//
聽 聽oCol := oBrw:AddCol()
聽 聽oCol:cHeader 聽 聽 聽 := "Descripci贸n"
聽 聽oCol:nWidth 聽 聽 聽 聽:= 350
聽 聽oCol:bStrData 聽 聽 聽:= {|| IIF( LEN( aProductos ) == 0, SPACE(10) ,;
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 aProductos[oBrw:nArrayAt, 2] ) }
聽 聽oCol:nHeadStrAlign := AL_CENTER
聽 聽oCol:nDataStrAlign := AL_LEFT
聽 聽oCol:nArrayCol := 2
//
聽 聽oCol := oBrw:AddCol()
聽 聽oCol:cHeader 聽 聽 聽 := "Cantidad"
聽 聽oCol:nWidth 聽 聽 聽 聽:= 50
聽 聽oCol:bStrData 聽 聽 聽:= {|| IIF( LEN( aProductos ) == 0, SPACE(10) ,;
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 aProductos[oBrw:nArrayAt, 3] ) }
聽 聽oCol:nHeadStrAlign := AL_CENTER
聽 聽oCol:nDataStrAlign := AL_RIGHT
聽 聽oCol:nArrayCol := 3
//
聽 聽oCol := oBrw:AddCol()
聽 聽oCol:cHeader 聽 聽 聽 := "Precio Unitario"
聽 聽oCol:nWidth 聽 聽 聽 聽 := 100
聽 聽oCol:bStrData 聽 聽 聽:= {|| IIF( LEN( aProductos ) == 0, SPACE(10) ,;
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 TRANSF( aProductos[oBrw:nArrayAt, 4], "@E999,999.99" ) ) }
聽 聽oCol:nHeadStrAlign := AL_CENTER
聽 聽oCol:nDataStrAlign := AL_RIGHT
聽 聽oCol:nArrayCol := 4
//
聽 聽oCol := oBrw:AddCol()
聽 聽oCol:cHeader 聽 聽 聽 := "Sub-Total"
聽 聽oCol:nWidth 聽 聽 聽 聽 := 100
聽 聽oCol:bStrData 聽 聽 聽:= {|| IIF( LEN( aProductos ) == 0, SPACE(10) ,;
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 TRANSF( aProductos[oBrw:nArrayAt, 5], "@E999,999.99" ) ) }
聽 聽oCol:nHeadStrAlign := AL_CENTER
聽 聽oCol:nDataStrAlign := AL_RIGHT
聽 聽oCol:nFooterType 聽 := AGGR_SUM
聽 聽oCol:nFootStrAlign := AL_RIGHT
聽 聽oCol:cDataType 聽 聽 := "N"
聽 聽oCol:cEditPicture 聽:= "@E 9,999,999.99"
聽 聽oCol:nArrayCol := 5
//
聽 聽oBrw:CreateFromResource( 100 )
聽 聽oBrw:SetArray( aProductos, .t. )

聽 聽oBrw:MakeTotals(); oBrw:RefreshFooters(); oBrw:REFRESH()
// FIN DEFINICION DEL xBROWSE CON ARRAY


// BOTONES CUERPO DE LA FACTURA (agr,mod,eli)
聽 聽REDEFINE BUTTONBMP aBtn[2] ID 202 OF oDlg ; // AGREGAR PRODUCTOS
聽 聽 聽 ACTION ( lAgregar := .t. ,; // ACTIVO LOS GETs
聽 聽 聽 聽 聽limpiaget( aVar, aGet ) ,; // INICIALIZO LAS var CUERPO FACTURA
聽 聽 聽 聽 聽aGet[24]:SetFocus(), aGet[24]:REFRESH() ) ; // VA A COD.
聽 聽 聽 BITMAP 2004 PROMPT "Agregar" ;
聽 聽 聽 WHEN ( !EMPTY( aVar[33] ) )

聽 聽REDEFINE BUTTONBMP aBtn[3] ID 203 OF oDlg ; // MODIFICAR PRODUCTOS
聽 聽 聽 ACTION ( IIF( LEN( aProductos ) == 0, lSuma := .f., ) ,;
聽 聽 聽 聽 聽lMODIFI := .t., modifipro( aVar, aGet, oBrw, .f. ) ) ; // ACT.LAS var CUERPO FACTURA
聽 聽 聽 BITMAP 2004 PROMPT "Modificar" ;
聽 聽 聽 WHEN lSuma .and. LEN( aProductos ) > 0

聽 聽REDEFINE BUTTONBMP aBtn[4] ID 204 OF oDlg ; // ELIMINAR PRODUCTOS
聽 聽 聽 ACTION ( IIF( LEN( aProductos ) == 0, lSuma := .f., ) ,;
聽 聽 聽 聽 聽elimipro( aVar, aGet, oBrw ) ) ;
聽 聽 聽 BITMAP 2004 PROMPT "Eliminar" ;
聽 聽 聽 WHEN lSuma .and. LEN( aProductos ) > 0
// FIN BOTONES CUERPO DE LA FACTURA (agr,mod,eli)
RETURN

PROCEDURE limpiaget( aVar, aGet ) // INICIALIZO LAS var CUERPO FACTURA

聽 聽aVar[26] := SPACE(20)
聽 聽aVar[27] := SPACE(100)
聽 聽aVar[28] := 1
聽 聽aVar[29] := 1
聽 聽aVar[30] := 0

聽 聽refresget( aGet )

RETURN

PROCEDURE modifipro( aVar, aGet, oBrw, lGraba ) // ACT.TOTALES CUANDO MODIFICO


聽 聽IF !lGraba // 1RA.LLAMADA, ACTUALIZO LOS GETs PERO NO EL BROWSE
// ACT.LOS var CON DATOS DEL PRODUCTO A MODIFICAR
聽 聽 聽 aVar[26] := oBrw:aArrayData[oBrw:nArrayAt,1]
聽 聽 聽 aGet[24]:REFRESH() // COD.PRODUCTO
聽 聽 聽 aVar[27] := oBrw:aArrayData[oBrw:nArrayAt,2]
聽 聽 聽 aGet[25]:REFRESH() // DESCRIPCION.PRODUCTO
聽 聽 聽 aVar[28] := oBrw:aArrayData[oBrw:nArrayAt,3]
聽 聽 聽 aGet[26]:REFRESH() // CANTIDAD
聽 聽 聽 aVar[29] := oBrw:aArrayData[oBrw:nArrayAt,4]
聽 聽 聽 aGet[27]:REFRESH() // PRECIO UNITARIO
聽 聽 聽 aVar[30] := oBrw:aArrayData[oBrw:nArrayAt,5]
聽 聽 聽 aGet[28]:REFRESH() // SUB.TOTAL
聽 聽 聽 aGet[26]:SetFocus()
聽 聽 聽 aGet[26]:REFRESH()

聽 聽ELSE // 2da.LLAMADA, AHORA SI ACTUALIZO BROWSE
// RESTO DEL MTO.BRUTO SUB.TOTAL DEL REGISTRO MODIFICADO
聽 聽 聽 aVar[23] := aVar[23] - oBrw:aArrayData[oBrw:nArrayAt,5] // MTO.BRUTO - S.TOTAL
// ELIMINO REG.DEL ARRAY PARA LUEGO AGREGAR EL NUEVO MODIFICADO
聽 聽 聽 ADEL( oBrw:aArrayData, oBrw:nArrayAt )
聽 聽 聽 ASIZE( oBrw:aArrayData, oBrw:nLen - 1 )

// SUMO AL MTO.BRUTO NUEVO SUB.TOTAL DEL REGISTRO MODIFICADO
聽 聽 聽 aVar[23] := aVar[23] + aVar[30]
聽 聽 聽 aGet[21]:REFRESH() // MTO.BRUTO + S.TOTAL
// AGREGO NUEVO REG.AL ARRAY
聽 聽 聽 AADD( oBrw:aArrayData, { aVar[26], aVar[27], aVar[28], aVar[29], aVar[28] * aVar[29] } )

聽 聽 聽 oBrw:MakeTotals(); oBrw:RefreshFooters(); oBrw:REFRESH()

// ACTUALIZO NUEVOS TOTALES
聽 聽 聽 sumatotal( aVar, aGet, oBrw )

聽 聽ENDIF

RETURN

PROCEDURE sumatotal( aVar, aGet, oBrwPro ) // ACTUALIZA TOTALES DE FACTURA(suma y resta)

聽 聽aVar[23] := oBrwPro:aCols[5]:nTotal

聽 聽aVar[24] := ( aVar[23] * aVar[39] ) / 100

聽 聽aVar[25] := aVar[23] + aVar[24]

聽 聽refresget( aGet )

聽 聽totalpagar( aVar ) // ACT.SAY TOTAL PAGAR

聽 聽IF aVar[23] = 0 // solo para pruebas
* 聽 聽 聽msginfo("No hay Productos para facturar", "PRUEBAS")
聽 聽 聽 RETURN
聽 聽ENDIF

RETURN

PROCEDURE totalpagar( aVar ) // ACT.SAY TOTAL PAGAR

聽 聽nTPagar := ROUND( aVar[22] + aVar[25], 2 ) // TOT.APORTE MENSUAL + NETO PAGAR

聽 聽aSay[2]:REFRESH() // ACT.TOTAL PAGAR FINAL

RETURN

PROCEDURE refresget( aGet ) // REFRESCA LOS oGET

聽 聽DEFAULT lTodos := .t.

聽 聽AEVAL( aGet, {|o| IIF( o:ClassName() == "TGET", o:Refresh(), ) } )

RETURN

PROCEDURE elimipro( aVar, aGet, oBrw ) // ELIMINA PRODUCTOS

聽 聽IF MSGNOYES("Seguro Desea Eliminar el C贸digo: " + oBrw:aArrayData[oBrw:nArrayAt,1] )
聽 聽 聽 aVar[23] := aVar[23] - oBrw:aArrayData[oBrw:nArrayAt,5] // MTO.BRUTO - S.TOTAL
聽 聽 聽 aGet[21]:REFRESH()

聽 聽 聽 ADEL( oBrw:aArrayData, oBrw:nArrayAt )
聽 聽 聽 ASIZE( oBrw:aArrayData, oBrw:nLen - 1 )
聽 聽 聽 oBrw:REFRESH()

聽 聽 聽 sumatotal( aVar, aGet, oBrw ) // ACT.TOTALES
聽 聽ENDIF

RETURN


Dios no est谩 muerto...



Gracias a mi Dios ante todo!
Posts: 53
Joined: Tue Aug 18, 2015 07:34 PM
Re: Ejemplo sencillo de factura
Posted: Fri Apr 15, 2016 04:25 PM
joseluisysturiz wrote:Aca te mando otra forma de como lo hago en otro sistema sin ser edicion directa en xbrowse...saludos.. :-)

Code (fw): Select all Collapse
PROCEDURE factura()

// DEFINICION BROWSE
聽 聽oBrw := TXBrowse():New( oDlg )

聽 聽WITH OBJECT oBrw
聽 聽 聽 :nMarqueeStyle 聽 聽:= MARQSTYLE_HIGHLROW
聽 聽 聽 :nColDividerStyle := LINESTYLE_BLACK
聽 聽 聽 :lAllowColSwapping := .f.
聽 聽 聽 :lAllowColHiding := .f.
聽 聽 聽 :lColDividerComplete := .t.
聽 聽 聽 :nHeaderHeight := 30
聽 聽 聽 :l2007 := .t.
聽 聽 聽 :lFooter := .t.
聽 聽 聽 :lRecordSelector := .t.
聽 聽 聽 :bClrStd := {|| IF( oBrw:nArrayAt % 2 == 0, {CLR_BLACK, CLR_WHITE} ,;
聽 聽 聽 聽 聽{0, RGB(203, 226, 254)} ) }
聽 聽END WITH
//
聽 聽oCol := oBrw:AddCol()
聽 聽oCol:cHeader 聽 聽 聽 := "C贸digo"
聽 聽oCol:nWidth 聽 聽 聽 聽:= 70
聽 聽oCol:bStrData 聽 聽 聽:= {|| IIF( LEN( aProductos ) == 0, SPACE(10) ,;
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 aProductos[oBrw:nArrayAt, 1] ) }
聽 聽oCol:nHeadStrAlign := AL_CENTER
聽 聽oCol:nDataStrAlign := AL_LEFT
聽 聽oCol:nArrayCol := 1
//
聽 聽oCol := oBrw:AddCol()
聽 聽oCol:cHeader 聽 聽 聽 := "Descripci贸n"
聽 聽oCol:nWidth 聽 聽 聽 聽:= 350
聽 聽oCol:bStrData 聽 聽 聽:= {|| IIF( LEN( aProductos ) == 0, SPACE(10) ,;
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 aProductos[oBrw:nArrayAt, 2] ) }
聽 聽oCol:nHeadStrAlign := AL_CENTER
聽 聽oCol:nDataStrAlign := AL_LEFT
聽 聽oCol:nArrayCol := 2
//
聽 聽oCol := oBrw:AddCol()
聽 聽oCol:cHeader 聽 聽 聽 := "Cantidad"
聽 聽oCol:nWidth 聽 聽 聽 聽:= 50
聽 聽oCol:bStrData 聽 聽 聽:= {|| IIF( LEN( aProductos ) == 0, SPACE(10) ,;
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 aProductos[oBrw:nArrayAt, 3] ) }
聽 聽oCol:nHeadStrAlign := AL_CENTER
聽 聽oCol:nDataStrAlign := AL_RIGHT
聽 聽oCol:nArrayCol := 3
//
聽 聽oCol := oBrw:AddCol()
聽 聽oCol:cHeader 聽 聽 聽 := "Precio Unitario"
聽 聽oCol:nWidth 聽 聽 聽 聽 := 100
聽 聽oCol:bStrData 聽 聽 聽:= {|| IIF( LEN( aProductos ) == 0, SPACE(10) ,;
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 TRANSF( aProductos[oBrw:nArrayAt, 4], "@E999,999.99" ) ) }
聽 聽oCol:nHeadStrAlign := AL_CENTER
聽 聽oCol:nDataStrAlign := AL_RIGHT
聽 聽oCol:nArrayCol := 4
//
聽 聽oCol := oBrw:AddCol()
聽 聽oCol:cHeader 聽 聽 聽 := "Sub-Total"
聽 聽oCol:nWidth 聽 聽 聽 聽 := 100
聽 聽oCol:bStrData 聽 聽 聽:= {|| IIF( LEN( aProductos ) == 0, SPACE(10) ,;
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 TRANSF( aProductos[oBrw:nArrayAt, 5], "@E999,999.99" ) ) }
聽 聽oCol:nHeadStrAlign := AL_CENTER
聽 聽oCol:nDataStrAlign := AL_RIGHT
聽 聽oCol:nFooterType 聽 := AGGR_SUM
聽 聽oCol:nFootStrAlign := AL_RIGHT
聽 聽oCol:cDataType 聽 聽 := "N"
聽 聽oCol:cEditPicture 聽:= "@E 9,999,999.99"
聽 聽oCol:nArrayCol := 5
//
聽 聽oBrw:CreateFromResource( 100 )
聽 聽oBrw:SetArray( aProductos, .t. )

聽 聽oBrw:MakeTotals(); oBrw:RefreshFooters(); oBrw:REFRESH()
// FIN DEFINICION DEL xBROWSE CON ARRAY


// BOTONES CUERPO DE LA FACTURA (agr,mod,eli)
聽 聽REDEFINE BUTTONBMP aBtn[2] ID 202 OF oDlg ; // AGREGAR PRODUCTOS
聽 聽 聽 ACTION ( lAgregar := .t. ,; // ACTIVO LOS GETs
聽 聽 聽 聽 聽limpiaget( aVar, aGet ) ,; // INICIALIZO LAS var CUERPO FACTURA
聽 聽 聽 聽 聽aGet[24]:SetFocus(), aGet[24]:REFRESH() ) ; // VA A COD.
聽 聽 聽 BITMAP 2004 PROMPT "Agregar" ;
聽 聽 聽 WHEN ( !EMPTY( aVar[33] ) )

聽 聽REDEFINE BUTTONBMP aBtn[3] ID 203 OF oDlg ; // MODIFICAR PRODUCTOS
聽 聽 聽 ACTION ( IIF( LEN( aProductos ) == 0, lSuma := .f., ) ,;
聽 聽 聽 聽 聽lMODIFI := .t., modifipro( aVar, aGet, oBrw, .f. ) ) ; // ACT.LAS var CUERPO FACTURA
聽 聽 聽 BITMAP 2004 PROMPT "Modificar" ;
聽 聽 聽 WHEN lSuma .and. LEN( aProductos ) > 0

聽 聽REDEFINE BUTTONBMP aBtn[4] ID 204 OF oDlg ; // ELIMINAR PRODUCTOS
聽 聽 聽 ACTION ( IIF( LEN( aProductos ) == 0, lSuma := .f., ) ,;
聽 聽 聽 聽 聽elimipro( aVar, aGet, oBrw ) ) ;
聽 聽 聽 BITMAP 2004 PROMPT "Eliminar" ;
聽 聽 聽 WHEN lSuma .and. LEN( aProductos ) > 0
// FIN BOTONES CUERPO DE LA FACTURA (agr,mod,eli)
RETURN

PROCEDURE limpiaget( aVar, aGet ) // INICIALIZO LAS var CUERPO FACTURA

聽 聽aVar[26] := SPACE(20)
聽 聽aVar[27] := SPACE(100)
聽 聽aVar[28] := 1
聽 聽aVar[29] := 1
聽 聽aVar[30] := 0

聽 聽refresget( aGet )

RETURN

PROCEDURE modifipro( aVar, aGet, oBrw, lGraba ) // ACT.TOTALES CUANDO MODIFICO


聽 聽IF !lGraba // 1RA.LLAMADA, ACTUALIZO LOS GETs PERO NO EL BROWSE
// ACT.LOS var CON DATOS DEL PRODUCTO A MODIFICAR
聽 聽 聽 aVar[26] := oBrw:aArrayData[oBrw:nArrayAt,1]
聽 聽 聽 aGet[24]:REFRESH() // COD.PRODUCTO
聽 聽 聽 aVar[27] := oBrw:aArrayData[oBrw:nArrayAt,2]
聽 聽 聽 aGet[25]:REFRESH() // DESCRIPCION.PRODUCTO
聽 聽 聽 aVar[28] := oBrw:aArrayData[oBrw:nArrayAt,3]
聽 聽 聽 aGet[26]:REFRESH() // CANTIDAD
聽 聽 聽 aVar[29] := oBrw:aArrayData[oBrw:nArrayAt,4]
聽 聽 聽 aGet[27]:REFRESH() // PRECIO UNITARIO
聽 聽 聽 aVar[30] := oBrw:aArrayData[oBrw:nArrayAt,5]
聽 聽 聽 aGet[28]:REFRESH() // SUB.TOTAL
聽 聽 聽 aGet[26]:SetFocus()
聽 聽 聽 aGet[26]:REFRESH()

聽 聽ELSE // 2da.LLAMADA, AHORA SI ACTUALIZO BROWSE
// RESTO DEL MTO.BRUTO SUB.TOTAL DEL REGISTRO MODIFICADO
聽 聽 聽 aVar[23] := aVar[23] - oBrw:aArrayData[oBrw:nArrayAt,5] // MTO.BRUTO - S.TOTAL
// ELIMINO REG.DEL ARRAY PARA LUEGO AGREGAR EL NUEVO MODIFICADO
聽 聽 聽 ADEL( oBrw:aArrayData, oBrw:nArrayAt )
聽 聽 聽 ASIZE( oBrw:aArrayData, oBrw:nLen - 1 )

// SUMO AL MTO.BRUTO NUEVO SUB.TOTAL DEL REGISTRO MODIFICADO
聽 聽 聽 aVar[23] := aVar[23] + aVar[30]
聽 聽 聽 aGet[21]:REFRESH() // MTO.BRUTO + S.TOTAL
// AGREGO NUEVO REG.AL ARRAY
聽 聽 聽 AADD( oBrw:aArrayData, { aVar[26], aVar[27], aVar[28], aVar[29], aVar[28] * aVar[29] } )

聽 聽 聽 oBrw:MakeTotals(); oBrw:RefreshFooters(); oBrw:REFRESH()

// ACTUALIZO NUEVOS TOTALES
聽 聽 聽 sumatotal( aVar, aGet, oBrw )

聽 聽ENDIF

RETURN

PROCEDURE sumatotal( aVar, aGet, oBrwPro ) // ACTUALIZA TOTALES DE FACTURA(suma y resta)

聽 聽aVar[23] := oBrwPro:aCols[5]:nTotal

聽 聽aVar[24] := ( aVar[23] * aVar[39] ) / 100

聽 聽aVar[25] := aVar[23] + aVar[24]

聽 聽refresget( aGet )

聽 聽totalpagar( aVar ) // ACT.SAY TOTAL PAGAR

聽 聽IF aVar[23] = 0 // solo para pruebas
* 聽 聽 聽msginfo("No hay Productos para facturar", "PRUEBAS")
聽 聽 聽 RETURN
聽 聽ENDIF

RETURN

PROCEDURE totalpagar( aVar ) // ACT.SAY TOTAL PAGAR

聽 聽nTPagar := ROUND( aVar[22] + aVar[25], 2 ) // TOT.APORTE MENSUAL + NETO PAGAR

聽 聽aSay[2]:REFRESH() // ACT.TOTAL PAGAR FINAL

RETURN

PROCEDURE refresget( aGet ) // REFRESCA LOS oGET

聽 聽DEFAULT lTodos := .t.

聽 聽AEVAL( aGet, {|o| IIF( o:ClassName() == "TGET", o:Refresh(), ) } )

RETURN

PROCEDURE elimipro( aVar, aGet, oBrw ) // ELIMINA PRODUCTOS

聽 聽IF MSGNOYES("Seguro Desea Eliminar el C贸digo: " + oBrw:aArrayData[oBrw:nArrayAt,1] )
聽 聽 聽 aVar[23] := aVar[23] - oBrw:aArrayData[oBrw:nArrayAt,5] // MTO.BRUTO - S.TOTAL
聽 聽 聽 aGet[21]:REFRESH()

聽 聽 聽 ADEL( oBrw:aArrayData, oBrw:nArrayAt )
聽 聽 聽 ASIZE( oBrw:aArrayData, oBrw:nLen - 1 )
聽 聽 聽 oBrw:REFRESH()

聽 聽 聽 sumatotal( aVar, aGet, oBrw ) // ACT.TOTALES
聽 聽ENDIF

RETURN





Hola buenos dias mi estimado Jose Luis, gracias por el aporte de tu codigo, creo que es mas sencillo de entenderle y aplicarle a mi sostema de control no entre ayer,tuve contratiempo en mi trabajo sin mas quedo de ti y del ejemplo agradezco tu atencion prestada acia mi sin nada a cambio

Saludos
Rosa
Posts: 2064
Joined: Fri Jan 06, 2006 09:28 PM
Re: Ejemplo sencillo de factura
Posted: Fri Apr 15, 2016 11:46 PM

Saludos Rosita, en este foro siempre encontraras ayuda en todo lo posible, si no de un codigo completo por lo menos de ideas de como hacerlo, hay que dar de gracia lo que se recibe de gracia, todos en algun momento fuimos principiantes y con ayudas y un poco de lectura y practica, nos fuimos superando sabiendo algo mas que algunos algunos pero tambien por menos que otros mas experimentados, y asi se van reeemplazando los escalafones, espero te sirva el codigo y sigo a la orden en lo que pueda...quede esperando dijeras de donde eres, gracias, saludos... :shock:

Dios no est谩 muerto...



Gracias a mi Dios ante todo!