Again xBrowse and new line from TDatabase
Again xBrowse and new line from TDatabase
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 ...
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.
- James Bott
- Posts: 4840
- Joined: Fri Nov 18, 2005 4:52 pm
- Location: San Diego, California, USA
- Contact:
Re: Again xBrowse and new line from TDatabase
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
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
Re: Again xBrowse and new line from TDatabase
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 ...
![Smile :-)](./images/smilies/icon_smile.gif)
Maybe you are right ...
![Smile :-)](./images/smilies/icon_smile.gif)
![Smile :)](./images/smilies/icon_smile.gif)
![Wink :wink:](./images/smilies/icon_wink.gif)
Regards !
Rimantas U.
- Otto
- Posts: 6403
- Joined: Fri Oct 07, 2005 7:07 pm
- Has thanked: 24 times
- Been thanked: 2 times
- Contact:
Re: Again xBrowse and new line from TDatabase
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
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
********************************************************************
mod harbour - Vamos a la conquista de la Web
modharbour.org
https://www.facebook.com/groups/modharbour.club
********************************************************************
Re: Again xBrowse and new line from TDatabase
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.
- nageswaragunupudi
- Posts: 10721
- Joined: Sun Nov 19, 2006 5:22 am
- Location: India
- Been thanked: 8 times
- Contact:
Re: Again xBrowse and new line from TDatabase
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.
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
#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
G. N. Rao.
Hyderabad, India
- James Bott
- Posts: 4840
- Joined: Fri Nov 18, 2005 4:52 pm
- Location: San Diego, California, USA
- Contact:
Re: Again xBrowse and new line from TDatabase
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
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
- nageswaragunupudi
- Posts: 10721
- Joined: Sun Nov 19, 2006 5:22 am
- Location: India
- Been thanked: 8 times
- Contact:
Re: Again xBrowse and new line from TDatabase
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
G. N. Rao.
Hyderabad, India
- James Bott
- Posts: 4840
- Joined: Fri Nov 18, 2005 4:52 pm
- Location: San Diego, California, USA
- Contact:
Re: Again xBrowse and new line from TDatabase
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
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
- nageswaragunupudi
- Posts: 10721
- Joined: Sun Nov 19, 2006 5:22 am
- Location: India
- Been thanked: 8 times
- Contact:
Re: Again xBrowse and new line from TDatabase
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
G. N. Rao.
Hyderabad, India
Re: Again xBrowse and new line from TDatabase
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 ...
![Smile :-)](./images/smilies/icon_smile.gif)
![Smile :)](./images/smilies/icon_smile.gif)
Regards !
Rimantas U.
- nageswaragunupudi
- Posts: 10721
- Joined: Sun Nov 19, 2006 5:22 am
- Location: India
- Been thanked: 8 times
- Contact:
Re: Again xBrowse and new line from TDatabase
>>
. 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.
. 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
G. N. Rao.
Hyderabad, India
Re: Again xBrowse and new line from TDatabase
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