DBCOMBO problem

Post Reply
alexstrickland
Posts: 23
Joined: Thu Aug 30, 2007 8:52 am

DBCOMBO problem

Post 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
User avatar
James Bott
Posts: 4654
Joined: Fri Nov 18, 2005 4:52 pm
Location: San Diego, California, USA
Contact:

Post 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
alexstrickland
Posts: 23
Joined: Thu Aug 30, 2007 8:52 am

Post 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
User avatar
James Bott
Posts: 4654
Joined: Fri Nov 18, 2005 4:52 pm
Location: San Diego, California, USA
Contact:

Post 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
Horizon
Posts: 997
Joined: Fri May 23, 2008 1:33 pm

Post 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,
Regards,

Hakan ONEMLI

Harbour & VS 2019 & FWH 20.12
User avatar
James Bott
Posts: 4654
Joined: Fri Nov 18, 2005 4:52 pm
Location: San Diego, California, USA
Contact:

Post 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
Horizon
Posts: 997
Joined: Fri May 23, 2008 1:33 pm

Post 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 
Regards,

Hakan ONEMLI

Harbour & VS 2019 & FWH 20.12
Post Reply