dbcombo blank

dbcombo blank

Postby brewster » Tue Dec 09, 2014 7:42 am

I have been using Dbcombos without problem in an existing program unchanged for 2 years.
Recently I recompiled with my new FWH 14.08 from FWH 6.12
Afterwards, I noticed that the last 2 dbcombos in the edit module are displaying blank values while all the rest are displaying their proper .dbf fields, upon edit.

I have added separate "gets" for each of the cDesc1 and cDesc2 vars to show the .dbf values do exist and display OK, just not in the same dbcombo vars.
Also, upon saving the edit even though these 2 dbcombo vars are showing blank they save with their respective original values correctly.

I attach a segment of that code.
Each dbcombo draws off of different .dbfs' oDbc1, 2, 3, 4
Vars are set as locals.

Hopefully I've included and portrayed the problem effectively.

Any help appreciated,
Bruce


>>>>>>
@ 8.5, 4.5 SAY "&D" OF oDlg SIZE 5, 11 color CLR_BLACK, rgb(236,245,255)
@ 126, 40 dbcombo oDBC1 var cDrpD of oDlg;
alias oTcomp:cAlias;
size 100,220 pixel;
itemfield "COD" ;
listfield "COMP";
update;

// this dbcombo and all the ones above, display the selected .dbf fields properly

@ 9.75, 3 SAY "D&river" OF oDlg SIZE 22, 11 color CLR_BLACK, rgb(236,245,255)
@ 146, 40 dbcombo oDBC2 var cDrvr of oDlg;
alias oTdrv:cAlias;
size 50,250 pixel;
itemfield "DRVR" ;
listfield "TNAME";
update;


@ 10.9, 4 SAY "Qty 1" OF oDlg SIZE 22, 11 color CLR_BLACK, rgb(236,245,255)
@ 12.5, 5 GET cQty1 OF oDlg SIZE 10, 11 Pict 'NN'

//cDesc2 will not display in the dbcombo, upon opening module for edit ???????
@ 10.9, 10 SAY "d&Esc1" OF oDlg SIZE 30, 16 color CLR_BLACK, rgb(236,245,255)
@ 163, 80 dbcombo oDBC4 var cDesc1 of oDlg;
alias oTDesc:cAlias;
size 40,75 pixel;
itemfield "COD" ;
listfield "DESC";
update;

// cDesc1 will display in this get
@ 12.25 , 17 get cDesc1 OF oDlg SIZE 20, 10

//--------

@ 12.25, 4 SAY "Qty 2" OF oDlg SIZE 22, 11 color CLR_BLACK, rgb(236,245,255)
@ 14.0 , 5 GET cQty2 OF oDlg SIZE 10, 11 Pict 'NN'

@ 12.25, 10 SAY "de&Sc2" OF oDlg SIZE 30, 16 color CLR_BLACK, rgb(236,245,255)

//cDesc2 will NOT display in this dbcombo upon opening module for edit ?????????
@ 183 , 80 dbcombo oDBC4 var cDesc2 of oDlg;
alias oTDesc:cAlias;
size 40,75 pixel;
itemfield "COD" ;
listfield "DESC";
update;

// cdesc2 will display in this get
@ 14.25 , 17 get cDesc2 OF oDlg SIZE 20, 10


@ 13.50, 3.75 SAY "Trip #" OF oDlg SIZE 22, 11 color CLR_BLACK, rgb(236,245,255)
@ 15.50, 5.0 GET cTrip_num OF oDlg SIZE 20, 11 Pict 'NNNNN'
<<<<<<<<

FWH 14.08
Harbour 3.2.0dev
BCC582
brewster
 
Posts: 43
Joined: Wed Jun 20, 2012 4:07 am

Re: dbcombo blank

Postby James Bott » Tue Dec 09, 2014 7:59 am

I am trying to understand your code. Are TComp, TDesc, etc database objects? If so you don't need to create memory vars, you can just use the database object fieldname, ie oCust:name.

And please use the code tags when posting code so it retains its format.
User avatar
James Bott
 
Posts: 4840
Joined: Fri Nov 18, 2005 4:52 pm
Location: San Diego, California, USA

Re: dbcombo blank

Postby brewster » Tue Dec 09, 2014 2:52 pm

James,

Appreciate the reply.

Hopefully, I have used "code tags" properly below. ( learning ! )


Yes, Tcomp, Tdesc, etc. are all database objects. An actual example of how I set them :

Code: Select all  Expand view  RUN


   Local cDesc1
 
   // desc vars
   local oDBC4, oTdesc

    // for desc list
    SELECT G  //TD
    use (cPath_seg + 'T_DESC') alias TD  
    set orde to "T_DES"
    database oTDesc
 



Do you mean , once I have set the database objects as above, where I have cDesc1, I should replace it with oTdesc:desc1 ?

The way I have the code with the cDesc1 style, is how I pulled it out of /samples.


Bruce
brewster
 
Posts: 43
Joined: Wed Jun 20, 2012 4:07 am

Re: dbcombo blank

Postby James Bott » Tue Dec 09, 2014 4:45 pm

Bruce,

Code: Select all  Expand view  RUN
  Local cDesc1
 
   // desc  
   local oDBC4, oTdesc

    // for desc list
    SELECT G  //TD
    use (cPath_seg + 'T_DESC') alias TD  
    set orde to "T_DES"
    database oTDesc

 

You are doing too much work. The above can be simplified to this:

Code: Select all  Expand view  RUN
local oDesc
database oDesc file cPath_seg + "T_desc"
oDesc:setOrder("T_DES)
oDesc:gotop()


Note that you don't need to assign aliases, they are assigned automatically, and you never need to use them in your code. Freedom from alias referencing!

I also suggest using more descriptive names and leaving off the "T_" and the leading "T" for your database object name. So instead of oTDesc, just oDesc, or oDescrip, or even oDescription. The idea is to make the code more readable.

An even better solution is to subclass TDatabase for each DBF file. So you do something like:

Code: Select all  Expand view  RUN
CLASS TDescrip from TDatabase
   method New()
ENDCLASS

Method New( lShared ) Class TCustomer
   DEFAULT lShared:=.t.
   super:new(,"T_Desc",,lShared)
   if ::use()
      ::setOrder("T_Des")
      ::gotop()
   endif
return self

 
Now you can do this anywhere in your program:

oDesc:= TDescrip():New()

One line gets you an open, indexed copy of your DBF!

I do suggest that you always build your key index as the first index in every compound index. That way you can just do:

::setOrder(1)

For any database and it will always be in key order.

-------------
>Do you mean , once I have set the database objects as above, where I have cDesc1, I should replace it with oTdesc:desc1 ?

Yes, with one exception. The value oTDesc:desc1 is actually data in an array, not a direct link to the field. So you are free to change this data in an edit and then abandon the changed data without it affecting the database record. So, when you are then assigning the oTdesc:desc1 data to a memory var you are essentially double buffering the data (and writing way more code).

So you can now do:

oDesc:= TDescrip():New()
oDesc:desc1:="whatever"
oDesc:save()

And you have changed the data for the first record in the dbf. Isn't that much easier?

The exception occurs when you have data in a browse and you then popup a dialog over it to edit one of the records in the browse, then start to edit the data in the dialog. Now, if the user moves a window or another program over the browse, then off, all the records in the browse get reread and redisplayed on the screen. This has the unfortunate side effect of reloading the data in the edit buffer which is being used in the dialog, so any changes made by the user to data in the dialog will be refreshed with data from the record. This is even more confusing because the data the user sees for each field is actually still showing as changed on the screen but the data in the controls' buffer has been changed back to that of the data in the DBF. That's hard to describe so I hope I was clear.

So what is the solution? Well, you can resort to what you have been doing and assign each field to memory variable. This does mean writing lots of code to load those vars then save them. This gets very tedious very quickly.

Fortunately, there is a better solution, and that is to use a record class which copies the data from a database record and thus is not affected by browse refreshing. I provide a TRecord class with my enhanced TData class. For more info about database classes, TData, and TRecord see my website gointellitech.com. [Yes, this is double-buffering, but made simple and smart.]

oItem:= TRecord():new(::oItems)
oItem:qty:= 7
oItem:save()

Did I mention, I love OOP!
User avatar
James Bott
 
Posts: 4840
Joined: Fri Nov 18, 2005 4:52 pm
Location: San Diego, California, USA

Re: dbcombo blank

Postby James Bott » Tue Dec 09, 2014 4:59 pm

Bruce,

Oh, back to your original problem, the last two dbcombos are using the same database and the same two itemfields and listfields. This can't work. You can't have the database's index pointer at two records at the same time. You will need two copies of the database open to do this.

Using the techniques discussed in my previous post, you can open two copies of a database like this:

oDesc1:= TDescrip():New()
oDesc2:= TDescrip():New()

They will both be opened in different workareas and indexed on the primary key. Simple.

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

Re: dbcombo blank

Postby nageswaragunupudi » Sun Jan 04, 2015 8:04 pm

Excellent explanation by Mr James.

This is very important:
The exception occurs when you have data in a browse and you then popup a dialog over it to edit one of the records in the browse, then start to edit the data in the dialog. Now, if the user moves a window or another program over the browse, then off, all the records in the browse get reread and redisplayed on the screen. This has the unfortunate side effect of reloading the data in the edit buffer which is being used in the dialog, so any changes made by the user to data in the dialog will be refreshed with data from the record. This is even more confusing because the data the user sees for each field is actually still showing as changed on the screen but the data in the controls' buffer has been changed back to that of the data in the DBF. That's hard to describe so I hope I was clear.

So what is the solution? Well, you can resort to what you have been doing and assign each field to memory variable. This does mean writing lots of code to load those vars then save them. This gets very tedious very quickly.

Fortunately, there is a better solution, and that is to use a record class which copies the data from a database record and thus is not affected by browse refreshing. I provide a TRecord class with my enhanced TData class. For more info about database classes, TData, and TRecord see my website gointellitech.com. [Yes, this is double-buffering, but made simple and smart.]

oItem:= TRecord():new(::oItems)
oItem:qty:= 7
oItem:save()


FWH natively provides TDataRow()

oRec := TDataRow():New( oDbf )
// works with RDD, TDataBase, ADO RecordSet, Dolphin, Arrays and directly with XBrowse of any object

oRec:Age := 7
oRec:Save()
Regards

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


Return to FiveWin for Harbour/xHarbour

Who is online

Users browsing this forum: Google [Bot], MaxP, Natter and 71 guests