0
votes

I've been searching for a few days now, but can't seem to work this out.

I have an excel workbook that houses a list of "ideas" from an Access database. The Table is connected in Read-Only mode (definitely don't want Excel writing back to Access!) on excel sheet "AllIdeas"

A few notes: The sheet "AllIdeas" will initially be hidden. The VBA Macros will unhide and filter it.

I have a Sheet titled "Dashboard" where I want the following functionality:

  1. (Not Working) Idea Owners can use a ComboBox and Click a "Button" (In this case, it's a rounded rectangle that I'll assign a macro to) to filter the information on "AllIdeas" to only show the ideas assigned to them.
  2. (Not Working) I want another ComboBox listing the "Status" of the Ideas (Open, Declined, Implemented, etc) along with a clickable rounded rectangle. The Macro for this rectangle needs to pull only the ideas for the Idea Owner (identified in combobox1) and the status (identified in combobox2). This second "button" macro would not run without both the Idea Owner and the Status selected.
  3. (Working) Users can enter an idea number and have the information pop up on the dashboard. This is useful if they know an idea number, but need the details.
  4. (Working) At the bottom of the Dashboard there is another rounded rectangle with a macro assigned that unhides the "AllIdeas" sheet and displays the entire table.
  5. (Working)On the "AllIdeas" sheet there is a button labeled "Click Here to Return to Dashboard". This Macro returns the user to the dashboard and hides the "AllIdeas" sheet.

Here is some of what I have. I apologize in advance for how messy this may be...this is my first venture into VBA:

    Sub AllIdeasBtn()
Worksheets("AllIdeas").Visible = xlSheetVisible
Worksheets("AllIdeas").Activate
If Worksheets("AllIdeas").AutoFilterMode Then          Worksheets("AllIdeas").ShowAllData
End Sub

Sub Back()
ActiveSheet.Visible = False
Sheets("Dashboard").Select
Sheets("AllIdeas").Visible = False


End Sub

I am completely stuck on how to use my comboBoxes along with a click macro to unhide the AllIdeas Sheet and filter it by the selections in the combo boxes. AllIdeas Example

1
I'm assuming there is a field in the AllIdeas sheet for "Idea Owners" and a field for "Status". If you have something working for "Idea Number", it should be similar for the other two. The challenge is, do you want the user to pick his name from a drop down list, or do you have some other means to identify him/her. I recommend you post a small mock up sample of your AllIdeas worksheet, and your Idea Number code. - OldUgly
You are correct, OldUgly, I have columns with the Idea Owners, Status, Etc. I would like for a user to select their name in a comboBox, then hit "Filter Ideas", and have the "AllIdeas" sheet become unhidden and filtered by the name selected. Here is the code I'm using for the "Idea query" on the dashboard: =IFERROR(INDEX(AllIdeas!D:D,MATCH(Dashboard!D13,AllIdeas!B:B,0)),"") - I'm running an index match, so a user can see the idea description, solution, and status; so long as they know the idea number. I posted an example of my dashboard at the end of my initial question. - jrichall

1 Answers

1
votes

jrichall - This answer is to provide a framework, with examples, to help address your problem. It does not lay things out exactly as you have designed.

I've broken it down this way ...

  1. Lists are required for unique Names, Status, Idea Numbers, etc., that exist on the AllIdeas table. These lists are used to limit the end users choices for filtering, but they need to be kept up to date as/when the contents change.
  2. You are limiting the end user to one kind of filter at a time - either by Name, Status, Idea Number, or something else. This means you need a way to eliminate one kind of filter when the other is chosen.
  3. The old filtering of AllIdeas needs to be eliminated before a new filter is applied.
  4. Displaying the filtered results on the Dashboard means maintaining the dashboard appearance.

Note: In my example, I am not using Combo Boxes. However, the concepts are easily transportable.


A simple AllIdeas

To test the code, a simple mockup of AllIdeas was generated ...

enter image description here


A simple dashboard

A simple dashboard was also put together. In it, Cells A2, B2, and C2 have their input protected using Data Validation.

enter image description here

A named Range defines the valid data. Illustrated above is the named Range "Names".


Lists and maintaining them

The Lists of valid Names, Status, and Numbers (named ranges) are maintained on a tab named "DropDowns". It looks like the following ...

enter image description here

You can see these lists do not contain all of the information contained in the AllIdeas table. Below is VBA code to update the "Names" list. Similar ones exist for updating the "Status" list and the "Numbers" list.

Sub UpdateNamesList()
Dim IdeaSht As Worksheet, ListSht As Worksheet
Dim IdeaRng As Range, myRng As Range
Dim iCount As Long, NameCol As Long
Dim myDict As Object, myKey As Variant
Dim namedRange As Name
' Initial
Set IdeaSht = Worksheets("AllIdeas")
Set ListSht = Worksheets("DropDowns")
Set myDict = CreateObject("Scripting.Dictionary")

' Find the column with the user names
For Each myRng In IdeaSht.Range(IdeaSht.Cells(1, 1), IdeaSht.Cells(1, IdeaSht.Cells(1, IdeaSht.Columns.Count).End(xlToLeft).Column))
    If myRng.Value = "Idea Owner" Then
        NameCol = myRng.Column
        Exit For
    End If
Next myRng

' Pull out unique user names
For Each myRng In IdeaSht.Range(IdeaSht.Cells(2, NameCol), IdeaSht.Cells(IdeaSht.Range("A" & IdeaSht.Rows.Count).End(xlUp).Row, NameCol))
    If Not myDict.exists(myRng.Value) Then
        myDict.Add myRng.Value, myRng.Value
    End If
Next myRng

' Change "Names" list to contain the unique user names
For Each myRng In ListSht.Range(ListSht.Cells(1, 1), ListSht.Cells(1, ListSht.Cells(1, ListSht.Columns.Count).End(xlToLeft).Column))
    If myRng.Value = "Names" Then
        NameCol = myRng.Column
        Exit For
    End If
Next myRng

iCount = 0
For Each myKey In myDict
    ListSht.Cells(2 + iCount, NameCol).Value = myKey
    iCount = iCount + 1
Next myKey

Set namedRange = ActiveWorkbook.Names("Names")
namedRange.RefersTo = ListSht.Range(ListSht.Cells(2, NameCol), ListSht.Cells(1 + iCount, NameCol))

' clean up
Set IdeaSht = Nothing
Set ListSht = Nothing
Set myDict = Nothing
Set namedRange = Nothing

End Sub

After running these routines, the named range lists now look like the following ...

enter image description here

These routines are added to the WorkBook_Open Event code, so they stay up to date for the user ...

Private Sub Workbook_Open()
    UpdateNamesList
    UpdateStatusList
    UpdateNumberList
End Sub

Now, the user has drop down lists that are up to date (a similar method could be used to keep combo boxes up to date) ...

enter image description here


Filtering - there can be only one!

To manage clearing filtering in Cell A2 when something is specified in Cell B2, or all other combinations of changes in the three filter specifications, the WorkSheet_Change event code for the Dashboard was used ...

Private Sub Worksheet_Change(ByVal Target As Range)
Dim iLoop As Long
    If Intersect(Target, ActiveSheet.Range("A2:C2")) Is Nothing Then Exit Sub
    Application.EnableEvents = False
    For iLoop = 1 To 3
        If Target.Column <> iLoop Then ActiveSheet.Cells(2, iLoop).Value = ""
    Next iLoop
    Application.EnableEvents = True
End Sub

Now, picking one filter automatically clears the other ...

enter image description here

enter image description here


Filtering and Displaying

The "FetchIdeas" button is connected to the following piece of VBA code ...

Sub FetchAllIdeas()
Dim IdeaSht As Worksheet, DshbrdSht As Worksheet
Dim myRng As Range
Dim lstRow As Long, lstCol As Long
Dim FltrVal() As Variant, FltrCol As Long
Dim myField As Long, iLoop As Long
'Initial
Set IdeaSht = Worksheets("AllIdeas")
Set DshbrdSht = Worksheets("Dashboard")

'Determine which filter we are using
ReDim FltrVal(1 To 1)
myField = 0
For Each myRng In DshbrdSht.Range("A2:C2")
    If myRng.Value <> "" Then
        FltrVal(1) = myRng.Value
        If myRng.Offset(-1, 0).Value = "GetByName" Then myField = 2
        If myRng.Offset(-1, 0).Value = "GetByStatus" Then myField = 3
        If myRng.Offset(-1, 0).Value = "GetByNumber" Then myField = 1
        Exit For
    End If
Next myRng

'Clear the dashboard
lstRow = DshbrdSht.Range("A" & DshbrdSht.Rows.Count).End(xlUp).Row
For iLoop = lstRow To 5 Step -1
    DshbrdSht.Cells(iLoop, 1).EntireRow.Delete
Next iLoop

'Filter the AllIdeas tab
If myField > 0 Then
    lstRow = IdeaSht.Range("A" & IdeaSht.Rows.Count).End(xlUp).Row
    lstCol = IdeaSht.Cells(1, IdeaSht.Columns.Count).End(xlToLeft).Column
    With IdeaSht
        .Cells.AutoFilter
        With .Range(IdeaSht.Cells(1, 1), IdeaSht.Cells(lstRow, lstCol))
            .AutoFilter field:=myField, Criteria1:=FltrVal
' and display on the dashboard
            .SpecialCells(xlCellTypeVisible).Copy Destination:=DshbrdSht.Range("A5")
        End With
    End With
End If


End Sub

It applies the filters, clears the dashboard, and puts the new filterd data on the dashboard ...

enter image description here

enter image description here

enter image description here