Again xBrowse and new line from TDatabase

Again xBrowse and new line from TDatabase

Postby Rimantas » Mon Oct 19, 2009 4:13 pm

Hi ,

It seems that I can't understand how to insert a new BLANK line in xBrowse . xBrose is working with TDataBase object . In tDataBase class exist method Blank() , but I can't to add a new blank line to xBrowse ... Is this possible ?

Many thanks for any help in advance ...
Rimantas U.
User avatar
Rimantas
 
Posts: 437
Joined: Fri Oct 07, 2005 12:56 pm
Location: Utena , Lithuania

Re: Again xBrowse and new line from TDatabase

Postby James Bott » Mon Oct 19, 2009 4:53 pm

Rimintas,

That is one of the problems I was trying to explain. You can add a blank record to a TDatabase object but you cannot display it in the browse. Then blank is just an empty aBuffer so you cannot see it by doing a goBottom() because there is no blank record. Going to the bottom will load that last record into aBuffer for display which is not what you want.

So whether you use a database object or not you will have to add a new blank record to get a blank record to display in the browse. Then if the user decides not to save the new record you will have to delete it.

As I mentioned before this is one reason it is so much easier to use a dialog for record editing. With a database object you can edit a blank buffer and thus only if the user wants to save the record is a new record added to the database.

James
User avatar
James Bott
 
Posts: 4840
Joined: Fri Nov 18, 2005 4:52 pm
Location: San Diego, California, USA

Re: Again xBrowse and new line from TDatabase

Postby Rimantas » Mon Oct 19, 2009 5:25 pm

James Bott wrote:Rimintas,

That is one of the problems I was trying to explain. You can add a blank record to a TDatabase object but you cannot display it in the browse. Then blank is just an empty aBuffer so you cannot see it by doing a goBottom() because there is no blank record. Going to the bottom will load that last record into aBuffer for display which is not what you want.

So whether you use a database object or not you will have to add a new blank record to get a blank record to display in the browse. Then if the user decides not to save the new record you will have to delete it.

As I mentioned before this is one reason it is so much easier to use a dialog for record editing. With a database object you can edit a blank buffer and thus only if the user wants to save the record is a new record added to the database.

James


James , my name is Rimantas ... :-)

Maybe you are right ... :-) But I hope that this can be solved ... In mine opinion , dialogs for inputs of new records isn't a good way . In mine main workplace I'm working with Microsoft Bussines Solution - Axapta , so I can compare some technologies . Of course , the database here is Oracle and here programmatically is done that grid can show a new blank record , because any SQL can do that . You can refuse from the new record without any risk , until "ttsbegin" and "ttscommit" transactions aren't running or save new record in database . Of course SQL technologies differs from DBF's , sorry . But I'm not believing that xBrowse can't to solve a such small problem ... :) . I hope that Antonio will answer or will give some good ideas how to do that ... :wink: . So why use Blank() in TDatabase if you can't add this in browse ? Only for input dialogs ?

Regards !
Rimantas U.
User avatar
Rimantas
 
Posts: 437
Joined: Fri Oct 07, 2005 12:56 pm
Location: Utena , Lithuania

Re: Again xBrowse and new line from TDatabase

Postby Otto » Mon Oct 19, 2009 6:23 pm

Hello Rimantas,

maybe you can - what I do often – read your records into an array and then work with this array and xBrowse.
I mean then you have something similar to a recordSet.
Best regards,
Otto
********************************************************************
mod harbour - Vamos a la conquista de la Web
modharbour.org
https://www.facebook.com/groups/modharbour.club
********************************************************************
User avatar
Otto
 
Posts: 6329
Joined: Fri Oct 07, 2005 7:07 pm

Re: Again xBrowse and new line from TDatabase

Postby Rimantas » Mon Oct 19, 2009 6:59 pm

Otto wrote:Hello Rimantas,

maybe you can - what I do often – read your records into an array and then work with this array and xBrowse.
I mean then you have something similar to a recordSet.
Best regards,
Otto


Hello Otto ,

Interesting idea ... But , as I can understand , this can be problem with a big table , or not ?

Regards !
Rimantas U.
User avatar
Rimantas
 
Posts: 437
Joined: Fri Oct 07, 2005 12:56 pm
Location: Utena , Lithuania

Re: Again xBrowse and new line from TDatabase

Postby nageswaragunupudi » Mon Oct 19, 2009 7:03 pm

Here is a small sample. Not perfect, but can be improved upon. This sample uses the sales.dbf in the fwh\samples folder.

This is the logic I was using in the DOS-Clipper days. The skip block here is adopted from samples provided by Clipper for DBU and Browse in their sample folder. This needs to be improved but this is a working sample with a few minor bugs to be resolved.
Code: Select all  Expand view
#include "FiveWin.Ch"
#include "ord.ch"
#include "xbrowse.ch"

REQUEST DBFCDX

static aNew
static lAppend := .f.

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

function Main()

   local oDlg, oBrw

   USE SALES NEW EXCLUSIVE

   aNew  := Array( Sales->( FCount() ) )
   BlankArray()

   DEFINE DIALOG oDlg SIZE 440,440 PIXEL

   @ 10,10 XBROWSE oBrw SIZE 200,200 PIXEL OF oDlg ;
      COLUMNS 'Date', 'Client', 'Article' ;
      ALIAS 'SALES' LINES CELL FASTEDIT

   oBrw:aCols[ 1 ]:bEditValue := { |x| If( x == nil, If( Sales->( RecNo() > LastRec() ), aNew[ 1 ], Sales->Date ), ;
            If( Sales->( RecNo() > LastRec() ), aNew[ 1 ] := x, Sales->Date := x ) ) }

   oBrw:aCols[ 2 ]:bEditValue := { |x| If( x == nil, If( Sales->( RecNo() > LastRec() ), aNew[ 2 ], Sales->Client ), ;
            If( Sales->( RecNo() > LastRec() ), aNew[ 2 ] := x, Sales->Client := x ) ) }

   oBrw:aCols[ 3 ]:bEditValue := { |x| If( x == nil, If( Sales->( RecNo() > LastRec() ), aNew[ 3 ], Sales->Article ), ;
            If( Sales->( RecNo() > LastRec() ), aNew[ 3 ] := x, Sales->Article := x ) ) }

   AEval( oBrw:aCols, { |o| o:nEditType := EDIT_GET } )
   AEval( oBrw:aCols, { |o| o:bOnChange := { || OnChange( oBrw ) } } )

   ADD TO oBrw DATA RecNo() HEADER 'RecNo'

   oBrw:bSkip     := { |n| Sales->( NewSkipper( n ) ) }
   oBrw:bKeyCount := { || Sales->( LastRec() ) + If( lAppend, 1, 0 ) }
   oBrw:bKeyNo    := { || Sales->( RecNo() ) }
   oBrw:bPastEof  := { || If( ! Eof(), ( lAppend := .t., BlankArray(), oBrw:GoDown(), oBrw:KeyCount() ), nil ) }
   oBrw:bChange   := { || If( lAppend .and. ! Eof(), ( lAppend := .f., BlankArray(), oBrw:Refresh() ), nil ) }

   oBrw:bRClicked := { || xbrowse( anew ) }

   oBrw:CreateFromCode()

   ACTIVATE DIALOG oDlg CENTERED

   CLOSE SALES


return ( 0 )

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

init procedure PrgInit

    SET DATE ITALIAN
    SET CENTURY ON
    SET EPOCH TO YEAR(DATE())-50
    SET DELETED ON
    SET EXCLUSIVE OFF

    RDDSetDefault( 'DBFCDX' )
    SET OPTIMIZE ON

return

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

exit procedure PrgExit

    SET RESOURCES TO

return

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

static function NewSkipper( nSkip )

   local nSkipped := 0

   DEFAULT nSkip  := 1

   if nSkip == 0
//      DbSkip( 0 )
   elseif nSkip > 0

      do while nSkipped < nSkip .and. ! Eof()
         DbSkip( 1 )
         if Eof()
            if lAppend
               nSkipped++
            else
               DbSkip( -1 )
            endif
            exit
         endif
         nSkipped++
      enddo

   else
      do while nSkipped > nSkip
         DbSkip( -1 )
         if Bof()
            DbGoTop()
            Exit
         else
            nSkipped--
         endif
      enddo
   endif

return nSkipped

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

static function BlankArray()

   local n

   for n := 1 to Len( aNew )
      aNew[ n ]  := Blank( Sales->( FieldGet( n ) ) )
   next n

return nil

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

static function OnChange( oBrw )

   if Sales->( Eof() )
      if ! Empty( aNew[ 1 ] ) .and. ! Empty( aNew[ 2 ] )
         Sales->( DbAppend() )
         Sales->Date := aNew[ 1 ]
         Sales->Client := aNew[ 2 ]
         Sales->Article := aNew[ 3 ]
         oBrw:GoBottom()
         oBrw:Refresh()
      endif
   endif

return nil

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

 
Regards

G. N. Rao.
Hyderabad, India
User avatar
nageswaragunupudi
 
Posts: 10625
Joined: Sun Nov 19, 2006 5:22 am
Location: India

Re: Again xBrowse and new line from TDatabase

Postby James Bott » Mon Oct 19, 2009 7:19 pm

Rao,

Good example. I was just thinking about that a similar thing could be done with a subclass of TDatabase.

One problem I see with your example is that it will only work with databases in natural order.

Regards,
James
User avatar
James Bott
 
Posts: 4840
Joined: Fri Nov 18, 2005 4:52 pm
Location: San Diego, California, USA

Re: Again xBrowse and new line from TDatabase

Postby nageswaragunupudi » Mon Oct 19, 2009 7:28 pm

James Bott wrote:Rao,

Good example. I was just thinking about that a similar thing could be done with a subclass of TDatabase.

One problem I see with your example is that it will only work with databases in natural order.

Regards,
James


Yes. This is a quick sample. We can improve it. I felt it too much to handle the index issues right now. Once the basic logic falls in place, it can be extended. Still there are one or two bugs in up and down navigation.

It is really worthwhile, if you can bring in similar improvement in your TData and FWin brings it in TDataBase class.
No doubt, some effort is required, but can be done.

As you suggested, we can probably start experimenting with a subclass of TDataBase
Regards

G. N. Rao.
Hyderabad, India
User avatar
nageswaragunupudi
 
Posts: 10625
Joined: Sun Nov 19, 2006 5:22 am
Location: India

Re: Again xBrowse and new line from TDatabase

Postby James Bott » Mon Oct 19, 2009 10:29 pm

Rao,

Actually, it is easy using TData. TData has an optional subclass that automatically recycles deleted records, so it is no problem to add and then delete a record (the most deleted records you would ever have is one). No database packing ever required.

James
User avatar
James Bott
 
Posts: 4840
Joined: Fri Nov 18, 2005 4:52 pm
Location: San Diego, California, USA

Re: Again xBrowse and new line from TDatabase

Postby nageswaragunupudi » Tue Oct 20, 2009 2:46 am

James Bott wrote:Rao,

Actually, it is easy using TData. TData has an optional subclass that automatically recycles deleted records, so it is no problem to add and then delete a record (the most deleted records you would ever have is one). No database packing ever required.

James

This is a very good feature. We don't really have to bother about inserting a ghost row.
Regards

G. N. Rao.
Hyderabad, India
User avatar
nageswaragunupudi
 
Posts: 10625
Joined: Sun Nov 19, 2006 5:22 am
Location: India

Re: Again xBrowse and new line from TDatabase

Postby Rimantas » Tue Oct 20, 2009 5:24 am

nageswaragunupudi wrote:
James Bott wrote:
Yes. This is a quick sample. We can improve it. I felt it too much to handle the index issues right now. Once the basic logic falls in place, it can be extended. Still there are one or two bugs in up and down navigation.

It is really worthwhile, if you can bring in similar improvement in your TData and FWin brings it in TDataBase class.
No doubt, some effort is required, but can be done.

As you suggested, we can probably start experimenting with a subclass of TDataBase


In mine opinion it's needfull to do subclass in xBrowse ... :-) . Here is static class - TXBrRow() . This is used only in CurrentRow() method . I can image that this class can be extended as for a new blank line , a la array line . Then extend in xBrowse class Paints methods , some DATAs for a new row condition and codeblocks ... It seems that I'll try to do something ... :)

Regards !
Rimantas U.
User avatar
Rimantas
 
Posts: 437
Joined: Fri Oct 07, 2005 12:56 pm
Location: Utena , Lithuania

Re: Again xBrowse and new line from TDatabase

Postby nageswaragunupudi » Tue Oct 20, 2009 6:27 am

>>
. Here is static class - TXBrRow() . This is used only in CurrentRow() method
>>
The purpose of this class is different. I was intended to help editing a row in a Dialog and not for inline editing. Particularly to solve the occasional problem of the underlying browse's record pointer getting disturbed due refresh reasons, while a particular record is being edited in a dialog in the foreground.
Regards

G. N. Rao.
Hyderabad, India
User avatar
nageswaragunupudi
 
Posts: 10625
Joined: Sun Nov 19, 2006 5:22 am
Location: India

Re: Again xBrowse and new line from TDatabase

Postby anserkk » Tue Oct 20, 2009 6:46 am

As I mentioned before this is one reason it is so much easier to use a dialog for record editing.


In mine opinion , dialogs for inputs of new records isn't a good way . I


maybe you can - what I do often – read your records into an array and then work with this array and xBrowse.
I mean then you have something similar to a recordSet.


In my clipper app, for many years I am using the technique of having a temporary database for grid style data entry. I insert blank records to the DBF for new grid lines and if the user wants to cancel the new entry, I delete the record from the DBF, . This is working fine here in multi user environment. Just an idea.

Regards
Anser
User avatar
anserkk
 
Posts: 1332
Joined: Fri Jun 13, 2008 11:04 am
Location: Kochi, India


Return to FiveWin for Harbour/xHarbour

Who is online

Users browsing this forum: Google [Bot] and 91 guests