+ Reply to Thread
Results 1 to 13 of 13

Defining Ranges

  1. #1
    Registered User
    Join Date
    10-22-2007
    Posts
    37

    Defining Ranges

    Hey there.

    This is slightly long, although only the first part is really my question - the rest is my reasoning for different approaches which don't seem like they'll work... so that's not as important = )


    So, I have some comboboxes I plan to use for state, city, and local address on a userform. I want to populate them in such a way that each higher-level category restricts the options for each lower-level entry. Example: If someone chooses the state of CA in the first box, only cities in CA are showing up in the "city" combobox. I know this is fairly straightforward, but how I am trying to implement it is not.


    First off, the data I am using has already been set up in a special worksheet. The general format is this:

    States are listed across the top in the first row, one state per column.

    Cities are listed in the columns beneath the state they belong to. The last entry in each city list is the word "Other" (which can be selected if the city the user wants is not already in the list). Also at the end of each Cities list (after Other) is a blank cell (which might be helpful to use later? anyway...). Example:

    Alaska | Alabama | ...

    Anchorage | Birmingham
    Other | Mobile
    | Other


    Local addresses are organized in a somewhat similar way below this...


    I have the State combobox populating well, but I am having trouble figuring out how to get the Cities combobox working. Something making this more challenging is the fact that the list of Cities is supposed to be dynamic, so the list may grow (but probably not shrink).


    Does anyone have any suggestions on getting this working? Here are some ideas I've had, but that don't seem like they'll work out.


    ~~~~~~~~~~~~~~

    Scenario 1:

    Use a foreach statement and the value of the state combobox to cycle through the range of states in the States row. Then take that column value and display in the Cities combobox everything in a range from the column below the State until reaching a cell with the value "Other." I can't figure out a way to get the range to stop at a (dynamically ending) cell once it reaches a value of "Other" however. I thought I could use a MATCH, but I think I'd need the row position of Other to define the end of range input for that (the "Lookup_array" value). So I can't find something if I need that something to find it!!

    Anyway, in pseudo-code something like this:

    Foreach (cell) in (Range of States)
    if comboboxState.Value = cell.value
    statecolumn = (column value of (the current) cell)
    else
    endif
    Next cell


    Then something like:

    (varEndCityRange) = MATCH("Other", (start range, end range), 0)


    Foreach (cell) In .Range(.Cells(3, statecolumn), .Cells(varEndCityRange, statecolumn))
    comboboxCity.AddItem (cell).Value

    Next (cell)


    Again, I don't think this will work because I can't figure out how to define the ranges in MATCH without already knowing the info I'm looking for (!!)



    ~~~~~~~~~~~~~


    Scenario 2:

    Once I know the column value for state, the cities start two rows down (so that's a fixed position). I was thinking of using OFFSET to somehow ID the range and spit it into the Cities box, but again I don't know how I could query down the list until I hit "Other" and then stop.



    ~~~~~~~~~~~~~~~


    Scenario 3:

    I could throw the entire range into an array, query for Other, find its cell position, and try to work from there. I get kind of lost from there though... that seems unnecessarily complex - unless I am missing something (very possible).


    ~~~~~~~~~~~~~~~~~


    Scenario 4:

    Make a variable Named Range for each list of cities. I think once this is done all I'd need to do is assign the combobox value to the named range. BIG downside on this is that I think this means I'd have to make a separate range for every state (dozens) AND that I'd probably need to use a similar strategy when I move on to populate the Local Address combobox (so dozens x about another dozen, NOT a great prospect).


    And insight into this brain twister would be very well appreciated!!

    Thanks = )

  2. #2
    Forum Expert
    Join Date
    01-15-2007
    Location
    Brisbane, Australia
    MS-Off Ver
    2007
    Posts
    6,591
    Hi

    See if the attached file gives you some ideas.

    Make a selection from the combobox on the left, and the data that goes into the second combobox populates.

    I've used some dymanic defined names to make this work. There is only on name for the towns, but it is dynamically created based on the selection of the state.

    HTH

    rylo
    Attached Files Attached Files

  3. #3
    Registered User
    Join Date
    10-22-2007
    Posts
    37

    trying to understand...

    This works ~really well~

    But I am always a student and I don't understand all of it yet (I'm pretty new to VBA and using excel). Could you walk me through:

    Please Login or Register  to view this content.
    I know you are defining a workbook name called "selstate" and setting that "= (selected state name)". But I don't understand why? Also the double """" seem like they would be adding in blank spaces into a string? What is interacting with that string and the "selstate" workbook name? I don't see it anywhere, am I missing something in another place perhaps?

    And I know "townlist" is being used as the list for the towns combobox. But where is "townlist" being defined? Either VBA is working much differently from how I assumed, or there must be code somewhere I am not seeing?


    Thanks!!

  4. #4
    Forum Expert
    Join Date
    01-15-2007
    Location
    Brisbane, Australia
    MS-Off Ver
    2007
    Posts
    6,591
    Hi

    Here goes.

    1) In the workbook there are 3 defined names.
    (a) selstate contains the state that has been selected and is a "constant"
    (b) cntrows will count the number of rows containing data for that state
    (c) townlist is dynamic and will cover the set of towns for the selected state.

    2) The combobox change event will create the constant defined name selstate based on the selection that has been made in the combobox. It then sets the rowsource for combobox2 to be the defined name townlist.

    3) the extra quotes are required in VBA to include the " as part of the formula. The defined name selstate has (as an example) a refers to of ="Alaska"
    The code
    Please Login or Register  to view this content.
    has 3 parts

    "=""": opening ", followed by "" to include ", then the closing "
    & ComboBox1.Value &: to concatenate the combobox1.value into the final string
    """": opening ", "" to include a ", then the closing "


    HTH

    rylo

  5. #5
    Registered User
    Join Date
    10-22-2007
    Posts
    37

    I get it!

    This is a really excellent response, thank you so much for helping me to understand this.

    I didn't understand those were defined names so I didn't have any clue on where to find them! I knew I could look them up going to Insert -> Name -> Define. I think they could also be put directly into the VBA code, correct? Would within the module be the place for that?

    Also, the string is fairly complex, thank you again for helping me to understand it and the way excel treats quotation marks.

    I have a lot more practice ahead of me!!

  6. #6
    Forum Expert
    Join Date
    01-15-2007
    Location
    Brisbane, Australia
    MS-Off Ver
    2007
    Posts
    6,591
    Hi

    The defined names are used as they stand. There is no need for any code to manipulate them, other than the bit I used to give selstate a constant result.

    Or am I missing the direction of your question???

    rylo

  7. #7
    Registered User
    Join Date
    10-22-2007
    Posts
    37

    defining names

    Actually, yes you already did! Turns out I was just confusing myself.


    I didn't realize the code was also actually defining the names, I thought that was a separate step I was missing somehow. It seems you can also define names by using the Excel file menu and going to Insert > Name > Define, correct? But there is no need for that, as your code is already defining the names - I just realized that after reading up on it some more.


    Thanks again!!

  8. #8
    Registered User
    Join Date
    10-22-2007
    Posts
    37

    uh oh

    one last thing (I promise ) I've changed some things slightly and now I'm getting a 380 error: "Could not set the RowSource property. Invalid Property Value."

    I'm trying to adapt the code to start one column over and account for one blank row between the headers (the state names) and the start of the cities.

    So:

    (States: ) | Alaska | Alabama |
    (blank ---|------------|----------->)
    (Cities: ) | Anchorage | Birmingham |
    | Fairbanks | Mobile |


    I've changed townlist to:
    Please Login or Register  to view this content.
    ~So basically the R4C1 to R3C2 (to start the OFFSET reference at B3 instead of A4, as my cities lists start at B3)~


    and cntrows to:
    Please Login or Register  to view this content.
    ~So basically the C1 to C2 (to start this OFFSET reference to column B instead of column A, to skip over it)~


    As far as I can see that should be accounting for everything, unless there is something that is calculating a *relative* position I am not accounting for?

    What am I missing?


    Note: I've changed Sheet1! to my worksheet name "Address List"! - I don't think the quotes would be causing any interference though, just thought I'd mention.
    Last edited by rokuk; 11-07-2007 at 02:16 PM.

  9. #9
    Forum Expert
    Join Date
    01-15-2007
    Location
    Brisbane, Australia
    MS-Off Ver
    2007
    Posts
    6,591
    Hi

    Can you put up an example of your working file structure. Include all the parts (code, userform, names) etc.

    I'll have a look.


    rylo

  10. #10
    Registered User
    Join Date
    10-22-2007
    Posts
    37

    hmm...

    This is part of a pretty big workbook, I'm going to have to do a lot of moving things around to get just the needed parts in there.

    Does that basically mean my logic / code should be working there, but for some reason isn't? If that's the case, I can look for some more out-there explanations. Otherwise, I will try to set up an example workbook and see if I can post it up?

    Or is there an easier way to do all this?

  11. #11
    Forum Expert
    Join Date
    01-15-2007
    Location
    Brisbane, Australia
    MS-Off Ver
    2007
    Posts
    6,591
    Hi

    Try modifying my example file to bring it into line with your new structure, and try adapting the formulas. If it doesn't work, then put up the modified example file.


    rylo

  12. #12
    Registered User
    Join Date
    10-22-2007
    Posts
    37

    ...

    I -almost- have it.

    I'm trying to figure out the "minuses" in the function parameters though.

    for cntrows you use:
    Please Login or Register  to view this content.
    Working from the right side, I know the first "-1" is to remove the extra value COUNTA is going to find when it includes the name of the state in row 1 in its count, right?

    But I don't understand the second "-1" (second from the right), that acts on the value OFFSET returns. OFFSET is supposed to return a range of cells (or the position of one cell, if the range is only covers one), correct? In VBA you can do mathematical equations with range objects?

    OK, let's assume you can. I think cells can be described in one of two ways, either the A1 format or the R1C1 format, correct? Which format is the default for returned data from functions?

    I'm wrong in here somewhere, but this is what I am thinking is going into the "columns" parameter for the OFFSET function - please let me know where I mess this up = ) So if combobox1.Value is Alaska, which is in cell B1, MATCH(selState,Sheet1!R1,0) will return (for example) "(B1)-1" leaving:

    Please Login or Register  to view this content.
    If it returns R1C2 instead of B1, the MATCH function would return "(R1C2)-1" instead, right? Does that subtraction just go through to leave it as "B0" or "R1C1", or where did I get lost?


    Similarly, I don't understand the subtraction value interacting with the return value for the MATCH function for "townlist" either.

    Please Login or Register  to view this content.
    For the "-1" to the right of the MATCH function - although I've learned to alter it to change some results, I just can't figure out how it is interacting... rather, WHAT it is interacting with, to puzzle out how it works (the "-1" value, not the function). Again, is MATCH returning an A1 type reference, an R1C1 type reference, something else (I know it is supposed to be returning a relative position, so I'm not sure how that is structured / conveyed)?


    This is probably a simple answer, but not knowing how or what those values are being subtracted from is driving me a little nuts = )

    Thanks!!
    Last edited by rokuk; 11-08-2007 at 05:51 PM.

  13. #13
    Forum Expert
    Join Date
    01-15-2007
    Location
    Brisbane, Australia
    MS-Off Ver
    2007
    Posts
    6,591
    Hi

    Nearly there. I'll use my example file structure to explain, and use the state of Alabamba, which is in B1.

    1) MATCH returns a number (when it works), so
    MATCH(selstate,Sheet1!$1:$1,0)
    will return 2.
    2) OFFSET(Sheet1!$A:$A,0,MATCH(selstate,Sheet1!$1:$1,0)-1) will become
    OFFSET(Sheet1!$A:$A,0,2-1) then
    OFFSET(Sheet1!$A:$A,0,1) which is column B.
    This has now identified that the range you are using in the COUNTA function is column B.
    3) Because the range B1:B6 contains 2 blank rows, COUNTA will return 4. As you don't want the heading included in the count, then subtract 1 to return the count of 3, which is the number of valid towns.

    There's a really good debugging trick that I've picked up along the way.

    In the formula bar, highlight part of the formula, then press F9. This will evaluate that part of the formula (if valid). So to test all this, take the Refers To formula from the defined name, pick a cell (say J3) and put the formula in that cell. You can then highlight MATCH(selstate,Sheet1!$1:$1,0) in the formula bar, press F9, it will evaluate to a number. The next relevant part of the formula is really the OFFSET part, but this will evaluate to an error as it is a range. However, if you highlight COUNTA(OFFSET(Sheet1!$A:$A,0,1-1)) and press F9, it will return a number.

    HTH

    rylo

+ Reply to Thread

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts

Search Engine Friendly URLs by vBSEO 3.6.0 RC 1