I have a Dialog with 2 DbCombo's.
1) DbCombo1 contains the Department names
2) DbCombo2 contains the Employee Names of those belong to the Department Selected in DbCombo1
My Requirement
Once the user selects a Department Name in DbCombo1, the array items of DbCombo2 is reset and only the employees who belong to the selected department should be listed. This part is working fine.
I need the DbCombo2 to select the name of the 1st employee in the list by default, which is not happening. Eventhough I assign the Employee code, the value is lost.
Actually I am working on MySQL, FWH xHarbour environment. To replicate the problem, I have created a sample program using DBF and arrays. As DbCombo does not support RecordSets, I create Arrays from RecordSet and use it with DbCombo. Instead of MySql Tables I have used DBF files to explain the problem.
Here is the sample code. Any help ?. I don't know where I am going wrong.
A cut and paste of the below given code can be used to test the problem mentioned by me.
- Code: Select all Expand view
- #Include "FiveWin.Ch"
#Include "DbCombo.Ch"
*------------------------------------------*
Function LogMeIn()
*------------------------------------------*
Local oDlg,oDbCmbEmployees,oDbCmbDepartment,oBtnLogin,oBtnCancel
Local nStyle,nDeptRecNo
Local aEmpCodes:={}, aEmpNames:={} , aDeptNames:={} , aDeptRecNo:={}
Local IsConnected,IsAllOK
Local aStructure
SET EXCLUSIVE ON
if !File("DEPARTMENT.DBF")
aStructure := {}
aAdd(aStructure,{"DEPT_NAME","C",11,0})
DbCreate("DEPARTMENT.DBF",aStructure)
endif
Select A
USE DEPARTMENT
ZAP
aData:={"Sales Dept.",;
"IT Dept. ",;
"Accts Dept." }
For i:=1 to len(aData)
APPEND BLANK
REPLACE DEPT_NAME with aData[i]
Next
if !File("EMPLOYEES.DBF")
aStructure := {}
aAdd(aStructure,{"EMP_CODE" ,"N", 3,0})
aAdd(aStructure,{"EMP_NAME" ,"C",30,0})
aAdd(aStructure,{"DEPT_NAME","C",11,0})
DbCreate("EMPLOYEES.DBF",aStructure)
ENDIF
Select B
USE EMPLOYEES
ZAP
aData:={}
aData:={ {1,"Anser (Sales)" , "Sales Dept."},;
{2,"John (Sales)" , "Sales Dept."},;
{3,"Abraham (Sales)" , "Sales Dept."},;
{4,"Anser (IT)" , "IT Dept. "},;
{5,"John (IT)" , "IT Dept. "},;
{6,"Abraham (IT)" , "IT Dept. "},;
{7,"Anser (Accts)" , "Accts Dept."},;
{8,"John (Accts)" , "Accts Dept."},;
{9,"Abraham (Accts)" , "Accts Dept."} }
For i:=1 to len(aData)
APPEND BLANK
REPLACE EMP_CODE with aData[i][1]
REPLACE EMP_NAME with aData[i][2]
REPLACE DEPT_NAME with aData[i][3]
Next
// Index the Database on Dept. Name
INDEX ON DEPT_NAME to EMPLOYEES
Select B
USE EMPLOYEES INDEX EMPLOYEES
Select DEPARTMENT
Go Top
Do While !eof()
aAdd(aDeptNames,DEPARTMENT->DEPT_NAME)
aAdd(aDeptRecNo,RecNo() )
Skip
Enddo
// nEmpCode is used as Character type, eventhough in DBF it is Numeric
// This is because DbCombo can handle only Character type array
nEmpCode:=space(3)
aEmpCodes:={} ; aEmpNames:={} ; cDeptName:=space(11)
IsAllOK:=.F.
Sele DEPARTMENT
Go Top
nDeptRecNo:=2 // 1st record in Department.Dbf should be always be Selected by Default
nStyle :=nOR( DS_MODALFRAME, WS_POPUP, WS_CAPTION ) // Removes the ? and x on the dialogue title
DEFINE DIALOG oDlg FROM 10,20 to 27,90 TITLE "Login " style nStyle
@01 ,3.6 say "Department" of oDlg
@02 ,3.6 say "Employee" of oDlg
IsConnected:=.F.
IsAppBrSetUpDone:=.F.
@1.2,8 DBCOMBO oDbCmbDepartment VAR nDeptRecNo;
ITEMS aDeptRecNo;
size 120,200 ; // Size Control width, Ht of the list when activated
LIST aDeptNames;
of oDlg;
VALID if(IsConnected, .T., ; // If already Connected then Return .T.
(IsConnected:=ConnectDB(nDeptRecNo,@nEmpCode,@aEmpCodes,@aEmpNames,oDbCmbEmployees,oDlg), ; // Else connect and Return the result ie T or F
IsConnected ) ) ; // Return the status of connection ie either .T. or .F.
update ;
ON CHANGE ( IsConnected:=ConnectDB(nDeptRecNo,@nEmpCode,@aEmpCodes,@aEmpNames,oDbCmbEmployees,oDlg),;
if(IsConnected, , ; // If connected
(IsAllOK:=.F. ,oDlg:End() ) ) ) // Not Connected
@2.3,8 DBCOMBO oDbCmbEmployees VAR nEmpCode;
ITEMS aEmpCodes;
size 120,200 ; // Size Control width, Ht of the list when activated
LIST aEmpNames;
of oDlg;
ON CHANGE ( IsAppBrSetUpDone:=SetAppEmployee(nEmpCode) ) ;
VALID if (IsAppBrSetUpDone, .T. ,; // if oApp Branch setup done then return .F.
SetAppEmployee(nEmpCode) ) ; // Else do the setup for oApp Branch details
update
@05,14 BUTTONBMP oBtnLogin PROMPT "Login" TEXTRIGHT SIZE 50,20 ;
ACTION oDlg:End()
@05,24 BUTTONBMP oBtnCancel PROMPT "Cancel" TEXTRIGHT SIZE 50,20 ;
ACTION oDlg:End() CANCEL
oBtnLogin:cToolTip:="Login"
oBtnCancel:cToolTip:="Cancel/Quit"
ACTIVATE DIALOG oDlg CENTERED
SELECT DEPARTMENT
Use
SELECT EMPLOYEES
Use
Return IsAllOK
*-------------------------------------------*
Function ConnectDB(nDeptRecNo,nEmpCode,aEmpCodes,aEmpNames,oDbCmbEmployees,oDlg)
*-------------------------------------------*
Local oError,oRecSet,bDbCmbOnChange,cDeptName
// Reset old values
aEmpCodes:={} ; aEmpNames:={} ; nBranchId:=0
Select DEPARTMENT
Goto nDeptRecNo
// Some validations are done here, like Database connectivity etc
cDeptName:=DEPARTMENT->DEPT_NAME
Sele EMPLOYEES
Go TOP
Seek cDeptName
Do WHILE EMPLOYEES->DEPT_NAME == cDeptName .and. !eof()
// If I don't use Str(), then I get Alltrim error at SetItems() ie on line 185
aAdd(aEmpCodes ,str(EMPLOYEES->EMP_CODE,3))
aAdd(aEmpNames ,EMPLOYEES->EMP_NAME)
Skip
Enddo
// I need the the 1st item in the DbCombo to be selected by default
if Len(aEmpCodes) > 0
nEmpCode:=Val(aEmpCodes[1])
Endif
MsgInfo("The Value of nEmpCode is "+str(nEmpCode)) // Shows the correct value
MsgInfo("ValType of nEmpCode is "+ValType(nEmpCode))
// See carefully the below given commands on DbCombo, when we do the SetItems of the DbCombo oDbCmbEmployees
// The On change event of oDbCmbEmployees gets fired before quiting this Function
// So to avoid that I am temporarily changing the OnChange to NIL and later restoring it
bDbCmbOnChange:=oDbCmbEmployees:bChange
oDbCmbEmployees:bChange:=NIL
oDbCmbEmployees:SetItems(aEmpCodes, aEmpNames)
oDbCmbEmployees:bChange:=bDbCmbOnChange
oDbCmbEmployees:Update()
/*
I tried all these, but failed to make DbCombo to select a default value
nEmpCode:=Val(oDbCmbEmployees:aItems[ 1 ])
MsgInfo("List "+oDbCmbEmployees:aItems[ 1 ])
oDbCmbEmployees:nAt:=1
*/
oDlg:cTitle:="Selected Dept :"+cDeptName+" -- Employee Code "+nEmpCode
// I can't understand what is happening here. The value of nEmpCode is Lost at this point
// I have even tested after removing the SetItem commands ie from line 178 to line 182
// really cant understand why this behavior
MsgInfo("Before Quiting ConnectDb() the Value of nEmpCode is lost, the val is :"+nEmpCode)
RETURN .T.
*-----------------------------------------------*
Function SetAppEmployee(nEmpCode)
*-----------------------------------------------*
Return .T.
Regards
Anser