Excel 2010 VBA Can't get Sub Menus to display - vba

I have the following code that builds a custom menu in Excel. Works well. I'm trying to modify it to use sub menus. It will add the menu item for East Options and West Options. I'm trying to modify the East and West # 1 items so they appear as a sub menu. I've tried a number of different things but I haven't got the syntax right. Any help would be appreciated. Thanks.........
Dim cbWsMenuBar As CommandBar
Dim TrCustom As CommandBarControl
Dim iHelpIndex As Long
Dim vFoundMenu As Boolean
Set cbWsMenuBar = Application.CommandBars("Worksheet Menu Bar")
cbWsMenuBar.Visible = True
Dim CCnt As Long
For CCnt = 1 To cbWsMenuBar.Controls.Count
If InStr(1, cbWsMenuBar.Controls(CCnt).Caption, "Translate") > 0 Then vFoundMenu = True
Next CCnt
If vFoundMenu = False Then
Set TrCustom = cbWsMenuBar.Controls.Add(Type:=msoControlPopup) ', before:=iHelpIndex)
With TrCustom
.Caption = "Menu Items”
With .Controls.Add(Type:=msoControlButton)
.Caption = "Business Unit to Group"
.OnAction = "ShowBU2GP"
End With
With .Controls.Add(Type:=msoControlButton)
.Caption = "Group to Business Unit"
.OnAction = "ShowGP2BU"
End With
With .Controls.Add(Type:=msoControlPopup)
.Caption = "East Region Options"
End With
‘ EAST # 1
' With .Controls.Add(Type:=msoControlButton)
' .Caption = "East Branch to DeptID"
' .OnAction = "ShowEastDeptID"
' .BeginGroup = True
' End With
With .Controls.Add(Type:=msoControlPopup)
.Caption = "West Options"
End With
' WEST # 1
' With .Controls.Add(Type:=msoControlButton)
' .Caption = "West Branch to DeptID"
' .OnAction = "ShowWestDeptID"
' .BeginGroup = True
' End With
End With
End If

I will show you a very simple example. Please amend it to suit your needs :)
Private Sub Sample()
Dim cb As CommandBar
Dim cbc As CommandBarControl
Dim newitem As CommandBarControl
Dim newSubItem As CommandBarControl
Set cb = Application.CommandBars(1)
'~~> Delete Existing command bar control
On Error Resume Next
cb.Controls("Menu Items").Delete
On Error GoTo 0
'~~> Re Create the Command Bar Control
Set cbc = cb.Controls.Add(Type:=msoControlPopup, temporary:=False)
With cbc
'~~> Main Heading
.Caption = "Menu Items"
'~~> First Sub Heading
Set newitem = .Controls.Add(Type:=msoControlPopup)
With newitem
.BeginGroup = True
.Caption = "East Region Options"
Set newSubItem = .Controls.Add(Type:=msoControlButton)
With newSubItem
.BeginGroup = True
'~~> Sub Item
.Caption = "Sub Item for East Region Options"
.Style = msoButtonCaption
.OnAction = "SomeMacro"
End With
End With
'~~> Second Sub Heading
Set newitem = .Controls.Add(Type:=msoControlPopup)
With newitem
.BeginGroup = True
.Caption = "West Region Options"
Set newSubItem = .Controls.Add(Type:=msoControlButton)
With newSubItem
.BeginGroup = True
'~~> Sub Item
.Caption = "Sub Item for Est Region Options"
.Style = msoButtonCaption
.OnAction = "SomeMacro"
End With
End With
'
'~~> And So On
'
End With
End Sub
Screenshot

Related

VLookup from excel workbook on a network drive

Right now I have 8 different textbox controls on a UserForm that when a value is entered a macro runs to open a workbook saved on a network folder then a VLookup is run. Below is the code for two of the TextBox controls and as you can see (due to my lack of coding ability); I ended up with 8 separate subs for each of the text boxes which opens up the workbook on the shared drive after a value is entered in the text box then closes the workbook and is not very efficient. After some research I am thinking of using Index and Match would be a better solution, but have no familiarity with those excel functions in VBA and could use some help with getting a starting point using Index and Match, if that is a better solution. Thank you all for your assistance.
Sub b1CIF()
Dim CustList As Workbook
Dim thisWB As Workbook
Dim thisWS As Worksheet
Dim wsRR As Worksheet
Dim bColor As Range
Dim Msg, Style, Title, Response
Msg = "OOOPS!" & vbNewLine & vbNewLine & "The CIF Number of " & LendStart.lsPBCIF.Value & " " & "is not correct or does not exist." & vbNewLine & "Please re-enter the CIF Number."
Style = vbOKCancel + vbCritical
Title = UCase("***CIF Data Entry Error!***")
Application.ScreenUpdating = False
Set CustList = Workbooks.Open("L:\Deposits\Information\Customers.xlsm")
Set thisWB = ThisWorkbook
Set thisWS = thisWB.Sheets("SavedInfo")
Set wsRR = thisWB.Sheets("RiskRating")
Set bColor = wsRR.Range("C3")
On Error GoTo ErrHandler
' NAME GRAB
If thisWS.Range("A2") <> "" Then
thisWS.Range("PBName").Value = _
WorksheetFunction.VLookup(thisWS.Range("A2").Value, CustList.Sheets("CIFMAST").Range("A1:Z50000"), 2, False)
With LendStart.lsPBName
.Value = thisWS.Range("PBName")
.Visible = True
.Locked = True
.BackColor = bColor.Interior.Color
.Font.Bold = True
.Font.Size = 9
.TextAlign = fmTextAlignCenter
.TabStop = False
End With
thisWB.Sheets("BorrInfo").Range("PB").Value = thisWS.Range("PBName")
' TELEPHONE NUMBER GRAB
thisWB.Sheets("BorrInfo").Range("PBPhone").Value = _
WorksheetFunction.VLookup(thisWS.Range("A2").Value, CustList.Sheets("CIFMAST").Range("A1:Z50000"), 9, False)
End If
CustList.Close
Application.ScreenUpdating = True
Exit Sub
ErrHandler:
LendStart.lsPBSCIF.Value = ""
With LendStart.lsPBName
.Value = ""
.Locked = True
End With
Response = MsgBox(Msg, Style, Title)
CustList.Close
Application.ScreenUpdating = True
End Sub
Sub b2CIF()
Dim CustList As Workbook
Dim thisWB As Workbook
Dim thisWS As Worksheet
Dim wsRR As Worksheet
Dim bColor As Range
Dim Msg, Style, Title, Response
Msg = "The CIF Number entered " & LendStart.lsPBSCIF.Value & " " & "is not correct." & vbNewLine & "Please re-enter the CIF Number."
Style = vbOKCancel + vbCritical
Title = UCase("***CIF data entry error!***")
Application.ScreenUpdating = False
Set CustList = Workbooks.Open("L:\Deposits\Information\Customers.xlsm")
Set thisWB = ThisWorkbook
Set thisWS = thisWB.Sheets("SavedInfo")
Set wsRR = thisWB.Sheets("RiskRating")
Set bColor = wsRR.Range("C3")
On Error GoTo ErrHandler
' NAME GRAB
If thisWS.Range("A3") <> "" Then
thisWS.Range("PBSName").Value = _
WorksheetFunction.VLookup(thisWS.Range("A3").Value, CustList.Sheets("CIFMAST").Range("A1:Z50000"), 2, False)
With LendStart.lsPBSName
.Value = thisWS.Range("PBSName")
.Visible = True
.Locked = True
.BackColor = bColor.Interior.Color
.Font.Bold = True
.Font.Size = 9
.TextAlign = fmTextAlignCenter
.TabStop = False
End With
thisWB.Sheets("BorrInfo").Range("PBS").Value = thisWS.Range("PBSName")
' TELEPHONE NUMBER GRAB
thisWB.Sheets("BorrInfo").Range("PBSPhone").Value = _
WorksheetFunction.VLookup(thisWS.Range("A3").Value, CustList.Sheets("CIFMAST").Range("A1:Z50000"), 9, False)
End If
CustList.Close
Application.ScreenUpdating = True
Exit Sub
ErrHandler:
LendStart.lsPBSCIF.Value = ""
Response = MsgBox(Msg, Style, Title)
CustList.Close
Application.ScreenUpdating = True
End Sub

dropdown list with autocomplete/ suggestion in excel vba

In a merged cell (named as SelName) I have a dropdown list with more then 100 items. Searching through the list is not efficient, as this list is constantly growing. Therefore, I would like to have a dropdown list with autocomplete/ suggestion function. One of the codes that I have is the following which I have found on extendoffice.com:
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
'Update by Extendoffice: 2017/8/15
Dim xCombox As OLEObject
Dim xStr As String
Dim xWs As Worksheet
Dim Cancel As Boolean
Set xWs = Application.ActiveSheet
'On Error Resume Next
Set xCombox = xWs.OLEObjects("TempCombo")
With xCombox
.ListFillRange = ""
.LinkedCell = ""
.Visible = False
End With
If Target.Validation.Type = 3 Then
Target.Validation.InCellDropdown = False
Cancel = True
xStr = Target.Validation.Formula1
xStr = Right(xStr, Len(xStr) - 1)
If xStr = "" Then Exit Sub
With xCombox
.Visible = True
.Left = Target.Left
.Top = Target.Top
.Width = Target.Width + 5
.Height = Target.Height + 5
.ListFillRange = xStr
.LinkedCell = Target.Address
End With
xCombox.Activate
Me.TempCombo.DropDown
End If
End Sub
Private Sub TempCombo_KeyDown(ByVal KeyCode As MSForms.ReturnInteger, ByVal Shift As Integer)
Select Case KeyCode
Case 9
Application.ActiveCell.Offset(0, 1).Activate
Case 13
Application.ActiveCell.Offset(1, 0).Activate
End Select
End Sub
First, I tried to test it in an empty sheet (with just the dropdown list) and it worked well. But as soon as I try to insert this code into the other worksheet, it doesn't. Does anyone has an idea what the problem could be?
FYI: I have several drop down lists in this worksheet and all of them are in merged cells. Additionally, I have some other Private subs...
Why do you have to do that instead of just creating a ComboBox control and setting ListFillRange and LinkedCell without any code?
The error happens because the Range you are editing (Target) does not have any Validation. You should add the check for validation:
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
Dim vType As XlDVType
On Error GoTo EndLine
vType = Target.Validation.Type
Dim xCombox As OLEObject
Dim xStr As String
Dim xWs As Worksheet
Dim Cancel As Boolean
Set xWs = Application.ActiveSheet
'On Error Resume Next
Set xCombox = xWs.OLEObjects("TempCombo")
With xCombox
.ListFillRange = ""
.LinkedCell = ""
.Visible = False
End With
If vType = 3 Then
Target.Validation.InCellDropdown = False
Cancel = True
xStr = Target.Validation.Formula1
xStr = Right(xStr, Len(xStr) - 1)
If xStr = "" Then Exit Sub
With xCombox
.Visible = True
.Left = Target.Left
.Top = Target.Top
.Width = Target.Width + 5
.Height = Target.Height + 5
.ListFillRange = xStr
.LinkedCell = Target.Address
End With
xCombox.Activate
Me.TempCombo.DropDown
End If
EndLine:
End Sub
EDIT
If i understand the problem correctly, you want a ComboBox that auto-fills from a column and auto-updates if you type more entries in the column. There is no need for such complicated code. You can simply add a ComboBox (say ComboBox1), set its ListFillRange (e.g. to A1:A20) and do this:
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
With ComboBox1
Dim OrigRange As Range: OrigRange = .ListFillRange
If Not Application.Intersect(OrigRange, Target) Is Nothing Then
.ListFillRange = .OrigRange.Resize(OrigRange.Cells(1).End(xlDown).Row - OrigRange.Row + 1)
End If
End With
End Sub
Autocomplete Dropdowns are now native with excel O365
https://www.excel-university.com/autocomplete-for-data-validation-dropdown-lists/

Outlook custom menu buttons

i have 2 menu buttons that i want added in outlook menu after help menu. i made the code to add the buttons but it just adds 2 more buttons every time i reopen outlook even if the 2 menu buttons are there already . Any help is welcomed.
Function ToolBarExists(strName As String) As Boolean
Dim tlbar As commandBar
For Each tlbar In ActiveExplorer.CommandBars
If tlbar.Name = strName Then
ToolBarExists = True
Exit For
End If
Next tlbar
End Function
Sub TBarExistsbutton1()
If ToolBarExists("button1") Then
If ActiveExplorer.CommandBars("button1").Visible = True Then
ActiveExplorer.CommandBars("button1").Visible = False
Else
ActiveExplorer.CommandBars("button1").Visible = True
End If
Else
Call a123
End If
End Sub
Sub TBarExistsbutton2()
If ToolBarExists("button2") Then
If ActiveExplorer.CommandBars("button2").Visible = True Then
ActiveExplorer.CommandBars("button2").Visible = False
Else
ActiveExplorer.CommandBars("button2").Visible = True
End If
Else
Call a1234
End If
End Sub
Sub a123()
Dim outl As Object
Dim msg As Object
Set outl = CreateObject("Outlook.Application")
Dim objBar As Office.commandBar
Dim objButton As Office.commandBarButton
Set objBar = Application.ActiveWindow.CommandBars("Menu Bar")
Set objButton = objBar.Controls.Add(msoControlButton)
With objButton
.caption = "button1"
.onAction = "macro1"
.faceId = 487
.Style = msoButtonIconAndCaption
End With
End Sub
Sub a1234()
Dim outl As Object
Dim msg As Object
Set outl = CreateObject("Outlook.Application")
Dim objBar As Office.commandBar
Dim objButton As Office.commandBarButton
Set objBar = Application.ActiveWindow.CommandBars("Menu Bar")
Set objButton = objBar.Controls.Add(msoControlButton)
With objButton
.caption = "button2"
.onAction = "macro2"
.faceId = 487
.Style = msoButtonIconAndCaption
End With
End Sub
In Outlook 2010. If Visible works for you incorporate it in a similar manner.
Option Explicit
Sub TBarExistsbutton1()
Dim cbControlCount As Long
Dim button1Found As Boolean
Dim j As Long
If ToolBarExists("Menu Bar") Then
cbControlCount = ActiveWindow.CommandBars("Menu Bar").Controls.count
Debug.Print " There are " & cbControlCount & " controls in " & "Menu Bar"
For j = 1 To cbControlCount
Debug.Print ActiveWindow.CommandBars("Menu Bar").Controls(j).Caption
If ActiveWindow.CommandBars("Menu Bar").Controls(j).Caption = "button1" Then
button1Found = True
Exit For
End If
Next j
If button1Found = False Then a123
Else
Debug.Print "Menu Bar does not exist."
a123
End If
End Sub

When locking a sheet, the VB Code stops working

Here is my code; when I lock the sheet the code stops working and will not pop up on the double click.
On another note is there a way to activate the code without requiring it to double click?
Private Sub Worksheet_Activate()
End Sub
'==========================
Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, _
Cancel As Boolean)
Dim str As String
Dim cboTemp As OLEObject
Dim ws As Worksheet
Set ws = ActiveSheet
Set cboTemp = ws.OLEObjects("NameBox")
On Error Resume Next
With cboTemp
'clear and hide the combo box
.ListFillRange = ""
.LinkedCell = ""
.Visible = False
End With
On Error GoTo errHandler
If Target.Validation.Type = 3 Then
'if the cell contains a data validation list
Cancel = True
Application.EnableEvents = False
'get the data validation formula
str = Target.Validation.Formula1
str = Right(str, Len(str) - 1)
With cboTemp
'show the combobox with the list
.Visible = True
.Left = Target.Left
.Top = Target.Top
.Width = Target.Width + 5
.Height = Target.Height + 5
.ListFillRange = str
.LinkedCell = Target.Address
End With
cboTemp.Activate
'open the drop down list automatically
Me.NameBox.DropDown
End If
errHandler:
Application.EnableEvents = True
Exit Sub
End Sub
'=========================================
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
Dim str As String
Dim cboTemp As OLEObject
Dim ws As Worksheet
Set ws = ActiveSheet
Application.EnableEvents = False
Application.ScreenUpdating = True
If Application.CutCopyMode Then
'allow copying and pasting on the worksheet
GoTo errHandler
End If
Set cboTemp = ws.OLEObjects("NameBox")
On Error Resume Next
With cboTemp
.Top = 10
.Left = 10
.Width = 0
.ListFillRange = ""
.LinkedCell = ""
.Visible = False
.Value = ""
End With
errHandler:
Application.EnableEvents = True
Exit Sub
End Sub
'====================================
'Optional code to move to next cell if Tab or Enter are pressed
'from code by Ted Lanham
'***NOTE: if KeyDown causes problems, change to KeyUp
Private Sub NameBox_KeyDown(ByVal _
KeyCode As MSForms.ReturnInteger, _
ByVal Shift As Integer)
Select Case KeyCode
Case 9 'Tab
ActiveCell.Offset(0, 1).Activate
Case 13 'Enter
ActiveCell.Offset(1, 0).Activate
Case Else
'do nothing
End Select
End Sub
'====================================

VBA If Not Intersect not working for larger values on worksheet_change

I have the following code:
Private Sub Worksheet_Change(ByVal Target As Range)
Dim btn As Button
Dim t As Range
Dim i As Integer
i = Target.Row
If Not Intersect(Target, Range("$B10:$B103")) Then
If Target.Value <> "" Then
For Each btn In ActiveSheet.Buttons
If btn.Name = "I" & i Then
btn.Delete
End If
Next btn
Set t = ActiveSheet.Range(Cells(i, 9), Cells(i, 9))
Set btn = ActiveSheet.Buttons.Add(t.Left, t.Top, t.Width, t.Height)
With btn
.OnAction = "imageshow"
.Caption = "View Images"
.Name = "I" & i
End With
Else
For Each btn In ActiveSheet.Buttons
If btn.Name = "I" & i Then
btn.Delete
End If
Next btn
End If
End If
End Sub
When I run it, it works if the value entered into B10:B103 is an Integer number, but if I use text or a Long number a combination of text and numbers (data entered in here will be of this form) then it will not work.
Change two lines:
Private Sub Worksheet_Change(ByVal Target As Range)
Dim btn As Button
Dim t As Range
Dim i As Long
i = Target.Row
If Not Intersect(Target, Range("$B10:$B103")) Is Nothing Then
If Target.Value <> "" Then
For Each btn In ActiveSheet.Buttons
If btn.Name = "I" & i Then
btn.Delete
End If
Next btn
Set t = ActiveSheet.Range(Cells(i, 9), Cells(i, 9))
Set btn = ActiveSheet.Buttons.Add(t.Left, t.Top, t.Width, t.Height)
With btn
.OnAction = "imageshow"
.Caption = "View Images"
.Name = "I" & i
End With
Else
For Each btn In ActiveSheet.Buttons
If btn.Name = "I" & i Then
btn.Delete
End If
Next btn
End If
End If
End Sub