Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations TouchToneTommy on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Combobox not populated with array 2

SitesMasstec

Programmer
Sep 26, 2010
571
Brasil
Hello colleagues!

I am trying to put in a Combobox the data from an array.

These are the data from the array I am using (just to be sure that the array has these data; the similar code is in the procedure Init in the Form):

VFPArray.jpg

This is the Form:

VFPComboboxArray.jpg
As you can see, the data from the array are not presented in the Combobox.

This is the code in the procedure AddItem in the Combobox:

Code:
With This
    FOR I=1 TO 3  && QtdeNomes
       .AddItem(NOMES(I,1),NOMES(I,2))
    NEXT I
    .ListIndex=1
ENDWITH

Thank you.
 
Your parameters to the method AddItem are incorrect. The first parameter is the text to display, the second parameter is the index value (numeric), and the third parameter is the column value (numeric). So, the correct code should be (untested):

Code:
With This
    FOR I=1 TO 3  && QtdeNomes
       .AddItem(NOMES(I,1), I, 1)
       .AddItem(NOMES(I,2), I, 2)
    NEXT I
    .ListIndex=1
ENDWITH

Also, see the property ColumnWidths. If you do not want the second column to be displayed in the dropdown selections, then set this property to the width of the control followed by zero. For example, if the control width is 100, then the property value would be ColumnWidths=200,0.

If you want the second array column to be the index value (numeric), then to use AddListItem where you specify the ListItemId. Note that ListIndex returns the sequential value; 1, 2, 3, ... and you should determine the selected value from ListItemId property.

I use the following code to populate comboboxes:

Code:
LOCAL lnCnt
SELECT id, bname FROM banks WHERE companyid = _VFP.CompanyId AND active = True AND !EMPTY(assetgrpid) INTO CURSOR c_temp
lnCnt = 0
SELECT c_temp
SCAN
    lnCnt = lnCnt + 1
    this.AddListRow(lnCnt, ALLTRIM(c_temp.bname), c_temp.id)
ENDSCAN
IF this.ListCount > 0
    this.ListItemId = 1
ENDIF
USE IN SELECT('c_temp')

The method "AddListRow" is a custom method that I added to my sub-class of the combobox:

Code:
PROCEDURE AddListRow
LPARAMETERS tnItemID, tcItem1, tcItem2, tcItem3, tcItem4, tcItem5, tcItem6, tcItem7, tcItem8, tcItem9, tcItem10, tcItem11, tcItem12
LOCAL lnCnt, lcParm
FOR lnCnt=1 TO PCOUNT()-1
    lcParm = "tcItem" + TRANSFORM(lnCnt)
    this.AddListItem(EVALUATE(lcParm), tnItemID, lnCnt)
ENDFOR
ENDPROC
 
Last edited:
Hello, Greg!

I uderstand your method works .

But as I have an array in memory, why not just my code in the AddItem in the Combobox doesn't work?
 
Try this code:

Code:
With This
    FOR I=1 TO 3  && QtdeNomes
       .AddListItem(NOMES(I,1), NOMES(I,2))
    NEXT I
    .ListIndex=1
ENDWITH

This sets the ListItemId value and not the ListIndex. To know which item was selected:

Code:
 lnSelectedItemId = this.ListItemId
 
Just a thought.

I didn't read the whole thread, but if the control is completely empty, perhaps you also need to add a REFRESH().

Even with the wrong parameters for the array elements, it wouldn't be empty. You'd see numbers or even a bunch of blank lines.
 
Hello, Joe!
It doesn't work, either.
Please see the code in the Init procedure in the Form:

Code:
    DECLARE NOMES(1,1)
   
    NOMES(1,1)="-"

    thisform.txtNOME.Value=YNOMECLI
    NOMECLI=YNOMECLI

    IF NOMECLI<>SPACE(34)
        NOMECLI=UPPER(ALLTRIM(NOMECLI))
        SELECT NOMAGENTE+"  (" + ALLTRIM(STR(CODAGENTE)) + ")  " + "Localizador: " + LOCALIZA, RECNO();
            FROM RESERVAS;
            WHERE UPPER(NOMAGENTE) LIKE "%&NOMECLI%" INTO ARRAY NOMES


        IF NOMES(1,1)="-"              
            RETURN               
      
       ELSE                          
            =ASORT(NOMES)
            QtdeNomes=ALEN(NOMES)
           
            thisform.cboNOMES.Refresh()
           
         ENDIF
    ENDIF

RETURN
 
I was referring to adding the REFRESH() directly after the code you use to add the items to the control.
 
I load my comboboxes in the Init method of the combobox and have no problems. Never had to do a refresh. In dependent comboboxes where a second combobox list is dependent on the first selection (like user selecting country and then the region/state from the second), I do a Clear and then reload the list in the second combobox via the first combobox InteractiveChange event. A refresh is never required.

Since I do not use the AddItem method, I am not sure, but I would think that since the combobox via this method is loaded by index and since the index values that are being passed are not starting with 1 and are consecutive, that the list is not being loaded.

UPDATE: I just created a test form with two comboboxes. The first Init method has the following code:

Code:
this.AddItem("Item 1", 10)
this.AddItem("Item 2", 35)
this.AddItem("Item 3", 63)

The second init method has the following code:

Code:
this.AddListItem("Item 1", 10)
this.AddListItem("Item 2", 35)
this.AddListItem("Item 3", 63)

When I run the form, I get an error message for each line in the first init method:

1750164436425.png

I then changed the index values to 1, 2, and 3 and the form runs correctly. I believe the index values have to start with 1 and be sequential for the AddItem method to work.
 
Last edited:
Hi,

Did you know that you can import directly the data from an array into your combobox ?

Set the ROWSOURCE property to the array name and the ROWSOURCETYPE property to 5 - Array. You'll have of course to REFRESH() or REQUERY() the combobox when data changes in the array.

see also https://learn.microsoft.com/en-us/p...ualstudio/foxpro/capture-input-in-a-combo-box

hth

MarK
 
I'd just use an array rowsource here, but if you really want to add the items manually, you need to use AddListItem, not AddItem.

You can use actually AddItem for the first column, but not for any of the others. That's because AddItem ALWAYS adds a new row.

Tamar
 
Mark:

Great! Simple and direct. Except that the Combobox doesn't show the second data (Record Number, from the original RESERVAS.DBF table) from each row in the array (please see my first post, running a PRG file: it shows the Record Number from a table):

VFPComboboxArray2.jpg

Code:
SELECT NOMAGENTE+"  (" + ALLTRIM(STR(CODAGENTE)) + ")  " + "Localizador: " + LOCALIZA, RECNO();
            FROM RESERVAS;
            WHERE UPPER(NOMAGENTE) LIKE "%&NOMECLI%" INTO ARRAY NOMES


I tried to put the following code in AddListItem procedure in the Combobox, as I have understand Tamar's advice, but the second data (Record Number) for each row is not shown.

Thank you.
 
See my reply to your original question. You have to do the AddItem method for each column with the same index value.
 
Dear colleagues:

I do not put any code in the AddItem or AddListItem.

Instead, I just put this code in the LostFocus procedure in the Combobox (the second column of the row should not be displayed; indeed I need its value, which is the record number - variable NumeRegi - in the original table to be read):

Code:
mychoice=thisform.cboNomes.ListIndex
NumeRegi=NOMES(mychoice,2)

Well, it seems to be the solution, at least for now, because it gives the value of NumeRegi, which was needed.

Thank you very much.
 

Part and Inventory Search

Sponsor

Back
Top