Re: [ADO Harbour] Consulta para borrar registro en un xBrowse con ADO

183 views
Skip to first unread message

Antonio Vázquez

unread,
Sep 1, 2021, 6:09:06 PM9/1/21
to ado-h...@googlegroups.com
Buenas.
Creo q te falta un oBrwMostrar:refresh() después de borrar el registro.
Saludos.

Obtener Outlook para Android

From: ado-h...@googlegroups.com <ado-h...@googlegroups.com> on behalf of Antonio Cardinaux <ancar...@gmail.com>
Sent: Wednesday, September 1, 2021 9:44:03 PM
To: ADO Harbour <ado-h...@googlegroups.com>
Subject: [ADO Harbour] Consulta para borrar registro en un xBrowse con ADO
 
Pongo el ejemplo de SQLAdo de David, de forma simplificada, y con el agregado de DELETE y ON DELETE

@ 1,10 XBROWSE TbMostrar OBJ oBrwMostrar;
WIDTH 780 ;
HEIGHT 430 ;
WORKAREA ( oRsBrw  ) ;
HEADERS aHeaders ;
FIELDS aFields ;
WIDTHS aWidths ;
COLUMNCONTROLS aCtrl ;
JUSTIFY aJusti ;
READONLY {.T.} ;   
FIXEDBLOCKS ;
      DELETE ;
      ON DELETE orBrw:Update()

    DEFINE BUTTON btnEliminar 
      ROW 120
    COL 10
      CAPTION "&Eliminar" 
    WIDTH 90 
  ACTION DelRow( oC,oRsBrw )
    END BUTTON
  
/***/
static Function DelRow( oC,oRsBrw )

oRsBrw:Delete()

retu  

Al querer eliminar un registro, no lo borra, no hace nada, la grilla queda tal como se muestra. ¿ Que estoy haciendo mal ?

--
Has recibido este mensaje porque estás suscrito al grupo "ADO Harbour" de Grupos de Google.
Para cancelar la suscripción a este grupo y dejar de recibir sus mensajes, envía un correo electrónico a ado-harbour...@googlegroups.com.
Para ver esta conversación en el sitio web, visita https://groups.google.com/d/msgid/ado-harbour/daa9752d-c281-4f08-bcca-151ec4dd4a75n%40googlegroups.com.

Antonio Cardinaux

unread,
Sep 2, 2021, 8:50:02 AM9/2/21
to ado-h...@googlegroups.com
Ahi le agregué el refresh a continuación de la línea del :delete(), pero sigue igual, por un momento pensé que era la forma de como abría el objeto ADO, en cursorlocation, pero en el archivo ADO.PRG, está como adUseClient, que supuestamente sirve para ingresar, modificar o borrar registros..., cuando pasó eso salí y volví a entrar en la aplicación, pero el registro sigue estando, así que no se porque no lo borra



--
Antonio Cardinaux - Lanús - Pcia. de  Buenos Aires - Argentina

avazq...@gmail.com

unread,
Sep 2, 2021, 9:05:26 AM9/2/21
to ado-h...@googlegroups.com

 

Hice algún cambio

 

@ 1,10 XBROWSE TbMostrar OBJ oBrwMostrar;

WIDTH 780 ;

HEIGHT 430 ;

WORKAREA ( oRsBrw  ) ;

HEADERS aHeaders ;

FIELDS aFields ;

WIDTHS aWidths ;

COLUMNCONTROLS aCtrl ;

JUSTIFY aJusti ;

READONLY {.T.} ;   

FIXEDBLOCKS ;

DELETE ;

ONDELETE orBrw:Update()                      // sobraba un espacio

DELETEWHEN { || msgyesno("Seguro que desea borrar el registro "+alltrim(orBrw:numreg)+"?") } ;                          // orBrw:numreg es el n de factura o lo que quieras, si quieres confirmar antes de borrar (aconsejable)

 

 

 

    DEFINE BUTTON btnEliminar 

              ROW 120

              COL 10

              CAPTION "&Eliminar" 

              WIDTH 90 

              ACTION DelRow( oC,oRsBrw )

    END BUTTON

  

/***/

static Function DelRow( oC,oRsBrw )    //SI oBrwMostrar lo tienees como local, deberías enviarlo como parámetro.

oRsBrw:Delete()

oRsBrw:update()            // Si no lo pones, no ejecuta la línea anterior.

oBrwMostrar:refresh()

retu  

 

 

SUERTE!!!!

 

 

Antonio Vázquez

avazq...@gmail.com

Antonio Cardinaux

unread,
Sep 2, 2021, 2:17:01 PM9/2/21
to ado-h...@googlegroups.com
Ahi probé con los cambios sugeridos. Lo único diferente que vi fue lo siguiente:

Como después de pulsar el botón borrar veia que el registro seguía estando en la grilla, pulsé de nuevo el botón eliminar, y me arrojó el error:

Error WINOLE/1007 El identificador de fila se refirió a una fila eliminada o a una fila marcada para eliminar. (0x80040E23): Microsoft Cursor Engine (DOS Error -2147352567)

Es la única diferencia que se ve. Como al arrojar ese error se cierra la aplicaci♀n, al volver a ingresar veo que el registro sigue estando. Encima no ejecuta el mensaje del DELETEWHEN, es como que directamente intenta borrar el registro, pero por algún motivo no lo hace.

Antonio Cardinaux

unread,
Sep 2, 2021, 4:49:38 PM9/2/21
to ado-h...@googlegroups.com
Ahi probé otra cosa. Si pulso la tecla DELETE en la fila que quiero borrar del XBROWSE, aparece el mensaje del DELETEWHEN, después aparece otro mensaje más corto, si en los 2 mensajes selecciono Si, ahi si borra el registro y se actualiza el XBROWSE, o sea funciona correctamente. Me faltaría encontrarle la vuelta para el caso de que el usuario quiera borrarlo desde el Botón "Eliminar", ahi es adonde no hace nada.

David Field

unread,
Sep 2, 2021, 8:36:51 PM9/2/21
to ADO Harbour
Hola a todos,

Para borrar un registro del Browse:
1. OnDelete o On Delete (no importa cual usen, OOHG lo entiende igual)

2. El bloque asignado a ON DELETE {|| oRs:Delete(), oRs:Update()}
   oRs:Delete() lo marca para su borrado, el Update() realiza las acciones de borrar, añadir o modificar la info. 

3. Error WINOLE/1007 El identificador de fila se refirió a una fila eliminada o a una fila marcada para eliminar. (0x80040E23): Microsoft Cursor Engine (DOS Error -2147352567)
Este error se da por que el registro YA fue marcado para borrarse y no se puede volver a borrar, lo pueden recuperar si no han realizado el Update() usando el método CancelUpdate().

4. OOHG se encarga de realizar el Refresh() al Browse después del DELETE() y no es necesario realizar Refresh() al RecordSet.

Saludos,
David Field

Antonio Cardinaux

unread,
Sep 3, 2021, 9:17:51 AM9/3/21
to ado-h...@googlegroups.com
Gracias David por la explicación. En el xbrowse funciona bien si uno pulsa la tecla delete, o sea posicionado en el xbrowse, tal como me dijo Antonio, el tema es si el usuario usa el botón que puse en el ejemplo de eliminar, que va a la función DelRow(), ahi lo que hace es:

oRsBrw:Delete()
oRsBrw:Update()
oBrwMostrar:Refresh()

pero esto no borra el registro y obviamente no va a cambiar nada en la grilla.

Gracias Antonio por la ayuda, lo que me sugeriste anduvo muy bien.



David Field

unread,
Sep 8, 2021, 5:26:41 PM9/8/21
to ADO Harbour
Hola,

Me quedé pensando en este caso y me puse a revisar el código del Metodo Delete() en h_xbrowse.prg y este primero borra el registro y posteriormente ejecuta el bloque asignado a ONDELETE por lo tanto la definición del botón puede quedar de esta forma:

DEFINE BUTTON btnEliminar 

              ROW 120

              COL 10

              CAPTION "&Eliminar" 

              WIDTH 90 

              ACTION oBrwMostrar:Delete()    

    END BUTTON

No sé si realizas algo más en  DelRow( oC,oRsBrw ) pero en todo caso NO requieres volver a ejecutar oRsBrw:Update() ya que el método Delete() del xbrowse lo ejecuta.

Saludos,
David Field

Antonio Cardinaux

unread,
Sep 9, 2021, 9:47:54 AM9/9/21
to ado-h...@googlegroups.com
Gracias David, por la prueba que hiciste, quise hacer lo mismo con mi ejemplo y ahora me aparece este error, que antes no me aparecía.

Error: Error WINOLE/1007 El valor de BOF o EOF es True, o el actual registro se eliminó;
la operación solicitada requiere un registro actual. (0x800A0BCD):
ADODB.Field (DOS Error -2147352567)

El error aparece ni bien borro un registro, en la línea de "AADD(aFields,...." de las líneas de más abajo.

La carga del XBROWSE la hago como en SQLAdo.prg:

cSql:="SELECT ... FROM tabla ORDER BY campo LIMIT 100"

If !Hb_IsObject(oC)
  MsgStop("Es necesario realizar primeramente la conexion","Error")
  Return
Endif

TRY
  oRsBrw:= DBADO():New(cSql,oC)
Catch
  MsgStop(cSql, "Error Comando SQL, Comprobantes en pantalla")
  Return
End Sequence

aFields:={}
if !oRsBrw:oRs:Eof()
  For n:= 1 TO oRsBrw:oRs:Fields:Count()
    AADD(aFields, &("{|wa| wa:oRs:Fields("+STR(n-1)+"):Value }")) // Acá arroja el error
  Next n
 
  if IsWindowDefined(frm)
    oGrdMostrar:WorkArea:= oRsBrw
oGrdMostrar:refresh()
  end if
end if

es como que al recorrer el recordset de nuevo y encontrarse con ese registro borrado, arroja el error...,no encontré ninguna sentencia o algo que averigue si tal registro está borrado o marcado para borrar.

Antonio Vázquez

unread,
Sep 9, 2021, 9:57:21 AM9/9/21
to ado-h...@googlegroups.com
El.experto es David.
Pero prueba lo siguiente:
Creo q debes refrescar el oRsBrw

If isw....
ORsBrw:refresh()
OGrdMostrar:workarea:=oRsBrw
Endif


Seguro q él luego matiza y corrige.
Saludos
Antonio Vázquez.



Obtener Outlook para Android

Sent: Thursday, September 9, 2021 3:48:09 PM
To: ado-h...@googlegroups.com <ado-h...@googlegroups.com>
Subject: Re: [ADO Harbour] Consulta para borrar registro en un xBrowse con ADO
 

Antonio Cardinaux

unread,
Sep 9, 2021, 10:21:25 AM9/9/21
to ado-h...@googlegroups.com
Gracias Antonio por el aporte, ahi lo probé pero el error sigue estando, porque el error está en el FOR que está antes de preguntar 

if IsWindowDefined(...

Pero bueno, era cuestión de probar. Gracias.

Antonio Vázquez

unread,
Sep 9, 2021, 10:50:05 AM9/9/21
to ado-h...@googlegroups.com
Te falta avanzar un registro antes del Next

ORaBrw:Skip()

Obtener Outlook para Android

Sent: Thursday, September 9, 2021 4:21:40 PM

Antonio Cardinaux

unread,
Sep 9, 2021, 1:46:24 PM9/9/21
to ado-h...@googlegroups.com
Otro intento más, pero sigue arrojando el mismo error.

David Field

unread,
Sep 9, 2021, 3:54:20 PM9/9/21
to ADO Harbour
Antonio,

Encuentro varias inconsistencias lógicas a tu ejemplo:
1. Si solo sirve en el caso de que exista la ventana o forma frm, entonces yo realizaría esa pregunta al principio, de lo contrario para qué hacer todo eso.
2. Si estas usando un GRID es MUCHO más fácil utilizar GETROWS(cSql, .T.) que de entrada te regresa un array con los valores de los registros y te evitas el TRY y el FOR NEXT.
3. Si por alguna razón requieres del recordset, te sugiero que SIEMPRE lo cierres al terminar de usarlo. A mi me ha causado problemas al no hacerlo.

Saludos,
David

David Field

unread,
Sep 9, 2021, 4:11:15 PM9/9/21
to ADO Harbour
Antonio,

Ejemplo de lo que digo anteriormente si utilizas un GRID:

 if IsWindowDefined(frm)
   cSql:="SELECT ... FROM tabla ORDER BY campo LIMIT 100"
   oGrdMostrar:Items:= GetRows(cSql, .T.)
end if

Si estás usando un xBROWSE:

if IsWindowDefined(frm)
   cSql:="SELECT ... FROM tabla ORDER BY campo LIMIT 100"

  If !Hb_IsObject(oC)
    MsgStop("Es necesario realizar primeramente la conexion","Error")
    Return
  Endif

  TRY
    oRsBrw:= DBADO():New(cSql,oC)
  Catch
    MsgStop(cSql, "Error Comando SQL, Comprobantes en pantalla")
    Return
  End Sequence

  aFields:= aTranspose(oRsBrw:GetRows())

 
   oGrdMostrar:WorkArea:= oRsBrw
   oGrdMostrar:refresh()
end if

----------------------------------------------------
Dicho lo anterior..., no sé para qué quieres aFields, tampoco me quedó claro si el error te está dando cuando borras un registro y luego ejecutas esto.

En tu código se vé:
if !oRsBrw:oRs:Eof()
  For n:= 1 TO oRsBrw:oRs:Fields:Count()
    AADD(aFields, &("{|wa| wa:oRs:Fields("+STR(n-1)+"):Value }")) // Acá arroja el error
  Next n

Sólo quieres los datos de ese registro?
De ser así, y lo borrar y luego quieres hacer esto, esa es la razón de tu error.
A diferencia de DBF, ADO no te permite acceder a registros marcados para borrar.

Si requieres hacer algo antes de borrar... recalcular totales, etc... entonces tendrás que hacerlo antes de marcar el registro para su borrado.

Saludos,
David Field

Antonio Cardinaux

unread,
Sep 9, 2021, 4:31:48 PM9/9/21
to ado-h...@googlegroups.com
Hola David, en realidad lo de aFields, lo usé como el ejemplo de sqlAdo.prg, se carga al principio antes de definir la ventana, de hecho toda esa rutina la puse en una función. Ahora, porque va a esa función cuando borro un registro usando la tecla DELETE dentro del XBROWSE..., no lo sé. Voy a usar un GRID, y Getrows, como dices. Bueno Gracias por los ejemplos.

David Field

unread,
Sep 9, 2021, 5:33:44 PM9/9/21
to ADO Harbour
Antonio,

En SQLADO se carga en aFields los nombres de los campos para que el objeto DBADO regrese los valores.
Tu estás cargando directamente el valor del campo.

No te podría decir a ciencia cierta sin ver el código completo de cómo defines el xBrowse.

Saludos,
David Field

Antonio Cardinaux

unread,
Sep 10, 2021, 8:51:35 AM9/10/21
to ado-h...@googlegroups.com
Hola David, 2 errores me aparecen al querer usar Getrows, tal como pusiste en el ejemplo.
El primero me dice que:

No existe la variable oConn
Llamada desde GetRows(171) in ADO.PRG

Alguien me habia dicho que cuando pasaba algo así, tenia que declarar oConn como public en el módulo desde donde llamo a Getrows(). Después de hacer eso me apareció este nuevo error:

No existe el método Execute
Llamada desde Execute(0)
Llamada desde Getrows(171) in ADO.PRG

Y hasta ahi llegué. ¿Que está faltando?

David Field

unread,
Sep 10, 2021, 12:27:29 PM9/10/21
to ADO Harbour

Si abres ado.prg y miras el código te darás cuenta que oConn debe ser variable pública donde reside la conexión a SQL... el objeto de conexión de ADO

Saludos,
David Field

Antonio Cardinaux

unread,
Sep 10, 2021, 2:30:48 PM9/10/21
to ado-h...@googlegroups.com

Como se ve que hay algo que no entiendo, me salí del ejemplo que puse como principal de este post, e hice uno aparte sencillo, pero que me sirve para lo de Getrows:

Ej.

/***/
FUNCTION PR_20210910( oC ) // oC es el objeto de conexión ADO

local aClie,cSql,oRs

aClie:={} // Un array común

cSql:="SELECT nombre FROM clientes ORDER BY nombre"
oRs:=Ado(cSql,oC)
aClie:=oRs:GetRows() 

Si esto lo hago así funciona sin problemas, pero si hago esto otro:

aClie:={}
cSql:="SELECT nombre FROM clientes ORDER BY nombre"
oRs:=Ado(cSql,oC)
aClie:=oRs:GetRows("SELECT nombre FROM clientes ORDER BY nombre",.T.) 

Ahi ya me arroja un error.
y si directamente hago como dices en el ejemplo que me pasaste:

aClie:=GetRows("SELECT nombre FROM clientes ORDER BY nombre",.T.) 

Me aparece 

No existe el método Execute

Puse el segundo ejemplo, porque es lo que habias puesto como manejo de Getrows en este posteo, y por lo que vi en otros posteos del mismo grupo, pero evidentemente hay algo que no me doy cuenta que me está faltando

David Field

unread,
Sep 11, 2021, 1:34:01 PM9/11/21
to ADO Harbour
Antonio,

Exactamente no entiendes por que probablemente no has abierto ado.prg para ver qué y cómo hace las cosas.

GetRows() es un método del objeto recordset que te regresa un array con la información contenida en el recordset.
Para ver el funcionamiento de oRs:GetRows()  ADO GetRows Method (w3schools.com)

En ado.prg yo creé aparte una función que se llama GetRows() que recibe como parámetro la instrucción SQL
Este es el extracto de ado.prg de la función GetRows()

*-----------------------------------------------------------------------------*
/* Esta función regresa en un array multidimensional los valores de los campos solicitados en cSQL 
Eg: GetRows("SELECT nombre, clave FROM departamentos")   util para COMBOBOX
=> { {nombre1, nombre2, ...}, {clave1, clave2, ...} }

La funcion aTranspose cambia el array al contrario de como está.
Si lToRec lo cambia a forma registro para que cada arreglo sea como un registro
Eg: GetRows("SELECT nombre, clave FROM departamentos", .T.)   util para GRID
=> { {nombre1, clave1}, {nombre2, clave2}, ...}
*/
Function GetRows(cSql, lToRec)
*-----------------------------------------------------------------------------*
Local aArray, oRs 
DEFAULT lToRec TO .F.

oRs := oConn:Execute(cSql)
If oRs:Eof
aArray := ARRAY(oRs:Fields:Count(),1)
Else
aArray := oRs:GetRows()
Endif
oRs:Close()
Return If(lToRec, aTranspose(aArray), aArray )

La primera instrucción que ejecuta es oRs:= oConn:Execute(cSql) donde oConn es la variable pública que contiene el objeto conexión, en tu caso es oC.
Si siempre quieres utilizar oC como tu variable que contiene el objeto de conexión, entonces cambia en ado.prg oConn por oC... o alternativamente:
1. Abre ADO.prg
2. Agrega a la funcion AdoConn
Function AdoConn(Server, Database, User, Pass, Engine, Port)
Local oC, sConection, nOption
Public oConn   // agrega esta linea

y al final
...
END SEQUENCE 
        oConn := oC   // agrega esta linea
Return oC
3. Guarda ado.prg

Execute() es método del objeto conexión que ejecuta la instrucción SQL y el resultado lo regresa en un RecordSet

Por qué creé una función GetRows()?
Es más rápido por que el Execute() del objeto conexión ejecuta la instrucción SQL y regresa el RecordSet el cual utilizo para ejecutar su metodo GetRows() y regresar el array.
Todo de forma muy sencilla y eficiente.

aClie:=oRs:GetRows("SELECT nombre FROM clientes ORDER BY nombre",.T.)  da error por que no son los parámetros adecuados para el Método GetRows()

aClie:=GetRows("SELECT nombre FROM clientes ORDER BY nombre",.T.)  de error que no existe el metodo Execute por que oConn NO ES oC
Este error lo puedes evitar siguiendo mis sugerencias de cambio en ADO.prg o sencillamente agregando a tu funcion:

/***/
FUNCTION PR_20210910( oC ) // oC es el objeto de conexión ADO

local aClie,cSql,oRs
PUBLIC oConn := oC


Entonces oConn SI ES oC... el objeto de conexión.

Saludos,
David Field

Antonio Cardinaux

unread,
Sep 13, 2021, 2:51:30 PM9/13/21
to ado-h...@googlegroups.com
Ahi funciona bien con las adaptaciones que me dijiste David. Gracias.
Lo único que no me funciona, es cuando quiero cargar directamente el Grid con lo que devuelve Getrows()

oGrdMostrar:items:=Getrows(cSql,.T.)

Al hacer eso me muestra el mensaje

Error BASE/1005 Message not found: TGRID:_ITEMS

Es medio raro, porque si lo hago como estaba haciendolo antes, o sea asigando a un recordset el valor de cSql, y cargando el recordset en un ciclo for ahi me lo carga sin problemas. O sea:

oRs:=Ado(cSql,oC)

for n:=1 to oRs:recordcount()
  oGrdMostrar:ADDITEM( {oRs:fields:item("campo1"):value, oRs:fields:item("campo2"):value} )
  oRs:MoveNext()
end for

Bueno eso funciona OK!

Antonio Cardinaux

unread,
Sep 13, 2021, 3:25:38 PM9/13/21
to ado-h...@googlegroups.com
Ya está, me contesto yo mismo, es 

:aitems
no
:items

Se me dió por buscar el error que arrojaba en el grupo de OOHG, y por suerte habia un posteo acerca del tema. 

David Field

unread,
Sep 15, 2021, 12:02:46 PM9/15/21
to ADO Harbour
Antonio,

Me alegro que hayas encontrado el problema.
Cuando tengas un error similar, es muy fácil encontrarlo.

Error BASE/1005 Message not found: TGRID:_ITEMS
El error te dice que no encuentra el mensaje _ITEMS para el objeto TGRID.
Algo a saber de objetos:
1. En OOHG todos los objetos comienzan con "T", por lo tanto estamos hablando del GRID
2. Cuando veas un '_' antes del nombre de la variable de instancia (mensaje o método) es que se le está haciendo una asignación. Igualmente te pudiera dar el mensaje de error con TGRID:ITEMS y sería porque está tratando de tomar el valor de la variable de instancia, por lo tanto, la variable con el error se llama 'ITEMS' y si abres h_grid.prg puedes buscar a ver si existe o si es un error de tipografía.  Nota: Es necesario también ver las variables de instancia de los objetos padres.

Saludos,
David Field

Antonio Cardinaux

unread,
Sep 16, 2021, 8:04:35 AM9/16/21
to ado-h...@googlegroups.com
Gracias David por la orientación en la parte de objetos.

José Orozco

unread,
Oct 2, 2021, 3:18:39 AM10/2/21
to ado-h...@googlegroups.com

Buenas noches.. Llevo bastante tiempo con este error. En un principio creí que era algo de mi código, al intentar editar una celda del browse y validar su contenido. Pero he quitado toda opción de validación.

Este es el menaje de error :

Aplicación: D:\Progamacion\Proyectos\Servicios\servicio.exe
Fecha: 01/09/2021  Hora: 21:59:19
Versión: OOHG Ver. 2020.06.08.rc1 (32 bits)
Alias en uso: SERVICIOS
Nombre de Equipo: LENOVOJOSE
Nombre de Usuario: LENOVOJOSE
Error: Error DBFCDX/1022  Se requiere bloqueo
desde (b)FIELDWBLOCK (0)
Llamada desde _OOHG_EVAL (0)
Llamada desde TXBROWSE:EDITCELL (2066)
Llamada desde TOBROWSE:EDITCELL (1157)
Llamada desde TOBROWSE:EDITALLCELLS (1290)
Llamada desde TOBROWSE:EVENTS_ENTER (3408)
Llamada desde TWINDOW:EVENTS (0)
Llamada desde _OOHG_TFORM_EVENTS2 (1830)
Llamada desde TFORM:EVENTS (0)
Llamada desde _OOHG_DOMESSAGELOOP (0)
Llamada desde TFORM:MESSAGELOOP (640)
Llamada desde TFORM:ACTIVATE (623)
Llamada desde PRINCIPAL (75)
Llamada desde MAIN (37)
--


Asi esta definido el browse:


@ 120, 10 BROWSE bServicios ;
      OBJ oServicios ;
      WIDTH 1300 ;
      HEIGHT 500 ;
      HEADERS { 'Teléfono', 'Dirección','Movil','Parad.','Observaciones','Hora R','Fecha R','Fecha D','Hora_D'  } ;
      WIDTHS { 140, 500, 80 , 85, 380, 110,110,110,110 } ;
      WORKAREA 'Servicios' ;
      FIELDS { 'Telefono', 'Direccion','Movil','Paradero','Observa','Hora_R','Fecha_R','Fecha_D ', 'Hora_D '} ;
      FONT "Roboto" SIZE 16 FONTCOLOR { 0, 0, 0 } ;
      BACKCOLOR { 225, 241, 255 } ;
      DYNAMICBACKCOLOR { bColor , bColor , bColor , bColor , bColor , bColor , bColor, bColor , bColor } ;
      DYNAMICFORECOLOR { bColor2, bColor2, bColor2, bColor2, bColor2, bColor2, bColor2, bColor2, bColor2} ;
      ON GOTFOCUS {|| oServicios:gobottom()} ;
      EDIT ;
      READONLY { .T., .T., .F., .F., .F., .T.,.T.,.T.,.T. } ;
      LOCK ;
      DELETE INPLACE;

  JUSTIFY { BROWSE_JTFY_LEFT, BROWSE_JTFY_LEFT, BROWSE_JTFY_CENTER ,BROWSE_JTFY_CENTER, BROWSE_JTFY_LEFT,                         BROWSE_JTFY_RIGHT,BROWSE_JTFY_RIGHT,BROWSE_JTFY_RIGHT,BROWSE_JTFY_RIGHT} ;
      NOVSCROLL ;
      DELETEMSG "Cancelando servicio" ;
      ON DELETE {|| Guardar_Conteo("3")} ;
      SELECTEDCOLORS { WHITE, {65,105,225}, WHITE, {128,128,128}, {106,90,205}, {135,206,250}, {105,105,105},{220,220,220} } ;
      SYNCHRONIZED ;
      DISABLEALTA


Sin embargo sigue generando ese error,, Y la base de datos debe abrirse en mode shared porque se trabaja en red..


!!! AYUDA POR  FAVOR ¡¡

David Field

unread,
Oct 3, 2021, 1:30:46 PM10/3/21
to ADO Harbour
Hola José,

Este grupo está más enfocado a la utilización de tablas SQL con ADO, pero... vamos tratando de ayudarte.

En primer lugar, te recomiendo que quites el  ON GOTFOCUS {|| oServicios:gobottom()} 
Windows es multitask y esa instrucción le dice que al tener el foco se mueva al final del archivo.
Cuando entras a editar una columna del Browse se crea una ventana con el control necesario para su edición, por lo tanto, el browse pierde el foco.
Al terminar de editar, se destruye la ventana de edición y el browse recupera el foco y por ende se ejecuta el ON GOTFOCUS
Es PROBABLE que se esté realizando el LOCK en el registro correcto, pero antes de grabar el dato este haya sido movido por tu instrucción OnGotFocus

Si esto no resuelve tu problema, (me apena decirlo pero) te sugiero que nos hagas llegar un prg compilable de tu problema junto con un esqueleto del DBF y cualquier indice necesario para intentar ayudarte.

Saludos,
David Field

PD. En un futuro, por favor abre una conversación nueva para tu mensaje en lugar de agregarlo como respuesta a otra conversación.

José Orozco

unread,
Oct 5, 2021, 10:35:22 AM10/5/21
to ado-h...@googlegroups.com

Muchas Gracias..  esa recomendación me solucionó el problema.


tenia esa clausula porque necesito que se muestren siempre los ultimos registros del browse ,, voy a ver como solucino eso entonces..


de Nuevo muchas Gracias

--
Has recibido este mensaje porque estás suscrito al grupo "ADO Harbour" de Grupos de Google.
Para cancelar la suscripción a este grupo y dejar de recibir sus mensajes, envía un correo electrónico a ado-harbour...@googlegroups.com.
Para ver esta conversación en el sitio web, visita https://groups.google.com/d/msgid/ado-harbour/80207c66-629d-4a1e-825e-33f84f54a0a5n%40googlegroups.com.
--

José Francisco Orozco

Whatsapp : +573506080326

Facebook :JoseOrozcoCucuta

José Orozco

unread,
Oct 5, 2021, 11:11:36 AM10/5/21
to ado-h...@googlegroups.com
Buenos días  a todos.

Saludos desde Colombia.


Desde hace tiempo ya he intentado migrar hacia motores Sql, de
preferencia MySql (MariasDb). pero no he logrado entender los pasos
iniciales. Los requerimientos y me gustaría saber cuales son y cuales
serian los pasos o instrucciones para hacer un CRUD, obvio basico.. y
como hacerlo usando el recordSet.



Muchas Graias

David Field

unread,
Oct 7, 2021, 1:21:14 AM10/7/21
to ADO Harbour
José,

Al entrar al grupo, hay un link para descargar un programa de prueba para MySQL y/o MariaDB.
Postea cualquier problema que tengas y te resolvemos.

POR FAVOR, si no estás contestando a una conversación, usa el botón de "Nueva Conversación" para tus preguntas, de esa manera ayudas a los demás que buscan en el grupo a resolver problemas.

Gracias,
David Field

Sergio Luengo

unread,
Jan 8, 2024, 2:22:58 PM1/8/24
to ado-h...@googlegroups.com

Hola buenos dias.

Necesitaria saber si se puede enviar whatsapp desde harbour

Si alguien me puede dar una mano se los agradeceria.

O algun link donde pueda consegir info

Muchas Gracias.

Sergio.

 


Enviado el: martes, 5 de octubre de 2021 11:33
Para: ado-h...@googlegroups.com

Ricardo Sassy

unread,
Jan 8, 2024, 3:19:16 PM1/8/24
to ado-h...@googlegroups.com

Hola Sergio.

Lamentablemente no hay una forma rápida, práctica y económica de hacer interface con Whatsapp.

La gente de Meta te vende una suscripción para abrir una cuenta de negocios y luego te dan acceso a la API para que puedas dotar a tu programa con la funcionalidad de envío de mensajes.

Esta es la página oficial: https://developers.facebook.com/docs/whatsapp

Los precios están basados en el concepto de “conversaciones” y tienen distinto valor según sea el tipo de “conversación”.

También hay empresas que funcionan como intermediarias, con sus propias api’s, y te permiten contratar servicios para el envío de mensajes desde tus propias apps.

Esta es una de ellas: https://www.infobip.com/whatsapp-business/api

Como en EEUU whatsapp se usa poco y nada (ellos usan sms a morir…) no hay muchos desarrollos de este tipo.

 

Saludos...

Ricardo Sassy   

Sergio Daniel Gudiño

unread,
Jan 8, 2024, 3:22:48 PM1/8/24
to ado-h...@googlegroups.com
Hola buenas tardes

me parece que te equivocastes de Sergio



jajajajaja

feliz año
abrazo

Sergio Gudiño

Ricardo Sassy

unread,
Jan 8, 2024, 3:46:02 PM1/8/24
to ado-h...@googlegroups.com

Es verdad !!!

 

Saludos y buen año.

Espero que Sergio Luengo lo lea.

 

 

danr...@gmail.com

unread,
Jan 8, 2024, 4:17:18 PM1/8/24
to ado-h...@googlegroups.com

Hola,

Yo lo pude resolver de una forma primitiva para unos cientos de mensajes que envía un cliente:

Sin pagarle nada a Meta

El cliente tiene que tener instalada la app de WhatsApp de escritorio.

Parte del código es el que sigue:

 

                    mensaje:=strtran("whatsapp://send?phone=549"+alltrim(numerodestino)+" &text=Buenos días. Su liquidación ya se encuentra disponible para facturar, nuestro CUIT es 30-54605367-5, somos responsable inscripto. Puede mandar su factura por este medio o al correo compro...@sanatorioxxxxx.com.ar. El importe a facturar es $ "+alltrim(tran(m->importe,'999,999,999.99'))+" "+txt_escrito+". Muchas Gracias."," ","%20")

                    Wapi_ShellExecute( NIL, "open", xmensaje,,,11)

                    HB_IDLESLEEP(1)

                    oShell:sendkeys("~")

 

cualquier duda, me preguntás

Saludos

Daniel

La Reja- Bs As

Argentina

 

 

De: ado-h...@googlegroups.com <ado-h...@googlegroups.com> En nombre de Sergio Luengo
Enviado el: lunes, 8 de enero de 2024 16:23
Para: ado-h...@googlegroups.com
Asunto: RE: [ADO Harbour] Consulta envios whatsapp

 

Hola buenos dias.

Sergio Luengo

unread,
Jan 9, 2024, 8:11:56 AM1/9/24
to ado-h...@googlegroups.com

Hola grupo.

 

Si, lei todos los mensajes que me enviaron.

 

Muchas gracias a todos por la info.

 

Voy a probar lo de Daniel para whatsapp. Y le comento como de va.

 

*--------------------------------*

 

Y les pregunto otra mas, como me escribiste Ricardo  el envio de sms, se puede hacer con harbour y hay que contratar un servicio si o si.

 

Porque mi primer idea era la de enviar sms pero se me complico un poco. Y no lo logre.

 

 

Saludos !!

Sergio Luengo

General Pico

La Pampa

Reply all
Reply to author
Forward
0 new messages