VBA Application worksheet function error:1004 - vba

I was trying to add index/match values to a textbox , when a combobox value is selected. I get error :1004. What I am doin wrong? Thanks
Private Sub cmbStkItem_Change()
Dim sh As Worksheet
Set sh = Sheets("suppliersdb")
txtStkSupName.Value = Application.WorksheetFunction.Index(sh.Range("B2:B100"), Application.WorksheetFunction.Match(Me.cmbStkItem.Value, sh.Range("c2:c100"), 0), "")
End Sub

Related

Event triggered by ANY checkbox click

I'm going crazy trying to find a way for code to run when I click on ANY of the checkboxes on my sheet. I've seen multiple articles talking about making a class module, but I can't seem to get it to work.
I have code that will populate column B to match column C. Whatever I manually type into C10 will populate into B10, even if C10 is a formula: =D9. So, I can type TRUE into D10 and the formula in C10 will result in: TRUE and then the code populates B10 to say: TRUE. Awesome... the trick is to have a checkbox linked to D10. When I click the checkbox, D10 says TRUE and the formula in C10 says TRUE, but that is as far as it goes. The VBA code does not recognize the checkbox click. If I then click on the sheet (selection change), then the code will run, so I know I need a different event.
It is easy enough to change the event to "Checkbox1_Click()", but I want it to work for ANY checkbox I click. I'm not having ANY luck after days of searching and trying different things.
here is the code I'm running so far
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
Dim i As Long
For i = 3 To 11
Range("B" & i).Value = Range("c" & i)
Next i
End Sub
Any help would be appreciated.
this works
' this goes into sheet code
Private Sub Worksheet_Activate()
activateCheckBoxes
End Sub
.
' put all this code in class a module and name the class module "ChkClass"
Option Explicit
Public WithEvents ChkBoxGroup As MSForms.CheckBox
Private Sub ChkBoxGroup_Change()
Debug.Print "ChkBoxGroup_Change"
End Sub
Private Sub ChkBoxGroup_Click()
Debug.Print "ChkBoxGroup_Click"; vbTab;
Debug.Print ChkBoxGroup.Caption; vbTab; ChkBoxGroup.Value
ChkBoxGroup.TopLeftCell.Offset(0, 2) = ChkBoxGroup.Value
End Sub
.
' this code goes into a module
Option Explicit
Dim CheckBoxes() As New ChkClass
Const numChkBoxes = 20
'
Sub doCheckBoxes()
makeCheckBoxes
activateCheckBoxes
End Sub
Sub makeCheckBoxes() ' creates a column of checkBoxes
Dim sht As Worksheet
Set sht = ActiveSheet
Dim i As Integer
For i = 1 To sht.Shapes.Count
' Debug.Print sht.Shapes(1).Properties
sht.Shapes(1).Delete
DoEvents
Next i
Dim xSize As Integer: xSize = 2 ' horizontal size (number of cells)
Dim ySize As Integer: ySize = 1 ' vertical size
Dim t As Range
Set t = sht.Range("b2").Resize(ySize, xSize)
For i = 1 To numChkBoxes
sht.Shapes.AddOLEObject ClassType:="Forms.CheckBox.1", Left:=t.Left, Top:=t.Top, Width:=t.Width - 2, Height:=t.Height
DoEvents
Set t = t.Offset(ySize)
Next i
End Sub
Sub activateCheckBoxes() ' assigns all checkBoxes on worksheet to ChkClass.ChkBoxGroup
Dim sht As Worksheet
Set sht = ActiveSheet
ReDim CheckBoxes(1 To 1)
Dim i As Integer
For i = 1 To sht.Shapes.Count
ReDim Preserve CheckBoxes(1 To i)
Set CheckBoxes(i).ChkBoxGroup = sht.Shapes(i).OLEFormat.Object.Object
Next i
End Sub
All you need is to let EVERY checkbox's _Click() event know that you want to run the Worksheet_SelectionChange event. To do so you need to add the following line into every _Click() sub:
Call Worksheet_SelectionChange(Range("a1"))
Please note that it is irrelevant what range is passed to the SelectionChange sub since you do not use the Target in your code.

Copying cell value to textbox vba

I have been trying to write a macro that will dynamically fill a textbox on a new sheet will the value of a cell from another sheet.
I have managed to get it working using this:
Sub copyDetail()
' Define variables
Dim pre As Worksheet
Dim des As Worksheet
Set pre = Sheets("Presentation")
Set des = Sheets("Description")
Dim i As Integer
Dim lbl As String
' Scroll through labels and copy where boolean = 1
For i = 2 To 17
If des.Cells(i, 2) = 1 Then
lbl = des.Cells(i, 11)
Sheets("Presentation").Select
ActiveSheet.Shapes.Range(Array("TextBox 1")).Select
Selection.Text = lbl
Else
End If
Next i
End Sub
I basically want to be able to do exactly what this does but without using select all the time as this changes sheets and slows down my code (I have many other sub's to run alongside this one). I've tried things like defining the textbox using this:
Dim myLabel As Object
Set myLabel = pre.Shapes.Range(Array("TextBox 1"))
But then I get an "object doesn't support this property or method" error when I try and call:
myLabel.Text = lbl
You can set the text of a TextBox like so:
ActiveSheet.Shapes("TextBox 1").TextFrame.Characters.Text = "Hello world"
You can set-up a little helper Sub in a Module to make the code re-usable:
Public Sub SetTextBoxText(ws As Worksheet, strShapeName As String, strText As String)
Dim shp As Shape
On Error Resume Next
Set shp = ws.Shapes(strShapeName)
If Not shp Is Nothing Then
shp.TextFrame.Characters.Text = strText
Else
Debug.Print "Shape not found"
End If
End Sub

VBA: Populating ListBox ActiveX control, on worksheet and not user form

I'm trying to populate a List Box (ActiveX control). This list box is on a sheet labeled "Dashboard" of my workbook, and not a user form. I want to populate it with a range from a sheet labeled "Data".
My problem is that if I populate it on the workbook open event procedure, I get an error when the workbook opens that it "Can't execute in break mode." However, there aren't breakpoints active at all.
If I populate it on the "Dashboard" worksheet active event procedure, it won't populate when the workbook is open. It only populates if I click on another worksheet, and then go back to the Dashboard worksheet, then it will populate.
Is there a better way to populate the list box so that it's always populated and ready to go? I have a lot of vLookup functions that are associated with the list box, and if the list box is not populated, then the rest of my code won't work.
I will post my codes that I have so far. The first is when I attempt to populate the listbox through the workbook_open even procedure. The second is through the "Dashboard" worksheet activate procedure.
Private Sub Workbook_Open()
Dim strName As String
Dim blDone As Boolean
Dim cPlanets As MSForms.ListBox
Dim vArray As Variant
Dim shtData As Worksheet
Dim wkbSolarSystem As Workbook
Set wkbSolarSystem = Application.Workbooks("workbookname.xlsm")
Set shtData = wkbSolarSystem.Worksheets("Data")
Set cPlanets = wkbSolarSystem.Worksheets("Dashboard").lstPlanets
vArray = shtData.Range("Planets").value
cPlanets.List = vArray
cPlanets.ListIndex = 3
'input box message for user when workbook opens up
strName = InputBox("Hello! Please enter your name", "Welcome!")
'check if there is a name entered via loop and if statement
Do
If Len(strName) = 0 Then
'if no name entered, ask user again
MsgBox ("Please enter a valid name to continue"), vbCritical, "Valid Name Required"
'ask user to type in name again
strName = InputBox("Hello! Please enter your name", "Welcome!")
Else
'display message with information for user
MsgBox ("Hello, " & strName)
blDone = True
End If
'finish loop statement
Loop Until blDone = True
This next code is the one I have on Sheet3 code worksheet activate procedure
Private Sub Worksheet_Activate()
Dim shtData As Worksheet
Dim wkbSolarSystem As Workbook
Set wkbSolarSystem = Application.Workbooks("workbookname.xlsm")
Set shtData = wkbSolarSystem.Worksheets("Data")
lstPlanets.List = shtData.Range("Planets").value
lstPlanets.ListIndex = 3
End Sub
You are declaring cPlanets as MSForms.ListBox, but in your question you say you are working with an ActiveX listbox on a sheet. So you should declare cPlanets as an Object, like:
Dim cPlanets As Object
Set cPlanets = wkbSolarSystem.Worksheets("Dashboard").lstPlanets
I tried this code on a different computer, and it works. It seems that it's the computer configuration that was causing the issue. The code works fine as it should on several different computers.

How to check if Excel sheet contains activeX control?

I try to create a macro, placed in Workbook_Open() procedure, which adds items for combo boxes, named CBTask for each sheet in workbook, (which has combo box named CBTask in it).
Unfortunatelly following code generates Compile error: Method or data member not found"
I believe it is because not every sheet has CBTask in it (even on error resume next does not help).
Is there any way to check if sheet contains combo box, so I could do the checking before trying clear it, or adding new items?
Private Sub Workbook_Open()
Dim ws As Worksheet
Dim i As Integer
Dim strTaskName As String
On Error Resume Next
For Each ws In ThisWorkbook.Worksheets
ws.CBTask.Clear
strTaskName = taskName(1)
Do
ws.CBTask.AddItem strTaskName
strTaskName = taskName(i)
i = i + 1
Loop While taskName <> "LastOne"
Next ws
On Error GoTo 0
End Sub
(as you can see, this code also uses additional function "taskName(intSubtaskValue as integer)" to convert integer to string (e.g. taksName(1) = "Task01", taskName(2) = "Task02...)
The Worksheet class doesn't have a member named CBTask which is why that code fails. I suggest you use the OLEObjects property instead:
ws.OLEObjects("CBTask").Object.Clear
To expand on Rory's answer, in addition to fully qualifying your objects, you can check if an ActiveX-control of a given name exists on a worksheet by using this function:
Function obj_exists(obj_name As String, on_worksheet As Worksheet) As Boolean
On Error GoTo errHandler
Debug.Print on_worksheet.OLEObjects(obj_name).Name
obj_exists = True
On Error GoTo 0
Exit Function
errHandler:
obj_exists = False
On Error GoTo 0
End Function

Get the value of an Excel cell using a Range object

I have a VB.Net function in an Excel addin that I need to find the first occurrence of a string in a worksheet, then return the entire value of the cell. For example, if cell F4 contains "apples and oranges", then Findit("apples") should find a range of $F$4, and return "apples and oranges".
In the code below, I'm getting the correct range stored in MatchedRange, but I can't figure out how to use that to get the value of that cell. I know I need to make the cell active, but that's where I'm struggling.
Private Sub FixFormulasButton_OnClick(sender As Object, control As IRibbonControl, pressed As Boolean) Handles FixFormulasButton.OnClick
Dim ws As Object = CType(ExcelApp.ActiveSheet, Excel.Worksheet)
Dim cells As Object = ws.Cells
Dim MatchRange As Object = CType(cells.Find("apples", LookAt:=Excel.XlLookAt.xlPart, Lookin:=Excel.XlFindLookIn.xlFormulas), Excel.Range)
If MatchRange Is Nothing Then
MessageBox.Show("found no apples", "do nothing", MessageBoxButtons.OK)
Else
MessageBox.Show(the contents of the cell at the range found above)
End if
End Sub