Could Not Set the Visible Property Error when Hiding a Frame - vba

I'm having an issue in Excel 2007 VBA whereby I'm trying to set the visible property to false on a frame within a UserForm.
Userform1.Frame1.Visible = False
When trying to set the property, excel throws the error:
Run-time error '-2147418113 (8000ffff)':
Could not set the Visible property. Unexpected call to method or property access.
I've researched this and the only thing that I've uncovered is that it might be something to do with not having a control to take the focus. In my case this is not true though as there is a button available to take the focus on another frame. The other frame is set to be visible prior to Frame1 being hidden.
Has anyone else experienced this issue or can help me understand what is causing this error?
Edit - Code Addition
Public Sub fOpenFrame(uf As UserForm, strName As String)
Dim con As Control
Dim i As Long
i = 5
Application.ScreenUpdating = False
With uf.Controls(strName)
.Top = 38.15
.Left = 120
.Height = 400
.Width = 565
.Visible = True
End With
For Each con In uf.Controls
If TypeName(con) = "Frame" And con.Name <> strName And InStr(con.Name, "Menu") < 1 _
And con.Name <> "frmNewAbsenceButton" And con.Name <> "frmExistingAbsenceButton" Then
With con
.Visible = False 'Error occurs here'
.Top = 5
.Left = i
.Height = 20
.Width = 20
End With
i = i + 25
End If
Next con
Application.ScreenUpdating = True
End Sub
Edit 2 - Pictures Added
This is the first frame Frame1. A msgbox pops up and when the user clicks yes, it opens Frame2.
This is Frame2. This frame opens with all the textboxes / comboboxes disabled. The button control 'Edit' is enabled.

I'd prefer to make all frames invisible first (and not to care about their position nor size); after that the only relevant frame can be made visible.
If the sub is in the userform's macromodule you can use Me("Frame4") and refrain from the argument: 'uf as userform'.
Public Sub fOpenFrame(uf As UserForm, strName As String)
for each it in uf.controls
if typename(it)="Frame" then it.visible=false
next
With uf.Controls(strName)
.Top = 38.15
.Left = 120
.Height = 400
.Width = 565
.Visible = True
End With
End Sub

I have been having the same issue intermittently.
After reading the other answers, I added .setfocus call to a valid textbox before I the visible = false call, and it seemed to fix the issue.
With con
textbox1.setfocus 'Adding this seemed to fix the issue
.Visible = False 'Error occurs here'
.Top = 5
.Left = i
.Height = 20
.Width = 20
End With

I have tested in excel 2010 the the code is working fine(I don't have excel 2007)
Please try the below code.
Private Sub Frame1_Click()
End Sub
Private Sub TextBox1_Change()
End Sub
Private Sub UserForm_Initialize()
Me.Frame1.Visible = False
End Sub

Related

removing controls added during run time

I have a userform that has a text box and whatever value is put into the textbox will determine the number of dynamic controls that are added to the user form and then there is a button and once that is clicked I want the dynamic controls to be removed from the userform altogether.
Below shows the code that is used to create the dynamic controls and this code works perfectly
For i = 1 To TextBox1.Value
newPosition = 360
Set cLabel = Me.Controls.Add("Forms.Label.1")
With cLabel
.Caption = "Label " & (i)
.Font.Size = 8
.Font.Bold = True
.Font.Name = "Tahoma"
'.Left = 70
.Left = 36
.Top = switchBoardLevel
.Width = 130
End With
switchBoardLevel = switchBoardLevel + newPosition
Set cButton = Me.Controls.Add("Forms.CommandButton.1")
With cButton
.Name = "CommandButton" & i
.Caption = "Calculate"
.Left = 300
.Top = buttonStartPosition
.Width = 45
.Height = 18
End With
ReDim Preserve TextListBox(1 To i)
Set TextListBox(i).ButtonGroup = cButton
buttonStartPosition = buttonStartPosition + newPosition
Next i
However there is a problem when it comes to removing the dynamically created controls. I have tried numerous ways to remove the controls. The code below is executed when the button is clicked to remove the controls but it just won't work for me and I am going round in circles so It would be greatly appreciated if someone could give me some guidance on the issue.
For Each TextListBox(i).ButtonGroup In Me.Controls
If (TypeOf TextListBox(i).ButtonGroup Is CommandButton) Then
TextListBox(i).ButtonGroup.Visible = False
End If
Next
You haven't given a lot of information but you can't loop that way - you need to loop through the array:
For i = Lbound(TextListBox) to UBound(TextListBox)
If TypeOf TextListBox(i).ButtonGroup Is MSForms.CommandButton Then
TextListBox(i).ButtonGroup.Visible = False
End If
Next

Excel VBA: Controls have Two Names (was: Label Click event fails)

My spreadsheet has labels that are created and removed dynamically. I have Click events for all of them (non-dynamic; the event code is always there). These are ActiveX labels on the sheet itself, not on a UserForm.
Intermittently, a label will be created that does not respond to clicking. I discovered that it's because some labels don't recognize the name I gave them. In other words, clicking lblLong1 triggers Label1_Click, not lblLong1_Click.
I remember reading somewhere that controls actually have two names. At first they're both the same. It looks like sometimes, my macro reassigns one of the names, and the rest of the time it does the other.
Can someone educate me about the two names of controls? I may not be able to find the place I read it.
If it can't be fixed, can I come up with a workaround?
This is the code that creates the labels, based on the first three controls (which are always present). Only the "lblLong" ones should be clickable:
Sub ControlsCreate()
Dim chkBox As Object, lblShort As Object, lblLong As Object
Dim chkTemp As Object, shortTemp As Object, longTemp As Object
Dim i, NumEntries, NumLines
With Sheets("input view")
Set chkBox = .Shapes("chkBox1")
Set lblShort = .Shapes("lblShort1")
Set lblLong = .Shapes("lblLong1")
chkBox.Top = [narr].Top
With lblShort
.Visible = True
.Top = chkBox.Top
.Left = [d1].Left + 10
.Width = 107
End With
With lblLong
.Top = lblShort.Top
.Visible = lblShort.Visible
.Left = lblShort.Left + lblShort.Width + 5
.Width = 371
End With
If LCase([narrreco].Value) = "type" Then
NumEntries = [tblrecotype].Rows.Count
Else
NumEntries = CutOffLeft([narrreco].Value, 4)
End If
For i = 2 To NumEntries
Set shortTemp = .OLEObjects.Add(ClassType:="Forms.Label.1", Link:=False, _
DisplayAsIcon:=False, Left:=lblShort.Left, Top:=chkBox.Top + 20 * i, Width:= _
lblShort.Width, Height:=lblShort.Height)
Set longTemp = .OLEObjects.Add(ClassType:="Forms.Label.1", Link:=False, _
DisplayAsIcon:=False, Left:=lblLong.Left, Top:=chkBox.Top + 20 * i, _
Width:=lblLong.Width, Height:=lblShort.Height)
shortTemp.Name = "lblShort" & i
longTemp.Name = "lblLong" & i
Next i
End With
End Sub
These are some of the click events for the labels:
Private Sub lblLong1_Click()
Call LabelstoFields(Me.lblLong1.Caption)
End Sub
Private Sub lblLong2_Click()
Call LabelstoFields(Me.lblLong2.Caption)
End Sub
Private Sub lblLong3_Click()
Call LabelstoFields(Me.lblLong3.Caption)
End Sub
(Etc.)

Creating Permanent Textbox on an Excel Userform

So I am creating a tool and user guide for my client. I am attempting to integrate the user guide into Excel in the form of a Userform. My first attempt was to insert these as images of the word document, however, if the user guide is ever updated that could mean a lot of work for anyone to update the userform as well. So I was looking to see if I could have a button for the user to click that would clear the userform and recreate it dynamically any time the User Guide is updated. My issue is that when I run my code the textboxes I create which contain the text from the user guide disappear after the userform is closed.
Do I have to have a set number of textboxes or can this be dynamic in the case that the user ever adds a new section to the user guide? Can I create textboxes that stay on the userform once it is closed?
My code is below:
For i = 1 To totPara
If wrdDoc.Paragraphs(i).Style = wrdDoc.Styles("Heading 1") Or wrdDoc.Paragraphs(i).Style = wrdDoc.Styles("Heading 2") Then
headerCtr = headerCtr + 1
If headerCtr = 2 Then
labelCtr = labelCtr + 1
Set tempTxt = Nothing
Set tempTxt = userGuide.Controls.Add("Forms.TextBox.1", "Test" & labelCtr, True)
With tempTxt
.Height = 276
.Width = 288
.Top = 54
.Left = 42
.MultiLine = True
End With
tempTxt.Text = wrdDoc.Paragraphs(i).Range.Text & Chr(13)
ElseIf headerCtr > 2 Then
Exit For
End If
ElseIf labelCtr <> 0 Then
tempTxt.Text = tempTxt.Text & wrdDoc.Paragraphs(i).Range.Text & Chr(13)
End If
Next i
For right now I set it to create a new textbox only when headerCtr is equal to 2 for testing but eventually I would like to create a new textbox for each of the 9 sections.
Thank you in advance for any help.
You have the option Hide the userform instead of Close the userform. When it is hidden the textboxes can still be accessed from the calling form.
Dim frm1 As frmMainInput
Set frm1 = New frmMainInput
frm1.tbProjectNumber.Value = iProject_Number
frm1.txtDocsInUse.Text = sDocsInUse
frm1.Show
If frm1.Proceed = False Then
GoTo Local_Exit
End If
iProject_Number = CInt(frm1.tbProjectNumber.Value)
Eventually call frm.close and set frm = Nothing
In the UserForm:
Private Sub cmdCancel_Click()
Proceed = False
Me.Hide
End Sub
Private Sub cmdOK_Click()
Proceed = True
Me.Hide
End Sub
No clue about the refreshing images etc.c

Type 13 mismatch error in VBA excel

Dear friends I'm trying to display photos of the persons as per the name selected in a combo box.
I'm successful in doing that but my problem is that
while continuously choosing different names in combo box suddenly at times it displays ** error 13, type mismatch** and my combo box too disappearing. But after that making the visibility of Mypics(Name defined to the table of person names and pictures) "TRUE" its appearing again after compiling 2 to 3 times.
here is my code
Private Sub Worksheet_Calculate()
Dim Mypics As Picture
Me.Pictures.Visible = False
With Range("B8")
For Each Mypics In Me.Pictures
If (Mypics.Name = .Text) Then
Mypics.Visible = True
Mypics.Top = .Top
Mypics.Left = .Left
Exit For
End If
Next Mypics
End With
End Sub
The cell "B8" is where the name of the picture appears according to the selected person name in combo box with reference to the Index number.
Often, cleaning up your code can produce wonders. I sincerely suggest avoiding using With if you're just aiming to use it once, as in your original code. How about trying the following:
Private Sub Worksheet_Calculate()
Dim Mypics As Picture
Dim TargetName As String
TargetName = Range("B8").Text
Me.Pictures.Visible = False
For Each Mypics In Me.Pictures
If Mypics.Name = TargetName Then
With Mypics
.Visible = True
.Top = .Top
.Left = .Left
End With
Exit For
End If
Next Mypics
End Sub
Let us know if this works. Also, try to Dim everything you can properly Dim. Often, a type mismatch error is thrown due to a variable being declared wrongly at the beginning of a code.

Finding if a TextBox/Label caption fits in the control

The scenario is trying to adjust font size to get a nice graphic arrangement, or trying to decide where to break a caption/subtitle.
a) In XL VBA is there a way to find out whether a text on a textbox, or caption on a label, still fits the control?
b) Is there a way to know where was the text/caption broken on multiline control?
I gave this a rest, gave it enough back-of-head time (which produces far better results than "burp a non-answer ASAP, for credits"), and...
Function TextWidth(aText As String, Optional aFont As NewFont) As Single
Dim theFont As New NewFont
Dim notSeenTBox As Control
On Error Resume Next 'trap for aFont=Nothing
theFont = aFont 'try assign
If Err.Number Then 'can't use aFont because it's not instantiated/set
theFont.Name = "Tahoma"
theFont.Size = 8
theFont.Bold = False
theFont.Italic = False
End If
On Error GoTo ErrHandler
'make a TextBox, fiddle with autosize et al, retrive control width
Set notSeenTBox = UserForms(0).Controls.Add("Forms.TextBox.1", "notSeen1", False)
notSeenTBox.MultiLine = False
notSeenTBox.AutoSize = True 'the trick
notSeenTBox.Font.Name = theFont.Name
notSeenTBox.SpecialEffect = 0
notSeenTBox.Width = 0 ' otherwise we get an offset (a ""feature"" from MS)
notSeenTBox.Text = aText
TextWidth = notSeenTBox.Width
'done with it, to scrap I say
UserForms(0).Controls.Remove ("notSeen1")
Exit Function
ErrHandler:
TextWidth = -1
MsgBox "TextWidth failed: " + Err.Description
End Function
I feel I'm getting/got close to answer b), but I'll give it a second mind rest... because it works better than stating "impossible" in a flash.
I'm sure there is no way to do this with the ordinary Excel controls on the Forms toolbar, not least because (as I understand it) they are simply drawings and not full Windows controls.
The simplest approach may be to make a slightly conservative estimate of the maximum text length for each control, through a few tests, and use these to manage your line breaks.
This can be achieved by taking advantage of the label or textbox's .AutoSize feature, and looping through font sizes until you reach the one that fits best.
Public Sub ResizeTextToFit(Ctrl As MSForms.Label) 'or TextBox
Const FONT_SHRINKAGE_FACTOR As Single = 0.9 'For more accuracy, use .95 or .99
Dim OrigWidth As Single
Dim OrigHeight As Single
Dim OrigLeft As Single
Dim OrigTop As Single
With Ctrl
If .Caption = "" Then Exit Sub
.AutoSize = False
OrigWidth = .Width
OrigHeight = .Height
OrigLeft = .Left
OrigTop = .Top
Do
.AutoSize = True
If .Width <= OrigWidth And .Height <= OrigHeight Then
Exit Do 'The font is small enough now
.Font.Size = .Font.Size * FONT_SHRINKAGE_FACTOR
.AutoSize = False
Loop
.AutoSize = False
.Width = OrigWidth
.Height = OrigHeight
.Left = OrigLeft
.Top = OrigTop
End With
End Sub