Hola Kleyber.
esa situaci贸n me he encontrado hoy, pero te comento como lo hago.
el browse lo muestro con una consulta que muestra una tabla con sus relaciones , es solamente para mostrar en el browse (es una vista en realidad),
luego a la hora de editar, hago una segunda consulta, de una sola fila (la misma que estoy posicionada en el browse) solamente para tomar los datos a editar, esta tampoco es editable ( esto en los casos en que el los datos a editar no est茅n el el primer query, en los casos en que todos los datos a editar esten el el primer query los tomo de ahi directo), y para insertar, actualizar lo hago directamente a las tablas involucradas.
para borrar tambi茅n lo hago directo.
te muestro un modulo completo para que te hagas una idea:
NOTA:tengo algunas extenciones propias para dolphin que usos por ejemplo query2, execute2, requery, etc. pero es mas por comodidad que otra cosa.
/*-------------------------------------------------------------------------------------------------*/
#include "credicom.ch"
/*-------------------------------------------------------------------------------------------------*/
PROCEDURE Cobradores()
聽 聽PRIVATE oError
聽 聽PRIVATE oDlg, oBrw, oToolbar, oPopUp1, oBtnFilter
聽 聽PRIVATE oQryCtrl, oQryCiud, oQryCobr
聽 聽PRIVATE lFiltrado
聽 聽lFiltrado := FALSE
聽 聽TRY
聽 聽 聽 oQryCtrl := oServer:Query2( "SELECT CONT_COBR FROM CONTROL" )
聽 聽 聽 oQryCiud := oServer:Query2( "SELECT NUM_CIUD, NOMBRE FROM CIUDADES ORDER BY NOMBRE" )
聽 聽 聽 oQryCobr := oServer:Query2( "SELECT * FROM vCATCOBR ORDER BY NUM_COBR")
聽 聽CATCH oError
聽 聽 聽 ShowError( oError, { oQryCtrl, oQryCiud, oQryCobr } )
聽 聽 聽 RETURN
聽 聽END
聽 聽oQryCobr:gotop()
聽 聽DEFINE DIALOG oDlg NAME "DLG_COBRADORESC" OF oMainWnd ICON GetIcon() FONT oFontD
聽 聽REDEFINE XBROWSE oBrw DATASOURCE oQryCobr ID 101 OF oDlg AUTOSORT ;
聽 聽 聽 ON DBLCLICK Cobradores_Editar( FALSE ) FONT oFontD
聽 聽ADD TO oBrw DATA oQryCobr:NUM_COBR TITLE "N煤mero" 聽 聽 聽 聽 聽SIZE 080 CENTER PICTURE "@L 999"
聽 聽ADD TO oBrw DATA oQryCobr:NOMBRE 聽 TITLE "Nombre cobrador" SIZE 250
聽 聽ADD TO oBrw DATA oQryCobr:CIUDAD 聽 TITLE "Ciudad" 聽 聽 聽 聽 聽SIZE 050
聽 聽ADD TO oBrw DATA oQryCobr:ACTIVO 聽 TITLE "Act" 聽 聽 聽 聽 聽 聽 SIZE 050
聽 聽WITH OBJECT oBrw
聽 聽 聽 :MyConfig()
聽 聽 聽 :aCols[ 01 ]:cSortOrder := "NUM_COBR"
聽 聽 聽 :aCols[ 02 ]:cSortOrder := "NOMBRE"
聽 聽 聽 :aCols[ 03 ]:cSortOrder := "CIUDAD"
聽 聽 聽 :aCols[ 04 ]:SetCheck( { "BMS_CHECKON","BMS_CHECKOFF" } )
聽 聽 聽 :bKeyDown 聽 聽 聽:= {|nKey| Cobradores_ProcesaTecla( nKey ) }
聽 聽 聽 :lHScroll 聽 聽 聽:= FALSE
聽 聽 聽 :nHeaderHeight := 36
聽 聽 聽 :nFreeze 聽 聽 聽 := 4
聽 聽END
聽 聽ACTIVATE DIALOG oDlg ON INIT Cobradores_Toolbar()
聽 聽oQryCtrl:END()
聽 聽oQryCiud:END()
聽 聽oQryCobr:END()
RETURN
/*-------------------------------------------------------------------------------------------------*/
PROCEDURE Cobradores_Toolbar()
聽 聽MENU oPopUp1 POPUP 2010
聽 聽 聽 MENUITEM "Mostrar solo &inactivos" ACTION Cobradores_Filtrar( 1 )
聽 聽 聽 MENUITEM "Mostrar solo &activos" 聽 ACTION Cobradores_Filtrar( 2 )
聽 聽 聽 SEPARATOR
聽 聽 聽 MENUITEM "Mostrar &todos" 聽 聽 聽 聽 聽ACTION Cobradores_Filtrar( 3 )
聽 聽ENDMENU
聽 聽DEFINE BUTTONBAR oToolBar OF oDlg SIZE 60, 60 2010
聽 聽DEFINE BUTTON NAME "TB_CLOSE" 聽 聽 OF oToolBar ACTION oDlg:END() 聽 聽 聽 聽 聽 聽 聽 聽 PROMPT "&Salir"
聽 聽DEFINE BUTTON NAME "TB_ADD" 聽 聽 聽 OF oToolBar ACTION Cobradores_Editar( TRUE 聽) PROMPT "&Nuevo" 聽 GROUP
聽 聽DEFINE BUTTON NAME "TB_EDIT" 聽 聽 聽OF oToolBar ACTION Cobradores_Editar( FALSE ) PROMPT "&Editar"
聽 聽DEFINE BUTTON NAME "TB_DELETE" 聽 聽OF oToolBar ACTION Cobradores_Borrar() 聽 聽 聽 聽PROMPT "&Borrar"
聽 聽DEFINE BUTTON NAME "TB_PRINTER" 聽 OF oToolBar ACTION Cobradores_Listar() 聽 聽 聽 聽PROMPT "&Imprimir"
聽 聽DEFINE BUTTON NAME "TB_FILTERADD" OF oToolBar ACTION Cobradores_Filtrar( 3 ) 聽 聽PROMPT "&Filtrar" 聽MENU oPopUp1 GROUP
聽 聽SET MSGBAR OF oDlg TO "INS=Nuevo, DEL=Borrar, ENTER=Editar, F3=Imprimir, F5=Filtrar, F9=Refrescar" 2010
聽 聽oDlg:SetControl( oBrw )
聽 聽WITH OBJECT oToolBar
聽 聽 聽 :bRClicked := {|| NIL }
聽 聽 聽 :bLClicked := {|| NIL }
聽 聽 聽 :aControls[ 1 ]:cToolTip := "Cierra modulo."
聽 聽 聽 :aControls[ 2 ]:cToolTip := "Agrega un nuevo registro."
聽 聽 聽 :aControls[ 3 ]:cToolTip := "Edita datos del registro actual."
聽 聽 聽 :aControls[ 4 ]:cToolTip := "Elimina datos del registro actual."
聽 聽 聽 :aControls[ 5 ]:cToolTip := "Lista datos para ser impresos."
聽 聽 聽 :aControls[ 6 ]:cToolTip := "Filtra registros a mostrar."
聽 聽 聽 oBtnFilter := :aControls[ 06 ]
聽 聽END
RETURN
/*-------------------------------------------------------------------------------------------------*/
PROCEDURE Cobradores_ProcesaTecla( nKey )
聽 聽DO CASE
聽 聽CASE nKey == VK_INSERT
聽 聽 聽 Cobradores_Editar( TRUE 聽)
聽 聽CASE nKey == VK_RETURN
聽 聽 聽 Cobradores_Editar( FALSE )
聽 聽CASE nKey == VK_DELETE
聽 聽 聽 Cobradores_Borrar()
聽 聽CASE nKey == VK_F3
聽 聽 聽 Cobradores_Listar()
聽 聽CASE nKey == VK_F5
聽 聽 聽 IF !lFiltrado
聽 聽 聽 聽 聽Cobradores_Filtrar( 2 )
聽 聽 聽 ELSE
聽 聽 聽 聽 聽Cobradores_Filtrar( 3 )
聽 聽 聽 ENDIF
聽 聽CASE nKey == VK_F9
聽 聽 聽 Refrescar_Browse( oBrw )
聽 聽ENDCASE
RETURN
/*-------------------------------------------------------------------------------------------------*/
PROCEDURE Cobradores_Filtrar( nOpcion )
聽 聽TRY
聽 聽 聽 DO CASE
聽 聽 聽 CASE nOpcion==1
聽 聽 聽 聽 聽oQryCobr:SetWhere( "ACTIVO=" + Var2Str( FALSE ), TRUE )
聽 聽 聽 CASE nOpcion==2
聽 聽 聽 聽 聽oQryCobr:SetWhere( "ACTIVO=" + Var2Str( TRUE 聽), TRUE )
聽 聽 聽 CASE nOpcion==3
聽 聽 聽 聽 聽oQryCobr:SetWhere( "", TRUE )
聽 聽 聽 END
聽 聽 聽 IF nOpcion < 3
聽 聽 聽 聽 聽WITH OBJECT oBtnFilter
聽 聽 聽 聽 聽 聽 :FreeBitmaps()
聽 聽 聽 聽 聽 聽 :LoadBitmaps( "TB_FILTERDEL" )
聽 聽 聽 聽 聽 聽 :cTooltip := "Elimina filtro, muestra todos los cobradores."
聽 聽 聽 聽 聽 聽 :Refresh()
聽 聽 聽 聽 聽END
聽 聽 聽 聽 聽lFiltrado := TRUE
聽 聽 聽 ELSE
聽 聽 聽 聽 聽WITH OBJECT oBtnFilter
聽 聽 聽 聽 聽 聽 :FreeBitmaps()
聽 聽 聽 聽 聽 聽 :LoadBitmaps( "TB_FILTERADD" )
聽 聽 聽 聽 聽 聽 :cTooltip := "Filtra los cobradores por estado."
聽 聽 聽 聽 聽 聽 :Refresh()
聽 聽 聽 聽 聽END
聽 聽 聽 聽 聽lFiltrado := FALSE
聽 聽 聽 ENDIF
聽 聽CATCH oError
聽 聽 聽 ShowError( oError )
聽 聽 聽 RETURN
聽 聽END
聽 聽oBrw:GoTop()
聽 聽oBrw:Refresh()
聽 聽oBrw:SetFocus()
RETURN
/*-------------------------------------------------------------------------------------------------*/
PROCEDURE Cobradores_Borrar()
聽 聽LOCAL oQryTmp
聽 聽IF oQryCobr:eof()
聽 聽 聽 MsgAlert( "No hay cobradores registradas, nada que borrar." )
聽 聽ELSE
聽 聽 聽 IF MsgNoYes( "Desea borrar datos del cobrador seleccionado?" )
聽 聽 聽 聽 聽TRY
聽 聽 聽 聽 聽 聽 oQryTmp := oServer:Query2( "SELECT COUNT(*) AS CONTADOR FROM RUTAS WHERE NUM_COBR=%1", { oQryCobr:NUM_COBR } )
聽 聽 聽 聽 聽 聽 IF oQryTmp:CONTADOR > 0
聽 聽 聽 聽 聽 聽 聽 聽 MsgAlert( "No se puede borrar al cobrador seleccionado, ya fue asignado a una ruta de cobro" )
聽 聽 聽 聽 聽 聽 ELSE
聽 聽 聽 聽 聽 聽 聽 聽oServer:Execute2( "DELETE FROM COBRADORES WHERE NUM_COBR=%1", { oQryCobr:NUM_COBR } )
聽 聽 聽 聽 聽 聽 聽 聽oQryCobr:ReQuery()
聽 聽 聽 聽 聽 聽 ENDIF
聽 聽 聽 聽 聽 聽 oQryTmp:End()
聽 聽 聽 聽 聽CATCH oError
聽 聽 聽 聽 聽 聽 ShowError( oError, { oQryTmp } )
聽 聽 聽 聽 聽END
聽 聽 聽 聽 聽oBrw:Refresh()
聽 聽 聽 ENDIF
聽 聽ENDIF
聽 聽oBrw:SetFocus()
RETURN
/*-------------------------------------------------------------------------------------------------*/
PROCEDURE Cobradores_Editar( lNuevo )
聽 聽LOCAL 聽oQryTmp
聽 聽PRIVATE oDlgE
聽 聽PRIVATE nNumCiud, cNomCiud, nNumCobr, cNomCobr, cDomCobr, cTelCobr, cCedCobr, dIngCobr, dRetCobr, lActivo, cNota
聽 聽PRIVATE oNomCiud
聽 聽IF oQryCiud:Eof()
聽 聽 聽 MsgAlert( "No hay ciudades/oficina definidas, no puede continuar." )
聽 聽 聽 oBrw:SetFocus()
聽 聽 聽 RETURN
聽 聽ENDIF
聽 聽IF lNuevo
聽 聽 聽 nNumCobr := oQryCtrl:CONT_COBR + 1
聽 聽 聽 nNumCiud := 0
聽 聽 聽 cNomCiud := ""
聽 聽 聽 cNomCobr := Space( 40 )
聽 聽 聽 cDomCobr := Space( 80 )
聽 聽 聽 cTelCobr := Space( 20 )
聽 聽 聽 cCedCobr := Space( 16 )
聽 聽 聽 dIngCobr := Date()
聽 聽 聽 dRetCobr := CToD( "" )
聽 聽 聽 lActivo 聽:= TRUE
聽 聽 聽 cNota 聽 聽:= ""
聽 聽ELSE
聽 聽 聽 IF oQryCobr:Eof()
聽 聽 聽 聽 聽MsgAlert( "No hay cobradores registrados, nada que editar." )
聽 聽 聽 聽 聽oBrw:SetFocus()
聽 聽 聽 聽 聽RETURN
聽 聽 聽 ENDIF
聽 聽 聽 TRY
聽 聽 聽 聽 聽oQryTmp 聽:= oServer:Query2( "SELECT * FROM vCATCOBR_E WHERE NUM_COBR=%1 LIMIT 1", { oQryCobr:NUM_COBR } )
聽 聽 聽 聽 聽nNumCobr := oQryTmp:NUM_COBR
聽 聽 聽 聽 聽nNumCiud := oQryTmp:NUM_CIUD
聽 聽 聽 聽 聽cNomCiud := oQryTmp:CIUDAD
聽 聽 聽 聽 聽cNomCobr := oQryTmp:NOMBRE
聽 聽 聽 聽 聽cDomCobr := oQryTmp:DOMICILIO
聽 聽 聽 聽 聽cTelCobr := oQryTmp:TELEFONOS
聽 聽 聽 聽 聽cCedCobr := oQryTmp:CEDULA
聽 聽 聽 聽 聽dIngCobr := oQryTmp:FECHA_ING
聽 聽 聽 聽 聽dRetCobr := oQryTmp:FECHA_RET
聽 聽 聽 聽 聽lActivo 聽:= oQryTmp:ACTIVO
聽 聽 聽 聽 聽cNota 聽 聽:= oQryTmp:NOTA
聽 聽 聽 聽 聽oQryTmp:END()
聽 聽 聽 CATCH oError
聽 聽 聽 聽 聽ShowError( oError, { oQryTmp } )
聽 聽 聽 聽 聽RETURN
聽 聽 聽 END
聽 聽ENDIF
聽 聽DEFINE DIALOG oDlgE NAME "DLG_COBRADORESE" OF oDlg ICON GetIcon() FONT oFontD
聽 聽REDEFINE GET nNumCobr ;
聽 聽 聽 ID 101 OF oDlgE ;
聽 聽 聽 PICTURE "999" ;
聽 聽 聽 WHEN FALSE
聽 聽REDEFINE GET cNomCobr ;
聽 聽 聽 ID 102 OF oDlgE ;
聽 聽 聽 PICTURE "@!"
聽 聽REDEFINE GET cDomCobr ;
聽 聽 聽 ID 103 OF oDlgE ;
聽 聽 聽 PICTURE "@!"
聽 聽REDEFINE GET oNomCiud VAR cNomCiud ;
聽 聽 聽 ID 104 OF oDlgE ;
聽 聽 聽 WHEN FALSE ;
聽 聽 聽 UPDATE
聽 聽REDEFINE BUTTON ;
聽 聽 聽 ID 105 OF oDlgE ;
聽 聽 聽 ACTION Cobradores_SeleccionarCiudad()
聽 聽REDEFINE GET cTelCobr ;
聽 聽 聽 ID 106 OF oDlgE ;
聽 聽 聽 PICTURE "@!"
聽 聽REDEFINE GET cCedCobr ;
聽 聽 聽 ID 107 OF oDlgE ;
聽 聽 聽 PICTURE "@!"
聽 聽REDEFINE GET dIngCobr ;
聽 聽 聽 ID 108 OF oDlgE ;
聽 聽 聽 PICTURE "@D"
聽 聽REDEFINE GET dRetCobr ;
聽 聽 聽 ID 109 OF oDlgE ;
聽 聽 聽 PICTURE "@D" ;
聽 聽 聽 WHEN !lNuevo
聽 聽REDEFINE CHECKBOX lActivo ;
聽 聽 聽 ID 110 OF oDlgE ;
聽 聽 聽 WHEN !lNuevo ;
聽 聽 聽 ON CHANGE Cobradores_Estado() ;
聽 聽 聽 UPDATE
聽 聽REDEFINE GET cNota ;
聽 聽 聽 ID 111 OF oDlgE ;
聽 聽 聽 MEMO
聽 聽REDEFINE BUTTON ;
聽 聽 聽 ID 201 OF oDlgE ;
聽 聽 聽 WHEN !Empty( cNomCobr ) .and. nNumCiud > 0 ;
聽 聽 聽 ACTION IIf( Cobradores_Grabar( lNuevo ), oDlgE:END(), NIL )
聽 聽REDEFINE BUTTON ;
聽 聽 聽 ID 202 OF oDlgE ;
聽 聽 聽 ACTION oDlgE:END() ;
聽 聽 聽 CANCEL
聽 聽ACTIVATE DIALOG oDlgE
聽 聽oBrw:SetFocus()
RETURN
/*-------------------------------------------------------------------------------------------------*/
PROCEDURE Cobradores_Estado()
聽 聽LOCAL oQryTmp
聽 聽TRY
聽 聽 聽 IF !lActivo
聽 聽 聽 聽 聽oQryTmp := oServer:Query2( "SELECT COUNT(*) AS CONTADOR FROM CLIENTES WHERE NUM_COBR=%1", { nNumCobr } )
聽 聽 聽 聽 聽IF oQryTmp:CONTADOR > 0
聽 聽 聽 聽 聽 聽 lActivo := TRUE
聽 聽 聽 聽 聽 聽 oDlgE:Update()
聽 聽 聽 聽 聽 聽 MsgAlert( "Hay una ruta de cobro que tiene a este cobrador asignado, por tanto no se puede desactivar." )
聽 聽 聽 聽 聽ENDIF
聽 聽 聽 聽 聽oQryTmp:END()
聽 聽 聽 ENDIF
聽 聽CATCH oError
聽 聽 聽 ShowError( oError, { oQryTmp } )
聽 聽END
RETURN
/*-------------------------------------------------------------------------------------------------*/
PROCEDURE Cobradores_SeleccionarCiudad()
聽 聽LOCAL bEval := {|| nNumCiud := oQryCiud:NUM_CIUD, ;
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 cNomCiud := oQryCiud:NOMBRE 聽, ;
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 oNomCiud:Refresh() }
聽 聽QSeleccionar( oDlgE, oQryCiud, "NOMBRE", "Lista de Ciudad/Oficina", bEval )
RETURN
/*-------------------------------------------------------------------------------------------------*/
FUNCTION Cobradores_Grabar( lNuevo )
聽 聽LOCAL cWhere
聽 聽LOCAL lGrabado := FALSE
聽 聽TRY
聽 聽 聽 oServer:BeginTransaction()
聽 聽 聽 IF lNuevo
聽 聽 聽 聽 聽oServer:Execute2( "UPDATE CONTROL SET CONT_COBR=%1", { nNumCobr } )
聽 聽 聽 聽 聽oServer:Insert( "COBRADORES", { "NUM_CIUD", "NUM_COBR", "NOMBRE", "DOMICILIO", "TELEFONOS", "CEDULA", "FECHA_ING", "FECHA_RET", "ACTIVO", "NOTA" }, ;
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽{ nNumCiud 聽, nNumCobr 聽, cNomCobr, cDomCobr, 聽 聽cTelCobr, 聽 聽cCedCobr, dIngCobr, 聽 聽dRetCobr 聽 , lActivo , cNota 聽} 聽)
聽 聽 聽 ELSE
聽 聽 聽 聽 聽cWhere := "NUM_COBR=" + Var2Str( nNumCobr )
聽 聽 聽 聽 聽oServer:Update( "COBRADORES", { "NUM_CIUD", "NUM_COBR", "NOMBRE", "DOMICILIO", "TELEFONOS", "CEDULA", "FECHA_ING", "FECHA_RET", "ACTIVO", "NOTA" }, ;
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽{ nNumCiud 聽, nNumCobr 聽, cNomCobr, cDomCobr, 聽 聽cTelCobr, 聽 聽cCedCobr, dIngCobr, 聽 聽dRetCobr 聽 , lActivo , cNota 聽}, cWhere 聽)
聽 聽 聽 ENDIF
聽 聽 聽 oServer:CommitTransaction()
聽 聽 聽 IIf( lNuevo, oQryCtrl:ReQuery(), NIL )
聽 聽 聽 oQryCobr:ReQuery()
聽 聽 聽 lGrabado := TRUE
聽 聽CATCH oError
聽 聽 聽 oServer:RollBack()
聽 聽 聽 ShowError( oError )
聽 聽END
聽 聽IF lGrabado
聽 聽 聽 IIf( lNuevo, ( oBrw:GoBottom(), oBrw:Refresh() ), oBrw:RefreshCurrent() )
聽 聽ELSE
聽 聽 聽 oBrw:GoTop()
聽 聽ENDIF
RETURN lGrabado
/*-------------------------------------------------------------------------------------------------*/
PROCEDURE Cobradores_Listar()
RETURN
/*-------------------------------------------------------------------------------------------------*/
/*EOF*/
/*-------------------------------------------------------------------------------------------------*/
vCATCOBR
select `A`.`NUM_COBR` AS `NUM_COBR`,`A`.`NOMBRE` AS `NOMBRE`,`A`.`NUM_CIUD` AS `NUM_CIUD`,`B`.`NOMCOR` AS `CIUDAD`,`A`.`ACTIVO` AS `ACTIVO` from (`COBRADORES` `A` left join `CIUDADES` `B` on((`A`.`NUM_CIUD` = `B`.`NUM_CIUD`)))
vCATCOBR_E
select `A`.`NUM_CIUD` AS `NUM_CIUD`,`A`.`NUM_COBR` AS `NUM_COBR`,`A`.`NOMBRE` AS `NOMBRE`,`A`.`CEDULA` AS `CEDULA`,`A`.`DOMICILIO` AS `DOMICILIO`,`A`.`TELEFONOS` AS `TELEFONOS`,`A`.`FECHA_ING` AS `FECHA_ING`,`A`.`FECHA_RET` AS `FECHA_RET`,`A`.`ACTIVO` AS `ACTIVO`,`A`.`NOTA` AS `NOTA`,`B`.`NOMBRE` AS `CIUDAD` from (`COBRADORES` `A` left join `CIUDADES` `B` on((`A`.`NUM_CIUD` = `B`.`NUM_CIUD`)))