Page 1 of 1

DBCOMBO problem

Posted: Mon Oct 01, 2007 10:11 pm
by alexstrickland
Hi Antonio

With the code below the drop-down is not initialised to "Production".

Code: Select all

#include "fivewin.ch"
#include "dbcombo.ch"


function main()
   local oDlg, oDBC2, oBtn
   //local cDept:= "400"
   local cDept:= 400
   local aItems, aList

   define dialog oDlg


   aList:= {"Accounting","HR","Marketing","Production","Research","Shipping","Sales"}
   //aItems:= {"100","200","400","300","600","500","700"}
   aItems:= {100,200,400,300,600,500,700}

   @ 30,30 DBCOMBO oDBC2 VAR cDept;
      items aItems;
      size 100,200 pixel;
      list aList;
      of oDlg;
      update


   @ 50, 50 button oBtn prompt "Selected";
      of oDlg pixel ;
      action msgInfo( "DeptNo: "+hb_valtostr(cDept),"Selected" );
      default

   activate dialog oDlg center;

return nil
The commented (character values) code is OK.

Did you check my last code posted for the XP theme issues with tabs?

Thanks and regards
Alex

Posted: Mon Oct 01, 2007 11:56 pm
by James Bott
Alex,

You cannot use numeric values with DBCombo. This is because DBCombo inherits from TCombobox and TCombobox has methods that assume if a passed parameter is numeric then it is for the location in the array not a value in the array. Since, the array doesn't contain a value in the 400th postion, then DBCombo is empty when it is displayed.

Awhile ago, I did make an attempt to modify DBCombo to handle numeric data for aItems, but I found that it would require rewriting a huge amount of the code and most people use character values for IDs anyway.

I assume from your commented code that you have already tried it using character values for aItems. And I tested it here (using chacter values) and it is working (although in your example "400" corresponds to "Marketing" not "Production").

Regards,
James

Posted: Tue Oct 02, 2007 8:25 am
by alexstrickland
Hi James

Thanks for the reply. I looked into the DBCombo class and made the change below. I created a new command to use my new class - TFixDBCombo. It seems to work ok, perhaps you could see if you can see any problems?

Regards
Alex

Code: Select all

#include "FiveWin.ch"
#include "Constant.ch"

#ifndef __CLIPPER__
   #define COMBO_BASE      320
#else
   #define COMBO_BASE  WM_USER
#endif
#define CB_ADDSTRING     ( COMBO_BASE + 3 )
#define CB_DELETESTRING  ( COMBO_BASE +  4 )
#define CB_GETCURSEL     ( COMBO_BASE +  7 )
#define CB_INSERTSTRING  ( COMBO_BASE + 10 )
#define CB_RESETCONTENT  ( COMBO_BASE + 11 )
#define CB_FINDSTRING    ( COMBO_BASE + 12 )
#define CB_SETCURSEL     ( COMBO_BASE + 14 )
#define CB_SHOWDROPDOWN  ( COMBO_BASE + 15 )
#define CB_ERR              -1

#define COLOR_WINDOW       5
#define COLOR_WINDOWTEXT   8

#define MB_ICONEXCLAMATION  48   // 0x0030

#define GWL_STYLE          -16

#ifdef __XPP__
#define Super ::TComboBox
#endif


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


CLASS TFixDBCombo FROM TDBCombo

   METHOD Default()

ENDCLASS

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

METHOD Default() CLASS TFixDBCombo

   local cStart := Eval( ::bSetGet )

   if ! Empty( ::hWnd ) .and. ::nStyle == CBS_DROPDOWNLIST
      ::nStyle := GetWindowLong( ::hWnd, GWL_STYLE )
   endif

   if cStart == nil
      Eval( ::bSetGet, If( Len( ::aItems ) > 0, ::aItems[ 1 ], "" ) )
      cStart = If( Len( ::aItems ) > 0, ::aItems[ 1 ], "" )
   endif

   AEval( ::aList, { | cList, nAt | ::SendMsg( CB_ADDSTRING, nAt, cList ) } )

   if ValType( cStart ) != "N"
      ::nAt = AScan( ::aList, { | cList | Upper( AllTrim( cList ) ) == ;
                                           Upper( AllTrim( cStart ) ) } )
   else
      //::nAt = cStart
      ::nAt = AScan( ::aItems, { | nList | nList == cStart } )
   endif

   ::nAt = If( ::nAt > 0, ::nAt, 1 )

   //if cStart == nil
      ::Select( ::nAt )
   //else
      //::Set( cStart )
   //endif

return nil

Posted: Tue Oct 02, 2007 1:32 pm
by James Bott
Alex,

As I said it is not that simple. You are going to have to check every method in both TDBCombo and TCombobox. Either methods also have to be modified in TCombobox also or new methods have to be created in DBCombo. But the real problem is that there is existing code that requires values for the location in the array. Changing the behavoir of DBCombo and/or Combobox is going to break this existing code.

It is very easy to convert your numeric data to character when you build the array, and to convert the selection back to numeric. That is a much simpler solution.

Regards,
James

Posted: Fri Oct 10, 2008 7:53 am
by Horizon
Hi James,

What is your suggestion Numeric ID in huge databases about setting default value using DBCombo. Should we use another method?

Thanks,

Posted: Sat Oct 11, 2008 4:50 am
by James Bott
Hakan,

>What is your suggestion Numeric ID in huge databases about setting default value using DBCombo. Should we use another method?

I wouldn't suggest using DBCombo for huge databases. The problem is that the entire database has to be loaded into an array which is going to cause a long delay.

I would suggest using the new ACTION clause of the GET, and calling up a browse in a window or dialog. A browse only loads enough records to fill the screen so it is very fast and the speed is not dependent on the size of the database.

Regards,
James

Posted: Sat Oct 11, 2008 2:24 pm
by Horizon
Thanks James,

I think I have seen that someone has wrote the class you have described. I should do a quick search.

I have also modified the alexstrickland's code. It works perfectly with numeric ID and initialize the value.

Code: Select all

#include "fivewin.ch" 
#include "dbcombo.ch" 


function main() 
   local oDlg, oDBC2, oBtn 
   //local cDept:= "600" 
   local cDept:= 600 
   local aItems, aList 

   define dialog oDlg 


   aList:= {"Accounting","HR","Marketing","Production","Research","Shipping","Sales"} 
   //aItems:= {"100","200","400","300","600","500","700"} 
   aItems:= {100,200,400,300,600,500,700} 

   @ 30,30 DBCOMBO oDBC2 VAR cDept; 
      items aItems; 
      size 100,200 pixel; 
      list aList; 
      of oDlg; 
      update 


   @ 50, 50 button oBtn prompt "Selected"; 
      of oDlg pixel ; 
      action msgInfo( "DeptNo: "+hb_valtostr(cDept),"Selected" ); 
      default 

   activate dialog oDlg center;
   ON INIT ( nAt:= ASCAN(oDBC2:aItems,cDept) , oDBC2:Select( nAt ))

return nil