Modeless MsgBox, Error trapping, .Find - vba

I have a subroutine that searches for an occurrence of a string in another workbook. I'm trying to get an error message to pop up if the string can't be found (it's most likely due to spelling mistakes), as vbModeless, and allows to user to click on the cell in the searched sheet with the correct value. Then I'd like to resume the search with the new value.
I'm at the moment stuck on making my simple MsgBox to be modeless.
Can anyone help? So far I have (simplified):
With ...
On Error GoTo UserSelect
celladdress = .Range("a1:bb100").Find("searchstring").Address
And my error label:
UserSelect:
MsgBox("Select the cell with the correct spelling") vbModeless
newstring = ActiveCell.Value
searchstring = newstring
Resume
I think it's the Modeless MsgBox giving me grief.

I don't believe that you can use vbModeless with msgbox. That is for use with the Show method of a user form.
What you probably need to do is create a user form that has a refedit control and a button on it. They can then pick a cell with the refedit control. When the user clicks on the button set a public variable on the form with the cell reference the selected.
Then you you need to use ".Show vbModal" on the user form and read off the cell they selected from the form public variable.
Edit:
Actually, you shouldn't need the public variable as the refedit control should be a public property of the form anyway.

I'm not 100% sure on the requirements here. Given a search string of dgo and a worksheet with cells containing bird, cat and dog. Do you want the user to:
(a) edit the cell containing dog and change it to say dgo instead
This would use the modal form and RefEdit control outlined by andynormancx. Like a MsgBox, the modal form pauses the macro until the form is closed
(b) allow the user to click on the cell containg dog and then re-run the search with dog as the search term
This is more complicated. I think that you would need to look at events here. This is fine if your subroutine is pretty much standalone but if it is part of a larger program then this could require substantial rewriting

Related

Conditional visibility on MS Access Form - how to write in VBA or Macro

I have some very (very) basic MS Access knowledge. I'm trying to expand a bit into either VBA or macros as I'd like to put in some conditional visibility for my form. Basically, I have a checkbox. If it's checked, I want three or four more fields to pop up. Someone was able to point me to a basic VBA formula of if (this checkbox) = true then, (fieldx).visible = true, else, (fieldx).visibility = false, end if.
But I'm so new to this that I need more help and explanation. I tried putting it in but couldn't get it to work (no error message, just nothing changed at all).
Specific questions:
-Does this formula seem right?
-If I want multiple fields to be visible, can I combine them into one formula or should I create a new "if" statement for all?
-Where do I enter this code? I'm running the Office 365 version. For all I know, I'm not even putting it in the right place.
-How do I determine the field names to replace the (this checkbox) and (fieldx) in the formula? I tried entering the name I title the fields as, but with the spaces in the name I got an error message, and without the spaces nothing happened. Is there a specific naming convention to turn the field names into formula-appropriate titles? Is the name listed somewhere?
-Once I get the formula entered, is there something I have to do to get it to run/take effect? I tried saving, closing and reopening with no changes.
-Is this the best way to go about this?
If there's anything else you think I should know, I would love to hear it - but please keep in mind I'm very new to this so if you could keep it at "dummy" or ELI5 levels of explanation, I'd appreciate it!
after creating a form with 4 textboxes and a checkbox put the form in design mode (lower right corner has design mode selected, select a textbox and hit property sheet on the ribbon (or f4).
On the property sheet note the visible property. set the visible property to false. Now the textbox will be invisible when the form starts.
Tip you can select all the textboxes at the same time and set their properties all at once.
Every control on the form and even the various parts of the form have properties you can set and play with. For instance you can give any name you want to any control. On the property sheet go to the other tab and set the name property.
Tip: choose a name you you will remember without having to look it up and describes the controls function.
Next select the checkbox (not the checkbox's label). On the property sheet go to the event tab and select the on click event. hit the ellipsis and choose code builder. Access is Event Driven. We want the textboxes to appear when the checkbox is selected so we put that code in the checkbox click event.
after choosing code builder we get the code window where we can browse among all the events for all our forms. for now all you should see is something like:
Private Sub mycheckbox_Click()
End Sub
So insert some code to handle the checkboxes like:
Private Sub mycheckbox_Click()
If mycheckbox = True Then
txtbox1.Visible = True
txtbox2.Visible = True
txtbox3.Visible = True
txtbox4.Visible = True
Else
txtbox1.Visible = False
txtbox2.Visible = False
txtbox3.Visible = False
txtbox4.Visible = False
End If
End Sub
now when the checkbox is not checked no textboxes are visible.
but when the checkbox is checked they appear

Get value from command button VBA

I have created A userform with few command buttons.
I can't seem to figure out how do I get the information from them.
I want to open this userform from another one and then I want the user to choose an option from one of the buttons which will change a specific cell in the table itself
the userform I created
I did not write anything on this userform therefor there is no code from it to show only the design.
how do get the information from the buttons to be written in A specific cell on a specific worksheet?
double click on one of the buttons, in the code menu a new sub should appear. this looks something like:
Sub CommandButton1_onClick()
End sub
Alongside this event method, it also has a few properties. The one that is usefull here is the CommandButton1.Value, this represents the state of the button (either true or false iirc).
So build for each button (I strongly advice giving them custom names to prevent getting lost in the trouble) as sub like this:
Sub CommandButton1_onClick()
if CommandButton1.Value then
ThisWorkBook.WorkSheets("WorksheetName").Range("YourRange").Value = "Some value"
else
ThisWorkBook.WorkSheets("WorksheetName").Range("YourRange").Value = ""
end if
End sub

Order of Events for the SheetFollowHyperlink Event

I have a workbook that lists people's names and overall performance for the past few weeks. I was asked to make it so that when their names are clicked, the details for that person would show. The solution I came up with at the time was to point all of the hyperlinks to a sheet that reminded them to turn on their macros.
In the WorkSheet_Activate event, I redirected them to another sheet that populated with the details for the person they had selected. This works fine. If the user doesn't have their macros turned on, they get a friendly reminder, but if they do, they immediately get redirected. There's just one problem. Because the hyperlink takes them somewhere else first, it causes the infamous "screen flicker".
On researching, I found the FollowHyperlink Events (I think the workbook level event would be most suitable for my purposes, though). However, before I get started rebuilding it, I wanted to make sure that this would solve the "screen flicker".
On MSDN, it states that the Event occurs when the user clicks the hyperlink. I can't seem to find anywhere that directly states whether this Event is triggered before or after the user is directed to the other sheet, though. If it gets triggered right after, that wouldn't really help me, but if it gets triggered before, I could put an Application.ScreenUpdates = False in the event, and it would solve my problem.
TL;DR (Get to the point already):
Does the Workbook_SheetFollowHyperlink Event happen before or after the user is directed to where ever the hyperlink is pointed?
To answer your question, the event is triggered after the hyperlink is followed. You can demonstrate this using the code below:
Private Sub Workbook_SheetFollowHyperlink(ByVal Sh As Object, ByVal Target As Hyperlink)
Debug.Print "Workbook level: " & ActiveSheet.Name
End Sub
When the event is triggered, the ActiveSheet is the sheet directed to by the hyperlink.
I'm not sure of a way to solve your problem directly, even the Click() event won't be raised when you click a hyperlink. However, the Worksheet level hyperlink event handler will be called before the Workbook level handler and this may speed the process up enough to not see the flicker.
You can prove this if you leave the Workbook level event as is and add the following code to the Worksheet containing the hyperlinks:
Private Sub Worksheet_FollowHyperlink(ByVal Target As Hyperlink)
Debug.Print "Worksheet level: " & ActiveSheet.Name
Sleep 1000
Debug.Print "Leaving worksheet level event"
End Sub
After a few experiments (see below) I concluded that:
Allow the user to use the hyperlink columns when macros are disabled.
When macros are enabled, hide the current hyperlink column and show another column that gives the user a different "hyperlink" that takes them directly to where you want them to go.
The 2nd hyperlink can easily be "simulated" such that it picks up the other columns hyperlink. (See below)
I hope his helps
Interesting, here's a few things I tried
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
' This does not fire if the user clicks directly on the hyperlink text
' it only fires if when click on the cell space that is not text
With ActiveCell
If Hyperlinks.Count Then
MsgBox "hi" & .Hyperlinks(1).Range
.Hyperlinks(1).Follow
End If
End With
End Sub
However you could make the text in the cells look like a hyperlink but actually just be blue underlined text. You could then use the Worksheet_SelectionChange to go to a related cell.
The question then become how to store the related cell.
You want to store it so that if row and column are inserted on the destination sheet, the reference will adjust. (eg NOT in comments, or the description of named ranges etc..)
Depending on how much data you have there's a variety of ways you could choose from.
I think I would favour this:
Having a hidden column next to the cell on display that has a hyperlink. The cell on display has a formula that is set to pick up the value from the hidden column (I quite like the sound of this as you have the hyperlink column already - so just modify the above code to get the hyperlink from the column next to the clicked cell using offset perhaps)
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
' This does not fire if the user clicks directly on the hyperlink text
With ActiveCell.offset(0,1)
If Hyperlinks.Count Then
.Hyperlinks(1).Follow
End If
End With
End Sub
You could mess around with named ranges, but it will be a pain.
I've just realised that what I tried won't help much as you need the hyperlink to work when macros have not been enabled!
So to get the above to work you could change the columns displayed when the user enables macros. ie the hyperlink column is shown when macros are disabled (and the column to the left of it is not).
When macros are enabled hide the hyperlink column and show the one to the left of it that will cause the SelectionChange event to run.
(You need to beware how other hyperlinks are used as any cell with a hyperlink next to it will respond to the event. You may need to use intersection to check the cell clicked is in a namedrange that contains "all the cells that need to respond to a user clicking them in the manner".
All the above sounds a bit mad, but it would appear the event model does not facilitate stopping the screen flickering.
I hope there is a better way of doing what you want, but for what it's worth, the above might help.
Harvey

Excel: Object Text Box can't do Carriage Returns in Protected vs. Unprotected Sheet states (w/ Text Unlocked)...why?

First and foremost, my due diligence rounded up a ton of answers regarding ActiveX Text Boxes, but nothing really about Object Text Boxes. For my project, I cannot use any ActiveX.
OK, so when a Sheet is Unprotected, an Object Text Box (from Insert > Shapes) works pretty much the way I want it to: the most important thing being that I can hit the Enter key and get a carriage return. Then, I go into the Shape Properties, and uncheck Lock Text, and protect the sheet.
Once the sheet is protected, though, the ability to do carriage returns (type Enter, and go down one line) goes away. Shift+Enter and Alt+Enter are no-goes as well.
Is it just not possible to have this functionality available? Are there any workarounds? Why does Excel hate me? Here are some of my ideas:
Unprotect Sheet when Text Box is clicked/activated, Protect when not
(couldn't figure out the syntax in VBA for this. "If Intersect..." is what I'm thinking)
Insert Word Doc Object (don't like this because one-click enters the
formula bar editing, and I can't get the font to stay)
Just use a merged cell and instruct users to double-click to enter
and use Alt+Enter for a new line.
The winning option for now is using a merged cell, but I may just have to see if ActiveX will work on our network. I really want to stick to the KISS principle here if at all possible for the end user...I don't mind coding in the backend to make it work, though.
Thank you for your thoughts!
EDIT: Here's some images to help...
Here's the functionality that I would like to have when my Sheet is protected:
Next, this is an ActiveX text box with it's properties window displayed (Developer > Design Mode > Properties). The properties that make it somewhat usable when the Sheet is protected are circled in red, the Multiline and Enter Key Behavior. But again, I'd prefer to not have to use ActiveX...plus, the user cannot change font color by line.
Finally, I found this interesting: There is another Text box under Form Control that is grayed out. From a search, it looks like this was taken away in favor of the drawing objects version of the text box...or maybe it's the same? The left is the drawing objects one, the middle is the grayed out Form Control, and the right is the ActiveX.
In sum, I would just like to see if there is a way to have the functionality of an unprotected Sheet's Shapes Text Box when the sheet is protected.
Assuming you are working with a TextBox shape, inserted from the ribbon, here:
Then you can use the optional parameter in the Protect method:
Sheet1.Protect DrawingObjects:=False
This will allow the user to edit text boxes on the worksheet, but the sheet itself will remain protected.
If you are using a Form Control (inserted from the Develper/Design ribbon) then you can set the .MultiLine property by accessing the shape's OLEFormat.Object:
Sub test()
Dim tb As Shape
Dim x As Object
'Get a handle on the SHAPE
Set tb = ActiveSheet.Shapes(2)
'You have to access its properties from the OLEFormat.Object:
tb.OLEFormat.Object.Object.MultiLine = True
End Sub
In my test, even on a Protected worksheet this allows the user to Shift + Enter to insert carriage returns:
Ctrl + Shift + Enter seems to work on a protected sheet.

VBA Excel comboBox dropdown is empty after obj.addItem

I have an Excel2010 VBA userform that has one comboBox, from which the user should be able to select a currently-open Excel Workbook. The USERFORM_Initialize subroutine contains (among other things) :
cbWorkbook.Clear
cbWorkbook.Visible = True
For Each wb In Workbooks
cbWorkbook.AddItem wb.name
Next wb
I have set a breakpoint at this code, and am able to step through it; in the present situation there are four open workbooks, and the "for each" is iterated four times, as appropriate. And I can see that wb.name contains the values that I want.
However, when the form displays and the dropbox arrow is clicked, the "list" is empty. It looks like there is room for one item, and that item is blank. (I believe this is typical of an empty dropdown box.)
Select attributes for the combobox are:
Autosize=False; AutoTab=false; Enabled=True; DropButtonStyle=1-fmDropButtonStyleArrow;
Height=18; ListRows=8; ListStyle=0; Locked=False; ShowOptionWhen=2; SpecialEffect=2; Style=0; Visible=True. At the time of execution, cbWorkbook.listCount = 4
This is in development, and it did appear to work as expected yesterday, but now seems to never work. Any ideas where I might be going wrong?
EDIT: I found the solution to this: I had inadvertantly duplicated another combo box over the top of cbWorksheet, effectively hiding it. The control I was seeing was empty, while the control I wanted was overlaid. Deletion of the rogue control box solved the issues.
My apologies; this should have been the first thing I sought.
I found the solution to this: I had inadvertantly duplicated another combo box over the top of cbWorksheet, effectively hiding it. The control I was seeing was empty, while the control I wanted was overlaid. Deletion of the rogue control box solved the issues.
My apologies; this should have been the first thing I sought.
With ComboBox1
.AddItem "This"
.AddItem "Is"
.AddItem "A"
.AddItem "Test"
End With
or if you want to fill it with Range data:
ActiveSheet.Shapes("ComboBox1").Select
Selection.ListFillRange = "k1:k10"
PS - submit your file for review; it should be easier to look at!